Overshoots and undershoots when using INSTemperature kernel

55 views
Skip to first unread message

Alvin Lee

unread,
May 3, 2020, 8:20:44 PM5/3/20
to moltres-users
Hi,

I am currently solving for the temperature solution of a molten salt reactor and have encountered overshoots and undershoots when using the INSTemperature kernel.

Because the problem size is large (1/8th core in 3D) and there are multiple separate effects to be investigated, I have adopted the following approach:

1) Solve for the steady-state neutron fluxes using Moltres with simple advection (velocity only in z-direction) and with a 'coarse' mesh.
2) Solve for the steady-state INS velocity field using Moltres (actually using MOOSE - INSMass, INSMomentum, etc) with a 'fine' mesh.
3) Restart from the steady-state INS solution file and copy/interpolate the neutron fluxes solution from (1) as AuxVariables, solve for the INS-velocity-field-advected Temperature variable.
(Whereby the temperature is 'generated' by the neutron fluxes and advects according to the INS velocity field. Temperature is the only variable to be solved here, the INS velocity field and neutron fluxes are unchanging.)

In this approach, (3) would give the approximate INS temperature solution.

The difficulty I have right now is that the temperature that is being solved with the INSTemeprature kernel produces spurious overshoots and undershoots.
I understand that overshoots and undershoots for scalar advection-diffusion is a well known challenging problem but I'm wondering if anyone has encountered similar problems and what are some strategies to minimize it.

Things I have already tried:
1. Reduce the mesh size - This reduces the overshoot/undershoot problem slightly but is rather expensive. I have already reduced the mesh size to the point that I am reaching the 'reasonable' computational limit.
2. Tried different boundary conditions. (TemperatureOutflowBC, VelocityFunctionTemperatureOutflowBC, DirichletBC) - All of them are somehow worse than not specifying a BC at the outflow. Besides, the overshoot/undershoot occurs within the reactor (away from boundaries) as well so I am doubtful that the boundary conditions are strong contributors to the overshoot/undershoot.
3. Naively modified the ConservativeAdvection kernel to accept velocity field (instead of a simple advection) so that I can use its full upwinding feature. - Doesn't work, produced severe overshoot/undershoot even in one timestep.

What I currently have in mind to try/ have not tried:
1. Up till now, I have been solving for the INS velocity field (2) by using First Order Lagrange variables. This might have caused the velocity field to NOT be divergence free. Perhaps I should have solved the INS velocity field by using Second Order Lagrange variables instead? This requires changing the mesh from HEX8 to HEX20 or even HEX27.
     - Should I use HEX20 or HEX27?
     - Do I set second order for only velocity or for both velocity and pressure?
     - When I move on to (3) does temperature have to be in Second Order Lagrange as well for this to work? 
2. Look into other modules within MOOSE and see if there are any scalar advection kernels that already employs some sort of numerical stabilization. Then try to replace INSTemperature with them.
     - I found INSADTemperatureAdvection but it only takes in Lagrange_Vec. How do I convert a set of scalar velocities (ux, uy, uz) into one vector object in MOOSE?
     - Perhaps something from Porous Flow?

I'm curious to know if you have encountered similar issues and your thoughts on my approaches. Do let me know and I thank you in advance for reading my long post!

 

Best Regards,
Alvin Lee
Graduate Student
Nuclear, Plasma, and Radiological Engineering
University of Illinois at Urbana-Champaign

Sun Myung Park

unread,
May 5, 2020, 11:42:14 AM5/5/20
to moltres-users
Hi Alvin,

I agree that using a finer mesh size might help. Perhaps it is the main source of the overshoots and undershoots you're observing in your results as moltres cannot resolve the temperature field accurately. 

Your velocity field should be divergence-free because the INSMass kernel explicitly handles that constraint. I've had good results with the velocity and pressure all in first-order with "integrate_p_by_parts=true", and SUPG/PSPG stabilizations activated. Without the PSPG stabilization, you would need second order velocity variables but I recommend using PSPG for your large 3D model. I can't comment on your velocity field results because I haven't seen them but I do believe that the Navier-Stokes module is heavily tested and verified, so I don't think you have to change the source code. 

None of the advection kernels nor the upwind schemes require temperature to be in second-order. I don't think you have to import advection kernels from other modules and they may not work because they were tailor-made to suit their own needs. 

Personally, I've found that most of the issues I faced were due to my own implementation errors/typos in my input files. I recommend double-checking your input file. I can help you review it if you don't mind sharing it.

Best,
Sun Myung

Sun Myung Park

unread,
May 5, 2020, 11:46:01 AM5/5/20
to moltres-users
In the first line, I mean in the context of your mesh. Moltres is generally accurate if you provide the right mesh and settings. Just wanted to clarify that for random people coming on here and reading this without proper context.

Alvin Lee

unread,
May 5, 2020, 12:49:19 PM5/5/20
to moltres-users
Hi Sun Myung,

Thanks!

