Skip to content

Commit a1ade2b

Browse files
authored
Use parser for input parameters of type long (#2506)
* Use parser for input parameters of type long * Revert "Use parser for input parameters of type long" This reverts commit 9573bb3. * Use parser for inputs of type long * add safeCasttoLong function * Fix typo in comment
1 parent 45ec9e3 commit a1ade2b

File tree

5 files changed

+67
-24
lines changed

5 files changed

+67
-24
lines changed

Source/Diagnostics/ReducedDiags/FieldProbe.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ FieldProbe::FieldProbe (std::string rd_name)
151151
}
152152
pp_rd_name.query("integrate", m_field_probe_integrate);
153153
pp_rd_name.query("raw_fields", raw_fields);
154-
pp_rd_name.query("interp_order", interp_order);
154+
queryWithParser(pp_rd_name, "interp_order", interp_order);
155155
pp_rd_name.query("do_moving_window_FP", do_moving_window_FP);
156156

157157
if (WarpX::gamma_boost > 1.0_rt)

Source/Initialization/PlasmaInjector.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ PlasmaInjector::PlasmaInjector (int ispecies, const std::string& name)
220220
queryWithParser(pp_species_name, "y_cut", y_cut);
221221
queryWithParser(pp_species_name, "z_cut", z_cut);
222222
getWithParser(pp_species_name, "q_tot", q_tot);
223-
pp_species_name.get("npart", npart);
223+
getWithParser(pp_species_name, "npart", npart);
224224
pp_species_name.query("do_symmetrize", do_symmetrize);
225225
gaussian_beam = true;
226226
parseMomentum(pp_species_name);

Source/Particles/LaserParticleContainer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ LaserParticleContainer::LaserParticleContainer (AmrCore* amr_core, int ispecies,
122122
);
123123

124124
pp_laser_name.query("do_continuous_injection", do_continuous_injection);
125-
pp_laser_name.query("min_particles_per_mode", m_min_particles_per_mode);
125+
queryWithParser(pp_laser_name, "min_particles_per_mode", m_min_particles_per_mode);
126126

