I'm trying to make some numerical simulation with NDSolve
. I have encountered a few problems. Here is a simplified version of the equations:
Cwirk = 50 25 3;
eq= {Q[tau] - 200 (tt[tau] - tae[tau]) == Cwirk tt'[tau],
Q[tau] - 100 (28 - tr[tau]) vF[tau] 7/6 == 0,
tr[tau] - tt[tau] - (28 - tt[tau]) Exp[-0.9/(7/6 vF[tau] 0.22)] == 0,
vF[tau] - Clip[(20 + 20 (20 - tt[tau])), {10^(-10), 100}] == 0,
tt[1] == 15, tr[1] == 15, vF[1] == 100, Q[1] == 0}
Using Clip
is to limit the vF in a specific range, e.g. between 0 and 100. 10^-10 is to prevent 1/0 error. I don't know if WhenEvent
could do the same thing. The tae is an interpolated function. E.g.:
li = Import[http://web.archive.org/web/20180623011154/https://rredc.nrel.gov/solar/old_data/nsrdb/1991-2005/data/tmy3/725958TYA.CSV];
tae = Interpolation[Transpose[{Range[8760], Drop[Drop[li, 1][[All, 32]], 1]}]]
But NDSolve
complains about complex values if I try to solve the equations
sol0 = Flatten[NDSolveValue[eq, tt, {tau, 1, 24 365}]]
NDSolveValue::mconly: For the method IDA, only machine real code is available. Unable to continue with complex values or beyond floating-point exceptions.
However, if I eliminate some equations with Rule
, it runs smoothly.
rs = {Q -> 100 (28 - tr) vF 7/6,
tr -> tt[tau] + (28 - tt[tau]) Exp[-0.9/(7/6 vF 0.22)],
vF -> Clip[20 + 20 (20 - tt[tau]), {10^(-10), 100}]};
eq = Q - 200 (tt[tau] - tae[tau]) == Cwirk tt'[tau];
sol2 = Flatten[NDSolve[{eq //. rs, tt[1] == 15}, tt, {tau, 1, 24 365}]]
But why?
The real problem is much bigger and it's not very easy to eliminate some equations. Is there any other solution for this problem?
EDIT
Here are part of the data from the file.
li = {{0, 1.5}, {1, -1}, {2, 0}, {3, 0}, {4, 3}, {5, 6}, {6, 10},
{7, 12}, {8, 14}, {9, 16}, {10, 17}, {11, 18}, {12, 20}, {13, 23},
{14, 23}, {15, 21}, {16, 17}, {17, 14}, {18, 12}, {19, 10},
{20, 9}, {21, 8}, {22, 4}, {23, 4}, {24, 1.5}};
tae = Interpolation[li];
sol0 = Flatten[NDSolveValue[eq, tt, {tau, 0, 24}]]
NDSolveValue::ivres: NDSolve has computed initial values that give a zero residual for the differential-algebraic system, but some components are different from those specified. If you need them to be satisfied, giving initial conditions for all dependent variables and their derivatives is recommended.
NDSolveValue::mconly: For the method IDA, only machine real code is available. Unable to continue with complex values or beyond floating-point exceptions.
I think the Exp[-0.9/(7/6 vF[tau] 0.22)]
is the problem. When vF
drops to 10^-10
, this Exp[]
become extremely small near zero and NDSolve
has difficulty to process it. Is there any way to avoid this?
EDIT2
@xzczd discovered that Exp[-0.9/(7/6 vF[tau] 0.22)]
is not the root of this error message after trying deactivating CatchMachineUnderflow. It appears that NDSolve cannot process the 10^-10
in the eq
. Increasing the 10^-10
to 0.1
solves the problem, but doesn't give me the accuracy I want. Any other solutions?
P.S. my intention is to prevent the vF
becoming negative, so if there is any way to make Clip[(20 + 20 (20 - tt[tau])), {0, 100}]
working is also acceptable.
EDIT3
Here are the optimized initial conditions.
eq = {Q[tau] - 200 (tt[tau] - tae[tau]) == Cwirk tt'[tau],
Q[tau] - 100 (28 - tr[tau]) vF[tau] 7/6 == 0,
tr[tau] - tt[tau] - (28 - tt[tau]) Exp[-0.9/(7/6 vF[tau] 0.22)] == 0,
vF[tau] - Clip[(20 + 20 (20 - tt[tau])), {10^(-10), 100}] == 0}
ic = FindRoot[eq[[All, 1]] == 0 /. tau -> 0,
Transpose[{{Q[0], tt[0], tr[0], vF[0]}, {3000, 20, 20, 20}}]] /.
Rule -> Equal
sol = NDSolve[Join[eq, ic], {Q, tt, tr, vF}, {tau, 0, 24}]
NDSolve::mconly: For the method NDSolve`IDA, only machine real code is available. Unable to continue with complex values or beyond floating-point exceptions.
Methods
that may work in your case. $\endgroup$li
into your post instead of giving it as an external link, that'll make your post more attractive. I know the original file is too large to post here, but I guess it's enough to reproduce the issue with just a small part of the data? (Actually I have difficulty in downloading the file here… ) $\endgroup$