Also, the natural boundary condition for FiPy is no-flux, so there's no need to 
do

  T_var.faceGrad.constrain(0, where=mesh.facesLeft)

> On Apr 22, 2019, at 1:28 PM, Guyer, Jonathan E. Dr. (Fed) via fipy 
> <FIPY@nist.gov> wrote:
> 
> Clara -
> 
> - The cause of everything dropping to zero is that T_var.old is initialized 
> to zero. This isn't a particularly useful initial value, but that's what it 
> is. Usually, T_var.updateOld() is the first thing called in the time step 
> loop, so this initial condition doesn't matter, but because of the way you've 
> structured your adaptive time steps, the first sweep is done with an 
> erroneous initial condition.
> 
> Call T_var.updateOld() one time before you start taking time steps.
> 
> - Your sweep tolerance is too severe. I adjusted to 1.0e-6 and the adaptive 
> stepper works much better.
> 
> - The way you define and update dt, you'll get recursion errors eventually. 
> Instead, define
> 
>   dt = 0.9*dr**2/(2.0*Diff[0].value)
> 
>   If you're curious, this is because:
> 
>   * Diff is a FaceVariable
>   * so, Diff[0] is a UnaryOperator Variable
>   * so, dt = 0.9*dr**2/(2.0*Diff[0]) is a BinaryOperator Variable
>   * so, dt *= 1.1/dt *= 0.8 is a BinaryOperator Variable that gets nested 
> deeper 
>     and deeper every time step
> 
>   Diff[0].value short circuits that
> 
> - Your problem is completely linear, so sweeps aren't necessary at this point
> 
> - This equation is fully implicit, so there's no need to start with such a 
> tiny initial time step
> 
> - Jon
> 
>> On Apr 19, 2019, at 2:42 PM, Clara Maurel <cmau...@mit.edu> wrote:
>> 
>> Hello everyone,
>> 
>> I apologize in advance for this very basic question…
>> I am trying to solve a 1D diffusion problem where I have a cooling planet 
>> (core+mantle) with an initial temperature profile and a diffusion 
>> coefficient that takes different values in the core and in the mantle. I 
>> want a fixed boundary condition at the surface (T = 200 K) and a zero 
>> gradient at the center of the body, but the temperature at the center (left 
>> of the mesh) is not fixed and should cool.
>> When I run the script, the whole profile immediately goes down to zero 
>> (except the end right of the mesh) and diffuses from there. I must be doing 
>> something wrong with the left boundary condition but I can’t figure out what.
>> 
>> Could someone help me to find out what I missed? Any hint would be greatly 
>> appreciated!
>> 
>> Thank you in advance for your help!
>> Clara
>> 
>> Here is my simple script:
>> 
>> from datetime import datetime
>> startTime = datetime.now()
>> import numpy as np
>> import scipy
>> from fipy import *
>> from fipy.solvers.pysparse import LinearLUSolver as Solver
>> from sympy import *
>> from scipy import interpolate
>> 
>> def Get_closest_id(L,value):
>>    return list(L).index(min(L, key=lambda x:abs(x-value)))
>> 
>> #------------------------------------#
>> # DIFFUSION EQUATION: INITIALIZATION #
>> #------------------------------------#
>> 
>> ## Dimensions (km)
>> R_body = 200.0
>> R_core = 50.0
>> 
>> ## Temperatures (K)
>> T_core = 1200.0
>> T_surf = 200.0
>> 
>> ## Mesh
>> nr = 1000
>> dr = R_body / nr
>> mesh = Grid1D(nx=nr, dx=dr)
>> 
>> ## Variable
>> T_var = CellVariable(name="T", mesh=mesh, hasOld=True)
>> 
>> ## Initial temperature profile
>> slope = (T_core-T_surf)/(R_core-R_body)
>> intercept = T_core-slope*R_core
>> T_var[:] = np.array([T_core]*int(R_core/dr) + 
>> list(slope*np.arange(R_core+dr, R_body+dr, dr)+intercept))
>> 
>> ## Initial conditions (fixed surface value, null gradient at the center of 
>> the core)
>> T_var.constrain(T_surf, mesh.facesRight)
>> T_var.faceGrad.constrain(0, where=mesh.facesLeft)
>> 
>> ## Diffusion coefficient (different in core and mantle, in km2 My-1)
>> Diff = FaceVariable(mesh=mesh)
>> X = mesh.faceCenters[0]
>> Diff.setValue(150.0, where=(R_core >= X))
>> Diff.setValue(15.0, where=(R_core < X) & (R_body >= X))
>> 
>> ## Equation
>> eq = TransientTerm(coeff=1.) == DiffusionTerm(Diff)
>> 
>> if __name__ == "__main__":
>>    viewer = Viewer(vars=(T_var),ymin=0,ymax=1400)
>>    viewer.plot()
>> 
>> if __name__ == '__main__':
>>    raw_input("Press <return> to proceed...")
>> 
>> ## Time and integration parameters (time in My; 3.154e13 = 1 My in s)
>> time = 0.0
>> duration = 1000.0
>> dt = 0.9*dr**2/(2.0*Diff[0])
>> 
>> total_sweeps = 4
>> tolerance = 1.0e-10
>> 
>> solver = Solver()
>> 
>> #-------------------------------#
>> # DIFFUSION EQUATION: MAIN LOOP #
>> #-------------------------------#
>> 
>> while time < duration:
>> 
>>    res0 = eq.sweep(T_var, dt=dt, solver=solver)
>> 
>>    for sweeps in range(total_sweeps):
>>        res = eq.sweep(T_var, dt=dt, solver=solver)
>> 
>>    if res < res0 * tolerance:
>>        time += dt
>>        dt *= 1.1
>>        T_var.updateOld()
>>        print dt, res
>>        if __name__ == '__main__':
>>            viewer.plot()
>> 
>>    else:
>>        dt *= 0.8
>>        T_var[:] = T_var.old
>>        print "warning " + str(res)
>> 
>> print datetime.now() - startTime
>> 
>> if __name__ == '__main__':
>>    raw_input("Press <return> to proceed...")
>> 
>> 
>> _______________________________________________
>> fipy mailing list
>> fipy@nist.gov
>> http://www.ctcms.nist.gov/fipy
>> [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]
> 
> 
> _______________________________________________
> fipy mailing list
> fipy@nist.gov
> http://www.ctcms.nist.gov/fipy
>  [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]


_______________________________________________
fipy mailing list
fipy@nist.gov
http://www.ctcms.nist.gov/fipy
  [ NIST internal ONLY: https://email.nist.gov/mailman/listinfo/fipy ]

Reply via email to