Merge pull request #2451 from gridley/refactor_write_source_bank

refactor particle source import/export
This commit is contained in:
Paul Romano 2023-04-26 06:36:50 -05:00 committed by GitHub
commit ec883f0fd8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 274 additions and 154 deletions

View file

@ -1,9 +1,7 @@
#ifndef OPENMC_FILE_UTILS_H
#define OPENMC_FILE_UTILS_H
#include <fstream> // for ifstream
#include <string>
#include <sys/stat.h>
namespace openmc {
@ -11,27 +9,18 @@ namespace openmc {
//! Determine if a path is a directory
//! \param[in] path Path to check
//! \return Whether the path is a directory
inline bool dir_exists(const std::string& path)
{
struct stat s;
if (stat(path.c_str(), &s) != 0)
return false;
return s.st_mode & S_IFDIR;
}
bool dir_exists(const std::string& path);
//! Determine if a file exists
//! \param[in] filename Path to file
//! \return Whether file exists
inline bool file_exists(const std::string& filename)
{
// rule out file being a path to a directory
if (dir_exists(filename))
return false;
bool file_exists(const std::string& filename);
std::ifstream s {filename};
return s.good();
}
// Gets the file extension of whatever string is passed in. This is defined as
// a sequence of strictly alphanumeric characters which follow the last period,
// i.e. at least one alphabet character is present, and zero or more numbers.
// If such a sequence of characters is not found, an empty string is returned.
std::string get_file_extension(const std::string& filename);
} // namespace openmc

View file

@ -4,6 +4,8 @@
#include "openmc/particle_data.h"
#include "openmc/vector.h"
#include <gsl/gsl-lite.hpp>
#include <string>
namespace openmc {
@ -26,11 +28,15 @@ vector<SourceSite> mcpl_source_sites(std::string path);
//! Write an MCPL source file
//
//! \param[in] filename Path to MCPL file
//! \param[in] surf_source_bank Whether to use the surface source bank
void write_mcpl_source_point(
const char* filename, bool surf_source_bank = false);
//! \param[in] filename Path to MCPL file
//! \param[in] source_bank Vector of SourceSites to write to file for this
//! MPI rank
//! \param[in] bank_indx Pointer to vector of site index ranges over all
//! MPI ranks. This can be computed by calling
//! calculate_parallel_index_vector on
//! source_bank.size().
void write_mcpl_source_point(const char* filename,
gsl::span<SourceSite> source_bank, vector<int64_t> const& bank_index);
} // namespace openmc
#endif // OPENMC_MCPL_INTERFACE_H

View file

@ -1,10 +1,14 @@
#ifndef OPENMC_MESSAGE_PASSING_H
#define OPENMC_MESSAGE_PASSING_H
#include <cstdint>
#ifdef OPENMC_MPI
#include <mpi.h>
#endif
#include "openmc/vector.h"
namespace openmc {
namespace mpi {
@ -17,6 +21,18 @@ extern MPI_Datatype source_site;
extern MPI_Comm intracomm;
#endif
// Calculates global indices of the bank particles
// across all ranks using a parallel scan. This is used to write
// the surface source file in parallel runs. It will probably
// be used in the future for other types of bank like particles
// in flight used to kick off transient simulations.
//
// More abstractly, this just takes a number from each MPI rank,
// and returns a vector which is the exclusive parallel scan across
// all of those numbers, having a length of the number of MPI ranks
// plus one.
vector<int64_t> calculate_parallel_index_vector(int64_t size);
} // namespace mpi
} // namespace openmc

View file

@ -115,6 +115,12 @@ public:
T* data() { return data_.get(); }
const T* data() const { return data_.get(); }
//! Classic iterators
T* begin() { return data_.get(); }
const T* cbegin() const { return data_.get(); }
T* end() { return data_.get() + size_; }
const T* cend() const { return data_.get() + size_; }
private:
//==========================================================================
// Data members

View file

@ -3,18 +3,44 @@
#include <cstdint>
#include <gsl/gsl-lite.hpp>
#include "hdf5.h"
#include "openmc/capi.h"
#include "openmc/particle.h"
#include "openmc/shared_array.h"
#include "openmc/vector.h"
namespace openmc {
void load_state_point();
vector<int64_t> calculate_surf_source_size();
void write_source_point(const char* filename, bool surf_source_bank = false);
void write_source_bank(hid_t group_id, bool surf_source_bank);
// By passing in a filename, source bank, and list of source indices
// on each MPI rank, this writes an HDF5 file which contains that
// information which can later be read in by read_source_bank
// (defined below). If you're writing code to write out a new kind
// of particle bank, this function is the one you want to use!
//
// For example, this is used to write both the surface source sites
// or fission source sites for eigenvalue continuation runs.
//
// This function ends up calling write_source_bank, and is responsible
// for opening the file to be written to and controlling whether the
// write is done in parallel (if compiled with parallel HDF5).
//
// bank_index is an exclusive parallel scan of the source_bank.size()
// 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);
// This appends a source bank specification to an HDF5 file
// that's already open. It is used internally by write_source_point.
void write_source_bank(hid_t group_id, gsl::span<SourceSite> source_bank,
const vector<int64_t>& bank_index);
void read_source_bank(
hid_t group_id, vector<SourceSite>& sites, bool distribute);
void write_tally_results_nr(hid_t file_id);