Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write surface source files per batch #3124

Merged
merged 24 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
abf9b6a
surface sourde per batch
zoeprieto Aug 19, 2024
4c3197a
surface source write only in active batchs for eigenvalue simulation
zoeprieto Aug 19, 2024
412eb3a
settings.surf_source_write with maximum particle files
zoeprieto Aug 19, 2024
8758a2f
default value of max_files added
zoeprieto Aug 19, 2024
3138746
format fix
zoeprieto Aug 19, 2024
c010270
info particle per surface file batch
zoeprieto Aug 23, 2024
29f2aa7
update messege
zoeprieto Aug 23, 2024
201ca7f
option to split source particle list per batch
zoeprieto Sep 10, 2024
b108ec7
format fix
zoeprieto Sep 10, 2024
4ba4c75
surface source batch and write message
zoeprieto Sep 12, 2024
9efee7f
suggested changes
zoeprieto Sep 13, 2024
242a320
message with number of particles
zoeprieto Sep 13, 2024
3c8f500
update test
zoeprieto Sep 13, 2024
2190220
suggested changes
zoeprieto Sep 13, 2024
a05b6fa
update settings.py
zoeprieto Sep 13, 2024
a52e61d
update documentation
zoeprieto Sep 16, 2024
8a93adc
unit test added and suggested changes
zoeprieto Sep 16, 2024
9ed9c08
Update docs/source/io_formats/settings.rst
zoeprieto Sep 17, 2024
177cb8c
option to write surface source file when maximum particle count is re…
zoeprieto Sep 26, 2024
6f8d653
change with clang format
zoeprieto Sep 26, 2024
4cdc3e9
Rename max_surf_files -> max_source_files
paulromano Oct 3, 2024
67a78b8
Variable name change, simplify mcpl/h5 source point calls
paulromano Oct 3, 2024
c44f1fc
Remove Python binding to current_surface_file
paulromano Oct 3, 2024
9e9335d
Rename current_source_file -> ssw_current_file
paulromano Oct 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/source/io_formats/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,15 @@ attributes/sub-elements:

*Default*: None

:max_source_files:
An integer value indicating the number of surface source files to be written
containing the maximum number of particles each. The surface source bank
will be cleared in simulation memory each time a surface source file is
written. By default a ``surface_source.h5`` file will be created when the
maximum number of saved particles is reached.

*Default*: 1

:mcpl:
An optional boolean which indicates if the banked particles should be
written to a file in the MCPL_-format instead of the native HDF5-based
Expand Down
11 changes: 11 additions & 0 deletions docs/source/usersguide/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,17 @@ or particles going to a cell::
.. note:: The ``cell``, ``cellfrom`` and ``cellto`` attributes cannot be
used simultaneously.

To generate more than one surface source files when the maximum number of stored
particles is reached, ``max_source_files`` is available. The surface source bank
will be cleared in simulation memory each time a surface source file is written.
As an example, to write a maximum of three surface source files:::

settings.surf_source_write = {
'surfaces_ids': [1, 2, 3],
'max_particles': 10000,
'max_source_files': 3
}

.. _compiled_source:

Compiled Sources
Expand Down
15 changes: 9 additions & 6 deletions include/openmc/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,17 @@ extern std::unordered_set<int>
statepoint_batch; //!< Batches when state should be written
extern std::unordered_set<int>
source_write_surf_id; //!< Surface ids where sources will be written

extern int
max_history_splits; //!< maximum number of particle splits for weight windows
extern int64_t max_surface_particles; //!< maximum number of particles to be
//!< banked on surfaces per process
extern int64_t ssw_cell_id; //!< Cell id for the surface source
//!< write setting
extern SSWCellType ssw_cell_type; //!< Type of option for the cell
//!< argument of surface source write
extern int64_t ssw_max_particles; //!< maximum number of particles to be
//!< banked on surfaces per process
extern int64_t ssw_max_files; //!< maximum number of surface source files
//!< to be created
extern int64_t ssw_cell_id; //!< Cell id for the surface source
//!< write setting
extern SSWCellType ssw_cell_type; //!< Type of option for the cell
//!< argument of surface source write
extern TemperatureMethod
temperature_method; //!< method for choosing temperatures
extern double
Expand Down
1 change: 1 addition & 0 deletions include/openmc/simulation.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ extern "C" int n_lost_particles; //!< cumulative number of lost particles
extern "C" bool need_depletion_rx; //!< need to calculate depletion rx?
extern "C" int restart_batch; //!< batch at which a restart job resumed
extern "C" bool satisfy_triggers; //!< have tally triggers been satisfied?
extern int ssw_current_file; //!< current surface source file
extern "C" int total_gen; //!< total number of generations simulated
extern double total_weight; //!< Total source weight in a batch
extern int64_t work_per_rank; //!< number of particles per MPI rank
Expand Down
8 changes: 6 additions & 2 deletions include/openmc/state_point.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define OPENMC_STATE_POINT_H

