The issue is that while stepFunc() is a Python function, it is not a Variable operator expression as far as FiPy is concerned. FiPy Variable operator expressions tend to be things that can be expressed as arithmetic expressions. Python conditionals don't work; greater/less-than expressions do.
It is possible to construct your own Variable class that can calculate something unusual, but I find this is seldom necessary. See the source code in fipy/variables for noiseVariable.py (and all of the ...NoiseVariable.py subclasses), modularVariable.py, histogramVariable.py for some examples. Generally, you need to override the _calcValue() method to perform the calculation you need. Usually I find it's easier and more maintainable to write an arithmetic expression for what I need. Whether the return value is an integer or float has no bearing on this; a float value is simply correct from the standpoint of evaluating the PDE. It might not matter, but integers can behave badly at unpredictable times. > On Feb 1, 2019, at 10:20 AM, Bill Greene <[email protected]> wrote: > > Your suggestion certainly works and I appreciate the quick response. > > However, in general, I would like to define more complicated functions of > time that are best > implemented in a function. So I am still interested in WHY the function > approach doesn't > work. Is there a way to tell FiPy to call that function whenever the time > Variable is changed? > If there is a manual section you can point me to, that would be great. > > (I changed the function to return a floating point number instead of an > integer but it is still > being treated as a constant.) > > Thanks, > > Bill > > On Fri, Feb 1, 2019 at 9:40 AM Guyer, Jonathan E. Dr. (Fed) via fipy > <[email protected]> wrote: > `time` is a Variable as FiPy understands it, but stepFunc() simply returns an > integer, so eqI is defined with a source that is the integer 0. > > I'd try > > eqI = fipy.TransientTerm(coeff=1.) == ((time < 0.1) * 0. + (time >= 0.1) * 1.) > > > On Feb 1, 2019, at 6:05 AM, Bill Greene <[email protected]> wrote: > > > > I am trying to solve an equation where the source term is > > a discontinuous function of time. I have followed examples > > where the source term is a simple, continuous function of time > > and these appear to work correctly. > > > > The key parts of my code are shown below: > > > > def stepFunc(t): > > if(t.value<.1): > > s = 0 > > else: > > s=1 > > print('t=', t, 's=', s) > > return s > > > > time = fipy.Variable(0., cached=1) > > eqI = fipy.TransientTerm(coeff=1.) == stepFunc(time) > > > > t = 0 > > for step in range(steps): > > time.setValue(t+dt/2.) > > eqI.solve(var=u, dt=dt) > > t += dt > > > > The function stepFunc appears to be called only once and the solution > > indicates that s=0 for the entire solution time. > > > > I thought that the cached option on the Variable object might affect this > > behavior but when I set it to zero, I get an error message that I don't > > understand. > > > > Any help will be much appreciated. > > > > Bill Greene > > > > _______________________________________________ > > fipy mailing list > > [email protected] > > http://www.ctcms.nist.gov/fipy > > [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ] > > > _______________________________________________ > fipy mailing list > [email protected] > http://www.ctcms.nist.gov/fipy > [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ] _______________________________________________ fipy mailing list [email protected] http://www.ctcms.nist.gov/fipy [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]
