4

I wish to solve a differential equation that contains a hard-to-evaluate integral and to plot the solution in a range at least $r\in(0,10)$. The equation comes from a Hartree equation (Schroedinger equation). The solution must satisfy the boundary condition $u[\infty]=1$ but I don't know how to tell Mathematica to consider this constraint.

eps = 10^-5;
end = 12;
a = -74.04252664070837;
b = 208.01432471151327;
d = -65.08706834153939;
A = 1.56692098226;
gamma = 1;

chi = 9.697836405827061;
kst=6.03474; (* actually i don't know this value exactly this is the best up to now*)
j[x_, r_] = 2 A^2 r x
g0[x_, r_] =  a + b/2 + 3 d/4 + A^2 (b + d) (x^2 + r^2) + d A^4 ((x^2 + r^2)^2 + 4 x^2 r^2)
g1[x_, r_] = j[x, r] (b + 2 d) + 4 d A^4 r x (r^2 + x^2)
f[x_] = x/Sqrt[x^2 + 2]
FNB[r_] :=  NIntegrate[(x^3/(2 + x^2) E^(-A^2 (r^2 + x^2)) (g0[x, r] BesselI[0, j[x, r]] -g1[x, r] BesselI[1, j[x, r]])), {x, 0, Infinity}] 
Plot[FNB[r], {r, 0, 5}]
eqnNB = u''[r] + u'[r]/r - u[r]/r^2 + u[r] - chi*(u[r])^(5) - 2 (Pi)^(3/2)/A u[r] FNB[r] == 0;
SolNB = NDSolve[{eqnNB, u[eps] == 0, u'[eps] == kst}, {u}, {r, eps, end}];
R[r_] = u[r] /. SolNB;
PlotNB = Plot[R[r]^2, {r, eps, end}]
FNB2[r_] :=  NIntegrate[(x R[x]^2 E^(-A^2 (r^2 + x^2)) (g0[x, r] BesselI[0, j[x, r]] - g1[x, r] BesselI[1, j[x, r]])), {x, 0, Infinity}];
eqnNB2 = u''[r] + u'[r]/r - u[r]/r^2 + u[r] - chi*(u[r])^(5) - 2 (Pi)^(3/2)/A u[r] FNB2[r] == 0;
SolNB2 = NDSolve[{eqnNB, u[eps] == 0, u'[eps] == kst}, {u}, {r, eps,end}];
R2[r_] = u[r] /. SolNB2;
PlotNB2 = Plot[R2[r]^2, {r, eps, end}]

I tried to compute the integral FNB[r] at first with a trial function f[x] similar to the solution I want to get, so that the value of the integral doesn't change so much. The problem is that the solution I get from the first iteration doesn't satisfy the boundary condition (this is quite obvious since I didn't tell Mathematica to satisfy it...), and also I don't get any solution from the second iteration when I try to compute the integral FNB[r] with the previously found solution.

bbgodfrey
  • 61,439
  • 17
  • 89
  • 156
edinorog
  • 57
  • 5
  • 1
    Your code doesn't seem to meet your description, where's the iteration? Also, where's the definition of rst and yst? – xzczd Jul 08 '18 at 04:12
  • @xzczd sorry, I've edited the code. The iteration is just another NDsolve to find the solution using the integral FNB2[r] computed using the solution found in the first iteraction SolNB – edinorog Jul 08 '18 at 09:47
  • So the original FNB is NIntegrate[(x u[x]^2 E^(-A^2 (r^2 + x^2)) (g0[x, r] BesselI[0, j[x, r]] - g1[x, r] BesselI[1, j[x, r]])), {x, 0, Infinity}], right? – xzczd Jul 08 '18 at 10:27
  • Yes, but at first I used a trial function x/Sqrt[x^2+2] to find the solution in the first iteration for NDsolve, otherwise it told me that the equation was delayed. I think it's a good compromise. – edinorog Jul 08 '18 at 10:30
  • The asymptotic limit of the equation is u[r] - chi*u[r]^5 - (2 Pi)^(3/2)/A u[r] FNB[r] == 0. Hence, the asymptotic solution is approximately, ((1 - FNB[12] (2 Pi)^(3/2)/A)/chi)^.25, which is 2.13479, not 1 as in the article you cited. Until this discrepancy is resolved, there is no point to trying to solve the complete equation. – bbgodfrey Jul 08 '18 at 16:52
  • @bbgodfrey you are right about u[r]/r^2 and chi*(u[r])^(5) , I've edited the post. I think the discrepancy you noticed it's because the right term is 2(Pi)^(3/2)/A u[r] FNB[r] and NOT (2Pi)^(3/2)/A u[r] FNB[r] (the 2 is not powered by 3/2. Thank you for pointing out this mistake – edinorog Jul 08 '18 at 16:58
  • Still too large by a factor of two. Note this this is a separatrix problem, which is very sensitive to numerical details. – bbgodfrey Jul 08 '18 at 17:04
  • @bbgodfrey I don't understand: the value of FNB[r] shouldn't be 0 at infinity thanks to the factor E^(-A^2 r^2) in the integral? – edinorog Jul 08 '18 at 17:20
  • No, because the modified Bessel functions are exponentially large. I get the same numerical result for FNB that @AlexTrounev gets. (However, his answer for u is wrong, because, he uses too small a value for kst. u == 0 is an attractor, so any value of kst that is too small will lead to a solution oscillating about u == 0. On the other hand, any value of kst that is too large leads to an exponentially growing solution. This is what makes the problem hard to solve.) – bbgodfrey Jul 08 '18 at 17:33
  • So i think the article I cited is not self-consistent: I have to find different values for the parameters a,b,d,Athat fit the asymptotic condition you wrote, right? Only then one can solve the equation. – edinorog Jul 08 '18 at 17:37
  • At the end of Sec 2 of the article, a, b, and A have the values you use, but d is 9.5. The resulting asymptotic value of u is 1.26, closer but still not right. I believe that the equation can be solved once the constants are determined. – bbgodfrey Jul 08 '18 at 18:58
  • @bbgodfrey At first I used the value of d the Author gives in the plot's caption on page 5615, that says d=1 when \[Gamma]=1 (that makes the exponential of u 5). Actually in my own paper I have different values of A,a,b,d so now I tried with them, choosing the value of chi that satisfies your asymptotic condition. Should I edit the post with the new parameters? I'm now seeing the thing you said before: for properly high values of kst the solution seems to approach 1 and not be attracted from 0 – edinorog Jul 08 '18 at 19:05
  • @bbgodfrey I've edited the post. – edinorog Jul 08 '18 at 19:25
  • Now my best value for kst is kst=6.034742740284 manages to give a nice solution up to r=6 – edinorog Jul 08 '18 at 23:17

2 Answers2

6

An iterative solution to the integro-differential equation, as requested by the OP, appears reasonable. Begin with

Off[InterpolatingFunction::dmval]
eps = 10^-5;
end = 12;
a = Rationalize[-74.04252664070837, 0];
b = Rationalize[ 208.01432471151327, 0];
d = Rationalize[-65.08706834153939, 0];
A = Rationalize[1.56692098226, 0];

chi = Rationalize[ 9.697836405827061, 0];
j[x_, r_] = 2 A^2 r x;
g0[x_, r_] = a + b/2 + 3 d/4 + A^2 (b + d) (x^2 + r^2) + 
    d A^4 ((x^2 + r^2)^2 + 4 x^2 r^2);
g1[x_, r_] = j[x, r] (b + 2 d) + 4 d A^4 r x (r^2 + x^2);

The first approximation to the integral is computed as

f[x_] = x/Sqrt[x^2 + 1/2];
FNB = Interpolation@Rationalize[Table[{r, E^(-A^2 (r^2 )) 
    NIntegrate[(x f[x]^2 E^(-A^2 ( x^2)) (g0[x, r] BesselI[0, j[x, r]] - 
    g1[x, r] BesselI[1, j[x, r]])), {x, 0, 30}]}, {r, 0, end, .1}], 0];

Note that all numerical quantities are rationalized, because subsequent NDSolve computations require high WorkingPrecision. (High WorkingPrecison is necessary, because this is a separatrix computation, which is extremely sensitive to initial conditions.) Note also that the initial guess for u[r], namely f[x_] = x/Sqrt[x^2 + 1/2], differs slightly from the initial guess in the question, because I felt that it would be a better first approximation, and it appears to be. Now, solve the resulting ODE for the next approximation to u[r], following the procedure described here.

eqnNB = u''[r] + u'[r]/r - u[r]/r^2 + u[r] - chi*(u[r])^(5) - 
    2 (Pi)^(3/2)/A u[r] FNB[r] == 0;
sp = ParametricNDSolveValue[{eqnNB, u[eps] == 0, u'[eps] == up0, 
    WhenEvent[u[r] > 12/10, {bool = 1, "StopIntegration"}], 
    WhenEvent[{u[r] < 8/10, u[r] < 0}, {bool = 0, "StopIntegration"}]}, 
    u, {r, eps, end + 1}, {up0, wp0}, WorkingPrecision -> wp0, 
    Method -> "StiffnessSwitching", 
    Method -> {"ParametricSensitivity" -> None}, MaxSteps -> 100000];
bl = 1; bu = 10; imax = 200; wp = 75;
Row[{ProgressIndicator[Dynamic[ip], {0, imax}], "   ", 
    ProgressIndicator[Dynamic[rm], {0, end}]}]
Do[bool = -1; bmiddle = (bl + bu)/2; s = sp[bmiddle, wp]; 
    rm = s["Domain"][[1, 2]]; If[bool == 0, bl = bmiddle, bu = bmiddle];
    ip = i; If[bool == -1, Return[]], {i, imax}] // AbsoluteTiming
N[bmiddle, wp]
Plot[{s[r], f[r]}, {r, eps, Min[rm, end]}, PlotRange -> All, AxesLabel -> {r, u}, 
    ImageSize -> Large, LabelStyle -> {Black, Bold, Medium}]

enter image description here

The original guess, f[r] agrees well with the new approximation, s[r], for r > 3. Now, substitute s into the integral.

FNB1 = Interpolation@Rationalize[Table[{r, E^(-A^2 (r^2 )) 
    NIntegrate[(x Piecewise[{{s[x], eps < x < end}}, f[x]]^2 E^(-A^2 ( x^2)) 
    (g0[x, r] BesselI[0, j[x, r]] - g1[x, r] BesselI[1, j[x, r]])), 
    {x, 0, 30}]}, {r, 0, end, .1}], 0];

and employ NDSolve as before to obtain the next approximation.

eqnNB1 = u''[r] + u'[r]/r - u[r]/r^2 + u[r] - chi*(u[r])^(5) - 
    2 (Pi)^(3/2)/A u[r] FNB1[r] == 0;
sp = ParametricNDSolveValue[{eqnNB1, u[eps] == 0, u'[eps] == up0, 
    WhenEvent[u[r] > 12/10, {bool = 1, "StopIntegration"}], 
    WhenEvent[{u[r] < 8/10, u[r] < 0}, {bool = 0, "StopIntegration"}]}, 
    u, {r, eps, end + 1}, {up0, wp0}, WorkingPrecision -> wp0, 
    Method -> "StiffnessSwitching", 
    Method -> {"ParametricSensitivity" -> None}, MaxSteps -> 100000];
bl = 1; bu = 10; imax = 200; wp = 75;
Row[{ProgressIndicator[Dynamic[ip], {0, imax}], "   ", 
    ProgressIndicator[Dynamic[rm], {0, end}]}]
Do[bool = -1; bmiddle = (bl + bu)/2; s1 = sp[bmiddle, wp]; 
    rm = s1["Domain"][[1, 2]]; If[bool == 0, bl = bmiddle, bu = bmiddle];
    ip = i; If[bool == -1, Return[]], {i, imax}] // AbsoluteTiming
N[bmiddle, wp]
Plot[{s1[r], s[r], f[r]}, {r, eps, Min[rm, end]}, PlotRange -> All, 
AxesLabel -> {r, u}, ImageSize -> Large, LabelStyle -> {Black, Bold, Medium}]

enter image description here

This process can be iterated to obtain progressively more accurate approximations. Each iteration took about 15 minutes on my PC.

Addendum: Converged Iterative Solution

Good convergence can be achieved with the following code (with constants defined above).

s[0][x_] = x/Sqrt[x^2 + 1/4];
FNB[0] = Interpolation@Rationalize[Table[{r, 
    E^(-A^2 (r^2 )) NIntegrate[(x s[0][x]^2 E^(-A^2 x^2) 
    (g0[x, r] BesselI[0, j[x, r]] - g1[x, r] BesselI[1, j[x, r]])), 
    {x, 0, 20}]}, {r, 0, end, .1}], 0];

mmin = 1; mmax = 20; imax = 200; wp = 75;
Row[{Dynamic[m], "   ", ProgressIndicator[Dynamic[ip], {0, imax}], 
    "   ", ProgressIndicator[Dynamic[rm], {0, end}]}]
Do[eqnNB = u''[r] + u'[r]/r - u[r]/r^2 + u[r] - chi*(u[r])^(5) - 
    2 (Pi)^(3/2)/A u[r] (FNB[m - 1][r] + FNB[Max[m - 2, 0]][r])/2 == 0;
    sp = ParametricNDSolveValue[{eqnNB, u[eps] == 0, u'[eps] == up0, 
    WhenEvent[u[r] > 11/10, {bool = 1, "StopIntegration"}], 
    WhenEvent[{u[r] < 9/10, u[r] < 0}, {bool = 0, "StopIntegration"}]}, u, 
    {r, eps, end + 1}, {up0, wp0}, WorkingPrecision -> wp0, 
    Method -> "StiffnessSwitching", 
    Method -> {"ParametricSensitivity" -> None}, MaxSteps -> 100000];
bl = 1; bu = 10;
Do[bool = -1; bmiddle = (bl + bu)/2; st = sp[bmiddle, wp]; rm = st["Domain"][[1, 2]]; 
    If[bool == 0, bl = bmiddle, bu = bmiddle]; ip = i;
    If[bool == -1, Return[]], {i, imax}];
s[m] = st; N[bmiddle, wp];
FNB[m] = Interpolation@Rationalize[Table[{r, 
    E^(-A^2 (r^2 )) NIntegrate[(x Piecewise[{{s[m][x], eps < x < end}}, 
    s[0][x]]^2 E^(-A^2 ( x^2)) (g0[x, r] BesselI[0, j[x, r]] -
    g1[x, r] BesselI[1, j[x, r]])), {x, 0, 30}]}, {r, 0, end, .1}], 0];, 
{m, mmin, mmax}]
Plot[Evaluate@Table[s[m][r], {m, mmax - 5, mmax}], {r, eps, end}, 
    PlotRange -> All, AxesLabel -> {r, u}, ImageSize -> Large, 
    LabelStyle -> {Black, Bold, Medium}]
Plot[Evaluate@Table[FNB[m][r], {m, mmax - 5, mmax}], {r, 0, end}, 
     PlotRange -> All, AxesLabel -> {r, "FNB"}, ImageSize -> Large, 
     LabelStyle -> {Black, Bold, Medium}]

enter image description here

enter image description here

Convergence is very good for both the solution, u, and the integral, FNB. (The slight irregularity in FNBat large r is due to a slight boundary condition mismatch, which I shall fix as time permits.) The only significant difference in the revised code used here is that (FNB[m - 1][r] + FNB[Max[m - 2, 0]][r])/2 replaces FNB[m - 1][r] in eqnNB to improve numerical stability. Note that this computation required 6 hours on my pc. However, mmax was excessively large to assure convergence, and mmax == 14 could have been run in 4 hours.

Explanation of using WhenEvent

Integrating an ODE long distances along a separatrix is difficult, because the numerical solution can depart rapidly from the true solution due to small errors in the initial condition. One method of improving the accuracy of the initial conditions is to choose initial guesses (bl and bu in the answer above) that bracket the unknown true initial condition, and then systematically reducing the uncertainty in the initial guesses by doing calculations with initial conditions that bifurcate the distance between the guesses. So, it is necessary to stop a calculation when it obviously is departing from the separatrix, and to note whether the trial calculation is departing above or below. In the answer above, the separatrix is expected to be near 1, except at small r. So, {9/10, 11/10} are expected to bracket the separatrix, and WhenEvent is used to stop the calculation, when the solution moves from inside to outside that range. (Merely being outside that range does not stop the calculation, which is why I check for u < 0 to catch cases in which the solution never reaches the desired range in the first place.) For a solution asymptotically approaching 2, use {18/10, 22/10} or something of that sort. Setting these limits may take some experimentation. Ideally, the range selected should bracket the desired solution with only a modest margin of error, because a large margin of error means that more computer time is required to detect when a particular computation is leaving the expected range.

bbgodfrey
  • 61,439
  • 17
  • 89
  • 156
  • Thanks a lot. I only don't really understand how to perform iterations. I simply repeated the part of your code from the definition of sp to the Plot with the substitutions sp→sp1,s→s1,eqnNB→eqnbNB1 ,FNB→FNB1 and rm→rm1 but now NDSolve solves the eqn just up to 0.3. What's the problem? Can you show me how you menage to perform the iterations? Simply I'm new to Mathematica and I don't understand that much your code. – edinorog Jul 09 '18 at 10:49
  • @AleLenoci I have changed the initial values of bl and bu and made a few other changes to make the code more robust. – bbgodfrey Jul 09 '18 at 16:22
  • Now using your code I can't get the right solution. Moreover I still don't understand how to perform the iteration and get your final plot...Could you please post the complete working code? thanks for the efforts – edinorog Jul 09 '18 at 17:03
  • Thanks for the update @bbgodfrey. This method can work also for other similas ODEs or the parameters you set are all specific for this case? – edinorog Jul 09 '18 at 18:32
  • @AleLenoci This method should work for similar ODEs. – bbgodfrey Jul 09 '18 at 19:13
  • I still can't get the second plot from your code, i don't understand what the problem is. You are plotting the second iteration? it seems that s1 is the same as s...where am I wrong? – edinorog Jul 09 '18 at 20:20
  • Typo corrected. – bbgodfrey Jul 10 '18 at 04:38
  • I would like to ask you something showing you the plot I've done iterating up to 5 times your code. How can I post images in comments? Or should I edit the question/your answer? Just to show the plot for further iterations – edinorog Jul 10 '18 at 13:23
  • Temporarily use the Answer box at the bottom of this page to download the picture. Then, cut the link, place it in your comment, and delete the answer you started without posting it. Is the solution I started not converging? – bbgodfrey Jul 10 '18 at 14:01
  • 1]: https://i.stack.imgur.com/KH7Kg.jpg. I see two families of solutions: one for even iterations and one for odd iterations. As the number of iterations increases it seems the solution's grows – edinorog Jul 10 '18 at 14:23
  • In another notebook I also I modified chi = Rationalize[9.697836405827061, 0]; in order to adjust the asymptotic condition (I have now a constant named JJ = Rationalize[+0.9611852103171311, 0]; instead of 1/A multiplying the integral in the equation). Now the solution is quite similar but I had to abort evaluation near r=12 because seems the algorithm can't accept more points. Is there a way to fix this changing the parameters you set in the algorithm? Here's the plot of the first iteration: [2]: https://i.stack.imgur.com/mAxXj.jpg – edinorog Jul 10 '18 at 14:30
  • With respect to your first recent comment, the iteration appears to be not converging. I must give that some thought. With respect to the second comment, increase end + 1 in the definition of sp, perhaps to end + 3/2. – bbgodfrey Jul 10 '18 at 14:37
  • The fact is that the solution for "even" families ( that one with peak at 2) is very similar to the plot reported in the paper i cited before, so could it be the author there just truncated the iterations.. – edinorog Jul 10 '18 at 14:49
  • @AleLenoci The addition I just made to my answer gives a converged solution. The oscillations are real. Later today, I hope to provide a slightly more rapidly converging solution. – bbgodfrey Jul 11 '18 at 18:46
  • Is the condition you impose WhenEvent[u[r] > 11/10, {bool = 1, "StopIntegration"}], WhenEvent[{u[r] < 9/10, u[r] < 0}, {bool = 0, "StopIntegration"}]} avoiding solutions with wide oscilations (and so divergence)? Althought it is a different equation from the one on the paper and I also changed some parameters I would expect a maximum near r=2 and little wider oscillations. However I'm mainly interested in understanding the way to solve these equations so thanks a lot for the efforts. – edinorog Jul 12 '18 at 15:01
  • My response to you question was too long for a comment, so I added it to the end of my answer. I hope it helps. By the way, if the answer meets your needs, please accept it by clicking the grey check mark to the left of the answer. Reading the short tutorial for this web site provides this and other useful information. – bbgodfrey Jul 12 '18 at 16:08
  • I've posted a new question https://mathematica.stackexchange.com/questions/179459/solving-integro-differential-equation-numerically-with-shooting-method about the same problem with different parameters. I'm using your code silghtlymodified to solve this problem but I cannot get convergence in those cases. I would be very grateful if you cold give a look. Thanks a lot. – edinorog Aug 03 '18 at 19:39
  • I shall take a look at set 2 first. – bbgodfrey Aug 04 '18 at 00:35
1

We can not take the eps too small, because there is a stop because of the divergence of the solution. Empirically, I picked up eps = 0.005. Then there is a solution, but it is not like expected - it's a function similar to Bessel's function.

eps = 5*10^-3;end = 12;
a = 1.9123;
b = -28.9815;
d = 1;
A = 1.6;
gamma = 1;
chi = 3.5;
j[x_, r_] := 2 A^2 r x
g0[x_, r_] := 
 a + b/2 + 3 d/4 + A^2 (b + d) (x^2 + r^2) + 
  d A^4 ((x^2 + r^2)^2 + 4 x^2 r^2)
g1[x_, r_] := j[x, r] (b + 2 d) + 4 d A^4 r x (r^2 + x^2)
U[0][x_] := x/Sqrt[x^2 + 2]
q[x_] := U[0][x]^2
FNB2 = Interpolation[
   Table[{r, 
     NIntegrate[(q[x]*x*
        Exp[-A^2 (r^2 + x^2)] (g0[x, r] BesselI[0, j[x, r]] - 
          g1[x, r] BesselI[1, j[x, r]])), {x, 0, Infinity}]}, {r, eps,
      end, .005}]];
U[1] = NDSolveValue[{u''[r] + u'[r]/r - u[r]/r^2 + u[r] - 
     chi*(u[r])^(5) - (2 Pi)^(3/2)/A u[r]*FNB2[r] == 0, 
   u'[eps] == 1.1, u[eps] == 0}, u, {r, eps, end}]

{Plot[U[1][r], {r, eps, end}, PlotRange -> All], 
 Plot[FNB2[r], {r, eps, end}, PlotRange -> All]}

fig1

Alex Trounev
  • 44,369
  • 3
  • 48
  • 106
  • thanks for the effort but as you said the solution doesn't fit boundary condition at infinity which is the key problem . I know from a paper that the solution should approach to 1 to infinity by a few dumped oscillations within the interval $(0,12)$. – edinorog Jul 08 '18 at 14:58
  • Can you name the article (paper) or give a link? – Alex Trounev Jul 08 '18 at 15:46
  • Sure, look here http://www.damtp.cam.ac.uk/user/ngb23/publications/nls2.pdf. It's Eq.22, look at the plot below where's plotted u[r]^2 – edinorog Jul 08 '18 at 16:19
  • There is a difference between your equation and the equation (22). I made a change to the equation in my message, but the solution to the equation did not change qualitatively. – Alex Trounev Jul 09 '18 at 04:42