1

I need to solve these 2 differential equations simultaneously.

dr^3/dt=(-3*D*Cs)/(ρ*r0^2 )*r*(1-C)

dC/dt=((D*4π*r0*N*(1-C)*r)-(Af*C))/V

Note: dr^3/dt is the derivative of r^3 with respect to t

The two equations resemble the change in particle radius (r) and concentration (C) with time for a dissolution process of a microsuspension and its simultaneous absorption in the bloodstream. What is expected to happen as the solid dissolves, is that radius, r, will decrease and the concentration, C, will increase and eventually plateau (i.e. reach an equilibrium) as the dissolved solid is being removed into the bloodstream by this Af*C term (where Af is some sort of absorption rate constant). The equations come from this paper which I am trying to replicate: jpharmsci.org/article/S0022-3549(18)30334-4/fulltext#sec3.2.1 -- Change in C with t is supposed to be like Figure 3 (DCU example).

I did the simplification: dr^3/dt = 3r^2*(dr/dt) and by dividing both sides of the equation by 3r^2. The odes become:

function dydt=odefcnNY_v3(t,y,D,Cs,rho,r0,N,V,Af)
dydt=zeros(2,1);
dydt(1)=((-D*Cs)/(rho*r0^2*y(1)))*(1-y(2)); % dr*/dt
dydt(2)=(D*4*pi*N*r0*(1-y(2))*y(1)-(Af*y(2)))/V; % dC*/dt
end
y(1) = r* and 
y(2) = C*
r* and C* 

is the terminology used in the paper and are "normalised" radius and concentration where

r*=r/r0 and C*=C/Cs

where:

  • r=particle radius (time varying and expressed by dydt(1))
  • r0=initial particle radius
  • C=concentration of dissolved solids (time varying and expressed by dydt(2))
  • Cs=saturated solubility

The rest of the code is below. Updated with feedback from authors on values used in paper and to correct initial values to y0=[1 0]

MW=224; % molecular weight
D=9.916e-5*(MW^-0.4569)*60/600000 %m2/s - [D(cm2/min)=9.916e-5*(MW^-0.4569)*60] equation provided by authors, divide by 600,000 to convert to m2/s 
rho=1300; %kg/m3
r0=10.1e-6; %m dv50
Cs=1.6*1e6/1e9; %kg/m3 - 1.6ug/m3 converted to kg/m3
V=5*0.3/1e6;%m3 5ml/Kg animal * 0.3Kg animal, divide by 1e6 to convert to m3
W=30*0.3/1000000; %kg; 30mg/Kg animal * 0.3Kg animal, divide by 1e6 to convert to m3
N=W/((4/3)*pi*r0^3*rho); % particle number
Af=0.7e-6/60; %m3/s
tspan=[0 24*3600]; %s in 24 hrs
y0=[1 0];
[t,y]=ode113(@(t,y) odefcnNY_v11(t,y,D,Cs,rho,r0,Af,N,V), tspan, y0);
plot(t/3600,y(:,1),'-o') %plot time in hr, and r*
xlabel('time, hr')
ylabel('r*, (rp/r0)')
legend('DCU')
title ('r*');
plot(t/3600,y(:,1)*r0*1e6); %plot r in microns
xlabel('time, hr');
ylabel('r, microns');
legend('DCU');
title('r');
plot(t/3600,y(:,2),'-') %plot time in hr, and C*
xlabel('time, hr')
ylabel('C* (C/Cs)')
legend('DCU')
title('C*');
plot(t/3600, y(:,2)*Cs) % time in hr, and bulk concentration on y
xlabel('time, hr')
ylabel('C, kg/m3')
legend('Dissolved drug concentration')
title ('C');

I first tried ode45, but the code was taking a very long time to run and eventually I got some errors. I then tried ode113 and got the below error.

Warning: Failure at t=2.112013e+00.  Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t.

Update: Code for function updated to resolve singularity issue:

function dydt=odefcnNY_v10(t,y,D,Cs,rho,r0,N,V,Af)
dydt=zeros(2,1);
dydt(1)=(-D*Cs)/(rho*r0^2)*(1-y(2))*y(1)/(1e-6+y(1)^2); % dr*/dt
dydt(2)=(D*4*pi*N*r0*(1-y(2))*y(1)-Af*y(2))/V; %dC*/dt
end

Results enter image description here

Mechanistic background to model

Derivation of dr/dt

Derivation of dydt(1)

Derivation of dC/dt

