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 ]

Reply via email to