2

I am solving PDEs with NDSolve and NIntegrate, but I do not know how to pass arguments correctly. My orignial code is very complicated, so I simplfied it to clarify the problems I met.

  1. Firstly, I solved the simplified code without passing the arguments:

    ClearAll[x, y,r, t]; ss = NDSolve[{ x'[t] == (NIntegrate[x[t]rr, {r, 0, 5}] + y[t] + t)*y[t], y'[t] == -x[t], x[0] == 1, y[0] == 1}, {x, y}, {t, 10}]; Plot[Evaluate[{x[t], y[t]} /. ss], {t, 0, 10}]

  2. Then I used the skil of passing arguments to solve the problems, and the code becomes:

    ClearAll[x, y, z, zz, t]; u[x_, r_] := xr; v[u_?NumericQ] := NIntegrate[ur, {r, 0, 5}]; z[v_, y_, t_] := v + y + t;

    s = NDSolve[{ x'[t] == z[t, t, t]*y[t], y'[t] == -x[t], x[0] == 1, y[0] == 1}, {x, y}, {t, 10}]; Plot[Evaluate[{x[t], y[t]} /. s], {t, 0, 10}] But I got different and wrong results. Why?

  3. I also tried to pass the arguments in another way, but I just got the error messages. Why?

    ClearAll[x, y, u, v, z, zz, t, f]; u[x_, r_] := xr; v[x_?NumberQ] := NIntegrate[ur, {r, 0, 5}]; z[v_, y_, t_] := v + y + t;

    s = NDSolve[{ x'[t] == z[v[u[x[t]]], y[t], t]*y[t], y'[t] == -x[t], x[0] == 1, y[0] == 1}, {x, y}, {t, 10}];

  4. I also tried another way to pass the arguments, and the result is correct and same to 1). But I prefer not to use it due to my complicated original code.

    ClearAll[x, y, u, v, z, zz, t, f]; u[x_, r_] := xr; v[x_?NumberQ] := NIntegrate[ur, {r, 0, 5}]; f = NIntegrate[u[x[t], r]*r, {r, 0, 5}]; z[v_, y_, t_] := v + y + t;

    s = NDSolve[{x'[t] == z[f, y[t], t]*y[t], y'[t] == -x[t], x[0] == 1, y[0] == 1}, {x, y}, {t, 10}];

    Plot[Evaluate[{x[t], y[t]} /. s], {t, 0, 10}]

How to pass arguments in complicated codes correctly?


The original equations look like this. They are integration-differential equations.

The only independent variables is z, the aim is to solve $\nu$[z], qr[z] and qi[z] from z=0 to z. The parameters are: A[z], B[z], D[z], d[z], and ne[$\rho$,z], $\gamma$[$\rho$,z], $\epsilon$r[$\rho$,z] and $\epsilon$i[$\rho$,z]. The integration of $\rho$ ranges from d to infinite.

Equations:

enter image description here

I wrote the code with error messages: NDSolve::ndnum: Encountered non-numerical value for a derivative at z == 0.1.

From equations to code, different names are used: $\rho$ -->r, D-->D0, d-->dmin. $\gamma$ -->$\gamma_0$

ClearAll[ν, qr, qi, r, γ, ne, ϵr, ϵi, dmin, A, B, D0, aL, Zni, νei];
aL = 10;
Zni = 0.001;
νei = 0.001;
γ= (1 + aL^2*ν^2*Exp[-2*qr*r^2])^0.5;
ne= Zni - 4*qr*γ*(1 -γ^(-2))*(1 - qr*r^2*(1 + γ^(-2)));
ϵr= 1 - ne/γ;
ϵi= 4*Pi*νei*ne;
dmin= Re[qr^(-0.5)*(-0.5*Log[Zni/(8*aL^2*ν^2*qr) (1+sqrt[4+(Zni/(4*qr))^2])])^0.5];
D0[ne_?NumericQ, qr_?NumericQ] := NIntegrate[16*Pi*νei*ne*Exp[-2*qr*r^2]*qr*r, {r, dmin, Infinity}];
A[ν_?NumericQ, qr_?NumericQ, ϵr_?NumericQ, qi_?NumericQ,ϵi_?NumericQ, dmin_?NumericQ] := 
  ν*NIntegrate[r*Exp[-qr*r^2]*((1-ϵr)*Sin[qi*r^2]-ϵi*Cos[qi*r^2]), {r, dmin, Infinity}];
B[ν_?NumericQ, qr_?NumericQ, ϵr_?NumericQ, qi_?NumericQ,ϵi_?NumericQ, dmin_?NumericQ] := 
  ν*NIntegrate[r*Exp[-qr*r^2]*((1-ϵr)*Cos[qi*r^2]+ϵi*Sin[qi*r^2]), {r, dmin, Infinity}];

