Peano
Loading...
Searching...
No Matches
GravityWaves.py
Go to the documentation of this file.
1# This file is part of the ExaHyPE2 project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3import peano4
4import exahype2
5from CouplingSynchronization import (
6 setLastSolver,
7 synchronizePatchGravityWaves,
8 coupleTimeStepping,
9)
10
11R = 8.31446261815324 # ideal gas constant in J / (mol * K)
12GRAVITY = 9.8067 # gravitational acceleration in m/s^2
13
14EINSTEIN_COEFFICIENTS = ["goldman", "langhoff", "turnbullLowe"]
15CSV_CONSTANTS = """
16 // CSV constants
17 static const char csvSeparator = ';';
18 static const int csvHeightIndex = 5;
19 static const int csvAtomicOxygenIndex = 8;
20 static const int csvNitrogenIndex = 9;
21 static const int csvMolecularOxygenIndex = 10;
22 static const int csvDensityIndex = 11;
23 static const int csvTemperatureIndex = 12;
24 static const int csvHydrogenIndex = 16;
25 """
26
27
29 csv_file_path, initialize_density: bool, initialize_hydrogen: bool
30):
31 density_interpolation = ""
32 density_csv = ""
33
34 hydrogen_interpolation = ""
35 hydrogen_csv = ""
36
37 if initialize_density:
38 density_interpolation = """// density is in g/cm^3, needs conversion into kg/m^3 = 1000 * g/cm^3
39 Q[Shortcuts::rho] = 1000.0 * interpolateBetweenRows(row, nextRow, csvDensityIndex, x(1));
40 #if !defined(WITH_GPU)
41 assertion1(!std::isnan(Q[Shortcuts::rho]), Q[Shortcuts::rho]);
42 assertion1(Q[Shortcuts::rho] > 0, Q[Shortcuts::rho]);
43 #endif"""
44 density_csv = """// density is in g/cm^3, needs conversion into kg/m^3 = 1000 * g/cm^3
45 Q[Shortcuts::rho] = 1000.0 * tarch::reader::CSVReader::extractFundamentalTypeFromRow<double>(';', csvDensityIndex, row);
46 #if !defined(WITH_GPU)
47 assertion1(!std::isnan(Q[Shortcuts::rho]), Q[Shortcuts::rho]);
48 assertion1(Q[Shortcuts::rho] > 0, Q[Shortcuts::rho]);
49 #endif"""
50
51 if initialize_hydrogen:
52 hydrogen_interpolation = """// populate hydrogen as it is also given in the model
53 Q[Shortcuts::H] = interpolateBetweenRows(row, nextRow, csvHydrogenIndex, x(1));"""
54 hydrogen_csv = """// populate hydrogen as it is also given in the model
55 Q[Shortcuts::H] = tarch::reader::CSVReader::extractFundamentalTypeFromRow<double>(csvSeparator, csvHydrogenIndex, row);"""
56
57 return (
58 """
59 std::fill_n(Q, Shortcuts::NumberOfDistinctVariables, 0.0);
60
61 // initialize CSV reader and skip first line of file, which contains column names
62 static tarch::reader::CSVReader csvReader(\""""
63 + csv_file_path
64 + """\", 1);
65 const int csvNumberOfRows = csvReader.getNumberOfRows();
66
67 // height in CSV is in km, so convert to m
68 const double csvMaxHeight = tarch::reader::CSVReader::extractFundamentalTypeFromRow<double>(csvSeparator, csvHeightIndex, csvReader.getRow(csvNumberOfRows - 1)) * 1000.0;
69
70 // height of x is in m
71 const int rowIndex = tarch::la::round(x(1) / (csvMaxHeight) * (csvNumberOfRows - 1));
72
73 // extract row
74 const std::string row = csvReader.getRow(rowIndex);
75
76 // if not last row, interpolate between rows for stratification in Euler solver
77 const bool interpolate = rowIndex < csvNumberOfRows - 1;
78
79 if (interpolate) {
80 const std::string nextRow = csvReader.getRow(rowIndex + 1);
81
82 auto interpolateBetweenRows = [](const std::string bottomRow, const std::string topRow, const int csvIndex, const double currentHeight) {
83 const auto bottomRowValue = tarch::reader::CSVReader::extractFundamentalTypeFromRow<double>(csvSeparator, csvIndex, bottomRow);
84 const auto topRowValue = tarch::reader::CSVReader::extractFundamentalTypeFromRow<double>(csvSeparator, csvIndex, topRow);
85 const auto topRowHeight = tarch::reader::CSVReader::extractFundamentalTypeFromRow<double>(csvSeparator, csvHeightIndex, topRow) * 1000.0;
86
87 return bottomRowValue + currentHeight * (topRowValue - bottomRowValue) / topRowHeight;
88 };
89
90 """
91 + density_interpolation
92 + """
93
94 // populate major species
95 // all number densities retreived from csv are cm^-3
96 // all production rates are also in cm^-3 s^-1
97 Q[Shortcuts::O] = interpolateBetweenRows(row, nextRow, csvAtomicOxygenIndex, x(1));
98 Q[Shortcuts::O2] = interpolateBetweenRows(row, nextRow, csvMolecularOxygenIndex, x(1));
99 Q[Shortcuts::N2] = interpolateBetweenRows(row, nextRow, csvNitrogenIndex, x(1));
100 """
101 + hydrogen_interpolation
102 + """
103 // temperature is in Kelvin
104 Q[Shortcuts::T] = interpolateBetweenRows(row, nextRow, csvTemperatureIndex, x(1));
105 } else {
106
107 """
108 + density_csv
109 + """
110
111 // populate major species
112 // all number densities retreived from csv are cm^-3
113 // all production rates are also in cm^-3 s^-1
114 Q[Shortcuts::O2] = tarch::reader::CSVReader::extractFundamentalTypeFromRow<double>(';', csvMolecularOxygenIndex, row);
115 Q[Shortcuts::O] = tarch::reader::CSVReader::extractFundamentalTypeFromRow<double>(';', csvAtomicOxygenIndex, row);
116 Q[Shortcuts::N2] = tarch::reader::CSVReader::extractFundamentalTypeFromRow<double>(';', csvNitrogenIndex, row);
117 """
118 + hydrogen_csv
119 + """
120 // temperature is in Kelvin
121 Q[Shortcuts::T] = tarch::reader::CSVReader::extractFundamentalTypeFromRow<double>(';', csvTemperatureIndex, row);
122 }
123"""
124 )
125
126
127def get_atmospheric_boundary_conditions(outside_accessor="Qoutside"):
128 return (
129 """
130 // normal == 0 => left
131 // normal == 1 => bottom
132 // normal == 2 => right
133 // normal == 3 => top
134
135 for (int unknown = 0; unknown < NumberOfUnknowns + NumberOfAuxiliaryVariables; ++unknown) {
136 """
137 + outside_accessor
138 + """[unknown] = Qinside[unknown];
139 }
140
141 if (normal == 1) {
142 // Reflective at bottom to keep atmosphere
143 // from escaping the domain through the Earth's surface
144 """
145 + outside_accessor
146 + """[Shortcuts::u] = Qinside[Shortcuts::u];
147 """
148 + outside_accessor
149 + """[Shortcuts::v] = -Qinside[Shortcuts::v];
150 #if DIMENSIONS == 3
151 """
152 + outside_accessor
153 + """[Shortcuts::w] = Qinside[Shortcuts::w];
154 #endif
155 }
156"""
157 )
158
159
161 atmospheric_solver, diffusion_solver, chemical_solver, size, arguments
162):
163 offset = [0] * arguments.dimensions
164
165 project = exahype2.Project(
166 namespace=["applications", "exahype2", "GravityWaves"],
167 project_name="GravityWaves",
168 directory=".",
169 executable="ExaHyPE",
170 )
171
172 setLastSolver(
173 atmospheric_solver=atmospheric_solver,
174 diffusion_solver=diffusion_solver,
175 chemical_solver=chemical_solver,
176 )
177
178 if atmospheric_solver is not None:
179 project.add_solver(atmospheric_solver)
180
181 if diffusion_solver is not None:
182 project.add_solver(diffusion_solver)
183
184 if chemical_solver is not None:
185 project.add_solver(chemical_solver)
186
187 coupleTimeStepping(
188 atmospheric_solver=atmospheric_solver,
189 diffusion_solver=diffusion_solver,
190 chemical_solver=chemical_solver,
191 )
192
193 project.set_output_path(arguments.output)
194
195 project.set_global_simulation_parameters(
196 dimensions=arguments.dimensions,
197 size=size,
198 offset=offset,
199 min_end_time=arguments.end_time,
200 max_end_time=arguments.end_time,
201 first_plot_time_stamp=(0 if arguments.number_of_snapshots > 0 else -1),
202 time_in_between_plots=(
203 arguments.end_time / arguments.number_of_snapshots
204 if arguments.number_of_snapshots > 0
205 else 0
206 ),
207 periodic_BC=[
208 arguments.periodic_boundary_conditions_x,
209 arguments.periodic_boundary_conditions_y,
210 arguments.periodic_boundary_conditions_z,
211 ],
212 )
213
214 synchronizePatchGravityWaves(
215 atmospheric_solver=atmospheric_solver,
216 diffusion_solver=diffusion_solver,
217 chemical_solver=chemical_solver,
218 )
219
220 project.set_build_mode(mode=peano4.output.string_to_mode(arguments.build_mode))
221 project = project.generate_Peano4_project(verbose=True)
222
223 project.output.makefile.add_CXX_flag(f"""-DGRAVITY={GRAVITY}""")
224 project.output.makefile.add_CXX_flag(f"""-DUNIVERSAL_GAS_CONSTANT={R}""")
225 project.output.makefile.add_CXX_flag(
226 f"""-DMOLAR_MASS_ATOMIC_OXYGEN=0.016"""
227 ) # in kg/mol
228 project.output.makefile.add_CXX_flag(
229 f"""-DMOLAR_MASS_MOLECULAR_OXYGEN=0.032"""
230 ) # in kg/mol
231 project.output.makefile.add_CXX_flag(
232 f"""-DMOLAR_MASS_NITROGEN=0.028"""
233 ) # in kg/mol
234 return project
get_atmospheric_boundary_conditions(outside_accessor="Qoutside")
get_CSV_initializer(csv_file_path, bool initialize_density, bool initialize_hydrogen)
create_peano_project(atmospheric_solver, diffusion_solver, chemical_solver, size, arguments)