Derivation of dydt(2)

Model Assumptions

Above you will find slides that show the derivations of these equations. They assumed that in the Noyes-Whitney equation for dissolution rate dM/dt=(/h)4^2(−), the film thickness, h, is equal to the particle radius, r. This is a simplification usually done in biopharmaceutics modelling if the Reynolds number is low and particles are <60um (in their case 10um). If we make this assumption, we are left with dM/dt=4(−). I am eager to replicate this paper as I want to do this exact same thing i.e. model drug absorption of a subcutaneous injection of a microsuspension. I have contacted the authors, who seem rather unsure of what they have done so I am looking at other sources, there is for example this paper: https://pubs.acs.org/doi/pdf/10.1021/acs.iecr.7b04730 where in equation 6, an equation for dC/dt is shown. They imbed the change in surface area per unit volume (a) (equation 5) into equation 6. And their mass transfer coefficient kL is a lumped parameter = D/h (diffusivity/film thickness).

  • `d(r^3)=3*r^2*dr`, check carefully that the equations are physically correct and correctly implemented. – Lutz Lehmann Nov 17 '19 at 00:10
  • Thanks - I implemented the suggestion. The Af*C term was missing in the second equation, now added. I did the simplification: dr^3/dt = 3*r^2*(dr/dt) and by dividing both sides of the equation by 3*r^2, dydt(1) now becomes: `dydt(1)=((-D*Cs)/(rho*r0^2*y(1)))*(1-y(2)); % dr*/dt` Is this correct? The code is now running, seems to be taking a while! – Engineer_1331 Nov 17 '19 at 01:47
  • Yes, that looks correct. For ODE that might be stiff use one of the implicit methods like `ode113` that also adapts the order of the method to the stiffness. This might increase the step sizes and thus work faster. – Lutz Lehmann Nov 17 '19 at 08:05
  • I got this error: Error using horzcat Requested 2x528701600 (7.9GB) array exceeds maximum array size preference. Creation of arrays greater than this limit may take a long time and cause MATLAB to become unresponsive. See array size limit or preference panel for more information. Error in ode45 (line 484) yout = [yout, zeros(neq,chunk,dataType)]; – Engineer_1331 Nov 17 '19 at 09:14
  • When I tried the ode113 I got this error: Warning: Failure at t=2.112013e+00. Unable to meet integration tolerances without reducing the step size below the smallest value allowed (7.105427e-15) at time t. Error using getByteStreamFromArray Error during serialization Error in matlab.graphics.internal.clearNotify (line 28) matlab.internal.editor.FigureManager.figureBeingCleared(fig, flag); .. Remainder of error is in the question – Engineer_1331 Nov 17 '19 at 10:17
  • What are the physics of the process, is there some solid reason that the system should not diverge or become otherwise singular after 2 sec? – Lutz Lehmann Nov 17 '19 at 11:21
  • The two equations resemble the change in particle radius (r) and concentration (C) with time for a dissolution process of a microsuspension. What is expected to happen as the solid dissolves, is that radius, r, will decrease and the concentration, C, will increase and eventually plateau as the dissolved solid is being removed into the bloodstream by this Af*C term (where Af is some sort of absorption rate constant). The equations come from this paper: https://jpharmsci.org/article/S0022-3549(18)30334-4/fulltext#sec3.2.1 -- Change in C with t is supposed to be like Figure 3 (DCU example). – Engineer_1331 Nov 17 '19 at 12:35
  • Do you have an alternative source for a similar process? I think the article lost a power of 2 from the surface area, dissolution is a surface process, it should be proportional to the surface area. Thus it should be `d(r^3)/dt=(-3*D*Cs)/(ρ*r0 )*r^2*(1-C)` so that `dr/dt = (-D*Cs)/(ρ*r0 )*(1-C)` for `r>0` switching to `dr/dt=0` constant for `r<=0`. – Lutz Lehmann Nov 17 '19 at 16:21
  • 1
    Thank you - I have implemented the suggestions you made. – Engineer_1331 Nov 17 '19 at 16:21
  • I added some clarification into the question. They make an assumption in the dissolution equation, dM/dt=(/h)4^2(−), that the film thickness, h = particle radius, r. And so we are left with r in the numerator. I added a link to another paper who have tried to model a similar thing. – Engineer_1331 Nov 17 '19 at 16:55
  • Ok, that might make sense. The answer remains valid, the radius shrinks to zero in finite time and you need to incorporate this in the solution process. – Lutz Lehmann Nov 17 '19 at 16:59
  • Thanks, so you mention that I need to modify the radius equation so that r=0 is a natural stationary point. I am not so familiar with this, could you show me how I can alter my code. i.e. as I will continue to work with dr/dt, then will this do it: `dr/dt = -K*sign(r)*(1-C)` (only difference is the r should be in the denominator as in `dydt(1)=((-D*Cs)/(rho*r0^2*y(1)))*(1-y(2)); % dr*/dt`) and do I also need to add your last line of code with the continuous approximations? – Engineer_1331 Nov 17 '19 at 17:15
  • You can use a variable `u=r^2` instead. If you want to stay with `r`, then a suitable mollification of `1/r` is `r/(eps^2+r^2)` with some small `eps`. This should also trap the radius at zero without becoming negative during the numerical process. – Lutz Lehmann Nov 17 '19 at 17:33
  • Is this correct: `function dydt=odefcnNY_v5(t,y,D,Cs,rho,r0,N,V,Af) dydt=zeros(2,1); u=y(1)^2; dydt(1)=((-D*Cs)/(rho*r0^2*u^(1/2)))*(1-y(2)); % dr*/dt dydt(2)=((D*4*pi*N*r0*(1-y(2))*u^(1/2))-(Af*y(2)))/V; %dC*/dt end` – Engineer_1331 Nov 17 '19 at 17:47
  • I added the modified function in the question for your review, it may be easier to view. – Engineer_1331 Nov 17 '19 at 17:53
  • The code runs, I added some graphical results into the question. The r change with time makes sense, it drops to a negative 10 um i.e. loses all its radius, although not sure why it starts at zero, when I specified that r0 = 10.1e-6 m (or 10 um)? The C* results also don't match the paper. But if we are sure the code has been implemented correctly, it could be the authors have done something wrong? – Engineer_1331 Nov 17 '19 at 18:27
  • No, it would be the other way around, `u=y(1)` would be the state variable and you would locally compute `r=u^0.5` or `r=u/abs(u)^0.5` or similar to get a sign-preserving square root. – Lutz Lehmann Nov 17 '19 at 18:29
  • Sorry to bother, I am sort of new to matlab, could you show how the code would look like? It seems to be the final step to solve this problem! – Engineer_1331 Nov 17 '19 at 19:34

