Peano
Loading...
Searching...
No Matches
airglow-chemistry.py
Go to the documentation of this file.
1import sys
2import os
3
4import exahype2
5
6sys.path.insert(0, os.path.abspath(".."))
7import GravityWaves
8from AirglowPDE import (
9 get_flux,
10 get_max_eigenvalue,
11 get_source_term,
12 get_initial_tendency_postprocessing,
13)
14from AirglowInitialization import (
15 get_initial_steady_state_for_airglow,
16 get_steady_state_for_ozone_MSISE,
17)
18
19"""
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/
23
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().
32"""
33
34if __name__ == "__main__":
35 parser = exahype2.ArgumentParser(
36 "ExaHyPE 2 Gravity Waves Airglow Chemistry Argument Parser"
37 )
38 parser.set_defaults(min_depth=5, degrees_of_freedom=16, end_time=500)
39 parser.add_argument(
40 "-ec",
41 "--einstein-coefficients",
42 choices=GravityWaves.EINSTEIN_COEFFICIENTS,
43 default="goldman",
44 help="|".join(GravityWaves.EINSTEIN_COEFFICIENTS),
45 )
46 parser.add_argument(
47 "-csv",
48 "--csv-file-path",
49 default="./OH_and_OI_airglow_layer_modulation_model.csv",
50 type=str,
51 help="Path to CSV file for use as initial conditions for this project.",
52 )
53 args = parser.parse_args()
54
55 size = [220e3, 220e3, 220e3]
56
57 initial_conditions = (
59 csv_file_path=args.csv_file_path,
60 initialize_density=False,
61 initialize_hydrogen=True,
62 )
63 + """
64
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;
74
75 """
76 + get_steady_state_for_ozone_MSISE(csv_file_path=args.csv_file_path)
77 + """
78
79 """
80 + get_initial_steady_state_for_airglow()
81 + """
82
83 // initialize remaining coupling variables for advection
84 Q[Shortcuts::u] = HORIZONTAL_WINDSPEED;
85 Q[Shortcuts::v] = 0.0;
86 #if DIMENSIONS == 3
87 Q[Shortcuts::w] = 0.0;
88 #endif"""
89 )
90
91 boundary_conditions = """
92 // normal == 0 => left
93 // normal == 1 => bottom
94 // normal == 2 => right
95 // normal == 3 => top
96
97 for (int unknown = 0; unknown < NumberOfUnknowns + NumberOfAuxiliaryVariables; ++unknown) {
98 Qoutside[unknown] = Qinside[unknown];
99 }
100
101 if (normal == 1) {
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];
106 #if DIMENSIONS == 3
107 Qoutside[Shortcuts::w] = Qinside[Shortcuts::w];
108 #endif
109 }"""
110
111 max_h = 1.1 * min(size) / (3.0**args.min_depth)
112 min_h = max_h * 3.0 ** (-args.amr_levels)
113
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")
119
120 # ALWAYS last auxiliary variable
121 auxiliary_list += ["dO3dt0"]
122
123 for i in range(0, 10):
124 unknowns_list.append("OH" + str(i))
125
126 from collections import OrderedDict
127
128 # order of parameters is VERY important here due to postprocessing
129 # relying on the order of parameters to stay consistent
130
131 chemical_unknowns = OrderedDict()
132 chemical_auxiliary_variables = OrderedDict()
133
134 for var in unknowns_list:
135 chemical_unknowns[var] = 1
136
137 for var in auxiliary_list:
138 chemical_auxiliary_variables[var] = 1
139
140 riemann_solver = exahype2.solvers.fv.godunov.GlobalAdaptiveTimeStep(
141 name="FVSolver",
142 patch_size=args.degrees_of_freedom,
143 unknowns=chemical_unknowns,
144 auxiliary_variables=chemical_auxiliary_variables,
145 min_volume_h=min_h,
146 max_volume_h=max_h,
147 time_step_relaxation=0.5,
148 )
149
150 riemann_solver.set_implementation(
151 initial_conditions=initial_conditions,
152 boundary_conditions=boundary_conditions,
153 source_term=get_source_term(),
154 flux=get_flux(),
155 max_eigenvalue=get_max_eigenvalue(),
156 )
157
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')
160
161 # initialize initial tendency
162 riemann_solver.postprocess_updated_patch = get_initial_tendency_postprocessing()
163
164 riemann_solver.add_solver_constants(GravityWaves.CSV_CONSTANTS)
165
167 atmospheric_solver=None,
168 diffusion_solver=None,
169 chemical_solver=riemann_solver,
170 size=size[: args.dimensions],
171 arguments=args,
172 )
173
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"""
178 )
179 project.output.makefile.add_CXX_flag(
180 f"""-DEINSTEIN_COEFFICIENTS=applications::exahype2::GravityWaves::Airglow::ProductionRates::{args.einstein_coefficients}EinsteinCoefficients"""
181 )
182
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)