Totally agree that the overshoots and undershoots are likely caused by the mesh not being fine enough.
I've experimented a bit with a simple toy model with different mesh sizes and it appears that overshoots and undershoots never really go away but simply becomes smaller to negligible as the mesh size decreases.
For instance, while the lowest temperature in the toy problem should be 900K (from the initial and boundary conditions), the first timestep would produce a minimum temperature of 899.999... K, with the number of trailing nines increasing with decreasing mesh size.
At some point, the overshoot and undershoot error becomes negligible and all's good.

Nonetheless, the difficulty I'm facing is that the problem domain is rather large and using even finer mesh is not an option anymore.
In that case, I'm trying to see if there are any other ways to reduce the overshoot/undershoot, such as a scalar advection kernel that has stabilization. 

I have been using first order velocity and pressure variables with SUPG and PSPG activated and with alphas of at least 1/3. I am, however, using "integrate_p_by_parts=false" as I found that using the "true" option somehow broke my simulation.

Right now, I am re-solving the velocity and pressure as second order variables and will be using that for the temperature advection solve. This is to see if the discontinuity in the spatial derivatives might be contributing to the overshoot/undershoot problem.
I'll post here again on whether the using second order velocity and pressure helps!

Alexander Lindsay

unread,
May 5, 2020, 1:17:14 PM5/5/20
to moltres-users
What is your Peclet number?

--
You received this message because you are subscribed to the Google Groups "moltres-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to moltres-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/moltres-users/79680f4f-fefa-46bd-a01c-fe4ea76e9b1d%40googlegroups.com.

Alvin Lee

unread,
May 5, 2020, 5:17:49 PM5/5/20
to moltres-users
Hi Alex, I did a back-of-envelope calculation and the Peclet number is about 1010.
To unsubscribe from this group and stop receiving emails from it, send an email to moltre...@googlegroups.com.

Alexander Lindsay

unread,
May 5, 2020, 7:15:46 PM5/5/20
to moltres-users
You will definitely need stabilization for the temperature field then.

It sounds like you are using the regular INS kernels, which is fine, but I'm not doing any more development on them. I've been focusing all development on the INSAD variant, which you've referenced. You can look at github.com/idaholab/moose/tree/next/modules/navier_stokes/test/tests/ins/lid_driven/ad_lid_driven.i for how to setup the INSAD variant. It exactly parallels the regular lid_driven example and gives the exact same results.

You can also look at github.com/idaholab/moose/tree/next/modules/navier_stokes/src/kernels/INSADTemperatureAdvection.C (which class you mentioned). In addition to the standard Galerkin term, that file also has the INSADTemperatureAdvectionSUPG kernel, which adds the stabilizing Petrov-Galerkin term. Note that you should get stabilization just by throwing in that kernel, but the method will be inconsistent if you are only including this advection term in the strong residual. Inconsistent here means that the finite element method will not converge to the true solution at the optimal rate when you refine the mesh (although it will converge).


To unsubscribe from this group and stop receiving emails from it, send an email to moltres-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/moltres-users/2805472c-e55a-4644-9550-1779c896729c%40googlegroups.com.

Alvin Lee

unread,
May 6, 2020, 2:52:08 AM5/6/20
to moltres-users
Thanks! I'm currently trying both the INSAD kernel with SUPG (first order velocity & pressures), as well as second order velocity & pressure using INS kernels without SUPG. I'll post back here on what I find!

Alexander Lindsay

unread,
May 6, 2020, 7:36:15 PM5/6/20
to moltres-users
If you're doing first order you need to make sure that you're adding INSADMassPSPG or else the discretization is unstable

To unsubscribe from this group and stop receiving emails from it, send an email to moltres-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/moltres-users/daa6bd9f-d9bb-4693-955f-e6b0dbf3c6a1%40googlegroups.com.

Alvin Lee

unread,
May 7, 2020, 5:13:51 AM5/7/20
to moltres-users
Hi Alex, got it!

Actually, I've already solved the steady-state velocity and pressure field previously using INSMass with PSPG and INSMomentum with SUPG, so I'm now only trying to solve for the temperature which advects with the solved velocity field and is 'generated' by the group1 and group2 neutron fluxes from another solution file.

One issue that I've encountered with the INSADTemperatureAdvectionSUPG kernel is that it only takes in the coupled variable of type Lagrange_vec which means I have to somehow reassemble the previously solved ux, uy and uz scalar velocity components into a coupled variable. For this, I have used SolutionUserObject, SolutionFunction and VectorFunctionIC but this method is somewhat memory intensive.
In addition, I have also tried the more straightforward "initial_from_file_var" method to see if simulations can be restarted but that action (CopyNodalVarsAction) doesn't seem to support coupled variables and appears to read the Lagrange_vec variable, which I had named "vel", as its individual scalar components, "vel_x", "vel_y" and "vel_z".