1 Answers1

0

In the original form of the radius equation

d(r^3)/dt = -3K*(r^3)^(1/3)*(1-C)

or the power-reduced one

dr/dt = -K/r*(1-C)  <==> d(r^2)/dt = -2K*(1-C)

you reach a singularity at the moment that the radius shrinks to zero like approximately r=sqrt(A-B*t), that is, the globules will have vanished in finite time. From that point on, obviously, one should have r=0. This can be obtained via a model change from a 2 component system to a scalar equation for C alone, getting the exact time via event mechanism.

Or alternatively, you can modify the radius equation so that r=0 is a natural stationary point. The first version somehow does that, but as the second versions are equivalent, one can still expect numerical difficulties. Possible modifications are

d(r^2)/dt = -2K*sign(r)*(1-C)

where the signum function can be replaced by continuous approximations like

x/(eps+abs(x)), x/max(eps,abs(x)), tanh(x/eps), ...

or in the reduced form, the singularity can be mollified as

dr/dt = -K*(1-C) * r/(eps^2+r^2)

or still in some other variation

dr/dt = -K*(1-C) * 2*r/(max(eps^2,r^2)+r^2)

Applied to the concrete case this gives (using python instead of matlab)

def odefcnNY(t,y,D,Cs,rho,r0,N,V,Af):
    r,C = y;
    drdt = (-D*Cs)/(rho*r0**2)*(1-C) * r/(1e-6+r**2); # dr*/dt
    dCdt = (D*4*pi*N*r0*(1-C)*r-(Af*C))/V;            # dC*/dt
    return [ drdt, dCdt ];

and apply an implicit method in view of the near singularity at r=0

D=8.3658e-10#m2/s 
rho=1300; #kg/m3
r0=10.1e-6; #m dv50
Cs=0.0016; #kg/m3
V=1.5e-6;#m3
W=9e-6; #kg
N=W/(4/3*pi*r0^3*rho);
Af=0.7e-6/60; #m3/s
tspan=[0, 24*3600]; #sec in 24 hours
y0=[1.0, 0.0]; # relative radius starts at full, 1.0
sol=solve_ivp(lambda t,y: odefcnNY(t,y,D,Cs,rho,r0,Af,N,V), tspan, y0, method="Radau", atol=1e-14);
t = sol.t; r,C = sol.y;