#include <cstdint>
#include <string>

#include <gsl/gsl-lite.hpp>

Expand Down Expand Up @@ -33,8 +34,11 @@ void load_state_point();
// values on each rank, used to create global indexing. This vector
// can be created by calling calculate_parallel_index_vector on
// source_bank.size() if such a vector is not already available.
void write_source_point(const char* filename, gsl::span<SourceSite> source_bank,
const vector<int64_t>& bank_index);
void write_h5_source_point(const char* filename,
gsl::span<SourceSite> source_bank, const vector<int64_t>& bank_index);

void write_source_point(std::string, gsl::span<SourceSite> source_bank,
const vector<int64_t>& bank_index, bool use_mcpl);

// This appends a source bank specification to an HDF5 file
// that's already open. It is used internally by write_source_point.
Expand Down
13 changes: 8 additions & 5 deletions openmc/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ class Settings:
banked (int)
:max_particles: Maximum number of particles to be banked on surfaces per
process (int)
:max_source_files: Maximum number of surface source files to be created (int)
:mcpl: Output in the form of an MCPL-file (bool)
:cell: Cell ID used to determine if particles crossing identified
surfaces are to be banked. Particles coming from or going to this
Expand Down Expand Up @@ -714,19 +715,21 @@ def surf_source_write(self, surf_source_write: dict):
cv.check_value(
"surface source writing key",
key,
("surface_ids", "max_particles", "mcpl", "cell", "cellfrom", "cellto"),
("surface_ids", "max_particles", "max_source_files", "mcpl", "cell", "cellfrom", "cellto"),
)
if key == "surface_ids":
cv.check_type(
"surface ids for source banking", value, Iterable, Integral
)
for surf_id in value:
cv.check_greater_than("surface id for source banking", surf_id, 0)

