Skip to content

Commit 15c99d0

Browse files
committed
introduce fill_field_vals
1 parent 86e7c9a commit 15c99d0

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed

tests/grtestutils/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ add_library(grtestutils
8383
GrackleCtxPack.cpp GrackleCtxPack.hpp
8484
field_container.cpp field_container.hpp
8585
field_info_detail.cpp field_info_detail.hpp
86+
fill_field_vals.hpp
8687
iterator_adaptor.hpp
8788
os.hpp os.cpp
8889
param.cpp param.hpp
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// See the LICENSE file for license and copyright information
4+
// SPDX-License-Identifier: NCSA AND BSD-3-Clause
5+
//
6+
//===----------------------------------------------------------------------===//
7+
///
8+
/// @file
9+
/// define fill_field_vals
10+
///
11+
//===----------------------------------------------------------------------===//
12+
#ifndef GRTESTUTILS_FILL_FIELD_VALS_HPP
13+
#define GRTESTUTILS_FILL_FIELD_VALS_HPP
14+
15+
#include "GrackleCtxPack.hpp"
16+
#include "grackle.h"
17+
#include "status_reporting.h"
18+
#include "./field_container.hpp"
19+
#include "./field_info_detail.hpp"
20+
#include "./status.hpp"
21+
22+
#include <optional>
23+
#include <string_view>
24+
#include <vector>
25+
26+
namespace grtest {
27+
28+
/// Fill in the values of @p fc by repeating the values from @p field_tile
29+
///
30+
/// @param[in, out] fc The field container that will be filled
31+
/// @param[in] field_tile Specifies the values to use
32+
template <class Tile>
33+
Status fill_field_vals(FieldContainer& fc, const Tile& field_tile) {
34+
// access field grid index properties
35+
int rank = fc.rank();
36+
int ix_start = fc.get_ptr()->grid_start[0];
37+
int ix_stop = fc.get_ptr()->grid_end[0] + 1;
38+
int iy_start = (rank >= 2) ? fc.get_ptr()->grid_start[1] : 0;
39+
int iy_stop = (rank >= 2) ? fc.get_ptr()->grid_end[1] + 1 : 1;
40+
int iz_start = (rank == 3) ? fc.get_ptr()->grid_start[2] : 0;
41+
int iz_stop = (rank == 3) ? fc.get_ptr()->grid_end[2] + 1 : 1;
42+
43+
int mx = fc.get_ptr()->grid_dimension[0];
44+
int my = (rank >= 2) ? fc.get_ptr()->grid_dimension[1] : 1;
45+
46+
int n_x_vals = ix_stop - ix_start;
47+
48+
// access properties about the tile
49+
int tile_len = field_tile.get_n_vals();
50+
51+
// a few error consistency checks
52+
if (tile_len <= 0) {
53+
return error::Adhoc("tile_len must be positive");
54+
} else if (tile_len > n_x_vals) {
55+
// we may want to revisit this in the future
56+
return error::Adhoc("tile_len can't exceed length of contiguous axis");
57+
}
58+
59+
// allocate the buffer
60+
std::vector<gr_float> tile_buf(tile_len);
61+
62+
for (auto [field_name, field_ptr] : fc) {
63+
if (!field_tile.fill_buf(tile_buf.data(), field_name)) {
64+
return error::Adhoc("field_tile doesn't recognize field name: " +
65+
field_name);
66+
}
67+
68+
for (int iz = iz_start; iz < iz_stop; iz++) {
69+
for (int iy = iy_start; iy < iy_stop; iy++) {
70+
for (int ix = ix_start; ix < ix_stop; ix++) {
71+
int i = ix + mx * (iy + my * iz);
72+
field_ptr[i] = tile_buf[ix % tile_len];
73+
}
74+
}
75+
}
76+
}
77+
78+
return OkStatus();
79+
}
80+
81+
/// Represents a very simplistic set of conditions
82+
struct SimpleFieldTile {
83+
double mfrac_metal;
84+
double mfrac_H;
85+
double mfrac_He;
86+
double mfrac_D;
87+
88+
// both of these are in code-units
89+
double common_density;
90+
double common_eint;
91+
92+
int get_n_vals() const noexcept { return 1; }
93+
94+
bool fill_buf(gr_float* buf, std::string_view field_name) const noexcept {
95+
if (field_name == "density") {
96+
buf[0] = common_density;
97+
} else if (field_name == "internal_energy") {
98+
buf[0] = common_eint;
99+
} else if (field_name == "metal_density") {
100+
buf[0] = mfrac_metal * common_density;
101+
} else if (field_name == "HI_density") {
102+
buf[0] = mfrac_H * common_density;
103+
} else if (field_name == "HeI_density") {
104+
buf[0] = mfrac_He * common_density;
105+
} else if (field_name == "DI_density") {
106+
buf[0] = mfrac_D * common_density;
107+
} else {
108+
field_detail::Kind kind = field_detail::Kind::UNSET;
109+
std::optional<field_detail::FieldInfo> maybe_field_info =
110+
field_detail::query_field_info(field_name);
111+
if (maybe_field_info.has_value()) {
112+
kind = maybe_field_info->kind;
113+
}
114+
115+
if (kind == field_detail::Kind::ELEMENTWISE_SOLVER_ARG) {
116+
buf[0] = 0.0;
117+
} else if (kind == field_detail::Kind::PRIMORDIAL_SPECIES) {
118+
gr_float tiny_number = 1.e-20;
119+
buf[0] = tiny_number * common_density;
120+
} else {
121+
return false;
122+
}
123+
}
124+
return true;
125+
}
126+
};
127+
128+
inline SimpleFieldTile make_simple_tile(const GrackleCtxPack& ctx_pack,
129+
code_units units, double metallicity) {
130+
GR_INTERNAL_REQUIRE(ctx_pack.is_initialized(), "ctx_pack was initialized");
131+
132+
const chemistry_data* my_chem = ctx_pack.my_chemistry();
133+
134+
// the internal energy roughly corresponds to 1000 K
135+
double common_eint = 1000.0 / get_temperature_units(&units);
136+
137+
return SimpleFieldTile{
138+
/* mfrac_metal = */ metallicity * my_chem->SolarMetalFractionByMass,
139+
/* mfrac_H = */ my_chem->HydrogenFractionByMass,
140+
/* mfrac_He = */ (1.0 - my_chem->HydrogenFractionByMass),
141+
/* mfrac_D = */ 2.0 * 3.4e-5,
142+
143+
// both of these are in code-units
144+
/* common_density = */ 1.0,
145+
/* common_eint = */ common_eint};
146+
}
147+
148+
} // namespace grtest
149+
150+
#endif // GRTESTUTILS_SET_FIELD_CONDITIONS_HPP

0 commit comments

Comments
 (0)