Hello everyone,
Hope you’re doing good. I’m having trouble with boundary temperature model. What I’m doing is mantle convection coupled with core cooling. The core is assumed to be an isothermal heating bath, i.e., we only need to calculate the core temperature (single value, scalar) based on energy balance at core-mantle boundary:
\rho_c C_{p,c} V_c \Delta T = q S \delta t
where \rho_c, C_{p,c}, V_c are core density, specific heat and volume. \Delta T is the temperature change during time interval \delta t. q is heat flux on CMB and S is surface of CMB. All parameters are given or known except heat flux q and \Delta T. Once q is known, temperature change \Delta T is known, and the temperature boundary condition for next step is known, as T_{new} = T_{old} + \Delta T. So basically this is Dirichlet boundary condition but it’s evolving.
How to get q? There are a couple of ways. (1) Adapting dynamic_core.cc where simple conduction heat flux is given in update(), but I realized later that advection also matters at CMB, so dymaic_core may underestimate the heat flux; (2) Making use of Postprocess which prints heat flux at the end of each step; (3) Duplicating functions in Postprocess and adapt them accordingly.
For the 1st way, I have confirmed that the heat flux from my plugin (with adapted dynamic_core inside) is different from that from Postprocess, as expected.
For the 2nd way, by including headers of Postprocess and calling the function aspect::Postprocess::internal::compute_heat_flux_through_boundary_faces(*this), the heat flux can be obtained but it’ still different from Postprocess.
For the last method, funtions from Postprocess are copied to my plugin, including compute_heat_flux_through_boundary_faces() and compute_dirichlet_boundary_heat_flux_solution_vector(). Unfortunately this still gave different heat flux from Postprocess.
There are two more caveats: the heat flux is calculated based on solving (full size?) heat equation on boundary, so this heat flux is accurate, including advection, conduction and more. So I need to get this heat flux. In addition, the Postprocess will be called at the end of each time step, so i have to escape the 1st step (during which initial boundary temperature is known and applied). Starting from 2nd step, I’ll call or use functions from Postprocess in my plugin (my plugin has update() and lives in BoundaryTemperature). I was assuming that the state of the end of n-th step should be the same as that of the beginning of n+1 step. But it turns out that they are different, e.g.,
*** Timestep 561: t=1.3578e+08 years, dt=36490.2 years
Heat flow at CMB = -29128.7, dT = 0.0118575
Solving temperature system... 7 iterations.
...
Postprocessing:
Writing graphical output: laneuville2013/solution/solution-00458
RMS, max velocity: 0.00857 m/year, 0.033 m/year
Temperature min/avg/max: 250 K, 1607 K, 1969 K
Heat fluxes through boundary parts: -2.649e+04 W, 4.442e+05 W
Writing depth average: laneuville2013/depth_average
Compositions min/max/mass: 0.07706/1/8.741e+12 // -9.466e-08/3.513e-06/3.943e+05 // -2.527e-08/9.384e-07/1.053e+05 // -2.226e-07/8.259e-06/9.269e+05 // -1.621e-07/6.017e-06/6.754e+05
*** Timestep 562: t=1.35817e+08 years, dt=36564 years
Heat flow at CMB = -29071, dT = 0.0118579
Solving temperature system... 7 iterations.
Solving peridotite system ... 7 iterations.
Note that temperature boundary will be executed before the solve of the system. I have no idea how to handle this difference, any ideas? Deeply appreciate your time and help!
Thanks,
Mingming