127127
if (m_e_max == amrex::Real(0.)){
128128
ablastr::warn_manager::WMRecordWarning("Laser",

Source/Utils/WarpXUtil.H

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,17 @@ void getCellCoordinates (int i, int j, int k,
197197
int
198198
safeCastToInt(amrex::Real x, const std::string& real_name);
199199

200+
/**
201+
* \brief Do a safe cast of a real to a long
202+
* This ensures that the float value is within the range of longs and if not,
203+
* raises an exception.
204+
*
205+
* \param x Real value to cast
206+
* \param real_name String, the name of the variable being casted to use in the error message
207+
*/
208+
long
209+
safeCastToLong(amrex::Real x, const std::string& real_name);
210+
200211
/**
201212
* \brief Initialize an amrex::Parser object from a string containing a math expression
202213
*
@@ -265,6 +276,10 @@ int queryWithParser (const amrex::ParmParse& a_pp, char const * const str, T& va
265276

266277
val = safeCastToInt(std::round(parser.compileHost<0>()()), str);
267278
}
279+
else if (std::is_same<T, long>::value) {
280+
281+
val = safeCastToLong(std::round(parser.compileHost<0>()()), str);
282+
}
268283
else {
269284
val = static_cast<T>(parser.compileHost<0>()());
270285
}
@@ -289,6 +304,9 @@ int queryArrWithParser (const amrex::ParmParse& a_pp, char const * const str, st
289304
if (std::is_same<T, int>::value) {
290305
val[i] = safeCastToInt(std::round(parser.compileHost<0>()()), str);
291306
}
307+
else if (std::is_same<T, long>::value) {
308+
val[i] = safeCastToLong(std::round(parser.compileHost<0>()()), str);
309+
}
292310
else {
293311
val[i] = static_cast<T>(parser.compileHost<0>()());
294312
}
@@ -330,6 +348,9 @@ int queryArrWithParser (const amrex::ParmParse& a_pp, char const * const str, st
330348
if (std::is_same<T, int>::value) {
331349
val[i] = safeCastToInt(std::round(parser.compileHost<0>()()), str);
332350
}
351+
else if (std::is_same<T, long>::value) {
352+
val[i] = safeCastToLong(std::round(parser.compileHost<0>()()), str);
353+
}
333354
else {
334355
val[i] = static_cast<T>(parser.compileHost<0>()());
335356
}
@@ -361,6 +382,9 @@ void getWithParser (const amrex::ParmParse& a_pp, char const * const str, T& val
361382
if (std::is_same<T, int>::value) {
362383
val = safeCastToInt(std::round(parser.compileHost<0>()()), str);
363384
}
385+
else if (std::is_same<T, long>::value) {
386+
val = safeCastToLong(std::round(parser.compileHost<0>()()), str);
387+
}
364388
else {
365389
val = static_cast<T>(parser.compileHost<0>()());
366390
}
@@ -380,6 +404,9 @@ void getArrWithParser (const amrex::ParmParse& a_pp, char const * const str, std
380404
if (std::is_same<T, int>::value) {
381405
val[i] = safeCastToInt(std::round(parser.compileHost<0>()()), str);
382406
}
407+
else if (std::is_same<T, long>::value) {
408+
val[i] = safeCastToLong(std::round(parser.compileHost<0>()()), str);
409+
}
383410
else {
384411
val[i] = static_cast<T>(parser.compileHost<0>()());
385412
}
@@ -416,6 +443,9 @@ void getArrWithParser (const amrex::ParmParse& a_pp, char const * const str, std
416443
if (std::is_same<T, int>::value) {
417444
val[i] = safeCastToInt(std::round(parser.compileHost<0>()()), str);
418445
}
446+
else if (std::is_same<T, long>::value) {
447+
val[i] = safeCastToLong(std::round(parser.compileHost<0>()()), str);
448+
}
419449
else {
420450
val[i] = static_cast<T>(parser.compileHost<0>()());
421451
}

Source/Utils/WarpXUtil.cpp

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -276,30 +276,43 @@ void Store_parserString(const amrex::ParmParse& pp, std::string query_string,
276276
f.clear();
277277
}
278278

279-
int safeCastToInt(const amrex::Real x, const std::string& real_name) {
280-
int result = 0;
281-
bool error_detected = false;
282-
std::string assert_msg;
283-
// (2.0*(numeric_limits<int>::max()/2+1)) converts numeric_limits<int>::max()+1 to a real ensuring accuracy to all digits
284-
// This accepts x = 2**31-1 but rejects 2**31.
285-
using namespace amrex::literals;
286-
constexpr amrex::Real max_range = (2.0_rt*static_cast<amrex::Real>(std::numeric_limits<int>::max()/2+1));
287-
if (x < max_range) {
288-
if (std::ceil(x) >= std::numeric_limits<int>::min()) {
289-
result = static_cast<int>(x);
279+
namespace WarpXUtilSafeCast {
280+
template< typename int_type >
281+
AMREX_FORCE_INLINE
282+
int_type safeCastTo(const amrex::Real x, const std::string& real_name) {
283+
int_type result = int_type(0);
284+
bool error_detected = false;
285+
std::string assert_msg;
286+
// (2.0*(numeric_limits<int>::max()/2+1)) converts numeric_limits<int>::max()+1 to a real ensuring accuracy to all digits
287+
// This accepts x = 2**31-1 but rejects 2**31.
288+
using namespace amrex::literals;
289+
constexpr amrex::Real max_range = (2.0_rt*static_cast<amrex::Real>(std::numeric_limits<int_type>::max()/2+1));
290+
if (x < max_range) {
291+
if (std::ceil(x) >= std::numeric_limits<int_type>::min()) {
292+
result = static_cast<int_type>(x);
293+
} else {
294+
error_detected = true;
295+
assert_msg = "Negative overflow detected when casting " + real_name + " = " +
296+
std::to_string(x) + " to integer type";
297+
}
298+
} else if (x > 0) {
299+
error_detected = true;
300+
assert_msg = "Overflow detected when casting " + real_name + " = " + std::to_string(x) + " to integer type";
290301
} else {
291302
error_detected = true;
292-
assert_msg = "Negative overflow detected when casting " + real_name + " = " + std::to_string(x) + " to int";
303+
assert_msg = "NaN detected when casting " + real_name + " to integer type";
293304
}
294-
} else if (x > 0) {
295-
error_detected = true;
296-
assert_msg = "Overflow detected when casting " + real_name + " = " + std::to_string(x) + " to int";
297-
} else {
298-
error_detected = true;
299-
assert_msg = "NaN detected when casting " + real_name + " to int";
300-
}
301-
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(!error_detected, assert_msg);
302-
return result;
305+
WARPX_ALWAYS_ASSERT_WITH_MESSAGE(!error_detected, assert_msg);
306+
return result;
307+
}
308+
}
309+
310+
int safeCastToInt(const amrex::Real x, const std::string& real_name) {
311+
return WarpXUtilSafeCast::safeCastTo<int> (x, real_name);
312+
}
313+
314+
long safeCastToLong(const amrex::Real x, const std::string& real_name) {
315+
return WarpXUtilSafeCast::safeCastTo<long> (x, real_name);
303316
}
304317

305318
Parser makeParser (std::string const& parse_function, amrex::Vector<std::string> const& varnames)

0 commit comments

Comments
 (0)