0
$\begingroup$

I run an experiment when I put some nutrients every day in week days but not in weekends. So I have a system of differential equations where I use the WhenEvent function to define the periodic pulses unce pr 24 hours by the Mod[t,24] function. My question is how can I exclude the evaluation of this function at certain days in time e.g. pulses from day 1 to 65 bu not in 7,8, 14,15 etc. I have tryed to write a Piecewise function as follows but I thing that the problem is that it is not evaluated appropriately at the specific time points. As an example:

ClearAll["Global`*"]
daysoff = {3, 4, 10, 11, 17, 18, 24, 25, 26, 27, 31, 32, 38, 39, 45, 
46, 52, 53, 59, 60};
timeoffinhour = 24*daysoff
expr[t_ /; MemberQ[timeoffinhour, t]] := 100;
expr[t_ /; Not@MemberQ[timeoffinhour, t]] := Mod[t, 24];
Plot[expr[t], {t, 0, 1500}, PlotRange -> Full, 
MaxRecursion -> 15, Exclusions -> None]
expr[768]

The plot shows that the part of the function at time belonging in timeoffinhour is not evaluated correctly as it is shown in the plot (points at 100 do not appear) and so happens in the WhenEvent conditions. However expr[768] evaluates correctly. Any suggestion comment is higely evaluated.

$\endgroup$
3
  • 2
    $\begingroup$ Where's the WhenEvent / NDSolve code? $\endgroup$
    – Michael E2
    Apr 2, 2018 at 11:28
  • $\begingroup$ Perhaps using DateObjects for the dates w nutrients and DayMatchQ[<date>, "Weekend"] would generalize the code. See reference.wolfram.com/language/ref/DayMatchQ.html $\endgroup$
    – FredrikD
    Apr 2, 2018 at 13:19
  • $\begingroup$ Thank you for the suggestion FredrikD. I think the issue is to define a function that will not be evaluated in certain values and this function to be used as a condition in WhenEvent function within NDSolve. $\endgroup$
    – Nitra
    Apr 2, 2018 at 17:14

1 Answer 1

2
$\begingroup$

Perhaps this:

daysoff = {3, 4, 10, 11, 17, 18, 24, 25, 26, 27, 31, 32, 38, 39, 45, 46, 52, 53, 59, 60};
timeoffinhour = 24*daysoff;
nf = Nearest[timeoffinhour];
sol = NDSolve[{u'[t] == -0.02 u[t], u[0] == 1,
    WhenEvent[Mod[t, 24] == 0 (*&&Length@nf[t,{1,0.5}]>0*), (* periodic event + condition unimplemented *)
     If[Length@nf[t, {1, 0.5}] > 0,
      du = 0.,            (* skip *)
      du = 0.4];          (* pulse *)
     u[t] -> u[t] + du]}, (* code fails if event rules put inside If[] *)
    u, {t, 0, 60*24}];

ListLinePlot[u /. First[sol], GridLines -> {timeoffinhour, None}]

Mathematica graphics

$\endgroup$
2
  • $\begingroup$ Thank you for your reply @Michael E2. This is exactly what I need. I have to understand the use of Nearest which is critical in this implementation. Sorry for not posting the code for my NDSove, WhenEvent but the code is too long. $\endgroup$
    – Nitra
    Apr 2, 2018 at 12:58
  • $\begingroup$ @Nitra You're welcome. nf[t, {1, 0.5}] returns the nearest time in timeoffinhour that is within a radius of 0.5 of the time t. The 1 limits the number of times returned to at most 1. So the return value will be a list of length zero or one. (You can make the 0.5 much smaller, but keep in mind that the condition is only tested if Mod[t, 24] == 0; so 0.5 is quite small enough in this case.) $\endgroup$
    – Michael E2
    Apr 2, 2018 at 13:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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