Skip to content

Commit

Permalink
add source terms based on input soundings (erf-model#1755)
Browse files Browse the repository at this point in the history
* add source terms based on input soundings

* update to input sounding changes and add docs
  • Loading branch information
asalmgren authored Aug 23, 2024
1 parent b8fd471 commit 02c12ed
Show file tree
Hide file tree
Showing 17 changed files with 284 additions and 154 deletions.
2 changes: 1 addition & 1 deletion CMake/BuildERFExe.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ function(build_erf_lib erf_lib_name)
${SRC_DIR}/IO/writeJobInfo.cpp
${SRC_DIR}/IO/console_io.cpp
${SRC_DIR}/SourceTerms/ERF_ApplySpongeZoneBCs.cpp
${SRC_DIR}/SourceTerms/ERF_ApplySpongeZoneBCs_ReadFromFile.cpp
${SRC_DIR}/SourceTerms/ERF_ApplySpongeZoneBCs_ReadFromFile.cpp
${SRC_DIR}/SourceTerms/ERF_make_buoyancy.cpp
${SRC_DIR}/SourceTerms/ERF_add_thin_body_sources.cpp
${SRC_DIR}/SourceTerms/ERF_make_mom_sources.cpp
Expand Down
110 changes: 68 additions & 42 deletions Docs/sphinx_doc/Inputs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -919,46 +919,65 @@ Forcing Terms
List of Parameters
------------------

+----------------------------------+-------------------+-------------------+-------------+
| Parameter | Definition | Acceptable | Default |
| | | Values | |
+==================================+===================+===================+=============+
| **erf.abl_driver_type** | Type of external | None, | None |
| | forcing term | PressureGradient | |
| | | GeostrophicWind | |
+----------------------------------+-------------------+-------------------+-------------+
| **erf.abl_pressure_grad** | Pressure gradient | 3 Reals | (0.,0.,0.) |
| | forcing term | | |
| | (only if | | |
| | abl.driver_type = | | |
| | PressureGradient) | | |
+----------------------------------+-------------------+-------------------+-------------+
| **erf.abl_geo_wind** | Geostrophic | 3 Reals | (0.,0.,0.) |
| | forcing term | | |
| | (only if | | |
| | abl.driver_type = | | |
| | GeostrophicWind) | | |
+----------------------------------+-------------------+-------------------+-------------+
| **erf.abl_geo_wind_table** | Path to text file | String | None |
| | containing a | | |
| | geostrophic wind | | |
| | profile | | |
| | (with z, Ug, and | | |
| | Vg whtiespace | | |
| | delimited | | |
| | columns) | | |
+----------------------------------+-------------------+-------------------+-------------+
| **erf.use_gravity** | Include gravity | true / false | false |
| | in momentum | | |
| | update? If true, | | |
| | there is buoyancy | | |
+----------------------------------+-------------------+-------------------+-------------+
| **erf.use_coriolis** | Include Coriolis | true / false | false |
| | forcing | | |
+----------------------------------+-------------------+-------------------+-------------+
| **erf.use_rayleigh_damping** | Include explicit | true / false | false |
| | Rayleigh damping | | |
+----------------------------------+-------------------+-------------------+-------------+
+-------------------------------------+------------------------+-------------------+---------------------+
| Parameter | Definition | Acceptable | Default |
| | | Values | |
+=====================================+========================+===================+=====================+
| **erf.abl_driver_type** | Type of external | None, | None |
| | forcing term | PressureGradient | |
| | | GeostrophicWind | |
+-------------------------------------+------------------------+-------------------+---------------------+
| **erf.abl_pressure_grad** | Pressure gradient | 3 Reals | (0.,0.,0.) |
| | forcing term | | |
| | (only if | | |
| | abl.driver_type = | | |
| | PressureGradient) | | |
+-------------------------------------+------------------------+-------------------+---------------------+
| **erf.abl_geo_wind** | Geostrophic | 3 Reals | (0.,0.,0.) |
| | forcing term | | |
| | (only if | | |
| | abl.driver_type = | | |
| | GeostrophicWind) | | |
+-------------------------------------+------------------------+-------------------+---------------------+
| **erf.abl_geo_wind_table** | Path to text file | String | None |
| | containing a | | |
| | geostrophic wind | | |
| | profile | | |
| | (with z, Ug, and | | |
| | Vg whtiespace | | |
| | delimited | | |
| | columns) | | |
+-------------------------------------+------------------------+-------------------+---------------------+
| **erf.use_gravity** | Include gravity | true / false | false |
| | in momentum | | |
| | update? If true, | | |
| | there is buoyancy | | |
+-------------------------------------+------------------------+-------------------+---------------------+
| **erf.use_coriolis** | Include Coriolis | true / false | false |
| | forcing | | |
+-------------------------------------+------------------------+-------------------+---------------------+
| **erf.use_rayleigh_damping** | Include explicit | true / false | false |
| | Rayleigh damping | | |
+-------------------------------------+------------------------+-------------------+---------------------+
| **erf.nudging_from_input_sounding** | Include explicit | true / false | false |
| | Rayleigh damping | | |
+-------------------------------------+------------------------+-------------------+---------------------+
| **erf.input_sounding_file** | Name(s) of the | String(s) | input_sounding_file |
| | input sounding file(s) | | |
+-------------------------------------+------------------------+-------------------+---------------------+
| **erf.input_sounding_time** | Time(s) of the | Real(s) | false |
| | input sounding file(s) | | |
+-------------------------------------+------------------------+-------------------+---------------------+
| **erf.tau_nudging** | Time scale for | Real | 5.0 |
| | nudging | | |
+-------------------------------------+------------------------+-------------------+---------------------+

If ``erf.nudging_from_input_sounding`` is true, it is expected that at least one input sounding
file is available. If there is only one, and no specification of time is made, it is assumed that
the one file corresponds to time = 0.0. If the final time supplied in
``input_*_sounding_*_time`` is less than the final time in the calculation, the final sounding supplied
in ``input_*_sounding_*_file`` will be used for all times later than the final value in
in ``input_*_sounding_*_time``.

In addition, custom forcings or tendencies may be defined on a problem-specific
basis. This affords additional flexibility in defining the RHS source term as
Expand Down Expand Up @@ -1015,9 +1034,16 @@ ERF can be initialized in different ways. These are listed below:
- Custom initialization:
Several problems under **Exec** are initialized in a custom manner. The state and velocity components are specific to the problem. These problems are meant for demonstration and do not include any terrain or map scale factors.
- Initialization using a NetCDF file:
Problems in ERF can be initialized using a NetCDF file containing the mesoscale data. The state and velocity components of the ERF domain are ingested from the mesoscale data. This is a more realistic problem with real atmospheric data used for initialization. The typical filename used for initialization is ``wrfinput_d01``, which is the outcome of running ``ideal.exe`` or ``real.exe`` of the WPS/WRF system. These problems are run with both terrain and map scale factors.
Problems in ERF can be initialized using a NetCDF file containing the mesoscale data.
The state and velocity components of the ERF domain are ingested from the mesoscale data.
This is a more realistic problem with real atmospheric data used for initialization.
The typical filename used for initialization is ``wrfinput_d01``, which is the outcome of running ``ideal.exe`` or ``real.exe`` of the WPS/WRF system.
These problems are run with both terrain and map scale factors.
- Initialization using an ``input_sounding`` file:
Problems in ERF can be initialized using an ``input_sounding`` file containing the vertical profile. This file has the same format as used by ``ideal.exe`` executable in WRF. Using this option for initialization, running ``ideal.exe`` and reading from the resulting ``wrfinput_d01`` file are not needed. This option is used for initializing ERF domain to a horizontally homogeneous mesoscale state and does not include terrain or map scale factors.
Problems in ERF can be initialized using an ``input_sounding`` file containing the vertical profile.
This file has the same format as used by ``ideal.exe`` executable in WRF.
Using this option for initialization, running ``ideal.exe`` and reading from the resulting ``wrfinput_d01`` file are not needed.
This option is used for initializing ERF domain to a horizontally homogeneous mesoscale state and does not include terrain or map scale factors.

In addition, there is a run-time option to project the initial velocity field to make it divergence-free. To take
advantage of this option, the code must be built with ``USE_POISSON_SOLVE = TRUE`` in the GNUmakefile if using gmake, or with
Expand Down
6 changes: 6 additions & 0 deletions Source/DataStructs/DataStruct.H
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ struct SolverChoice {
pp.query("add_custom_geostrophic_profile", custom_geostrophic_profile);
pp.query("custom_forcing_uses_primitive_vars", custom_forcing_prim_vars);

pp.query("nudging_from_input_sounding", nudging_from_input_sounding);

have_geo_wind_profile = (!abl_geo_wind_table.empty() || custom_geostrophic_profile);
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(!(!abl_geo_wind_table.empty() && custom_geostrophic_profile),
"Should not have both abl_geo_wind_table and custom_geostrophic_profile set.");
Expand Down Expand Up @@ -532,6 +534,10 @@ struct SolverChoice {
bool custom_geostrophic_profile = false;
bool custom_forcing_prim_vars = false;

// Do we use source terms to nudge the solution towards
// the time-varying data provided in input sounding files?
bool nudging_from_input_sounding = false;

// User specified MOST BC type
bool use_explicit_most = false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <AMReX_Gpu.H>
#include <AMReX_Geometry.H>

#include <EOS.H>
#include <ERF_Constants.H>
#include <Interpolation_1D.H>

Expand All @@ -19,10 +20,45 @@
*/
struct InputSoundingData {
public:
InputSoundingData () {}
InputSoundingData ()
{
amrex::ParmParse pp("erf");
pp.query("tau_nudging", tau_nudging);

// Read in input_sounding filename
n_sounding_files = pp.countval("input_sounding_file");
if (n_sounding_files > 0) {
input_sounding_file.resize(n_sounding_files);
pp.queryarr("input_sounding_file", input_sounding_file, 0, n_sounding_files);
} else {
n_sounding_files = 1;
input_sounding_file.resize(n_sounding_files);
input_sounding_file[0] = "input_sounding";
}

// Read in input_sounding times
n_sounding_times = pp.countval("input_sounding_time");

if (n_sounding_times > 0) {
input_sounding_time.resize(n_sounding_times);
pp.queryarr("input_sounding_time", input_sounding_time, 0, n_sounding_times);
} else {
n_sounding_times = 1;
input_sounding_time.resize(n_sounding_times);
input_sounding_time[0] = 0.0;
}

void resize_arrays (int nt) {
ntimes = nt;
// If we have more files than times or times than files we just use the minimum
int n = std::min(n_sounding_times, n_sounding_files);
n_sounding_files = n;
n_sounding_times = n;
input_sounding_file.resize(n);
input_sounding_time.resize(n);
}

void resize_arrays ()
{
ntimes = n_sounding_files;

z_inp_sound.resize(ntimes);
theta_inp_sound.resize(ntimes);
Expand All @@ -37,8 +73,7 @@ public:
V_inp_sound_d.resize(ntimes);
}

void read_from_file (const std::string input_sounding_file,
const amrex::Geometry &geom,
void read_from_file (const amrex::Geometry &geom,
const amrex::Vector<amrex::Real>& zlevels_stag,
int itime)
{
Expand All @@ -58,8 +93,8 @@ public:
V_inp_sound[itime].resize(Nz+2);

// Read the input_sounding file
amrex::Print() << "input_sounding file location : " << input_sounding_file << std::endl;
std::ifstream input_sounding_reader(input_sounding_file);
amrex::Print() << "input_sounding file location : " << input_sounding_file[itime] << std::endl;
std::ifstream input_sounding_reader(input_sounding_file[itime]);
if(!input_sounding_reader.is_open()) {
amrex::Error("Error opening the input_sounding file\n");
}
Expand Down Expand Up @@ -263,6 +298,13 @@ public:
// Members
int ntimes;

amrex::Real tau_nudging = 5.0; // time scale used for nudging

amrex::Vector<std::string> input_sounding_file = {};
amrex::Vector<amrex::Real> input_sounding_time = {};
int n_sounding_files = 0;
int n_sounding_times = 0;

// - read from file
amrex::Real press_ref_inp_sound, theta_ref_inp_sound, qv_ref_inp_sound; // input

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,14 @@
*/
struct InputSpongeData {
public:
InputSpongeData () {}
InputSpongeData ()
{
// Text input_sounding file
amrex::ParmParse pp("erf");
pp.query("input_sponge_file", input_sponge_file);
}

void read_from_file (const std::string input_sponge_file,
const amrex::Geometry &geom,
void read_from_file (const amrex::Geometry &geom,
const amrex::Vector<amrex::Real>& zlevels_stag)
{
const int klo = 0;
Expand Down Expand Up @@ -103,6 +107,9 @@ public:
}

// Members

std::string input_sponge_file = "input_sponge_file.txt";

// - read from file
amrex::Vector<amrex::Real> z_inp_sponge, U_inp_sponge, V_inp_sponge;
};
Expand Down
2 changes: 2 additions & 0 deletions Source/DataStructs/Make.package
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
CEXE_headers += DataStruct.H
CEXE_headers += DiffStruct.H
CEXE_headers += AdvStruct.H
CEXE_headers += InputSoundingData.H
CEXE_headers += InputSpongeData.H
CEXE_headers += SpongeStruct.H
CEXE_headers += TurbStruct.H
CEXE_headers += TurbPertStruct.H
9 changes: 0 additions & 9 deletions Source/ERF.H
Original file line number Diff line number Diff line change
Expand Up @@ -946,15 +946,6 @@ private:
int real_width{0};
int real_set_width{0};

// Text input_sounding file
static amrex::Vector<std::string> input_sounding_file;
static amrex::Vector<amrex::Real> input_sounding_time;
int n_sounding_files = 1;
int n_sounding_times = 1;

// Text input_sponge file
static std::string input_sponge_file;

// Flag to trigger initialization from input_sounding like WRF's ideal.exe
// used with init_type == "input_sounding"
static bool init_sounding_ideal;
Expand Down
Loading

0 comments on commit 02c12ed

Please sign in to comment.