s = NDSolve[{ ν'[z] == -A[ν[z], qr[z], ϵr,qi[z], ϵi, dmin]qr[z] - D0[ne, qr[z]]ν[z], qr'[z] == -2 A[ν[z], qr[z], ϵr,qi[z], ϵi, dmin]qr[z]^2/ν[z]-D0[ne,qr[z]]qr[z], qi'[z] == -3 A[ν[z], qr[z], ϵr,qi[z], ϵi, dmin]qr[z]qi[z]/ν[z] +
B[ν[z], qr[z], ϵr,qi[z], ϵi, dmin]qr[z]^2/ν[z] -
D0[ne, qr[z]]
qi[z], ν[0.1] == 1., qr[0.1] == 10^(-4), qi[0.1] == 0.}, {ν, qr, qi}, {z, 0.1, 10000.}]

Michael E2
  • 235,386
  • 17
  • 334
  • 747
sixpenny
  • 33
  • 6
  • Your understanding for function is wrong. Just evaluate z[t, t, t] separately and think about why this happens. You may also want to read this question. Also, x[t] should be taken out of NIntegrate i.e. it should be x[t] NIntegrate[r*r, {r, 0, 5}]. – xzczd Jun 13 '16 at 06:51
  • I am still trying to understand, but... And in my original code, x is a function of r, so it was x[r] not x[t]. – sixpenny Jun 13 '16 at 07:11
  • Then I doubt if NDSolve will handle your code correctly. As far as I can tell, NDSolve isn't able to directly solve this type of integro-differential equation (at least currently). – xzczd Jun 13 '16 at 07:27
  • If it is true, that is a big pity! I thought that mma is more powerful than matlab, then spent weeks to try to solve the integro-differential equations with mma. I still can not solve it. On the contrary, I only spent one day to solve the problem with matlab using runge-kuta method. And the coding with matlab is more straight forward. Maybe both mma and matlab have their own advantages. It will be useful to point out the weakness of mma, especially compared to matlab. Thus more guys will save their time! – sixpenny Jun 13 '16 at 15:03
  • I began to use Mathematica because of a set of complicated PDEs, too, and as far as I can tell, for solving PDEs, Mathematica is much more handy then MATLAB. Though NDSolve can't directly handle this type of DE, Mathematica can solve several types of integro-differential equation (yeah there's a variety of integro-differential equations!) with just a little additional programming, for example this, this, this... – xzczd Jun 13 '16 at 15:07
  • ...Programming something like classical Runge-Kutta (BTW it's also a built-in method of NDSolve!) is easy in Mathematica, too, for example this , but I really doubt if such a pedagogic algorithm (Yeah RK4 is just a relatively practical pedagogic algorithm!) will be able to handle a really complicated DE system.(You may want to read this). Finally, with all due respect, though the learning curve of MMA is deemed to be steep, if you've really learned MMA for weeks, I should say you're... – xzczd Jun 13 '16 at 15:23
  • ...reading the wrong book, given your unclear understanding for functions. For learning the core language, a good resource is this. (BTW here's the unfinished Chinese edition.) Or, if you don't have enough time to learn the core language currently, I suggest you not to abuse functions, at least. BTW, given currently the DE is oversimplified, I suggest you to modify them a little more to reflect the nature of the original problem. (I do appreciate your effort for simplifying so far!) – xzczd Jun 13 '16 at 15:48
  • I have read the book and the examples. They are interesting and useful! However, I evaluated z[t, t, t] in 1) and 2), and they are the same. I still do not know why, 1) and 2) give different results. I will post my original complicated questions elsewhere. – sixpenny Jun 20 '16 at 02:16
  • Well, but I think z[t, t, t] isn't used in 1) ? – xzczd Jun 20 '16 at 03:07
  • Sorry, z[t,t,t] in 2) and 4). – sixpenny Jun 20 '16 at 04:45
  • You actually use z[f, y[t], t] in 4). If you still have difficulty in understanding, evaluate z[aa, bb, cc], z[t1, t2, t3], z[ff, yy, zz] and compare the result. – xzczd Jun 20 '16 at 05:21
  • I understand!!! Thank you. – sixpenny Jun 20 '16 at 06:03
  • I just uploaded the original equations. Do they look like, I must use Runge-Kutta method? – sixpenny Jun 20 '16 at 06:19
  • Again, with all due respect, you should also learn how to ask good questions, or your questions will keep being closed. Let alone the "too localized" part, your new-added original equation set is rather unclear, for example: Are the $qr$ and $q_r$ the same function? What's the independent variable(s) of $\nu, q_r, q_i$ etc.? (At beginning I thought $z$ is the only independent variable, but then I saw a $n_e(\rho,z)$ term.) What's the boundary condition of the equation set? – xzczd Jun 20 '16 at 07:24
  • I am sorry!!! I have revised the equatons and questions. – sixpenny Jun 20 '16 at 08:33
  • Yes, my question is too localized. So I just need a hint on how to solve them. – sixpenny Jun 20 '16 at 08:38
  • Then your early claim "in my original code, x is a function of r" is wrong, and your equation set turns out to be one of the simplest type of integro-differential equation, which can indeed be solved by the ?NumericQ technique. I'm a little busy at the moment, but will probably write an answer within several hours. – xzczd Jun 20 '16 at 08:45
  • What's the definition of $Ln$? Is $\gamma_0$ nonnegative? – xzczd Jun 20 '16 at 10:36
  • By definition, Ln is log_e not log_10. γ0 is nonnegtive. – sixpenny Jun 20 '16 at 11:17
  • Welcome to Mathematica.SE! I suggest the following: 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Take the tour! 3) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! – Michael E2 Jun 22 '16 at 03:14

