# Speed up ParametricNDSolve

I' m trying to solve a second order ode with one parameter.However the solution is taking too much time. I tried using

Method -> {Automatic, "SymbolicProcessing" -> 0}


but it gives me incorrect results. Here' s the code

dm2 = 7.4*10^(-5); ye = 5/6; lv = 2.48*p1/dm2; Rs = 6.95*10^(5); ye1 = (3*ye - 1)/2;
h0 = -1; d0 = 120; l1 = 1.4*10^5;

bperpRs = Interpolation@data1
dendir[r_] = ye1*d0*(1 - Tanh[r/l1]);
h1[r_] = lv*dendir[r]/(1.63*10^4);
h12[r_] = lv*bperpRs[r]/(1.1*10^6);

eqn = {D[y1[r], {r, 2}] - (h12'[r]/h12[r]) y1'[
r] + ((Pi/lv)^2 ((h12[r])^2 + (h0 + h1[r])^2) +
I*Pi*h1'[r]/lv - I*Pi*(h0 + h1[r])*h12'[r]/(lv*h12[r])) y1[
r] == 0,  y1[0] == 1, (D[y1[r], r] /. r -> 0) == -I*Pi*(h0 + h1[0])/lv};

soln = ParametricNDSolve[eqn, y1, {r, 0, Rs}, {p1}]


I want to plot Abs[y1[p1][Rs]] against p1 where p1 has domain (0.001, 0.015). Is there a way to speed up the solution?

File data1 contains following data

data1 = {
{0.,0.009},{10425.,0.012},{20850.,0.027},{31275.,0.042},
{41700.,0.06},{52125.,0.08},{62550.,0.101},{72975.,0.124},{83400.,0.144},
{93825.,0.167},{104250.,0.185},{114675.,0.208},{125100.,0.225},
{135525.,0.237},{145950.,0.25},{156375.,0.258},{166800.,0.258},
{177225.,0.258},{187650.,0.25},{198075.,0.239},{208500.,0.223},
{218925.,0.199},{229350.,0.174},{239775.,0.148},{250200.,0.116},
{260625.,0.083},{271050.,0.054},{281475.,0.029},{291900.,0.024},
{302325.,0.045},{312750.,0.068},{323175.,0.081},{333600.,0.097},
{344025.,0.1},{354450.,0.1},{364875.,0.092},{375300.,0.083},
{385725.,0.083},{396150.,0.101},{406575.,0.137},{417000.,0.191},
{427425.,0.252},{437850.,0.317},{448275.,0.392},{458700.,0.47},
{469125.,0.548},{479550.,0.626},{489975.,0.7},{500400.,0.769},
{510825.,0.835},{521250.,0.892},{531675.,0.94},{542100.,0.974},
{552525.,0.998},{562950.,1.006},{573375.,0.998},{583800.,0.976},
{594225.,0.943},{604650.,0.894},{615075.,0.83},{625500.,0.755},
{635925.,0.664},{646350.,0.566},{656775.,0.459},{667200.,0.343},
{677625.,0.22},{686660.,0.113},{695695.,0.015}
};

• Can you show how you timed this, is it perhaps the Plot that takes long? – user21 Jan 11 at 9:10
• Yes you are correct soln = ParametricNDSolve[eqn, y1, {r, 0, Rs}, {p1}] // Timing gives 0.000266 seconds. While Plot[Evaluate[(Abs[y1[en][Rs] /. soln])], {en, 0.002, 0.015}, PlotRange -> All] takes forever. – user62311 Jan 11 at 10:53
• The reason for the incorrect result: Checking soln for examplary p1 shows, that the simulation timerange used by NDSolve is sometimes smaller <Rs. Trying to evaluate the solutution at t=Rs extrapolates and gives "incorrect" result. – Ulrich Neumann Jan 11 at 11:13
• @Ulrich Neumann: can you tell me how you arrived at this? I checked for different values of r, but each time it gives wrong result. – user62311 Jan 11 at 11:20

Not a solution speed up, but a step forward(hopefully):

Try

Y1 = ParametricNDSolveValue[eqn, y1, {r, 0, Rs}, {p1}]


The solution for let's set p1=.0015

Y1[.0015][Rs]      (* 12s evaluation time*)
(*-0.00432859 - 1.00503 I*)


solution {Abs[Y1[p1][Rs]], p1}:

sol = Table[{Abs[Y1[p1][Rs]], p1}, {p1, Subdivide[.001, .0015, 10]}];
ListPlot[{sol, sol}, Joined -> {False, True}]


• Thanks for the answer. This method is definitely much faster. – user62311 Jan 11 at 18:32