Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm using ParametricNDsolve to check best fit of a model (function Eb1) with some data, and I have four free parameters I want to test. I can easily construct a Parametric solution between the two boundaries of interest $r_{n}$ and $r_{o}$ - however, I also need to define the function between $0 \leq r \leq r_{n}$; in this case it's a constant whose value is given by Eb1($r_{n}$) , so that for $r \leq r_{n}$ the value is constant. I can do this with Piecewise when I manually specify the parameters (kme, kmn, j, eo) but I am running into errors using Piecewise with a parametric function; my code so far is;

(*Constants required*)
a = 8.2314*10^-7; omega = 3.0318*10^7; Do2 = 2*10^-9; po = 106; ro = 235*10^-6; micron = 1*10^-6; qm = 10^-4; mic = 1*10^-6; De = 5.5*10^-11;  con = (a*omega)/(6*Do2); rl = Sqrt[(6*Do2*po)/(omega*a)];

(*Functions that are pre-defined*)
 rn = Piecewise[{{0, ro <=  rl}, {ro*(0.5 - Cos[(ArcCos[1 - (2*rl*rl)/(ro^2)] - 2*Pi)/3]), ro  > rl}}];

p[r_] = Piecewise[{{po + con*(r^2 - ro^2 + 2*(rn^3)*(1/r - 1/ro)), r > rn} , {0 , r <= rn}}];

q[r_] = qm*((kme/(kme + p[r]))*(p[r]/(kmn + p[r]))  + (kmn/(kmn + p[r]))*j);


(*Coupled Equations to be solved*)
  eqnDe = D[Ef1[r, t], t] -  De*(D[Ef1[r, t], r, r] + (2/r)*(D[Ef1[r, t], r])) + q[r]*Ef1[r, t];

eqnBo = D[Eb1[r, t], t] - (Ef1[r, t])*q[r];


(*Parametric solution for unknowns kme, kmn, j and eo*)
x = ParametricNDSolve[{eqnBo == 0, Eb1[r, 0] == 0, eqnDe == 0, 
Ef1[r, 0] == 0, Derivative[1, 0][Ef1][rn, t] == 0, 
Ef1[ro, t] == eo},  Eb1, {r, rn, ro}, {t, 0, 14400}, {kme, kmn, j, eo}];

So far so good; now to define the full range of Eb1, including the domain $r < r_n$, I try to use Piecewise;

Ebound[r_] = 
  Piecewise[{{Eb1[rn, 14400] /. x, r < rn}, {Eb1[r, 14400] /. x, 
 r >= rn}}];

but this yields the error ParametricNDSolve::fpct: "Too many parameters in {kme,kmn,j,eo} to be filled from {r,14400}." - Similar error messages occur when I try Ebound[r_,kme_,kmn_,j_,eo_] - is there anyway I can define this chunk of the domain with the parametric solution? I'll meet to do this before I try fitting to the data and I have and this is proving a stumbling block!

share|improve this question

1 Answer 1

The problem is that you specify a parametric function with 4 arguments (*{kme, kmn, j, eo}*) but only feed the function call two.

You'd need to set the proper parameters but then this will work:

x = ParametricNDSolveValue[{eqnBo == 0, Eb1[r, 0] == 0, eqnDe == 0, 
    Ef1[r, 0] == 0, Derivative[1, 0][Ef1][rn, t] == 0, 
    Ef1[ro, t] == eo}, 
   Eb1, {r, rn, ro}, {t, 0, 14400}, {kme, kmn, j, eo}];

x is now a paramtric function and expects four aguments, the values of kme, kmn, j, eo. Once those 4 are given it will return an InterpolatingFunction that can be evaluated with two arguments (r first, then t).

Ebound[r_] := With[{fun = x[1, 1, 1, 1]},
  Piecewise[{{fun[rn, 14400], r < rn}, {x[r, 14400], r >= rn}}]
  ]

And the call the function with

 Ebound[1]

You most likely want the Ebound to be SetDelayed.

share|improve this answer
    
Thanks for this but I'm still a little confused: As I understand it, the function Eb1 has two dependent variables, [r,t]. The parameters are [kme,kmn,j,eo] - should the call then be something like; Ebound[r_] := Piecewise[{{x[rn, 14400, kme, kmn, j, eo], r < rn}, {x[r, 14400, kme, kmn, j, eo], r >= rn}}]; Thanks for answering by the way! –  DRG Jul 11 at 13:17
    
Also, if I'm understanding correctly, this gives "x" in piecewise format - my question is how do I give Eb1 in piecewise from this? –  DRG Jul 11 at 13:23
    
Thanks for the edit - I get now that x calls four functions - however, I'm still unsure how to define Eb1 now from this, as this is really what I want to define (and then fit) - if you could explain this I'd be delighted. I keep trying replacement rules for it and mathematica doesn't seem to like them! –  DRG Jul 11 at 13:46
    
Ok I tried this : Ebound[r_] = Piecewise[{{Eb1[rn, 14400] /. x[kme, kmn, j, eo], r < rn}, {Eb1[r, 14400] /. x[kme, kmn, j, eo], r >= rn}}]; but this yields the "not a list of rules" error. Any ideas? –  DRG Jul 11 at 16:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.