then results in a solution plot

plot of the start of the solution

which now with the corrected parameters looks close to the published graphs.

Lutz Lehmann
  • 25,219
  • 2
  • 22
  • 51
  • thanks! can we check `drdt = (-D*Cs)/(rho*r0**2)*(1-C) * r/(1e-6+r**2); # dr*/dt`. After the simplification going from `dr^3/dt` to `drdt` the equation became `dydt(1)=((-D*Cs)/(rho*r0^2*y(1)))*(1-y(2)); % dr*/dt` i.e. the r or y(1) is in the denominator. – Engineer_1331 Nov 18 '19 at 21:45
  • Just compare the graphs, for large `r`, `r/(eps^2+r^2)` looks like `1/r`, for small `r` the mollification is still continuous. It looks perhaps better if you compare the dynamic of `r^2`, where then `r^2/(eps^2+r^2)` approximates the unit ramp function. – Lutz Lehmann Nov 18 '19 at 22:04
  • and (1-C) should be in the numerator. – Engineer_1331 Nov 18 '19 at 22:04
  • Yes I see now that for large `r`, `r/(eps^2+r^2)` becomes `1/r`. What about (1-C), shouldn't it be in the numerator? – Engineer_1331 Nov 18 '19 at 22:12
  • Yes, I see no equation where it is not? – Lutz Lehmann Nov 18 '19 at 22:33
  • Sorry, my bad. I have updated D and W after feedback from the authors on the parameters they used. I also realised I made a mistake with the initial values. y0 should be `y0= [1 0]` as `r = r0 at t=0`, therefore `r*=1`. I put the results in the question. The results show a reasonable graph for r*, but the C* is way underestimated. It should be a value between 0 and 1 as it is the fraction of the drug dissolved compared to the saturated concentration, Cs. I will continue to dig on the reason why! Thanks for your help on this - you have really been excellent! – Engineer_1331 Nov 19 '19 at 20:50
  • Hi - I noticed another thing: the order of the arguments in the function and the ode113 call didn't match. `[t,y]=ode113(@(t,y) odefcnNY_v11(t,y,D,Cs,rho,r0,Af,N,V), tspan, y0); and function dydt=odefcnNY_v11(t,y,D,Cs,rho,r0,N,V,Af)`, it should be: `t,y,D,Cs,rho,r0,N,V,Af`. This way C* values are more reasonable i.e. <1. They still don't match the paper, but they are more reasonable than before. – Engineer_1331 Nov 29 '19 at 08:02
  • Yes, that is a grave error. But now saturation is reached immediately and dissolution is verrry slow. // The previous C* values were not larger than 1, they were ridiculously small at 2.5e-23. Now it climbs in the first minutes to 0.93. – Lutz Lehmann Nov 29 '19 at 08:22
  • Yes, indeed I meant the C* values should be between 0 and 1. The slow dissolution may not be surprising as the particles only have 1.5 ml (the injected volume) to dissolve in. This is the assumption made in the paper, i.e. that there is no other liquid in the subcutaneous region for the solids to dissolve in other than the 1.5 ml of liquid that is injected. If you increase the timescale to 200 hours, you will see the particles diminish and the C* and r* drop to zero. It does seem to go faster at the beginning and plateau to a higher value for us than in the paper and I can't figure out why. – Engineer_1331 Nov 29 '19 at 09:12
  • I am now trying to solve a similar problem, but for the in-vitro dissolution of a nanosuspension: https://stackoverflow.com/questions/59101142/solving-differential-equations-in-matlab-in-vitro-dissolution. As you have been helping me on this one, if you have any insights on the new question that would be appreciated! – Engineer_1331 Nov 29 '19 at 09:17
  • As the formulas replicate the formulas in the paper, it can only be the constants that make the difference. All you can do is check again if they all belong to the case you want to replicate and have the correct scale. The current form of computing them from more primary quantities should be rather stable against errors. – Lutz Lehmann Nov 29 '19 at 09:19
  • Yes I agree. I am having others cross check the constants in the code against the paper. Failing that, I will contact the authors again and in parallel implement the same calculation but to other data. Although they don't really state how they derive parameters like Af from the dosing study, but that can also be another question to them :) – Engineer_1331 Nov 29 '19 at 09:31