1 Answers1

2

As mentioned in the comments above, your understanding for function is wrong. You'd better put more effort in learning the core language of Mathematica, or even consider revisiting the definition of function in math. The following is a not-the-simplest but correct way to code your equation set in Mathematica, do read it carefully:

Clear["`*"]
vei = 1/1000;
r0 = Sqrt[1 + v^2 Exp[-2 qr rho^2]];
ne = 1/1000 - 4 qr r0 (1 - 1/r0^2) (1 - qr rho^2 (1 + 1/r0^2));
er = 1 - ne/r0; ei = 4 Pi vei ne;

d[v_, qr_] = Sqrt[(-Log@(1/1000 1/(v^2 qr) (1 + Sqrt[4 + (1/(1000 4 qr))^2])))]/Sqrt[qr];

{coreA[v_, qr_, qi_, rho_], coreB[v_, qr_, qi_, rho_]} = 
  Exp[-qr rho^2] rho RotationMatrix[qi rho^2].{ei, 1 - er};
int[core_, v_, qr_, qi_?NumericQ] := 
 v NIntegrate[core[v, qr, qi, rho] , {rho, d[v, qr], Infinity}, MaxRecursion -> 40]

coreD[v_, qr_, rho_] = 16 Pi vei ne Exp[-2 qr rho^2] qr rho;
intD[v_, qr_?NumericQ] := 
 NIntegrate[coreD[v, qr, rho], {rho, 0, Infinity}, MaxRecursion -> 40]

(* Notice I've actually modified the sign of A! *)    
eqn = With[{v = v@z, qr = qr@z, qi = qi@z}, 
   With[{intA = int[coreA, v, qr, qi], intB = int[coreB, v, qr, qi], 
     intD = intD[v, qr]}, {D[v, z] == intA qr - intD v, 
     D[qr, z] == 2 intA qr^2/v - intD qr, 
     D[qi, z] == 3 intA qi qr/v + intB qr^2/v - intD qi}]];

bc = {v[0] == 1, qr[0] == 10^(-4), qi[0] == 0};

{solv, solqr, solqi} = NDSolveValue[{eqn, bc}, {v, qr, qi}, {z, 0, 1}]
(* Some warning generated, but a result is still given *)
Plot[{Re@#[z], Im@#@z} &@solv // Evaluate, {z, 0, 1}]

enter image description here

When solving the equation set, NIntegrate spits out a lot of warning, I'm not sure about the reason. Perhaps it's a clue of divergence and the model should be checked, perhaps a higher WorkingPrecision or MaxRecursion is needed. Anyway I'd like to stop here and leave the remaining work to you.

xzczd
  • 65,995
  • 9
  • 163
  • 468
  • I understood! I revised my code accordingly, and solved the problem. Inside the integration, core[v, qr, qi, rho] not 'core' should be used. While outside the integration, ne, not only ne[v, qr, qi, rho] can be used. This is one of the important issues I learned. Thank you very much! – sixpenny Jun 22 '16 at 03:44
  • @sixpenny Actually the fatal part isn't the integration. What's crucial is, the independent variable must explictly exist in the body of function. Just compare the output of Clear[a, b, f]; b=a; f[a_]=b^2; f[2] and Clear[a, b, f]; b=a; f[a_]:=b^2; f[2] and think about why. If still feel confused, check the document ofSet and SetDelayed and try Clear[a, b, f]; b=a; Trace[f[a_]=b^2] – xzczd Jun 22 '16 at 03:56