elif key == "mcpl":
cv.check_type("write to an MCPL-format file", value, bool)
elif key in ("max_particles", "cell", "cellfrom", "cellto"):
elif key in ("max_particles", "max_source_files", "cell", "cellfrom", "cellto"):
name = {
"max_particles": "maximum particle banks on surfaces per process",
"max_source_files": "maximun surface source files to be written",
"cell": "Cell ID for source banking (from or to)",
"cellfrom": "Cell ID for source banking (from only)",
"cellto": "Cell ID for source banking (to only)",
Expand Down Expand Up @@ -1243,7 +1246,7 @@ def _create_surf_source_write_subelement(self, root):
if "mcpl" in self._surf_source_write:
subelement = ET.SubElement(element, "mcpl")
subelement.text = str(self._surf_source_write["mcpl"]).lower()
for key in ("max_particles", "cell", "cellfrom", "cellto"):
for key in ("max_particles", "max_source_files", "cell", "cellfrom", "cellto"):
if key in self._surf_source_write:
subelement = ET.SubElement(element, key)
subelement.text = str(self._surf_source_write[key])
Expand Down Expand Up @@ -1642,14 +1645,14 @@ def _surf_source_write_from_xml_element(self, root):
elem = root.find('surf_source_write')
if elem is None:
return
for key in ('surface_ids', 'max_particles', 'mcpl', 'cell', 'cellto', 'cellfrom'):
for key in ('surface_ids', 'max_particles', 'max_source_files', 'mcpl', 'cell', 'cellto', 'cellfrom'):
value = get_text(elem, key)
if value is not None:
if key == 'surface_ids':
value = [int(x) for x in value.split()]
elif key == 'mcpl':
value = value in ('true', '1')
elif key in ('max_particles', 'cell', 'cellfrom', 'cellto'):
elif key in ('max_particles', 'max_source_files', 'cell', 'cellfrom', 'cellto'):
value = int(value)
self.surf_source_write[key] = value

Expand Down
5 changes: 5 additions & 0 deletions src/finalize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ int openmc_finalize()
settings::source_latest = false;
settings::source_separate = false;
settings::source_write = true;
settings::ssw_cell_id = C_NONE;
settings::ssw_cell_type = SSWCellType::None;
settings::ssw_max_particles = 0;
settings::ssw_max_files = 1;
settings::survival_biasing = false;
settings::temperature_default = 293.6;
settings::temperature_method = TemperatureMethod::NEAREST;
Expand All @@ -141,6 +145,7 @@ int openmc_finalize()

simulation::keff = 1.0;
simulation::need_depletion_rx = false;
simulation::ssw_current_file = 1;
simulation::total_gen = 0;

simulation::entropy_mesh = nullptr;
Expand Down
13 changes: 10 additions & 3 deletions src/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ SolverType solver_type {SolverType::MONTE_CARLO};
std::unordered_set<int> sourcepoint_batch;
std::unordered_set<int> statepoint_batch;
std::unordered_set<int> source_write_surf_id;
int64_t max_surface_particles;
int64_t ssw_max_particles;
int64_t ssw_max_files;
int64_t ssw_cell_id {C_NONE};
SSWCellType ssw_cell_type {SSWCellType::None};
TemperatureMethod temperature_method {TemperatureMethod::NEAREST};
Expand Down Expand Up @@ -785,14 +786,20 @@ void read_settings_xml(pugi::xml_node root)

// Get maximum number of particles to be banked per surface
if (check_for_node(node_ssw, "max_particles")) {
max_surface_particles =
std::stoll(get_node_value(node_ssw, "max_particles"));
ssw_max_particles = std::stoll(get_node_value(node_ssw, "max_particles"));
} else {
fatal_error("A maximum number of particles needs to be specified "
"using the 'max_particles' parameter to store surface "
"source points.");
}

// Get maximum number of surface source files to be created
if (check_for_node(node_ssw, "max_source_files")) {
ssw_max_files = std::stoll(get_node_value(node_ssw, "max_source_files"));
} else {
ssw_max_files = 1;
}

if (check_for_node(node_ssw, "mcpl")) {
surf_mcpl_write = get_node_value_bool(node_ssw, "mcpl");

Expand Down
60 changes: 34 additions & 26 deletions src/simulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ int openmc_simulation_init()
// Reset global variables -- this is done before loading state point (as that
// will potentially populate k_generation and entropy)
simulation::current_batch = 0;
simulation::ssw_current_file = 1;
simulation::k_generation.clear();
simulation::entropy.clear();
openmc_reset();
Expand Down Expand Up @@ -308,6 +309,7 @@ int n_lost_particles {0};
bool need_depletion_rx {false};
int restart_batch;
bool satisfy_triggers {false};
int ssw_current_file;
int total_gen {0};
double total_weight;
int64_t work_per_rank;
Expand Down Expand Up @@ -337,15 +339,14 @@ void allocate_banks()

if (settings::surf_source_write) {
// Allocate surface source bank
simulation::surf_source_bank.reserve(settings::max_surface_particles);
simulation::surf_source_bank.reserve(settings::ssw_max_particles);
}
}

void initialize_batch()
{
// Increment current batch
++simulation::current_batch;

if (settings::run_mode == RunMode::FIXED_SOURCE) {
if (settings::solver_type == SolverType::RANDOM_RAY &&
simulation::current_batch < settings::n_inactive + 1) {
Expand Down Expand Up @@ -439,42 +440,49 @@ void finalize_batch()
std::string source_point_filename = fmt::format("{0}source.{1:0{2}}",
settings::path_output, simulation::current_batch, w);
gsl::span<SourceSite> bankspan(simulation::source_bank);
if (settings::source_mcpl_write) {
write_mcpl_source_point(
source_point_filename.c_str(), bankspan, simulation::work_index);
} else {
write_source_point(
source_point_filename.c_str(), bankspan, simulation::work_index);
}
write_source_point(source_point_filename, bankspan,
simulation::work_index, settings::source_mcpl_write);
}

// Write a continously-overwritten source point if requested.
if (settings::source_latest) {

// note: correct file extension appended automatically
auto filename = settings::path_output + "source";
gsl::span<SourceSite> bankspan(simulation::source_bank);
if (settings::source_mcpl_write) {
write_mcpl_source_point(
filename.c_str(), bankspan, simulation::work_index);
} else {
write_source_point(filename.c_str(), bankspan, simulation::work_index);
}
write_source_point(filename.c_str(), bankspan, simulation::work_index,
settings::source_mcpl_write);
}
}

// Write out surface source if requested.
if (settings::surf_source_write &&
simulation::current_batch == settings::n_batches) {
auto filename = settings::path_output + "surface_source";
auto surf_work_index =
mpi::calculate_parallel_index_vector(simulation::surf_source_bank.size());
gsl::span<SourceSite> surfbankspan(simulation::surf_source_bank.begin(),
simulation::surf_source_bank.size());
if (settings::surf_mcpl_write) {
write_mcpl_source_point(filename.c_str(), surfbankspan, surf_work_index);
} else {
write_source_point(filename.c_str(), surfbankspan, surf_work_index);
simulation::ssw_current_file <= settings::ssw_max_files) {
bool last_batch = (simulation::current_batch == settings::n_batches);
if (simulation::surf_source_bank.full() || last_batch) {
// Determine appropriate filename
auto filename = fmt::format("{}surface_source.{}", settings::path_output,
simulation::current_batch);
if (settings::ssw_max_files == 1 ||
(simulation::ssw_current_file == 1 && last_batch)) {
filename = settings::path_output + "surface_source";
}

// Get span of source bank and calculate parallel index vector
auto surf_work_index = mpi::calculate_parallel_index_vector(
simulation::surf_source_bank.size());
gsl::span<SourceSite> surfbankspan(simulation::surf_source_bank.begin(),
simulation::surf_source_bank.size());

// Write surface source file
write_source_point(
filename, surfbankspan, surf_work_index, settings::surf_mcpl_write);

// Reset surface source bank and increment counter
simulation::surf_source_bank.clear();
if (!last_batch && settings::ssw_max_files >= 1) {
simulation::surf_source_bank.reserve(settings::ssw_max_particles);
}
++simulation::ssw_current_file;
}
}
}
Expand Down
20 changes: 18 additions & 2 deletions src/state_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "openmc/error.h"
#include "openmc/file_utils.h"
#include "openmc/hdf5_interface.h"
#include "openmc/mcpl_interface.h"
#include "openmc/mesh.h"
#include "openmc/message_passing.h"
#include "openmc/mgxs_interface.h"
Expand Down Expand Up @@ -568,8 +569,23 @@ hid_t h5banktype()
return banktype;
}

void write_source_point(const char* filename, gsl::span<SourceSite> source_bank,
const vector<int64_t>& bank_index)
void write_source_point(std::string filename, gsl::span<SourceSite> source_bank,
const vector<int64_t>& bank_index, bool use_mcpl)
{
std::string ext = use_mcpl ? "mcpl" : "h5";
write_message("Creating source file {}.{} with {} particles ...", filename,
ext, source_bank.size(), 5);

// Dispatch to appropriate function based on file type
if (use_mcpl) {
write_mcpl_source_point(filename.c_str(), source_bank, bank_index);
} else {
write_h5_source_point(filename.c_str(), source_bank, bank_index);
}
}

void write_h5_source_point(const char* filename,
gsl::span<SourceSite> source_bank, const vector<int64_t>& bank_index)
{
// When using parallel HDF5, the file is written to collectively by all
// processes. With MPI-only, the file is opened and written by the master
Expand Down
3 changes: 1 addition & 2 deletions tests/regression_tests/dagmc/legacy/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,4 @@ def test_surf_source(model):

def test_dagmc(model):
harness = PyAPITestHarness('statepoint.5.h5', model)
harness.main()

harness.main()
2 changes: 1 addition & 1 deletion tests/regression_tests/surface_source/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,4 @@ def test_surface_source_read(model):
harness = SurfaceSourceTestHarness('statepoint.10.h5',
model,
'inputs_true_read.dat')
harness.main()
harness.main()
2 changes: 1 addition & 1 deletion tests/regression_tests/surface_source_write/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1129,4 +1129,4 @@ def test_surface_source_cell_dagmc(
harness = SurfaceSourceWriteTestHarness(
"statepoint.5.h5", model=model, workdir=folder
)
harness.main()
harness.main()
Loading