3/initiliaze from mesh#613
Conversation
…er density and pressure from grid variables with names varName_init. fixed_density and isothermal: Added a functionality to read the fixed denstiy or temperature from grid variables with names varName_init
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #613 +/- ##
=======================================
Coverage 56.92% 56.92%
=======================================
Files 97 97
Lines 10092 10120 +28
Branches 1462 1466 +4
=======================================
+ Hits 5745 5761 +16
- Misses 3757 3765 +8
- Partials 590 594 +4 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
mikekryjak
left a comment
There was a problem hiding this comment.
Thanks @malamast, this is really useful work. I left a few comments and suggestions for typo fixes.
Can you also please add a docs section on this on the https://hermes3.readthedocs.io/en/latest/execution.html page as a new subsection called Initialising from known profiles? Let me know if you need any help with this.
| // Try to read the initial field from the mesh | ||
| mesh->get(N, std::string("N") + name + "_init"); // Units: [m^-3/s] | ||
| N /= Nnorm; // Normalization | ||
| } |
There was a problem hiding this comment.
This will cause a bug when evolve_log is true as logN would not be populated, causing an issue here:
hermes-3/src/evolve_density.cxx
Lines 181 to 184 in d362cb4
Here is where logN is calculated:
hermes-3/src/evolve_density.cxx
Lines 71 to 89 in d362cb4
I think all that's needed here is to make sure it's calculated from the grid value:
if (evolve_log && !alloptions["hermes"]["restarting"]) {
logN = log(N);
}
| if (initialize_from_mesh) { | ||
| // Try to read the initial field from the mesh | ||
| mesh->get(P, std::string("P") + name + "_init"); // Units: Pascal [Pa] | ||
| P /= Pnorm; // Normalization |
There was a problem hiding this comment.
See comment https://github.com/boutproject/hermes-3/pull/613/changes#r3569745560. Need to calculate logP if evolve_log is true.
|
|
||
| if (initialize_from_mesh) { | ||
| // Try to read the initial field from the mesh | ||
| mesh->get(N, std::string("N") + name + "_init"); // Units: [m^-3/s] |
There was a problem hiding this comment.
If the variable isn't in the grid, it will be set to zero. This makes it quite annoying if you misspell the variable or forget to put it in and don't check the console dump which shows the warning.
My LLM suggests that this can be overcome because get() gives a return status you can use:
std::string variable = std::string("N") + name + "_init"
if (mesh->get(N, variable) != 0) {
throw BoutException("Could not load '{}' from the mesh", variable);
}
You can see the return status for mesh->get() defined here - if the value isn't found, it will be set to default and it will return 1:
https://github.com/boutproject/BOUT-dev/blob/9eb94c7c9d9539c1e4e60ec84377a48d5ab50b22/src/mesh/mesh.cxx#L231-L236
This needs to be applied to every place a variable is read from the grid.
|
|
||
| if (initialize_from_mesh) { | ||
| // Try to read the initial field from the mesh | ||
| mesh->get(N, std::string("N") + name + "_init"); // Units: [m^-3/s] |
There was a problem hiding this comment.
|
|
||
| if (initialize_from_mesh) { | ||
| // Try to read the initial field from the mesh | ||
| mesh->get(P, std::string("P") + name + "_init"); // Units: Pascal [Pa] |
There was a problem hiding this comment.
| // Initilize the Field3D N from 2D profiles stored in the mesh file. | ||
| initialize_from_mesh = | ||
| n_options["initialize_from_mesh"] | ||
| .doc("Initilize field from 2D profiles stored in the mesh file?") |
There was a problem hiding this comment.
| .doc("Initilize field from 2D profiles stored in the mesh file?") | |
| .doc("Initialize field from 2D profiles stored in the mesh file?") |
| // Initilize the Field3D P from 2D profiles stored in the mesh file. | ||
| initialize_from_mesh = | ||
| p_options["initialize_from_mesh"] | ||
| .doc("Initilize field from 2D profiles stored in the mesh file?") |
There was a problem hiding this comment.
| .doc("Initilize field from 2D profiles stored in the mesh file?") | |
| .doc("Initialize field from 2D profiles stored in the mesh file?") |
| // Initilize the Field3D T from 2D profiles stored in the mesh file. | ||
| initialize_from_mesh = | ||
| options["initialize_from_mesh"] | ||
| .doc("Initilize field from 2D profiles stored in the mesh file?") |
There was a problem hiding this comment.
| .doc("Initilize field from 2D profiles stored in the mesh file?") | |
| .doc("Initialize field from 2D profiles stored in the mesh file?") |
|
|
||
| if (initialize_from_mesh) { | ||
| // Try to read the initial field from the mesh | ||
| mesh->get(N, std::string("N") + name + "_init"); // Units: [m^-3/s] |
There was a problem hiding this comment.
| mesh->get(N, std::string("N") + name + "_init"); // Units: [m^-3/s] | |
| mesh->get(N, std::string("N") + name + "_init"); // Units: [m^-3] |
|
|
||
| if (initialize_from_mesh) { | ||
| // Try to read the initial field from the mesh | ||
| mesh->get(N, std::string("N") + name + "_init"); // Units: [m^-3/s] |
There was a problem hiding this comment.
| mesh->get(N, std::string("N") + name + "_init"); // Units: [m^-3/s] | |
| mesh->get(N, std::string("N") + name + "_init"); // Units: [m^-3] |
Purpose
Added a functionality to initialize number density and pressure from grid variables with names varName_init.
You can set up 2D profiles in the grid e.g. Nd+_init from example from EFIT files (1D omp profiles and no polidal variation) and then in the input file you set:
[Nd+]
initialize_from_mesh = true # Should be in SI units with name: _init
Change Summary
I changed the isothermal component as well. I made the T variable a Field3D var instead of BoutReal so that it can be set up from grid.
Validation
I tested it with my cases for 2D and 3D.
AI Assistance
No.
Documentation
None
Review Notes
None