Hi all and thank you in advance.
I am working on a time-dependent transport-chemistry model to study the composition of planetary atmospheres.
The equations are the following $$\frac{\partial n(z,t)}{\partial t} = -\frac{\partial \Phi (z,t)}{\partial z} + p(z,t) -n(z,t)l(z,t)$$ for each chemical component, characterized by a density profile $n(z,t)$.
Let's focus in the chemistry part, because the problem I am going to explain does not take place for transport alone (modeled as a thermodynamic diffusion flux $\Phi$). $$\frac{\partial n(z,t)}{\partial t} = p(z,t) -n(z,t)l(z,t).$$
Let's suppose we have three molecules interacting following the following reactions
H2O + O --> 2OH
2OH --> H2O + O
The set of equations to be modeled are
$$\partial n_{H2O}/\partial{t} = \partial n_{O}/\partial{t} = -An_{H2O}n_{O} +Bn_{OH}^{2}\\ \partial n_{OH}/\partial{t} = 2An_{H2O}n_{O} -2Bn_{OH}^{2}$$
The algorithm I am testing is a semi-implicit Bulirsch-Stoer method (see Numerical recipes in Fortran, page 735, for a detailed explanation). I basically adapted the code is provided within the book.
This algorithm is suitable for my project because it makes an error estimation so that time step is constantly adapted. I need to integrate up to million of years in about 1 hour, i.e. my simulation up to a certain point has to integrate with $h > 10^5 s$.
Next I am displaying a screenshot from this "toy model" typical realization (This would be a first step before including hundreds of reactions of the same kind)
The system clearly achieves stationary state, but the time step does not increase beyond than $h \approx 10^{-3}$. The idea is that in a Stiff Systems time step increases as reactions contributions as these become stationary.
So far, I think the core of my problem is the piece of code devoted to determine the error associated for each integrated step
errmax=SMALL
do i=1,nv
errmax=max(errmax,abs(yerr(i)/yscal(i)))
end do
errmax=errmax/eps
Where what I less understand is the "yscal" factor. In the previous reference (Numerical Recipes in Fortran, page 735) it is mentioned
We now mention an important point: "It is absolutely crucial to scale your variables properly when integrating stiff problems with automatic stepsize adjustment. As in our nonstiff routines, you will be asked to supply a vector $y_{scal}$ with which the error is to be scaled. For example, to get constant fractional errors, simply set $y_{scal} = |y|$. You can get constant absolute errors relative to some maximum values by setting $y_{scal}$ equal to those maximum values. In stiff problems, there are often strongly decreasing pieces of the solution which you are not particularly interested in following once they are small. You can control the relative error above some threshold $C$ and the absolute error below the threshold by setting
$y_{scal} = max(C,|y|)$
If you are using appropriate non-dimensional units, then each component of $C$ should be of order unity. If you are not sure what values to take for $C$, simply try setting each component equal to unity. We strongly advocate the previous expression for stiff problems
"Playing" with such $y_{scal}$ definitely the behavior changes so that I believe including the proper expression for it I can get the desired result. When I include "transport" alone, I obtain the desired evolution in $h$ the time step. Something happens with chemistry.
I am open to any kind of suggestions. Even if you can provide me other ideas to implement. I experimented a bit with Rosenbrock methods with the same exact result. I am really stuck with such model.