From bc08d8a6b8ddf812433a3ec84a0e0642b4bbf91a Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Thu, 12 Dec 2019 17:24:03 -0500 Subject: [PATCH 01/43] Explicitly name lowlevel HDF5 read/write dataset --- include/openmc/hdf5_interface.h | 99 +++++++++++++++++++-------------- src/hdf5_interface.cpp | 53 +++++++++++------- src/state_point.cpp | 2 +- 3 files changed, 90 insertions(+), 64 deletions(-) diff --git a/include/openmc/hdf5_interface.h b/include/openmc/hdf5_interface.h index ee3419fa22..72eaa39368 100644 --- a/include/openmc/hdf5_interface.h +++ b/include/openmc/hdf5_interface.h @@ -26,13 +26,17 @@ namespace openmc { //============================================================================== void read_attr(hid_t obj_id, const char* name, hid_t mem_type_id, - void* buffer); + void* buffer); + void write_attr(hid_t obj_id, int ndim, const hsize_t* dims, const char* name, - hid_t mem_type_id, const void* buffer); -void read_dataset(hid_t obj_id, const char* name, hid_t mem_type_id, - void* buffer, bool indep); -void write_dataset(hid_t group_id, int ndim, const hsize_t* dims, const char* name, - hid_t mem_type_id, const void* buffer, bool indep); + hid_t mem_type_id, const void* buffer); + +void read_dataset_lowlevel(hid_t obj_id, const char* name, hid_t mem_type_id, + void* buffer, bool indep); + +void write_dataset_lowlevel(hid_t group_id, int ndim, const hsize_t* dims, + const char* name, hid_t mem_type_id, const void* buffer, bool indep); + bool using_mpio_device(hid_t obj_id); //============================================================================== @@ -86,34 +90,32 @@ extern "C" { void read_attr_string(hid_t obj_id, const char* name, size_t slen, char* buffer); void read_complex(hid_t obj_id, const char* name, - std::complex* buffer, bool indep); - void read_double(hid_t obj_id, const char* name, double* buffer, - bool indep); - void read_int(hid_t obj_id, const char* name, int* buffer, - bool indep); + std::complex* buffer, bool indep); + void read_double(hid_t obj_id, const char* name, double* buffer, bool indep); + void read_int(hid_t obj_id, const char* name, int* buffer, bool indep); void read_llong(hid_t obj_id, const char* name, long long* buffer, - bool indep); - void read_string(hid_t obj_id, const char* name, size_t slen, - char* buffer, bool indep); + bool indep); + void read_string(hid_t obj_id, const char* name, size_t slen, char* buffer, + bool indep); - void read_tally_results(hid_t group_id, hsize_t n_filter, - hsize_t n_score, double* results); + void read_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score, + double* results); void write_attr_double(hid_t obj_id, int ndim, const hsize_t* dims, - const char* name, const double* buffer); + const char* name, const double* buffer); void write_attr_int(hid_t obj_id, int ndim, const hsize_t* dims, - const char* name, const int* buffer); + const char* name, const int* buffer); void write_attr_string(hid_t obj_id, const char* name, const char* buffer); void write_double(hid_t group_id, int ndim, const hsize_t* dims, - const char* name, const double* buffer, bool indep); + const char* name, const double* buffer, bool indep); void write_int(hid_t group_id, int ndim, const hsize_t* dims, - const char* name, const int* buffer, bool indep); + const char* name, const int* buffer, bool indep); void write_llong(hid_t group_id, int ndim, const hsize_t* dims, - const char* name, const long long* buffer, bool indep); + const char* name, const long long* buffer, bool indep); void write_string(hid_t group_id, int ndim, const hsize_t* dims, size_t slen, - const char* name, char const* buffer, bool indep); + const char* name, char const* buffer, bool indep); void write_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score, - const double* results); + const double* results); } // extern "C" //============================================================================== @@ -233,7 +235,7 @@ template inline std::enable_if_t>::value> read_dataset(hid_t obj_id, const char* name, T& buffer, bool indep=false) { - read_dataset(obj_id, name, H5TypeMap::type_id, &buffer, indep); + read_dataset_lowlevel(obj_id, name, H5TypeMap::type_id, &buffer, indep); } // overload for std::string @@ -251,9 +253,11 @@ read_dataset(hid_t obj_id, const char* name, std::string& str, bool indep=false) // array version template inline void -read_dataset(hid_t dset, const char* name, std::array& buffer, bool indep=false) +read_dataset(hid_t dset, const char* name, std::array& buffer, + bool indep=false) { - read_dataset(dset, name, H5TypeMap::type_id, buffer.data(), indep); + read_dataset_lowlevel(dset, name, H5TypeMap::type_id, buffer.data(), + indep); } // vector version @@ -267,11 +271,13 @@ void read_dataset(hid_t dset, std::vector& vec, bool indep=false) vec.resize(shape[0]); // Read data into vector - read_dataset(dset, nullptr, H5TypeMap::type_id, vec.data(), indep); + read_dataset_lowlevel(dset, nullptr, H5TypeMap::type_id, vec.data(), + indep); } template -void read_dataset(hid_t obj_id, const char* name, std::vector& vec, bool indep=false) +void read_dataset(hid_t obj_id, const char* name, std::vector& vec, + bool indep=false) { hid_t dset = open_dataset(obj_id, name); read_dataset(dset, vec, indep); @@ -291,14 +297,17 @@ void read_dataset(hid_t dset, xt::xarray& arr, bool indep=false) arr.resize(shape); // Read data from attribute - read_dataset(dset, nullptr, H5TypeMap::type_id, arr.data(), indep); + read_dataset_lowlevel(dset, nullptr, H5TypeMap::type_id, arr.data(), + indep); } template<> -void read_dataset(hid_t dset, xt::xarray>& arr, bool indep); +void read_dataset(hid_t dset, xt::xarray>& arr, + bool indep); template -void read_dataset(hid_t obj_id, const char* name, xt::xarray& arr, bool indep=false) +void read_dataset(hid_t obj_id, const char* name, xt::xarray& arr, + bool indep=false) { // Open dataset and read array hid_t dset = open_dataset(obj_id, name); @@ -308,7 +317,8 @@ void read_dataset(hid_t obj_id, const char* name, xt::xarray& arr, bool indep template -void read_dataset(hid_t obj_id, const char* name, xt::xtensor& arr, bool indep=false) +void read_dataset(hid_t obj_id, const char* name, xt::xtensor& arr, + bool indep=false) { // Open dataset and read array hid_t dset = open_dataset(obj_id, name); @@ -346,7 +356,7 @@ read_dataset(hid_t obj_id, const char* name, Position& r, bool indep=false) template inline void read_dataset_as_shape(hid_t obj_id, const char* name, - xt::xtensor& arr, bool indep=false) + xt::xtensor& arr, bool indep=false) { hid_t dset = open_dataset(obj_id, name); @@ -357,7 +367,8 @@ inline void read_dataset_as_shape(hid_t obj_id, const char* name, std::vector buffer(size); // Read data from attribute - read_dataset(dset, nullptr, H5TypeMap::type_id, buffer.data(), indep); + read_dataset_lowlevel(dset, nullptr, H5TypeMap::type_id, buffer.data(), + indep); // Adapt into xarray arr = xt::adapt(buffer, arr.shape()); @@ -367,8 +378,8 @@ inline void read_dataset_as_shape(hid_t obj_id, const char* name, template -inline void read_nd_vector(hid_t obj_id, const char* name, xt::xtensor& result, - bool must_have=false) +inline void read_nd_vector(hid_t obj_id, const char* name, + xt::xtensor& result, bool must_have=false) { if (object_exists(obj_id, name)) { read_dataset_as_shape(obj_id, name, result, true); @@ -431,7 +442,8 @@ template inline std::enable_if_t>::value> write_dataset(hid_t obj_id, const char* name, T buffer) { - write_dataset(obj_id, 0, nullptr, name, H5TypeMap::type_id, &buffer, false); + write_dataset_lowlevel(obj_id, 0, nullptr, name, H5TypeMap::type_id, + &buffer, false); } inline void @@ -444,11 +456,13 @@ template inline void write_dataset(hid_t obj_id, const char* name, const std::array& buffer) { hsize_t dims[] {N}; - write_dataset(obj_id, 1, dims, name, H5TypeMap::type_id, buffer.data(), false); + write_dataset_lowlevel(obj_id, 1, dims, name, H5TypeMap::type_id, + buffer.data(), false); } inline void -write_dataset(hid_t obj_id, const char* name, const std::vector& buffer) +write_dataset(hid_t obj_id, const char* name, + const std::vector& buffer) { auto n {buffer.size()}; hsize_t dims[] {n}; @@ -477,7 +491,8 @@ template inline void write_dataset(hid_t obj_id, const char* name, const std::vector& buffer) { hsize_t dims[] {buffer.size()}; - write_dataset(obj_id, 1, dims, name, H5TypeMap::type_id, buffer.data(), false); + write_dataset_lowlevel(obj_id, 1, dims, name, H5TypeMap::type_id, + buffer.data(), false); } // Template for xarray, xtensor, etc. @@ -487,8 +502,8 @@ write_dataset(hid_t obj_id, const char* name, const xt::xcontainer& arr) using T = typename D::value_type; auto s = arr.shape(); std::vector dims {s.cbegin(), s.cend()}; - write_dataset(obj_id, dims.size(), dims.data(), name, H5TypeMap::type_id, - arr.data(), false); + write_dataset_lowlevel(obj_id, dims.size(), dims.data(), name, + H5TypeMap::type_id, arr.data(), false); } inline void diff --git a/src/hdf5_interface.cpp b/src/hdf5_interface.cpp index b1a90cb8f7..d4434225a2 100644 --- a/src/hdf5_interface.cpp +++ b/src/hdf5_interface.cpp @@ -49,7 +49,8 @@ get_shape(hid_t obj_id, hsize_t* dims) } else if (type == H5I_ATTR) { dspace = H5Aget_space(obj_id); } else { - throw std::runtime_error{"Expected dataset or attribute in call to get_shape."}; + throw std::runtime_error{ + "Expected dataset or attribute in call to get_shape."}; } H5Sget_simple_extent_dims(dspace, dims, nullptr); H5Sclose(dspace); @@ -74,7 +75,8 @@ std::vector object_shape(hid_t obj_id) } else if (type == H5I_ATTR) { dspace = H5Aget_space(obj_id); } else { - throw std::runtime_error{"Expected dataset or attribute in call to object_shape."}; + throw std::runtime_error{ + "Expected dataset or attribute in call to object_shape."}; } int n = H5Sget_simple_extent_ndims(dspace); @@ -471,8 +473,8 @@ read_attr_string(hid_t obj_id, const char* name, size_t slen, char* buffer) void -read_dataset(hid_t obj_id, const char* name, hid_t mem_type_id, - void* buffer, bool indep) +read_dataset_lowlevel(hid_t obj_id, const char* name, hid_t mem_type_id, + void* buffer, bool indep) { hid_t dset = obj_id; if (name) dset = open_dataset(obj_id, name); @@ -520,26 +522,27 @@ void read_dataset(hid_t dset, xt::xarray>& arr, bool indep) void read_double(hid_t obj_id, const char* name, double* buffer, bool indep) { - read_dataset(obj_id, name, H5T_NATIVE_DOUBLE, buffer, indep); + read_dataset_lowlevel(obj_id, name, H5T_NATIVE_DOUBLE, buffer, indep); } void read_int(hid_t obj_id, const char* name, int* buffer, bool indep) { - read_dataset(obj_id, name, H5T_NATIVE_INT, buffer, indep); + read_dataset_lowlevel(obj_id, name, H5T_NATIVE_INT, buffer, indep); } void read_llong(hid_t obj_id, const char* name, long long* buffer, bool indep) { - read_dataset(obj_id, name, H5T_NATIVE_LLONG, buffer, indep); + read_dataset_lowlevel(obj_id, name, H5T_NATIVE_LLONG, buffer, indep); } void -read_string(hid_t obj_id, const char* name, size_t slen, char* buffer, bool indep) +read_string(hid_t obj_id, const char* name, size_t slen, char* buffer, + bool indep) { // Create datatype for a string hid_t datatype = H5Tcopy(H5T_C_S1); @@ -548,7 +551,7 @@ read_string(hid_t obj_id, const char* name, size_t slen, char* buffer, bool inde H5Tset_strpad(datatype, H5T_STR_NULLPAD); // Read data into buffer - read_dataset(obj_id, name, datatype, buffer, indep); + read_dataset_lowlevel(obj_id, name, datatype, buffer, indep); // Free resources H5Tclose(datatype); @@ -556,7 +559,8 @@ read_string(hid_t obj_id, const char* name, size_t slen, char* buffer, bool inde void -read_complex(hid_t obj_id, const char* name, std::complex* buffer, bool indep) +read_complex(hid_t obj_id, const char* name, std::complex* buffer, + bool indep) { // Create compound datatype for complex numbers struct complex_t { @@ -569,7 +573,7 @@ read_complex(hid_t obj_id, const char* name, std::complex* buffer, bool H5Tinsert(complex_id, "i", HOFFSET(complex_t, im), H5T_NATIVE_DOUBLE); // Read data - read_dataset(obj_id, name, complex_id, buffer, indep); + read_dataset_lowlevel(obj_id, name, complex_id, buffer, indep); // Free resources H5Tclose(complex_id); @@ -577,7 +581,8 @@ read_complex(hid_t obj_id, const char* name, std::complex* buffer, bool void -read_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score, double* results) +read_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score, + double* results) { // Create dataspace for hyperslab in memory hsize_t dims[] {n_filter, n_score, 3}; @@ -654,8 +659,8 @@ write_attr_string(hid_t obj_id, const char* name, const char* buffer) void -write_dataset(hid_t group_id, int ndim, const hsize_t* dims, const char* name, - hid_t mem_type_id, const void* buffer, bool indep) +write_dataset_lowlevel(hid_t group_id, int ndim, const hsize_t* dims, + const char* name, hid_t mem_type_id, const void* buffer, bool indep) { // If array is given, create a simple dataspace. Otherwise, create a scalar // datascape. @@ -696,7 +701,8 @@ void write_double(hid_t group_id, int ndim, const hsize_t* dims, const char* name, const double* buffer, bool indep) { - write_dataset(group_id, ndim, dims, name, H5T_NATIVE_DOUBLE, buffer, indep); + write_dataset_lowlevel(group_id, ndim, dims, name, H5T_NATIVE_DOUBLE, buffer, + indep); } @@ -704,7 +710,8 @@ void write_int(hid_t group_id, int ndim, const hsize_t* dims, const char* name, const int* buffer, bool indep) { - write_dataset(group_id, ndim, dims, name, H5T_NATIVE_INT, buffer, indep); + write_dataset_lowlevel(group_id, ndim, dims, name, H5T_NATIVE_INT, buffer, + indep); } @@ -712,7 +719,8 @@ void write_llong(hid_t group_id, int ndim, const hsize_t* dims, const char* name, const long long* buffer, bool indep) { - write_dataset(group_id, ndim, dims, name, H5T_NATIVE_LLONG, buffer, indep); + write_dataset_lowlevel(group_id, ndim, dims, name, H5T_NATIVE_LLONG, buffer, + indep); } @@ -725,7 +733,7 @@ write_string(hid_t group_id, int ndim, const hsize_t* dims, size_t slen, hid_t datatype = H5Tcopy(H5T_C_S1); H5Tset_size(datatype, slen); - write_dataset(group_id, ndim, dims, name, datatype, buffer, indep); + write_dataset_lowlevel(group_id, ndim, dims, name, datatype, buffer, indep); // Free resources H5Tclose(datatype); @@ -734,14 +742,17 @@ write_string(hid_t group_id, int ndim, const hsize_t* dims, size_t slen, void -write_string(hid_t group_id, const char* name, const std::string& buffer, bool indep) +write_string(hid_t group_id, const char* name, const std::string& buffer, + bool indep) { - write_string(group_id, 0, nullptr, buffer.length(), name, buffer.c_str(), indep); + write_string(group_id, 0, nullptr, buffer.length(), name, buffer.c_str(), + indep); } void -write_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score, const double* results) +write_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score, + const double* results) { // Set dimensions of sum/sum_sq hyperslab to store hsize_t count[] {n_filter, n_score, 2}; diff --git a/src/state_point.cpp b/src/state_point.cpp index 4c159c1678..31454ec4df 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -418,7 +418,7 @@ void load_state_point() if (mpi::master) { #endif // Read global tally data - read_dataset(file_id, "global_tallies", H5T_NATIVE_DOUBLE, + read_dataset_lowlevel(file_id, "global_tallies", H5T_NATIVE_DOUBLE, simulation::global_tallies.data(), false); // Check if tally results are present From 6a2f3ee2efb4b59de49986eac012e7f97a4d9c03 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 13 Dec 2019 11:51:22 -0500 Subject: [PATCH 02/43] Use collective IO for read/write tally results --- include/openmc/hdf5_interface.h | 32 ++++++++------- src/hdf5_interface.cpp | 72 ++++++++++++++++----------------- src/state_point.cpp | 2 +- 3 files changed, 54 insertions(+), 52 deletions(-) diff --git a/include/openmc/hdf5_interface.h b/include/openmc/hdf5_interface.h index 72eaa39368..ddb2319ae4 100644 --- a/include/openmc/hdf5_interface.h +++ b/include/openmc/hdf5_interface.h @@ -32,10 +32,11 @@ void write_attr(hid_t obj_id, int ndim, const hsize_t* dims, const char* name, hid_t mem_type_id, const void* buffer); void read_dataset_lowlevel(hid_t obj_id, const char* name, hid_t mem_type_id, - void* buffer, bool indep); + hid_t mem_space_id, bool indep, void* buffer); void write_dataset_lowlevel(hid_t group_id, int ndim, const hsize_t* dims, - const char* name, hid_t mem_type_id, const void* buffer, bool indep); + const char* name, hid_t mem_type_id, hid_t mem_space_id, bool indep, + const void* buffer); bool using_mpio_device(hid_t obj_id); @@ -235,7 +236,8 @@ template inline std::enable_if_t>::value> read_dataset(hid_t obj_id, const char* name, T& buffer, bool indep=false) { - read_dataset_lowlevel(obj_id, name, H5TypeMap::type_id, &buffer, indep); + read_dataset_lowlevel(obj_id, name, H5TypeMap::type_id, H5S_ALL, indep, + &buffer); } // overload for std::string @@ -256,8 +258,8 @@ template inline void read_dataset(hid_t dset, const char* name, std::array& buffer, bool indep=false) { - read_dataset_lowlevel(dset, name, H5TypeMap::type_id, buffer.data(), - indep); + read_dataset_lowlevel(dset, name, H5TypeMap::type_id, H5S_ALL, indep, + buffer.data()); } // vector version @@ -271,8 +273,8 @@ void read_dataset(hid_t dset, std::vector& vec, bool indep=false) vec.resize(shape[0]); // Read data into vector - read_dataset_lowlevel(dset, nullptr, H5TypeMap::type_id, vec.data(), - indep); + read_dataset_lowlevel(dset, nullptr, H5TypeMap::type_id, H5S_ALL, indep, + vec.data()); } template @@ -297,8 +299,8 @@ void read_dataset(hid_t dset, xt::xarray& arr, bool indep=false) arr.resize(shape); // Read data from attribute - read_dataset_lowlevel(dset, nullptr, H5TypeMap::type_id, arr.data(), - indep); + read_dataset_lowlevel(dset, nullptr, H5TypeMap::type_id, H5S_ALL, indep, + arr.data()); } template<> @@ -367,8 +369,8 @@ inline void read_dataset_as_shape(hid_t obj_id, const char* name, std::vector buffer(size); // Read data from attribute - read_dataset_lowlevel(dset, nullptr, H5TypeMap::type_id, buffer.data(), - indep); + read_dataset_lowlevel(dset, nullptr, H5TypeMap::type_id, H5S_ALL, indep, + buffer.data()); // Adapt into xarray arr = xt::adapt(buffer, arr.shape()); @@ -443,7 +445,7 @@ std::enable_if_t>::value> write_dataset(hid_t obj_id, const char* name, T buffer) { write_dataset_lowlevel(obj_id, 0, nullptr, name, H5TypeMap::type_id, - &buffer, false); + H5S_ALL, false, &buffer); } inline void @@ -457,7 +459,7 @@ write_dataset(hid_t obj_id, const char* name, const std::array& buffer) { hsize_t dims[] {N}; write_dataset_lowlevel(obj_id, 1, dims, name, H5TypeMap::type_id, - buffer.data(), false); + H5S_ALL, false, buffer.data()); } inline void @@ -492,7 +494,7 @@ write_dataset(hid_t obj_id, const char* name, const std::vector& buffer) { hsize_t dims[] {buffer.size()}; write_dataset_lowlevel(obj_id, 1, dims, name, H5TypeMap::type_id, - buffer.data(), false); + H5S_ALL, false, buffer.data()); } // Template for xarray, xtensor, etc. @@ -503,7 +505,7 @@ write_dataset(hid_t obj_id, const char* name, const xt::xcontainer& arr) auto s = arr.shape(); std::vector dims {s.cbegin(), s.cend()}; write_dataset_lowlevel(obj_id, dims.size(), dims.data(), name, - H5TypeMap::type_id, arr.data(), false); + H5TypeMap::type_id, H5S_ALL, false, arr.data()); } inline void diff --git a/src/hdf5_interface.cpp b/src/hdf5_interface.cpp index d4434225a2..bd73e05fa2 100644 --- a/src/hdf5_interface.cpp +++ b/src/hdf5_interface.cpp @@ -474,7 +474,7 @@ read_attr_string(hid_t obj_id, const char* name, size_t slen, char* buffer) void read_dataset_lowlevel(hid_t obj_id, const char* name, hid_t mem_type_id, - void* buffer, bool indep) + hid_t mem_space_id, bool indep, void* buffer) { hid_t dset = obj_id; if (name) dset = open_dataset(obj_id, name); @@ -489,11 +489,11 @@ read_dataset_lowlevel(hid_t obj_id, const char* name, hid_t mem_type_id, H5Pset_dxpl_mpio(plist, data_xfer_mode); // Read data - H5Dread(dset, mem_type_id, H5S_ALL, H5S_ALL, plist, buffer); + H5Dread(dset, mem_type_id, mem_space_id, H5S_ALL, plist, buffer); H5Pclose(plist); #endif } else { - H5Dread(dset, mem_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer); + H5Dread(dset, mem_type_id, mem_space_id, H5S_ALL, H5P_DEFAULT, buffer); } if (name) H5Dclose(dset); @@ -522,21 +522,22 @@ void read_dataset(hid_t dset, xt::xarray>& arr, bool indep) void read_double(hid_t obj_id, const char* name, double* buffer, bool indep) { - read_dataset_lowlevel(obj_id, name, H5T_NATIVE_DOUBLE, buffer, indep); + read_dataset_lowlevel(obj_id, name, H5T_NATIVE_DOUBLE, H5S_ALL, indep, + buffer); } void read_int(hid_t obj_id, const char* name, int* buffer, bool indep) { - read_dataset_lowlevel(obj_id, name, H5T_NATIVE_INT, buffer, indep); + read_dataset_lowlevel(obj_id, name, H5T_NATIVE_INT, H5S_ALL, indep, buffer); } void read_llong(hid_t obj_id, const char* name, long long* buffer, bool indep) { - read_dataset_lowlevel(obj_id, name, H5T_NATIVE_LLONG, buffer, indep); + read_dataset_lowlevel(obj_id, name, H5T_NATIVE_LLONG, H5S_ALL, indep, buffer); } @@ -551,7 +552,7 @@ read_string(hid_t obj_id, const char* name, size_t slen, char* buffer, H5Tset_strpad(datatype, H5T_STR_NULLPAD); // Read data into buffer - read_dataset_lowlevel(obj_id, name, datatype, buffer, indep); + read_dataset_lowlevel(obj_id, name, datatype, H5S_ALL, indep, buffer); // Free resources H5Tclose(datatype); @@ -573,7 +574,7 @@ read_complex(hid_t obj_id, const char* name, std::complex* buffer, H5Tinsert(complex_id, "i", HOFFSET(complex_t, im), H5T_NATIVE_DOUBLE); // Read data - read_dataset_lowlevel(obj_id, name, complex_id, buffer, indep); + read_dataset_lowlevel(obj_id, name, complex_id, H5S_ALL, indep, buffer); // Free resources H5Tclose(complex_id); @@ -585,18 +586,18 @@ read_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score, double* results) { // Create dataspace for hyperslab in memory - hsize_t dims[] {n_filter, n_score, 3}; - hsize_t start[] {0, 0, 1}; - hsize_t count[] {n_filter, n_score, 2}; - hid_t memspace = H5Screate_simple(3, dims, nullptr); + constexpr int ndim = 3; + hsize_t dims[ndim] {n_filter, n_score, 3}; + hsize_t start[ndim] {0, 0, 1}; + hsize_t count[ndim] {n_filter, n_score, 2}; + hid_t memspace = H5Screate_simple(ndim, dims, nullptr); H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, nullptr, count, nullptr); - // Create and write dataset - hid_t dset = H5Dopen(group_id, "results", H5P_DEFAULT); - H5Dread(dset, H5T_NATIVE_DOUBLE, memspace, H5S_ALL, H5P_DEFAULT, results); + // Read the dataset + read_dataset_lowlevel(group_id, "results", H5T_NATIVE_DOUBLE, memspace, + false, results); // Free resources - H5Dclose(dset); H5Sclose(memspace); } @@ -660,7 +661,8 @@ write_attr_string(hid_t obj_id, const char* name, const char* buffer) void write_dataset_lowlevel(hid_t group_id, int ndim, const hsize_t* dims, - const char* name, hid_t mem_type_id, const void* buffer, bool indep) + const char* name, hid_t mem_type_id, hid_t mem_space_id, bool indep, + const void* buffer) { // If array is given, create a simple dataspace. Otherwise, create a scalar // datascape. @@ -684,11 +686,11 @@ write_dataset_lowlevel(hid_t group_id, int ndim, const hsize_t* dims, H5Pset_dxpl_mpio(plist, data_xfer_mode); // Write data - H5Dwrite(dset, mem_type_id, H5S_ALL, H5S_ALL, plist, buffer); + H5Dwrite(dset, mem_type_id, mem_space_id, H5S_ALL, plist, buffer); H5Pclose(plist); #endif } else { - H5Dwrite(dset, mem_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer); + H5Dwrite(dset, mem_type_id, mem_space_id, H5S_ALL, H5P_DEFAULT, buffer); } // Free resources @@ -701,8 +703,8 @@ void write_double(hid_t group_id, int ndim, const hsize_t* dims, const char* name, const double* buffer, bool indep) { - write_dataset_lowlevel(group_id, ndim, dims, name, H5T_NATIVE_DOUBLE, buffer, - indep); + write_dataset_lowlevel(group_id, ndim, dims, name, H5T_NATIVE_DOUBLE, H5S_ALL, + indep, buffer); } @@ -710,8 +712,8 @@ void write_int(hid_t group_id, int ndim, const hsize_t* dims, const char* name, const int* buffer, bool indep) { - write_dataset_lowlevel(group_id, ndim, dims, name, H5T_NATIVE_INT, buffer, - indep); + write_dataset_lowlevel(group_id, ndim, dims, name, H5T_NATIVE_INT, H5S_ALL, + indep, buffer); } @@ -719,8 +721,8 @@ void write_llong(hid_t group_id, int ndim, const hsize_t* dims, const char* name, const long long* buffer, bool indep) { - write_dataset_lowlevel(group_id, ndim, dims, name, H5T_NATIVE_LLONG, buffer, - indep); + write_dataset_lowlevel(group_id, ndim, dims, name, H5T_NATIVE_LLONG, H5S_ALL, + indep, buffer); } @@ -733,7 +735,8 @@ write_string(hid_t group_id, int ndim, const hsize_t* dims, size_t slen, hid_t datatype = H5Tcopy(H5T_C_S1); H5Tset_size(datatype, slen); - write_dataset_lowlevel(group_id, ndim, dims, name, datatype, buffer, indep); + write_dataset_lowlevel(group_id, ndim, dims, name, datatype, H5S_ALL, indep, + buffer); // Free resources H5Tclose(datatype); @@ -755,24 +758,21 @@ write_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score, const double* results) { // Set dimensions of sum/sum_sq hyperslab to store - hsize_t count[] {n_filter, n_score, 2}; - hid_t dspace = H5Screate_simple(3, count, nullptr); + constexpr int ndim = 3; + hsize_t count[ndim] {n_filter, n_score, 2}; // Set dimensions of results array - hsize_t dims[] {n_filter, n_score, 3}; - hsize_t start[] {0, 0, 1}; - hid_t memspace = H5Screate_simple(3, dims, nullptr); + hsize_t dims[ndim] {n_filter, n_score, 3}; + hsize_t start[ndim] {0, 0, 1}; + hid_t memspace = H5Screate_simple(ndim, dims, nullptr); H5Sselect_hyperslab(memspace, H5S_SELECT_SET, start, nullptr, count, nullptr); // Create and write dataset - hid_t dset = H5Dcreate(group_id, "results", H5T_NATIVE_DOUBLE, dspace, - H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - H5Dwrite(dset, H5T_NATIVE_DOUBLE, memspace, H5S_ALL, H5P_DEFAULT, results); + write_dataset_lowlevel(group_id, ndim, count, "results", H5T_NATIVE_DOUBLE, + memspace, false, results); // Free resources - H5Dclose(dset); H5Sclose(memspace); - H5Sclose(dspace); } diff --git a/src/state_point.cpp b/src/state_point.cpp index 31454ec4df..fb82bb6d25 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -419,7 +419,7 @@ void load_state_point() #endif // Read global tally data read_dataset_lowlevel(file_id, "global_tallies", H5T_NATIVE_DOUBLE, - simulation::global_tallies.data(), false); + H5S_ALL, false, simulation::global_tallies.data()); // Check if tally results are present bool present; From 5115e8ca85bd6ce2a925100aec6afb36f3b96116 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 27 Jan 2020 21:57:54 -0600 Subject: [PATCH 03/43] Add .clang-format file --- .clang-format | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000..39cea75656 --- /dev/null +++ b/.clang-format @@ -0,0 +1,111 @@ +--- +Language: Cpp +# BasedOnStyle: Mozilla +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeComma +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeComma +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 90 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 2 +ContinuationIndentWidth: 2 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + - Regex: '.*' + Priority: 1 +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: false +IndentPPDirectives: None +IndentWidth: 2 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 8 +UseTab: Never +... From 8b5ed5f12dd0907ae265e489253ef824f48cbae1 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 27 Jan 2020 22:05:20 -0600 Subject: [PATCH 04/43] All note in style guide about using clang-format --- docs/source/devguide/styleguide.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/source/devguide/styleguide.rst b/docs/source/devguide/styleguide.rst index 562b75e897..a46744a3fe 100644 --- a/docs/source/devguide/styleguide.rst +++ b/docs/source/devguide/styleguide.rst @@ -12,6 +12,14 @@ adding new code in OpenMC. C++ --- +.. important:: To ensure consistent styling with little effort, this project + uses `clang-format `_. The + repository contains a ``.clang-format`` file that can be used to + automatically apply the style rules that are described below. The easiest + way to use clang-format is through a plugin/extension for your editor/IDE + that automatically runs clang-format using the ``.clang-format`` file + whenever a file is saved. + Indentation ----------- From a7238a59c08c44ec3c4d42442b0341c49428f591 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 3 Feb 2020 07:08:54 -0600 Subject: [PATCH 05/43] Apply @smharper suggestions from code review Co-Authored-By: Sterling Harper --- .clang-format | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.clang-format b/.clang-format index 39cea75656..d7ba659f1d 100644 --- a/.clang-format +++ b/.clang-format @@ -2,7 +2,7 @@ Language: Cpp # BasedOnStyle: Mozilla AccessModifierOffset: -2 -AlignAfterOpenBracket: Align +AlignAfterOpenBracket: DontAlign AlignConsecutiveAssignments: false AlignConsecutiveDeclarations: false AlignEscapedNewlines: Right @@ -19,7 +19,7 @@ AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: Yes BinPackArguments: false -BinPackParameters: false +BinPackParameters: true BraceWrapping: AfterClass: false AfterControlStatement: false @@ -39,10 +39,10 @@ BraceWrapping: BreakBeforeBinaryOperators: None BreakBeforeBraces: Custom BreakBeforeInheritanceComma: false -BreakInheritanceList: BeforeComma +BreakInheritanceList: BeforeColon BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false -BreakConstructorInitializers: BeforeComma +BreakConstructorInitializers: BeforeColon BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true ColumnLimit: 90 @@ -55,7 +55,7 @@ Cpp11BracedListStyle: true DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false -FixNamespaceComments: false +FixNamespaceComments: true ForEachMacros: - foreach - Q_FOREACH From f3e9a347b42335dad2caca0793abc0dd4314b2b3 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 3 Feb 2020 07:25:58 -0600 Subject: [PATCH 06/43] Address remaining @smharper comments on #1467 --- .clang-format | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.clang-format b/.clang-format index d7ba659f1d..153f0e4a33 100644 --- a/.clang-format +++ b/.clang-format @@ -18,7 +18,7 @@ AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: Yes -BinPackArguments: false +BinPackArguments: true BinPackParameters: true BraceWrapping: AfterClass: false @@ -38,14 +38,11 @@ BraceWrapping: SplitEmptyNamespace: true BreakBeforeBinaryOperators: None BreakBeforeBraces: Custom -BreakBeforeInheritanceComma: false BreakInheritanceList: BeforeColon BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeColon -BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true -ColumnLimit: 90 +ColumnLimit: 80 CommentPragmas: '^ IWYU pragma:' CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: false From 3813b1cdb12532a58f423301f28ef42e31ba89fb Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 3 Feb 2020 13:35:45 -0600 Subject: [PATCH 07/43] Update results for test_mgxs_library_distribcell to match pandas 1.0 --- .../mgxs_library_distribcell/results_true.dat | 182 +++++++++--------- 1 file changed, 91 insertions(+), 91 deletions(-) diff --git a/tests/regression_tests/mgxs_library_distribcell/results_true.dat b/tests/regression_tests/mgxs_library_distribcell/results_true.dat index 9f58621c12..a24cfb7cef 100644 --- a/tests/regression_tests/mgxs_library_distribcell/results_true.dat +++ b/tests/regression_tests/mgxs_library_distribcell/results_true.dat @@ -1,91 +1,91 @@ - sum(distribcell) group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.457353 0.010474 - sum(distribcell) group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.410174 0.011573 - sum(distribcell) group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.410166 0.011577 - sum(distribcell) group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.066556 0.00251 - sum(distribcell) group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.028979 0.002712 - sum(distribcell) group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.037577 0.001487 - sum(distribcell) group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.092377 0.003628 - sum(distribcell) group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 7.276706e+06 287579.247699 - sum(distribcell) group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.390797 0.008717 - sum(distribcell) group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.387332 0.014241 - sum(distribcell) group in group out legendre nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P0 total 0.387009 0.014230 -1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P1 total 0.047179 0.004923 -2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P2 total 0.015713 0.003654 -3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P3 total 0.005378 0.003137 - sum(distribcell) group in group out legendre nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P0 total 0.387332 0.014241 -1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P1 total 0.047187 0.004933 -2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P2 total 0.015727 0.003654 -3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P3 total 0.005387 0.003141 - sum(distribcell) group in group out nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 1.000834 0.037242 - sum(distribcell) group in group out nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.094516 0.0059 - sum(distribcell) group in group out nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 1.0 0.037213 - sum(distribcell) group in group out legendre nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P0 total 0.390797 0.016955 -1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P1 total 0.047641 0.005091 -2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P2 total 0.015866 0.003708 -3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P3 total 0.005430 0.003170 - sum(distribcell) group in group out legendre nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P0 total 0.391123 0.022356 -1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P1 total 0.047680 0.005395 -2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P2 total 0.015880 0.003758 -3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 P3 total 0.005435 0.003179 - sum(distribcell) group out nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 1.0 0.080455 - sum(distribcell) group out nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 1.0 0.080541 - sum(distribcell) group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 5.139437e-07 2.133314e-08 - sum(distribcell) group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 total 0.091725 0.003604 - sum(distribcell) group in group out nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.093985 0.005872 - sum(distribcell) delayedgroup group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.000021 8.253906e-07 -1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 total 0.000112 4.284000e-06 -2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 total 0.000109 4.105197e-06 -3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 total 0.000252 9.271419e-06 -4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 total 0.000112 3.888624e-06 -5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 total 0.000047 1.625563e-06 - sum(distribcell) delayedgroup group out nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.0 0.000000 -1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 total 1.0 1.414214 -2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 total 1.0 1.414214 -3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 total 0.0 0.000000 -4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 total 0.0 0.000000 -5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 total 1.0 1.414214 - sum(distribcell) delayedgroup group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.000227 0.000012 -1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 total 0.001209 0.000061 -2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 total 0.001177 0.000059 -3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 total 0.002727 0.000135 -4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 total 0.001210 0.000058 -5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 total 0.000504 0.000024 - sum(distribcell) delayedgroup group in nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 total 0.013353 0.000686 -1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 total 0.032613 0.001627 -2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 total 0.121054 0.005911 -3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 total 0.305627 0.014428 -4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 total 0.860892 0.037879 -5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 total 2.891521 0.127879 - sum(distribcell) delayedgroup group in group out nuclide mean std. dev. -0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 1 1 1 total 0.000000 0.000000 -1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 2 1 1 total 0.000175 0.000175 -2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 3 1 1 total 0.000178 0.000178 -3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 4 1 1 total 0.000000 0.000000 -4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 5 1 1 total 0.000000 0.000000 -5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13... 6 1 1 total 0.000178 0.000178 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.457353 0.010474 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.410174 0.011573 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.410166 0.011577 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.066556 0.00251 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.028979 0.002712 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.037577 0.001487 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.092377 0.003628 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 7.276706e+06 287579.247699 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.390797 0.008717 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.387332 0.014241 + sum(distribcell) group in group out legendre nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P0 total 0.387009 0.014230 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P1 total 0.047179 0.004923 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P2 total 0.015713 0.003654 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P3 total 0.005378 0.003137 + sum(distribcell) group in group out legendre nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P0 total 0.387332 0.014241 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P1 total 0.047187 0.004933 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P2 total 0.015727 0.003654 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P3 total 0.005387 0.003141 + sum(distribcell) group in group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 1.000834 0.037242 + sum(distribcell) group in group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 0.094516 0.0059 + sum(distribcell) group in group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 1.0 0.037213 + sum(distribcell) group in group out legendre nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P0 total 0.390797 0.016955 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P1 total 0.047641 0.005091 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P2 total 0.015866 0.003708 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P3 total 0.005430 0.003170 + sum(distribcell) group in group out legendre nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P0 total 0.391123 0.022356 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P1 total 0.047680 0.005395 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P2 total 0.015880 0.003758 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 P3 total 0.005435 0.003179 + sum(distribcell) group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 1.0 0.080455 + sum(distribcell) group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 1.0 0.080541 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 5.139437e-07 2.133314e-08 + sum(distribcell) group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 total 0.091725 0.003604 + sum(distribcell) group in group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 0.093985 0.005872 + sum(distribcell) delayedgroup group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 0.000021 8.253906e-07 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 2 1 total 0.000112 4.284000e-06 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 3 1 total 0.000109 4.105197e-06 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 4 1 total 0.000252 9.271419e-06 +4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 5 1 total 0.000112 3.888624e-06 +5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 6 1 total 0.000047 1.625563e-06 + sum(distribcell) delayedgroup group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 0.0 0.000000 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 2 1 total 1.0 1.414214 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 3 1 total 1.0 1.414214 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 4 1 total 0.0 0.000000 +4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 5 1 total 0.0 0.000000 +5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 6 1 total 1.0 1.414214 + sum(distribcell) delayedgroup group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 0.000227 0.000012 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 2 1 total 0.001209 0.000061 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 3 1 total 0.001177 0.000059 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 4 1 total 0.002727 0.000135 +4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 5 1 total 0.001210 0.000058 +5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 6 1 total 0.000504 0.000024 + sum(distribcell) delayedgroup group in nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 total 0.013353 0.000686 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 2 1 total 0.032613 0.001627 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 3 1 total 0.121054 0.005911 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 4 1 total 0.305627 0.014428 +4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 5 1 total 0.860892 0.037879 +5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 6 1 total 2.891521 0.127879 + sum(distribcell) delayedgroup group in group out nuclide mean std. dev. +0 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 1 1 1 total 0.000000 0.000000 +1 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 2 1 1 total 0.000175 0.000175 +2 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 3 1 1 total 0.000178 0.000178 +3 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 4 1 1 total 0.000000 0.000000 +4 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 5 1 1 total 0.000000 0.000000 +5 ((0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...),) 6 1 1 total 0.000178 0.000178 From efb3beb8ce8db6126ef50eaf2269a8975c3fa409 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 3 Feb 2020 14:43:24 -0600 Subject: [PATCH 08/43] Add expected failure for mgxs_library_distribcell on Python 3.5 --- tests/regression_tests/mgxs_library_distribcell/test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/regression_tests/mgxs_library_distribcell/test.py b/tests/regression_tests/mgxs_library_distribcell/test.py index 5290d313bb..9fe567388e 100644 --- a/tests/regression_tests/mgxs_library_distribcell/test.py +++ b/tests/regression_tests/mgxs_library_distribcell/test.py @@ -1,8 +1,10 @@ import hashlib +import sys import openmc import openmc.mgxs from openmc.examples import pwr_assembly +import pytest from tests.testing_harness import PyAPITestHarness @@ -64,6 +66,8 @@ class MGXSTestHarness(PyAPITestHarness): return outstr +@pytest.mark.xfail(sys.version_info < (3, 6), + reason="Pandas 1.0 API changed and requires Python 3.6+") def test_mgxs_library_distribcell(): model = pwr_assembly() harness = MGXSTestHarness('statepoint.10.h5', model) From 79c35d6c914c4476a38191689c7484ac480a357f Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 7 Feb 2020 12:13:12 -0600 Subject: [PATCH 09/43] Remove depletion chain generation scripts --- scripts/casl_chain.py | 280 ----------------------- scripts/openmc-make-depletion-chain | 46 ---- scripts/openmc-make-depletion-chain-casl | 247 -------------------- 3 files changed, 573 deletions(-) delete mode 100755 scripts/casl_chain.py delete mode 100755 scripts/openmc-make-depletion-chain delete mode 100755 scripts/openmc-make-depletion-chain-casl diff --git a/scripts/casl_chain.py b/scripts/casl_chain.py deleted file mode 100755 index 2edc1b6d94..0000000000 --- a/scripts/casl_chain.py +++ /dev/null @@ -1,280 +0,0 @@ -# This dictionary contains the 255-nuclides, simplified burnup chain used in -# CASL-ORIGEN, which can be found in Appendix A of Kang Seog Kim, "Specification -# for the VERA Depletion Benchmark Suite", CASL-U-2015-1014-000, Rev. 0, -# ORNL/TM-2016/53, 2016. -# -# Note 32 of the 255 nuclides appear twice as they are both activation -# nuclides (category 1) and fission product nuclides (category 3). - -# Te129 has been added due to its link to I129 production. - -CASL_CHAIN = { - # Nuclide: (Stable, CAT, IFPY, Special yield treatment) - # Stable: True if nuclide has no decay reactions - # CAT: Category of nuclides - # 1-Activation nuclides - # 2-Heavy metal nuclides - # 3-Fission product nuclides - # IFPY: Indicator of fission product yield - # 0-Non FPY - # 1-Direct FPY (-1 indicates (stable+metastable) direct FPY) - # 2-Cumulative FPY - # 3-Special treatment with weight fractions - # Special yield: (nuclide_i/weight_i/IFPY_i) - 'B10': (True, 1, 0, None), - 'B11': (True, 1, 0, None), - 'O16': (True, 1, 0, None), - 'Ag107': (True, 1, 0, None), - 'Ag109': (True, 1, 0, None), # redundant as FP - 'Ag110': (False, 1, 0, None), # redundant as FP - 'Cd110': (True, 1, 0, None), # redundant as FP - 'Cd111': (True, 1, 0, None), # redundant as FP - 'Cd112': (True, 1, 0, None), - 'Cd113': (True, 1, 0, None), # redundant as FP - 'Cd114': (True, 1, 0, None), - 'Cd115': (False, 1, 0, None), - 'In113': (True, 1, 0, None), - 'In115': (True, 1, 0, None), # redundant as FP - 'Sm152': (True, 1, 0, None), # redundant as FP - 'Sm153': (False, 1, 0, None), # redundant as FP - 'Eu151': (True, 1, 0, None), # redundant as FP - 'Eu152': (False, 1, 0, None), - 'Eu152_m1': (False, 1, 0, None), - 'Eu153': (True, 1, 0, None), # redundant as FP - 'Eu154': (False, 1, 0, None), # redundant as FP - 'Eu155': (False, 1, 0, None), # redundant as FP - 'Eu156': (False, 1, 0, None), # redundant as FP - 'Eu157': (False, 1, 0, None), # redundant as FP - 'Gd152': (True, 1, 0, None), - 'Gd154': (True, 1, 0, None), # redundant as FP - 'Gd155': (True, 1, 0, None), # redundant as FP - 'Gd156': (True, 1, 0, None), # redundant as FP - 'Gd157': (True, 1, 0, None), # redundant as FP - 'Gd158': (True, 1, 0, None), # redundant as FP - 'Gd159': (False, 1, 0, None), # redundant as FP - 'Gd160': (True, 1, 0, None), # redundant as FP - 'Gd161': (False, 1, 0, None), # redundant as FP - 'Tb159': (True, 1, 0, None), # redundant as FP - 'Tb160': (False, 1, 0, None), # redundant as FP - 'Tb161': (False, 1, 0, None), # redundant as FP - 'Dy160': (True, 1, 0, None), # redundant as FP - 'Dy161': (True, 1, 0, None), # redundant as FP - 'Dy162': (True, 1, 0, None), # redundant as FP - 'Dy163': (True, 1, 0, None), # redundant as FP - 'Dy164': (True, 1, 0, None), # redundant as FP - 'Dy165': (False, 1, 0, None), # redundant as FP - 'Ho165': (True, 1, 0, None), # redundant as FP - 'Er162': (True, 1, 0, None), - 'Er164': (True, 1, 0, None), - 'Er166': (True, 1, 0, None), - 'Er167': (True, 1, 0, None), - 'Er168': (True, 1, 0, None), - 'Er169': (False, 1, 0, None), - 'Er170': (True, 1, 0, None), - 'Er171': (False, 1, 0, None), - 'Tm169': (True, 1, 0, None), - 'Tm170': (False, 1, 0, None), - 'Tm171': (False, 1, 0, None), - 'Hf174': (True, 1, 0, None), - 'Hf176': (True, 1, 0, None), - 'Hf177': (True, 1, 0, None), - 'Hf178': (True, 1, 0, None), - 'Hf179': (True, 1, 0, None), - 'Hf180': (True, 1, 0, None), - 'Hf181': (False, 1, 0, None), - 'Ta181': (True, 1, 0, None), - 'Ta182': (False, 1, 0, None), - 'Th230': (False, 2, 0, None), - 'Th231': (False, 2, 0, None), - 'Th232': (False, 2, 0, None), - 'Th233': (False, 2, 0, None), - 'Th234': (False, 2, 0, None), - 'Pa231': (False, 2, 0, None), - 'Pa232': (False, 2, 0, None), - 'Pa233': (False, 2, 0, None), - 'Pa234': (False, 2, 0, None), - 'U232': (False, 2, 0, None), - 'U233': (False, 2, 0, None), - 'U234': (False, 2, 0, None), - 'U235': (False, 2, 0, None), - 'U236': (False, 2, 0, None), - 'U237': (False, 2, 0, None), - 'U238': (False, 2, 0, None), - 'U239': (False, 2, 0, None), - 'Np236': (False, 2, 0, None), - 'Np237': (False, 2, 0, None), - 'Np238': (False, 2, 0, None), - 'Np239': (False, 2, 0, None), - 'Np240': (False, 2, 0, None), - 'Np240_m1': (False, 2, 0, None), - 'Pu236': (False, 2, 0, None), - 'Pu237': (False, 2, 0, None), - 'Pu238': (False, 2, 0, None), - 'Pu239': (False, 2, 0, None), - 'Pu240': (False, 2, 0, None), - 'Pu241': (False, 2, 0, None), - 'Pu242': (False, 2, 0, None), - 'Pu243': (False, 2, 0, None), - 'Am241': (False, 2, 0, None), - 'Am242': (False, 2, 0, None), - 'Am242_m1': (False, 2, 0, None), - 'Am243': (False, 2, 0, None), - 'Am244': (False, 2, 0, None), - 'Am244_m1': (False, 2, 0, None), - 'Cm242': (False, 2, 0, None), - 'Cm243': (False, 2, 0, None), - 'Cm244': (False, 2, 0, None), - 'Cm245': (False, 2, 0, None), - 'Cm246': (False, 2, 0, None), - 'Br81': (True, 3, 2, None), - 'Br82': (False, 3, 2, None), - 'Kr82': (True, 3, 3, [('Br82_m1', 0.024, 1), ('Kr82', 1.000, 1)]), - 'Kr83': (True, 3, 2, None), - 'Kr84': (True, 3, 2, None), - 'Kr85': (False, 3, 2, None), - 'Kr86': (True, 3, 2, None), - 'Sr89': (False, 3, 2, None), - 'Sr90': (False, 3, 2, None), - 'Y89': (True, 3, 1, None), - 'Y90': (False, 3, 1, None), - 'Y91': (False, 3, 2, None), - 'Zr91': (True, 3, 1, None), - 'Zr93': (False, 3, 2, None), - 'Zr95': (False, 3, 2, None), - 'Zr96': (True, 3, 2, None), - 'Nb95': (False, 3, 3, [('Nb95',1.000, 1), ('Nb95_m1', 0.944, 1)]), - 'Mo95': (True, 3, 3, [('Nb95_m1',0.056, 1), ('Mo95', 1.000, 1)]), - 'Mo96': (True, 3, 3, [('Nb96',1.000, 1), ('Mo96', 1.000, 1)]), - 'Mo97': (True, 3, 2, None), - 'Mo98': (True, 3, 2, None), - 'Mo99': (False, 3, 2, None), - 'Mo100': (True, 3, 2, None), - 'Tc99': (False, 3, 1, None), - 'Tc99_m1': (False, 3, 1, None), - 'Tc100': (False, 3, 1, None), - 'Ru100': (True, 3, 1, None), - 'Ru101': (True, 3, 2, None), - 'Ru102': (True, 3, 2, None), - 'Ru103': (False, 3, 2, None), - 'Ru104': (True, 3, 2, None), - 'Ru105': (False, 3, 2, None), - 'Ru106': (False, 3, 2, None), - 'Rh102': (False, 3, 1, None), - 'Rh102_m1': (False, 3, 1, None), - 'Rh103': (True, 3, 1, None), - 'Rh103_m1': (False, 3, 1, None), - 'Rh104': (False, 3, 1, None), - 'Rh105': (False, 3, 1, None), - 'Rh105_m1': (False, 3, 1, None), - 'Rh106': (False, 3, 1, None), - 'Rh106_m1': (False, 3, 1, None), - 'Pd104': (True, 3, 1, None), - 'Pd105': (True, 3, 1, None), - 'Pd106': (True, 3, 1, None), - 'Pd107': (False, 3, 2, None), - 'Pd108': (True, 3, 2, None), - 'Pd109': (False, 3, 2, None), - 'Ag109': (True, 3, 1, None), - 'Ag109_m1': (False, 3, 1, None), - 'Ag110': (False, 3, 2, None), - 'Ag110_m1': (False, 3, 2, None), - 'Ag111': (False, 3, 2, None), - 'Cd110': (True, 3, 1, None), - 'Cd111': (True, 3, 3, [('Ag110', -1.000, 2), ('Cd110', 1.000, 2), ('Cd111', 1.000, 1)]), - 'Cd113': (True, 3, 2, None), - 'In115': (True, 3, 2, None), - 'Sb121': (True, 3, 2, None), - 'Sb123': (False, 3, 2, None), - 'Sb125': (False, 3, 2, None), - 'Sb127': (False, 3, 2, None), - 'Te127': (False, 3, -1, None), - 'Te127_m1': (False, 3, -1, None), - 'Te129': (False, 3, 1, None), - 'Te129_m1': (False, 3, 2, None), - 'Te132': (False, 3, 2, None), - 'I127': (True, 3, 1, None), - 'I128': (False, 3, 3, [('I128', 0.931, 2)]), - 'I129': (False, 3, 3, [('I129', 1.000, 2), ('I129', -1.000, 2)]), - 'I130': (False, 3, 2, None), - 'I131': (False, 3, 2, None), - 'I132': (False, 3, 1, None), - 'I135': (False, 3, 2, None), - 'Xe128': (True, 3, 1, None), - 'Xe130': (True, 3, 1, None), - 'Xe131': (True, 3, 1, None), - 'Xe132': (True, 3, 1, None), - 'Xe133': (False, 3, 2, None), - 'Xe134': (True, 3, 2, None), - 'Xe135': (False, 3, 1, None), - 'Xe135_m1': (False, 3, 1, None), - 'Xe136': (True, 3, 2, None), - 'Xe137': (False, 3, 2, None), - 'Cs133': (True, 3, 1, None), - 'Cs134': (False, 3, 1, None), - 'Cs135': (False, 3, 1, None), - 'Cs136': (False, 3, 1, None), - 'Cs137': (False, 3, 1, None), - 'Ba134': (True, 3, 1, None), - 'Ba137': (True, 3, 1, None), - 'Ba140': (False, 3, 2, None), - 'La139': (True, 3, 2, None), - 'La140': (False, 3, 1, None), - 'Ce140': (True, 3, 1, None), - 'Ce141': (False, 3, 2, None), - 'Ce142': (True, 3, 2, None), - 'Ce143': (False, 3, 2, None), - 'Ce144': (False, 3, 2, None), - 'Pr141': (True, 3, 1, None), - 'Pr142': (False, 3, 1, None), - 'Pr143': (False, 3, 1, None), - 'Pr144': (False, 3, 1, None), - 'Nd142': (True, 3, 1, None), - 'Nd143': (True, 3, 1, None), - 'Nd144': (False, 3, 1, None), - 'Nd145': (True, 3, 2, None), - 'Nd146': (True, 3, 2, None), - 'Nd147': (False, 3, 2, None), - 'Nd148': (True, 3, 2, None), - 'Nd149': (False, 3, 2, None), - 'Nd150': (True, 3, 2, None), - 'Nd151': (False, 3, 2, None), - 'Pm147': (False, 3, 1, None), - 'Pm148': (False, 3, -1, None), - 'Pm148_m1': (False, 3, -1, None), - 'Pm149': (False, 3, 1, None), - 'Pm150': (False, 3, 1, None), - 'Pm151': (False, 3, 1, None), - 'Sm147': (False, 3, 1, None), - 'Sm148': (False, 3, 1, None), - 'Sm149': (False, 3, 1, None), - 'Sm150': (True, 3, 1, None), - 'Sm151': (False, 3, 1, None), - 'Sm152': (True, 3, 2, None), - 'Sm153': (False, 3, 2, None), - 'Sm154': (True, 3, 2, None), - 'Sm155': (False, 3, 2, None), - 'Eu151': (True, 3, 1, None), - 'Eu153': (True, 3, 1, None), - 'Eu154': (False, 3, 1, None), - 'Eu155': (False, 3, 1, None), - 'Eu156': (False, 3, 2, None), - 'Eu157': (False, 3, 2, None), - 'Gd154': (True, 3, 1, None), - 'Gd155': (True, 3, 1, None), - 'Gd156': (True, 3, 1, None), - 'Gd157': (True, 3, 1, None), - 'Gd158': (True, 3, 2, None), - 'Gd159': (False, 3, 2, None), - 'Gd160': (True, 3, 2, None), - 'Gd161': (False, 3, 2, None), - 'Tb159': (True, 3, 1, None), - 'Tb160': (False, 3, 1, None), - 'Tb161': (False, 3, 1, None), - 'Dy160': (True, 3, 1, None), - 'Dy161': (True, 3, 1, None), - 'Dy162': (True, 3, 2, None), - 'Dy163': (True, 3, 2, None), - 'Dy164': (True, 3, 2, None), - 'Dy165': (False, 3, 2, None), - 'Ho165': (True, 3, 3, [('Dy165_m1', 0.022, 2), ('Ho165', 1.000, 1)]) -} diff --git a/scripts/openmc-make-depletion-chain b/scripts/openmc-make-depletion-chain deleted file mode 100755 index 01f009a2a0..0000000000 --- a/scripts/openmc-make-depletion-chain +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python3 - -import os -from pathlib import Path -from zipfile import ZipFile - -from openmc._utils import download -import openmc.deplete - - -URLS = [ - 'https://www.nndc.bnl.gov/endf/b7.1/zips/ENDF-B-VII.1-neutrons.zip', - 'https://www.nndc.bnl.gov/endf/b7.1/zips/ENDF-B-VII.1-decay.zip', - 'https://www.nndc.bnl.gov/endf/b7.1/zips/ENDF-B-VII.1-nfy.zip' -] - -def main(): - endf_dir = os.environ.get("OPENMC_ENDF_DATA") - if endf_dir is not None: - endf_dir = Path(endf_dir) - elif all(os.path.isdir(lib) for lib in ("neutrons", "decay", "nfy")): - endf_dir = Path(".") - else: - for url in URLS: - basename = download(url) - with ZipFile(basename, 'r') as zf: - print('Extracting {}...'.format(basename)) - zf.extractall() - endf_dir = Path(".") - - decay_files = tuple((endf_dir / "decay").glob("*endf")) - neutron_files = tuple((endf_dir / "neutrons").glob("*endf")) - nfy_files = tuple((endf_dir / "nfy").glob("*endf")) - - # check files exist - for flist, ftype in [(decay_files, "decay"), (neutron_files, "neutron"), - (nfy_files, "neutron fission product yield")]: - if not flist: - raise IOError("No {} endf files found in {}".format(ftype, endf_dir)) - - chain = openmc.deplete.Chain.from_endf(decay_files, nfy_files, neutron_files) - chain.export_to_xml('chain_endfb71.xml') - - -if __name__ == '__main__': - main() diff --git a/scripts/openmc-make-depletion-chain-casl b/scripts/openmc-make-depletion-chain-casl deleted file mode 100755 index 9da3b01c32..0000000000 --- a/scripts/openmc-make-depletion-chain-casl +++ /dev/null @@ -1,247 +0,0 @@ -#!/usr/bin/env python3 - -import glob -import os -from zipfile import ZipFile -from collections import OrderedDict, defaultdict -from io import StringIO -from itertools import chain - -try: - import lxml.etree as ET - _have_lxml = True -except ImportError: - import xml.etree.ElementTree as ET - _have_lxml = False - -import openmc.data -import openmc.deplete -from openmc._xml import clean_indentation -from openmc.deplete.chain import _REACTIONS -from openmc.deplete.nuclide import Nuclide, DecayTuple, ReactionTuple, \ - FissionYieldDistribution -from openmc._utils import download - -from casl_chain import CASL_CHAIN - -URLS = [ - 'https://www.nndc.bnl.gov/endf/b7.1/zips/ENDF-B-VII.1-neutrons.zip', - 'https://www.nndc.bnl.gov/endf/b7.1/zips/ENDF-B-VII.1-decay.zip', - 'https://www.nndc.bnl.gov/endf/b7.1/zips/ENDF-B-VII.1-nfy.zip' -] - -def main(): - if os.path.isdir('./decay') and os.path.isdir('./nfy') and os.path.isdir('./neutrons'): - endf_dir = '.' - elif 'OPENMC_ENDF_DATA' in os.environ: - endf_dir = os.environ['OPENMC_ENDF_DATA'] - else: - for url in URLS: - basename = download(url) - with ZipFile(basename, 'r') as zf: - print('Extracting {}...'.format(basename)) - zf.extractall() - endf_dir = '.' - - decay_files = glob.glob(os.path.join(endf_dir, 'decay', '*.endf')) - fpy_files = glob.glob(os.path.join(endf_dir, 'nfy', '*.endf')) - neutron_files = glob.glob(os.path.join(endf_dir, 'neutrons', '*.endf')) - - # Create a Chain - chain = openmc.deplete.Chain() - - print('Reading ENDF nuclear data from "{}"...'.format(os.path.abspath(endf_dir))) - - # Create dictionary mapping target to filename - print('Processing neutron sub-library files...') - reactions = {} - for f in neutron_files: - evaluation = openmc.data.endf.Evaluation(f) - nuc_name = evaluation.gnd_name - if nuc_name in CASL_CHAIN: - reactions[nuc_name] = {} - for mf, mt, nc, mod in evaluation.reaction_list: - # Q value for each reaction is given in MF=3 - if mf == 3: - file_obj = StringIO(evaluation.section[3, mt]) - openmc.data.endf.get_head_record(file_obj) - q_value = openmc.data.endf.get_cont_record(file_obj)[1] - reactions[nuc_name][mt] = q_value - - # Determine what decay and FPY nuclides are available - print('Processing decay sub-library files...') - decay_data = {} - for f in decay_files: - decay_obj = openmc.data.Decay(f) - nuc_name = decay_obj.nuclide['name'] - if nuc_name in CASL_CHAIN: - decay_data[nuc_name] = decay_obj - - for nuc_name in CASL_CHAIN: - if nuc_name not in decay_data: - print('WARNING: {} has no decay data!'.format(nuc_name)) - - print('Processing fission product yield sub-library files...') - fpy_data = {} - for f in fpy_files: - fpy_obj = openmc.data.FissionProductYields(f) - name = fpy_obj.nuclide['name'] - if name in CASL_CHAIN: - fpy_data[name] = fpy_obj - - print('Creating depletion_chain...') - missing_daughter = [] - missing_rx_product = [] - missing_fpy = [] - - for idx, parent in enumerate(sorted(decay_data, key=openmc.data.zam)): - data = decay_data[parent] - - nuclide = Nuclide() - nuclide.name = parent - - chain.nuclides.append(nuclide) - chain.nuclide_dict[parent] = idx - - if not CASL_CHAIN[parent][0] and \ - not data.nuclide['stable'] and data.half_life.nominal_value != 0.0: - nuclide.half_life = data.half_life.nominal_value - nuclide.decay_energy = sum(E.nominal_value for E in - data.average_energies.values()) - sum_br = 0.0 - for i, mode in enumerate(data.modes): - decay_type = ','.join(mode.modes) - if mode.daughter in decay_data: - target = mode.daughter - else: - missing_daughter.append((parent, mode)) - continue - - # Write branching ratio, taking care to ensure sum is unity by - # slightly modifying last value if necessary - br = mode.branching_ratio.nominal_value - sum_br += br - if i == len(data.modes) - 1 and sum_br != 1.0: - br = 1.0 - sum(m.branching_ratio.nominal_value - for m in data.modes[:-1]) - - # Append decay mode - nuclide.decay_modes.append(DecayTuple(decay_type, target, br)) - - # If nuclide has incident neutron data, we need to list what - # transmutation reactions are possible - if parent in reactions: - reactions_available = reactions[parent].keys() - for name, mts, changes in _REACTIONS: - if mts & reactions_available: - delta_A, delta_Z = changes - A = data.nuclide['mass_number'] + delta_A - Z = data.nuclide['atomic_number'] + delta_Z - daughter = '{}{}'.format(openmc.data.ATOMIC_SYMBOL[Z], A) - - if name not in chain.reactions: - chain.reactions.append(name) - - if daughter not in decay_data: - missing_rx_product.append((parent, name, daughter)) - daughter = 'Nothing' - - # Store Q value -- use sorted order so we get summation - # reactions (e.g., MT=103) first - for mt in sorted(mts): - if mt in reactions[parent]: - q_value = reactions[parent][mt] - break - else: - q_value = 0.0 - - nuclide.reactions.append(ReactionTuple( - name, daughter, q_value, 1.0)) - - # Check for fission reactions - if any(mt in reactions_available for mt in [18, 19, 20, 21, 38]): - if parent in fpy_data: - q_value = reactions[parent][18] - nuclide.reactions.append( - ReactionTuple('fission', 0, q_value, 1.0)) - - if 'fission' not in chain.reactions: - chain.reactions.append('fission') - else: - missing_fpy.append(parent) - - if parent in fpy_data: - fpy = fpy_data[parent] - - if fpy.energies is not None: - yield_energies = fpy.energies - else: - yield_energies = [0.0] - - yield_data = {} - for E, table_yd, table_yc in zip(yield_energies, fpy.independent, fpy.cumulative): - yields = defaultdict(float) - for product in table_yd: - if product in decay_data: - # identifier - ifpy = CASL_CHAIN[product][2] - # 1 for independent - if ifpy == 1: - if product not in table_yd: - print('No independent fission yields found for {} in {}'.format(product, parent)) - else: - yields[product] += table_yd[product].nominal_value - # 2 for cumulative - elif ifpy == 2: - if product not in table_yc: - print('No cumulative fission yields found for {} in {}'.format(product, parent)) - else: - yields[product] += table_yc[product].nominal_value - # -1 for independent (stable + metastable) - elif ifpy == -1: - if product not in table_yd: - print('No independent fission yields found for {} in {}'.format(product, parent)) - else: - yields[product] += table_yc[product].nominal_value - product_meta = '{}_m1'.format(product) - if product_meta in table_yd: - yields[product] += table_yc[product_meta].nominal_value - # 3 for special treatment with weight fractions - elif ifpy == 3: - for name_i, weight_i, ifpy_i in CASL_CHAIN[product][3]: - if name_i not in table_yd: - print('No fission yields found for {} in {}'.format(name_i, parent)) - else: - if ifpy_i == 1: - yields[product] += weight_i * table_yd[name_i].nominal_value - elif ifpy_i == 2: - yields[product] += weight_i * table_yc[name_i].nominal_value - - yield_data[E] = yields - - nuclide.yield_data = FissionYieldDistribution(yield_data) - - # Display warnings - if missing_daughter: - print('The following decay modes have daughters with no decay data:') - for parent, mode in missing_daughter: - print(' {} -> {} ({})'.format(parent, mode.daughter, ','.join(mode.modes))) - print('') - - if missing_rx_product: - print('The following reaction products have no decay data:') - for vals in missing_rx_product: - print('{} {} -> {}'.format(*vals)) - print('') - - if missing_fpy: - print('The following fissionable nuclides have no fission product yields:') - for parent in missing_fpy: - print(' ' + parent) - print('') - - chain.export_to_xml('chain_casl.xml') - - -if __name__ == '__main__': - main() From d45583ed1914a40ae699ca5364eba66bc732fd49 Mon Sep 17 00:00:00 2001 From: Gavin Ridley Date: Fri, 7 Feb 2020 15:16:02 -0500 Subject: [PATCH 10/43] add some getters to 1D distributions --- include/openmc/distribution.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/openmc/distribution.h b/include/openmc/distribution.h index f9d718cdb1..33ff2ffcbf 100644 --- a/include/openmc/distribution.h +++ b/include/openmc/distribution.h @@ -62,6 +62,9 @@ public: //! \param seed Pseudorandom number seed pointer //! \return Sampled value double sample(uint64_t* seed) const; + + double a() const { return a_; } + double b() const { return a_; } private: double a_; //!< Lower bound of distribution double b_; //!< Upper bound of distribution @@ -80,6 +83,8 @@ public: //! \param seed Pseudorandom number seed pointer //! \return Sampled value double sample(uint64_t* seed) const; + + double theta() const { return theta_; } private: double theta_; //!< Factor in exponential [eV] }; @@ -97,6 +102,9 @@ public: //! \param seed Pseudorandom number seed pointer //! \return Sampled value double sample(uint64_t* seed) const; + + double a() const { return a_; } + double b() const { return b_; } private: double a_; //!< Factor in exponential [eV] double b_; //!< Factor in square root [1/eV] @@ -115,6 +123,9 @@ public: //! \param seed Pseudorandom number seed pointer //! \return Sampled value double sample(uint64_t* seed) const; + + double mean_value() const { return mean_value_; } + double std_dev() const { return std_dev_; } private: double mean_value_; //!< middle of distribution [eV] double std_dev_; //!< standard deviation [eV] @@ -134,6 +145,10 @@ public: //! \param seed Pseudorandom number seed pointer //! \return Sampled value double sample(uint64_t* seed) const; + + double e0() const { return e0_; } + double m_rat() const { return m_rat_; } + double kt() const { return kt_; } private: // example DT fusion m_rat = 5 (D = 2 + T = 3) // ion temp = 20000 eV @@ -161,6 +176,8 @@ public: // x property std::vector& x() { return x_; } const std::vector& x() const { return x_; } + const std::vector& p() const { return p_; } + Interpolation interp() const { return interp_; } private: std::vector x_; //!< tabulated independent variable std::vector p_; //!< tabulated probability density @@ -188,6 +205,8 @@ public: //! \param seed Pseudorandom number seed pointer //! \return Sampled value double sample(uint64_t* seed) const; + + const std::vector& x() const { return x_; } private: std::vector x_; //! Possible outcomes }; From 9d0649d1dd4b0fffb9a618f16aaf89b9b2e7e500 Mon Sep 17 00:00:00 2001 From: Gavin Ridley Date: Fri, 7 Feb 2020 16:42:10 -0500 Subject: [PATCH 11/43] fix typo --- include/openmc/distribution.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/openmc/distribution.h b/include/openmc/distribution.h index 33ff2ffcbf..92c10aed3e 100644 --- a/include/openmc/distribution.h +++ b/include/openmc/distribution.h @@ -64,7 +64,7 @@ public: double sample(uint64_t* seed) const; double a() const { return a_; } - double b() const { return a_; } + double b() const { return b_; } private: double a_; //!< Lower bound of distribution double b_; //!< Upper bound of distribution From b534c947a504d854ae4c4e3fe48340bfdae62139 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sun, 9 Feb 2020 21:57:49 -0600 Subject: [PATCH 12/43] Bug fix for reading output settings in Settings.from_xml --- openmc/settings.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/openmc/settings.py b/openmc/settings.py index 3730d7bd74..eb2f926f3a 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -385,11 +385,11 @@ class Settings(object): @property def dagmc(self): return self._dagmc - + @property def event_based(self): return self._event_based - + @property def max_particles_in_flight(self): return self._max_particles_in_flight @@ -721,12 +721,12 @@ class Settings(object): def delayed_photon_scaling(self, value): cv.check_type('delayed photon scaling', value, bool) self._delayed_photon_scaling = value - + @event_based.setter def event_based(self, value): cv.check_type('event based', value, bool) self._event_based = value - + @max_particles_in_flight.setter def max_particles_in_flight(self, value): cv.check_type('max particles in flight', value, Integral) @@ -976,12 +976,12 @@ class Settings(object): if self._delayed_photon_scaling is not None: elem = ET.SubElement(root, "delayed_photon_scaling") elem.text = str(self._delayed_photon_scaling).lower() - + def _create_event_based_subelement(self, root): if self._event_based is not None: elem = ET.SubElement(root, "event_based") elem.text = str(self._event_based).lower() - + def _create_max_particles_in_flight_subelement(self, root): if self._max_particles_in_flight is not None: elem = ET.SubElement(root, "max_particles_in_flight") @@ -1056,7 +1056,7 @@ class Settings(object): if value is not None: if key in ('summary', 'tallies'): value = value in ('true', '1') - self.output[key] = value + self.output[key] = value def _statepoint_from_xml_element(self, root): elem = root.find('state_point') @@ -1227,12 +1227,12 @@ class Settings(object): text = get_text(root, 'delayed_photon_scaling') if text is not None: self.delayed_photon_scaling = text in ('true', '1') - + def _event_based_from_xml_element(self, root): text = get_text(root, 'event_based') if text is not None: self.event_based = text in ('true', '1') - + def _max_particles_in_flight_from_xml_element(self, root): text = get_text(root, 'max_particles_in_flight') if text is not None: From f91d69128842c9d2d3295ac03b4a124a3af6b8e1 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sun, 12 Jan 2020 23:23:55 -0600 Subject: [PATCH 13/43] Update GSL to latest version --- CMakeLists.txt | 5 +++-- vendor/gsl-lite | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 80909b83c0..212e55cdae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -161,7 +161,8 @@ target_link_libraries(xtensor INTERFACE xtl) add_subdirectory(vendor/gsl-lite) # Make sure contract violations throw exceptions -target_compile_definitions(gsl-lite INTERFACE GSL_THROW_ON_CONTRACT_VIOLATION) +target_compile_definitions(gsl-lite-v1 INTERFACE GSL_THROW_ON_CONTRACT_VIOLATION) +target_compile_definitions(gsl-lite-v1 INTERFACE gsl_CONFIG_ALLOWS_NONSTRICT_SPAN_COMPARISON=1) #=============================================================================== # RPATH information @@ -345,7 +346,7 @@ endif() # target_link_libraries treats any arguments starting with - but not -l as # linker flags. Thus, we can pass both linker flags and libraries together. target_link_libraries(libopenmc ${ldflags} ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES} - pugixml faddeeva xtensor gsl-lite) + pugixml faddeeva xtensor gsl-lite-v1) if(dagmc) target_compile_definitions(libopenmc PRIVATE DAGMC) diff --git a/vendor/gsl-lite b/vendor/gsl-lite index 93607223a4..a5706326ed 160000 --- a/vendor/gsl-lite +++ b/vendor/gsl-lite @@ -1 +1 @@ -Subproject commit 93607223a48621dae3cedd6b3335431b38067fae +Subproject commit a5706326ed116c315c0e12b72ed39439aff2222f From 8f242d0b07dd182148400aa76ab645575f13b022 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sun, 19 Jan 2020 10:28:34 -0600 Subject: [PATCH 14/43] Avoid narrowing warnings on index_ members --- src/material.cpp | 3 ++- src/tallies/filter.cpp | 6 ++++-- src/tallies/tally.cpp | 5 +++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/material.cpp b/src/material.cpp index 570c28bcbe..6ee8749351 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -47,8 +47,9 @@ std::vector> materials; //============================================================================== Material::Material(pugi::xml_node node) - : index_{model::materials.size()} { + index_ = model::materials.size(); // Avoids warning about narrowing + if (check_for_node(node, "id")) { this->set_id(std::stoi(get_node_value(node, "id"))); } else { diff --git a/src/tallies/filter.cpp b/src/tallies/filter.cpp index 689abde605..afe47fbd09 100644 --- a/src/tallies/filter.cpp +++ b/src/tallies/filter.cpp @@ -57,8 +57,10 @@ extern "C" size_t tally_filters_size() // Filter implementation //============================================================================== -Filter::Filter() : index_{model::tally_filters.size()} -{ } +Filter::Filter() +{ + index_ = model::tally_filters.size(); // Avoids warning about narrowing +} Filter::~Filter() { diff --git a/src/tallies/tally.cpp b/src/tallies/tally.cpp index 49bfd901ab..22d0e2e041 100644 --- a/src/tallies/tally.cpp +++ b/src/tallies/tally.cpp @@ -244,15 +244,16 @@ score_str_to_int(std::string score_str) //============================================================================== Tally::Tally(int32_t id) - : index_{model::tallies.size()} { + index_ = model::tallies.size(); // Avoids warning about narrowing this->set_id(id); this->set_filters({}); } Tally::Tally(pugi::xml_node node) - : index_{model::tallies.size()} { + index_ = model::tallies.size(); // Avoids warning about narrowing + // Copy and set tally id if (!check_for_node(node, "id")) { throw std::runtime_error{"Must specify id for tally in tally XML file."}; From da53b433750df43e7015610a54d1021e7ca17405 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 13 Jan 2020 07:02:06 -0600 Subject: [PATCH 15/43] Add {fmt} modern formatting library as dependency --- .gitmodules | 3 +++ CMakeLists.txt | 9 ++++++++- vendor/fmt | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) create mode 160000 vendor/fmt diff --git a/.gitmodules b/.gitmodules index 4e2f341674..ff91200103 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "vendor/xtl"] path = vendor/xtl url = https://github.com/xtensor-stack/xtl.git +[submodule "vendor/fmt"] + path = vendor/fmt + url = https://github.com/fmtlib/fmt.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 212e55cdae..ec6b500b45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,6 +140,13 @@ endif() add_subdirectory(vendor/pugixml) +#=============================================================================== +# {fmt} library +#=============================================================================== + +set(FMT_INSTALL ON CACHE BOOL "Generate the install target.") +add_subdirectory(vendor/fmt) + #=============================================================================== # xtensor header-only library #=============================================================================== @@ -346,7 +353,7 @@ endif() # target_link_libraries treats any arguments starting with - but not -l as # linker flags. Thus, we can pass both linker flags and libraries together. target_link_libraries(libopenmc ${ldflags} ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES} - pugixml faddeeva xtensor gsl-lite-v1) + pugixml faddeeva xtensor gsl-lite-v1 fmt::fmt) if(dagmc) target_compile_definitions(libopenmc PRIVATE DAGMC) diff --git a/vendor/fmt b/vendor/fmt new file mode 160000 index 0000000000..65ac626c58 --- /dev/null +++ b/vendor/fmt @@ -0,0 +1 @@ +Subproject commit 65ac626c5856f5aad1f1542e79407a6714357043 From 570433b9170f847923a5d512a041558f49a8deb1 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 13 Jan 2020 07:32:16 -0600 Subject: [PATCH 16/43] Start using fmt::format in code --- src/cell.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index d56e877d3f..9e640ce4ed 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -8,7 +8,10 @@ #include #include #include + + #include +#include #include "openmc/capi.h" #include "openmc/constants.h" @@ -83,9 +86,8 @@ tokenize(const std::string region_spec) { i++; } else { - std::stringstream err_msg; - err_msg << "Region specification contains invalid character, \"" - << region_spec[i] << "\""; + auto err_msg = fmt::format( + "Region specification contains invalid character, \"{}\"", region_spec[i]); fatal_error(err_msg); } } From 843c136d36ff8517b8c95fd2d8ca802cea95abc7 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sun, 19 Jan 2020 16:18:48 -0600 Subject: [PATCH 17/43] Convert most uses of iostreams in output.cpp to fmt::print --- src/output.cpp | 303 ++++++++++++++++++++----------------------------- 1 file changed, 123 insertions(+), 180 deletions(-) diff --git a/src/output.cpp b/src/output.cpp index 4744385c19..f32d4c2598 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -11,6 +11,7 @@ #include #include // for pair +#include #ifdef _OPENMP #include #endif @@ -44,53 +45,53 @@ namespace openmc { void title() { - std::cout << - " %%%%%%%%%%%%%%%\n" << - " %%%%%%%%%%%%%%%%%%%%%%%%\n" << - " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" << - " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" << - " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" << - " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" << - " %%%%%%%%%%%%%%%%%%%%%%%%\n" << - " %%%%%%%%%%%%%%%%%%%%%%%%\n" << - " ############### %%%%%%%%%%%%%%%%%%%%%%%%\n" << - " ################## %%%%%%%%%%%%%%%%%%%%%%%\n" << - " ################### %%%%%%%%%%%%%%%%%%%%%%%\n" << - " #################### %%%%%%%%%%%%%%%%%%%%%%\n" << - " ##################### %%%%%%%%%%%%%%%%%%%%%\n" << - " ###################### %%%%%%%%%%%%%%%%%%%%\n" << - " ####################### %%%%%%%%%%%%%%%%%%\n" << - " ####################### %%%%%%%%%%%%%%%%%\n" << - " ###################### %%%%%%%%%%%%%%%%%\n" << - " #################### %%%%%%%%%%%%%%%%%\n" << - " ################# %%%%%%%%%%%%%%%%%\n" << - " ############### %%%%%%%%%%%%%%%%\n" << - " ############ %%%%%%%%%%%%%%%\n" << - " ######## %%%%%%%%%%%%%%\n" << - " %%%%%%%%%%%\n\n"; + fmt::print( + " %%%%%%%%%%%%%%%\n" + " %%%%%%%%%%%%%%%%%%%%%%%%\n" + " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" + " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" + " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" + " %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n" + " %%%%%%%%%%%%%%%%%%%%%%%%\n" + " %%%%%%%%%%%%%%%%%%%%%%%%\n" + " ############### %%%%%%%%%%%%%%%%%%%%%%%%\n" + " ################## %%%%%%%%%%%%%%%%%%%%%%%\n" + " ################### %%%%%%%%%%%%%%%%%%%%%%%\n" + " #################### %%%%%%%%%%%%%%%%%%%%%%\n" + " ##################### %%%%%%%%%%%%%%%%%%%%%\n" + " ###################### %%%%%%%%%%%%%%%%%%%%\n" + " ####################### %%%%%%%%%%%%%%%%%%\n" + " ####################### %%%%%%%%%%%%%%%%%\n" + " ###################### %%%%%%%%%%%%%%%%%\n" + " #################### %%%%%%%%%%%%%%%%%\n" + " ################# %%%%%%%%%%%%%%%%%\n" + " ############### %%%%%%%%%%%%%%%%\n" + " ############ %%%%%%%%%%%%%%%\n" + " ######## %%%%%%%%%%%%%%\n" + " %%%%%%%%%%%\n\n"); // Write version information - std::cout << - " | The OpenMC Monte Carlo Code\n" << - " Copyright | 2011-2020 MIT and OpenMC contributors\n" << - " License | http://openmc.readthedocs.io/en/latest/license.html\n" << - " Version | " << VERSION_MAJOR << '.' << VERSION_MINOR << '.' - << VERSION_RELEASE << (VERSION_DEV ? "-dev" : "") << '\n'; + fmt::print( + " | The OpenMC Monte Carlo Code\n" + " Copyright | 2011-2020 MIT and OpenMC contributors\n" + " License | http://openmc.readthedocs.io/en/latest/license.html\n" + " Version | {}.{}.{}{}\n", VERSION_MAJOR, VERSION_MINOR, + VERSION_RELEASE, VERSION_DEV ? "-dev" : ""); #ifdef GIT_SHA1 - std::cout << " Git SHA1 | " << GIT_SHA1 << '\n'; + fmt::print(" Git SHA1 | {}\n", GIT_SHA1); #endif // Write the date and time - std::cout << " Date/Time | " << time_stamp() << '\n'; + fmt::print(" Date/Time | {}\n", time_stamp()); #ifdef OPENMC_MPI // Write number of processors - std::cout << " MPI Processes | " << mpi::n_procs << '\n'; + fmt::print(" MPI Processes | {}\n", mpi::n_procs); #endif #ifdef _OPENMP // Write number of OpenMP threads - std::cout << " OpenMP Threads | " << omp_get_max_threads() << '\n'; + fmt::print(" OpenMP Threads | {}\n", omp_get_max_threads()); #endif std::cout << std::endl; } @@ -146,64 +147,61 @@ extern "C" void print_particle(Particle* p) // Display particle type and ID. switch (p->type_) { case Particle::Type::neutron: - std::cout << "Neutron "; + fmt::print("Neutron "); break; case Particle::Type::photon: - std::cout << "Photon "; + fmt::print("Photon "); break; case Particle::Type::electron: - std::cout << "Electron "; + fmt::print("Electron "); break; case Particle::Type::positron: - std::cout << "Positron "; + fmt::print("Positron "); break; default: - std::cout << "Unknown Particle "; + fmt::print("Unknown Particle "); } - std::cout << p->id_ << "\n"; + fmt::print("{}\n", p->id_); // Display particle geometry hierarchy. for (auto i = 0; i < p->n_coord_; i++) { - std::cout << " Level " << i << "\n"; + fmt::print(" Level {}\n", i); if (p->coord_[i].cell != C_NONE) { const Cell& c {*model::cells[p->coord_[i].cell]}; - std::cout << " Cell = " << c.id_ << "\n"; + fmt::print(" Cell = {}\n", c.id_); } if (p->coord_[i].universe != C_NONE) { const Universe& u {*model::universes[p->coord_[i].universe]}; - std::cout << " Universe = " << u.id_ << "\n"; + fmt::print(" Universe = {}\n", u.id_); } if (p->coord_[i].lattice != C_NONE) { const Lattice& lat {*model::lattices[p->coord_[i].lattice]}; - std::cout << " Lattice = " << lat.id_ << "\n"; - std::cout << " Lattice position = (" << p->coord_[i].lattice_x - << "," << p->coord_[i].lattice_y << "," - << p->coord_[i].lattice_z << ")\n"; + fmt::print(" Lattice = {}\n", lat.id_); + fmt::print(" Lattice position = ({},{},{})\n", p->coord_[i].lattice_x, + p->coord_[i].lattice_y, p->coord_[i].lattice_z); } - std::cout << " r = (" << p->coord_[i].r.x << ", " - << p->coord_[i].r.y << ", " << p->coord_[i].r.z << ")\n"; - std::cout << " u = (" << p->coord_[i].u.x << ", " - << p->coord_[i].u.y << ", " << p->coord_[i].u.z << ")\n"; + fmt::print(" r = "); + std::cout << p->coord_[i].r << '\n'; + fmt::print(" u = "); + std::cout << p->coord_[i].u << '\n'; } // Display miscellaneous info. if (p->surface_ != 0) { const Surface& surf {*model::surfaces[std::abs(p->surface_)-1]}; - std::cout << " Surface = " << std::copysign(surf.id_, p->surface_) << "\n"; + fmt::print(" Surface = {}\n", std::copysign(surf.id_, p->surface_)); } - std::cout << " Weight = " << p->wgt_ << "\n"; + fmt::print(" Weight = {}\n", p->wgt_); if (settings::run_CE) { - std::cout << " Energy = " << p->E_ << "\n"; + fmt::print(" Energy = {}\n", p->E_); } else { - std::cout << " Energy Group = " << p->g_ << "\n"; + fmt::print(" Energy Group = {}\n", p->g_); } - std::cout << " Delayed Group = " << p->delayed_group_ << "\n"; - - std::cout << "\n"; + fmt::print(" Delayed Group = {}\n\n", p->delayed_group_); } //============================================================================== @@ -215,65 +213,53 @@ void print_plot() for (auto pl : model::plots) { // Plot id - std::cout << "Plot ID: " << pl.id_ << "\n"; + fmt::print("Plot ID: {}\n", pl.id_); // Plot filename - std::cout << "Plot file: " << pl.path_plot_ << "\n"; + fmt::print("Plot file: {}\n", pl.path_plot_); // Plot level - std::cout << "Universe depth: " << pl.level_ << "\n"; + fmt::print("Universe depth: {}\n", pl.level_); // Plot type if (PlotType::slice == pl.type_) { - std::cout << "Plot Type: Slice" << "\n"; + fmt::print("Plot Type: Slice\n"); } else if (PlotType::voxel == pl.type_) { - std::cout << "Plot Type: Voxel" << "\n"; + fmt::print("Plot Type: Voxel\n"); } // Plot parameters - std::cout << "Origin: " << pl.origin_[0] << " " - << pl.origin_[1] << " " - << pl.origin_[2] << "\n"; + fmt::print("Origin: {} {} {}\n", pl.origin_[0], pl.origin_[1], pl.origin_[2]); if (PlotType::slice == pl.type_) { - std::cout << std::setprecision(4) - << "Width: " - << pl.width_[0] << " " - << pl.width_[1] << "\n"; + fmt::print("Width: {:4} {:4}\n", pl.width_[0], pl.width_[1]); } else if (PlotType::voxel == pl.type_) { - std::cout << std::setprecision(4) - << "Width: " - << pl.width_[0] << " " - << pl.width_[1] << " " - << pl.width_[2] << "\n"; + fmt::print("Width: {:4} {:4} {:4}\n", pl.width_[0], pl.width_[1], + pl.width_[2]); } if (PlotColorBy::cells == pl.color_by_) { - std::cout << "Coloring: Cells" << "\n"; + fmt::print("Coloring: Cells\n"); } else if (PlotColorBy::mats == pl.color_by_) { - std::cout << "Coloring: Materials" << "\n"; + fmt::print("Coloring: Materials\n"); } if (PlotType::slice == pl.type_) { switch(pl.basis_) { case PlotBasis::xy: - std::cout << "Basis: XY" << "\n"; + fmt::print("Basis: XY\n"); break; case PlotBasis::xz: - std::cout << "Basis: XZ" << "\n"; + fmt::print("Basis: XZ\n"); break; case PlotBasis::yz: - std::cout << "Basis: YZ" << "\n"; + fmt::print("Basis: YZ\n"); break; } - std::cout << "Pixels: " << pl.pixels_[0] << " " - << pl.pixels_[1] << " " << "\n"; + fmt::print("Pixels: {} {}\n", pl.pixels_[0], pl.pixels_[1]); } else if (PlotType::voxel == pl.type_) { - std::cout << "Voxels: " << pl.pixels_[0] << " " - << pl.pixels_[1] << " " - << pl.pixels_[2] << "\n"; + fmt::print("Voxels: {} {} {}\n", pl.pixels_[0], pl.pixels_[1], pl.pixels_[2]); } - std::cout << "\n"; - + fmt::print("\n"); } } @@ -291,23 +277,22 @@ print_overlap_check() if (mpi::master) { header("cell overlap check summary", 1); - std::cout << " Cell ID No. Overlap Checks\n"; + fmt::print(" Cell ID No. Overlap Checks\n"); std::vector sparse_cell_ids; for (int i = 0; i < model::cells.size(); i++) { - std::cout << " " << std::setw(8) << model::cells[i]->id_ << std::setw(17) - << model::overlap_check_count[i] << "\n"; + fmt::print(" {:8}{:17}\n", model::cells[i]->id_, model::overlap_check_count[i]); if (model::overlap_check_count[i] < 10) { sparse_cell_ids.push_back(model::cells[i]->id_); } } - std::cout << "\n There were " << sparse_cell_ids.size() - << " cells with less than 10 overlap checks\n"; + fmt::print("\n There were {} cells with less than 10 overlap checks\n", + sparse_cell_ids.size()); for (auto id : sparse_cell_ids) { - std::cout << " " << id; + fmt::print(" {}", id); } - std::cout << "\n"; + fmt::print("\n"); } } @@ -316,7 +301,7 @@ print_overlap_check() void print_usage() { if (mpi::master) { - std::cout << + fmt::print( "Usage: openmc [options] [directory]\n\n" "Options:\n" " -c, --volume Run in stochastic volume calculation mode\n" @@ -329,7 +314,7 @@ void print_usage() " -t, --track Write tracks for all particles\n" " -e, --event Run using event-based parallelism\n" " -v, --version Show version information\n" - " -h, --help Show this message\n"; + " -h, --help Show this message\n"); } } @@ -338,14 +323,14 @@ void print_usage() void print_version() { if (mpi::master) { - std::cout << "OpenMC version " << VERSION_MAJOR << '.' << VERSION_MINOR - << '.' << VERSION_RELEASE << '\n'; + fmt::print("OpenMC version {}.{}.{}\n", VERSION_MAJOR, VERSION_MINOR, + VERSION_RELEASE); #ifdef GIT_SHA1 - std::cout << "Git SHA1: " << GIT_SHA1 << '\n'; + fmt::print("Git SHA1: {}\n", GIT_SHA1); #endif - std::cout << "Copyright (c) 2011-2019 Massachusetts Institute of " + fmt::print("Copyright (c) 2011-2019 Massachusetts Institute of " "Technology and OpenMC contributors\nMIT/X license at " - "\n"; + "\n"); } } @@ -354,13 +339,13 @@ void print_version() void print_columns() { if (settings::entropy_on) { - std::cout << + fmt::print( " Bat./Gen. k Entropy Average k \n" - " ========= ======== ======== ====================\n"; + " ========= ======== ======== ====================\n"); } else { - std::cout << + fmt::print( " Bat./Gen. k Average k\n" - " ========= ======== ====================\n"; + " ========= ======== ====================\n"); } } @@ -368,85 +353,63 @@ void print_columns() void print_generation() { - // Save state of cout - auto f {std::cout.flags()}; - // Determine overall generation and number of active generations int i = overall_generation() - 1; int n = simulation::current_batch > settings::n_inactive ? settings::gen_per_batch*simulation::n_realizations + simulation::current_gen : 0; - // Set format for values - std::cout << std::fixed << std::setprecision(5); - // write out information batch and option independent output - std::cout << " " << std::setw(9) << std::to_string(simulation::current_batch) - + "/" + std::to_string(simulation::current_gen) << " " << std::setw(8) - << simulation::k_generation[i]; + auto batch_and_gen = std::to_string(simulation::current_batch) + "/" + + std::to_string(simulation::current_gen); + fmt::print(" {:>9} {:8.5f}", batch_and_gen, simulation::k_generation[i]); // write out entropy info if (settings::entropy_on) { - std::cout << " " << std::setw(8) << simulation::entropy[i]; + fmt::print(" {:8.5f}", simulation::entropy[i]); } if (n > 1) { - std::cout << " " << std::setw(8) << simulation::keff << " +/-" - << std::setw(8) << simulation::keff_std; + fmt::print(" {:8.5f} +/-{:8.5f}", simulation::keff, simulation::keff_std); } - std::cout << '\n'; - - // Restore state of cout - std::cout.flags(f); + std::cout << std::endl; } //============================================================================== void print_batch_keff() { - // Save state of cout - auto f {std::cout.flags()}; - // Determine overall generation and number of active generations int i = simulation::current_batch*settings::gen_per_batch - 1; int n = simulation::n_realizations*settings::gen_per_batch; - // Set format for values - std::cout << std::fixed << std::setprecision(5); - // write out information batch and option independent output - std::cout << " " << std::setw(9) << std::to_string(simulation::current_batch) - + "/" + std::to_string(settings::gen_per_batch) << " " << std::setw(8) - << simulation::k_generation[i]; + auto batch_and_gen = std::to_string(simulation::current_batch) + "/" + + std::to_string(settings::gen_per_batch); + fmt::print(" {:>9} {:8.5f}", batch_and_gen, simulation::k_generation[i]); // write out entropy info if (settings::entropy_on) { - std::cout << " " << std::setw(8) << simulation::entropy[i]; + fmt::print(" {:8.5f}", simulation::entropy[i]); } if (n > 1) { - std::cout << " " << std::setw(8) << simulation::keff << " +/-" - << std::setw(8) << simulation::keff_std; + fmt::print(" {:8.5f} +/-{:8.5f}", simulation::keff, simulation::keff_std); } std::cout << std::endl; - - // Restore state of cout - std::cout.flags(f); } //============================================================================== void show_time(const char* label, double secs, int indent_level=0) { - std::cout << std::string(2*indent_level, ' '); int width = 33 - indent_level*2; - std::cout << " " << std::setw(width) << std::left << label << " = " - << std::setw(10) << std::right << secs << " seconds\n"; + fmt::print("{0:{1}} {2:<{3}} = {4:>10.4e} seconds\n", + "", 2*indent_level, label, width, secs); } void show_rate(const char* label, double particles_per_sec) { - std::cout << " " << std::setw(33) << std::left << label << " = " << - particles_per_sec << " particles/second\n"; + fmt::print(" {:<33} = {:.6} particles/second\n", label, particles_per_sec); } void print_runtime() @@ -457,11 +420,7 @@ void print_runtime() header("Timing Statistics", 6); if (settings::verbosity < 6) return; - // Save state of cout - auto f {std::cout.flags()}; - // display time elapsed for various sections - std::cout << std::scientific << std::setprecision(4); show_time("Total time for initialization", time_initialize.elapsed()); show_time("Reading cross sections", time_read_xs.elapsed(), 1); show_time("Total time in simulation", time_inactive.elapsed() + @@ -490,9 +449,6 @@ void print_runtime() show_time("Total time for finalization", time_finalize.elapsed()); show_time("Total time elapsed", time_total.elapsed()); - // Restore state of cout - std::cout.flags(f); - // Calculate particle rate in active/inactive batches int n_active = simulation::current_batch - settings::n_inactive; double speed_inactive = 0.0; @@ -519,15 +475,11 @@ void print_runtime() } // display calculation rate - std::cout << std::setprecision(6) << std::showpoint; if (!(settings::restart_run && (simulation::restart_batch >= settings::n_inactive)) && settings::n_inactive > 0) { show_rate("Calculation Rate (inactive)", speed_inactive); } show_rate("Calculation Rate (active)", speed_active); - - // Restore state of cout - std::cout.flags(f); } //============================================================================== @@ -545,9 +497,6 @@ mean_stdev(const double* x, int n) void print_results() { - // Save state of cout - auto f {std::cout.flags()}; - // display header block for results header("Results", 4); if (settings::verbosity < 4) return; @@ -564,52 +513,46 @@ void print_results() t_n3 = 1.0; } - // Set formatting for floats - std::cout << std::fixed << std::setprecision(5); - // write global tallies const auto& gt = simulation::global_tallies; double mean, stdev; if (n > 1) { if (settings::run_mode == RunMode::EIGENVALUE) { std::tie(mean, stdev) = mean_stdev(>(GlobalTally::K_COLLISION, 0), n); - std::cout << " k-effective (Collision) = " - << mean << " +/- " << t_n1 * stdev << '\n'; + fmt::print(" k-effective (Collision) = {:.5f} +/- {:.5f}\n", + mean, t_n1 * stdev); std::tie(mean, stdev) = mean_stdev(>(GlobalTally::K_TRACKLENGTH, 0), n); - std::cout << " k-effective (Track-length) = " - << mean << " +/- " << t_n1 * stdev << '\n'; + fmt::print(" k-effective (Track-length) = {:.5f} +/- {:.5f}\n", + mean, t_n1 * stdev); std::tie(mean, stdev) = mean_stdev(>(GlobalTally::K_ABSORPTION, 0), n); - std::cout << " k-effective (Absorption) = " - << mean << " +/- " << t_n1 * stdev << '\n'; + fmt::print(" k-effective (Absorption) = {:.5f} +/- {:.5f}\n", + mean, t_n1 * stdev); if (n > 3) { double k_combined[2]; openmc_get_keff(k_combined); - std::cout << " Combined k-effective = " - << k_combined[0] << " +/- " << t_n3 * k_combined[1] << '\n'; + fmt::print(" Combined k-effective = {:.5f} +/- {:.5f}\n", + k_combined[0], k_combined[1]); } } std::tie(mean, stdev) = mean_stdev(>(GlobalTally::LEAKAGE, 0), n); - std::cout << " Leakage Fraction = " - << mean << " +/- " << t_n1 * stdev << '\n'; + fmt::print(" Leakage Fraction = {:.5f} +/- {:.5f}\n", + mean, t_n1 * stdev); } else { if (mpi::master) warning("Could not compute uncertainties -- only one " "active batch simulated!"); if (settings::run_mode == RunMode::EIGENVALUE) { - std::cout << " k-effective (Collision) = " - << gt(GlobalTally::K_COLLISION, TallyResult::SUM) / n << '\n'; - std::cout << " k-effective (Track-length) = " - << gt(GlobalTally::K_TRACKLENGTH, TallyResult::SUM) / n << '\n'; - std::cout << " k-effective (Absorption) = " - << gt(GlobalTally::K_ABSORPTION, TallyResult::SUM) / n << '\n'; + fmt::print(" k-effective (Collision) = {:.5f}\n", + gt(GlobalTally::K_COLLISION, TallyResult::SUM) / n); + fmt::print(" k-effective (Track-length) = {:.5f}\n", + gt(GlobalTally::K_TRACKLENGTH, TallyResult::SUM) / n); + fmt::print(" k-effective (Absorption) = {:.5f}\n", + gt(GlobalTally::K_ABSORPTION, TallyResult::SUM) / n); } - std::cout << " Leakage Fraction = " - << gt(GlobalTally::LEAKAGE, TallyResult::SUM) / n << '\n'; + fmt::print(" Leakage Fraction = {:.5f}\n", + gt(GlobalTally::LEAKAGE, TallyResult::SUM) / n); } - std::cout << '\n'; - - // Restore state of cout - std::cout.flags(f); + fmt::print("\n"); } //============================================================================== From 7383a52f1fcfccf6cf8260698f79f5a0bdfa7da9 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 20 Jan 2020 10:06:26 -0600 Subject: [PATCH 18/43] Use fmt::print and fmt::format in many places --- src/cell.cpp | 82 +++++--------- src/dagmc.cpp | 35 ++---- src/distribution_spatial.cpp | 8 +- src/geometry.cpp | 53 ++++----- src/geometry_aux.cpp | 44 ++++---- src/hdf5_interface.cpp | 31 ++---- src/initialize.cpp | 9 +- src/lattice.cpp | 40 +++---- src/mgxs.cpp | 15 ++- src/output.cpp | 48 ++++---- src/particle.cpp | 10 +- src/physics.cpp | 25 +++-- src/physics_mg.cpp | 16 ++- src/plot.cpp | 197 ++++++++++----------------------- src/reaction.cpp | 23 ++-- src/secondary_uncorrelated.cpp | 7 +- 16 files changed, 240 insertions(+), 403 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index 9e640ce4ed..d09cde948a 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -9,7 +9,7 @@ #include #include - +#include #include #include @@ -158,10 +158,8 @@ generate_rpn(int32_t cell_id, std::vector infix) // If we run out of operators without finding a left parenthesis, it // means there are mismatched parentheses. if (it == stack.rend()) { - std::stringstream err_msg; - err_msg << "Mismatched parentheses in region specification for cell " - << cell_id; - fatal_error(err_msg); + fatal_error(fmt::format( + "Mismatched parentheses in region specification for cell {}", cell_id)); } rpn.push_back(stack.back()); stack.pop_back(); @@ -177,10 +175,8 @@ generate_rpn(int32_t cell_id, std::vector infix) // If the operator is a parenthesis it is mismatched. if (op >= OP_RIGHT_PAREN) { - std::stringstream err_msg; - err_msg << "Mismatched parentheses in region specification for cell " - << cell_id; - fatal_error(err_msg); + fatal_error(fmt::format( + "Mismatched parentheses in region specification for cell {}", cell_id)); } rpn.push_back(stack.back()); @@ -198,9 +194,7 @@ void Universe::to_hdf5(hid_t universes_group) const { // Create a group for this universe. - std::stringstream group_name; - group_name << "universe " << id_; - auto group = create_group(universes_group, group_name); + auto group = create_group(universes_group, fmt::format("universe {}", id_)); // Write the contained cells. if (cells_.size() > 0) { @@ -301,22 +295,19 @@ CSGCell::CSGCell(pugi::xml_node cell_node) bool fill_present = check_for_node(cell_node, "fill"); bool material_present = check_for_node(cell_node, "material"); if (!(fill_present || material_present)) { - std::stringstream err_msg; - err_msg << "Neither material nor fill was specified for cell " << id_; - fatal_error(err_msg); + fatal_error(fmt::format( + "Neither material nor fill was specified for cell {}", id_)); } if (fill_present && material_present) { - std::stringstream err_msg; - err_msg << "Cell " << id_ << " has both a material and a fill specified; " - << "only one can be specified per cell"; - fatal_error(err_msg); + fatal_error(fmt::format("Cell {} has both a material and a fill specified; " + "only one can be specified per cell", id_)); } if (fill_present) { fill_ = std::stoi(get_node_value(cell_node, "fill")); if (fill_ == universe_) { - fatal_error("Cell " + std::to_string(id_) + - " is filled with the same universe that it is contained in."); + fatal_error(fmt::format("Cell {} is filled with the same universe that" + "it is contained in.", id_)); } } else { fill_ = C_NONE; @@ -338,9 +329,8 @@ CSGCell::CSGCell(pugi::xml_node cell_node) } } } else { - std::stringstream err_msg; - err_msg << "An empty material element was specified for cell " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("An empty material element was specified for cell {}", + id_)); } } @@ -351,20 +341,16 @@ CSGCell::CSGCell(pugi::xml_node cell_node) // Make sure this is a material-filled cell. if (material_.size() == 0) { - std::stringstream err_msg; - err_msg << "Cell " << id_ << " was specified with a temperature but " - "no material. Temperature specification is only valid for cells " - "filled with a material."; - fatal_error(err_msg); + fatal_error(fmt::format( + "Cell {} was specified with a temperature but no material. Temperature" + "specification is only valid for cells filled with a material.", id_)); } // Make sure all temperatures are non-negative. for (auto T : sqrtkT_) { if (T < 0) { - std::stringstream err_msg; - err_msg << "Cell " << id_ - << " was specified with a negative temperature"; - fatal_error(err_msg); + fatal_error(fmt::format( + "Cell {} was specified with a negative temperature", id_)); } } @@ -426,17 +412,14 @@ CSGCell::CSGCell(pugi::xml_node cell_node) // Read the translation vector. if (check_for_node(cell_node, "translation")) { if (fill_ == C_NONE) { - std::stringstream err_msg; - err_msg << "Cannot apply a translation to cell " << id_ - << " because it is not filled with another universe"; - fatal_error(err_msg); + fatal_error(fmt::format("Cannot apply a translation to cell {}" + " because it is not filled with another universe", id_)); } auto xyz {get_node_array(cell_node, "translation")}; if (xyz.size() != 3) { - std::stringstream err_msg; - err_msg << "Non-3D translation vector applied to cell " << id_; - fatal_error(err_msg); + fatal_error(fmt::format( + "Non-3D translation vector applied to cell {}", id_)); } translation_ = xyz; } @@ -444,17 +427,14 @@ CSGCell::CSGCell(pugi::xml_node cell_node) // Read the rotation transform. if (check_for_node(cell_node, "rotation")) { if (fill_ == C_NONE) { - std::stringstream err_msg; - err_msg << "Cannot apply a rotation to cell " << id_ - << " because it is not filled with another universe"; - fatal_error(err_msg); + fatal_error(fmt::format("Cannot apply a rotation to cell {}" + " because it is not filled with another universe", id_)); } auto rot {get_node_array(cell_node, "rotation")}; if (rot.size() != 3 && rot.size() != 9) { - std::stringstream err_msg; - err_msg << "Non-3D rotation vector applied to cell " << id_; - fatal_error(err_msg); + fatal_error(fmt::format( + "Non-3D rotation vector applied to cell {}", id_)); } // Compute and store the rotation matrix. @@ -534,9 +514,7 @@ void CSGCell::to_hdf5(hid_t cell_group) const { // Create a group for this cell. - std::stringstream group_name; - group_name << "cell " << id_; - auto group = create_group(cell_group, group_name); + auto group = create_group(cell_group, fmt::format("cell {}", id_)); if (!name_.empty()) { write_string(group, "name", name_, false); @@ -1013,9 +991,7 @@ void read_cells(pugi::xml_node node) if (search == model::cell_map.end()) { model::cell_map[id] = i; } else { - std::stringstream err_msg; - err_msg << "Two or more cells use the same unique ID: " << id; - fatal_error(err_msg); + fatal_error(fmt::format("Two or more cells use the same unique ID: {}", id)); } } diff --git a/src/dagmc.cpp b/src/dagmc.cpp index e14a6062ad..3f16799a5c 100644 --- a/src/dagmc.cpp +++ b/src/dagmc.cpp @@ -12,11 +12,10 @@ #include "openmc/surface.h" #ifdef DAGMC - #include "uwuw.hpp" #include "dagmcmetadata.hpp" - #endif +#include #include #include @@ -110,11 +109,10 @@ void legacy_assign_material(const std::string& mat_string, DAGCell* c) c->material_.push_back(m->id_); // report error if more than one material is found } else { - std::stringstream err_msg; - err_msg << "More than one material found with name " << mat_string - << ". Please ensure materials have unique names if using this" - << " property to assign materials."; - fatal_error(err_msg); + fatal_error(fmt::format( + "More than one material found with name {}. Please ensure materials " + "have unique names if using this property to assign materials.", + mat_string)); } } } @@ -125,10 +123,8 @@ void legacy_assign_material(const std::string& mat_string, DAGCell* c) auto id = std::stoi(mat_string); c->material_.emplace_back(id); } catch (const std::invalid_argument&) { - std::stringstream err_msg; - err_msg << "No material " << mat_string - << " found for volume (cell) " << c->id_; - fatal_error(err_msg); + fatal_error(fmt::format( + "No material {} found for volume (cell) {}", mat_string, c->id_)); } } @@ -153,7 +149,6 @@ void load_dagmc_geometry() model::DAG = new moab::DagMC(); } - std::string filename = settings::path_input + DAGMC_FILENAME; // --- Materials --- @@ -253,9 +248,7 @@ void load_dagmc_geometry() rval = model::DAG->prop_value(vol_handle, "mat", mat_value); MB_CHK_ERR_CONT(rval); } else { - std::stringstream err_msg; - err_msg << "Volume " << c->id_ << " has no material assignment."; - fatal_error(err_msg.str()); + fatal_error(fmt::format("Volume {} has no material assignment.", c->id_)); } std::string cmp_str = mat_value; @@ -277,10 +270,8 @@ void load_dagmc_geometry() int mat_number = uwuw.material_library[uwuw_mat].metadata["mat_number"].asInt(); c->material_.push_back(mat_number); } else { - std::stringstream err_msg; - err_msg << "Material with value " << mat_value << " not found "; - err_msg << "in the UWUW material library"; - fatal_error(err_msg); + fatal_error(fmt::format("Material with value {} not found in the " + "UWUW material library", mat_value)); } } else { legacy_assign_material(mat_value, c); @@ -348,10 +339,8 @@ void load_dagmc_geometry() } else if (bc_value == "periodic") { fatal_error("Periodic boundary condition not supported in DAGMC."); } else { - std::stringstream err_msg; - err_msg << "Unknown boundary condition \"" << bc_value - << "\" specified on surface " << s->id_; - fatal_error(err_msg); + fatal_error(fmt::format("Unknown boundary condition \"{}\" specified " + "on surface {}", bc_value, s->id_)); } } else { // if no condition is found, set to transmit diff --git a/src/distribution_spatial.cpp b/src/distribution_spatial.cpp index 12432baf79..125d8afa6d 100644 --- a/src/distribution_spatial.cpp +++ b/src/distribution_spatial.cpp @@ -96,9 +96,7 @@ CylindricalIndependent::CylindricalIndependent(pugi::xml_node node) if (origin.size() == 3) { origin_ = origin; } else { - std::stringstream err_msg; - err_msg << "Origin for cylindrical source distribution must be length 3"; - fatal_error(err_msg); + fatal_error("Origin for cylindrical source distribution must be length 3"); } } else { // If no coordinates were specified, default to (0, 0, 0) @@ -162,9 +160,7 @@ SphericalIndependent::SphericalIndependent(pugi::xml_node node) if (origin.size() == 3) { origin_ = origin; } else { - std::stringstream err_msg; - err_msg << "Origin for spherical source distribution must be length 3"; - fatal_error(err_msg); + fatal_error("Origin for spherical source distribution must be length 3"); } } else { // If no coordinates were specified, default to (0, 0, 0) diff --git a/src/geometry.cpp b/src/geometry.cpp index 8bbc4d90c8..d2012d9019 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -1,7 +1,9 @@ #include "openmc/geometry.h" #include -#include + +#include +#include #include "openmc/cell.h" #include "openmc/constants.h" @@ -47,11 +49,9 @@ bool check_cell_overlap(Particle* p, bool error) if (c.contains(p->coord_[j].r, p->coord_[j].u, p->surface_)) { if (index_cell != p->coord_[j].cell) { if (error) { - std::stringstream err_msg; - err_msg << "Overlapping cells detected: " << c.id_ << ", " - << model::cells[p->coord_[j].cell]->id_ << " on universe " - << univ.id_; - fatal_error(err_msg); + fatal_error(fmt::format( + "Overlapping cells detected: {}, {} on universe {}", + c.id_, model::cells[p->coord_[j].cell]->id_, univ.id_)); } return true; } @@ -120,8 +120,7 @@ find_cell_inner(Particle* p, const NeighborList* neighbor_list) // Announce the cell that the particle is entering. if (found && (settings::verbosity >= 10 || p->trace_)) { - std::stringstream msg; - msg << " Entering cell " << model::cells[i_cell]->id_; + auto msg = fmt::format(" Entering cell {}", model::cells[i_cell]->id_); write_message(msg, 1); } @@ -229,11 +228,8 @@ find_cell_inner(Particle* p, const NeighborList* neighbor_list) if (lat.outer_ != NO_OUTER_UNIVERSE) { coord.universe = lat.outer_; } else { - std::stringstream err_msg; - err_msg << "Particle " << p->id_ << " is outside lattice " - << lat.id_ << " but the lattice has no defined outer " - "universe."; - warning(err_msg); + warning(fmt::format("Particle {} is outside lattice {} but the " + "lattice has no defined outer universe.", p->id_, lat.id_)); return false; } } @@ -298,11 +294,9 @@ cross_lattice(Particle* p, const BoundaryInfo& boundary) auto& lat {*model::lattices[coord.lattice]}; if (settings::verbosity >= 10 || p->trace_) { - std::stringstream msg; - msg << " Crossing lattice " << lat.id_ << ". Current position (" - << coord.lattice_x << "," << coord.lattice_y << "," - << coord.lattice_z << "). r=" << p->r(); - write_message(msg, 1); + write_message(fmt::format( + " Crossing lattice {}. Current position ({},{},{}). r={}", + lat.id_, coord.lattice_x, coord.lattice_y, coord.lattice_z, p->r()), 1); } // Set the lattice indices. @@ -326,10 +320,8 @@ cross_lattice(Particle* p, const BoundaryInfo& boundary) p->n_coord_ = 1; bool found = find_cell(p, 0); if (!found && p->alive_) { - std::stringstream err_msg; - err_msg << "Could not locate particle " << p->id_ - << " after crossing a lattice boundary"; - p->mark_as_lost(err_msg); + p->mark_as_lost(fmt::format("Could not locate particle {} after " + "crossing a lattice boundary", p->id_)); } } else { @@ -343,10 +335,8 @@ cross_lattice(Particle* p, const BoundaryInfo& boundary) p->n_coord_ = 1; bool found = find_cell(p, 0); if (!found && p->alive_) { - std::stringstream err_msg; - err_msg << "Could not locate particle " << p->id_ - << " after crossing a lattice boundary"; - p->mark_as_lost(err_msg); + p->mark_as_lost(fmt::format("Could not locate particle {} after " + "crossing a lattice boundary", p->id_)); } } } @@ -400,10 +390,8 @@ BoundaryInfo distance_to_boundary(Particle* p) level_lat_trans = lattice_distance.second; if (d_lat < 0) { - std::stringstream err_msg; - err_msg << "Particle " << p->id_ - << " had a negative distance to a lattice boundary"; - p->mark_as_lost(err_msg); + p->mark_as_lost(fmt::format( + "Particle {} had a negative distance to a lattice boundary", p->id_)); } } @@ -462,10 +450,7 @@ openmc_find_cell(const double* xyz, int32_t* index, int32_t* instance) p.u() = {0.0, 0.0, 1.0}; if (!find_cell(&p, false)) { - std::stringstream msg; - msg << "Could not find cell at position (" << p.r().x << ", " << p.r().y - << ", " << p.r().z << ")."; - set_errmsg(msg); + set_errmsg(fmt::format("Could not find cell at position {}.", p.r())); return OPENMC_E_GEOMETRY; } diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 6ee2899493..0df1198b10 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -4,7 +4,8 @@ #include #include -#include "pugixml.hpp" +#include +#include #include "openmc/cell.h" #include "openmc/constants.h" @@ -94,10 +95,8 @@ adjust_indices() c->type_ = Fill::LATTICE; c->fill_ = search_lat->second; } else { - std::stringstream err_msg; - err_msg << "Specified fill " << id << " on cell " << c->id_ - << " is neither a universe nor a lattice."; - fatal_error(err_msg); + fatal_error(fmt::format("Specified fill {} on cell {} is neither a " + "universe nor a lattice.", id, c->id_)); } } else { c->type_ = Fill::MATERIAL; @@ -105,10 +104,9 @@ adjust_indices() if (mat_id != MATERIAL_VOID) { auto search = model::material_map.find(mat_id); if (search == model::material_map.end()) { - std::stringstream err_msg; - err_msg << "Could not find material " << mat_id - << " specified on cell " << c->id_; - fatal_error(err_msg); + fatal_error(fmt::format( + "Could not find material {} specified on cell {}", + mat_id, c->id_)); } // Change from ID to index mat_id = search->second; @@ -123,10 +121,8 @@ adjust_indices() if (search != model::universe_map.end()) { c->universe_ = search->second; } else { - std::stringstream err_msg; - err_msg << "Could not find universe " << c->universe_ - << " specified on cell " << c->id_; - fatal_error(err_msg); + fatal_error(fmt::format("Could not find universe {} specified on cell {}", + c->universe_, c->id_)); } } @@ -345,23 +341,21 @@ prepare_distribcell() if (c.material_.size() > 1) { if (c.material_.size() != c.n_instances_) { - std::stringstream err_msg; - err_msg << "Cell " << c.id_ << " was specified with " - << c.material_.size() << " materials but has " << c.n_instances_ - << " distributed instances. The number of materials must equal " - "one or the number of instances."; - fatal_error(err_msg); + fatal_error(fmt::format( + "Cell {} was specified with {} materials but has {} distributed " + "instances. The number of materials must equal one or the number " + "of instances.", c.id_, c.material_.size(), c.n_instances_ + )); } } if (c.sqrtkT_.size() > 1) { if (c.sqrtkT_.size() != c.n_instances_) { - std::stringstream err_msg; - err_msg << "Cell " << c.id_ << " was specified with " - << c.sqrtkT_.size() << " temperatures but has " << c.n_instances_ - << " distributed instances. The number of temperatures must equal " - "one or the number of instances."; - fatal_error(err_msg); + fatal_error(fmt::format( + "Cell {} was specified with {} temperatures but has {} distributed " + "instances. The number of temperatures must equal one or the number " + "of instances.", c.id_, c.sqrtkT_.size(), c.n_instances_ + )); } } } diff --git a/src/hdf5_interface.cpp b/src/hdf5_interface.cpp index bd73e05fa2..f207f53b7d 100644 --- a/src/hdf5_interface.cpp +++ b/src/hdf5_interface.cpp @@ -2,12 +2,12 @@ #include #include -#include #include #include #include "xtensor/xtensor.hpp" #include "xtensor/xarray.hpp" +#include #include "hdf5.h" #include "hdf5_hl.h" @@ -105,9 +105,7 @@ create_group(hid_t parent_id, char const *name) { hid_t out = H5Gcreate(parent_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if (out < 0) { - std::stringstream err_msg; - err_msg << "Failed to create HDF5 group \"" << name << "\""; - fatal_error(err_msg); + fatal_error(fmt::format("Failed to create HDF5 group \"{}\"", name)); } return out; } @@ -161,17 +159,13 @@ ensure_exists(hid_t obj_id, const char* name, bool attribute) { if (attribute) { if (!attribute_exists(obj_id, name)) { - std::stringstream err_msg; - err_msg << "Attribute \"" << name << "\" does not exist in object " - << object_name(obj_id); - fatal_error(err_msg); + fatal_error(fmt::format("Attribute \"{}\" does not exist in object {}", + name, object_name(obj_id))); } } else { if (!object_exists(obj_id, name)) { - std::stringstream err_msg; - err_msg << "Object \"" << name << "\" does not exist in object " - << object_name(obj_id); - fatal_error(err_msg); + fatal_error(fmt::format("Object \"{}\" does not exist in object {}", + name, object_name(obj_id))); } } } @@ -194,9 +188,7 @@ file_open(const char* filename, char mode, bool parallel) flags = (mode == 'x' ? H5F_ACC_EXCL : H5F_ACC_TRUNC); break; default: - std::stringstream err_msg; - err_msg << "Invalid file mode: " << mode; - fatal_error(err_msg); + fatal_error(fmt::format("Invalid file mode: ", mode)); } hid_t plist = H5P_DEFAULT; @@ -216,9 +208,8 @@ file_open(const char* filename, char mode, bool parallel) file_id = H5Fopen(filename, flags, plist); } if (file_id < 0) { - std::stringstream msg; - msg << "Failed to open HDF5 file with mode '" << mode << "': " << filename; - fatal_error(msg); + fatal_error(fmt::format( + "Failed to open HDF5 file with mode '{}': {}", mode, filename)); } #ifdef PHDF5 @@ -394,9 +385,7 @@ object_exists(hid_t object_id, const char* name) { htri_t out = H5LTpath_valid(object_id, name, true); if (out < 0) { - std::stringstream err_msg; - err_msg << "Failed to check if object \"" << name << "\" exists."; - fatal_error(err_msg); + fatal_error(fmt::format("Failed to check if object \"{}\" exists.", name)); } return (out > 0); } diff --git a/src/initialize.cpp b/src/initialize.cpp index 22479ae29d..a5b516f688 100644 --- a/src/initialize.cpp +++ b/src/initialize.cpp @@ -3,13 +3,13 @@ #include #include // for getenv #include -#include #include #include #ifdef _OPENMP #include #endif +#include #include "openmc/capi.h" #include "openmc/constants.h" @@ -155,9 +155,8 @@ parse_command_line(int argc, char* argv[]) settings::path_particle_restart = argv[i]; settings::particle_restart_run = true; } else { - std::stringstream msg; - msg << "Unrecognized file after restart flag: " << filetype << "."; - strcpy(openmc_err_msg, msg.str().c_str()); + auto msg = fmt::format("Unrecognized file after restart flag: {}.", filetype); + strcpy(openmc_err_msg, msg.c_str()); return OPENMC_E_INVALID_ARGUMENT; } @@ -224,7 +223,7 @@ parse_command_line(int argc, char* argv[]) settings::write_all_tracks = true; } else { - std::cerr << "Unknown option: " << argv[i] << '\n'; + fmt::print(stderr, "Unknown option: {}\n", argv[i]); print_usage(); return OPENMC_E_UNASSIGNED; } diff --git a/src/lattice.cpp b/src/lattice.cpp index 092ff3d116..a8dd23aa8e 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -1,9 +1,11 @@ #include "openmc/lattice.h" #include -#include +#include #include +#include + #include "openmc/cell.h" #include "openmc/error.h" #include "openmc/geometry.h" @@ -71,10 +73,8 @@ Lattice::adjust_indices() if (search != model::universe_map.end()) { *it = search->second; } else { - std::stringstream err_msg; - err_msg << "Invalid universe number " << uid << " specified on " - "lattice " << id_; - fatal_error(err_msg); + fatal_error(fmt::format( + "Invalid universe number {} specified on lattice {}", uid, id_)); } } @@ -84,10 +84,8 @@ Lattice::adjust_indices() if (search != model::universe_map.end()) { outer_ = search->second; } else { - std::stringstream err_msg; - err_msg << "Invalid universe number " << outer_ << " specified on " - "lattice " << id_; - fatal_error(err_msg); + fatal_error(fmt::format( + "Invalid universe number {} specified on lattice {}", outer_, id_)); } } } @@ -184,12 +182,9 @@ RectLattice::RectLattice(pugi::xml_node lat_node) std::string univ_str {get_node_value(lat_node, "universes")}; std::vector univ_words {split(univ_str)}; if (univ_words.size() != nx*ny*nz) { - std::stringstream err_msg; - err_msg << "Expected " << nx*ny*nz - << " universes for a rectangular lattice of size " - << nx << "x" << ny << "x" << nz << " but " << univ_words.size() - << " were specified."; - fatal_error(err_msg); + fatal_error(fmt::format( + "Expected {} universes for a rectangular lattice of size {}x{]x{} but {} " + "were specified.", nx*ny*nz, nx, ny, nz, univ_words.size())); } // Parse the universes. @@ -487,12 +482,10 @@ HexLattice::HexLattice(pugi::xml_node lat_node) std::string univ_str {get_node_value(lat_node, "universes")}; std::vector univ_words {split(univ_str)}; if (univ_words.size() != n_univ) { - std::stringstream err_msg; - err_msg << "Expected " << n_univ - << " universes for a hexagonal lattice with " << n_rings_ - << " rings and " << n_axial_ << " axial levels" << " but " - << univ_words.size() << " were specified."; - fatal_error(err_msg); + fatal_error(fmt::format( + "Expected {} universes for a hexagonal lattice with {} rings and {} " + "axial levels but {} were specified.", n_univ, n_rings_, n_axial_, + univ_words.size())); } // Parse the universes. @@ -1069,9 +1062,8 @@ void read_lattices(pugi::xml_node node) if (in_map == model::lattice_map.end()) { model::lattice_map[id] = i_lat; } else { - std::stringstream err_msg; - err_msg << "Two or more lattices use the same unique ID: " << id; - fatal_error(err_msg); + fatal_error(fmt::format( + "Two or more lattices use the same unique ID: {}", id)); } } } diff --git a/src/mgxs.cpp b/src/mgxs.cpp index 55be267bca..094361dcbb 100644 --- a/src/mgxs.cpp +++ b/src/mgxs.cpp @@ -9,6 +9,7 @@ #include #endif +#include #include "xtensor/xmath.hpp" #include "xtensor/xsort.hpp" #include "xtensor/xadapt.hpp" @@ -121,10 +122,9 @@ Mgxs::metadata_from_hdf5(hid_t xs_id, const std::vector& temperature, temps_to_read.push_back(std::round(temp_actual)); } } else { - std::stringstream msg; - msg << "MGXS library does not contain cross sections for " - << in_name << " at or near " << std::round(T) << " K."; - fatal_error(msg); + fatal_error(fmt::format( + "MGXS library does not contain cross sections for {} at or near {} K.", + in_name, std::round(T))); } } break; @@ -350,10 +350,9 @@ Mgxs::Mgxs(const std::string& in_name, const std::vector& mat_kTs, auto temp_actual = micros[m]->kTs[micro_t[m]]; if (std::abs(temp_actual - temp_desired) >= K_BOLTZMANN * settings::temperature_tolerance) { - std::stringstream msg; - msg << "MGXS Library does not contain cross section for " << name - << " at or near " << std::round(temp_desired / K_BOLTZMANN) << "K."; - fatal_error(msg); + fatal_error(fmt::format( + "MGXS Library does not contain cross section for {} at or near {} K.", + name, std::round(temp_desired / K_BOLTZMANN))); } } break; diff --git a/src/output.cpp b/src/output.cpp index f32d4c2598..ecfdb8a95d 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -12,6 +12,7 @@ #include // for pair #include +#include #ifdef _OPENMP #include #endif @@ -184,10 +185,8 @@ extern "C" void print_particle(Particle* p) p->coord_[i].lattice_y, p->coord_[i].lattice_z); } - fmt::print(" r = "); - std::cout << p->coord_[i].r << '\n'; - fmt::print(" u = "); - std::cout << p->coord_[i].u << '\n'; + fmt::print(" r = {}\n", p->coord_[i].r); + fmt::print(" u = {}\n", p->coord_[i].u); } // Display miscellaneous info. @@ -586,7 +585,6 @@ write_tallies() // Open the tallies.out file. std::ofstream tallies_out; tallies_out.open("tallies.out", std::ios::out | std::ios::trunc); - tallies_out << std::setprecision(6); // Loop over each tally. for (auto i_tally = 0; i_tally < model::tallies.size(); ++i_tally) { @@ -595,10 +593,10 @@ write_tallies() // Write header block. std::string tally_header("TALLY " + std::to_string(tally.id_)); if (!tally.name_.empty()) tally_header += ": " + tally.name_; - tallies_out << header(tally_header) << "\n\n"; + fmt::print(tallies_out, "{}\n\n", header(tally_header)); if (!tally.writable_) { - tallies_out << " Internal\n\n"; + fmt::print(tallies_out, " Internal\n\n"); continue; } @@ -614,21 +612,20 @@ write_tallies() const auto& deriv {model::tally_derivs[tally.deriv_]}; switch (deriv.variable) { case DerivativeVariable::DENSITY: - tallies_out << " Density derivative Material " - << std::to_string(deriv.diff_material) << "\n"; + fmt::print(tallies_out, " Density derivative Material {}\n", + deriv.diff_material); break; case DerivativeVariable::NUCLIDE_DENSITY: - tallies_out << " Nuclide density derivative Material " - << std::to_string(deriv.diff_material) << " Nuclide " - << data::nuclides[deriv.diff_nuclide]->name_ << "\n"; + fmt::print(tallies_out, " Nuclide density derivative Material {} Nuclide {}\n", + deriv.diff_material, data::nuclides[deriv.diff_nuclide]->name_); break; case DerivativeVariable::TEMPERATURE: - tallies_out << " Temperature derivative Material " - << std::to_string(deriv.diff_material) << "\n"; + fmt::print(tallies_out, " Temperature derivative Material {}\n", + deriv.diff_material); break; default: - fatal_error("Differential tally dependent variable for tally " - + std::to_string(tally.id_) + " not defined in output.cpp"); + fatal_error(fmt::format("Differential tally dependent variable for " + "tally {} not defined in output.cpp", tally.id_)); } } @@ -651,8 +648,8 @@ write_tallies() auto i_filt = tally.filters(i); const auto& filt {*model::tally_filters[i_filt]}; auto& match {filter_matches[i_filt]}; - tallies_out << std::string(indent+1, ' ') - << filt.text_label(match.i_bin_) << "\n"; + fmt::print(tallies_out, "{0:{1}}{2}\n", "", indent + 1, + filt.text_label(match.i_bin_)); } indent += 2; } @@ -662,14 +659,14 @@ write_tallies() for (auto i_nuclide : tally.nuclides_) { // Write label for this nuclide bin. if (i_nuclide == -1) { - tallies_out << std::string(indent+1, ' ') << "Total Material\n"; + fmt::print(tallies_out, "{0:{1}}Total Material\n", "", indent + 1); } else { if (settings::run_CE) { - tallies_out << std::string(indent+1, ' ') - << data::nuclides[i_nuclide]->name_ << "\n"; + fmt::print(tallies_out, "{0:{1}}{2}\n", "", indent + 1, + data::nuclides[i_nuclide]->name_); } else { - tallies_out << std::string(indent+1, ' ') - << data::mg.nuclides_[i_nuclide].name << "\n"; + fmt::print(tallies_out, "{0:{1}}{2}\n", "", indent + 1, + data::mg.nuclides_[i_nuclide].name); } } @@ -681,9 +678,8 @@ write_tallies() double mean, stdev; std::tie(mean, stdev) = mean_stdev( &tally.results_(filter_index, score_index, 0), tally.n_realizations_); - tallies_out << std::string(indent+1, ' ') << std::left - << std::setw(36) << score_name << " " << mean << " +/- " - << t_value * stdev << "\n"; + fmt::print(tallies_out, "{0:{1}}{2:<36} {3:.6} +/- {4:.6}\n", + "", indent + 1, score_name, mean, t_value * stdev); score_index += 1; } indent -= 2; diff --git a/src/particle.cpp b/src/particle.cpp index bd9a611392..276fc197d1 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -2,7 +2,8 @@ #include // copy, min #include // log, abs, copysign -#include + +#include #include "openmc/bank.h" #include "openmc/capi.h" @@ -643,14 +644,13 @@ Particle::write_restart() const if (settings::run_mode == RunMode::PARTICLE) return; // Set up file name - std::stringstream filename; - filename << settings::path_output << "particle_" << simulation::current_batch - << '_' << id_ << ".h5"; + auto filename = fmt::format("{}particle_{}_{}.h5", settings::path_output, + simulation::current_batch, id_); #pragma omp critical (WriteParticleRestart) { // Create file - hid_t file_id = file_open(filename.str(), 'w'); + hid_t file_id = file_open(filename, 'w'); // Write filetype and version info write_attribute(file_id, "filetype", "particle restart"); diff --git a/src/physics.cpp b/src/physics.cpp index 6c46bf4293..a0f929125c 100644 --- a/src/physics.cpp +++ b/src/physics.cpp @@ -21,9 +21,10 @@ #include "openmc/thermal.h" #include "openmc/tallies/tally.h" +#include + #include // for max, min, max_element #include // for sqrt, exp, log, abs, copysign -#include namespace openmc { @@ -61,17 +62,19 @@ void collision(Particle* p) // Display information about collision if (settings::verbosity >= 10 || p->trace_) { - std::stringstream msg; + std::string msg; if (p->event_ == TallyEvent::KILL) { - msg << " Killed. Energy = " << p->E_ << " eV."; + msg = fmt::format(" Killed. Energy = {} eV.", p->E_); } else if (p->type_ == Particle::Type::neutron) { - msg << " " << reaction_name(p->event_mt_) << " with " << - data::nuclides[p->event_nuclide_]->name_ << ". Energy = " << p->E_ << " eV."; + msg = fmt::format(" {} with {}. Energy = {} eV.", + reaction_name(p->event_mt_), data::nuclides[p->event_nuclide_]->name_, + p->E_); } else if (p->type_ == Particle::Type::photon) { - msg << " " << reaction_name(p->event_mt_) << " with " << - to_element(data::nuclides[p->event_nuclide_]->name_) << ". Energy = " << p->E_ << " eV."; + msg = fmt::format(" {} with {}. Energy = {} eV.", + reaction_name(p->event_mt_), + to_element(data::nuclides[p->event_nuclide_]->name_), p->E_); } else { - msg << " Disappeared. Energy = " << p->E_ << " eV."; + msg = fmt::format(" Disappeared. Energy = {} eV.", p->E_); } write_message(msg, 1); } @@ -189,7 +192,7 @@ create_fission_sites(Particle* p, int i_nuclide, const Reaction* rx) // Sample delayed group and angle/energy for fission reaction sample_fission_neutron(i_nuclide, rx, p->E_, &site, p->current_seed()); - + // Store fission site in bank if (use_fission_bank) { int64_t idx = simulation::fission_bank.thread_safe_append(site); @@ -210,7 +213,7 @@ create_fission_sites(Particle* p, int i_nuclide, const Reaction* rx) if (p->delayed_group_ > 0) { nu_d[p->delayed_group_-1]++; } - + // Write fission particles to nuBank if (use_fission_bank) { p->nu_bank_.emplace_back(); @@ -220,7 +223,7 @@ create_fission_sites(Particle* p, int i_nuclide, const Reaction* rx) nu_bank_entry->delayed_group = site.delayed_group; } } - + // If shared fission bank was full, and no fissions could be added, // set the particle fission flag to false. if (nu == skipped) { diff --git a/src/physics_mg.cpp b/src/physics_mg.cpp index 1ac7c1979e..526a21439b 100644 --- a/src/physics_mg.cpp +++ b/src/physics_mg.cpp @@ -1,8 +1,8 @@ #include "openmc/physics_mg.h" #include -#include +#include #include "xtensor/xarray.hpp" #include "openmc/bank.h" @@ -31,10 +31,8 @@ collision_mg(Particle* p) sample_reaction(p); // Display information about collision - if ((settings::verbosity >= 10) || (p->trace_)) { - std::stringstream msg; - msg << " Energy Group = " << p->g_; - write_message(msg, 1); + if ((settings::verbosity >= 10) || p->trace_) { + write_message(fmt::format(" Energy Group = {}", p->g_), 1); } } @@ -113,13 +111,13 @@ create_fission_sites(Particle* p) // Initialize the counter of delayed neutrons encountered for each delayed // group. double nu_d[MAX_DELAYED_GROUPS] = {0.}; - + // Clear out particle's nu fission bank p->nu_bank_.clear(); p->fission_ = true; int skipped = 0; - + // Determine whether to place fission sites into the shared fission bank // or the secondary particle bank. bool use_fission_bank = (settings::run_mode == RunMode::EIGENVALUE); @@ -176,7 +174,7 @@ create_fission_sites(Particle* p) if (p->delayed_group_ > 0) { nu_d[dg]++; } - + // Write fission particles to nuBank if (use_fission_bank) { p->nu_bank_.emplace_back(); @@ -186,7 +184,7 @@ create_fission_sites(Particle* p) nu_bank_entry->delayed_group = site.delayed_group; } } - + // If shared fission bank was full, and no fissions could be added, // set the particle fission flag to false. if (nu == skipped) { diff --git a/src/plot.cpp b/src/plot.cpp index 5aa6a61b86..0ff7857127 100644 --- a/src/plot.cpp +++ b/src/plot.cpp @@ -4,6 +4,8 @@ #include #include +#include +#include #include "xtensor/xview.hpp" #include "openmc/constants.h" @@ -92,10 +94,8 @@ extern "C" int openmc_plot_geometry() { for (auto pl : model::plots) { - std::stringstream ss; - ss << "Processing plot " << pl.id_ << ": " - << pl.path_plot_ << "..."; - write_message(ss.str(), 5); + write_message(fmt::format("Processing plot {}: {}...", + pl.id_, pl.path_plot_), 5); if (PlotType::slice == pl.type_) { // create 2D image @@ -188,9 +188,7 @@ Plot::set_id(pugi::xml_node plot_node) // Check to make sure 'id' hasn't been used if (model::plot_map.find(id_) != model::plot_map.end()) { - std::stringstream err_msg; - err_msg << "Two or more plots use the same unique ID: " << id_; - fatal_error(err_msg.str()); + fatal_error(fmt::format("Two or more plots use the same unique ID: {}", id_)); } } @@ -210,11 +208,9 @@ Plot::set_type(pugi::xml_node plot_node) else if (type_str == "voxel") { type_ = PlotType::voxel; } else { - // if we're here, something is wrong - std::stringstream err_msg; - err_msg << "Unsupported plot type '" << type_str - << "' in plot " << id_; - fatal_error(err_msg.str()); + // if we're here, something is wrong + fatal_error(fmt::format("Unsupported plot type '{}' in plot {}", + type_str, id_)); } } } @@ -223,24 +219,24 @@ void Plot::set_output_path(pugi::xml_node plot_node) { // Set output file path - std::stringstream filename; + std::string filename; if (check_for_node(plot_node, "filename")) { - filename << get_node_value(plot_node, "filename"); + filename = get_node_value(plot_node, "filename"); } else { - filename << "plot_" << id_; + filename = fmt::format("plot_{}", id_); } // add appropriate file extension to name switch(type_) { case PlotType::slice: - filename << ".ppm"; + filename.append(".ppm"); break; case PlotType::voxel: - filename << ".h5"; + filename.append(".h5"); break; } - path_plot_ = filename.str(); + path_plot_ = filename; // Copy plot pixel size std::vector pxls = get_node_array(plot_node, "pixels"); @@ -249,10 +245,7 @@ Plot::set_output_path(pugi::xml_node plot_node) pixels_[0] = pxls[0]; pixels_[1] = pxls[1]; } else { - std::stringstream err_msg; - err_msg << " must be length 2 in slice plot " - << id_; - fatal_error(err_msg.str()); + fatal_error(fmt::format(" must be length 2 in slice plot {}", id_)); } } else if (PlotType::voxel == type_) { if (pxls.size() == 3) { @@ -260,10 +253,7 @@ Plot::set_output_path(pugi::xml_node plot_node) pixels_[1] = pxls[1]; pixels_[2] = pxls[2]; } else { - std::stringstream err_msg; - err_msg << " must be length 3 in voxel plot " - << id_; - fatal_error(err_msg.str()); + fatal_error(fmt::format(" must be length 3 in voxel plot {}", id_)); } } } @@ -276,19 +266,13 @@ Plot::set_bg_color(pugi::xml_node plot_node) std::vector bg_rgb = get_node_array(plot_node, "background"); if (PlotType::voxel == type_) { if (mpi::master) { - std::stringstream err_msg; - err_msg << "Background color ignored in voxel plot " - << id_; - warning(err_msg.str()); + warning(fmt::format("Background color ignored in voxel plot {}", id_)); } } if (bg_rgb.size() == 3) { not_found_ = bg_rgb; } else { - std::stringstream err_msg; - err_msg << "Bad background RGB in plot " - << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Bad background RGB in plot {}", id_)); } } } @@ -309,10 +293,8 @@ Plot::set_basis(pugi::xml_node plot_node) } else if ("yz" == pl_basis) { basis_ = PlotBasis::yz; } else { - std::stringstream err_msg; - err_msg << "Unsupported plot basis '" << pl_basis - << "' in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Unsupported plot basis '{}' in plot {}", + pl_basis, id_)); } } } @@ -325,10 +307,7 @@ Plot::set_origin(pugi::xml_node plot_node) if (pl_origin.size() == 3) { origin_ = pl_origin; } else { - std::stringstream err_msg; - err_msg << "Origin must be length 3 in plot " - << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Origin must be length 3 in plot {}", id_)); } } @@ -342,20 +321,14 @@ Plot::set_width(pugi::xml_node plot_node) width_.x = pl_width[0]; width_.y = pl_width[1]; } else { - std::stringstream err_msg; - err_msg << " must be length 2 in slice plot " - << id_; - fatal_error(err_msg); + fatal_error(fmt::format(" must be length 2 in slice plot {}", id_)); } } else if (PlotType::voxel == type_) { if (pl_width.size() == 3) { pl_width = get_node_array(plot_node, "width"); width_ = pl_width; } else { - std::stringstream err_msg; - err_msg << " must be length 3 in voxel plot " - << id_; - fatal_error(err_msg); + fatal_error(fmt::format(" must be length 3 in voxel plot {}", id_)); } } } @@ -367,9 +340,7 @@ Plot::set_universe(pugi::xml_node plot_node) if (check_for_node(plot_node, "level")) { level_ = std::stoi(get_node_value(plot_node, "level")); if (level_ < 0) { - std::stringstream err_msg; - err_msg << "Bad universe level in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Bad universe level in plot {}", id_)); } } else { level_ = PLOT_LEVEL_LOWEST; @@ -391,10 +362,8 @@ Plot::set_default_colors(pugi::xml_node plot_node) color_by_ = PlotColorBy::mats; colors_.resize(model::materials.size()); } else { - std::stringstream err_msg; - err_msg << "Unsupported plot color type '" << pl_color_by - << "' in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Unsupported plot color type '{}' in plot {}", + pl_color_by, id_)); } for (auto& c : colors_) { @@ -411,10 +380,7 @@ Plot::set_user_colors(pugi::xml_node plot_node) { if (!plot_node.select_nodes("color").empty() && PlotType::voxel == type_) { if (mpi::master) { - std::stringstream err_msg; - err_msg << "Color specifications ignored in voxel plot " - << id_; - warning(err_msg); + warning(fmt::format("Color specifications ignored in voxel plot {}", id_)); } } @@ -422,19 +388,15 @@ Plot::set_user_colors(pugi::xml_node plot_node) // Make sure 3 values are specified for RGB std::vector user_rgb = get_node_array(cn, "rgb"); if (user_rgb.size() != 3) { - std::stringstream err_msg; - err_msg << "Bad RGB in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Bad RGB in plot {}", id_)); } // Ensure that there is an id for this color specification int col_id; if (check_for_node(cn, "id")) { col_id = std::stoi(get_node_value(cn, "id")); } else { - std::stringstream err_msg; - err_msg << "Must specify id for color specification in plot " - << id_; - fatal_error(err_msg); + fatal_error(fmt::format( + "Must specify id for color specification in plot {}", id_)); } // Add RGB if (PlotColorBy::cells == color_by_) { @@ -442,20 +404,16 @@ Plot::set_user_colors(pugi::xml_node plot_node) col_id = model::cell_map[col_id]; colors_[col_id] = user_rgb; } else { - std::stringstream err_msg; - err_msg << "Could not find cell " << col_id - << " specified in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Could not find cell {} specified in plot {}", + col_id, id_)); } } else if (PlotColorBy::mats == color_by_) { if (model::material_map.find(col_id) != model::material_map.end()) { col_id = model::material_map[col_id]; colors_[col_id] = user_rgb; } else { - std::stringstream err_msg; - err_msg << "Could not find material " << col_id - << " specified in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format( + "Could not find material {} specified in plot {}", col_id, id_)); } } } // color node loop @@ -469,9 +427,7 @@ Plot::set_meshlines(pugi::xml_node plot_node) if (!mesh_line_nodes.empty()) { if (PlotType::voxel == type_) { - std::stringstream msg; - msg << "Meshlines ignored in voxel plot " << id_; - warning(msg); + warning(fmt::format("Meshlines ignored in voxel plot {}", id_)); } if (mesh_line_nodes.size() == 1) { @@ -483,9 +439,8 @@ Plot::set_meshlines(pugi::xml_node plot_node) if (check_for_node(meshlines_node, "meshtype")) { meshtype = get_node_value(meshlines_node, "meshtype"); } else { - std::stringstream err_msg; - err_msg << "Must specify a meshtype for meshlines specification in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format( + "Must specify a meshtype for meshlines specification in plot {}", id_)); } // Ensure that there is a linewidth for this meshlines specification @@ -494,9 +449,8 @@ Plot::set_meshlines(pugi::xml_node plot_node) meshline_width = get_node_value(meshlines_node, "linewidth"); meshlines_width_ = std::stoi(meshline_width); } else { - std::stringstream err_msg; - err_msg << "Must specify a linewidth for meshlines specification in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format( + "Must specify a linewidth for meshlines specification in plot {}", id_)); } // Check for color @@ -504,9 +458,7 @@ Plot::set_meshlines(pugi::xml_node plot_node) // Check and make sure 3 values are specified for RGB std::vector ml_rgb = get_node_array(meshlines_node, "color"); if (ml_rgb.size() != 3) { - std::stringstream err_msg; - err_msg << "Bad RGB for meshlines color in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Bad RGB for meshlines color in plot {}", id_)); } meshlines_color_ = ml_rgb; } @@ -514,9 +466,7 @@ Plot::set_meshlines(pugi::xml_node plot_node) // Set mesh based on type if ("ufs" == meshtype) { if (!simulation::ufs_mesh) { - std::stringstream err_msg; - err_msg << "No UFS mesh for meshlines on plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("No UFS mesh for meshlines on plot {}", id_)); } else { for (int i = 0; i < model::meshes.size(); ++i) { if (const auto* m @@ -531,9 +481,7 @@ Plot::set_meshlines(pugi::xml_node plot_node) } } else if ("entropy" == meshtype) { if (!simulation::entropy_mesh) { - std::stringstream err_msg; - err_msg << "No entropy mesh for meshlines on plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("No entropy mesh for meshlines on plot {}", id_)); } else { for (int i = 0; i < model::meshes.size(); ++i) { if (const auto* m @@ -553,29 +501,22 @@ Plot::set_meshlines(pugi::xml_node plot_node) tally_mesh_id = std::stoi(get_node_value(meshlines_node, "id")); } else { std::stringstream err_msg; - err_msg << "Must specify a mesh id for meshlines tally " - << "mesh specification in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Must specify a mesh id for meshlines tally " + "mesh specification in plot {}", id_)); } // find the tally index int idx; int err = openmc_get_mesh_index(tally_mesh_id, &idx); if (err != 0) { - std::stringstream err_msg; - err_msg << "Could not find mesh " << tally_mesh_id - << " specified in meshlines for plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Could not find mesh {} specified in " + "meshlines for plot {}", tally_mesh_id, id_)); } index_meshlines_mesh_ = idx; } else { - std::stringstream err_msg; - err_msg << "Invalid type for meshlines on plot " << id_ ; - fatal_error(err_msg); + fatal_error(fmt::format("Invalid type for meshlines on plot {}", id_ )); } } else { - std::stringstream err_msg; - err_msg << "Mutliple meshlines specified in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Mutliple meshlines specified in plot {}", id_)); } } } @@ -589,9 +530,7 @@ Plot::set_mask(pugi::xml_node plot_node) if (!mask_nodes.empty()) { if (PlotType::voxel == type_) { if (mpi::master) { - std::stringstream wrn_msg; - wrn_msg << "Mask ignored in voxel plot " << id_; - warning(wrn_msg); + warning(fmt::format("Mask ignored in voxel plot {}", id_)); } } @@ -602,9 +541,7 @@ Plot::set_mask(pugi::xml_node plot_node) // Determine how many components there are and allocate std::vector iarray = get_node_array(mask_node, "components"); if (iarray.size() == 0) { - std::stringstream err_msg; - err_msg << "Missing in mask of plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Missing in mask of plot {}", id_)); } // First we need to change the user-specified identifiers to indices @@ -615,20 +552,16 @@ Plot::set_mask(pugi::xml_node plot_node) col_id = model::cell_map[col_id]; } else { - std::stringstream err_msg; - err_msg << "Could not find cell " << col_id - << " specified in the mask in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Could not find cell {} specified in the " + "mask in plot {}", col_id, id_)); } } else if (PlotColorBy::mats == color_by_) { if (model::material_map.find(col_id) != model::material_map.end()) { col_id = model::material_map[col_id]; } else { - std::stringstream err_msg; - err_msg << "Could not find material " << col_id - << " specified in the mask in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Could not find material {} specified in " + "the mask in plot {}", col_id, id_)); } } } @@ -646,9 +579,7 @@ Plot::set_mask(pugi::xml_node plot_node) } } else { - std::stringstream err_msg; - err_msg << "Mutliple masks specified in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Mutliple masks specified in plot {}", id_)); } } } @@ -660,18 +591,14 @@ void Plot::set_overlap_color(pugi::xml_node plot_node) { // check for custom overlap color if (check_for_node(plot_node, "overlap_color")) { if (!color_overlaps_) { - std::stringstream wrn_msg; - wrn_msg << "Overlap color specified in plot " << id_ - << " but overlaps won't be shown."; - warning(wrn_msg); + warning(fmt::format( + "Overlap color specified in plot {} but overlaps won't be shown.", id_)); } std::vector olap_clr = get_node_array(plot_node, "overlap_color"); if (olap_clr.size() == 3) { overlap_color_ = olap_clr; } else { - std::stringstream err_msg; - err_msg << "Bad overlap RGB in plot " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Bad overlap RGB in plot {}", id_)); } } } @@ -716,9 +643,9 @@ void output_ppm(Plot pl, const ImageData& data) of.open(fname); // Write header - of << "P6" << "\n"; + of << "P6\n"; of << pl.pixels_[0] << " " << pl.pixels_[1] << "\n"; - of << "255" << "\n"; + of << "255\n"; of.close(); of.open(fname, std::ios::binary | std::ios::app); @@ -729,11 +656,7 @@ void output_ppm(Plot pl, const ImageData& data) of << rgb.red << rgb.green << rgb.blue; } } - - // Close file - // THIS IS HERE TO MATCH FORTRAN VERSION, NOT TECHNICALLY NECESSARY of << "\n"; - of.close(); } //============================================================================== diff --git a/src/reaction.cpp b/src/reaction.cpp index f7f1e87acb..ff22540e1f 100644 --- a/src/reaction.cpp +++ b/src/reaction.cpp @@ -3,6 +3,8 @@ #include #include // for move +#include + #include "openmc/constants.h" #include "openmc/hdf5_interface.h" #include "openmc/endf.h" @@ -35,8 +37,7 @@ Reaction::Reaction(hid_t group, const std::vector& temperatures) // Read cross section and threshold_idx data for (auto t : temperatures) { // Get group corresponding to temperature - std::string temp_str {std::to_string(t) + "K"}; - hid_t temp_group = open_group(group, temp_str.c_str()); + hid_t temp_group = open_group(group, fmt::format("{}K", t).c_str()); hid_t dset = open_dataset(temp_group, "xs"); // Get threshold index @@ -178,7 +179,7 @@ std::string reaction_name(int mt) } else if (mt == N_NPA) { return "(n,npa)"; } else if (N_N1 <= mt && mt <= N_N40) { - return "(n,n" + std::to_string(mt-50) + ")"; + return fmt::format("(n,n{})", mt - 50); } else if (mt == N_NC) { return "(n,nc)"; } else if (mt == N_DISAPPEAR) { @@ -244,33 +245,31 @@ std::string reaction_name(int mt) } else if (mt == PHOTOELECTRIC) { return "photoelectric"; } else if (534 <= mt && mt <= 572) { - std::stringstream name; - name << "photoelectric, " << SUBSHELLS[mt - 534] << " subshell"; - return name.str(); + return fmt::format("photoelectric, {} subshell", SUBSHELLS[mt - 534]); } else if (600 <= mt && mt <= 648) { - return "(n,p" + std::to_string(mt-600) + ")"; + return fmt::format("(n,p{})", mt - 600); } else if (mt == 649) { return "(n,pc)"; } else if (650 <= mt && mt <= 698) { - return "(n,d" + std::to_string(mt-650) + ")"; + return fmt::format("(n,d{})", mt - 650); } else if (mt == 699) { return "(n,dc)"; } else if (700 <= mt && mt <= 748) { - return "(n,t" + std::to_string(mt-700) + ")"; + return fmt::format("(n,t{})", mt - 700); } else if (mt == 749) { return "(n,tc)"; } else if (750 <= mt && mt <= 798) { - return "(n,3He" + std::to_string(mt-750) + ")"; + return fmt::format("(n,3He{})", mt - 750); } else if (mt == 799) { return "(n,3Hec)"; } else if (800 <= mt && mt <= 848) { - return "(n,a" + std::to_string(mt-800) + ")"; + return fmt::format("(n,a{})", mt - 800); } else if (mt == 849) { return "(n,ac)"; } else if (mt == HEATING_LOCAL) { return "heating-local"; } else { - return "MT=" + std::to_string(mt); + return fmt::format("MT={}", mt); } } diff --git a/src/secondary_uncorrelated.cpp b/src/secondary_uncorrelated.cpp index 1421fcf83e..320761916e 100644 --- a/src/secondary_uncorrelated.cpp +++ b/src/secondary_uncorrelated.cpp @@ -1,8 +1,9 @@ #include "openmc/secondary_uncorrelated.h" -#include // for stringstream #include // for string +#include + #include "openmc/error.h" #include "openmc/hdf5_interface.h" #include "openmc/random_lcg.h" @@ -42,9 +43,7 @@ UncorrelatedAngleEnergy::UncorrelatedAngleEnergy(hid_t group) } else if (type == "watt") { energy_ = UPtrEDist{new WattEnergy{energy_group}}; } else { - std::stringstream msg; - msg << "Energy distribution type '" << type << "' not implemented."; - warning(msg); + warning(fmt::format("Energy distribution type '{}' not implemented.", type)); } close_group(energy_group); } From 2a230cd73947d2a449c53f52237339683ca4de6c Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 20 Jan 2020 13:43:02 -0600 Subject: [PATCH 19/43] More use of fmt::print and fmt::format --- include/openmc/plot.h | 5 +- include/openmc/volume_calc.h | 1 + src/settings.cpp | 27 ++++----- src/source.cpp | 22 +++---- src/state_point.cpp | 14 ++--- src/surface.cpp | 62 +++++++------------- src/tallies/derivative.cpp | 24 +++----- src/tallies/filter_azimuthal.cpp | 7 +-- src/tallies/filter_cell.cpp | 10 ++-- src/tallies/filter_cell_instance.cpp | 15 +++-- src/tallies/filter_distribcell.cpp | 8 +-- src/tallies/filter_energy.cpp | 10 ++-- src/tallies/filter_energyfunc.cpp | 13 ++--- src/tallies/filter_material.cpp | 10 ++-- src/tallies/filter_mesh.cpp | 21 ++++--- src/tallies/filter_mu.cpp | 6 +- src/tallies/filter_polar.cpp | 6 +- src/tallies/filter_sph_harm.cpp | 16 ++--- src/tallies/filter_sptl_legendre.cpp | 12 ++-- src/tallies/filter_surface.cpp | 10 ++-- src/tallies/filter_universe.cpp | 10 ++-- src/tallies/filter_zernike.cpp | 10 ++-- src/tallies/tally.cpp | 87 ++++++++++++---------------- src/tallies/trigger.cpp | 20 ++++--- src/thermal.cpp | 16 ++--- src/track_output.cpp | 12 ++-- src/volume_calc.cpp | 30 ++++------ src/wmp.cpp | 16 ++--- src/xml_interface.cpp | 21 +++---- 29 files changed, 219 insertions(+), 302 deletions(-) diff --git a/include/openmc/plot.h b/include/openmc/plot.h index 04db9710aa..e05d6f2e2e 100644 --- a/include/openmc/plot.h +++ b/include/openmc/plot.h @@ -11,6 +11,7 @@ #include "openmc/position.h" #include "openmc/constants.h" #include "openmc/cell.h" +#include "openmc/error.h" #include "openmc/geometry.h" #include "openmc/particle.h" #include "openmc/xml_interface.h" @@ -154,10 +155,8 @@ T PlotBase::get_map() const { in_i = 1; out_i = 2; break; -#ifdef __GNUC__ default: - __builtin_unreachable(); -#endif + UNREACHABLE(); } // set initial position diff --git a/include/openmc/volume_calc.h b/include/openmc/volume_calc.h index e025ab3b01..3258be9d6b 100644 --- a/include/openmc/volume_calc.h +++ b/include/openmc/volume_calc.h @@ -7,6 +7,7 @@ #include "pugixml.hpp" #include "xtensor/xtensor.hpp" +#include #include #include #include diff --git a/src/settings.cpp b/src/settings.cpp index 32a7958d8d..9bdfd77562 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -2,9 +2,9 @@ #include // for ceil, pow #include // for numeric_limits -#include #include +#include #ifdef _OPENMP #include #endif @@ -130,7 +130,7 @@ void get_run_parameters(pugi::xml_node node_base) if (n_particles == -1) { n_particles = std::stoll(get_node_value(node_base, "particles")); } - + // Get maximum number of in flight particles for event-based mode if (check_for_node(node_base, "max_particles_in_flight")) { max_particles_in_flight = std::stoll(get_node_value(node_base, @@ -195,13 +195,13 @@ void read_settings_xml() std::string filename = path_input + "settings.xml"; if (!file_exists(filename)) { if (run_mode != RunMode::PLOTTING) { - std::stringstream msg; - msg << "Settings XML file '" << filename << "' does not exist! In order " + fatal_error(fmt::format( + "Settings XML file '{}' does not exist! In order " "to run OpenMC, you first need a set of input files; at a minimum, this " "includes settings.xml, geometry.xml, and materials.xml. Please consult " - "the user's guide at http://openmc.readthedocs.io for further " - "information."; - fatal_error(msg); + "the user's guide at https://docs.openmc.org for further " + "information.", filename + )); } else { // The settings.xml file is optional if we just want to make a plot. return; @@ -494,9 +494,8 @@ void read_settings_xml() if (check_for_node(root, "entropy_mesh")) { int temp = std::stoi(get_node_value(root, "entropy_mesh")); if (model::mesh_map.find(temp) == model::mesh_map.end()) { - std::stringstream msg; - msg << "Mesh " << temp << " specified for Shannon entropy does not exist."; - fatal_error(msg); + fatal_error(fmt::format( + "Mesh {} specified for Shannon entropy does not exist.", temp)); } index_entropy_mesh = model::mesh_map.at(temp); @@ -544,10 +543,8 @@ void read_settings_xml() if (check_for_node(root, "ufs_mesh")) { auto temp = std::stoi(get_node_value(root, "ufs_mesh")); if (model::mesh_map.find(temp) == model::mesh_map.end()) { - std::stringstream msg; - msg << "Mesh " << temp << " specified for uniform fission site method " - "does not exist."; - fatal_error(msg); + fatal_error(fmt::format("Mesh {} specified for uniform fission site " + "method does not exist.", temp)); } i_ufs_mesh = model::mesh_map.at(temp); @@ -792,7 +789,7 @@ void read_settings_xml() if (check_for_node(root, "delayed_photon_scaling")) { delayed_photon_scaling = get_node_value_bool(root, "delayed_photon_scaling"); } - + // Check whether to use event-based parallelism if (check_for_node(root, "event_based")) { event_based = get_node_value_bool(root, "event_based"); diff --git a/src/source.cpp b/src/source.cpp index 6314eb23f7..6315208543 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -1,8 +1,8 @@ #include "openmc/source.h" #include // for move -#include // for stringstream +#include #include "xtensor/xadapt.hpp" #include "openmc/bank.h" @@ -68,9 +68,8 @@ SourceDistribution::SourceDistribution(pugi::xml_node node) // Check if source file exists if (!file_exists(settings::path_source)) { - std::stringstream msg; - msg << "Source file '" << settings::path_source << "' does not exist."; - fatal_error(msg); + fatal_error(fmt::format("Source file '{}' does not exist.", + settings::path_source)); } } else { @@ -97,9 +96,8 @@ SourceDistribution::SourceDistribution(pugi::xml_node node) } else if (type == "point") { space_ = UPtrSpace{new SpatialPoint(node_space)}; } else { - std::stringstream msg; - msg << "Invalid spatial distribution for external source: " << type; - fatal_error(msg); + fatal_error(fmt::format( + "Invalid spatial distribution for external source: {}", type)); } } else { @@ -123,9 +121,8 @@ SourceDistribution::SourceDistribution(pugi::xml_node node) } else if (type == "mu-phi") { angle_ = UPtrAngle{new PolarAzimuthal(node_angle)}; } else { - std::stringstream msg; - msg << "Invalid angular distribution for external source: " << type; - fatal_error(msg); + fatal_error(fmt::format( + "Invalid angular distribution for external source: {}", type)); } } else { @@ -244,9 +241,8 @@ void initialize_source() // Read the source from a binary file instead of sampling from some // assumed source distribution - std::stringstream msg; - msg << "Reading source file from " << settings::path_source << "..."; - write_message(msg, 6); + write_message(fmt::format("Reading source file from {}...", + settings::path_source), 6); // Open the binary file hid_t file_id = file_open(settings::path_source, 'r', true); diff --git a/src/state_point.cpp b/src/state_point.cpp index 60fd3826de..706eb17efe 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -2,10 +2,10 @@ #include #include // for int64_t -#include // for setfill, setw #include #include +#include #include "xtensor/xbuilder.hpp" // for empty_like #include "xtensor/xview.hpp" @@ -41,10 +41,8 @@ openmc_statepoint_write(const char* filename, bool* write_source) int w = std::to_string(settings::n_max_batches).size(); // Set filename for state point - std::stringstream ss; - ss << settings::path_output << "statepoint." << std::setfill('0') - << std::setw(w) << simulation::current_batch << ".h5"; - filename_ = ss.str(); + filename_ = fmt::format("{0}statepoint.{1:0{2}}.h5", + settings::path_output, simulation::current_batch, w); } // Determine whether or not to write the source bank @@ -523,10 +521,8 @@ write_source_point(const char* filename) // Determine width for zero padding int w = std::to_string(settings::n_max_batches).size(); - std::stringstream s; - s << settings::path_output << "source." << std::setfill('0') - << std::setw(w) << simulation::current_batch << ".h5"; - filename_ = s.str(); + filename_ = fmt::format("{0}source.{1:0{2}}.h5", + settings::path_output, simulation::current_batch, w); } hid_t file_id; diff --git a/src/surface.cpp b/src/surface.cpp index f5399fa6a8..b1ba2eb050 100644 --- a/src/surface.cpp +++ b/src/surface.cpp @@ -2,9 +2,10 @@ #include #include -#include #include +#include + #include "openmc/error.h" #include "openmc/dagmc.h" #include "openmc/hdf5_interface.h" @@ -35,10 +36,8 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1) std::string coeffs = get_node_value(surf_node, "coeffs"); int n_words = word_count(coeffs); if (n_words != 1) { - std::stringstream err_msg; - err_msg << "Surface " << surf_id << " expects 1 coeff but was given " - << n_words; - fatal_error(err_msg); + fatal_error(fmt::format("Surface {} expects 1 coeff but was given {}", + surf_id, n_words)); } // Parse the coefficients. @@ -55,10 +54,8 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2, std::string coeffs = get_node_value(surf_node, "coeffs"); int n_words = word_count(coeffs); if (n_words != 3) { - std::stringstream err_msg; - err_msg << "Surface " << surf_id << " expects 3 coeffs but was given " - << n_words; - fatal_error(err_msg); + fatal_error(fmt::format("Surface {} expects 3 coeffs but was given {}", + surf_id, n_words)); } // Parse the coefficients. @@ -75,10 +72,8 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2, std::string coeffs = get_node_value(surf_node, "coeffs"); int n_words = word_count(coeffs); if (n_words != 4) { - std::stringstream err_msg; - err_msg << "Surface " << surf_id << " expects 4 coeffs but was given " - << n_words; - fatal_error(err_msg); + fatal_error(fmt::format("Surface {} expects 4 coeffs but was given ", + surf_id, n_words)); } // Parse the coefficients. @@ -96,10 +91,8 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2, std::string coeffs = get_node_value(surf_node, "coeffs"); int n_words = word_count(coeffs); if (n_words != 10) { - std::stringstream err_msg; - err_msg << "Surface " << surf_id << " expects 10 coeffs but was given " - << n_words; - fatal_error(err_msg); + fatal_error(fmt::format("Surface {} expects 10 coeffs but was given {}", + surf_id, n_words)); } // Parse the coefficients. @@ -145,10 +138,8 @@ Surface::Surface(pugi::xml_node surf_node) } else if (surf_bc == "periodic") { bc_ = BoundaryType::PERIODIC; } else { - std::stringstream err_msg; - err_msg << "Unknown boundary condition \"" << surf_bc - << "\" specified on surface " << id_; - fatal_error(err_msg); + fatal_error(fmt::format("Unknown boundary condition \"{}\" specified " + "on surface {}", surf_bc, id_)); } } else { @@ -1170,9 +1161,7 @@ void read_surfaces(pugi::xml_node node) model::surfaces.push_back(std::make_unique(surf_node)); } else { - std::stringstream err_msg; - err_msg << "Invalid surface type, \"" << surf_type << "\""; - fatal_error(err_msg); + fatal_error(fmt::format("Invalid surface type, \"{}\"", surf_type)); } } } @@ -1184,9 +1173,8 @@ void read_surfaces(pugi::xml_node node) if (in_map == model::surface_map.end()) { model::surface_map[id] = i_surf; } else { - std::stringstream err_msg; - err_msg << "Two or more surfaces use the same unique ID: " << id; - fatal_error(err_msg); + fatal_error(fmt::format( + "Two or more surfaces use the same unique ID: {}", id)); } } @@ -1202,11 +1190,9 @@ void read_surfaces(pugi::xml_node node) // Make sure this surface inherits from PeriodicSurface. if (!surf) { - std::stringstream err_msg; - err_msg << "Periodic boundary condition not supported for surface " - << surf_base->id_ - << ". Periodic BCs are only supported for planar surfaces."; - fatal_error(err_msg); + fatal_error(fmt::format( + "Periodic boundary condition not supported for surface {}. Periodic " + "BCs are only supported for planar surfaces.", surf_base->id_)); } // See if this surface makes part of the global bounding box. @@ -1278,10 +1264,8 @@ void read_surfaces(pugi::xml_node node) // This is a SurfacePlane. We won't try to find it's partner if the // user didn't specify one. if (surf->i_periodic_ == C_NONE) { - std::stringstream err_msg; - err_msg << "No matching periodic surface specified for periodic " - "boundary condition on surface " << surf->id_; - fatal_error(err_msg); + fatal_error(fmt::format("No matching periodic surface specified for " + "periodic boundary condition on surface {}", surf->id_)); } else { // Convert the surface id to an index. surf->i_periodic_ = model::surface_map[surf->i_periodic_]; @@ -1290,10 +1274,8 @@ void read_surfaces(pugi::xml_node node) // Make sure the opposite surface is also periodic. if (model::surfaces[surf->i_periodic_]->bc_ != Surface::BoundaryType::PERIODIC) { - std::stringstream err_msg; - err_msg << "Could not find matching surface for periodic boundary " - "condition on surface " << surf->id_; - fatal_error(err_msg); + fatal_error(fmt::format("Could not find matching surface for periodic " + "boundary condition on surface {}", surf->id_)); } } } diff --git a/src/tallies/derivative.cpp b/src/tallies/derivative.cpp index 1d2d2fc99b..483008340c 100644 --- a/src/tallies/derivative.cpp +++ b/src/tallies/derivative.cpp @@ -7,7 +7,7 @@ #include "openmc/tallies/tally.h" #include "openmc/xml_interface.h" -#include +#include template class std::vector; @@ -55,20 +55,16 @@ TallyDerivative::TallyDerivative(pugi::xml_node node) } } if (!found) { - std::stringstream out; - out << "Could not find the nuclide \"" << nuclide_name - << "\" specified in derivative " << id << " in any material."; - fatal_error(out); + fatal_error(fmt::format("Could not find the nuclide \"{}\" specified in " + "derivative {} in any material.", nuclide_name, id)); } } else if (variable_str == "temperature") { variable = DerivativeVariable::TEMPERATURE; } else { - std::stringstream out; - out << "Unrecognized variable \"" << variable_str - << "\" on derivative " << id; - fatal_error(out); + fatal_error(fmt::format("Unrecognized variable \"{}\" on derivative {}", + variable_str, id)); } diff_material = std::stoi(get_node_value(node, "material")); @@ -568,7 +564,7 @@ score_track_derivative(Particle* p, double distance) // A void material cannot be perturbed so it will not affect flux derivatives. if (p->material_ == MATERIAL_VOID) return; const Material& material {*model::materials[p->material_]}; - + for (auto idx = 0; idx < model::tally_derivs.size(); idx++) { const auto& deriv = model::tally_derivs[idx]; auto& flux_deriv = p->flux_derivs_[idx]; @@ -641,11 +637,9 @@ void score_collision_derivative(Particle* p) if (material.nuclide_[i] == deriv.diff_nuclide) break; // Make sure we found the nuclide. if (material.nuclide_[i] != deriv.diff_nuclide) { - std::stringstream err_msg; - err_msg << "Could not find nuclide " - << data::nuclides[deriv.diff_nuclide]->name_ << " in material " - << material.id_ << " for tally derivative " << deriv.id; - fatal_error(err_msg); + fatal_error(fmt::format( + "Could not find nuclide {} in material {} for tally derivative {}", + data::nuclides[deriv.diff_nuclide]->name_, material.id_, deriv.id)); } // phi is proportional to Sigma_s // (1 / phi) * (d_phi / d_N) = (d_Sigma_s / d_N) / Sigma_s diff --git a/src/tallies/filter_azimuthal.cpp b/src/tallies/filter_azimuthal.cpp index 2cf03a1277..4d18e5974b 100644 --- a/src/tallies/filter_azimuthal.cpp +++ b/src/tallies/filter_azimuthal.cpp @@ -1,7 +1,8 @@ #include "openmc/tallies/filter_azimuthal.h" #include -#include + +#include #include "openmc/constants.h" #include "openmc/error.h" @@ -77,9 +78,7 @@ AzimuthalFilter::to_statepoint(hid_t filter_group) const std::string AzimuthalFilter::text_label(int bin) const { - std::stringstream out; - out << "Azimuthal Angle [" << bins_[bin] << ", " << bins_[bin+1] << ")"; - return out.str(); + return fmt::format("Azimuthal Angle [{}, {})", bins_[bin], bins_[bin+1]); } } // namespace openmc diff --git a/src/tallies/filter_cell.cpp b/src/tallies/filter_cell.cpp index 3077c42ea4..86e78df91b 100644 --- a/src/tallies/filter_cell.cpp +++ b/src/tallies/filter_cell.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_cell.h" -#include +#include #include "openmc/capi.h" #include "openmc/cell.h" @@ -17,10 +17,8 @@ CellFilter::from_xml(pugi::xml_node node) for (auto& c : cells) { auto search = model::cell_map.find(c); if (search == model::cell_map.end()) { - std::stringstream err_msg; - err_msg << "Could not find cell " << c - << " specified on tally filter."; - throw std::runtime_error{err_msg.str()}; + throw std::runtime_error{fmt::format( + "Could not find cell {} specified on tally filter.", c)}; } c = search->second; } @@ -72,7 +70,7 @@ CellFilter::to_statepoint(hid_t filter_group) const std::string CellFilter::text_label(int bin) const { - return "Cell " + std::to_string(model::cells[cells_[bin]]->id_); + return fmt::format("Cell {}", model::cells[cells_[bin]]->id_); } //============================================================================== diff --git a/src/tallies/filter_cell_instance.cpp b/src/tallies/filter_cell_instance.cpp index 3417ca0774..cb6381410c 100644 --- a/src/tallies/filter_cell_instance.cpp +++ b/src/tallies/filter_cell_instance.cpp @@ -1,8 +1,9 @@ #include "openmc/tallies/filter_cell_instance.h" -#include #include +#include + #include "openmc/capi.h" #include "openmc/cell.h" #include "openmc/error.h" @@ -29,10 +30,8 @@ CellInstanceFilter::from_xml(pugi::xml_node node) gsl::index instance = cells[2*i + 1]; auto search = model::cell_map.find(cell_id); if (search == model::cell_map.end()) { - std::stringstream err_msg; - err_msg << "Could not find cell " << cell_id - << " specified on tally filter."; - throw std::runtime_error{err_msg.str()}; + throw std::runtime_error{fmt::format( + "Could not find cell {} specified on tally filter.", cell_id)}; } gsl::index index = search->second; instances.push_back({index, instance}); @@ -55,9 +54,9 @@ CellInstanceFilter::set_cell_instances(gsl::span instances) Expects(x.index_cell < model::cells.size()); const auto& c {model::cells[x.index_cell]}; if (c->type_ != Fill::MATERIAL) { - throw std::invalid_argument{"Cell " + std::to_string(c->id_) + " is not " - "filled with a material. Only material cells can be used in a cell " - "instance filter."}; + throw std::invalid_argument{fmt::format( + "Cell {} is not filled with a material. Only material cells can be " + "used in a cell instance filter.", c->id_)}; } cell_instances_.push_back(x); map_[x] = cell_instances_.size() - 1; diff --git a/src/tallies/filter_distribcell.cpp b/src/tallies/filter_distribcell.cpp index 9efe317590..7ea9b9b04f 100644 --- a/src/tallies/filter_distribcell.cpp +++ b/src/tallies/filter_distribcell.cpp @@ -1,5 +1,7 @@ #include "openmc/tallies/filter_distribcell.h" +#include + #include "openmc/cell.h" #include "openmc/error.h" #include "openmc/geometry_aux.h" // For distribcell_path @@ -19,10 +21,8 @@ DistribcellFilter::from_xml(pugi::xml_node node) // Find index in global cells vector corresponding to cell ID auto search = model::cell_map.find(cells[0]); if (search == model::cell_map.end()) { - std::stringstream err_msg; - err_msg << "Could not find cell " << cell_ - << " specified on tally filter."; - throw std::runtime_error{err_msg.str()}; + throw std::runtime_error{fmt::format( + "Could not find cell {} specified on tally filter.", cell_)}; } this->set_cell(search->second); diff --git a/src/tallies/filter_energy.cpp b/src/tallies/filter_energy.cpp index a2c69c9478..1ffea14029 100644 --- a/src/tallies/filter_energy.cpp +++ b/src/tallies/filter_energy.cpp @@ -1,5 +1,7 @@ #include "openmc/tallies/filter_energy.h" +#include + #include "openmc/capi.h" #include "openmc/constants.h" // For F90_NONE #include "openmc/mgxs_interface.h" @@ -90,9 +92,7 @@ EnergyFilter::to_statepoint(hid_t filter_group) const std::string EnergyFilter::text_label(int bin) const { - std::stringstream out; - out << "Incoming Energy [" << bins_[bin] << ", " << bins_[bin+1] << ")"; - return out.str(); + return fmt::format("Incoming Energy [{}, {})", bins_[bin], bins_[bin+1]); } //============================================================================== @@ -119,9 +119,7 @@ EnergyoutFilter::get_all_bins(const Particle* p, TallyEstimator estimator, std::string EnergyoutFilter::text_label(int bin) const { - std::stringstream out; - out << "Outgoing Energy [" << bins_[bin] << ", " << bins_[bin+1] << ")"; - return out.str(); + return fmt::format("Outgoing Energy [{}, {})", bins_[bin], bins_[bin+1]); } //============================================================================== diff --git a/src/tallies/filter_energyfunc.cpp b/src/tallies/filter_energyfunc.cpp index 59cc4fcaa2..cecd8306ba 100644 --- a/src/tallies/filter_energyfunc.cpp +++ b/src/tallies/filter_energyfunc.cpp @@ -1,8 +1,6 @@ #include "openmc/tallies/filter_energyfunc.h" -#include // for setprecision -#include // for scientific -#include +#include #include "openmc/error.h" #include "openmc/search.h" @@ -82,12 +80,9 @@ EnergyFunctionFilter::to_statepoint(hid_t filter_group) const std::string EnergyFunctionFilter::text_label(int bin) const { - std::stringstream out; - out << std::scientific << std::setprecision(1) - << "Energy Function f" - << "([ " << energy_.front() << ", ..., " << energy_.back() << "]) = " - << "[" << y_.front() << ", ..., " << y_.back() << "]"; - return out.str(); + return fmt::format( + "Energy Function f([{:.1e}, ..., {:.1e}]) = [{:.1e}, ..., {:.1e}]", + energy_.front(), energy_.back(), y_.front(), y_.back()); } //============================================================================== diff --git a/src/tallies/filter_material.cpp b/src/tallies/filter_material.cpp index f0c2bbf8e6..2760b028d1 100644 --- a/src/tallies/filter_material.cpp +++ b/src/tallies/filter_material.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_material.h" -#include +#include #include "openmc/capi.h" #include "openmc/material.h" @@ -16,10 +16,8 @@ MaterialFilter::from_xml(pugi::xml_node node) for (auto& m : mats) { auto search = model::material_map.find(m); if (search == model::material_map.end()) { - std::stringstream err_msg; - err_msg << "Could not find material " << m - << " specified on tally filter."; - throw std::runtime_error{err_msg.str()}; + throw std::runtime_error{fmt::format( + "Could not find material {} specified on tally filter.", m)}; } m = search->second; } @@ -69,7 +67,7 @@ MaterialFilter::to_statepoint(hid_t filter_group) const std::string MaterialFilter::text_label(int bin) const { - return "Material " + std::to_string(model::materials[materials_[bin]]->id_); + return fmt::format("Material {}", model::materials[materials_[bin]]->id_); } //============================================================================== diff --git a/src/tallies/filter_mesh.cpp b/src/tallies/filter_mesh.cpp index f80e31dc19..609c3662bc 100644 --- a/src/tallies/filter_mesh.cpp +++ b/src/tallies/filter_mesh.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_mesh.h" -#include +#include #include "openmc/capi.h" #include "openmc/constants.h" @@ -24,9 +24,8 @@ MeshFilter::from_xml(pugi::xml_node node) if (search != model::mesh_map.end()) { set_mesh(search->second); } else{ - std::stringstream err_msg; - err_msg << "Could not find mesh " << id << " specified on tally filter."; - fatal_error(err_msg); + fatal_error(fmt::format( + "Could not find mesh {} specified on tally filter.", id)); } } @@ -61,13 +60,13 @@ MeshFilter::text_label(int bin) const std::vector ijk(n_dim); mesh.get_indices_from_bin(bin, ijk.data()); - std::stringstream out; - out << "Mesh Index (" << ijk[0]; - if (n_dim > 1) out << ", " << ijk[1]; - if (n_dim > 2) out << ", " << ijk[2]; - out << ")"; - - return out.str(); + if (n_dim > 2) { + return fmt::format("Mesh Index ({}, {}, {})", ijk[0], ijk[1], ijk[2]); + } else if (n_dim > 1) { + return fmt::format("Mesh Index ({}, {})", ijk[0], ijk[1]); + } else { + return fmt::format("Mesh Index ({})", ijk[0]) ; + } } void diff --git a/src/tallies/filter_mu.cpp b/src/tallies/filter_mu.cpp index a345fe2bd1..2a75089d50 100644 --- a/src/tallies/filter_mu.cpp +++ b/src/tallies/filter_mu.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_mu.h" -#include +#include #include "openmc/error.h" #include "openmc/search.h" @@ -69,9 +69,7 @@ MuFilter::to_statepoint(hid_t filter_group) const std::string MuFilter::text_label(int bin) const { - std::stringstream out; - out << "Change-in-Angle [" << bins_[bin] << ", " << bins_[bin+1] << ")"; - return out.str(); + return fmt::format("Change-in-Angle [{}, {})", bins_[bin], bins_[bin+1]); } } // namespace openmc diff --git a/src/tallies/filter_polar.cpp b/src/tallies/filter_polar.cpp index f35c1d3cd4..367ca738a2 100644 --- a/src/tallies/filter_polar.cpp +++ b/src/tallies/filter_polar.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_polar.h" -#include +#include #include "openmc/constants.h" #include "openmc/error.h" @@ -77,9 +77,7 @@ PolarFilter::to_statepoint(hid_t filter_group) const std::string PolarFilter::text_label(int bin) const { - std::stringstream out; - out << "Polar Angle [" << bins_[bin] << ", " << bins_[bin+1] << ")"; - return out.str(); + return fmt::format("Polar Angle [{}, {})", bins_[bin], bins_[bin+1]); } } // namespace openmc diff --git a/src/tallies/filter_sph_harm.cpp b/src/tallies/filter_sph_harm.cpp index bbeebf5b18..b9852aafd7 100644 --- a/src/tallies/filter_sph_harm.cpp +++ b/src/tallies/filter_sph_harm.cpp @@ -2,6 +2,9 @@ #include // For pair +#include +#include + #include "openmc/capi.h" #include "openmc/error.h" #include "openmc/math_functions.h" @@ -36,10 +39,8 @@ SphericalHarmonicsFilter::set_cosine(gsl::cstring_span cosine) } else if (cosine == "particle") { cosine_ = SphericalHarmonicsCosine::particle; } else { - std::stringstream err_msg; - err_msg << "Unrecognized cosine type, \"" << cosine - << "\" in spherical harmonics filter"; - throw std::invalid_argument{err_msg.str()}; + throw std::invalid_argument{fmt::format("Unrecognized cosine type, \"{}\" " + "in spherical harmonics filter", gsl::to_string(cosine))}; } } @@ -88,15 +89,14 @@ SphericalHarmonicsFilter::to_statepoint(hid_t filter_group) const std::string SphericalHarmonicsFilter::text_label(int bin) const { - std::stringstream out; + Expects(bin >= 0 && bin < n_bins_); for (int n = 0; n < order_ + 1; n++) { if (bin < (n + 1) * (n + 1)) { int m = (bin - n*n) - n; - out << "Spherical harmonic expansion, Y" << n << "," << m; - break; + return fmt::format("Spherical harmonic expansion, Y{},{}", n, m); } } - return out.str(); + UNREACHABLE(); } //============================================================================== diff --git a/src/tallies/filter_sptl_legendre.cpp b/src/tallies/filter_sptl_legendre.cpp index 71cc3f399f..1b38ec1547 100644 --- a/src/tallies/filter_sptl_legendre.cpp +++ b/src/tallies/filter_sptl_legendre.cpp @@ -2,6 +2,8 @@ #include // For pair +#include + #include "openmc/capi.h" #include "openmc/error.h" #include "openmc/math_functions.h" @@ -107,17 +109,13 @@ SpatialLegendreFilter::to_statepoint(hid_t filter_group) const std::string SpatialLegendreFilter::text_label(int bin) const { - std::stringstream out; - out << "Legendre expansion, "; if (axis_ == LegendreAxis::x) { - out << "x"; + return fmt::format("Legendre expansion, x axis, P{}", bin); } else if (axis_ == LegendreAxis::y) { - out << "y"; + return fmt::format("Legendre expansion, y axis, P{}", bin); } else { - out << "z"; + return fmt::format("Legendre expansion, z axis, P{}", bin); } - out << " axis, P" << std::to_string(bin); - return out.str(); } //============================================================================== diff --git a/src/tallies/filter_surface.cpp b/src/tallies/filter_surface.cpp index 5613f039a1..203a6a094e 100644 --- a/src/tallies/filter_surface.cpp +++ b/src/tallies/filter_surface.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_surface.h" -#include +#include #include "openmc/error.h" #include "openmc/surface.h" @@ -17,10 +17,8 @@ SurfaceFilter::from_xml(pugi::xml_node node) for (auto& s : surfaces) { auto search = model::surface_map.find(s); if (search == model::surface_map.end()) { - std::stringstream err_msg; - err_msg << "Could not find surface " << s - << " specified on tally filter."; - throw std::runtime_error{err_msg.str()}; + throw std::runtime_error{fmt::format( + "Could not find surface {} specified on tally filter.", s)}; } s = search->second; @@ -75,7 +73,7 @@ SurfaceFilter::to_statepoint(hid_t filter_group) const std::string SurfaceFilter::text_label(int bin) const { - return "Surface " + std::to_string(model::surfaces[surfaces_[bin]]->id_); + return fmt::format("Surface {}", model::surfaces[surfaces_[bin]]->id_); } } // namespace openmc diff --git a/src/tallies/filter_universe.cpp b/src/tallies/filter_universe.cpp index 289e96f561..75c5ebe599 100644 --- a/src/tallies/filter_universe.cpp +++ b/src/tallies/filter_universe.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_universe.h" -#include +#include #include "openmc/cell.h" #include "openmc/error.h" @@ -16,10 +16,8 @@ UniverseFilter::from_xml(pugi::xml_node node) for (auto& u : universes) { auto search = model::universe_map.find(u); if (search == model::universe_map.end()) { - std::stringstream err_msg; - err_msg << "Could not find universe " << u - << " specified on tally filter."; - throw std::runtime_error{err_msg.str()}; + throw std::runtime_error{fmt::format( + "Could not find universe {} specified on tally filter.", u)}; } u = search->second; } @@ -71,7 +69,7 @@ UniverseFilter::to_statepoint(hid_t filter_group) const std::string UniverseFilter::text_label(int bin) const { - return "Universe " + std::to_string(model::universes[universes_[bin]]->id_); + return fmt::format("Universe {}", model::universes[universes_[bin]]->id_); } } // namespace openmc diff --git a/src/tallies/filter_zernike.cpp b/src/tallies/filter_zernike.cpp index 826d9f508f..badd85103b 100644 --- a/src/tallies/filter_zernike.cpp +++ b/src/tallies/filter_zernike.cpp @@ -4,6 +4,9 @@ #include #include // For pair +#include +#include + #include "openmc/capi.h" #include "openmc/error.h" #include "openmc/math_functions.h" @@ -58,17 +61,16 @@ ZernikeFilter::to_statepoint(hid_t filter_group) const std::string ZernikeFilter::text_label(int bin) const { - std::stringstream out; + Expects(bin >= 0 && bin < n_bins_); for (int n = 0; n < order_+1; n++) { int last = (n + 1) * (n + 2) / 2; if (bin < last) { int first = last - (n + 1); int m = -n + (bin - first) * 2; - out << "Zernike expansion, Z" << n << "," << m; - break; + return fmt::format("Zernike expansion, Z{},{}", n, m); } } - return out.str(); + UNREACHABLE(); } void diff --git a/src/tallies/tally.cpp b/src/tallies/tally.cpp index 22d0e2e041..b52c09ee35 100644 --- a/src/tallies/tally.cpp +++ b/src/tallies/tally.cpp @@ -28,6 +28,7 @@ #include "openmc/tallies/filter_surface.h" #include "openmc/xml_interface.h" +#include #include "xtensor/xadapt.hpp" #include "xtensor/xbuilder.hpp" // for empty_like #include "xtensor/xview.hpp" @@ -35,7 +36,6 @@ #include // for max #include #include // for size_t -#include #include namespace openmc { @@ -287,8 +287,8 @@ Tally::Tally(pugi::xml_node node) // Determine if filter ID is valid auto it = model::filter_map.find(filter_id); if (it == model::filter_map.end()) { - throw std::runtime_error{"Could not find filter " + std::to_string(filter_id) - + " specified on tally " + std::to_string(id_)}; + throw std::runtime_error{fmt::format( + "Could not find filter {} specified on tally {}", filter_id, id_)}; } // Store the index of the filter @@ -334,8 +334,7 @@ Tally::Tally(pugi::xml_node node) this->set_scores(node); if (!check_for_node(node, "scores")) { - fatal_error("No scores specified on tally " + std::to_string(id_) - + "."); + fatal_error(fmt::format("No scores specified on tally {}.", id_)); } // Check if tally is compatible with particle type @@ -371,9 +370,9 @@ Tally::Tally(pugi::xml_node node) auto pf = dynamic_cast(f); for (auto p : pf->particles()) { if (p != Particle::Type::neutron) { - warning("Particle filter other than NEUTRON used with photon " - "transport turned off. All tallies for particle type " + - std::to_string(static_cast(p)) + " will have no scores"); + warning(fmt::format("Particle filter other than NEUTRON used with " + "photon transport turned off. All tallies for particle type {}" + " will have no scores", static_cast(p))); } } } @@ -386,8 +385,8 @@ Tally::Tally(pugi::xml_node node) // Find the derivative with the given id, and store it's index. auto it = model::tally_deriv_map.find(deriv_id); if (it == model::tally_deriv_map.end()) { - fatal_error("Could not find derivative " + std::to_string(deriv_id) - + " specified on tally " + std::to_string(id_)); + fatal_error(fmt::format( + "Could not find derivative {} specified on tally {}", deriv_id, id_)); } deriv_ = it->second; @@ -403,11 +402,10 @@ Tally::Tally(pugi::xml_node node) || deriv.variable == DerivativeVariable::TEMPERATURE) { for (int i_nuc : nuclides_) { if (has_energyout && i_nuc == -1) { - fatal_error("Error on tally " + std::to_string(id_) - + ": Cannot use a 'nuclide_density' or 'temperature' " - "derivative on a tally with an outgoing energy filter and " - "'total' nuclide rate. Instead, tally each nuclide in the " - "material individually."); + fatal_error(fmt::format("Error on tally {}: Cannot use a " + "'nuclide_density' or 'temperature' derivative on a tally with an " + "outgoing energy filter and 'total' nuclide rate. Instead, tally " + "each nuclide in the material individually.", id_)); // Note that diff tallies with these characteristics would work // correctly if no tally events occur in the perturbed material // (e.g. pertrubing moderator but only tallying fuel), but this @@ -432,11 +430,11 @@ Tally::Tally(pugi::xml_node node) estimator_ = TallyEstimator::ANALOG; } else if (est == "tracklength" || est == "track-length" || est == "pathlength" || est == "path-length") { - // If the estimator was set to an analog/collision estimator, this means - // the tally needs post-collision information + // If the estimator was set to an analog estimator, this means the + // tally needs post-collision information if (estimator_ == TallyEstimator::ANALOG || estimator_ == TallyEstimator::COLLISION) { - throw std::runtime_error{"Cannot use track-length estimator for tally " - + std::to_string(id_)}; + throw std::runtime_error{fmt::format("Cannot use track-length " + "estimator for tally {}", id_)}; } // Set estimator to track-length estimator @@ -446,16 +444,16 @@ Tally::Tally(pugi::xml_node node) // If the estimator was set to an analog estimator, this means the // tally needs post-collision information if (estimator_ == TallyEstimator::ANALOG) { - throw std::runtime_error{"Cannot use collision estimator for tally " + - std::to_string(id_)}; + throw std::runtime_error{fmt::format("Cannot use collision estimator " + "for tally ", id_)}; } // Set estimator to collision estimator estimator_ = TallyEstimator::COLLISION; } else { - throw std::runtime_error{"Invalid estimator '" + est + "' on tally " + - std::to_string(id_)}; + throw std::runtime_error{fmt::format( + "Invalid estimator '{}' on tally {}", est, id_)}; } } } @@ -485,7 +483,7 @@ Tally::set_id(int32_t id) // Make sure no other tally has the same ID if (model::tally_map.find(id) != model::tally_map.end()) { - throw std::runtime_error{"Two tallies have the same ID: " + std::to_string(id)}; + throw std::runtime_error{fmt::format("Two tallies have the same ID: {}", id)}; } // If no ID specified, auto-assign next ID in sequence @@ -542,7 +540,7 @@ void Tally::set_scores(pugi::xml_node node) { if (!check_for_node(node, "scores")) - fatal_error("No scores specified on tally " + std::to_string(id_)); + fatal_error(fmt::format("No scores specified on tally {}", id_)); auto scores = get_node_array(node, "scores"); set_scores(scores); @@ -659,8 +657,9 @@ Tally::set_scores(const std::vector& scores) for (auto it1 = scores_.begin(); it1 != scores_.end(); ++it1) { for (auto it2 = it1 + 1; it2 != scores_.end(); ++it2) { if (*it1 == *it2) - fatal_error("Duplicate score of type \"" + reaction_name(*it1) - + "\" found in tally " + std::to_string(id_)); + fatal_error(fmt::format( + "Duplicate score of type \"{}\" found in tally {}", + reaction_name(*it1), id_)); } } @@ -720,9 +719,8 @@ Tally::set_nuclides(const std::vector& nuclides) } else { auto search = data::nuclide_map.find(nuc); if (search == data::nuclide_map.end()) - fatal_error("Could not find the nuclide " + nuc - + " specified in tally " + std::to_string(id_) - + " in any material"); + fatal_error(fmt::format("Could not find the nuclide {} specified in " + "tally {} in any material", nuc, id_)); nuclides_.push_back(search->second); } } @@ -743,15 +741,12 @@ Tally::init_triggers(pugi::xml_node node) } else if (type_str == "rel_err") { metric = TriggerMetric::relative_error; } else { - std::stringstream msg; - msg << "Unknown trigger type \"" << type_str << "\" in tally " << id_; - fatal_error(msg); + fatal_error(fmt::format("Unknown trigger type \"{}\" in tally {}", + type_str, id_)); } } else { - std::stringstream msg; - msg << "Must specify trigger type for tally " << id_ - << " in tally XML file"; - fatal_error(msg); + fatal_error(fmt::format( + "Must specify trigger type for tally {} in tally XML file", id_)); } // Read the trigger threshold. @@ -759,10 +754,8 @@ Tally::init_triggers(pugi::xml_node node) if (check_for_node(trigger_node, "threshold")) { threshold = std::stod(get_node_value(trigger_node, "threshold")); } else { - std::stringstream msg; - msg << "Must specify trigger threshold for tally " << id_ - << " in tally XML file"; - fatal_error(msg); + fatal_error(fmt::format( + "Must specify trigger threshold for tally {} in tally XML file", id_)); } // Read the trigger scores. @@ -786,10 +779,8 @@ Tally::init_triggers(pugi::xml_node node) if (reaction_name(this->scores_[i_score]) == score_str) break; } if (i_score == this->scores_.size()) { - std::stringstream msg; - msg << "Could not find the score \"" << score_str << "\" in tally " - << id_ << " but it was listed in a trigger on that tally"; - fatal_error(msg); + fatal_error(fmt::format("Could not find the score \"{}\" in tally " + "{} but it was listed in a trigger on that tally", score_str, id_)); } triggers_.push_back({metric, threshold, i_score}); } @@ -1078,7 +1069,7 @@ openmc_get_tally_index(int32_t id, int32_t* index) { auto it = model::tally_map.find(id); if (it == model::tally_map.end()) { - set_errmsg("No tally exists with ID=" + std::to_string(id) + "."); + set_errmsg(fmt::format("No tally exists with ID={}.", id)); return OPENMC_E_INVALID_ID; } @@ -1182,9 +1173,7 @@ openmc_tally_set_type(int32_t index, const char* type) } else if (strcmp(type, "surface") == 0) { model::tallies[index]->type_ = TallyType::SURFACE; } else { - std::stringstream errmsg; - errmsg << "Unknown tally type: " << type; - set_errmsg(errmsg); + set_errmsg(fmt::format("Unknown tally type: {}", type)); return OPENMC_E_INVALID_ARGUMENT; } diff --git a/src/tallies/trigger.cpp b/src/tallies/trigger.cpp index 7fb3475c9b..405650b2b7 100644 --- a/src/tallies/trigger.cpp +++ b/src/tallies/trigger.cpp @@ -1,9 +1,10 @@ #include "openmc/tallies/trigger.h" #include -#include #include // for std::pair +#include + #include "openmc/capi.h" #include "openmc/constants.h" #include "openmc/error.h" @@ -170,13 +171,14 @@ check_triggers() // At least one trigger is unsatisfied. Let the user know which one. simulation::satisfy_triggers = false; - std::stringstream msg; - msg << "Triggers unsatisfied, max unc./thresh. is "; + std::string msg; if (keff_ratio >= tally_ratio) { - msg << keff_ratio << " for eigenvalue"; + msg = fmt::format("Triggers unsatisfied, max unc./thresh. is {} for " + "eigenvalue", keff_ratio); } else { - msg << tally_ratio << " for " << reaction_name(score) << " in tally " - << tally_id; + msg = fmt::format( + "Triggers unsatisfied, max unc./thresh. is {} for {} in tally {}", + tally_ratio, reaction_name(score), tally_id); } write_message(msg, 7); @@ -189,10 +191,10 @@ check_triggers() auto n_pred_batches = static_cast(n_active * max_ratio * max_ratio) + settings::n_inactive + 1; - std::stringstream msg; - msg << "The estimated number of batches is " << n_pred_batches; + std::string msg = fmt::format("The estimated number of batches is {}", + n_pred_batches); if (n_pred_batches > settings::n_max_batches) { - msg << " --- greater than max batches"; + msg.append(" --- greater than max batches"); warning(msg); } else { write_message(msg, 7); diff --git a/src/thermal.cpp b/src/thermal.cpp index ee06ed8aa7..d7bdb150cc 100644 --- a/src/thermal.cpp +++ b/src/thermal.cpp @@ -2,8 +2,8 @@ #include // for sort, move, min, max, find #include // for round, sqrt, abs -#include // for stringstream +#include #include "xtensor/xarray.hpp" #include "xtensor/xbuilder.hpp" #include "xtensor/xmath.hpp" @@ -88,10 +88,8 @@ ThermalScattering::ThermalScattering(hid_t group, const std::vector& tem temps_to_read.push_back(std::round(temp_actual)); } } else { - std::stringstream msg; - msg << "Nuclear data library does not contain cross sections for " - << name_ << " at or near " << std::round(T) << " K."; - fatal_error(msg); + fatal_error(fmt::format("Nuclear data library does not contain cross " + "sections for {} at or near {} K.", name_, std::round(T))); } } break; @@ -115,10 +113,8 @@ ThermalScattering::ThermalScattering(hid_t group, const std::vector& tem } } if (!found) { - std::stringstream msg; - msg << "Nuclear data library does not contain cross sections for " - << name_ << " at temperatures that bound " << std::round(T) << " K."; - fatal_error(msg); + fatal_error(fmt::format("Nuclear data library does not contain cross " + "sections for {} at temperatures that bound {} K.", name_, std::round(T))); } } } @@ -132,7 +128,7 @@ ThermalScattering::ThermalScattering(hid_t group, const std::vector& tem for (auto T : temps_to_read) { // Get temperature as a string - std::string temp_str = std::to_string(T) + "K"; + std::string temp_str = fmt::format("{}K", T); // Read exact temperature value double kT; diff --git a/src/track_output.cpp b/src/track_output.cpp index 5e071be01b..3b358621b5 100644 --- a/src/track_output.cpp +++ b/src/track_output.cpp @@ -6,10 +6,10 @@ #include "openmc/settings.h" #include "openmc/simulation.h" +#include #include "xtensor/xtensor.hpp" #include // for size_t -#include #include #include @@ -35,9 +35,9 @@ void write_particle_track(Particle& p) void finalize_particle_track(Particle& p) { - std::stringstream filename; - filename << settings::path_output << "track_" << simulation::current_batch - << '_' << simulation::current_gen << '_' << p.id_ << ".h5"; + std::string filename = fmt::format("{}track_{}_{}_{}.h5", + settings::path_output, simulation::current_batch, simulation::current_gen, + p.id_); // Determine number of coordinates for each particle std::vector n_coords; @@ -47,7 +47,7 @@ void finalize_particle_track(Particle& p) #pragma omp critical (FinalizeParticleTrack) { - hid_t file_id = file_open(filename.str().c_str(), 'w'); + hid_t file_id = file_open(filename, 'w'); write_attribute(file_id, "filetype", "track"); write_attribute(file_id, "version", VERSION_TRACK); write_attribute(file_id, "n_particles", p.tracks_.size()); @@ -61,7 +61,7 @@ void finalize_particle_track(Particle& p) data(j, 1) = t[j].y; data(j, 2) = t[j].z; } - std::string name = "coordinates_" + std::to_string(i); + std::string name = fmt::format("coordinates_{}", i); write_dataset(file_id, name.c_str(), data); } file_close(file_id); diff --git a/src/volume_calc.cpp b/src/volume_calc.cpp index 10ea6bca4e..f2f9348336 100644 --- a/src/volume_calc.cpp +++ b/src/volume_calc.cpp @@ -15,6 +15,7 @@ #include "openmc/timer.h" #include "openmc/xml_interface.h" +#include #ifdef _OPENMP #include #endif @@ -23,7 +24,6 @@ #include // for copy #include // for pow, sqrt -#include #include namespace openmc { @@ -66,9 +66,8 @@ VolumeCalculation::VolumeCalculation(pugi::xml_node node) threshold_ = std::stod(get_node_value(threshold_node, "threshold")); if (threshold_ <= 0.0) { - std::stringstream msg; - msg << "Invalid error threshold " << threshold_ << " provided for a volume calculation."; - fatal_error(msg); + fatal_error(fmt::format("Invalid error threshold {} provided for a " + "volume calculation.", threshold_)); } std::string tmp = get_node_value(threshold_node, "type"); @@ -79,9 +78,8 @@ VolumeCalculation::VolumeCalculation(pugi::xml_node node) } else if ( tmp == "rel_err") { trigger_type_ = TriggerMetric::relative_error; } else { - std::stringstream msg; - msg << "Invalid volume calculation trigger type '" << tmp << "' provided."; - fatal_error(msg); + fatal_error(fmt::format( + "Invalid volume calculation trigger type '{}' provided.", tmp)); } } @@ -394,8 +392,7 @@ void VolumeCalculation::to_hdf5(const std::string& filename, for (int i = 0; i < domain_ids_.size(); ++i) { - hid_t group_id = create_group(file_id, "domain_" - + std::to_string(domain_ids_[i])); + hid_t group_id = create_group(file_id, fmt::format("domain_{}", domain_ids_[i])); // Write volume for domain const auto& result {results[i]}; @@ -468,7 +465,7 @@ int openmc_calculate_volumes() { for (int i = 0; i < model::volume_calcs.size(); ++i) { if (mpi::master) { - write_message("Running volume calculation " + std::to_string(i+1) + "...", 4); + write_message(fmt::format("Running volume calculation {}...", i + 1), 4); } // Run volume calculation @@ -487,15 +484,13 @@ int openmc_calculate_volumes() { // Display domain volumes for (int j = 0; j < vol_calc.domain_ids_.size(); j++) { - std::stringstream msg; - msg << domain_type << vol_calc.domain_ids_[j] << ": " << - results[j].volume[0] << " +/- " << results[j].volume[1] << " cm^3"; - write_message(msg, 4); + write_message(fmt::format("{}{}: {} +/- {} cm^3", domain_type, + vol_calc.domain_ids_[j], results[j].volume[0], results[j].volume[1]), 4); } // Write volumes to HDF5 file - std::string filename = settings::path_output + "volume_" - + std::to_string(i+1) + ".h5"; + std::string filename = fmt::format("{}volume_{}.h5", + settings::path_output, i + 1); vol_calc.to_hdf5(filename, results); } @@ -504,8 +499,7 @@ int openmc_calculate_volumes() { // Show elapsed time time_volume.stop(); if (mpi::master) { - write_message("Elapsed time: " + std::to_string(time_volume.elapsed()) - + " s", 6); + write_message(fmt::format("Elapsed time: {} s", time_volume.elapsed()), 6); } return 0; diff --git a/src/wmp.cpp b/src/wmp.cpp index f514b9e838..d441de7db8 100644 --- a/src/wmp.cpp +++ b/src/wmp.cpp @@ -6,8 +6,9 @@ #include "openmc/math_functions.h" #include "openmc/nuclide.h" +#include + #include -#include namespace openmc { @@ -201,15 +202,14 @@ void check_wmp_version(hid_t file) std::array version; read_attribute(file, "version", version); if (version[0] != WMP_VERSION[0]) { - std::stringstream msg; - msg << "WMP data format uses version " << version[0] << "." << - version[1] << " whereas your installation of OpenMC expects version " - << WMP_VERSION[0] << ".x data."; - fatal_error(msg); + fatal_error(fmt::format( + "WMP data format uses version {}.{} whereas your installation of " + "OpenMC expects version {}.x data.", + version[0], version[1], WMP_VERSION[0])); } } else { - fatal_error("WMP data does not indicate a version. Your installation of " - "OpenMC expects version " + std::to_string(WMP_VERSION[0]) + ".x data."); + fatal_error(fmt::format("WMP data does not indicate a version. Your " + "installation of OpenMC expects version {}x data.", WMP_VERSION[0])); } } diff --git a/src/xml_interface.cpp b/src/xml_interface.cpp index 60ae7ffcab..cab7fd2df1 100644 --- a/src/xml_interface.cpp +++ b/src/xml_interface.cpp @@ -1,10 +1,9 @@ #include "openmc/xml_interface.h" -#include // for transform -#include +#include #include "openmc/error.h" - +#include "openmc/string_utils.h" namespace openmc { @@ -19,17 +18,13 @@ get_node_value(pugi::xml_node node, const char* name, bool lowercase, } else if (node.child(name)) { value_char = node.child_value(name); } else { - std::stringstream err_msg; - err_msg << "Node \"" << name << "\" is not a member of the \"" - << node.name() << "\" XML node"; - fatal_error(err_msg); + fatal_error(fmt::format( + "Node \"{}\" is not a member of the \"{}\" XML node", name, node.name())); } std::string value {value_char}; // Convert to lower-case if needed - if (lowercase) { - std::transform(value.begin(), value.end(), value.begin(), ::tolower); - } + if (lowercase) to_lower(value); // Strip leading/trailing whitespace if needed if (strip) { @@ -48,10 +43,8 @@ get_node_value_bool(pugi::xml_node node, const char* name) } else if (node.child(name)) { return node.child(name).text().as_bool(); } else { - std::stringstream err_msg; - err_msg << "Node \"" << name << "\" is not a member of the \"" - << node.name() << "\" XML node"; - fatal_error(err_msg); + fatal_error(fmt::format( + "Node \"{}\" is not a member of the \"{}\" XML node", name, node.name())); } return false; } From cc919d25c5954e2e977099c30a8ac9cbc270db5c Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 7 Feb 2020 14:55:11 -0600 Subject: [PATCH 20/43] Use fmt/core.h header to reduce compile time --- src/cell.cpp | 3 +-- src/dagmc.cpp | 2 +- src/geometry.cpp | 2 +- src/geometry_aux.cpp | 2 +- src/hdf5_interface.cpp | 2 +- src/initialize.cpp | 4 ++-- src/lattice.cpp | 2 +- src/mgxs.cpp | 2 +- src/output.cpp | 2 +- src/particle.cpp | 4 ++-- src/physics.cpp | 2 +- src/physics_mg.cpp | 4 ++-- src/plot.cpp | 2 +- src/reaction.cpp | 2 +- src/secondary_uncorrelated.cpp | 2 +- src/settings.cpp | 2 +- src/source.cpp | 2 +- src/state_point.cpp | 2 +- src/surface.cpp | 2 +- src/tallies/derivative.cpp | 2 +- src/tallies/filter_azimuthal.cpp | 2 +- src/tallies/filter_cell.cpp | 2 +- src/tallies/filter_cell_instance.cpp | 2 +- src/tallies/filter_distribcell.cpp | 2 +- src/tallies/filter_energy.cpp | 2 +- src/tallies/filter_energyfunc.cpp | 2 +- src/tallies/filter_material.cpp | 2 +- src/tallies/filter_mesh.cpp | 2 +- src/tallies/filter_mu.cpp | 2 +- src/tallies/filter_polar.cpp | 2 +- src/tallies/filter_sph_harm.cpp | 2 +- src/tallies/filter_sptl_legendre.cpp | 2 +- src/tallies/filter_surface.cpp | 2 +- src/tallies/filter_universe.cpp | 2 +- src/tallies/filter_zernike.cpp | 2 +- src/tallies/tally.cpp | 2 +- src/tallies/trigger.cpp | 2 +- src/thermal.cpp | 2 +- src/track_output.cpp | 2 +- src/volume_calc.cpp | 2 +- src/wmp.cpp | 2 +- src/xml_interface.cpp | 2 +- 42 files changed, 45 insertions(+), 46 deletions(-) diff --git a/src/cell.cpp b/src/cell.cpp index d09cde948a..cd6199b755 100644 --- a/src/cell.cpp +++ b/src/cell.cpp @@ -9,9 +9,8 @@ #include #include -#include +#include #include -#include #include "openmc/capi.h" #include "openmc/constants.h" diff --git a/src/dagmc.cpp b/src/dagmc.cpp index 3f16799a5c..59435f2450 100644 --- a/src/dagmc.cpp +++ b/src/dagmc.cpp @@ -15,7 +15,7 @@ #include "uwuw.hpp" #include "dagmcmetadata.hpp" #endif -#include +#include #include #include diff --git a/src/geometry.cpp b/src/geometry.cpp index d2012d9019..055f0ec7f3 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -2,7 +2,7 @@ #include -#include +#include #include #include "openmc/cell.h" diff --git a/src/geometry_aux.cpp b/src/geometry_aux.cpp index 0df1198b10..ae6d894aa8 100644 --- a/src/geometry_aux.cpp +++ b/src/geometry_aux.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include "openmc/cell.h" diff --git a/src/hdf5_interface.cpp b/src/hdf5_interface.cpp index f207f53b7d..1fcc97f3c3 100644 --- a/src/hdf5_interface.cpp +++ b/src/hdf5_interface.cpp @@ -7,7 +7,7 @@ #include "xtensor/xtensor.hpp" #include "xtensor/xarray.hpp" -#include +#include #include "hdf5.h" #include "hdf5_hl.h" diff --git a/src/initialize.cpp b/src/initialize.cpp index a5b516f688..10d86ee80f 100644 --- a/src/initialize.cpp +++ b/src/initialize.cpp @@ -9,7 +9,7 @@ #ifdef _OPENMP #include #endif -#include +#include #include "openmc/capi.h" #include "openmc/constants.h" @@ -134,7 +134,7 @@ parse_command_line(int argc, char* argv[]) } else if (arg == "-n" || arg == "--particles") { i += 1; settings::n_particles = std::stoll(argv[i]); - + } else if (arg == "-e" || arg == "--event") { settings::event_based = true; diff --git a/src/lattice.cpp b/src/lattice.cpp index a8dd23aa8e..8f88d8c591 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include "openmc/cell.h" #include "openmc/error.h" diff --git a/src/mgxs.cpp b/src/mgxs.cpp index 094361dcbb..163954caae 100644 --- a/src/mgxs.cpp +++ b/src/mgxs.cpp @@ -9,7 +9,7 @@ #include #endif -#include +#include #include "xtensor/xmath.hpp" #include "xtensor/xsort.hpp" #include "xtensor/xadapt.hpp" diff --git a/src/output.cpp b/src/output.cpp index ecfdb8a95d..d98cfd4a1d 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -11,7 +11,7 @@ #include #include // for pair -#include +#include #include #ifdef _OPENMP #include diff --git a/src/particle.cpp b/src/particle.cpp index 276fc197d1..24bec111c1 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -3,7 +3,7 @@ #include // copy, min #include // log, abs, copysign -#include +#include #include "openmc/bank.h" #include "openmc/capi.h" @@ -236,7 +236,7 @@ Particle::event_advance() score_track_derivative(this, distance); } } - + void Particle::event_cross_surface() { diff --git a/src/physics.cpp b/src/physics.cpp index a0f929125c..1065c200b1 100644 --- a/src/physics.cpp +++ b/src/physics.cpp @@ -21,7 +21,7 @@ #include "openmc/thermal.h" #include "openmc/tallies/tally.h" -#include +#include #include // for max, min, max_element #include // for sqrt, exp, log, abs, copysign diff --git a/src/physics_mg.cpp b/src/physics_mg.cpp index 526a21439b..f63a48d2ad 100644 --- a/src/physics_mg.cpp +++ b/src/physics_mg.cpp @@ -2,7 +2,7 @@ #include -#include +#include #include "xtensor/xarray.hpp" #include "openmc/bank.h" @@ -153,7 +153,7 @@ create_fission_sites(Particle* p) // We add 1 to the delayed_group bc in MG, -1 is prompt, but in the rest // of the code, 0 is prompt. site.delayed_group = dg + 1; - + // Store fission site in bank if (use_fission_bank) { int64_t idx = simulation::fission_bank.thread_safe_append(site); diff --git a/src/plot.cpp b/src/plot.cpp index 0ff7857127..bc94b3ad66 100644 --- a/src/plot.cpp +++ b/src/plot.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include "xtensor/xview.hpp" diff --git a/src/reaction.cpp b/src/reaction.cpp index ff22540e1f..ce00907527 100644 --- a/src/reaction.cpp +++ b/src/reaction.cpp @@ -3,7 +3,7 @@ #include #include // for move -#include +#include #include "openmc/constants.h" #include "openmc/hdf5_interface.h" diff --git a/src/secondary_uncorrelated.cpp b/src/secondary_uncorrelated.cpp index 320761916e..a1aa8ca0bb 100644 --- a/src/secondary_uncorrelated.cpp +++ b/src/secondary_uncorrelated.cpp @@ -2,7 +2,7 @@ #include // for string -#include +#include #include "openmc/error.h" #include "openmc/hdf5_interface.h" diff --git a/src/settings.cpp b/src/settings.cpp index 9bdfd77562..5bd53de259 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -4,7 +4,7 @@ #include // for numeric_limits #include -#include +#include #ifdef _OPENMP #include #endif diff --git a/src/source.cpp b/src/source.cpp index 6315208543..b15a15d23a 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -2,7 +2,7 @@ #include // for move -#include +#include #include "xtensor/xadapt.hpp" #include "openmc/bank.h" diff --git a/src/state_point.cpp b/src/state_point.cpp index 706eb17efe..503b1354e6 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include "xtensor/xbuilder.hpp" // for empty_like #include "xtensor/xview.hpp" diff --git a/src/surface.cpp b/src/surface.cpp index b1ba2eb050..a2c54260a9 100644 --- a/src/surface.cpp +++ b/src/surface.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include "openmc/error.h" #include "openmc/dagmc.h" diff --git a/src/tallies/derivative.cpp b/src/tallies/derivative.cpp index 483008340c..b749d69064 100644 --- a/src/tallies/derivative.cpp +++ b/src/tallies/derivative.cpp @@ -7,7 +7,7 @@ #include "openmc/tallies/tally.h" #include "openmc/xml_interface.h" -#include +#include template class std::vector; diff --git a/src/tallies/filter_azimuthal.cpp b/src/tallies/filter_azimuthal.cpp index 4d18e5974b..a7c29b2dbb 100644 --- a/src/tallies/filter_azimuthal.cpp +++ b/src/tallies/filter_azimuthal.cpp @@ -2,7 +2,7 @@ #include -#include +#include #include "openmc/constants.h" #include "openmc/error.h" diff --git a/src/tallies/filter_cell.cpp b/src/tallies/filter_cell.cpp index 86e78df91b..76a80f0d56 100644 --- a/src/tallies/filter_cell.cpp +++ b/src/tallies/filter_cell.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_cell.h" -#include +#include #include "openmc/capi.h" #include "openmc/cell.h" diff --git a/src/tallies/filter_cell_instance.cpp b/src/tallies/filter_cell_instance.cpp index cb6381410c..e3d7e02b22 100644 --- a/src/tallies/filter_cell_instance.cpp +++ b/src/tallies/filter_cell_instance.cpp @@ -2,7 +2,7 @@ #include -#include +#include #include "openmc/capi.h" #include "openmc/cell.h" diff --git a/src/tallies/filter_distribcell.cpp b/src/tallies/filter_distribcell.cpp index 7ea9b9b04f..43e68a8f93 100644 --- a/src/tallies/filter_distribcell.cpp +++ b/src/tallies/filter_distribcell.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_distribcell.h" -#include +#include #include "openmc/cell.h" #include "openmc/error.h" diff --git a/src/tallies/filter_energy.cpp b/src/tallies/filter_energy.cpp index 1ffea14029..1138dabe2c 100644 --- a/src/tallies/filter_energy.cpp +++ b/src/tallies/filter_energy.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_energy.h" -#include +#include #include "openmc/capi.h" #include "openmc/constants.h" // For F90_NONE diff --git a/src/tallies/filter_energyfunc.cpp b/src/tallies/filter_energyfunc.cpp index cecd8306ba..8c4e5609d7 100644 --- a/src/tallies/filter_energyfunc.cpp +++ b/src/tallies/filter_energyfunc.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_energyfunc.h" -#include +#include #include "openmc/error.h" #include "openmc/search.h" diff --git a/src/tallies/filter_material.cpp b/src/tallies/filter_material.cpp index 2760b028d1..8311fc73b1 100644 --- a/src/tallies/filter_material.cpp +++ b/src/tallies/filter_material.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_material.h" -#include +#include #include "openmc/capi.h" #include "openmc/material.h" diff --git a/src/tallies/filter_mesh.cpp b/src/tallies/filter_mesh.cpp index 609c3662bc..6c2cc8bd12 100644 --- a/src/tallies/filter_mesh.cpp +++ b/src/tallies/filter_mesh.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_mesh.h" -#include +#include #include "openmc/capi.h" #include "openmc/constants.h" diff --git a/src/tallies/filter_mu.cpp b/src/tallies/filter_mu.cpp index 2a75089d50..f874488b1e 100644 --- a/src/tallies/filter_mu.cpp +++ b/src/tallies/filter_mu.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_mu.h" -#include +#include #include "openmc/error.h" #include "openmc/search.h" diff --git a/src/tallies/filter_polar.cpp b/src/tallies/filter_polar.cpp index 367ca738a2..c814107508 100644 --- a/src/tallies/filter_polar.cpp +++ b/src/tallies/filter_polar.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_polar.h" -#include +#include #include "openmc/constants.h" #include "openmc/error.h" diff --git a/src/tallies/filter_sph_harm.cpp b/src/tallies/filter_sph_harm.cpp index b9852aafd7..fe014d0f46 100644 --- a/src/tallies/filter_sph_harm.cpp +++ b/src/tallies/filter_sph_harm.cpp @@ -2,7 +2,7 @@ #include // For pair -#include +#include #include #include "openmc/capi.h" diff --git a/src/tallies/filter_sptl_legendre.cpp b/src/tallies/filter_sptl_legendre.cpp index 1b38ec1547..6f060ed446 100644 --- a/src/tallies/filter_sptl_legendre.cpp +++ b/src/tallies/filter_sptl_legendre.cpp @@ -2,7 +2,7 @@ #include // For pair -#include +#include #include "openmc/capi.h" #include "openmc/error.h" diff --git a/src/tallies/filter_surface.cpp b/src/tallies/filter_surface.cpp index 203a6a094e..72061becbe 100644 --- a/src/tallies/filter_surface.cpp +++ b/src/tallies/filter_surface.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_surface.h" -#include +#include #include "openmc/error.h" #include "openmc/surface.h" diff --git a/src/tallies/filter_universe.cpp b/src/tallies/filter_universe.cpp index 75c5ebe599..ac39030419 100644 --- a/src/tallies/filter_universe.cpp +++ b/src/tallies/filter_universe.cpp @@ -1,6 +1,6 @@ #include "openmc/tallies/filter_universe.h" -#include +#include #include "openmc/cell.h" #include "openmc/error.h" diff --git a/src/tallies/filter_zernike.cpp b/src/tallies/filter_zernike.cpp index badd85103b..eab76cbc8d 100644 --- a/src/tallies/filter_zernike.cpp +++ b/src/tallies/filter_zernike.cpp @@ -4,7 +4,7 @@ #include #include // For pair -#include +#include #include #include "openmc/capi.h" diff --git a/src/tallies/tally.cpp b/src/tallies/tally.cpp index b52c09ee35..b63128dc04 100644 --- a/src/tallies/tally.cpp +++ b/src/tallies/tally.cpp @@ -28,7 +28,7 @@ #include "openmc/tallies/filter_surface.h" #include "openmc/xml_interface.h" -#include +#include #include "xtensor/xadapt.hpp" #include "xtensor/xbuilder.hpp" // for empty_like #include "xtensor/xview.hpp" diff --git a/src/tallies/trigger.cpp b/src/tallies/trigger.cpp index 405650b2b7..0665828fdf 100644 --- a/src/tallies/trigger.cpp +++ b/src/tallies/trigger.cpp @@ -3,7 +3,7 @@ #include #include // for std::pair -#include +#include #include "openmc/capi.h" #include "openmc/constants.h" diff --git a/src/thermal.cpp b/src/thermal.cpp index d7bdb150cc..67ca8905f7 100644 --- a/src/thermal.cpp +++ b/src/thermal.cpp @@ -3,7 +3,7 @@ #include // for sort, move, min, max, find #include // for round, sqrt, abs -#include +#include #include "xtensor/xarray.hpp" #include "xtensor/xbuilder.hpp" #include "xtensor/xmath.hpp" diff --git a/src/track_output.cpp b/src/track_output.cpp index 3b358621b5..314e43351b 100644 --- a/src/track_output.cpp +++ b/src/track_output.cpp @@ -6,7 +6,7 @@ #include "openmc/settings.h" #include "openmc/simulation.h" -#include +#include #include "xtensor/xtensor.hpp" #include // for size_t diff --git a/src/volume_calc.cpp b/src/volume_calc.cpp index f2f9348336..8cae7743d3 100644 --- a/src/volume_calc.cpp +++ b/src/volume_calc.cpp @@ -15,7 +15,7 @@ #include "openmc/timer.h" #include "openmc/xml_interface.h" -#include +#include #ifdef _OPENMP #include #endif diff --git a/src/wmp.cpp b/src/wmp.cpp index d441de7db8..96e1d5641d 100644 --- a/src/wmp.cpp +++ b/src/wmp.cpp @@ -6,7 +6,7 @@ #include "openmc/math_functions.h" #include "openmc/nuclide.h" -#include +#include #include diff --git a/src/xml_interface.cpp b/src/xml_interface.cpp index cab7fd2df1..a715dfae28 100644 --- a/src/xml_interface.cpp +++ b/src/xml_interface.cpp @@ -1,6 +1,6 @@ #include "openmc/xml_interface.h" -#include +#include #include "openmc/error.h" #include "openmc/string_utils.h" From 8854286e66e3cf12abd34ecf8c0341f6b6024391 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 10 Feb 2020 16:05:42 -0500 Subject: [PATCH 21/43] Raise helpful error for large banks in openmc.lib --- openmc/lib/core.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/openmc/lib/core.py b/openmc/lib/core.py index dcd896fa64..6a2a7cdeaa 100644 --- a/openmc/lib/core.py +++ b/openmc/lib/core.py @@ -336,9 +336,23 @@ def source_bank(): n = c_int64() _dll.openmc_source_bank(ptr, n) - # Convert to numpy array with appropriate datatype - bank_dtype = np.dtype(_Bank) - return as_array(ptr, (n.value,)).view(bank_dtype) + try: + # Convert to numpy array with appropriate datatype + bank_dtype = np.dtype(_Bank) + return as_array(ptr, (n.value,)).view(bank_dtype) + + except ValueError as err: + # If a known numpy error was raised (github.com/numpy/numpy/issues + # /14214), re-raise with a more helpful error message. + if len(err.args) == 0: + raise err + if err.args[0].startswith('invalid shape in fixed-type tuple'): + raise ValueError('The source bank is too large to access via ' + 'openmc.lib with this version of numpy. Use a different ' + 'version of numpy or reduce the bank size (fewer particles ' + 'per MPI process) so that it is smaller than 2 GB.') from err + else: + raise err def statepoint_write(filename=None, write_source=True): From 32cc4c8d434018d9d14fa90bd09b628bf668701f Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 10 Feb 2020 16:01:30 -0600 Subject: [PATCH 22/43] Support timestep units in Integrator.__init__ --- openmc/deplete/abc.py | 82 ++++++++++++++++++++------- openmc/deplete/integrators.py | 104 ++++++++++++++++++++++++++-------- 2 files changed, 142 insertions(+), 44 deletions(-) diff --git a/openmc/deplete/abc.py b/openmc/deplete/abc.py index 10976dd0ed..a9640852cc 100644 --- a/openmc/deplete/abc.py +++ b/openmc/deplete/abc.py @@ -31,6 +31,9 @@ __all__ = [ "Integrator", "SIIntegrator", "DepSystemSolver"] +_SECONDS_PER_DAY = 24*60*60 +_SECONDS_PER_YEAR = 365.25*24*60*60 + OperatorResult = namedtuple('OperatorResult', ['k', 'rates']) OperatorResult.__doc__ = """\ Result of applying transport operator @@ -597,9 +600,11 @@ class Integrator(ABC): ---------- operator : openmc.deplete.TransportOperator Operator to perform transport simulations - timesteps : iterable of float - Array of timesteps in units of [s]. Note that values are not - cumulative. + timesteps : iterable of float or iterable of tuple + Array of timesteps. Note that values are not cumulative. The units are + specified by the `timestep_units` argument when `timesteps` is an + iterable of float. Alternatively, units can be specified for each step + by passing an iterable of (value, unit) tuples. power : float or iterable of float, optional Power of the reactor in [W]. A single value indicates that the power is constant over all timesteps. An iterable @@ -612,6 +617,11 @@ class Integrator(ABC): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. + timestep_units : {'s', 'd', 'a', 'MWd/kg'} + Units for values specified in the `timesteps` argument. 's' means + seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that + the values are given in burnup (MW-d of energy deposited per kilogram + of heavy metal). Attributes ---------- @@ -625,7 +635,8 @@ class Integrator(ABC): Power of the reactor in [W] for each interval in :attr:`timesteps` """ - def __init__(self, operator, timesteps, power=None, power_density=None): + def __init__(self, operator, timesteps, power=None, power_density=None, + timestep_units='s'): # Check number of stages previously used if operator.prev_res is not None: res = operator.prev_res[-1] @@ -638,27 +649,51 @@ class Integrator(ABC): self._num_stages)) self.operator = operator self.chain = operator.chain - if not isinstance(timesteps, Iterable): - self.timesteps = [timesteps] - else: - self.timesteps = timesteps + + # Determine power and normalize units to W + mass = operator.heavy_metal if power is None: if power_density is None: raise ValueError("Either power or power density must be set") if not isinstance(power_density, Iterable): - power = power_density * operator.heavy_metal + power = power_density * mass else: - power = [p * operator.heavy_metal for p in power_density] - + power = [p*mass for p in power_density] if not isinstance(power, Iterable): # Ensure that power is single value if that is the case - power = [power] * len(self.timesteps) - elif len(power) != len(self.timesteps): + power = [power] * len(timesteps) + + if len(power) != len(timesteps): raise ValueError( "Number of time steps != number of powers. {} vs {}".format( - len(self.timesteps), len(power))) + len(timesteps), len(power))) - self.power = power + # Get list of times / units + if isinstance(timesteps[0], Iterable): + times, units = zip(*timesteps) + else: + times = timesteps + units = [timestep_units] * len(timesteps) + + # Determine number of seconds for each timestep + seconds = [] + for time, unit, watts in zip(times, units, power): + if unit == 's': + seconds.append(time) + elif unit in ('d', 'day'): + seconds.append(time*_SECONDS_PER_DAY) + elif unit in ('a', 'yr', 'year'): + seconds.append(time*_SECONDS_PER_YEAR) + elif unit.lower() == 'mwd/kg': + watt_days_per_kg = 1e6*time + kilograms = 1e-3*mass + days = watt_days_per_kg * kilograms / watts + seconds.append(days*_SECONDS_PER_DAY) + else: + raise ValueError("Invalid timestep unit: {}".format(unit)) + + self.timesteps = asarray(seconds) + self.power = asarray(power) @abstractmethod def __call__(self, conc, rates, dt, power, i): @@ -772,9 +807,11 @@ class SIIntegrator(Integrator): ---------- operator : openmc.deplete.TransportOperator The operator object to simulate on. - timesteps : iterable of float - Array of timesteps in units of [s]. Note that values are not - cumulative. + timesteps : iterable of float or iterable of tuple + Array of timesteps. Note that values are not cumulative. The units are + specified by the `timestep_units` argument when `timesteps` is an + iterable of float. Alternatively, units can be specified for each step + by passing an iterable of (value, unit) tuples. power : float or iterable of float, optional Power of the reactor in [W]. A single value indicates that the power is constant over all timesteps. An iterable @@ -787,6 +824,11 @@ class SIIntegrator(Integrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. + timestep_units : {'s', 'd', 'a', 'MWd/kg'} + Units for values specified in the `timesteps` argument. 's' means + seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that + the values are given in burnup (MW-d of energy deposited per kilogram + of heavy metal). n_steps : int, optional Number of stochastic iterations per depletion interval. Must be greater than zero. Default : 10 @@ -805,10 +847,10 @@ class SIIntegrator(Integrator): Number of stochastic iterations per depletion interval """ def __init__(self, operator, timesteps, power=None, power_density=None, - n_steps=10): + timestep_units='s', n_steps=10): check_type("n_steps", n_steps, Integral) check_greater_than("n_steps", n_steps, 0) - super().__init__(operator, timesteps, power, power_density) + super().__init__(operator, timesteps, power, power_density, timestep_units) self.n_steps = n_steps def _get_bos_data_from_operator(self, step_index, step_power, bos_conc): diff --git a/openmc/deplete/integrators.py b/openmc/deplete/integrators.py index 67106aa3e1..84f838cb7a 100644 --- a/openmc/deplete/integrators.py +++ b/openmc/deplete/integrators.py @@ -31,9 +31,11 @@ class PredictorIntegrator(Integrator): ---------- operator : openmc.deplete.TransportOperator Operator to perform transport simulations - timesteps : iterable of float - Array of timesteps in units of [s]. Note that values are not - cumulative. + timesteps : iterable of float or iterable of tuple + Array of timesteps. Note that values are not cumulative. The units are + specified by the `timestep_units` argument when `timesteps` is an + iterable of float. Alternatively, units can be specified for each step + by passing an iterable of (value, unit) tuples. power : float or iterable of float, optional Power of the reactor in [W]. A single value indicates that the power is constant over all timesteps. An iterable @@ -46,6 +48,11 @@ class PredictorIntegrator(Integrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. + timestep_units : {'s', 'd', 'a', 'MWd/kg'} + Units for values specified in the `timesteps` argument. 's' means + seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that + the values are given in burnup (MW-d of energy deposited per kilogram + of heavy metal). Attributes ---------- @@ -113,9 +120,11 @@ class CECMIntegrator(Integrator): ---------- operator : openmc.deplete.TransportOperator Operator to perform transport simulations - timesteps : iterable of float - Array of timesteps in units of [s]. Note that values are not - cumulative. + timesteps : iterable of float or iterable of tuple + Array of timesteps. Note that values are not cumulative. The units are + specified by the `timestep_units` argument when `timesteps` is an + iterable of float. Alternatively, units can be specified for each step + by passing an iterable of (value, unit) tuples. power : float or iterable of float, optional Power of the reactor in [W]. A single value indicates that the power is constant over all timesteps. An iterable @@ -128,6 +137,11 @@ class CECMIntegrator(Integrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. + timestep_units : {'s', 'd', 'a', 'MWd/kg'} + Units for values specified in the `timesteps` argument. 's' means + seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that + the values are given in burnup (MW-d of energy deposited per kilogram + of heavy metal). Attributes ---------- @@ -203,9 +217,11 @@ class CF4Integrator(Integrator): ---------- operator : openmc.deplete.TransportOperator Operator to perform transport simulations - timesteps : iterable of float - Array of timesteps in units of [s]. Note that values are not - cumulative. + timesteps : iterable of float or iterable of tuple + Array of timesteps. Note that values are not cumulative. The units are + specified by the `timestep_units` argument when `timesteps` is an + iterable of float. Alternatively, units can be specified for each step + by passing an iterable of (value, unit) tuples. power : float or iterable of float, optional Power of the reactor in [W]. A single value indicates that the power is constant over all timesteps. An iterable @@ -218,6 +234,11 @@ class CF4Integrator(Integrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. + timestep_units : {'s', 'd', 'a', 'MWd/kg'} + Units for values specified in the `timesteps` argument. 's' means + seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that + the values are given in burnup (MW-d of energy deposited per kilogram + of heavy metal). Attributes ---------- @@ -310,9 +331,11 @@ class CELIIntegrator(Integrator): ---------- operator : openmc.deplete.TransportOperator Operator to perform transport simulations - timesteps : iterable of float - Array of timesteps in units of [s]. Note that values are not - cumulative. + timesteps : iterable of float or iterable of tuple + Array of timesteps. Note that values are not cumulative. The units are + specified by the `timestep_units` argument when `timesteps` is an + iterable of float. Alternatively, units can be specified for each step + by passing an iterable of (value, unit) tuples. power : float or iterable of float, optional Power of the reactor in [W]. A single value indicates that the power is constant over all timesteps. An iterable @@ -325,6 +348,11 @@ class CELIIntegrator(Integrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. + timestep_units : {'s', 'd', 'a', 'MWd/kg'} + Units for values specified in the `timesteps` argument. 's' means + seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that + the values are given in burnup (MW-d of energy deposited per kilogram + of heavy metal). Attributes ---------- @@ -404,9 +432,11 @@ class EPCRK4Integrator(Integrator): ---------- operator : openmc.deplete.TransportOperator Operator to perform transport simulations - timesteps : iterable of float - Array of timesteps in units of [s]. Note that values are not - cumulative. + timesteps : iterable of float or iterable of tuple + Array of timesteps. Note that values are not cumulative. The units are + specified by the `timestep_units` argument when `timesteps` is an + iterable of float. Alternatively, units can be specified for each step + by passing an iterable of (value, unit) tuples. power : float or iterable of float, optional Power of the reactor in [W]. A single value indicates that the power is constant over all timesteps. An iterable @@ -419,6 +449,11 @@ class EPCRK4Integrator(Integrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. + timestep_units : {'s', 'd', 'a', 'MWd/kg'} + Units for values specified in the `timesteps` argument. 's' means + seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that + the values are given in burnup (MW-d of energy deposited per kilogram + of heavy metal). Attributes ---------- @@ -518,9 +553,11 @@ class LEQIIntegrator(Integrator): ---------- operator : openmc.deplete.TransportOperator Operator to perform transport simulations - timesteps : iterable of float - Array of timesteps in units of [s]. Note that values are not - cumulative. + timesteps : iterable of float or iterable of tuple + Array of timesteps. Note that values are not cumulative. The units are + specified by the `timestep_units` argument when `timesteps` is an + iterable of float. Alternatively, units can be specified for each step + by passing an iterable of (value, unit) tuples. power : float or iterable of float, optional Power of the reactor in [W]. A single value indicates that the power is constant over all timesteps. An iterable @@ -533,6 +570,11 @@ class LEQIIntegrator(Integrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. + timestep_units : {'s', 'd', 'a', 'MWd/kg'} + Units for values specified in the `timesteps` argument. 's' means + seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that + the values are given in burnup (MW-d of energy deposited per kilogram + of heavy metal). Attributes ---------- @@ -629,9 +671,11 @@ class SICELIIntegrator(SIIntegrator): ---------- operator : openmc.deplete.TransportOperator The operator object to simulate on. - timesteps : iterable of float - Array of timesteps in units of [s]. Note that values are not - cumulative. + timesteps : iterable of float or iterable of tuple + Array of timesteps. Note that values are not cumulative. The units are + specified by the `timestep_units` argument when `timesteps` is an + iterable of float. Alternatively, units can be specified for each step + by passing an iterable of (value, unit) tuples. power : float or iterable of float, optional Power of the reactor in [W]. A single value indicates that the power is constant over all timesteps. An iterable @@ -644,6 +688,11 @@ class SICELIIntegrator(SIIntegrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. + timestep_units : {'s', 'd', 'a', 'MWd/kg'} + Units for values specified in the `timesteps` argument. 's' means + seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that + the values are given in burnup (MW-d of energy deposited per kilogram + of heavy metal). n_steps : int, optional Number of stochastic iterations per depletion interval. Must be greater than zero. Default : 10 @@ -730,9 +779,11 @@ class SILEQIIntegrator(SIIntegrator): ---------- operator : openmc.deplete.TransportOperator The operator object to simulate on. - timesteps : iterable of float - Array of timesteps in units of [s]. Note that values are not - cumulative. + timesteps : iterable of float or iterable of tuple + Array of timesteps. Note that values are not cumulative. The units are + specified by the `timestep_units` argument when `timesteps` is an + iterable of float. Alternatively, units can be specified for each step + by passing an iterable of (value, unit) tuples. power : float or iterable of float, optional Power of the reactor in [W]. A single value indicates that the power is constant over all timesteps. An iterable @@ -745,6 +796,11 @@ class SILEQIIntegrator(SIIntegrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. + timestep_units : {'s', 'd', 'a', 'MWd/kg'} + Units for values specified in the `timesteps` argument. 's' means + seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that + the values are given in burnup (MW-d of energy deposited per kilogram + of heavy metal). n_steps : int, optional Number of stochastic iterations per depletion interval. Must be greater than zero. Default : 10 From 8771987bf40ad036107419acf9ea948fc3a1919a Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 11 Feb 2020 06:44:05 -0600 Subject: [PATCH 23/43] Add unit test checking depletion timestep units for all integrators --- tests/unit_tests/test_deplete_integrator.py | 69 ++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/tests/unit_tests/test_deplete_integrator.py b/tests/unit_tests/test_deplete_integrator.py index 47c9690ae9..9d5766fd5c 100644 --- a/tests/unit_tests/test_deplete_integrator.py +++ b/tests/unit_tests/test_deplete_integrator.py @@ -7,6 +7,7 @@ will be left unimplemented and testing will be done via regression. """ import copy +from random import uniform from unittest.mock import MagicMock import numpy as np @@ -15,11 +16,24 @@ import pytest from openmc.deplete import ( ReactionRates, Results, ResultsList, comm, OperatorResult, - PredictorIntegrator, SICELIIntegrator) + PredictorIntegrator, CECMIntegrator, CF4Integrator, CELIIntegrator, + EPCRK4Integrator, LEQIIntegrator, SICELIIntegrator, SILEQIIntegrator) from tests import dummy_operator +INTEGRATORS = [ + PredictorIntegrator, + CECMIntegrator, + CF4Integrator, + CELIIntegrator, + EPCRK4Integrator, + LEQIIntegrator, + SICELIIntegrator, + SILEQIIntegrator +] + + def test_results_save(run_in_tmpdir): """Test data save module""" @@ -159,3 +173,56 @@ def test_integrator(run_in_tmpdir, scheme): dep_time = res.get_depletion_time() assert dep_time.shape == (2, ) assert all(dep_time > 0) + + +@pytest.mark.parametrize("integrator", INTEGRATORS) +def test_timesteps(integrator): + # Crate fake operator + op = MagicMock() + op.prev_res = None + op.chain = None + + # Set heavy metal mass and power randomly + op.heavy_metal = uniform(0, 10000) + power = uniform(0, 1e6) + + # Reference timesteps in seconds + day = 86400.0 + ref_timesteps = [1*day, 2*day, 5*day, 10*day] + + # Case 1, timesteps in second + timesteps = ref_timesteps + x = integrator(op, timesteps, power, timestep_units='s') + assert np.allclose(x.timesteps, ref_timesteps) + + # Case 2, timesteps in days + timesteps = [t / day for t in ref_timesteps] + x = integrator(op, timesteps, power, timestep_units='d') + assert np.allclose(x.timesteps, ref_timesteps) + + # Case 3, timesteps in years + year = 365.25*day + timesteps = [t / year for t in ref_timesteps] + x = integrator(op, timesteps, power, timestep_units='a') + assert np.allclose(x.timesteps, ref_timesteps) + + # Case 4, timesteps in MWd/kg + kilograms = op.heavy_metal / 1000.0 + days = [t/day for t in ref_timesteps] + megawatts = power / 1000000.0 + burnup = [t * megawatts / kilograms for t in days] + x = integrator(op, burnup, power, timestep_units='MWd/kg') + assert np.allclose(x.timesteps, ref_timesteps) + + # Case 5, mixed units + burnup_per_day = (1e-6*power) / kilograms + timesteps = [(burnup_per_day, 'MWd/kg'), (2*day, 's'), (5, 'd'), + (10*burnup_per_day, 'MWd/kg')] + x = integrator(op, timesteps, power) + assert np.allclose(x.timesteps, ref_timesteps) + + # Bad units should raise an exception + with pytest.raises(ValueError, match="unit"): + integrator(op, ref_timesteps, power, timestep_units='🐨') + with pytest.raises(ValueError, match="unit"): + integrator(op, [(800.0, 'gorillas')], power) From 85264aa38c60d6846de5ca7005373c7cb3b9a47c Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 11 Feb 2020 07:08:53 -0600 Subject: [PATCH 24/43] Support minutes and hours for depletion timesteps rather than years --- openmc/deplete/abc.py | 29 +++++----- openmc/deplete/integrators.py | 64 ++++++++++----------- tests/unit_tests/test_deplete_integrator.py | 26 +++++---- 3 files changed, 64 insertions(+), 55 deletions(-) diff --git a/openmc/deplete/abc.py b/openmc/deplete/abc.py index a9640852cc..d75833a6f1 100644 --- a/openmc/deplete/abc.py +++ b/openmc/deplete/abc.py @@ -31,8 +31,9 @@ __all__ = [ "Integrator", "SIIntegrator", "DepSystemSolver"] +_SECONDS_PER_MINUTE = 60 +_SECONDS_PER_HOUR = 60*60 _SECONDS_PER_DAY = 24*60*60 -_SECONDS_PER_YEAR = 365.25*24*60*60 OperatorResult = namedtuple('OperatorResult', ['k', 'rates']) OperatorResult.__doc__ = """\ @@ -617,11 +618,11 @@ class Integrator(ABC): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. - timestep_units : {'s', 'd', 'a', 'MWd/kg'} + timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'} Units for values specified in the `timesteps` argument. 's' means - seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that - the values are given in burnup (MW-d of energy deposited per kilogram - of heavy metal). + seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates + that the values are given in burnup (MW-d of energy deposited per + kilogram of heavy metal). Attributes ---------- @@ -678,19 +679,21 @@ class Integrator(ABC): # Determine number of seconds for each timestep seconds = [] for time, unit, watts in zip(times, units, power): - if unit == 's': + if unit in ('s', 'sec'): seconds.append(time) + elif unit in ('min', 'minute'): + seconds.append(time*_SECONDS_PER_MINUTE) + elif unit in ('h', 'hr', 'hour'): + seconds.append(time*_SECONDS_PER_HOUR) elif unit in ('d', 'day'): seconds.append(time*_SECONDS_PER_DAY) - elif unit in ('a', 'yr', 'year'): - seconds.append(time*_SECONDS_PER_YEAR) elif unit.lower() == 'mwd/kg': watt_days_per_kg = 1e6*time kilograms = 1e-3*mass days = watt_days_per_kg * kilograms / watts seconds.append(days*_SECONDS_PER_DAY) else: - raise ValueError("Invalid timestep unit: {}".format(unit)) + raise ValueError("Invalid timestep unit '{}'".format(unit)) self.timesteps = asarray(seconds) self.power = asarray(power) @@ -824,11 +827,11 @@ class SIIntegrator(Integrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. - timestep_units : {'s', 'd', 'a', 'MWd/kg'} + timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'} Units for values specified in the `timesteps` argument. 's' means - seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that - the values are given in burnup (MW-d of energy deposited per kilogram - of heavy metal). + seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates + that the values are given in burnup (MW-d of energy deposited per + kilogram of heavy metal). n_steps : int, optional Number of stochastic iterations per depletion interval. Must be greater than zero. Default : 10 diff --git a/openmc/deplete/integrators.py b/openmc/deplete/integrators.py index 84f838cb7a..da8509d591 100644 --- a/openmc/deplete/integrators.py +++ b/openmc/deplete/integrators.py @@ -48,11 +48,11 @@ class PredictorIntegrator(Integrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. - timestep_units : {'s', 'd', 'a', 'MWd/kg'} + timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'} Units for values specified in the `timesteps` argument. 's' means - seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that - the values are given in burnup (MW-d of energy deposited per kilogram - of heavy metal). + seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates + that the values are given in burnup (MW-d of energy deposited per + kilogram of heavy metal). Attributes ---------- @@ -137,11 +137,11 @@ class CECMIntegrator(Integrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. - timestep_units : {'s', 'd', 'a', 'MWd/kg'} + timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'} Units for values specified in the `timesteps` argument. 's' means - seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that - the values are given in burnup (MW-d of energy deposited per kilogram - of heavy metal). + seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates + that the values are given in burnup (MW-d of energy deposited per + kilogram of heavy metal). Attributes ---------- @@ -234,11 +234,11 @@ class CF4Integrator(Integrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. - timestep_units : {'s', 'd', 'a', 'MWd/kg'} + timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'} Units for values specified in the `timesteps` argument. 's' means - seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that - the values are given in burnup (MW-d of energy deposited per kilogram - of heavy metal). + seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates + that the values are given in burnup (MW-d of energy deposited per + kilogram of heavy metal). Attributes ---------- @@ -348,11 +348,11 @@ class CELIIntegrator(Integrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. - timestep_units : {'s', 'd', 'a', 'MWd/kg'} + timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'} Units for values specified in the `timesteps` argument. 's' means - seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that - the values are given in burnup (MW-d of energy deposited per kilogram - of heavy metal). + seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates + that the values are given in burnup (MW-d of energy deposited per + kilogram of heavy metal). Attributes ---------- @@ -449,11 +449,11 @@ class EPCRK4Integrator(Integrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. - timestep_units : {'s', 'd', 'a', 'MWd/kg'} + timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'} Units for values specified in the `timesteps` argument. 's' means - seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that - the values are given in burnup (MW-d of energy deposited per kilogram - of heavy metal). + seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates + that the values are given in burnup (MW-d of energy deposited per + kilogram of heavy metal). Attributes ---------- @@ -570,11 +570,11 @@ class LEQIIntegrator(Integrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. - timestep_units : {'s', 'd', 'a', 'MWd/kg'} + timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'} Units for values specified in the `timesteps` argument. 's' means - seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that - the values are given in burnup (MW-d of energy deposited per kilogram - of heavy metal). + seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates + that the values are given in burnup (MW-d of energy deposited per + kilogram of heavy metal). Attributes ---------- @@ -688,11 +688,11 @@ class SICELIIntegrator(SIIntegrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. - timestep_units : {'s', 'd', 'a', 'MWd/kg'} + timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'} Units for values specified in the `timesteps` argument. 's' means - seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that - the values are given in burnup (MW-d of energy deposited per kilogram - of heavy metal). + seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates + that the values are given in burnup (MW-d of energy deposited per + kilogram of heavy metal). n_steps : int, optional Number of stochastic iterations per depletion interval. Must be greater than zero. Default : 10 @@ -796,11 +796,11 @@ class SILEQIIntegrator(SIIntegrator): Power density of the reactor in [W/gHM]. It is multiplied by initial heavy metal inventory to get total power if ``power`` is not speficied. - timestep_units : {'s', 'd', 'a', 'MWd/kg'} + timestep_units : {'s', 'min', 'h', 'd', 'MWd/kg'} Units for values specified in the `timesteps` argument. 's' means - seconds, 'd' means days, 'a' means years, and 'MWd/kg' indicates that - the values are given in burnup (MW-d of energy deposited per kilogram - of heavy metal). + seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates + that the values are given in burnup (MW-d of energy deposited per + kilogram of heavy metal). n_steps : int, optional Number of stochastic iterations per depletion interval. Must be greater than zero. Default : 10 diff --git a/tests/unit_tests/test_deplete_integrator.py b/tests/unit_tests/test_deplete_integrator.py index 9d5766fd5c..110894cdad 100644 --- a/tests/unit_tests/test_deplete_integrator.py +++ b/tests/unit_tests/test_deplete_integrator.py @@ -190,23 +190,29 @@ def test_timesteps(integrator): day = 86400.0 ref_timesteps = [1*day, 2*day, 5*day, 10*day] - # Case 1, timesteps in second + # Case 1, timesteps in seconds timesteps = ref_timesteps x = integrator(op, timesteps, power, timestep_units='s') assert np.allclose(x.timesteps, ref_timesteps) - # Case 2, timesteps in days + # Case 2, timesteps in minutes + minute = 60 + timesteps = [t / minute for t in ref_timesteps] + x = integrator(op, timesteps, power, timestep_units='min') + assert np.allclose(x.timesteps, ref_timesteps) + + # Case 3, timesteps in hours + hour = 60*60 + timesteps = [t / hour for t in ref_timesteps] + x = integrator(op, timesteps, power, timestep_units='h') + assert np.allclose(x.timesteps, ref_timesteps) + + # Case 4, timesteps in days timesteps = [t / day for t in ref_timesteps] x = integrator(op, timesteps, power, timestep_units='d') assert np.allclose(x.timesteps, ref_timesteps) - # Case 3, timesteps in years - year = 365.25*day - timesteps = [t / year for t in ref_timesteps] - x = integrator(op, timesteps, power, timestep_units='a') - assert np.allclose(x.timesteps, ref_timesteps) - - # Case 4, timesteps in MWd/kg + # Case 5, timesteps in MWd/kg kilograms = op.heavy_metal / 1000.0 days = [t/day for t in ref_timesteps] megawatts = power / 1000000.0 @@ -214,7 +220,7 @@ def test_timesteps(integrator): x = integrator(op, burnup, power, timestep_units='MWd/kg') assert np.allclose(x.timesteps, ref_timesteps) - # Case 5, mixed units + # Case 6, mixed units burnup_per_day = (1e-6*power) / kilograms timesteps = [(burnup_per_day, 'MWd/kg'), (2*day, 's'), (5, 'd'), (10*burnup_per_day, 'MWd/kg')] From 516ac9e1d372ff2030939dc87fd0699d81bb3c9c Mon Sep 17 00:00:00 2001 From: stevendargaville Date: Tue, 11 Feb 2020 13:37:00 +0000 Subject: [PATCH 25/43] Modified the MAX_LOST_PARTICLES const in particle.h to be a variable stored in settings that can be modified by the c/python/xml layers. --- include/openmc/particle.h | 3 --- include/openmc/settings.h | 9 +++++---- openmc/lib/settings.py | 1 + openmc/settings.py | 26 ++++++++++++++++++++++++++ openmc/statepoint.py | 6 ++++++ src/particle.cpp | 6 +++++- src/settings.cpp | 12 ++++++++++-- 7 files changed, 53 insertions(+), 10 deletions(-) diff --git a/include/openmc/particle.h b/include/openmc/particle.h index 8143ee5a30..ee59d73014 100644 --- a/include/openmc/particle.h +++ b/include/openmc/particle.h @@ -34,9 +34,6 @@ namespace openmc { // use to store the bins for delayed group tallies. constexpr int MAX_DELAYED_GROUPS {8}; -// Maximum number of lost particles -constexpr int MAX_LOST_PARTICLES {10}; - // Maximum number of lost particles, relative to the total number of particles constexpr double REL_MAX_LOST_PARTICLES {1.0e-6}; diff --git a/include/openmc/settings.h b/include/openmc/settings.h index cbc0c488b9..1dcdea3cc7 100644 --- a/include/openmc/settings.h +++ b/include/openmc/settings.h @@ -63,10 +63,11 @@ extern std::string path_source; extern std::string path_sourcepoint; //!< path to a source file extern "C" std::string path_statepoint; //!< path to a statepoint file -extern "C" int32_t n_batches; //!< number of (inactive+active) batches -extern "C" int32_t n_inactive; //!< number of inactive batches -extern "C" int32_t gen_per_batch; //!< number of generations per batch -extern "C" int64_t n_particles; //!< number of particles per generation +extern "C" int32_t n_batches; //!< number of (inactive+active) batches +extern "C" int32_t n_inactive; //!< number of inactive batches +extern "C" int32_t n_max_lost_particles; //!< maximum number of lost particles +extern "C" int32_t gen_per_batch; //!< number of generations per batch +extern "C" int64_t n_particles; //!< number of particles per generation extern int64_t max_particles_in_flight; //!< Max num. event-based particles in flight diff --git a/openmc/lib/settings.py b/openmc/lib/settings.py index 275c73a934..a25ccb962f 100644 --- a/openmc/lib/settings.py +++ b/openmc/lib/settings.py @@ -22,6 +22,7 @@ class _Settings(object): entropy_on = _DLLGlobal(c_bool, 'entropy_on') generations_per_batch = _DLLGlobal(c_int32, 'gen_per_batch') inactive = _DLLGlobal(c_int32, 'n_inactive') + max_lost_particles = _DLLGlobal(c_int32, 'n_max_lost_particles') particles = _DLLGlobal(c_int64, 'n_particles') restart_run = _DLLGlobal(c_bool, 'restart_run') run_CE = _DLLGlobal(c_bool, 'run_CE') diff --git a/openmc/settings.py b/openmc/settings.py index eb2f926f3a..79e7719a3d 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -58,6 +58,8 @@ class Settings(object): history-based parallelism. generations_per_batch : int Number of generations per batch + max_lost_particles : int + Maximum number of lost particles inactive : int Number of inactive batches keff_trigger : dict @@ -176,6 +178,7 @@ class Settings(object): self._batches = None self._generations_per_batch = None self._inactive = None + self._max_lost_particles = None self._particles = None self._keff_trigger = None @@ -254,6 +257,10 @@ class Settings(object): def inactive(self): return self._inactive + @property + def max_lost_particles(self): + return self._max_lost_particles + @property def particles(self): return self._particles @@ -417,6 +424,12 @@ class Settings(object): cv.check_greater_than('inactive batches', inactive, 0, True) self._inactive = inactive + @max_lost_particles.setter + def max_lost_particles(self, max_lost_particles): + cv.check_type('max_lost_particles', max_lost_particles, Integral) + cv.check_greater_than('max_lost_particles', max_lost_particles, 0) + self._max_lost_particles = max_lost_particles + @particles.setter def particles(self, particles): cv.check_type('particles', particles, Integral) @@ -763,6 +776,11 @@ class Settings(object): element = ET.SubElement(root, "inactive") element.text = str(self._inactive) + def _create_max_lost_particles_subelement(self, root): + if self._max_lost_particles is not None: + element = ET.SubElement(root, "max_lost_particles") + element.text = str(self._max_lost_particles) + def _create_particles_subelement(self, root): if self._particles is not None: element = ET.SubElement(root, "particles") @@ -1009,6 +1027,7 @@ class Settings(object): self._particles_from_xml_element(elem) self._batches_from_xml_element(elem) self._inactive_from_xml_element(elem) + self._max_lost_particles_from_xml_element(elem) self._generations_per_batch_from_xml_element(elem) def _run_mode_from_xml_element(self, root): @@ -1031,6 +1050,11 @@ class Settings(object): if text is not None: self.inactive = int(text) + def _max_lost_particles_from_xml_element(self, root): + text = get_text(root, 'max_lost_particles') + if text is not None: + self.max_lost_particles = int(text) + def _generations_per_batch_from_xml_element(self, root): text = get_text(root, 'generations_per_batch') if text is not None: @@ -1270,6 +1294,7 @@ class Settings(object): self._create_particles_subelement(root_element) self._create_batches_subelement(root_element) self._create_inactive_subelement(root_element) + self._create_max_lost_particles_subelement(root_element) self._create_generations_per_batch_subelement(root_element) self._create_keff_trigger_subelement(root_element) self._create_source_subelement(root_element) @@ -1340,6 +1365,7 @@ class Settings(object): settings._particles_from_xml_element(root) settings._batches_from_xml_element(root) settings._inactive_from_xml_element(root) + settings._max_lost_particles_from_xml_element(root) settings._generations_per_batch_from_xml_element(root) settings._keff_trigger_from_xml_element(root) settings._source_from_xml_element(root) diff --git a/openmc/statepoint.py b/openmc/statepoint.py index 5802a74cae..051195ec96 100644 --- a/openmc/statepoint.py +++ b/openmc/statepoint.py @@ -77,6 +77,8 @@ class StatePoint(object): Number of batches n_inactive : int Number of inactive batches + n_max_lost_particles : int + Number of max lost particles n_particles : int Number of particles per generation n_realizations : int @@ -312,6 +314,10 @@ class StatePoint(object): else: return None + @property + def n_max_lost_particles(self): + return self._f['n_max_lost_particles'][()] + @property def n_particles(self): return self._f['n_particles'][()] diff --git a/src/particle.cpp b/src/particle.cpp index bd9a611392..8e66222048 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -164,6 +164,8 @@ Particle::event_calculate_xs() if (cell_born_ == C_NONE) cell_born_ = coord_[n_coord_ - 1].cell; } + std::cout << "settings::n_max_lost_particles " << settings::n_max_lost_particles << std::endl; + // Write particle track. if (write_track_) write_particle_track(*this); @@ -628,9 +630,11 @@ Particle::mark_as_lost(const char* message) auto n = simulation::current_batch * settings::gen_per_batch * simulation::work_per_rank; + std::cout << simulation::n_lost_particles << "HELLLOOOOOOOOOOOO MS DOUBTFIRE" << std::endl; + // Abort the simulation if the maximum number of lost particles has been // reached - if (simulation::n_lost_particles >= MAX_LOST_PARTICLES && + if (simulation::n_lost_particles >= settings::n_max_lost_particles && simulation::n_lost_particles >= REL_MAX_LOST_PARTICLES*n) { fatal_error("Maximum number of lost particles has been reached."); } diff --git a/src/settings.cpp b/src/settings.cpp index 32a7958d8d..41a55501c2 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -79,6 +79,7 @@ std::string path_statepoint; int32_t n_batches; int32_t n_inactive {0}; +int32_t n_max_lost_particles {10}; int32_t gen_per_batch {1}; int64_t n_particles {-1}; @@ -143,6 +144,11 @@ void get_run_parameters(pugi::xml_node node_base) } if (!trigger_on) n_max_batches = n_batches; + // Get max number of lost particles + if (check_for_node(node_base, "max_lost_particles")) { + n_max_lost_particles = std::stoi(get_node_value(node_base, "max_lost_particles")); + } + // Get number of inactive batches if (run_mode == RunMode::EIGENVALUE) { if (check_for_node(node_base, "inactive")) { @@ -343,14 +349,16 @@ void read_settings_xml() // Read run parameters get_run_parameters(node_mode); - // Check number of active batches, inactive batches, and particles + // Check number of active batches, inactive batches, max lost particles and particles if (n_batches <= n_inactive) { fatal_error("Number of active batches must be greater than zero."); } else if (n_inactive < 0) { fatal_error("Number of inactive batches must be non-negative."); } else if (n_particles <= 0) { fatal_error("Number of particles must be greater than zero."); - } + } else if (n_max_lost_particles <= 0) { + fatal_error("Number of max lost particles must be greater than zero."); + } } // Copy random number seed if specified From 9f64dd1a880a150682ae6140da1a9546b1982a35 Mon Sep 17 00:00:00 2001 From: stevendargaville Date: Tue, 11 Feb 2020 13:37:26 +0000 Subject: [PATCH 26/43] Modified the REL_MAX_LOST_PARTICLES const in particle.h to be a variable stored in settings that can be modified by the c/python/xml layers. --- include/openmc/particle.h | 3 --- include/openmc/settings.h | 11 ++++++----- openmc/lib/settings.py | 1 + openmc/settings.py | 31 +++++++++++++++++++++++++++++-- openmc/statepoint.py | 8 +++++++- src/particle.cpp | 6 +----- src/settings.cpp | 10 +++++++++- 7 files changed, 53 insertions(+), 17 deletions(-) diff --git a/include/openmc/particle.h b/include/openmc/particle.h index ee59d73014..2917b45e4a 100644 --- a/include/openmc/particle.h +++ b/include/openmc/particle.h @@ -34,9 +34,6 @@ namespace openmc { // use to store the bins for delayed group tallies. constexpr int MAX_DELAYED_GROUPS {8}; -// Maximum number of lost particles, relative to the total number of particles -constexpr double REL_MAX_LOST_PARTICLES {1.0e-6}; - constexpr double CACHE_INVALID {-1.0}; //============================================================================== diff --git a/include/openmc/settings.h b/include/openmc/settings.h index 1dcdea3cc7..3407eadf4b 100644 --- a/include/openmc/settings.h +++ b/include/openmc/settings.h @@ -63,11 +63,12 @@ extern std::string path_source; extern std::string path_sourcepoint; //!< path to a source file extern "C" std::string path_statepoint; //!< path to a statepoint file -extern "C" int32_t n_batches; //!< number of (inactive+active) batches -extern "C" int32_t n_inactive; //!< number of inactive batches -extern "C" int32_t n_max_lost_particles; //!< maximum number of lost particles -extern "C" int32_t gen_per_batch; //!< number of generations per batch -extern "C" int64_t n_particles; //!< number of particles per generation +extern "C" int32_t n_batches; //!< number of (inactive+active) batches +extern "C" int32_t n_inactive; //!< number of inactive batches +extern "C" int32_t n_max_lost_particles; //!< maximum number of lost particles +extern double relative_max_lost_particles; //!< maximum number of lost particles, relative to the total number of particles +extern "C" int32_t gen_per_batch; //!< number of generations per batch +extern "C" int64_t n_particles; //!< number of particles per generation extern int64_t max_particles_in_flight; //!< Max num. event-based particles in flight diff --git a/openmc/lib/settings.py b/openmc/lib/settings.py index a25ccb962f..8345e00881 100644 --- a/openmc/lib/settings.py +++ b/openmc/lib/settings.py @@ -23,6 +23,7 @@ class _Settings(object): generations_per_batch = _DLLGlobal(c_int32, 'gen_per_batch') inactive = _DLLGlobal(c_int32, 'n_inactive') max_lost_particles = _DLLGlobal(c_int32, 'n_max_lost_particles') + rel_max_lost_particles = _DLLGlobal(c_double, 'relative_max_lost_particles') particles = _DLLGlobal(c_int64, 'n_particles') restart_run = _DLLGlobal(c_bool, 'restart_run') run_CE = _DLLGlobal(c_bool, 'run_CE') diff --git a/openmc/settings.py b/openmc/settings.py index 79e7719a3d..794c97b618 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -60,6 +60,8 @@ class Settings(object): Number of generations per batch max_lost_particles : int Maximum number of lost particles + rel_max_lost_particles : int + Maximum number of lost particles, relative to the total number of particles inactive : int Number of inactive batches keff_trigger : dict @@ -179,6 +181,7 @@ class Settings(object): self._generations_per_batch = None self._inactive = None self._max_lost_particles = None + self._rel_max_lost_particles = None self._particles = None self._keff_trigger = None @@ -261,6 +264,10 @@ class Settings(object): def max_lost_particles(self): return self._max_lost_particles + @property + def rel_max_lost_particles(self): + return self._rel_max_lost_particles + @property def particles(self): return self._particles @@ -430,6 +437,13 @@ class Settings(object): cv.check_greater_than('max_lost_particles', max_lost_particles, 0) self._max_lost_particles = max_lost_particles + @rel_max_lost_particles.setter + def rel_max_lost_particles(self, rel_max_lost_particles): + cv.check_type('rel_max_lost_particles', rel_max_lost_particles, Real) + cv.check_greater_than('rel_max_lost_particles', rel_max_lost_particles, 0) + cv.check_less_than('rel_max_lost_particles', rel_max_lost_particles, 1) + self._rel_max_lost_particles = rel_max_lost_particles + @particles.setter def particles(self, particles): cv.check_type('particles', particles, Integral) @@ -779,7 +793,12 @@ class Settings(object): def _create_max_lost_particles_subelement(self, root): if self._max_lost_particles is not None: element = ET.SubElement(root, "max_lost_particles") - element.text = str(self._max_lost_particles) + element.text = str(self._max_lost_particles) + + def _create_rel_max_lost_particles_subelement(self, root): + if self._rel_max_lost_particles is not None: + element = ET.SubElement(root, "rel_max_lost_particles") + element.text = str(self._rel_max_lost_particles) def _create_particles_subelement(self, root): if self._particles is not None: @@ -1028,6 +1047,7 @@ class Settings(object): self._batches_from_xml_element(elem) self._inactive_from_xml_element(elem) self._max_lost_particles_from_xml_element(elem) + self._rel_max_lost_particles_from_xml_element(elem) self._generations_per_batch_from_xml_element(elem) def _run_mode_from_xml_element(self, root): @@ -1053,7 +1073,12 @@ class Settings(object): def _max_lost_particles_from_xml_element(self, root): text = get_text(root, 'max_lost_particles') if text is not None: - self.max_lost_particles = int(text) + self.max_lost_particles = int(text) + + def _rel_max_lost_particles_from_xml_element(self, root): + text = get_text(root, 'rel_max_lost_particles') + if text is not None: + self.rel_max_lost_particles = float(text) def _generations_per_batch_from_xml_element(self, root): text = get_text(root, 'generations_per_batch') @@ -1295,6 +1320,7 @@ class Settings(object): self._create_batches_subelement(root_element) self._create_inactive_subelement(root_element) self._create_max_lost_particles_subelement(root_element) + self._create_rel_max_lost_particles_subelement(root_element) self._create_generations_per_batch_subelement(root_element) self._create_keff_trigger_subelement(root_element) self._create_source_subelement(root_element) @@ -1366,6 +1392,7 @@ class Settings(object): settings._batches_from_xml_element(root) settings._inactive_from_xml_element(root) settings._max_lost_particles_from_xml_element(root) + settings._rel_max_lost_particles_from_xml_element(root) settings._generations_per_batch_from_xml_element(root) settings._keff_trigger_from_xml_element(root) settings._source_from_xml_element(root) diff --git a/openmc/statepoint.py b/openmc/statepoint.py index 051195ec96..0d78bf68dc 100644 --- a/openmc/statepoint.py +++ b/openmc/statepoint.py @@ -79,6 +79,8 @@ class StatePoint(object): Number of inactive batches n_max_lost_particles : int Number of max lost particles + relative_max_lost_particles : float + Number of max lost particles, relative to the total number of particles n_particles : int Number of particles per generation n_realizations : int @@ -316,7 +318,11 @@ class StatePoint(object): @property def n_max_lost_particles(self): - return self._f['n_max_lost_particles'][()] + return self._f['n_max_lost_particles'][()] + + @property + def relative_max_lost_particles(self): + return self._f['relative_max_lost_particles'][()] @property def n_particles(self): diff --git a/src/particle.cpp b/src/particle.cpp index 8e66222048..79e6625771 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -164,8 +164,6 @@ Particle::event_calculate_xs() if (cell_born_ == C_NONE) cell_born_ = coord_[n_coord_ - 1].cell; } - std::cout << "settings::n_max_lost_particles " << settings::n_max_lost_particles << std::endl; - // Write particle track. if (write_track_) write_particle_track(*this); @@ -630,12 +628,10 @@ Particle::mark_as_lost(const char* message) auto n = simulation::current_batch * settings::gen_per_batch * simulation::work_per_rank; - std::cout << simulation::n_lost_particles << "HELLLOOOOOOOOOOOO MS DOUBTFIRE" << std::endl; - // Abort the simulation if the maximum number of lost particles has been // reached if (simulation::n_lost_particles >= settings::n_max_lost_particles && - simulation::n_lost_particles >= REL_MAX_LOST_PARTICLES*n) { + simulation::n_lost_particles >= settings::relative_max_lost_particles*n) { fatal_error("Maximum number of lost particles has been reached."); } } diff --git a/src/settings.cpp b/src/settings.cpp index 41a55501c2..d72e5f17f7 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -80,6 +80,7 @@ std::string path_statepoint; int32_t n_batches; int32_t n_inactive {0}; int32_t n_max_lost_particles {10}; +double relative_max_lost_particles {1.0e-6}; int32_t gen_per_batch {1}; int64_t n_particles {-1}; @@ -149,6 +150,11 @@ void get_run_parameters(pugi::xml_node node_base) n_max_lost_particles = std::stoi(get_node_value(node_base, "max_lost_particles")); } + // Get relative number of lost particles + if (check_for_node(node_base, "rel_max_lost_particles")) { + relative_max_lost_particles = std::stod(get_node_value(node_base, "rel_max_lost_particles")); + } + // Get number of inactive batches if (run_mode == RunMode::EIGENVALUE) { if (check_for_node(node_base, "inactive")) { @@ -358,7 +364,9 @@ void read_settings_xml() fatal_error("Number of particles must be greater than zero."); } else if (n_max_lost_particles <= 0) { fatal_error("Number of max lost particles must be greater than zero."); - } + } else if (relative_max_lost_particles <= 0.0 || relative_max_lost_particles >= 1.0) { + fatal_error("Relative max lost particles must be between zero and one."); + } } // Copy random number seed if specified From 6a40a535e482aa0ae31949b0836c22f3d6445f48 Mon Sep 17 00:00:00 2001 From: stevendargaville Date: Tue, 11 Feb 2020 13:37:32 +0000 Subject: [PATCH 27/43] Modified the test_settings unit test for new max_lost_particles and rel_max_lost_particles to check they can be assigned/read by the python interface --- tests/unit_tests/test_settings.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/unit_tests/test_settings.py b/tests/unit_tests/test_settings.py index 9c33f6a2d4..c3ff728798 100644 --- a/tests/unit_tests/test_settings.py +++ b/tests/unit_tests/test_settings.py @@ -9,6 +9,8 @@ def test_export_to_xml(run_in_tmpdir): s.generations_per_batch = 10 s.inactive = 100 s.particles = 1000000 + s.max_lost_particles = 5 + s.rel_max_lost_particles = 1e-4 s.keff_trigger = {'type': 'std_dev', 'threshold': 0.001} s.energy_mode = 'continuous-energy' s.max_order = 5 @@ -62,6 +64,8 @@ def test_export_to_xml(run_in_tmpdir): assert s.generations_per_batch == 10 assert s.inactive == 100 assert s.particles == 1000000 + assert s.max_lost_particles == 5 + assert s.rel_max_lost_particles == 1e-4 assert s.keff_trigger == {'type': 'std_dev', 'threshold': 0.001} assert s.energy_mode == 'continuous-energy' assert s.max_order == 5 From 9224ca318675fcbb06c8eb97d9569466874dda21 Mon Sep 17 00:00:00 2001 From: stevendargaville Date: Tue, 11 Feb 2020 13:37:37 +0000 Subject: [PATCH 28/43] Modified an existing regression test to include the new max_lost_particles and relative version. This is mainly a test that the python/xml input/output routines work through the comparison the regression test harness does in this test, neither of these trigger the end of the simulation. --- tests/regression_tests/photon_source/inputs_true.dat | 2 ++ tests/regression_tests/photon_source/test.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/regression_tests/photon_source/inputs_true.dat b/tests/regression_tests/photon_source/inputs_true.dat index 89f4de0e0c..83c909ac69 100644 --- a/tests/regression_tests/photon_source/inputs_true.dat +++ b/tests/regression_tests/photon_source/inputs_true.dat @@ -18,6 +18,8 @@ fixed source 10000 1 + 5 + 0.1 0 0 0 diff --git a/tests/regression_tests/photon_source/test.py b/tests/regression_tests/photon_source/test.py index 94b0280031..09a0b4a2d0 100644 --- a/tests/regression_tests/photon_source/test.py +++ b/tests/regression_tests/photon_source/test.py @@ -31,6 +31,8 @@ class SourceTestHarness(PyAPITestHarness): settings = openmc.Settings() settings.particles = 10000 settings.batches = 1 + settings.max_lost_particles = 5 + settings.rel_max_lost_particles = 0.1 settings.photon_transport = True settings.electron_treatment = 'ttb' settings.cutoff = {'energy_photon' : 1000.0} From b6a03949c82aee90824b9daf60d3d74a587b5b19 Mon Sep 17 00:00:00 2001 From: stevendargaville Date: Tue, 11 Feb 2020 13:37:41 +0000 Subject: [PATCH 29/43] Modified the StatePoint output to include the new max_lost_particles and relative version. Further modified an existing regression test to check the StatePoint write-out of these variables --- src/state_point.cpp | 4 ++++ tests/regression_tests/photon_source/results_true.dat | 2 ++ tests/regression_tests/photon_source/test.py | 2 ++ 3 files changed, 8 insertions(+) diff --git a/src/state_point.cpp b/src/state_point.cpp index 60fd3826de..a9213bcb4e 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -93,6 +93,8 @@ openmc_statepoint_write(const char* filename, bool* write_source) write_attribute(file_id, "photon_transport", settings::photon_transport); write_dataset(file_id, "n_particles", settings::n_particles); write_dataset(file_id, "n_batches", settings::n_batches); + write_dataset(file_id, "n_max_lost_particles", settings::n_max_lost_particles); + write_dataset(file_id, "relative_max_lost_particles", settings::relative_max_lost_particles); // Write out current batch number write_dataset(file_id, "current_batch", simulation::current_batch); @@ -373,6 +375,8 @@ void load_state_point() read_dataset(file_id, "n_particles", settings::n_particles); int temp; read_dataset(file_id, "n_batches", temp); + read_dataset(file_id, "n_max_lost_particles", settings::n_max_lost_particles); + read_dataset(file_id, "relative_max_lost_particles", settings::relative_max_lost_particles); // Take maximum of statepoint n_batches and input n_batches settings::n_batches = std::max(settings::n_batches, temp); diff --git a/tests/regression_tests/photon_source/results_true.dat b/tests/regression_tests/photon_source/results_true.dat index 1448ad6db8..ab6ac9ff83 100644 --- a/tests/regression_tests/photon_source/results_true.dat +++ b/tests/regression_tests/photon_source/results_true.dat @@ -1,3 +1,5 @@ tally 1: sum = 2.275713E+02 sum_sq = 5.178870E+04 +max_lost = 5.000000E+00 +rel_max_lost = 1.000000E-01 diff --git a/tests/regression_tests/photon_source/test.py b/tests/regression_tests/photon_source/test.py index 09a0b4a2d0..c5c42d680e 100644 --- a/tests/regression_tests/photon_source/test.py +++ b/tests/regression_tests/photon_source/test.py @@ -54,6 +54,8 @@ class SourceTestHarness(PyAPITestHarness): outstr += 'tally {}:\n'.format(t.id) outstr += 'sum = {:12.6E}\n'.format(t.sum[0, 0, 0]) outstr += 'sum_sq = {:12.6E}\n'.format(t.sum_sq[0, 0, 0]) + outstr += 'max_lost = {:12.6E}\n'.format(sp.n_max_lost_particles) + outstr += 'rel_max_lost = {:12.6E}\n'.format(sp.relative_max_lost_particles) return outstr From 70e914d2458f6c35ef46f25b93f221f056dac813 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 11 Feb 2020 10:12:34 -0600 Subject: [PATCH 30/43] Fix failing tests --- openmc/deplete/abc.py | 7 +++---- tests/unit_tests/test_deplete_integrator.py | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/openmc/deplete/abc.py b/openmc/deplete/abc.py index d75833a6f1..912c0b1fb4 100644 --- a/openmc/deplete/abc.py +++ b/openmc/deplete/abc.py @@ -652,14 +652,13 @@ class Integrator(ABC): self.chain = operator.chain # Determine power and normalize units to W - mass = operator.heavy_metal if power is None: if power_density is None: raise ValueError("Either power or power density must be set") if not isinstance(power_density, Iterable): - power = power_density * mass + power = power_density * operator.heavy_metal else: - power = [p*mass for p in power_density] + power = [p*operator.heavy_metal for p in power_density] if not isinstance(power, Iterable): # Ensure that power is single value if that is the case power = [power] * len(timesteps) @@ -689,7 +688,7 @@ class Integrator(ABC): seconds.append(time*_SECONDS_PER_DAY) elif unit.lower() == 'mwd/kg': watt_days_per_kg = 1e6*time - kilograms = 1e-3*mass + kilograms = 1e-3*operator.heavy_metal days = watt_days_per_kg * kilograms / watts seconds.append(days*_SECONDS_PER_DAY) else: diff --git a/tests/unit_tests/test_deplete_integrator.py b/tests/unit_tests/test_deplete_integrator.py index 110894cdad..6c09b3feac 100644 --- a/tests/unit_tests/test_deplete_integrator.py +++ b/tests/unit_tests/test_deplete_integrator.py @@ -119,14 +119,14 @@ def test_results_save(run_in_tmpdir): np.testing.assert_array_equal(res[1].time, t2) -@pytest.mark.parametrize("timesteps", (1, [1])) -def test_bad_integrator_inputs(timesteps): +def test_bad_integrator_inputs(): """Test failure modes for Integrator inputs""" op = MagicMock() op.prev_res = None op.chain = None op.heavy_metal = 1.0 + timesteps = [1] # No power nor power density given with pytest.raises(ValueError, match="Either power or power density"): From 39a60c361c9111575d9ded988c8459dbc4b82342 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 12 Feb 2020 07:19:31 -0600 Subject: [PATCH 31/43] Clarify that heavy metal is initial Co-Authored-By: Andrew Johnson --- openmc/deplete/abc.py | 4 ++-- openmc/deplete/integrators.py | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/openmc/deplete/abc.py b/openmc/deplete/abc.py index 912c0b1fb4..658e93da5a 100644 --- a/openmc/deplete/abc.py +++ b/openmc/deplete/abc.py @@ -622,7 +622,7 @@ class Integrator(ABC): Units for values specified in the `timesteps` argument. 's' means seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates that the values are given in burnup (MW-d of energy deposited per - kilogram of heavy metal). + kilogram of initial heavy metal). Attributes ---------- @@ -830,7 +830,7 @@ class SIIntegrator(Integrator): Units for values specified in the `timesteps` argument. 's' means seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates that the values are given in burnup (MW-d of energy deposited per - kilogram of heavy metal). + kilogram of initial heavy metal). n_steps : int, optional Number of stochastic iterations per depletion interval. Must be greater than zero. Default : 10 diff --git a/openmc/deplete/integrators.py b/openmc/deplete/integrators.py index da8509d591..38a7c33b1f 100644 --- a/openmc/deplete/integrators.py +++ b/openmc/deplete/integrators.py @@ -52,7 +52,7 @@ class PredictorIntegrator(Integrator): Units for values specified in the `timesteps` argument. 's' means seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates that the values are given in burnup (MW-d of energy deposited per - kilogram of heavy metal). + kilogram of initial heavy metal). Attributes ---------- @@ -141,7 +141,7 @@ class CECMIntegrator(Integrator): Units for values specified in the `timesteps` argument. 's' means seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates that the values are given in burnup (MW-d of energy deposited per - kilogram of heavy metal). + kilogram of initial heavy metal). Attributes ---------- @@ -238,7 +238,7 @@ class CF4Integrator(Integrator): Units for values specified in the `timesteps` argument. 's' means seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates that the values are given in burnup (MW-d of energy deposited per - kilogram of heavy metal). + kilogram of initial heavy metal). Attributes ---------- @@ -352,7 +352,7 @@ class CELIIntegrator(Integrator): Units for values specified in the `timesteps` argument. 's' means seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates that the values are given in burnup (MW-d of energy deposited per - kilogram of heavy metal). + kilogram of initial heavy metal). Attributes ---------- @@ -453,7 +453,7 @@ class EPCRK4Integrator(Integrator): Units for values specified in the `timesteps` argument. 's' means seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates that the values are given in burnup (MW-d of energy deposited per - kilogram of heavy metal). + kilogram of initial heavy metal). Attributes ---------- @@ -574,7 +574,7 @@ class LEQIIntegrator(Integrator): Units for values specified in the `timesteps` argument. 's' means seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates that the values are given in burnup (MW-d of energy deposited per - kilogram of heavy metal). + kilogram of initial heavy metal). Attributes ---------- @@ -692,7 +692,7 @@ class SICELIIntegrator(SIIntegrator): Units for values specified in the `timesteps` argument. 's' means seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates that the values are given in burnup (MW-d of energy deposited per - kilogram of heavy metal). + kilogram of initial heavy metal). n_steps : int, optional Number of stochastic iterations per depletion interval. Must be greater than zero. Default : 10 @@ -800,7 +800,7 @@ class SILEQIIntegrator(SIIntegrator): Units for values specified in the `timesteps` argument. 's' means seconds, 'min' means minutes, 'h' means hours, and 'MWd/kg' indicates that the values are given in burnup (MW-d of energy deposited per - kilogram of heavy metal). + kilogram of initial heavy metal). n_steps : int, optional Number of stochastic iterations per depletion interval. Must be greater than zero. Default : 10 From 3682f7adcbf6420198a39e332207818685a9524f Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 12 Feb 2020 07:36:29 -0600 Subject: [PATCH 32/43] Add type/value checks on timestep, power, and units --- openmc/deplete/abc.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/openmc/deplete/abc.py b/openmc/deplete/abc.py index 658e93da5a..95bd3326b8 100644 --- a/openmc/deplete/abc.py +++ b/openmc/deplete/abc.py @@ -665,7 +665,7 @@ class Integrator(ABC): if len(power) != len(timesteps): raise ValueError( - "Number of time steps != number of powers. {} vs {}".format( + "Number of time steps ({}) != number of powers ({})".format( len(timesteps), len(power))) # Get list of times / units @@ -678,6 +678,13 @@ class Integrator(ABC): # Determine number of seconds for each timestep seconds = [] for time, unit, watts in zip(times, units, power): + # Make sure values passed make sense + check_type('timestep', time, Real) + check_greater_than('timestep', time, 0.0, True) + check_type('timestep units', unit, str) + check_type('power', watts, Real) + check_greater_than('power', watts, 0.0, True) + if unit in ('s', 'sec'): seconds.append(time) elif unit in ('min', 'minute'): From 4966ff7c5dff243853881c75125994dda6d3a887 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 12 Feb 2020 12:21:25 -0600 Subject: [PATCH 33/43] Ensure timesteps are positive Co-Authored-By: Andrew Johnson --- openmc/deplete/abc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openmc/deplete/abc.py b/openmc/deplete/abc.py index 95bd3326b8..31479f9952 100644 --- a/openmc/deplete/abc.py +++ b/openmc/deplete/abc.py @@ -680,7 +680,7 @@ class Integrator(ABC): for time, unit, watts in zip(times, units, power): # Make sure values passed make sense check_type('timestep', time, Real) - check_greater_than('timestep', time, 0.0, True) + check_greater_than('timestep', time, 0.0, False) check_type('timestep units', unit, str) check_type('power', watts, Real) check_greater_than('power', watts, 0.0, True) From 4200b0dfbf11cf555d3f791285508bf0a18c87fd Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 12 Feb 2020 16:05:58 -0600 Subject: [PATCH 34/43] Update depletion-related documentation --- docs/source/usersguide/depletion.rst | 17 ++- .../pincell_depletion/restart_depletion.py | 50 +++---- .../python/pincell_depletion/run_depletion.py | 122 ++++++------------ 3 files changed, 67 insertions(+), 122 deletions(-) diff --git a/docs/source/usersguide/depletion.rst b/docs/source/usersguide/depletion.rst index 4a4c7b1f88..f6feb6d245 100644 --- a/docs/source/usersguide/depletion.rst +++ b/docs/source/usersguide/depletion.rst @@ -33,12 +33,11 @@ material compositions over time. Each method appears as a different class. For example, :class:`openmc.deplete.CECMIntegrator` runs a depletion calculation using the CE/CM algorithm (deplete over a timestep using the middle-of-step reaction rates). An instance of :class:`openmc.deplete.Operator` is passed to -one of these functions along with the power level and timesteps:: +one of these functions along with the timesteps and power level:: - power = 1200.0e6 - days = 24*60*60 - timesteps = [10.0*days, 10.0*days, 10.0*days] - openmc.deplete.CECMIntegrator(op, power, timesteps).integrate() + power = 1200.0e6 # watts + timesteps = [10.0, 10.0, 10.0] # days + openmc.deplete.CECMIntegrator(op, timesteps, power, timestep_units='d').integrate() The coupled transport-depletion problem is executed, and once it is done a ``depletion_results.h5`` file is written. The results can be analyzed using the @@ -67,7 +66,7 @@ the energy deposited during a transport calculation will be lower than expected. This causes the reaction rates to be over-adjusted to hit the user-specific power, or power density, leading to an over-depletion of burnable materials. -There are some remedies. First, the fission Q values can be directly set in a +There are some remedies. First, the fission Q values can be directly set in a variety of ways. This requires knowing what the total fission energy release should be, including indirect components. Some examples are provided below:: @@ -99,11 +98,11 @@ Local Spectra and Repeated Materials ------------------------------------ It is not uncommon to explicitly create a single burnable material across many locations. -From a pure transport perspective, there is nothing wrong with creating a single +From a pure transport perspective, there is nothing wrong with creating a single 3.5 wt.% enriched fuel ``fuel_3``, and placing that fuel in every fuel pin in an assembly or even full core problem. This certainly expedites the model making process, but can pose -issues with depletion. -Under this setup, :mod:`openmc.deplete` will deplete a single ``fuel_3`` material using +issues with depletion. +Under this setup, :mod:`openmc.deplete` will deplete a single ``fuel_3`` material using a single set of reaction rates, and produce a single new composition for the next time step. This can be problematic if the same ``fuel_3`` is used in very different regions of the problem. diff --git a/examples/python/pincell_depletion/restart_depletion.py b/examples/python/pincell_depletion/restart_depletion.py index 013a2469e0..f0387e066f 100644 --- a/examples/python/pincell_depletion/restart_depletion.py +++ b/examples/python/pincell_depletion/restart_depletion.py @@ -1,25 +1,7 @@ import openmc import openmc.deplete -import numpy as np import matplotlib.pyplot as plt -############################################################################### -# Simulation Input File Parameters -############################################################################### - -# OpenMC simulation parameters -batches = 100 -inactive = 10 -particles = 1000 - -# Depletion simulation parameters -time_step = 1*24*60*60 # s -final_time = 5*24*60*60 # s -time_steps = np.full(final_time // time_step, time_step) - -chain_file = './chain_simple.xml' -power = 174 # W/cm, for 2D simulations only (use W for 3D) - ############################################################################### # Load previous simulation results ############################################################################### @@ -37,31 +19,34 @@ previous_results = openmc.deplete.ResultsList("depletion_results.h5") ############################################################################### # Instantiate a Settings object, set all runtime parameters -settings_file = openmc.Settings() -settings_file.batches = batches -settings_file.inactive = inactive -settings_file.particles = particles +settings = openmc.Settings() +settings.batches = 100 +settings.inactive = 10 +settings.particles = 10000 # Create an initial uniform spatial source distribution over fissionable zones bounds = [-0.62992, -0.62992, -1, 0.62992, 0.62992, 1] uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:], only_fissionable=True) -settings_file.source = openmc.source.Source(space=uniform_dist) +settings.source = openmc.source.Source(space=uniform_dist) entropy_mesh = openmc.RegularMesh() entropy_mesh.lower_left = [-0.39218, -0.39218, -1.e50] entropy_mesh.upper_right = [0.39218, 0.39218, 1.e50] entropy_mesh.dimension = [10, 10, 1] -settings_file.entropy_mesh = entropy_mesh +settings.entropy_mesh = entropy_mesh ############################################################################### # Initialize and run depletion calculation ############################################################################### -op = openmc.deplete.Operator(geometry, settings_file, chain_file, - previous_results) +# Create depletion "operator" +chain_file = './chain_simple.xml' +op = openmc.deplete.Operator(geometry, settings, chain_file, previous_results) # Perform simulation using the predictor algorithm -integrator = openmc.deplete.PredictorIntegrator(op, time_steps, power) +time_steps = [1.0, 1.0, 1.0, 1.0, 1.0] # days +power = 174 # W/cm, for 2D simulations only (use W for 3D) +integrator = openmc.deplete.PredictorIntegrator(op, time_steps, power, timestep_units='d') integrator.integrate() ############################################################################### @@ -77,27 +62,28 @@ time, keff = results.get_eigenvalue() # Obtain U235 concentration as a function of time time, n_U235 = results.get_atoms('1', 'U235') -# Obtain Xe135 absorption as a function of time -time, Xe_gam = results.get_reaction_rate('1', 'Xe135', '(n,gamma)') +# Obtain Xe135 capture reaction rate as a function of time +time, Xe_capture = results.get_reaction_rate('1', 'Xe135', '(n,gamma)') ############################################################################### # Generate plots ############################################################################### +days = 24*60*60 plt.figure() -plt.plot(time/(24*60*60), keff, label="K-effective") +plt.plot(time/days, keff, label="K-effective") plt.xlabel("Time (days)") plt.ylabel("Keff") plt.show() plt.figure() -plt.plot(time/(24*60*60), n_U235, label="U 235") +plt.plot(time/days, n_U235, label="U 235") plt.xlabel("Time (days)") plt.ylabel("n U5 (-)") plt.show() plt.figure() -plt.plot(time/(24*60*60), Xe_gam, label="Xe135 absorption") +plt.plot(time/days, Xe_capture, label="Xe135 capture") plt.xlabel("Time (days)") plt.ylabel("RR (-)") plt.show() diff --git a/examples/python/pincell_depletion/run_depletion.py b/examples/python/pincell_depletion/run_depletion.py index 9933edd48a..ce4b0cf5e6 100644 --- a/examples/python/pincell_depletion/run_depletion.py +++ b/examples/python/pincell_depletion/run_depletion.py @@ -1,47 +1,31 @@ +from math import pi + import openmc import openmc.deplete -import numpy as np import matplotlib.pyplot as plt -############################################################################### -# Simulation Input File Parameters -############################################################################### - -# OpenMC simulation parameters -batches = 100 -inactive = 10 -particles = 1000 - -# Depletion simulation parameters -time_step = 1*24*60*60 # s -final_time = 5*24*60*60 # s -time_steps = np.full(final_time // time_step, time_step) -chain_file = './chain_simple.xml' -power = 174 # W/cm, for 2D simulations only (use W for 3D) - ############################################################################### # Define materials ############################################################################### # Instantiate some Materials and register the appropriate Nuclides -uo2 = openmc.Material(material_id=1, name='UO2 fuel at 2.4% wt enrichment') +uo2 = openmc.Material(name='UO2 fuel at 2.4% wt enrichment') uo2.set_density('g/cm3', 10.29769) uo2.add_element('U', 1., enrichment=2.4) uo2.add_element('O', 2.) -uo2.depletable = True -helium = openmc.Material(material_id=2, name='Helium for gap') +helium = openmc.Material(name='Helium for gap') helium.set_density('g/cm3', 0.001598) helium.add_element('He', 2.4044e-4) -zircaloy = openmc.Material(material_id=3, name='Zircaloy 4') +zircaloy = openmc.Material(name='Zircaloy 4') zircaloy.set_density('g/cm3', 6.55) -zircaloy.add_element('Sn', 0.014 , 'wo') +zircaloy.add_element('Sn', 0.014, 'wo') zircaloy.add_element('Fe', 0.00165, 'wo') -zircaloy.add_element('Cr', 0.001 , 'wo') +zircaloy.add_element('Cr', 0.001, 'wo') zircaloy.add_element('Zr', 0.98335, 'wo') -borated_water = openmc.Material(material_id=4, name='Borated water') +borated_water = openmc.Material(name='Borated water') borated_water.set_density('g/cm3', 0.740582) borated_water.add_element('B', 4.0e-5) borated_water.add_element('H', 5.0e-2) @@ -52,87 +36,62 @@ borated_water.add_s_alpha_beta('c_H_in_H2O') # Create geometry ############################################################################### -# Instantiate ZCylinder surfaces -fuel_or = openmc.ZCylinder(surface_id=1, x0=0, y0=0, r=0.39218, name='Fuel OR') -clad_ir = openmc.ZCylinder(surface_id=2, x0=0, y0=0, r=0.40005, name='Clad IR') -clad_or = openmc.ZCylinder(surface_id=3, x0=0, y0=0, r=0.45720, name='Clad OR') -left = openmc.XPlane(surface_id=4, x0=-0.62992, name='left') -right = openmc.XPlane(surface_id=5, x0=0.62992, name='right') -bottom = openmc.YPlane(surface_id=6, y0=-0.62992, name='bottom') -top = openmc.YPlane(surface_id=7, y0=0.62992, name='top') +# Define surfaces +pitch = 1.25984 +fuel_or = openmc.ZCylinder(r=0.39218, name='Fuel OR') +clad_ir = openmc.ZCylinder(r=0.40005, name='Clad IR') +clad_or = openmc.ZCylinder(r=0.45720, name='Clad OR') +box = openmc.model.rectangular_prism(pitch, pitch, boundary_type='reflective') -left.boundary_type = 'reflective' -right.boundary_type = 'reflective' -top.boundary_type = 'reflective' -bottom.boundary_type = 'reflective' +# Define cells +fuel = openmc.Cell(fill=uo2, region=-fuel_or) +gap = openmc.Cell(fill=helium, region=+fuel_or & -clad_ir) +clad = openmc.Cell(fill=zircaloy, region=+clad_ir & -clad_or) +water = openmc.Cell(fill=borated_water, region=+clad_or & box) -# Instantiate Cells -fuel = openmc.Cell(cell_id=1, name='cell 1') -gap = openmc.Cell(cell_id=2, name='cell 2') -clad = openmc.Cell(cell_id=3, name='cell 3') -water = openmc.Cell(cell_id=4, name='cell 4') - -# Use surface half-spaces to define regions -fuel.region = -fuel_or -gap.region = +fuel_or & -clad_ir -clad.region = +clad_ir & -clad_or -water.region = +clad_or & +left & -right & +bottom & -top - -# Register Materials with Cells -fuel.fill = uo2 -gap.fill = helium -clad.fill = zircaloy -water.fill = borated_water - -# Instantiate Universe -root = openmc.Universe(universe_id=0, name='root universe') - -# Register Cells with Universe -root.add_cells([fuel, gap, clad, water]) - -# Instantiate a Geometry, register the root Universe -geometry = openmc.Geometry(root) +# Define overall geometry +geometry = openmc.Geometry([fuel, gap, clad, water]) ############################################################################### # Set volumes of depletable materials ############################################################################### -# Compute cell areas -area = {} -area[fuel] = np.pi * fuel_or.coefficients['r'] ** 2 - -# Set materials volume for depletion. Set to an area for 2D simulations -uo2.volume = area[fuel] +# Set material volume for depletion. For 2D simulations, this should be an area. +uo2.volume = pi * fuel_or.r**2 ############################################################################### # Transport calculation settings ############################################################################### # Instantiate a Settings object, set all runtime parameters, and export to XML -settings_file = openmc.Settings() -settings_file.batches = batches -settings_file.inactive = inactive -settings_file.particles = particles +settings = openmc.Settings() +settings.batches = 100 +settings.inactive = 10 +settings.particles = 1000 # Create an initial uniform spatial source distribution over fissionable zones bounds = [-0.62992, -0.62992, -1, 0.62992, 0.62992, 1] uniform_dist = openmc.stats.Box(bounds[:3], bounds[3:], only_fissionable=True) -settings_file.source = openmc.source.Source(space=uniform_dist) +settings.source = openmc.source.Source(space=uniform_dist) entropy_mesh = openmc.RegularMesh() entropy_mesh.lower_left = [-0.39218, -0.39218, -1.e50] entropy_mesh.upper_right = [0.39218, 0.39218, 1.e50] entropy_mesh.dimension = [10, 10, 1] -settings_file.entropy_mesh = entropy_mesh +settings.entropy_mesh = entropy_mesh ############################################################################### # Initialize and run depletion calculation ############################################################################### -op = openmc.deplete.Operator(geometry, settings_file, chain_file) +# Create depletion "operator" +chain_file = './chain_simple.xml' +op = openmc.deplete.Operator(geometry, settings, chain_file) # Perform simulation using the predictor algorithm -integrator = openmc.deplete.PredictorIntegrator(op, time_steps, power) +time_steps = [1.0, 1.0, 1.0, 1.0, 1.0] # days +power = 174 # W/cm, for 2D simulations only (use W for 3D) +integrator = openmc.deplete.PredictorIntegrator(op, time_steps, power, timestep_units='d') integrator.integrate() ############################################################################### @@ -148,27 +107,28 @@ time, keff = results.get_eigenvalue() # Obtain U235 concentration as a function of time time, n_U235 = results.get_atoms('1', 'U235') -# Obtain Xe135 absorption as a function of time -time, Xe_gam = results.get_reaction_rate('1', 'Xe135', '(n,gamma)') +# Obtain Xe135 capture reaction rate as a function of time +time, Xe_capture = results.get_reaction_rate('1', 'Xe135', '(n,gamma)') ############################################################################### # Generate plots ############################################################################### +days = 24*60*60 plt.figure() -plt.plot(time/(24*60*60), keff, label="K-effective") +plt.plot(time/days, keff, label="K-effective") plt.xlabel("Time (days)") plt.ylabel("Keff") plt.show() plt.figure() -plt.plot(time/(24*60*60), n_U235, label="U 235") +plt.plot(time/days, n_U235, label="U235") plt.xlabel("Time (days)") plt.ylabel("n U5 (-)") plt.show() plt.figure() -plt.plot(time/(24*60*60), Xe_gam, label="Xe135 absorption") +plt.plot(time/days, Xe_capture, label="Xe135 capture") plt.xlabel("Time (days)") plt.ylabel("RR (-)") plt.show() From 061fc82e4374f0d810acf017236216e77eced683 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Wed, 12 Feb 2020 12:30:19 +0000 Subject: [PATCH 35/43] These fixes allow the Cmake find_package infrastructure to work correctly --- CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec6b500b45..3cbd27b4e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,7 +207,6 @@ endif() add_library(faddeeva STATIC vendor/faddeeva/Faddeeva.cc) target_include_directories(faddeeva PUBLIC - $ $ ) target_compile_options(faddeeva PRIVATE ${cxxflags}) @@ -389,7 +388,7 @@ add_custom_command(TARGET libopenmc POST_BUILD #=============================================================================== set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/OpenMC) -install(TARGETS openmc libopenmc faddeeva +install(TARGETS openmc libopenmc faddeeva pugixml gsl-lite EXPORT openmc-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} From aa9acca56ad1d8e43d6774afda37a6d4b8d70a32 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Wed, 12 Feb 2020 22:10:41 +0000 Subject: [PATCH 36/43] Revert "These fixes allow the Cmake find_package infrastructure to work correctly" This reverts commit cfee500608a823cdbed751ed4cd7675cef519561. --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3cbd27b4e3..ec6b500b45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,6 +207,7 @@ endif() add_library(faddeeva STATIC vendor/faddeeva/Faddeeva.cc) target_include_directories(faddeeva PUBLIC + $ $ ) target_compile_options(faddeeva PRIVATE ${cxxflags}) @@ -388,7 +389,7 @@ add_custom_command(TARGET libopenmc POST_BUILD #=============================================================================== set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/OpenMC) -install(TARGETS openmc libopenmc faddeeva pugixml gsl-lite +install(TARGETS openmc libopenmc faddeeva EXPORT openmc-targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} From b9c3d7af5424d241be522bcf8f791c9e1dfa4ce3 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Wed, 12 Feb 2020 22:11:58 +0000 Subject: [PATCH 37/43] Fix CMake issues per Paul R fixes --- cmake/OpenMCConfig.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/OpenMCConfig.cmake b/cmake/OpenMCConfig.cmake index 0bc86fa71c..29a0e4542f 100644 --- a/cmake/OpenMCConfig.cmake +++ b/cmake/OpenMCConfig.cmake @@ -1,5 +1,8 @@ get_filename_component(OpenMC_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) +find_package(fmt REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../fmt) +find_package(gsl-lite REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../gsl-lite) +find_package(pugixml REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../pugixml) find_package(xtl REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../xtl) find_package(xtensor REQUIRED HINTS ${OpenMC_CMAKE_DIR}/../xtensor) From 8154eeed13db2a663464e9a204749a6d0bb67c10 Mon Sep 17 00:00:00 2001 From: stevendargaville Date: Thu, 13 Feb 2020 14:41:40 +0000 Subject: [PATCH 38/43] Revert "Modified the StatePoint output to include the new max_lost_particles and relative version. Further modified an existing regression test to check the StatePoint write-out of these variables" This reverts commit b6a03949c82aee90824b9daf60d3d74a587b5b19. --- src/state_point.cpp | 4 ---- tests/regression_tests/photon_source/results_true.dat | 2 -- tests/regression_tests/photon_source/test.py | 2 -- 3 files changed, 8 deletions(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index a9213bcb4e..60fd3826de 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -93,8 +93,6 @@ openmc_statepoint_write(const char* filename, bool* write_source) write_attribute(file_id, "photon_transport", settings::photon_transport); write_dataset(file_id, "n_particles", settings::n_particles); write_dataset(file_id, "n_batches", settings::n_batches); - write_dataset(file_id, "n_max_lost_particles", settings::n_max_lost_particles); - write_dataset(file_id, "relative_max_lost_particles", settings::relative_max_lost_particles); // Write out current batch number write_dataset(file_id, "current_batch", simulation::current_batch); @@ -375,8 +373,6 @@ void load_state_point() read_dataset(file_id, "n_particles", settings::n_particles); int temp; read_dataset(file_id, "n_batches", temp); - read_dataset(file_id, "n_max_lost_particles", settings::n_max_lost_particles); - read_dataset(file_id, "relative_max_lost_particles", settings::relative_max_lost_particles); // Take maximum of statepoint n_batches and input n_batches settings::n_batches = std::max(settings::n_batches, temp); diff --git a/tests/regression_tests/photon_source/results_true.dat b/tests/regression_tests/photon_source/results_true.dat index ab6ac9ff83..1448ad6db8 100644 --- a/tests/regression_tests/photon_source/results_true.dat +++ b/tests/regression_tests/photon_source/results_true.dat @@ -1,5 +1,3 @@ tally 1: sum = 2.275713E+02 sum_sq = 5.178870E+04 -max_lost = 5.000000E+00 -rel_max_lost = 1.000000E-01 diff --git a/tests/regression_tests/photon_source/test.py b/tests/regression_tests/photon_source/test.py index c5c42d680e..09a0b4a2d0 100644 --- a/tests/regression_tests/photon_source/test.py +++ b/tests/regression_tests/photon_source/test.py @@ -54,8 +54,6 @@ class SourceTestHarness(PyAPITestHarness): outstr += 'tally {}:\n'.format(t.id) outstr += 'sum = {:12.6E}\n'.format(t.sum[0, 0, 0]) outstr += 'sum_sq = {:12.6E}\n'.format(t.sum_sq[0, 0, 0]) - outstr += 'max_lost = {:12.6E}\n'.format(sp.n_max_lost_particles) - outstr += 'rel_max_lost = {:12.6E}\n'.format(sp.relative_max_lost_particles) return outstr From 68312dd9818cecd8129206b4a1a9d816432169e5 Mon Sep 17 00:00:00 2001 From: stevendargaville Date: Thu, 13 Feb 2020 14:43:31 +0000 Subject: [PATCH 39/43] Revert "Modified an existing regression test to include the new max_lost_particles and relative version. This is mainly a test that the python/xml input/output routines work through the comparison the regression test harness does in this test, neither of these trigger the end of the simulation." This reverts commit 9224ca318675fcbb06c8eb97d9569466874dda21. --- tests/regression_tests/photon_source/inputs_true.dat | 2 -- tests/regression_tests/photon_source/test.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/tests/regression_tests/photon_source/inputs_true.dat b/tests/regression_tests/photon_source/inputs_true.dat index 83c909ac69..89f4de0e0c 100644 --- a/tests/regression_tests/photon_source/inputs_true.dat +++ b/tests/regression_tests/photon_source/inputs_true.dat @@ -18,8 +18,6 @@ fixed source 10000 1 - 5 - 0.1 0 0 0 diff --git a/tests/regression_tests/photon_source/test.py b/tests/regression_tests/photon_source/test.py index 09a0b4a2d0..94b0280031 100644 --- a/tests/regression_tests/photon_source/test.py +++ b/tests/regression_tests/photon_source/test.py @@ -31,8 +31,6 @@ class SourceTestHarness(PyAPITestHarness): settings = openmc.Settings() settings.particles = 10000 settings.batches = 1 - settings.max_lost_particles = 5 - settings.rel_max_lost_particles = 0.1 settings.photon_transport = True settings.electron_treatment = 'ttb' settings.cutoff = {'energy_photon' : 1000.0} From 18b469bfa5cc4b4d1280655e9166c997db267481 Mon Sep 17 00:00:00 2001 From: stevendargaville Date: Thu, 13 Feb 2020 14:44:53 +0000 Subject: [PATCH 40/43] Removed new variables from the statepoint python file as they are no longer read out --- openmc/statepoint.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/openmc/statepoint.py b/openmc/statepoint.py index 0d78bf68dc..a8e13efd25 100644 --- a/openmc/statepoint.py +++ b/openmc/statepoint.py @@ -77,10 +77,6 @@ class StatePoint(object): Number of batches n_inactive : int Number of inactive batches - n_max_lost_particles : int - Number of max lost particles - relative_max_lost_particles : float - Number of max lost particles, relative to the total number of particles n_particles : int Number of particles per generation n_realizations : int @@ -316,10 +312,6 @@ class StatePoint(object): else: return None - @property - def n_max_lost_particles(self): - return self._f['n_max_lost_particles'][()] - @property def relative_max_lost_particles(self): return self._f['relative_max_lost_particles'][()] From a9d1e37aba4aeadb683947861bb0a392c364e878 Mon Sep 17 00:00:00 2001 From: stevendargaville Date: Thu, 13 Feb 2020 14:46:34 +0000 Subject: [PATCH 41/43] Changed the name of the max_lost_particles in the C++ layer to match the python side --- include/openmc/settings.h | 2 +- openmc/lib/settings.py | 2 +- src/particle.cpp | 2 +- src/settings.cpp | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/openmc/settings.h b/include/openmc/settings.h index 3407eadf4b..8cee3c72ab 100644 --- a/include/openmc/settings.h +++ b/include/openmc/settings.h @@ -65,7 +65,7 @@ extern "C" std::string path_statepoint; //!< path to a statepoint file extern "C" int32_t n_batches; //!< number of (inactive+active) batches extern "C" int32_t n_inactive; //!< number of inactive batches -extern "C" int32_t n_max_lost_particles; //!< maximum number of lost particles +extern "C" int32_t max_lost_particles; //!< maximum number of lost particles extern double relative_max_lost_particles; //!< maximum number of lost particles, relative to the total number of particles extern "C" int32_t gen_per_batch; //!< number of generations per batch extern "C" int64_t n_particles; //!< number of particles per generation diff --git a/openmc/lib/settings.py b/openmc/lib/settings.py index 8345e00881..fa72e13234 100644 --- a/openmc/lib/settings.py +++ b/openmc/lib/settings.py @@ -22,7 +22,7 @@ class _Settings(object): entropy_on = _DLLGlobal(c_bool, 'entropy_on') generations_per_batch = _DLLGlobal(c_int32, 'gen_per_batch') inactive = _DLLGlobal(c_int32, 'n_inactive') - max_lost_particles = _DLLGlobal(c_int32, 'n_max_lost_particles') + max_lost_particles = _DLLGlobal(c_int32, 'max_lost_particles') rel_max_lost_particles = _DLLGlobal(c_double, 'relative_max_lost_particles') particles = _DLLGlobal(c_int64, 'n_particles') restart_run = _DLLGlobal(c_bool, 'restart_run') diff --git a/src/particle.cpp b/src/particle.cpp index 79e6625771..7e98b2ce67 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -630,7 +630,7 @@ Particle::mark_as_lost(const char* message) // Abort the simulation if the maximum number of lost particles has been // reached - if (simulation::n_lost_particles >= settings::n_max_lost_particles && + if (simulation::n_lost_particles >= settings::max_lost_particles && simulation::n_lost_particles >= settings::relative_max_lost_particles*n) { fatal_error("Maximum number of lost particles has been reached."); } diff --git a/src/settings.cpp b/src/settings.cpp index d72e5f17f7..933f9a2172 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -79,7 +79,7 @@ std::string path_statepoint; int32_t n_batches; int32_t n_inactive {0}; -int32_t n_max_lost_particles {10}; +int32_t max_lost_particles {10}; double relative_max_lost_particles {1.0e-6}; int32_t gen_per_batch {1}; int64_t n_particles {-1}; @@ -147,7 +147,7 @@ void get_run_parameters(pugi::xml_node node_base) // Get max number of lost particles if (check_for_node(node_base, "max_lost_particles")) { - n_max_lost_particles = std::stoi(get_node_value(node_base, "max_lost_particles")); + max_lost_particles = std::stoi(get_node_value(node_base, "max_lost_particles")); } // Get relative number of lost particles @@ -362,7 +362,7 @@ void read_settings_xml() fatal_error("Number of inactive batches must be non-negative."); } else if (n_particles <= 0) { fatal_error("Number of particles must be greater than zero."); - } else if (n_max_lost_particles <= 0) { + } else if (max_lost_particles <= 0) { fatal_error("Number of max lost particles must be greater than zero."); } else if (relative_max_lost_particles <= 0.0 || relative_max_lost_particles >= 1.0) { fatal_error("Relative max lost particles must be between zero and one."); From a9fc400863952502bad61fd73bb80993448afc74 Mon Sep 17 00:00:00 2001 From: stevendargaville Date: Thu, 13 Feb 2020 14:51:32 +0000 Subject: [PATCH 42/43] Also removed relative_max_lost_particles from statepoint python as it is not being written out --- openmc/statepoint.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/openmc/statepoint.py b/openmc/statepoint.py index a8e13efd25..84512d70e7 100644 --- a/openmc/statepoint.py +++ b/openmc/statepoint.py @@ -310,11 +310,7 @@ class StatePoint(object): if self.run_mode == 'eigenvalue': return self._f['n_inactive'][()] else: - return None - - @property - def relative_max_lost_particles(self): - return self._f['relative_max_lost_particles'][()] + return None @property def n_particles(self): From d763806c43ea05adb25831b8fd11c828fd40d06a Mon Sep 17 00:00:00 2001 From: stevendargaville Date: Thu, 13 Feb 2020 14:52:44 +0000 Subject: [PATCH 43/43] Also made rel_max_lost_particle name consistent between C++ and python layers --- include/openmc/settings.h | 2 +- openmc/lib/settings.py | 2 +- src/particle.cpp | 2 +- src/settings.cpp | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/openmc/settings.h b/include/openmc/settings.h index 8cee3c72ab..2b4203646f 100644 --- a/include/openmc/settings.h +++ b/include/openmc/settings.h @@ -66,7 +66,7 @@ extern "C" std::string path_statepoint; //!< path to a statepoint file extern "C" int32_t n_batches; //!< number of (inactive+active) batches extern "C" int32_t n_inactive; //!< number of inactive batches extern "C" int32_t max_lost_particles; //!< maximum number of lost particles -extern double relative_max_lost_particles; //!< maximum number of lost particles, relative to the total number of particles +extern double rel_max_lost_particles; //!< maximum number of lost particles, relative to the total number of particles extern "C" int32_t gen_per_batch; //!< number of generations per batch extern "C" int64_t n_particles; //!< number of particles per generation diff --git a/openmc/lib/settings.py b/openmc/lib/settings.py index fa72e13234..68d68c29e0 100644 --- a/openmc/lib/settings.py +++ b/openmc/lib/settings.py @@ -23,7 +23,7 @@ class _Settings(object): generations_per_batch = _DLLGlobal(c_int32, 'gen_per_batch') inactive = _DLLGlobal(c_int32, 'n_inactive') max_lost_particles = _DLLGlobal(c_int32, 'max_lost_particles') - rel_max_lost_particles = _DLLGlobal(c_double, 'relative_max_lost_particles') + rel_max_lost_particles = _DLLGlobal(c_double, 'rel_max_lost_particles') particles = _DLLGlobal(c_int64, 'n_particles') restart_run = _DLLGlobal(c_bool, 'restart_run') run_CE = _DLLGlobal(c_bool, 'run_CE') diff --git a/src/particle.cpp b/src/particle.cpp index 7e98b2ce67..8f6dba803f 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -631,7 +631,7 @@ Particle::mark_as_lost(const char* message) // Abort the simulation if the maximum number of lost particles has been // reached if (simulation::n_lost_particles >= settings::max_lost_particles && - simulation::n_lost_particles >= settings::relative_max_lost_particles*n) { + simulation::n_lost_particles >= settings::rel_max_lost_particles*n) { fatal_error("Maximum number of lost particles has been reached."); } } diff --git a/src/settings.cpp b/src/settings.cpp index 933f9a2172..706a171458 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -80,7 +80,7 @@ std::string path_statepoint; int32_t n_batches; int32_t n_inactive {0}; int32_t max_lost_particles {10}; -double relative_max_lost_particles {1.0e-6}; +double rel_max_lost_particles {1.0e-6}; int32_t gen_per_batch {1}; int64_t n_particles {-1}; @@ -152,7 +152,7 @@ void get_run_parameters(pugi::xml_node node_base) // Get relative number of lost particles if (check_for_node(node_base, "rel_max_lost_particles")) { - relative_max_lost_particles = std::stod(get_node_value(node_base, "rel_max_lost_particles")); + rel_max_lost_particles = std::stod(get_node_value(node_base, "rel_max_lost_particles")); } // Get number of inactive batches @@ -364,7 +364,7 @@ void read_settings_xml() fatal_error("Number of particles must be greater than zero."); } else if (max_lost_particles <= 0) { fatal_error("Number of max lost particles must be greater than zero."); - } else if (relative_max_lost_particles <= 0.0 || relative_max_lost_particles >= 1.0) { + } else if (rel_max_lost_particles <= 0.0 || rel_max_lost_particles >= 1.0) { fatal_error("Relative max lost particles must be between zero and one."); } }