I think the above is not a problem with the INSAD kernels per se, but rather a lack of infrastructure that supports the Lagrange_vec or similar coupled variables. For instance, we may need to have an upgraded CopyNodalVarsAction to be able to copy coupled variables, and/or simply have an AuxKernel that assembles a Lagrange_vec from several Lagrange variables, sort of like an inverse of VectorVariableComponentAux.

Nonetheless, if you are aware a better method to restart Lagrange_vec or reassemble it from a set of scalar components, do let me know! Thanks!

Alexander Lindsay

unread,
May 7, 2020, 12:07:01 PM5/7/20
to moltres-users
It would be straightforward to write that VectorAuxKernel that generates a vector variable from standard field variables. Have you ever done any MOOSE/Moltres development?

To unsubscribe from this group and stop receiving emails from it, send an email to moltres-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/moltres-users/e4c3facd-0b79-4508-a55d-fc182de9cd23%40googlegroups.com.

Alvin Lee

unread,
May 7, 2020, 4:38:16 PM5/7/20
to moltres-users

 Hi Alex, I haven't done much MOOSE/Moltres development other than look inside the .C and .h files to learn what they exactly do behind the scenes. Nonetheless, I'll try to get started and see what I can come up with. Thanks!



Best Regards,
Alvin Lee
Graduate Student
Nuclear, Plasma, and Radiological Engineering
University of Illinois at Urbana-Champaign


Alexander Lindsay

unread,
May 7, 2020, 4:53:58 PM5/7/20
to moltres-users
If you're successful, that is an object we would want in the MOOSE framework, so you could have an opportunity to submit your first MOOSE pull request!

To unsubscribe from this group and stop receiving emails from it, send an email to moltres-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/moltres-users/4b671815-dd35-480a-bb58-b6c9dd62d376%40googlegroups.com.

Alvin Lee

unread,
May 27, 2020, 8:57:17 PM5/27/20
to moltres-users
Hi all,

I figured that I likely won't have enough time right now to adequately work on a better solution so here's a quick update on my experiences regarding this issue as well as some pointers for future users who may encounter the same problem:

1) Stabilization using the INSADTemeratureAdvectionSUPG kernel adequately resolved the overshoot and undershoot problem I had. I had also used the INSADTemperatureAdvection kernel for the actual temperature advection, instead of the older INSTemperature kernel. It should be noted that while the INSTemperature kernel contained both temperature advection and diffusion physics, the INSADTemperatureAdvection only contained the temperature advection part and diffusion should be handled separately. For the stabilization constant "tau", one would need to do some trial and error to obtain the minimum value that would still resolve the overshoot and undershoot, in order to avoid introducing too much inaccuracy from the stabilization. Do also note that "tau" should be input as one of the material properties.

2) Regarding restarting a simulation that involved Lagrange_vec coupled variables, one can use the following method:
i. It should be noted that Lagrange_vec variables would be referred to by its components when using SolutionUserObject or the "initial_from_file_var" method (which uses libmesh's copy_nodal_solution). i.e. If the Lagrange_vec in the previous simulation is named "vel", SolutionUserObject or the "initial_from_file_var" method would see it as 3 individual components called "vel_x", "vel_y" and "vel_z". Therefore, to initialize a new Lagrange_vec in the current simulation from the previous simulation, first use SolutionUserObject on each of the individual "vel_x", "vel_y" and "vel_z" components to read their solutions.
ii. Next, set up 3 separate SolutionFunctions which refers to the above 3 SolutionUserObjects.
iii. Finally, use VectorFunctionIC that refers to the above SolutionFunctions to initialize the Lagrange_vec in the current simulation.

An example is shown below:
[UserObjects]
  [./uxs]
    type = SolutionUserObject
    system_variables = vel_x
    mesh = ${out_file}
    timestep = LATEST
    execute_on = initial
  [../]
  [./uys]
    type = SolutionUserObject
    system_variables = vel_y
    mesh = ${out_file}
    timestep = LATEST
    execute_on = initial
  [../]
  [./uzs]
    type = SolutionUserObject
    system_variables = vel_z
    mesh = ${out_file}
    timestep = LATEST
    execute_on = initial
  [../]
[]

[Functions]
  [./uxf]
    type = SolutionFunction
    solution = uxs
  [../]
  [./uyf]
    type = SolutionFunction
    solution = uys
  [../]
  [./uzf]
    type = SolutionFunction
    solution = uzs
  [../]
[]

[AuxVariables]
  [./vel]
    family = LAGRANGE_VEC
    order = FIRST
    #scaling = 1e-4
  [../]
[]

[ICs]
  [./vel_ic]
    type = VectorFunctionIC
    variable = vel
    function_x = uxf
    function_y = uyf
    function_z = uzf
    #block = 'fuel'
  [../]
[]

3) Having an improved CopyNodalVarsAction class that can copy coupled variables would definitely help a lot, especially in terms of memory usage and the initial computational time required to set up the initial conditions. Nonetheless, for now, the above method should suffice (provided that your simulation is small enough that you don't run out of memory).


I hope the above helps!
Reply all
Reply to author
Forward
0 new messages