6sys.path.insert(0, os.path.abspath(
".."))
8from AirglowPDE
import (
12 get_initial_tendency_postprocessing,
14from AirglowInitialization
import (
15 get_initial_steady_state_for_airglow,
16 get_steady_state_for_ozone_MSISE,
20This application demonstrates how to setup a scenario for airglow chemistry.
21It shows steady states for chemicals and needed interpolations for coupling with the stratified atmosphere model.
22Input files can be obtained from https://ccmc.gsfc.nasa.gov/models/NRLMSIS~00/
24The application makes the following assumptions:
25 - The height passed to the initial conditions is in [m];
26 - The number densities in the input file are in [cm^-3];
27 - The temperature in the input file is in [K];
28 - The height in the input file is in [km];
29 - The air density in the input file is in [g/cm^3];
30 - The CSV file uses a delimiter as assigned in get_csv_constants();
31 - The CSV file has values at indices assigned in get_csv_constants().
34if __name__ ==
"__main__":
35 parser = exahype2.ArgumentParser(
36 "ExaHyPE 2 Gravity Waves Airglow Chemistry Argument Parser"
38 parser.set_defaults(min_depth=5, degrees_of_freedom=16, end_time=500)
41 "--einstein-coefficients",
42 choices=GravityWaves.EINSTEIN_COEFFICIENTS,
44 help=
"|".join(GravityWaves.EINSTEIN_COEFFICIENTS),
49 default=
"./OH_and_OI_airglow_layer_modulation_model.csv",
51 help=
"Path to CSV file for use as initial conditions for this project.",
53 args = parser.parse_args()
55 size = [220e3, 220e3, 220e3]
57 initial_conditions = (
59 csv_file_path=args.csv_file_path,
60 initialize_density=
False,
61 initialize_hydrogen=
True,
65 // create steady state in minor species
66 using ProductionRates = applications::exahype2::GravityWaves::Airglow::ProductionRates;
67 const {{COMPUTE_PRECISION}} O = Q[Shortcuts::O];
68 const {{COMPUTE_PRECISION}} O2 = Q[Shortcuts::O2];
69 const {{COMPUTE_PRECISION}} N2 = Q[Shortcuts::N2];
70 const {{COMPUTE_PRECISION}} M = Q[Shortcuts::O] + Q[Shortcuts::O2] + Q[Shortcuts::N2];
71 const {{COMPUTE_PRECISION}} H = Q[Shortcuts::H];
72 const {{COMPUTE_PRECISION}} T = Q[Shortcuts::T];
73 constexpr int BANDWIDTH = EINSTEIN_BANDWIDTH;
76 + get_steady_state_for_ozone_MSISE(csv_file_path=args.csv_file_path)
80 + get_initial_steady_state_for_airglow()
83 // initialize remaining coupling variables for advection
84 Q[Shortcuts::u] = HORIZONTAL_WINDSPEED;
85 Q[Shortcuts::v] = 0.0;
87 Q[Shortcuts::w] = 0.0;
91 boundary_conditions =
"""
92 // normal == 0 => left
93 // normal == 1 => bottom
94 // normal == 2 => right
97 for (int unknown = 0; unknown < NumberOfUnknowns + NumberOfAuxiliaryVariables; ++unknown) {
98 Qoutside[unknown] = Qinside[unknown];
102 // Reflective at bottom to keep atmosphere
103 // from escaping the domain through the Earth's surface
104 Qoutside[Shortcuts::u] = Qinside[Shortcuts::u];
105 Qoutside[Shortcuts::v] = -Qinside[Shortcuts::v];
107 Qoutside[Shortcuts::w] = Qinside[Shortcuts::w];
111 max_h = 1.1 * min(size) / (3.0**args.min_depth)
112 min_h = max_h * 3.0 ** (-args.amr_levels)
114 unknowns_list = [
"O",
"O2",
"N2",
"O3",
"H",
"O2cu",
"OS"]
115 auxiliary_list = [
"u",
"v"]
116 if args.dimensions == 3:
117 auxiliary_list.append(
"w")
118 auxiliary_list.append(
"T")
121 auxiliary_list += [
"dO3dt0"]
123 for i
in range(0, 10):
124 unknowns_list.append(
"OH" + str(i))
126 from collections
import OrderedDict
131 chemical_unknowns = OrderedDict()
132 chemical_auxiliary_variables = OrderedDict()
134 for var
in unknowns_list:
135 chemical_unknowns[var] = 1
137 for var
in auxiliary_list:
138 chemical_auxiliary_variables[var] = 1
140 riemann_solver = exahype2.solvers.fv.godunov.GlobalAdaptiveTimeStep(
142 patch_size=args.degrees_of_freedom,
143 unknowns=chemical_unknowns,
144 auxiliary_variables=chemical_auxiliary_variables,
147 time_step_relaxation=0.5,
150 riemann_solver.set_implementation(
151 initial_conditions=initial_conditions,
152 boundary_conditions=boundary_conditions,
153 source_term=get_source_term(),
155 max_eigenvalue=get_max_eigenvalue(),
158 riemann_solver.add_user_solver_includes(f
"""#include \"../ProductionRates.h\"\n""")
159 riemann_solver.add_user_solver_includes(
'#include "tarch/reader/CSVReader.h"\n')
162 riemann_solver.postprocess_updated_patch = get_initial_tendency_postprocessing()
164 riemann_solver.add_solver_constants(GravityWaves.CSV_CONSTANTS)
167 atmospheric_solver=
None,
168 diffusion_solver=
None,
169 chemical_solver=riemann_solver,
170 size=size[: args.dimensions],
174 project.output.makefile.add_CXX_flag(f
"""-DHORIZONTAL_WINDSPEED=10.5""")
175 project.output.makefile.add_CXX_flag(f
"""-DCHEMISTRY_NUMERICAL_THRESHOLD=1E-5""")
176 project.output.makefile.add_CXX_flag(
177 f
"""-DEINSTEIN_BANDWIDTH=applications::exahype2::GravityWaves::Airglow::ProductionRates::{args.einstein_coefficients.upper()}BANDWIDTH"""
179 project.output.makefile.add_CXX_flag(
180 f
"""-DEINSTEIN_COEFFICIENTS=applications::exahype2::GravityWaves::Airglow::ProductionRates::{args.einstein_coefficients}EinsteinCoefficients"""
183 project.build(make=
True, make_clean_first=
True, throw_away_data_after_build=
True)
get_CSV_initializer(csv_file_path, bool initialize_density, bool initialize_hydrogen)
create_peano_project(atmospheric_solver, diffusion_solver, chemical_solver, size, arguments)