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 ]

Reply via email to