From debc085cf692cb4f2a8a9585d0acfe4a7b06bfb9 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 22 Jun 2022 22:50:07 +0200 Subject: [PATCH 001/146] add placeholder skeleton for MCPL-input --- include/openmc/source.h | 19 +++++++++++++++++++ src/source.cpp | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/openmc/source.h b/include/openmc/source.h index 18fddc6899..cadbfe93bb 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -100,6 +100,25 @@ private: vector sites_; //!< Source sites from a file }; +//============================================================================== +// MCPL-file input source +//============================================================================== +class MCPLFileSource : public Source { +public: + // Constructors, destructors + MCPLFileSource(std::string path); + ~MCPLFileSource(); + + // Defer implementation to custom source library + SourceSite sample(uint64_t* seed) const override + +private: + vector sites_; //! Date: Thu, 23 Jun 2022 11:34:53 +0200 Subject: [PATCH 002/146] include mcpl header --- src/source.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/source.cpp b/src/source.cpp index cd8b5e5743..5e26fa0a8d 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -31,6 +31,10 @@ #include "openmc/state_point.h" #include "openmc/xml_interface.h" +#ifdef HAS_MCPL +#include +#endif + namespace openmc { //============================================================================== From 5d74af4bf766ab732d320081be47b9c4f78303fe Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Thu, 23 Jun 2022 11:35:46 +0200 Subject: [PATCH 003/146] declarations of MCPL-internals --- include/openmc/source.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/include/openmc/source.h b/include/openmc/source.h index cadbfe93bb..69dd47eae9 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -109,11 +109,20 @@ public: MCPLFileSource(std::string path); ~MCPLFileSource(); - // Defer implementation to custom source library - SourceSite sample(uint64_t* seed) const override + // Properties + ParticleType particle_type() const { return particle_; } + + //! Sample from the external source distribution + //! \param[inout] seed Pseudorandom seed pointer + //! \return Site read from MCPL-file + SourceSite sample(uint64_t* seed) const override; private: + ParticleType particle_ {ParticleType::neutron}; //!< Type of particle emitted vector sites_; //! Date: Thu, 23 Jun 2022 11:37:05 +0200 Subject: [PATCH 004/146] internals of sample and constructor --- src/source.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 5e26fa0a8d..231f355fc2 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -337,7 +337,7 @@ CustomSourceWrapper::~CustomSourceWrapper() } //=========================================================================== -// Read an MCPL-file +// Read particles from an MCPL-file //=========================================================================== MCPLFileSource::MCPLFileSource(std::string path) { @@ -348,12 +348,55 @@ MCPLFileSource::MCPLFileSource(std::string path) // Read the source from a binary file instead of sampling from some // assumed source distribution - write_message(6, "Reading source file from {}...", path); + write_message(6, "Reading mcpl source file from {}",path); // Open the mcpl file - id_t file_id = mcpl_open(path.c_str) - + mcpl_file = mcpl_open(path.c_str); + //do checks on the mcpl_file to see if particles are many enough. + // should model this on the example source shown in the docs. + uint64_t nparticles=mcpl_hdr_nparticles(mcpl_file); + +} + +MCPLFileSource::~MCPLFilsSource(){ + mcpl_close_file(mcpl_file); +} + +SourceSite MCPLFileSource::sample(uint64_t *seed){ + SourceSite omc_particle; + mcpl_particle *mcpl_particle; + //extract particle from mcpl-file + mcpl_particle=mcpl_reazd(mcplfile); + // check if it is a neutron or a photon. otherwise skip + while ( mcpl_particle->pdgcode!=2112 && mcpl_particle->pdgcode!=22 ) + { + mcpl_particle(mcpl_read(mcplfile); + //check for file exhaustion + } + + if(mcpl_particle->pdgcode=2112) { + omc_particle_=ParticleType::neutron; + } else { + omc_particle_=Particletype::photon; + } + + //particle is good, convert to openmc-formalism + omc_particle.r.x=mcpl_particle.x; + omc_particle.r.y=mcpl_particle.y; + omc_particle.r.z=mcpl_particle.z; + + omc_particle.u.x=mcpl_particle->direction[0]; + omc_particle.u.y=mcpl_particle->direction[1]; + omc_particle.u.z=mcpl_particle->direction[2]; + + //mcpl stores particles in MeV + omc_particle.E=mcpl_particle->ekin*1e6; + + omc_particle.t=mcpl_particle->time*1e-3; + omc_particle.wgt=mcpl_particle->weight; + omc_particle.delayed_group=0; + return omc_particle; } From 909b96f31e90a8a8ce40e890b3f4e73ee516466b Mon Sep 17 00:00:00 2001 From: erkn Date: Mon, 27 Jun 2022 23:25:35 +0200 Subject: [PATCH 005/146] (wip): skeleton for input only test --- .../regression_tests/source_mcpl_file/test.py | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 tests/regression_tests/source_mcpl_file/test.py diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py new file mode 100644 index 0000000000..5a6a87d878 --- /dev/null +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -0,0 +1,52 @@ +import pathlib as pl +import os +import shutil +import subprocess +import textwrap + +import openmc +import pytest + +from tests.testing_harness import TestHarness + +def model(): + subprocess.run(['gcc','-o gen_dummt_mcpl.out','-lm','-lmcpl','gen_dummy_mcpl.c'] ) + subprocess.run(['./gen_dummy_mcpl.out']) + +class SourceMCPLFileTestHarness(TestHarness): + def execute_test(self): + """Run OpenMC with the appropriate arguments and check the outputs.""" + try: + self._create_input() + self._run_openmc() + self._test_output_created() + results = self._get_results() + self._write_results(results) + self._compare_results() + finally: + self._cleanup() + + def update_results(self): + """Update the results_true using the current version of OpenMC.""" + try: + self._create_input() + self._run_openmc() + self._test_output_created() + results = self._get_results() + self._write_results(results) + self._overwrite_results() + finally: + self._cleanup() + + def _test_output_created(self): + """Check that the output files were created""" + stat epoint = glob.glob(os.path.join(os.getcwd(), self._sp_name)) + assert len(statepoint) == 1, 'Either multiple or no statepoint files ' \ + 'exist.' + assert statepoint[0].endswith('h5'), \ + 'statepoint file does not end with h5.' + +def test_mcpl_source_file(): + harness = SourceMCPLFileTestHarness('statepoint.10.h5') + harness.main() + From 3c30dbba5b643e8464eb9b45a8667e08bf6ad44b Mon Sep 17 00:00:00 2001 From: erkn Date: Mon, 27 Jun 2022 23:26:01 +0200 Subject: [PATCH 006/146] c-prog to generate a dummy mcpl --- .../source_mcpl_file/gen_dummy_mcpl.c | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c diff --git a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c new file mode 100644 index 0000000000..7b5a933f18 --- /dev/null +++ b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include + +const int batches=10; +const int particles=10000; + +double rand01(){ + double r=rand()/((double) RAND_MAX); + return r; +} + + +int main(int argc, char **argv){ + char outfilename[128]; + snprintf(outfilename,127,"source.%d.mcpl",batches); + + /*generate an mcpl_header_of sorts*/ + mcpl_outfile_t outfile=mcpl_create_outfile(outfilename); + mcpl_particle_t *particle, Particle; + + char line[256]; + snprintf(line,255,"gen_dummy_mcpl.c"); + mcpl_hdr_set_srcname(outfile,line); + mcpl_enable_universal_pdgcode(outfile,2112);/*all particles are neutrons*/ + snprintf(line,255,"Dummy MCPL-file for testing OpenMC mcpl input"); + mcpl_hdr_add_comment(outfile,line); + + /*also add the instrument file and the command line as blobs*/ + FILE *fp; + if( (fp=fopen("gen_dummy_mcpl.c","rb"))!=NULL){ + unsigned char *buffer; + int size,status; + /*find the file size by seeking to end, "tell" the position, and then go back again*/ + fseek(fp, 0L, SEEK_END); + size = ftell(fp); // get current file pointer + fseek(fp, 0L, SEEK_SET); // seek back to beginning of file + if ( size && (buffer=malloc(size))!=NULL){ + if (size!=(fread(buffer,1,size,fp))){ + fprintf(stderr,"Warning: c source generator file not read cleanly\n"); + } + mcpl_hdr_add_data(outfile, "mcpl_point_source_file_generator", size, buffer); + free(buffer); + } + fclose(fp); + } else { + fprintf(stderr,"Warning: could not open c source generator file, hence not embedded.\n"); + } + + + /*the main particle loop*/ + particle=&Particle; + int i; + for (i=0;iposition[0]=0; + particle->position[1]=0; + particle->position[2]=0; + + /*generate a random direction on unit sphere*/ + double nrm=2.0; + double vx,vy,vz; + int iter=0; + do { + if(iter>100){ + printf("warning: exceeed max random vector attempts: at loop %d -> %g %d\n",i,nrm,iter); + } + vx=rand01()*2.0-1.0; + vy=rand01()*2.0-1.0; + vz=rand01()*2.0-1.0; + nrm=(vx*vx + vy*vy + vz*vz); + iter++; + } while (nrm>1.0); + vx/=sqrt(nrm); + vy/=sqrt(nrm); + vz/=sqrt(nrm); + particle->direction[0]=vx; + particle->direction[1]=vy; + particle->direction[2]=vz; + + /*generate the kinetic energy (in MeV) of the particle*/ + particle->ekin=1e-3; + + /*set time=0*/ + particle->time=0; + /*set weight*/ + particle->weight=1; + + particle->userflags=0; + mcpl_add_particle(outfile,particle); + } + mcpl_closeandgzip_outfile(outfile); +} From bc797c4df83b906bebe454cd1c9d7a17bd52c49c Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 5 Jul 2022 01:30:07 +0200 Subject: [PATCH 007/146] don't zip the output-file --- .../source_mcpl_file/gen_dummy_mcpl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c index 7b5a933f18..f35a07fc44 100644 --- a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c +++ b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c @@ -54,20 +54,20 @@ int main(int argc, char **argv){ int i; for (i=0;iposition[0]=0; particle->position[1]=0; particle->position[2]=0; - + /*generate a random direction on unit sphere*/ double nrm=2.0; double vx,vy,vz; int iter=0; do { if(iter>100){ - printf("warning: exceeed max random vector attempts: at loop %d -> %g %d\n",i,nrm,iter); + printf("Warning: Exceeded max random vector attempts: at loop %d -> %g %d\n",i,nrm,iter); } vx=rand01()*2.0-1.0; vy=rand01()*2.0-1.0; @@ -82,9 +82,9 @@ int main(int argc, char **argv){ particle->direction[1]=vy; particle->direction[2]=vz; - /*generate the kinetic energy (in MeV) of the particle*/ + /*generate the kinetic energy (in MeV) of the particle*/ particle->ekin=1e-3; - + /*set time=0*/ particle->time=0; /*set weight*/ @@ -93,5 +93,5 @@ int main(int argc, char **argv){ particle->userflags=0; mcpl_add_particle(outfile,particle); } - mcpl_closeandgzip_outfile(outfile); + mcpl_close_outfile(outfile); } From 80e69b2e0856d5af025087283964fd5a03e20339 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 5 Jul 2022 01:53:14 +0200 Subject: [PATCH 008/146] now compiles fine if mcpl is indeed installed --- .../regression_tests/source_mcpl_file/test.py | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py index 5a6a87d878..0adf67f1aa 100644 --- a/tests/regression_tests/source_mcpl_file/test.py +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -3,16 +3,13 @@ import os import shutil import subprocess import textwrap - +import glob import openmc import pytest from tests.testing_harness import TestHarness -def model(): - subprocess.run(['gcc','-o gen_dummt_mcpl.out','-lm','-lmcpl','gen_dummy_mcpl.c'] ) - subprocess.run(['./gen_dummy_mcpl.out']) - + class SourceMCPLFileTestHarness(TestHarness): def execute_test(self): """Run OpenMC with the appropriate arguments and check the outputs.""" @@ -26,6 +23,10 @@ class SourceMCPLFileTestHarness(TestHarness): finally: self._cleanup() + def _create_input(self): + subprocess.run(['gcc','-o','gen_dummy_mcpl.out','gen_dummy_mcpl.c','-lm','-lmcpl']) + subprocess.run(['./gen_dummy_mcpl.out']) + def update_results(self): """Update the results_true using the current version of OpenMC.""" try: @@ -40,13 +41,19 @@ class SourceMCPLFileTestHarness(TestHarness): def _test_output_created(self): """Check that the output files were created""" - stat epoint = glob.glob(os.path.join(os.getcwd(), self._sp_name)) + statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name)) assert len(statepoint) == 1, 'Either multiple or no statepoint files ' \ 'exist.' assert statepoint[0].endswith('h5'), \ 'statepoint file does not end with h5.' + def _cleanup(self): + super()._cleanup() + source_mcpl=glob.glob(os.path.join(os.getcwd(),'source*.mcpl')) + for f in source_mcpl: + if (os.path.exists(f)): + os.remove(f) + def test_mcpl_source_file(): harness = SourceMCPLFileTestHarness('statepoint.10.h5') harness.main() - From 6d352aa55c8fab8bf427bceeb165c6b870d94e53 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 22 Jun 2022 22:50:07 +0200 Subject: [PATCH 009/146] add placeholder skeleton for MCPL-input --- include/openmc/source.h | 19 +++++++++++++++++++ src/source.cpp | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/openmc/source.h b/include/openmc/source.h index 18fddc6899..cadbfe93bb 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -100,6 +100,25 @@ private: vector sites_; //!< Source sites from a file }; +//============================================================================== +// MCPL-file input source +//============================================================================== +class MCPLFileSource : public Source { +public: + // Constructors, destructors + MCPLFileSource(std::string path); + ~MCPLFileSource(); + + // Defer implementation to custom source library + SourceSite sample(uint64_t* seed) const override + +private: + vector sites_; //! Date: Thu, 23 Jun 2022 11:34:53 +0200 Subject: [PATCH 010/146] include mcpl header --- src/source.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/source.cpp b/src/source.cpp index cd8b5e5743..5e26fa0a8d 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -31,6 +31,10 @@ #include "openmc/state_point.h" #include "openmc/xml_interface.h" +#ifdef HAS_MCPL +#include +#endif + namespace openmc { //============================================================================== From c43989af9c222b20413ee3b892feaf20919b8707 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Thu, 23 Jun 2022 11:35:46 +0200 Subject: [PATCH 011/146] declarations of MCPL-internals --- include/openmc/source.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/include/openmc/source.h b/include/openmc/source.h index cadbfe93bb..69dd47eae9 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -109,11 +109,20 @@ public: MCPLFileSource(std::string path); ~MCPLFileSource(); - // Defer implementation to custom source library - SourceSite sample(uint64_t* seed) const override + // Properties + ParticleType particle_type() const { return particle_; } + + //! Sample from the external source distribution + //! \param[inout] seed Pseudorandom seed pointer + //! \return Site read from MCPL-file + SourceSite sample(uint64_t* seed) const override; private: + ParticleType particle_ {ParticleType::neutron}; //!< Type of particle emitted vector sites_; //! Date: Thu, 23 Jun 2022 11:37:05 +0200 Subject: [PATCH 012/146] internals of sample and constructor --- src/source.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 5e26fa0a8d..231f355fc2 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -337,7 +337,7 @@ CustomSourceWrapper::~CustomSourceWrapper() } //=========================================================================== -// Read an MCPL-file +// Read particles from an MCPL-file //=========================================================================== MCPLFileSource::MCPLFileSource(std::string path) { @@ -348,12 +348,55 @@ MCPLFileSource::MCPLFileSource(std::string path) // Read the source from a binary file instead of sampling from some // assumed source distribution - write_message(6, "Reading source file from {}...", path); + write_message(6, "Reading mcpl source file from {}",path); // Open the mcpl file - id_t file_id = mcpl_open(path.c_str) - + mcpl_file = mcpl_open(path.c_str); + //do checks on the mcpl_file to see if particles are many enough. + // should model this on the example source shown in the docs. + uint64_t nparticles=mcpl_hdr_nparticles(mcpl_file); + +} + +MCPLFileSource::~MCPLFilsSource(){ + mcpl_close_file(mcpl_file); +} + +SourceSite MCPLFileSource::sample(uint64_t *seed){ + SourceSite omc_particle; + mcpl_particle *mcpl_particle; + //extract particle from mcpl-file + mcpl_particle=mcpl_reazd(mcplfile); + // check if it is a neutron or a photon. otherwise skip + while ( mcpl_particle->pdgcode!=2112 && mcpl_particle->pdgcode!=22 ) + { + mcpl_particle(mcpl_read(mcplfile); + //check for file exhaustion + } + + if(mcpl_particle->pdgcode=2112) { + omc_particle_=ParticleType::neutron; + } else { + omc_particle_=Particletype::photon; + } + + //particle is good, convert to openmc-formalism + omc_particle.r.x=mcpl_particle.x; + omc_particle.r.y=mcpl_particle.y; + omc_particle.r.z=mcpl_particle.z; + + omc_particle.u.x=mcpl_particle->direction[0]; + omc_particle.u.y=mcpl_particle->direction[1]; + omc_particle.u.z=mcpl_particle->direction[2]; + + //mcpl stores particles in MeV + omc_particle.E=mcpl_particle->ekin*1e6; + + omc_particle.t=mcpl_particle->time*1e-3; + omc_particle.wgt=mcpl_particle->weight; + omc_particle.delayed_group=0; + return omc_particle; } From 103c6ffa0330ab1313489a27b2d9504cfb30f7ba Mon Sep 17 00:00:00 2001 From: erkn Date: Mon, 27 Jun 2022 23:25:35 +0200 Subject: [PATCH 013/146] (wip): skeleton for input only test --- .../regression_tests/source_mcpl_file/test.py | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 tests/regression_tests/source_mcpl_file/test.py diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py new file mode 100644 index 0000000000..5a6a87d878 --- /dev/null +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -0,0 +1,52 @@ +import pathlib as pl +import os +import shutil +import subprocess +import textwrap + +import openmc +import pytest + +from tests.testing_harness import TestHarness + +def model(): + subprocess.run(['gcc','-o gen_dummt_mcpl.out','-lm','-lmcpl','gen_dummy_mcpl.c'] ) + subprocess.run(['./gen_dummy_mcpl.out']) + +class SourceMCPLFileTestHarness(TestHarness): + def execute_test(self): + """Run OpenMC with the appropriate arguments and check the outputs.""" + try: + self._create_input() + self._run_openmc() + self._test_output_created() + results = self._get_results() + self._write_results(results) + self._compare_results() + finally: + self._cleanup() + + def update_results(self): + """Update the results_true using the current version of OpenMC.""" + try: + self._create_input() + self._run_openmc() + self._test_output_created() + results = self._get_results() + self._write_results(results) + self._overwrite_results() + finally: + self._cleanup() + + def _test_output_created(self): + """Check that the output files were created""" + stat epoint = glob.glob(os.path.join(os.getcwd(), self._sp_name)) + assert len(statepoint) == 1, 'Either multiple or no statepoint files ' \ + 'exist.' + assert statepoint[0].endswith('h5'), \ + 'statepoint file does not end with h5.' + +def test_mcpl_source_file(): + harness = SourceMCPLFileTestHarness('statepoint.10.h5') + harness.main() + From 73fb335350bb3b6ed0199e9c3cc4ee19d73b163e Mon Sep 17 00:00:00 2001 From: erkn Date: Mon, 27 Jun 2022 23:26:01 +0200 Subject: [PATCH 014/146] c-prog to generate a dummy mcpl --- .../source_mcpl_file/gen_dummy_mcpl.c | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c diff --git a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c new file mode 100644 index 0000000000..7b5a933f18 --- /dev/null +++ b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include + +const int batches=10; +const int particles=10000; + +double rand01(){ + double r=rand()/((double) RAND_MAX); + return r; +} + + +int main(int argc, char **argv){ + char outfilename[128]; + snprintf(outfilename,127,"source.%d.mcpl",batches); + + /*generate an mcpl_header_of sorts*/ + mcpl_outfile_t outfile=mcpl_create_outfile(outfilename); + mcpl_particle_t *particle, Particle; + + char line[256]; + snprintf(line,255,"gen_dummy_mcpl.c"); + mcpl_hdr_set_srcname(outfile,line); + mcpl_enable_universal_pdgcode(outfile,2112);/*all particles are neutrons*/ + snprintf(line,255,"Dummy MCPL-file for testing OpenMC mcpl input"); + mcpl_hdr_add_comment(outfile,line); + + /*also add the instrument file and the command line as blobs*/ + FILE *fp; + if( (fp=fopen("gen_dummy_mcpl.c","rb"))!=NULL){ + unsigned char *buffer; + int size,status; + /*find the file size by seeking to end, "tell" the position, and then go back again*/ + fseek(fp, 0L, SEEK_END); + size = ftell(fp); // get current file pointer + fseek(fp, 0L, SEEK_SET); // seek back to beginning of file + if ( size && (buffer=malloc(size))!=NULL){ + if (size!=(fread(buffer,1,size,fp))){ + fprintf(stderr,"Warning: c source generator file not read cleanly\n"); + } + mcpl_hdr_add_data(outfile, "mcpl_point_source_file_generator", size, buffer); + free(buffer); + } + fclose(fp); + } else { + fprintf(stderr,"Warning: could not open c source generator file, hence not embedded.\n"); + } + + + /*the main particle loop*/ + particle=&Particle; + int i; + for (i=0;iposition[0]=0; + particle->position[1]=0; + particle->position[2]=0; + + /*generate a random direction on unit sphere*/ + double nrm=2.0; + double vx,vy,vz; + int iter=0; + do { + if(iter>100){ + printf("warning: exceeed max random vector attempts: at loop %d -> %g %d\n",i,nrm,iter); + } + vx=rand01()*2.0-1.0; + vy=rand01()*2.0-1.0; + vz=rand01()*2.0-1.0; + nrm=(vx*vx + vy*vy + vz*vz); + iter++; + } while (nrm>1.0); + vx/=sqrt(nrm); + vy/=sqrt(nrm); + vz/=sqrt(nrm); + particle->direction[0]=vx; + particle->direction[1]=vy; + particle->direction[2]=vz; + + /*generate the kinetic energy (in MeV) of the particle*/ + particle->ekin=1e-3; + + /*set time=0*/ + particle->time=0; + /*set weight*/ + particle->weight=1; + + particle->userflags=0; + mcpl_add_particle(outfile,particle); + } + mcpl_closeandgzip_outfile(outfile); +} From c6c876d835fe2177426ee64f4ae8dc15d5e616f2 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 5 Jul 2022 01:30:07 +0200 Subject: [PATCH 015/146] don't zip the output-file --- .../source_mcpl_file/gen_dummy_mcpl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c index 7b5a933f18..f35a07fc44 100644 --- a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c +++ b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c @@ -54,20 +54,20 @@ int main(int argc, char **argv){ int i; for (i=0;iposition[0]=0; particle->position[1]=0; particle->position[2]=0; - + /*generate a random direction on unit sphere*/ double nrm=2.0; double vx,vy,vz; int iter=0; do { if(iter>100){ - printf("warning: exceeed max random vector attempts: at loop %d -> %g %d\n",i,nrm,iter); + printf("Warning: Exceeded max random vector attempts: at loop %d -> %g %d\n",i,nrm,iter); } vx=rand01()*2.0-1.0; vy=rand01()*2.0-1.0; @@ -82,9 +82,9 @@ int main(int argc, char **argv){ particle->direction[1]=vy; particle->direction[2]=vz; - /*generate the kinetic energy (in MeV) of the particle*/ + /*generate the kinetic energy (in MeV) of the particle*/ particle->ekin=1e-3; - + /*set time=0*/ particle->time=0; /*set weight*/ @@ -93,5 +93,5 @@ int main(int argc, char **argv){ particle->userflags=0; mcpl_add_particle(outfile,particle); } - mcpl_closeandgzip_outfile(outfile); + mcpl_close_outfile(outfile); } From 8719a539f9f8c9134ded079b2eec64c6cdf3aa82 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 5 Jul 2022 01:53:14 +0200 Subject: [PATCH 016/146] now compiles fine if mcpl is indeed installed --- .../regression_tests/source_mcpl_file/test.py | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py index 5a6a87d878..0adf67f1aa 100644 --- a/tests/regression_tests/source_mcpl_file/test.py +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -3,16 +3,13 @@ import os import shutil import subprocess import textwrap - +import glob import openmc import pytest from tests.testing_harness import TestHarness -def model(): - subprocess.run(['gcc','-o gen_dummt_mcpl.out','-lm','-lmcpl','gen_dummy_mcpl.c'] ) - subprocess.run(['./gen_dummy_mcpl.out']) - + class SourceMCPLFileTestHarness(TestHarness): def execute_test(self): """Run OpenMC with the appropriate arguments and check the outputs.""" @@ -26,6 +23,10 @@ class SourceMCPLFileTestHarness(TestHarness): finally: self._cleanup() + def _create_input(self): + subprocess.run(['gcc','-o','gen_dummy_mcpl.out','gen_dummy_mcpl.c','-lm','-lmcpl']) + subprocess.run(['./gen_dummy_mcpl.out']) + def update_results(self): """Update the results_true using the current version of OpenMC.""" try: @@ -40,13 +41,19 @@ class SourceMCPLFileTestHarness(TestHarness): def _test_output_created(self): """Check that the output files were created""" - stat epoint = glob.glob(os.path.join(os.getcwd(), self._sp_name)) + statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name)) assert len(statepoint) == 1, 'Either multiple or no statepoint files ' \ 'exist.' assert statepoint[0].endswith('h5'), \ 'statepoint file does not end with h5.' + def _cleanup(self): + super()._cleanup() + source_mcpl=glob.glob(os.path.join(os.getcwd(),'source*.mcpl')) + for f in source_mcpl: + if (os.path.exists(f)): + os.remove(f) + def test_mcpl_source_file(): harness = SourceMCPLFileTestHarness('statepoint.10.h5') harness.main() - From 0d1c346b5a12d2a452450b435a80cf4a2fbbe608 Mon Sep 17 00:00:00 2001 From: erkn Date: Sat, 9 Jul 2022 16:31:00 +0200 Subject: [PATCH 017/146] fix misprints --- src/source.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 231f355fc2..37e580b18d 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -345,7 +345,7 @@ MCPLFileSource::MCPLFileSource(std::string path) if (!file_exists(path)) { fatal_error(fmt::format("Source file '{}' does not exist.", path)); } - + // Read the source from a binary file instead of sampling from some // assumed source distribution write_message(6, "Reading mcpl source file from {}",path); @@ -367,7 +367,7 @@ SourceSite MCPLFileSource::sample(uint64_t *seed){ SourceSite omc_particle; mcpl_particle *mcpl_particle; //extract particle from mcpl-file - mcpl_particle=mcpl_reazd(mcplfile); + mcpl_particle=mcpl_read(mcplfile); // check if it is a neutron or a photon. otherwise skip while ( mcpl_particle->pdgcode!=2112 && mcpl_particle->pdgcode!=22 ) { @@ -375,9 +375,9 @@ SourceSite MCPLFileSource::sample(uint64_t *seed){ //check for file exhaustion } - if(mcpl_particle->pdgcode=2112) { + if(mcpl_particle->pdgcode==2112) { omc_particle_=ParticleType::neutron; - } else { + } else if (mcpl_particle->pdgcode==22){ omc_particle_=Particletype::photon; } From 7a6c69fbd5daefcca4b612affdbac6ecd46e9d32 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Mon, 11 Jul 2022 09:49:29 +0200 Subject: [PATCH 018/146] fix misprints --- src/source.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 231f355fc2..9ec1ff798c 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -367,7 +367,7 @@ SourceSite MCPLFileSource::sample(uint64_t *seed){ SourceSite omc_particle; mcpl_particle *mcpl_particle; //extract particle from mcpl-file - mcpl_particle=mcpl_reazd(mcplfile); + mcpl_particle=mcpl_read(mcplfile); // check if it is a neutron or a photon. otherwise skip while ( mcpl_particle->pdgcode!=2112 && mcpl_particle->pdgcode!=22 ) { @@ -375,9 +375,9 @@ SourceSite MCPLFileSource::sample(uint64_t *seed){ //check for file exhaustion } - if(mcpl_particle->pdgcode=2112) { + if(mcpl_particle->pdgcode==2112) { omc_particle_=ParticleType::neutron; - } else { + } else if (mcpl_particle->pdgcode==22){ omc_particle_=Particletype::photon; } @@ -390,9 +390,9 @@ SourceSite MCPLFileSource::sample(uint64_t *seed){ omc_particle.u.y=mcpl_particle->direction[1]; omc_particle.u.z=mcpl_particle->direction[2]; - //mcpl stores particles in MeV + //mcpl stores kinetic energy in MeV omc_particle.E=mcpl_particle->ekin*1e6; - + //mcpl stores time in ms omc_particle.t=mcpl_particle->time*1e-3; omc_particle.wgt=mcpl_particle->weight; omc_particle.delayed_group=0; From 34746926d349d0e04134893aa987c49d9508e121 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 12 Jul 2022 13:48:55 +0200 Subject: [PATCH 019/146] add necessary xmls --- tests/regression_tests/source_mcpl_file/geometry.xml | 8 ++++++++ tests/regression_tests/source_mcpl_file/materials.xml | 9 +++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/regression_tests/source_mcpl_file/geometry.xml create mode 100644 tests/regression_tests/source_mcpl_file/materials.xml diff --git a/tests/regression_tests/source_mcpl_file/geometry.xml b/tests/regression_tests/source_mcpl_file/geometry.xml new file mode 100644 index 0000000000..bc56030e18 --- /dev/null +++ b/tests/regression_tests/source_mcpl_file/geometry.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/regression_tests/source_mcpl_file/materials.xml b/tests/regression_tests/source_mcpl_file/materials.xml new file mode 100644 index 0000000000..2472a74717 --- /dev/null +++ b/tests/regression_tests/source_mcpl_file/materials.xml @@ -0,0 +1,9 @@ + + + + + + + + + From 25cfc328d04c930a8d75ba41eb46ed7e26c64cae Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 12 Jul 2022 13:49:56 +0200 Subject: [PATCH 020/146] set seed to make test deteministic --- tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c index f35a07fc44..61eea95c6f 100644 --- a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c +++ b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c @@ -52,6 +52,7 @@ int main(int argc, char **argv){ /*the main particle loop*/ particle=&Particle; int i; + srand(1234); for (i=0;i Date: Tue, 12 Jul 2022 13:50:35 +0200 Subject: [PATCH 021/146] test target result --- tests/regression_tests/source_mcpl_file/results_true.dat | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/regression_tests/source_mcpl_file/results_true.dat diff --git a/tests/regression_tests/source_mcpl_file/results_true.dat b/tests/regression_tests/source_mcpl_file/results_true.dat new file mode 100644 index 0000000000..f2209006a1 --- /dev/null +++ b/tests/regression_tests/source_mcpl_file/results_true.dat @@ -0,0 +1,2 @@ +k-combined: +3.017557E-01 3.398770E-03 From b0bb63cb3508d0dff59fd950a60dc35db2188b19 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 12 Jul 2022 13:50:53 +0200 Subject: [PATCH 022/146] yet another necessary file --- tests/regression_tests/source_mcpl_file/settings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/regression_tests/source_mcpl_file/settings.xml diff --git a/tests/regression_tests/source_mcpl_file/settings.xml b/tests/regression_tests/source_mcpl_file/settings.xml new file mode 100644 index 0000000000..8b1510e0ce --- /dev/null +++ b/tests/regression_tests/source_mcpl_file/settings.xml @@ -0,0 +1,11 @@ + + + + 10 + 5 + 1000 + + + source.10.mcpl + + From e480b5c851c542e53ff6e83236994f23c2bfdba3 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 12 Jul 2022 14:40:01 +0200 Subject: [PATCH 023/146] add a check that the test input got created as intended --- tests/regression_tests/source_mcpl_file/test.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py index 0adf67f1aa..922ddddd31 100644 --- a/tests/regression_tests/source_mcpl_file/test.py +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -15,6 +15,7 @@ class SourceMCPLFileTestHarness(TestHarness): """Run OpenMC with the appropriate arguments and check the outputs.""" try: self._create_input() + self._test_input_created() self._run_openmc() self._test_output_created() results = self._get_results() @@ -31,6 +32,7 @@ class SourceMCPLFileTestHarness(TestHarness): """Update the results_true using the current version of OpenMC.""" try: self._create_input() + self._test_input_created() self._run_openmc() self._test_output_created() results = self._get_results() @@ -39,6 +41,14 @@ class SourceMCPLFileTestHarness(TestHarness): finally: self._cleanup() + def _test_input_created(self): + """Check that the input mcpl.file was generated as it should""" + mcplfile=glob.glob(os.path.join(os.getcwd(),'source.10.mcpl')) + assert len(mcplfile) == 1, 'Either multiple or no mcpl files ' \ + 'exist.' + assert mcplfile[0].endswith('mcpl'), \ + 'output file does not end with mcpl.' + def _test_output_created(self): """Check that the output files were created""" statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name)) @@ -55,5 +65,5 @@ class SourceMCPLFileTestHarness(TestHarness): os.remove(f) def test_mcpl_source_file(): - harness = SourceMCPLFileTestHarness('statepoint.10.h5') + harness = SourceMCPLFileTestHarness('source.10.mcpl') harness.main() From 8c9bb761e5d3838a33822f7fa283acab106cc736 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 13 Jul 2022 10:25:55 +0200 Subject: [PATCH 024/146] fix bugs and finalize interface to MCPL --- include/openmc/source.h | 22 +++++++------ src/source.cpp | 73 +++++++++++++++++++++++++---------------- 2 files changed, 57 insertions(+), 38 deletions(-) diff --git a/include/openmc/source.h b/include/openmc/source.h index 69dd47eae9..4d7ec104aa 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -12,6 +12,10 @@ #include "openmc/particle.h" #include "openmc/vector.h" +#ifdef OPENMC_MCPL +#include +#endif + namespace openmc { //============================================================================== @@ -100,6 +104,7 @@ private: vector sites_; //!< Source sites from a file }; +#ifdef OPENMC_MCPL //============================================================================== // MCPL-file input source //============================================================================== @@ -109,24 +114,21 @@ public: MCPLFileSource(std::string path); ~MCPLFileSource(); - // Properties - ParticleType particle_type() const { return particle_; } - + // Methods //! Sample from the external source distribution //! \param[inout] seed Pseudorandom seed pointer //! \return Site read from MCPL-file - SourceSite sample(uint64_t* seed) const override; + SourceSite sample(uint64_t* seed) const; private: - ParticleType particle_ {ParticleType::neutron}; //!< Type of particle emitted + SourceSite read_single_particle() const; + void read_source_bank(vector &sites_); + vector sites_; //! #endif @@ -336,6 +336,7 @@ CustomSourceWrapper::~CustomSourceWrapper() #endif } +#ifdef OPENMC_MCPL //=========================================================================== // Read particles from an MCPL-file //=========================================================================== @@ -351,54 +352,70 @@ MCPLFileSource::MCPLFileSource(std::string path) write_message(6, "Reading mcpl source file from {}",path); // Open the mcpl file - mcpl_file = mcpl_open(path.c_str); + mcpl_file = mcpl_open_file(path.c_str()); //do checks on the mcpl_file to see if particles are many enough. // should model this on the example source shown in the docs. - uint64_t nparticles=mcpl_hdr_nparticles(mcpl_file); + n_sites=mcpl_hdr_nparticles(mcpl_file); + read_source_bank(sites_); } -MCPLFileSource::~MCPLFilsSource(){ +MCPLFileSource::~MCPLFileSource(){ mcpl_close_file(mcpl_file); } -SourceSite MCPLFileSource::sample(uint64_t *seed){ - SourceSite omc_particle; - mcpl_particle *mcpl_particle; +SourceSite MCPLFileSource::sample(uint64_t* seed) const +{ + size_t i_site = sites_.size() * prn(seed); + return sites_[i_site]; +} + +void MCPLFileSource::read_source_bank(vector &sites_) +{ + sites_.resize(n_sites); + for (int i=0;ipdgcode!=2112 && mcpl_particle->pdgcode!=22 ) - { - mcpl_particle(mcpl_read(mcplfile); - //check for file exhaustion + mcpl_particle=mcpl_read(mcpl_file); + // check if it is a neutron or a photon. otherwise skip + while ( mcpl_particle->pdgcode!=2112 && mcpl_particle->pdgcode!=22 ) { + mcpl_particle=mcpl_read(mcpl_file); + //should check for file exhaustion This could happen if particles are other than + //neutrons or photons } if(mcpl_particle->pdgcode==2112) { - omc_particle_=ParticleType::neutron; - } else if (mcpl_particle->pdgcode==22){ - omc_particle_=Particletype::photon; + omc_particle_.particle=ParticleType::neutron; + } else if (mcpl_particle->pdgcode==22) { + omc_particle_.particle=ParticleType::photon; } //particle is good, convert to openmc-formalism - omc_particle.r.x=mcpl_particle.x; - omc_particle.r.y=mcpl_particle.y; - omc_particle.r.z=mcpl_particle.z; + omc_particle_.r.x=mcpl_particle->position[0]; + omc_particle_.r.y=mcpl_particle->position[1]; + omc_particle_.r.z=mcpl_particle->position[2]; - omc_particle.u.x=mcpl_particle->direction[0]; - omc_particle.u.y=mcpl_particle->direction[1]; - omc_particle.u.z=mcpl_particle->direction[2]; + omc_particle_.u.x=mcpl_particle->direction[0]; + omc_particle_.u.y=mcpl_particle->direction[1]; + omc_particle_.u.z=mcpl_particle->direction[2]; //mcpl stores kinetic energy in MeV - omc_particle.E=mcpl_particle->ekin*1e6; + omc_particle_.E=mcpl_particle->ekin*1e6; //mcpl stores time in ms - omc_particle.t=mcpl_particle->time*1e-3; - omc_particle.wgt=mcpl_particle->weight; - omc_particle.delayed_group=0; - return omc_particle; + omc_particle_.time=mcpl_particle->time*1e-3; + omc_particle_.wgt=mcpl_particle->weight; + omc_particle_.delayed_group=0; + return omc_particle_; } - +#endif //OPENMC_MCPL //============================================================================== // Non-member functions From 915d69fb3d217cf705158dba680b8f02a99208c7 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 13 Jul 2022 10:26:24 +0200 Subject: [PATCH 025/146] add an option to turn on mcpl-support --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 85dcd7084d..6af9643cdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ option(OPENMC_ENABLE_COVERAGE "Compile with coverage analysis flags" option(OPENMC_USE_DAGMC "Enable support for DAGMC (CAD) geometry" OFF) option(OPENMC_USE_LIBMESH "Enable support for libMesh unstructured mesh tallies" OFF) option(OPENMC_USE_MPI "Enable MPI" OFF) +option(OPENMC_USE_MCPL "Enable MPCPL" OFF) #=============================================================================== # Set a default build configuration if not explicitly specified @@ -154,6 +155,10 @@ if(OPENMC_ENABLE_COVERAGE) list(APPEND ldflags --coverage) endif() +if(OPENMC_USE_MCPL) + list(APPEND ldflags -lmcpl) +endif() + # Show flags being used message(STATUS "OpenMC C++ flags: ${cxxflags}") message(STATUS "OpenMC Linker flags: ${ldflags}") @@ -408,6 +413,10 @@ endif() if (OPENMC_USE_MPI) target_compile_definitions(libopenmc PUBLIC -DOPENMC_MPI) endif() +if(OPENMC_USE_MCPL) + target_compile_definitions(libopenmc PUBLIC -DOPENMC_MCPL) +endif() + # Set git SHA1 hash as a compile definition if(GIT_FOUND) From b140eeb7cb4c7a1ee76172cd21c32c2e9951a24b Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 13 Jul 2022 10:27:18 +0200 Subject: [PATCH 026/146] add a source type to the settings interface --- src/settings.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/settings.cpp b/src/settings.cpp index eb0d4936c7..12e0a80509 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -430,6 +430,9 @@ void read_settings_xml() if (check_for_node(node, "file")) { auto path = get_node_value(node, "file", false, true); model::external_sources.push_back(make_unique(path)); + } else if (check_for_node(node, "mcpl")) { + auto path = get_node_value(node, "mcpl", false, true); + model::external_sources.push_back(make_unique(path)); } else if (check_for_node(node, "library")) { // Get shared library path and parameters auto path = get_node_value(node, "library", false, true); From cd163ef0b91fb4acc30630528b0728d8bab3098e Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 13 Jul 2022 12:13:10 +0200 Subject: [PATCH 027/146] only add mcpl-support if OPENMC_MCPL is defined --- src/settings.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/settings.cpp b/src/settings.cpp index 12e0a80509..d419cab06f 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -430,9 +430,11 @@ void read_settings_xml() if (check_for_node(node, "file")) { auto path = get_node_value(node, "file", false, true); model::external_sources.push_back(make_unique(path)); +#ifdef OPENMC_MCPL } else if (check_for_node(node, "mcpl")) { auto path = get_node_value(node, "mcpl", false, true); model::external_sources.push_back(make_unique(path)); +#endif } else if (check_for_node(node, "library")) { // Get shared library path and parameters auto path = get_node_value(node, "library", false, true); From a79233b3ec85f59647fb800da7db0973ce9365e8 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 13 Jul 2022 14:13:33 +0200 Subject: [PATCH 028/146] needed to avoid name clashes with other tests --- tests/regression_tests/source_mcpl_file/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/regression_tests/source_mcpl_file/__init__.py diff --git a/tests/regression_tests/source_mcpl_file/__init__.py b/tests/regression_tests/source_mcpl_file/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From eff690fd90032abd0d4a5e68f5babcc38c476de1 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 13 Jul 2022 20:55:53 +0200 Subject: [PATCH 029/146] fail without tripping the entire test-process --- tests/regression_tests/source_mcpl_file/test.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py index 922ddddd31..f55a769047 100644 --- a/tests/regression_tests/source_mcpl_file/test.py +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -1,11 +1,6 @@ -import pathlib as pl import os -import shutil import subprocess -import textwrap import glob -import openmc -import pytest from tests.testing_harness import TestHarness @@ -25,7 +20,8 @@ class SourceMCPLFileTestHarness(TestHarness): self._cleanup() def _create_input(self): - subprocess.run(['gcc','-o','gen_dummy_mcpl.out','gen_dummy_mcpl.c','-lm','-lmcpl']) + compiled=subprocess.run(['gcc','-o','gen_dummy_mcpl.out','gen_dummy_mcpl.c','-lm','-lmcpl']) + assert compiled==0, 'Could not compile mcpl-file generator code' subprocess.run(['./gen_dummy_mcpl.out']) def update_results(self): From 1ba696741412b17ac676cc2a0b4a78c606906d35 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Fri, 15 Jul 2022 21:35:59 +0200 Subject: [PATCH 030/146] fix typo Co-authored-by: Paul Romano --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6af9643cdb..be56f1c12f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ option(OPENMC_ENABLE_COVERAGE "Compile with coverage analysis flags" option(OPENMC_USE_DAGMC "Enable support for DAGMC (CAD) geometry" OFF) option(OPENMC_USE_LIBMESH "Enable support for libMesh unstructured mesh tallies" OFF) option(OPENMC_USE_MPI "Enable MPI" OFF) -option(OPENMC_USE_MCPL "Enable MPCPL" OFF) +option(OPENMC_USE_MCPL "Enable MCPL" OFF) #=============================================================================== # Set a default build configuration if not explicitly specified From 380cfc150b449ef56debb5261caa010a52c42bdd Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 9 Aug 2022 08:12:19 +0200 Subject: [PATCH 031/146] refactor MCPL file read part of FileSource A new constructor is added to FileSource that reads from a given MCPL-file. --- include/openmc/source.h | 30 +--------- src/settings.cpp | 2 +- src/source.cpp | 128 +++++++++++++++------------------------- 3 files changed, 52 insertions(+), 108 deletions(-) diff --git a/include/openmc/source.h b/include/openmc/source.h index 4d7ec104aa..5c2dae9311 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -96,7 +96,9 @@ class FileSource : public Source { public: // Constructors explicit FileSource(std::string path); - +#ifdef OPENMC_MCPL + explicit FileSource(mcpl_file_t mcpl_file); +#endif // Methods SourceSite sample(uint64_t* seed) const override; @@ -104,32 +106,6 @@ private: vector sites_; //!< Source sites from a file }; -#ifdef OPENMC_MCPL -//============================================================================== -// MCPL-file input source -//============================================================================== -class MCPLFileSource : public Source { -public: - // Constructors, destructors - MCPLFileSource(std::string path); - ~MCPLFileSource(); - - // Methods - //! Sample from the external source distribution - //! \param[inout] seed Pseudorandom seed pointer - //! \return Site read from MCPL-file - SourceSite sample(uint64_t* seed) const; - -private: - SourceSite read_single_particle() const; - void read_source_bank(vector &sites_); - - vector sites_; //!(path)); + model::external_sources.push_back(make_unique(mcpl_open_file(path.c_str()))); #endif } else if (check_for_node(node, "library")) { // Get shared library path and parameters diff --git a/src/source.cpp b/src/source.cpp index 82978f1030..49e51c4b16 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -277,6 +277,54 @@ FileSource::FileSource(std::string path) file_close(file_id); } +#ifdef OPENMC_MCPL +FileSource::FileSource(mcpl_file_t mcpl_file) +{ + //do checks on the mcpl_file to see if particles are many enough. + // should model this on the example source shown in the docs. + size_t n_sites=mcpl_hdr_nparticles(mcpl_file); + + sites_.resize(n_sites); + for (int i=0;ipdgcode!=2112 && mcpl_particle->pdgcode!=22 ) { + mcpl_particle=mcpl_read(mcpl_file); + //should check for file exhaustion This could happen if particles are other than + //neutrons or photons + } + + if(mcpl_particle->pdgcode==2112) { + site_.particle=ParticleType::neutron; + } else if (mcpl_particle->pdgcode==22) { + site_.particle=ParticleType::photon; + } + + //particle is good, convert to openmc-formalism + site_.r.x=mcpl_particle->position[0]; + site_.r.y=mcpl_particle->position[1]; + site_.r.z=mcpl_particle->position[2]; + + site_.u.x=mcpl_particle->direction[0]; + site_.u.y=mcpl_particle->direction[1]; + site_.u.z=mcpl_particle->direction[2]; + + //mcpl stores kinetic energy in MeV + site_.E=mcpl_particle->ekin*1e6; + //mcpl stores time in ms + site_.time=mcpl_particle->time*1e-3; + site_.wgt=mcpl_particle->weight; + site_.delayed_group=0; + sites_[i]=site_; + } + mcpl_close_file(mcpl_file); +} +#endif //OPENMC_MCPL + SourceSite FileSource::sample(uint64_t* seed) const { size_t i_site = sites_.size() * prn(seed); @@ -336,86 +384,6 @@ CustomSourceWrapper::~CustomSourceWrapper() #endif } -#ifdef OPENMC_MCPL -//=========================================================================== -// Read particles from an MCPL-file -//=========================================================================== -MCPLFileSource::MCPLFileSource(std::string path) -{ - // Check if source file exists - if (!file_exists(path)) { - fatal_error(fmt::format("Source file '{}' does not exist.", path)); - } - - // Read the source from a binary file instead of sampling from some - // assumed source distribution - write_message(6, "Reading mcpl source file from {}",path); - - // Open the mcpl file - mcpl_file = mcpl_open_file(path.c_str()); - - //do checks on the mcpl_file to see if particles are many enough. - // should model this on the example source shown in the docs. - n_sites=mcpl_hdr_nparticles(mcpl_file); - - read_source_bank(sites_); -} - -MCPLFileSource::~MCPLFileSource(){ - mcpl_close_file(mcpl_file); -} - -SourceSite MCPLFileSource::sample(uint64_t* seed) const -{ - size_t i_site = sites_.size() * prn(seed); - return sites_[i_site]; -} - -void MCPLFileSource::read_source_bank(vector &sites_) -{ - sites_.resize(n_sites); - for (int i=0;ipdgcode!=2112 && mcpl_particle->pdgcode!=22 ) { - mcpl_particle=mcpl_read(mcpl_file); - //should check for file exhaustion This could happen if particles are other than - //neutrons or photons - } - - if(mcpl_particle->pdgcode==2112) { - omc_particle_.particle=ParticleType::neutron; - } else if (mcpl_particle->pdgcode==22) { - omc_particle_.particle=ParticleType::photon; - } - - //particle is good, convert to openmc-formalism - omc_particle_.r.x=mcpl_particle->position[0]; - omc_particle_.r.y=mcpl_particle->position[1]; - omc_particle_.r.z=mcpl_particle->position[2]; - - omc_particle_.u.x=mcpl_particle->direction[0]; - omc_particle_.u.y=mcpl_particle->direction[1]; - omc_particle_.u.z=mcpl_particle->direction[2]; - - //mcpl stores kinetic energy in MeV - omc_particle_.E=mcpl_particle->ekin*1e6; - //mcpl stores time in ms - omc_particle_.time=mcpl_particle->time*1e-3; - omc_particle_.wgt=mcpl_particle->weight; - omc_particle_.delayed_group=0; - return omc_particle_; -} -#endif //OPENMC_MCPL //============================================================================== // Non-member functions From aa571c2c33b421e2524e249ca00f9584e891dd0a Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 6 Sep 2022 02:22:21 +0200 Subject: [PATCH 032/146] wip add MCPL-out to openmc code for writing a source_bank/point compiles but is untested --- include/openmc/state_point.h | 9 +++ src/state_point.cpp | 125 +++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/include/openmc/state_point.h b/include/openmc/state_point.h index 5ada2bf88d..2d92c935a6 100644 --- a/include/openmc/state_point.h +++ b/include/openmc/state_point.h @@ -9,6 +9,10 @@ #include "openmc/particle.h" #include "openmc/vector.h" +#ifdef OPENMC_MCPL +#include +#endif + namespace openmc { void load_state_point(); @@ -21,5 +25,10 @@ void write_tally_results_nr(hid_t file_id); void restart_set_keff(); void write_unstructured_mesh_results(); +#ifdef OPENMC_MCPL +void write_mcpl_source_point(const char *filename_, bool surf_source_bank = false); +void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank); +#endif + } // namespace openmc #endif // OPENMC_STATE_POINT_H diff --git a/src/state_point.cpp b/src/state_point.cpp index 9ea0459153..babd670a2d 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -28,6 +28,10 @@ #include "openmc/timer.h" #include "openmc/vector.h" +#ifdef OPENMC_MCPL +#include +#endif + namespace openmc { extern "C" int openmc_statepoint_write(const char* filename, bool* write_source) @@ -598,6 +602,45 @@ void write_source_point(const char* filename, bool surf_source_bank) file_close(file_id); } +void write_mcpl_point(const char *filename, bool surf_source_bank) +{ + std::string filename_; + if (filename) { + filename_ = filename; + } else { + // Determine width for zero padding + int w = std::to_string(settings::n_max_batches).size(); + + filename_ = fmt::format("{0}source.{1:0{2}}.mcpl", settings::path_output, + simulation::current_batch, w); + } + + mcpl_outfile_t file_id; + + std::string line; + if (mpi::master) { + // this must be rewritten: file_open is h5-specific + file_id = mcpl_create_outfile(filename_.c_str()); + //write_attribute(file_id, "filetype", "source"); + //write header stuff (oopy in xml-files as binary blobs for instance)) + if (VERSION_DEV){ + line=fmt::format("OpenMC {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_RELEASE}-development"); + } else { + line=fmt::format("OpenMC {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_RELEASE}"); + } + mcpl_hdr_set_srcname(file_id,line.c_str()); + } + + write_mcpl_source_bank(file_id, surf_source_bank); + + if (mpi::master) { + //change this - this is h5 specific + mcpl_closeandgzip_outfile(file_id); + } + +} + + void write_source_bank(hid_t group_id, bool surf_source_bank) { hid_t banktype = h5banktype(); @@ -714,6 +757,88 @@ void write_source_bank(hid_t group_id, bool surf_source_bank) H5Tclose(banktype); } +void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) +{ + int64_t dims_size = settings::n_particles; + int64_t count_size = simulation::work_per_rank; + + // Set vectors for source bank and starting bank index of each process + vector* bank_index = &simulation::work_index; + vector* source_bank = &simulation::source_bank; + vector surf_source_index_vector; + vector surf_source_bank_vector; + + if(surf_source_bank) { + surf_source_index_vector = calculate_surf_source_size(); + dims_size = surf_source_index_vector[mpi::n_procs]; + count_size = simulation::surf_source_bank.size(); + + bank_index = &surf_source_index_vector; + + // Copy data in a SharedArray into a vector. + surf_source_bank_vector.resize(count_size); + surf_source_bank_vector.assign(simulation::surf_source_bank.data(), + simulation::surf_source_bank.data() + count_size); + source_bank = &surf_source_bank_vector; + } + + if (mpi::master) { + //write particles from the master node + //loop over the other nodes and receive data - then write those. + for (int i = 0; i < mpi::n_procs; ++i) { +#ifdef OPENMC_MPI + if (i>0) + MPI_Recv(source_bank->data(), count[0], mpi::source_site, i, i, + mpi::intracomm, MPI_STATUS_IGNORE); +#endif + //now write the source_banke data again. + for (vector::iterator _site=source_bank->begin(); _site!=source_bank->end();_site++){ + //particle is now at the iterator + //write it to the mcpl-file + mcpl_particle_t p; + p.position[0]=_site->r.x; + p.position[1]=_site->r.y; + p.position[2]=_site->r.z; + + p.direction[0]=_site->u.x; + p.direction[1]=_site->u.y; + p.direction[2]=_site->u.x; + + //mcpl stores kinetic energy in MeV + p.ekin=_site->E*1e-6; + + p.time=_site->time*1e3; + + p.weight=_site->wgt; + + switch(_site->particle){ + case ParticleType::neutron: + p.pdgcode=2112; + break; + case ParticleType::photon: + p.pdgcode=22; + break; + case ParticleType::electron: + p.pdgcode=11; + break; + case ParticleType::positron: + p.pdgcode=-11; + break; + } + + mcpl_add_particle(file_id,&p); + } + } + } else { +#ifdef OPENMC_MPI + MPI_Send(source_bank->data(), count_size, mpi::source_site, 0, mpi::rank, + mpi::intracomm); +#endif + } + +} + + // Determine member names of a compound HDF5 datatype std::string dtype_member_names(hid_t dtype_id) { From be09b442fbfc41d029ed0eccef87ea25477f40aa Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 6 Sep 2022 09:11:41 +0200 Subject: [PATCH 033/146] allow electrons and positrons as well --- src/source.cpp | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 82978f1030..e7c944cb58 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -383,19 +383,30 @@ SourceSite MCPLFileSource::read_single_particle() const { SourceSite omc_particle_; const mcpl_particle_t *mcpl_particle; - //extract particle from mcpl-file + // extract particle from mcpl-file mcpl_particle=mcpl_read(mcpl_file); - // check if it is a neutron or a photon. otherwise skip - while ( mcpl_particle->pdgcode!=2112 && mcpl_particle->pdgcode!=22 ) { + // check if it is a neutron, photon, electron, or positron. Otherwise skip. + int pdg=mcpl_particle->pdgcode; + while ( pdg!=2112 && pdg!=22 && pdg!=11 && pdg!=-11) { mcpl_particle=mcpl_read(mcpl_file); - //should check for file exhaustion This could happen if particles are other than - //neutrons or photons + pdg=mcpl_particle->pdgcode; + //should check for file exhaustion. This could happen if particles are other than + //neutrons, photons, electrons, or positrons. } - if(mcpl_particle->pdgcode==2112) { - omc_particle_.particle=ParticleType::neutron; - } else if (mcpl_particle->pdgcode==22) { - omc_particle_.particle=ParticleType::photon; + switch(pdg){ + case 2112: + omc_particle_.particle=ParticleType::neutron; + break; + case 22: + omc_particle_.particle=ParticleType::photon; + break; + case 11: + omc_particle_.particle=ParticleType::electron; + break; + case -11: + omc_particle_.particle=ParticleType::positron; + break; } //particle is good, convert to openmc-formalism From 4e5ba4b4601209f389c394cd3747891e76b43f1c Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 6 Sep 2022 09:12:01 +0200 Subject: [PATCH 034/146] expose a python function to check for mcpl --- openmc/lib/__init__.py | 3 +++ src/source.cpp | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/openmc/lib/__init__.py b/openmc/lib/__init__.py index c14b0d9c28..1e337fc073 100644 --- a/openmc/lib/__init__.py +++ b/openmc/lib/__init__.py @@ -48,6 +48,9 @@ def _coord_levels(): def _libmesh_enabled(): return c_bool.in_dll(_dll, "LIBMESH_ENABLED").value +def _mcpl_enabled(): + return c_bool.in_dll(_dll, "MCPL_ENABLED").value + from .error import * from .core import * from .nuclide import * diff --git a/src/source.cpp b/src/source.cpp index e7c944cb58..9b426c3cfa 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -41,6 +41,12 @@ namespace openmc { // Global variables //============================================================================== +#ifdef OPENMC_MCPL +const bool MCPL_ENABLED = true; +#else +const bool MCPL_ENABLED = false; +#endif + namespace model { vector> external_sources; From 32e71395b3ad44ecc7080ba39d4b920adfb88702 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 6 Sep 2022 23:06:19 +0200 Subject: [PATCH 035/146] add a trigger to simulation control --- src/simulation.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/simulation.cpp b/src/simulation.cpp index b70535c330..05c8c04508 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -406,6 +406,13 @@ void finalize_batch() auto filename = settings::path_output + "surface_source.h5"; write_source_point(filename.c_str(), true); } + + if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ + auto filename = settings::path_output + ".mcpl"; + write_mcplt_source_point(filename.c_str(), true); + } + + } void initialize_generation() From ab665fb4563be28b6cfd365634049c90f133f485 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Fri, 15 Jul 2022 21:35:59 +0200 Subject: [PATCH 036/146] fix typo Co-authored-by: Paul Romano --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6af9643cdb..be56f1c12f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ option(OPENMC_ENABLE_COVERAGE "Compile with coverage analysis flags" option(OPENMC_USE_DAGMC "Enable support for DAGMC (CAD) geometry" OFF) option(OPENMC_USE_LIBMESH "Enable support for libMesh unstructured mesh tallies" OFF) option(OPENMC_USE_MPI "Enable MPI" OFF) -option(OPENMC_USE_MCPL "Enable MPCPL" OFF) +option(OPENMC_USE_MCPL "Enable MCPL" OFF) #=============================================================================== # Set a default build configuration if not explicitly specified From 71568d4f4bffa21a2a9c26725619cd180a9a59ff Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 9 Aug 2022 08:12:19 +0200 Subject: [PATCH 037/146] refactor MCPL file read part of FileSource A new constructor is added to FileSource that reads from a given MCPL-file. --- include/openmc/source.h | 30 ++--------- src/settings.cpp | 2 +- src/source.cpp | 116 +++++++++++++++++----------------------- 3 files changed, 53 insertions(+), 95 deletions(-) diff --git a/include/openmc/source.h b/include/openmc/source.h index 4d7ec104aa..5c2dae9311 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -96,7 +96,9 @@ class FileSource : public Source { public: // Constructors explicit FileSource(std::string path); - +#ifdef OPENMC_MCPL + explicit FileSource(mcpl_file_t mcpl_file); +#endif // Methods SourceSite sample(uint64_t* seed) const override; @@ -104,32 +106,6 @@ private: vector sites_; //!< Source sites from a file }; -#ifdef OPENMC_MCPL -//============================================================================== -// MCPL-file input source -//============================================================================== -class MCPLFileSource : public Source { -public: - // Constructors, destructors - MCPLFileSource(std::string path); - ~MCPLFileSource(); - - // Methods - //! Sample from the external source distribution - //! \param[inout] seed Pseudorandom seed pointer - //! \return Site read from MCPL-file - SourceSite sample(uint64_t* seed) const; - -private: - SourceSite read_single_particle() const; - void read_source_bank(vector &sites_); - - vector sites_; //!(path)); + model::external_sources.push_back(make_unique(mcpl_open_file(path.c_str()))); #endif } else if (check_for_node(node, "library")) { // Get shared library path and parameters diff --git a/src/source.cpp b/src/source.cpp index 9b426c3cfa..9cdf1632bf 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -283,6 +283,54 @@ FileSource::FileSource(std::string path) file_close(file_id); } +#ifdef OPENMC_MCPL +FileSource::FileSource(mcpl_file_t mcpl_file) +{ + //do checks on the mcpl_file to see if particles are many enough. + // should model this on the example source shown in the docs. + size_t n_sites=mcpl_hdr_nparticles(mcpl_file); + + sites_.resize(n_sites); + for (int i=0;ipdgcode!=2112 && mcpl_particle->pdgcode!=22 ) { + mcpl_particle=mcpl_read(mcpl_file); + //should check for file exhaustion This could happen if particles are other than + //neutrons or photons + } + + if(mcpl_particle->pdgcode==2112) { + site_.particle=ParticleType::neutron; + } else if (mcpl_particle->pdgcode==22) { + site_.particle=ParticleType::photon; + } + + //particle is good, convert to openmc-formalism + site_.r.x=mcpl_particle->position[0]; + site_.r.y=mcpl_particle->position[1]; + site_.r.z=mcpl_particle->position[2]; + + site_.u.x=mcpl_particle->direction[0]; + site_.u.y=mcpl_particle->direction[1]; + site_.u.z=mcpl_particle->direction[2]; + + //mcpl stores kinetic energy in MeV + site_.E=mcpl_particle->ekin*1e6; + //mcpl stores time in ms + site_.time=mcpl_particle->time*1e-3; + site_.wgt=mcpl_particle->weight; + site_.delayed_group=0; + sites_[i]=site_; + } + mcpl_close_file(mcpl_file); +} +#endif //OPENMC_MCPL + SourceSite FileSource::sample(uint64_t* seed) const { size_t i_site = sites_.size() * prn(seed); @@ -366,73 +414,7 @@ MCPLFileSource::MCPLFileSource(std::string path) read_source_bank(sites_); } - -MCPLFileSource::~MCPLFileSource(){ - mcpl_close_file(mcpl_file); -} - -SourceSite MCPLFileSource::sample(uint64_t* seed) const -{ - size_t i_site = sites_.size() * prn(seed); - return sites_[i_site]; -} - -void MCPLFileSource::read_source_bank(vector &sites_) -{ - sites_.resize(n_sites); - for (int i=0;ipdgcode; - while ( pdg!=2112 && pdg!=22 && pdg!=11 && pdg!=-11) { - mcpl_particle=mcpl_read(mcpl_file); - pdg=mcpl_particle->pdgcode; - //should check for file exhaustion. This could happen if particles are other than - //neutrons, photons, electrons, or positrons. - } - - switch(pdg){ - case 2112: - omc_particle_.particle=ParticleType::neutron; - break; - case 22: - omc_particle_.particle=ParticleType::photon; - break; - case 11: - omc_particle_.particle=ParticleType::electron; - break; - case -11: - omc_particle_.particle=ParticleType::positron; - break; - } - - //particle is good, convert to openmc-formalism - omc_particle_.r.x=mcpl_particle->position[0]; - omc_particle_.r.y=mcpl_particle->position[1]; - omc_particle_.r.z=mcpl_particle->position[2]; - - omc_particle_.u.x=mcpl_particle->direction[0]; - omc_particle_.u.y=mcpl_particle->direction[1]; - omc_particle_.u.z=mcpl_particle->direction[2]; - - //mcpl stores kinetic energy in MeV - omc_particle_.E=mcpl_particle->ekin*1e6; - //mcpl stores time in ms - omc_particle_.time=mcpl_particle->time*1e-3; - omc_particle_.wgt=mcpl_particle->weight; - omc_particle_.delayed_group=0; - return omc_particle_; -} -#endif //OPENMC_MCPL +#endif //============================================================================== // Non-member functions From 73a391daef86e3a93c0c7180d9ff7f670afff240 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 6 Sep 2022 02:22:21 +0200 Subject: [PATCH 038/146] wip add MCPL-out to openmc code for writing a source_bank/point compiles but is untested --- include/openmc/state_point.h | 9 +++ src/state_point.cpp | 125 +++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/include/openmc/state_point.h b/include/openmc/state_point.h index 5ada2bf88d..2d92c935a6 100644 --- a/include/openmc/state_point.h +++ b/include/openmc/state_point.h @@ -9,6 +9,10 @@ #include "openmc/particle.h" #include "openmc/vector.h" +#ifdef OPENMC_MCPL +#include +#endif + namespace openmc { void load_state_point(); @@ -21,5 +25,10 @@ void write_tally_results_nr(hid_t file_id); void restart_set_keff(); void write_unstructured_mesh_results(); +#ifdef OPENMC_MCPL +void write_mcpl_source_point(const char *filename_, bool surf_source_bank = false); +void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank); +#endif + } // namespace openmc #endif // OPENMC_STATE_POINT_H diff --git a/src/state_point.cpp b/src/state_point.cpp index 9ea0459153..babd670a2d 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -28,6 +28,10 @@ #include "openmc/timer.h" #include "openmc/vector.h" +#ifdef OPENMC_MCPL +#include +#endif + namespace openmc { extern "C" int openmc_statepoint_write(const char* filename, bool* write_source) @@ -598,6 +602,45 @@ void write_source_point(const char* filename, bool surf_source_bank) file_close(file_id); } +void write_mcpl_point(const char *filename, bool surf_source_bank) +{ + std::string filename_; + if (filename) { + filename_ = filename; + } else { + // Determine width for zero padding + int w = std::to_string(settings::n_max_batches).size(); + + filename_ = fmt::format("{0}source.{1:0{2}}.mcpl", settings::path_output, + simulation::current_batch, w); + } + + mcpl_outfile_t file_id; + + std::string line; + if (mpi::master) { + // this must be rewritten: file_open is h5-specific + file_id = mcpl_create_outfile(filename_.c_str()); + //write_attribute(file_id, "filetype", "source"); + //write header stuff (oopy in xml-files as binary blobs for instance)) + if (VERSION_DEV){ + line=fmt::format("OpenMC {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_RELEASE}-development"); + } else { + line=fmt::format("OpenMC {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_RELEASE}"); + } + mcpl_hdr_set_srcname(file_id,line.c_str()); + } + + write_mcpl_source_bank(file_id, surf_source_bank); + + if (mpi::master) { + //change this - this is h5 specific + mcpl_closeandgzip_outfile(file_id); + } + +} + + void write_source_bank(hid_t group_id, bool surf_source_bank) { hid_t banktype = h5banktype(); @@ -714,6 +757,88 @@ void write_source_bank(hid_t group_id, bool surf_source_bank) H5Tclose(banktype); } +void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) +{ + int64_t dims_size = settings::n_particles; + int64_t count_size = simulation::work_per_rank; + + // Set vectors for source bank and starting bank index of each process + vector* bank_index = &simulation::work_index; + vector* source_bank = &simulation::source_bank; + vector surf_source_index_vector; + vector surf_source_bank_vector; + + if(surf_source_bank) { + surf_source_index_vector = calculate_surf_source_size(); + dims_size = surf_source_index_vector[mpi::n_procs]; + count_size = simulation::surf_source_bank.size(); + + bank_index = &surf_source_index_vector; + + // Copy data in a SharedArray into a vector. + surf_source_bank_vector.resize(count_size); + surf_source_bank_vector.assign(simulation::surf_source_bank.data(), + simulation::surf_source_bank.data() + count_size); + source_bank = &surf_source_bank_vector; + } + + if (mpi::master) { + //write particles from the master node + //loop over the other nodes and receive data - then write those. + for (int i = 0; i < mpi::n_procs; ++i) { +#ifdef OPENMC_MPI + if (i>0) + MPI_Recv(source_bank->data(), count[0], mpi::source_site, i, i, + mpi::intracomm, MPI_STATUS_IGNORE); +#endif + //now write the source_banke data again. + for (vector::iterator _site=source_bank->begin(); _site!=source_bank->end();_site++){ + //particle is now at the iterator + //write it to the mcpl-file + mcpl_particle_t p; + p.position[0]=_site->r.x; + p.position[1]=_site->r.y; + p.position[2]=_site->r.z; + + p.direction[0]=_site->u.x; + p.direction[1]=_site->u.y; + p.direction[2]=_site->u.x; + + //mcpl stores kinetic energy in MeV + p.ekin=_site->E*1e-6; + + p.time=_site->time*1e3; + + p.weight=_site->wgt; + + switch(_site->particle){ + case ParticleType::neutron: + p.pdgcode=2112; + break; + case ParticleType::photon: + p.pdgcode=22; + break; + case ParticleType::electron: + p.pdgcode=11; + break; + case ParticleType::positron: + p.pdgcode=-11; + break; + } + + mcpl_add_particle(file_id,&p); + } + } + } else { +#ifdef OPENMC_MPI + MPI_Send(source_bank->data(), count_size, mpi::source_site, 0, mpi::rank, + mpi::intracomm); +#endif + } + +} + + // Determine member names of a compound HDF5 datatype std::string dtype_member_names(hid_t dtype_id) { From d07223bf681e5d6e1d7cbde0dac6f97059a12767 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 6 Sep 2022 23:06:19 +0200 Subject: [PATCH 039/146] add a trigger to simulation control --- src/simulation.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/simulation.cpp b/src/simulation.cpp index b70535c330..05c8c04508 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -406,6 +406,13 @@ void finalize_batch() auto filename = settings::path_output + "surface_source.h5"; write_source_point(filename.c_str(), true); } + + if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ + auto filename = settings::path_output + ".mcpl"; + write_mcplt_source_point(filename.c_str(), true); + } + + } void initialize_generation() From 55f2be19e6c0ef51d7a7946ac15a9f2df51da6da Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Fri, 16 Sep 2022 16:07:22 +0200 Subject: [PATCH 040/146] refactor MCPL file read part of FileSource A new constructor is added to FileSource that reads from a given MCPL-file. --- src/source.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/source.cpp b/src/source.cpp index 626d02f9d7..21522438cf 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -426,6 +426,7 @@ MCPLFileSource::MCPLFileSource(std::string path) read_source_bank(sites_); } +<<<<<<< HEAD MCPLFileSource::~MCPLFileSource(){ mcpl_close_file(mcpl_file); @@ -495,6 +496,9 @@ SourceSite MCPLFileSource::read_single_particle() const #endif //OPENMC_MCPL ======= >>>>>>> 380cfc150b449ef56debb5261caa010a52c42bdd +======= +#endif +>>>>>>> 71568d4f4 (refactor MCPL file read part of FileSource) //============================================================================== // Non-member functions From f0af56b181555f52d05f245240846f4ce8eadcaa Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 6 Sep 2022 02:22:21 +0200 Subject: [PATCH 041/146] wip add MCPL-out to openmc code for writing a source_bank/point compiles but is untested --- include/openmc/state_point.h | 9 +++ src/state_point.cpp | 125 +++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/include/openmc/state_point.h b/include/openmc/state_point.h index 5ada2bf88d..2d92c935a6 100644 --- a/include/openmc/state_point.h +++ b/include/openmc/state_point.h @@ -9,6 +9,10 @@ #include "openmc/particle.h" #include "openmc/vector.h" +#ifdef OPENMC_MCPL +#include +#endif + namespace openmc { void load_state_point(); @@ -21,5 +25,10 @@ void write_tally_results_nr(hid_t file_id); void restart_set_keff(); void write_unstructured_mesh_results(); +#ifdef OPENMC_MCPL +void write_mcpl_source_point(const char *filename_, bool surf_source_bank = false); +void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank); +#endif + } // namespace openmc #endif // OPENMC_STATE_POINT_H diff --git a/src/state_point.cpp b/src/state_point.cpp index 9ea0459153..babd670a2d 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -28,6 +28,10 @@ #include "openmc/timer.h" #include "openmc/vector.h" +#ifdef OPENMC_MCPL +#include +#endif + namespace openmc { extern "C" int openmc_statepoint_write(const char* filename, bool* write_source) @@ -598,6 +602,45 @@ void write_source_point(const char* filename, bool surf_source_bank) file_close(file_id); } +void write_mcpl_point(const char *filename, bool surf_source_bank) +{ + std::string filename_; + if (filename) { + filename_ = filename; + } else { + // Determine width for zero padding + int w = std::to_string(settings::n_max_batches).size(); + + filename_ = fmt::format("{0}source.{1:0{2}}.mcpl", settings::path_output, + simulation::current_batch, w); + } + + mcpl_outfile_t file_id; + + std::string line; + if (mpi::master) { + // this must be rewritten: file_open is h5-specific + file_id = mcpl_create_outfile(filename_.c_str()); + //write_attribute(file_id, "filetype", "source"); + //write header stuff (oopy in xml-files as binary blobs for instance)) + if (VERSION_DEV){ + line=fmt::format("OpenMC {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_RELEASE}-development"); + } else { + line=fmt::format("OpenMC {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_RELEASE}"); + } + mcpl_hdr_set_srcname(file_id,line.c_str()); + } + + write_mcpl_source_bank(file_id, surf_source_bank); + + if (mpi::master) { + //change this - this is h5 specific + mcpl_closeandgzip_outfile(file_id); + } + +} + + void write_source_bank(hid_t group_id, bool surf_source_bank) { hid_t banktype = h5banktype(); @@ -714,6 +757,88 @@ void write_source_bank(hid_t group_id, bool surf_source_bank) H5Tclose(banktype); } +void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) +{ + int64_t dims_size = settings::n_particles; + int64_t count_size = simulation::work_per_rank; + + // Set vectors for source bank and starting bank index of each process + vector* bank_index = &simulation::work_index; + vector* source_bank = &simulation::source_bank; + vector surf_source_index_vector; + vector surf_source_bank_vector; + + if(surf_source_bank) { + surf_source_index_vector = calculate_surf_source_size(); + dims_size = surf_source_index_vector[mpi::n_procs]; + count_size = simulation::surf_source_bank.size(); + + bank_index = &surf_source_index_vector; + + // Copy data in a SharedArray into a vector. + surf_source_bank_vector.resize(count_size); + surf_source_bank_vector.assign(simulation::surf_source_bank.data(), + simulation::surf_source_bank.data() + count_size); + source_bank = &surf_source_bank_vector; + } + + if (mpi::master) { + //write particles from the master node + //loop over the other nodes and receive data - then write those. + for (int i = 0; i < mpi::n_procs; ++i) { +#ifdef OPENMC_MPI + if (i>0) + MPI_Recv(source_bank->data(), count[0], mpi::source_site, i, i, + mpi::intracomm, MPI_STATUS_IGNORE); +#endif + //now write the source_banke data again. + for (vector::iterator _site=source_bank->begin(); _site!=source_bank->end();_site++){ + //particle is now at the iterator + //write it to the mcpl-file + mcpl_particle_t p; + p.position[0]=_site->r.x; + p.position[1]=_site->r.y; + p.position[2]=_site->r.z; + + p.direction[0]=_site->u.x; + p.direction[1]=_site->u.y; + p.direction[2]=_site->u.x; + + //mcpl stores kinetic energy in MeV + p.ekin=_site->E*1e-6; + + p.time=_site->time*1e3; + + p.weight=_site->wgt; + + switch(_site->particle){ + case ParticleType::neutron: + p.pdgcode=2112; + break; + case ParticleType::photon: + p.pdgcode=22; + break; + case ParticleType::electron: + p.pdgcode=11; + break; + case ParticleType::positron: + p.pdgcode=-11; + break; + } + + mcpl_add_particle(file_id,&p); + } + } + } else { +#ifdef OPENMC_MPI + MPI_Send(source_bank->data(), count_size, mpi::source_site, 0, mpi::rank, + mpi::intracomm); +#endif + } + +} + + // Determine member names of a compound HDF5 datatype std::string dtype_member_names(hid_t dtype_id) { From 04c8ffc81c7ed7ced0c3525b5ec13f15f8fc079c Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 6 Sep 2022 23:06:19 +0200 Subject: [PATCH 042/146] add a trigger to simulation control --- src/simulation.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/simulation.cpp b/src/simulation.cpp index b70535c330..05c8c04508 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -406,6 +406,13 @@ void finalize_batch() auto filename = settings::path_output + "surface_source.h5"; write_source_point(filename.c_str(), true); } + + if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ + auto filename = settings::path_output + ".mcpl"; + write_mcplt_source_point(filename.c_str(), true); + } + + } void initialize_generation() From 314f3dbbab75104f217d1e20e2146ced28108707 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 4 Oct 2022 10:11:06 +0200 Subject: [PATCH 043/146] do not define these functions if no MCPL present --- src/state_point.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index babd670a2d..5b00f302dc 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -602,6 +602,7 @@ void write_source_point(const char* filename, bool surf_source_bank) file_close(file_id); } +#ifdef OPENMC_MCPL void write_mcpl_point(const char *filename, bool surf_source_bank) { std::string filename_; @@ -639,7 +640,7 @@ void write_mcpl_point(const char *filename, bool surf_source_bank) } } - +#endif void write_source_bank(hid_t group_id, bool surf_source_bank) { @@ -757,6 +758,7 @@ void write_source_bank(hid_t group_id, bool surf_source_bank) H5Tclose(banktype); } +#ifdef OPENMC_MCPL void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) { int64_t dims_size = settings::n_particles; @@ -837,7 +839,7 @@ void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) } } - +#endif // Determine member names of a compound HDF5 datatype std::string dtype_member_names(hid_t dtype_id) From 2de20231ad584fa7a77a5b135c82f6e995671bcc Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 5 Oct 2022 10:56:36 +0200 Subject: [PATCH 044/146] use find_package instead - MCPL now supports this --- CMakeLists.txt | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index be56f1c12f..98dc4fcaf0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,6 +128,13 @@ if(${HDF5_VERSION} VERSION_GREATER_EQUAL 1.12.0) list(APPEND cxxflags -DH5Oget_info_by_idx_vers=1 -DH5O_info_t_vers=1) endif() +#=============================================================================== +# MCPL +#=============================================================================== +if (OPENMC_USE_MCPL) + find_package(MCPL REQUIRED) +endif() + #=============================================================================== # Set compile/link flags based on which compiler is being used #=============================================================================== @@ -155,10 +162,6 @@ if(OPENMC_ENABLE_COVERAGE) list(APPEND ldflags --coverage) endif() -if(OPENMC_USE_MCPL) - list(APPEND ldflags -lmcpl) -endif() - # Show flags being used message(STATUS "OpenMC C++ flags: ${cxxflags}") message(STATUS "OpenMC Linker flags: ${ldflags}") @@ -413,10 +416,6 @@ endif() if (OPENMC_USE_MPI) target_compile_definitions(libopenmc PUBLIC -DOPENMC_MPI) endif() -if(OPENMC_USE_MCPL) - target_compile_definitions(libopenmc PUBLIC -DOPENMC_MCPL) -endif() - # Set git SHA1 hash as a compile definition if(GIT_FOUND) @@ -460,6 +459,11 @@ if (OPENMC_USE_MPI) target_link_libraries(libopenmc MPI::MPI_CXX) endif() +if (OPENMC_USE_MCPL) + target_compile_definitions(libopenmc PUBLIC OPENMC_MCPL) + target_link_libraries(libopenmc MCPL::mcpl) +endif() + #=============================================================================== # openmc executable #=============================================================================== From 7418cb99dd7c22e80532dcc46a9d2c4c04ceb63d Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 5 Oct 2022 10:59:02 +0200 Subject: [PATCH 045/146] add mcpl-output settings --- include/openmc/settings.h | 1 + src/settings.cpp | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/openmc/settings.h b/include/openmc/settings.h index 1e061b235b..66825867d8 100644 --- a/include/openmc/settings.h +++ b/include/openmc/settings.h @@ -48,6 +48,7 @@ extern bool source_latest; //!< write latest source at each batch? extern bool source_separate; //!< write source to separate file? extern bool source_write; //!< write source in HDF5 files? extern bool surf_source_write; //!< write surface source file? +extern bool surf_mcpl_write; //!< write surface mcpl file? extern bool surf_source_read; //!< read surface source file? extern bool survival_biasing; //!< use survival biasing? extern bool temperature_multipole; //!< use multipole data? diff --git a/src/settings.cpp b/src/settings.cpp index 11dd96e025..d1762596c6 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -61,6 +61,7 @@ bool source_latest {false}; bool source_separate {false}; bool source_write {true}; bool surf_source_write {false}; +bool surf_mcpl_write {false}; bool surf_source_read {false}; bool survival_biasing {false}; bool temperature_multipole {false}; @@ -682,9 +683,14 @@ void read_settings_xml() max_surface_particles = std::stoll(get_node_value(node_ssw, "max_particles")); } +#ifdef OPENMC_MCPL + if(check_for_node(node_ssw, "mcpl")){ + surf_mcpl_write=true; + } +#endif } - // If source is not seperate and is to be written out in the statepoint file, + // If source is not separate and is to be written out in the statepoint file, // make sure that the sourcepoint batch numbers are contained in the // statepoint list if (!source_separate) { From 172c518f0e161d0176385c67d3717ad9fb229038 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 5 Oct 2022 10:59:28 +0200 Subject: [PATCH 046/146] fix typo --- src/simulation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simulation.cpp b/src/simulation.cpp index 05c8c04508..353ef99265 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -409,7 +409,7 @@ void finalize_batch() if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ auto filename = settings::path_output + ".mcpl"; - write_mcplt_source_point(filename.c_str(), true); + write_mcpl_source_point(filename.c_str(), true); } From 83e2921034f5c448d500b93634999cdb3f350e0b Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 5 Oct 2022 11:00:39 +0200 Subject: [PATCH 047/146] add cond. compilation guards for MCPL functions --- src/state_point.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index babd670a2d..7c1a454476 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -602,7 +602,8 @@ void write_source_point(const char* filename, bool surf_source_bank) file_close(file_id); } -void write_mcpl_point(const char *filename, bool surf_source_bank) +#ifdef OPENMC_MCPL +void write_mcpl_source_point(const char *filename, bool surf_source_bank) { std::string filename_; if (filename) { @@ -639,7 +640,7 @@ void write_mcpl_point(const char *filename, bool surf_source_bank) } } - +#endif void write_source_bank(hid_t group_id, bool surf_source_bank) { @@ -757,6 +758,7 @@ void write_source_bank(hid_t group_id, bool surf_source_bank) H5Tclose(banktype); } +#ifdef OPENMC_MCPL void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) { int64_t dims_size = settings::n_particles; @@ -837,7 +839,7 @@ void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) } } - +#endif // Determine member names of a compound HDF5 datatype std::string dtype_member_names(hid_t dtype_id) From 5e82bb2e1f1b2857375566f98669be6c93b22638 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 6 Sep 2022 09:12:01 +0200 Subject: [PATCH 048/146] expose a python function to check for mcpl --- openmc/lib/__init__.py | 3 +++ src/source.cpp | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/openmc/lib/__init__.py b/openmc/lib/__init__.py index c14b0d9c28..1e337fc073 100644 --- a/openmc/lib/__init__.py +++ b/openmc/lib/__init__.py @@ -48,6 +48,9 @@ def _coord_levels(): def _libmesh_enabled(): return c_bool.in_dll(_dll, "LIBMESH_ENABLED").value +def _mcpl_enabled(): + return c_bool.in_dll(_dll, "MCPL_ENABLED").value + from .error import * from .core import * from .nuclide import * diff --git a/src/source.cpp b/src/source.cpp index 49e51c4b16..eace931d63 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -41,6 +41,12 @@ namespace openmc { // Global variables //============================================================================== +#ifdef OPENMC_MCPL +const bool MCPL_ENABLED = true; +#else +const bool MCPL_ENABLED = false; +#endif + namespace model { vector> external_sources; From 6038555def28547a0f392f0eeded8d8d49269d51 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 6 Sep 2022 02:22:21 +0200 Subject: [PATCH 049/146] wip add MCPL-out to openmc code for writing a source_bank/point compiles but is untested --- include/openmc/state_point.h | 9 +++ src/state_point.cpp | 125 +++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/include/openmc/state_point.h b/include/openmc/state_point.h index 5ada2bf88d..2d92c935a6 100644 --- a/include/openmc/state_point.h +++ b/include/openmc/state_point.h @@ -9,6 +9,10 @@ #include "openmc/particle.h" #include "openmc/vector.h" +#ifdef OPENMC_MCPL +#include +#endif + namespace openmc { void load_state_point(); @@ -21,5 +25,10 @@ void write_tally_results_nr(hid_t file_id); void restart_set_keff(); void write_unstructured_mesh_results(); +#ifdef OPENMC_MCPL +void write_mcpl_source_point(const char *filename_, bool surf_source_bank = false); +void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank); +#endif + } // namespace openmc #endif // OPENMC_STATE_POINT_H diff --git a/src/state_point.cpp b/src/state_point.cpp index 9ea0459153..babd670a2d 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -28,6 +28,10 @@ #include "openmc/timer.h" #include "openmc/vector.h" +#ifdef OPENMC_MCPL +#include +#endif + namespace openmc { extern "C" int openmc_statepoint_write(const char* filename, bool* write_source) @@ -598,6 +602,45 @@ void write_source_point(const char* filename, bool surf_source_bank) file_close(file_id); } +void write_mcpl_point(const char *filename, bool surf_source_bank) +{ + std::string filename_; + if (filename) { + filename_ = filename; + } else { + // Determine width for zero padding + int w = std::to_string(settings::n_max_batches).size(); + + filename_ = fmt::format("{0}source.{1:0{2}}.mcpl", settings::path_output, + simulation::current_batch, w); + } + + mcpl_outfile_t file_id; + + std::string line; + if (mpi::master) { + // this must be rewritten: file_open is h5-specific + file_id = mcpl_create_outfile(filename_.c_str()); + //write_attribute(file_id, "filetype", "source"); + //write header stuff (oopy in xml-files as binary blobs for instance)) + if (VERSION_DEV){ + line=fmt::format("OpenMC {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_RELEASE}-development"); + } else { + line=fmt::format("OpenMC {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_RELEASE}"); + } + mcpl_hdr_set_srcname(file_id,line.c_str()); + } + + write_mcpl_source_bank(file_id, surf_source_bank); + + if (mpi::master) { + //change this - this is h5 specific + mcpl_closeandgzip_outfile(file_id); + } + +} + + void write_source_bank(hid_t group_id, bool surf_source_bank) { hid_t banktype = h5banktype(); @@ -714,6 +757,88 @@ void write_source_bank(hid_t group_id, bool surf_source_bank) H5Tclose(banktype); } +void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) +{ + int64_t dims_size = settings::n_particles; + int64_t count_size = simulation::work_per_rank; + + // Set vectors for source bank and starting bank index of each process + vector* bank_index = &simulation::work_index; + vector* source_bank = &simulation::source_bank; + vector surf_source_index_vector; + vector surf_source_bank_vector; + + if(surf_source_bank) { + surf_source_index_vector = calculate_surf_source_size(); + dims_size = surf_source_index_vector[mpi::n_procs]; + count_size = simulation::surf_source_bank.size(); + + bank_index = &surf_source_index_vector; + + // Copy data in a SharedArray into a vector. + surf_source_bank_vector.resize(count_size); + surf_source_bank_vector.assign(simulation::surf_source_bank.data(), + simulation::surf_source_bank.data() + count_size); + source_bank = &surf_source_bank_vector; + } + + if (mpi::master) { + //write particles from the master node + //loop over the other nodes and receive data - then write those. + for (int i = 0; i < mpi::n_procs; ++i) { +#ifdef OPENMC_MPI + if (i>0) + MPI_Recv(source_bank->data(), count[0], mpi::source_site, i, i, + mpi::intracomm, MPI_STATUS_IGNORE); +#endif + //now write the source_banke data again. + for (vector::iterator _site=source_bank->begin(); _site!=source_bank->end();_site++){ + //particle is now at the iterator + //write it to the mcpl-file + mcpl_particle_t p; + p.position[0]=_site->r.x; + p.position[1]=_site->r.y; + p.position[2]=_site->r.z; + + p.direction[0]=_site->u.x; + p.direction[1]=_site->u.y; + p.direction[2]=_site->u.x; + + //mcpl stores kinetic energy in MeV + p.ekin=_site->E*1e-6; + + p.time=_site->time*1e3; + + p.weight=_site->wgt; + + switch(_site->particle){ + case ParticleType::neutron: + p.pdgcode=2112; + break; + case ParticleType::photon: + p.pdgcode=22; + break; + case ParticleType::electron: + p.pdgcode=11; + break; + case ParticleType::positron: + p.pdgcode=-11; + break; + } + + mcpl_add_particle(file_id,&p); + } + } + } else { +#ifdef OPENMC_MPI + MPI_Send(source_bank->data(), count_size, mpi::source_site, 0, mpi::rank, + mpi::intracomm); +#endif + } + +} + + // Determine member names of a compound HDF5 datatype std::string dtype_member_names(hid_t dtype_id) { From 2ba7f8d1882cf5e2562b473e233b4ca84ab81080 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 6 Sep 2022 23:06:19 +0200 Subject: [PATCH 050/146] add a trigger to simulation control --- src/simulation.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/simulation.cpp b/src/simulation.cpp index b70535c330..05c8c04508 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -406,6 +406,13 @@ void finalize_batch() auto filename = settings::path_output + "surface_source.h5"; write_source_point(filename.c_str(), true); } + + if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ + auto filename = settings::path_output + ".mcpl"; + write_mcplt_source_point(filename.c_str(), true); + } + + } void initialize_generation() From 91cd304f0e4fd32eb6df0bdb75dd3f7d169013ce Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 5 Oct 2022 10:56:36 +0200 Subject: [PATCH 051/146] use find_package instead - MCPL now supports this --- CMakeLists.txt | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index be56f1c12f..98dc4fcaf0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,6 +128,13 @@ if(${HDF5_VERSION} VERSION_GREATER_EQUAL 1.12.0) list(APPEND cxxflags -DH5Oget_info_by_idx_vers=1 -DH5O_info_t_vers=1) endif() +#=============================================================================== +# MCPL +#=============================================================================== +if (OPENMC_USE_MCPL) + find_package(MCPL REQUIRED) +endif() + #=============================================================================== # Set compile/link flags based on which compiler is being used #=============================================================================== @@ -155,10 +162,6 @@ if(OPENMC_ENABLE_COVERAGE) list(APPEND ldflags --coverage) endif() -if(OPENMC_USE_MCPL) - list(APPEND ldflags -lmcpl) -endif() - # Show flags being used message(STATUS "OpenMC C++ flags: ${cxxflags}") message(STATUS "OpenMC Linker flags: ${ldflags}") @@ -413,10 +416,6 @@ endif() if (OPENMC_USE_MPI) target_compile_definitions(libopenmc PUBLIC -DOPENMC_MPI) endif() -if(OPENMC_USE_MCPL) - target_compile_definitions(libopenmc PUBLIC -DOPENMC_MCPL) -endif() - # Set git SHA1 hash as a compile definition if(GIT_FOUND) @@ -460,6 +459,11 @@ if (OPENMC_USE_MPI) target_link_libraries(libopenmc MPI::MPI_CXX) endif() +if (OPENMC_USE_MCPL) + target_compile_definitions(libopenmc PUBLIC OPENMC_MCPL) + target_link_libraries(libopenmc MCPL::mcpl) +endif() + #=============================================================================== # openmc executable #=============================================================================== From 9b58c2f6dc93c4c51ce6ee7a26e7ffc645434020 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 5 Oct 2022 10:59:02 +0200 Subject: [PATCH 052/146] add mcpl-output settings --- include/openmc/settings.h | 1 + src/settings.cpp | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/openmc/settings.h b/include/openmc/settings.h index 1e061b235b..66825867d8 100644 --- a/include/openmc/settings.h +++ b/include/openmc/settings.h @@ -48,6 +48,7 @@ extern bool source_latest; //!< write latest source at each batch? extern bool source_separate; //!< write source to separate file? extern bool source_write; //!< write source in HDF5 files? extern bool surf_source_write; //!< write surface source file? +extern bool surf_mcpl_write; //!< write surface mcpl file? extern bool surf_source_read; //!< read surface source file? extern bool survival_biasing; //!< use survival biasing? extern bool temperature_multipole; //!< use multipole data? diff --git a/src/settings.cpp b/src/settings.cpp index 11dd96e025..d1762596c6 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -61,6 +61,7 @@ bool source_latest {false}; bool source_separate {false}; bool source_write {true}; bool surf_source_write {false}; +bool surf_mcpl_write {false}; bool surf_source_read {false}; bool survival_biasing {false}; bool temperature_multipole {false}; @@ -682,9 +683,14 @@ void read_settings_xml() max_surface_particles = std::stoll(get_node_value(node_ssw, "max_particles")); } +#ifdef OPENMC_MCPL + if(check_for_node(node_ssw, "mcpl")){ + surf_mcpl_write=true; + } +#endif } - // If source is not seperate and is to be written out in the statepoint file, + // If source is not separate and is to be written out in the statepoint file, // make sure that the sourcepoint batch numbers are contained in the // statepoint list if (!source_separate) { From 43538ac2021f36caf0d72e002a119a806aa14b71 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 5 Oct 2022 10:59:28 +0200 Subject: [PATCH 053/146] fix typo --- src/simulation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simulation.cpp b/src/simulation.cpp index 05c8c04508..353ef99265 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -409,7 +409,7 @@ void finalize_batch() if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ auto filename = settings::path_output + ".mcpl"; - write_mcplt_source_point(filename.c_str(), true); + write_mcpl_source_point(filename.c_str(), true); } From cba745b28b6e384311393c177456b518b60b4f55 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 5 Oct 2022 11:00:39 +0200 Subject: [PATCH 054/146] add cond. compilation guards for MCPL functions --- src/state_point.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index babd670a2d..7c1a454476 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -602,7 +602,8 @@ void write_source_point(const char* filename, bool surf_source_bank) file_close(file_id); } -void write_mcpl_point(const char *filename, bool surf_source_bank) +#ifdef OPENMC_MCPL +void write_mcpl_source_point(const char *filename, bool surf_source_bank) { std::string filename_; if (filename) { @@ -639,7 +640,7 @@ void write_mcpl_point(const char *filename, bool surf_source_bank) } } - +#endif void write_source_bank(hid_t group_id, bool surf_source_bank) { @@ -757,6 +758,7 @@ void write_source_bank(hid_t group_id, bool surf_source_bank) H5Tclose(banktype); } +#ifdef OPENMC_MCPL void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) { int64_t dims_size = settings::n_particles; @@ -837,7 +839,7 @@ void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) } } - +#endif // Determine member names of a compound HDF5 datatype std::string dtype_member_names(hid_t dtype_id) From 179df586853b65600518a0ea62526cc2193e0206 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Fri, 16 Sep 2022 16:07:22 +0200 Subject: [PATCH 055/146] refactor MCPL file read part of FileSource A new constructor is added to FileSource that reads from a given MCPL-file. --- src/source.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/source.cpp b/src/source.cpp index eace931d63..bd76969d17 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -391,6 +391,79 @@ CustomSourceWrapper::~CustomSourceWrapper() } +MCPLFileSource::~MCPLFileSource(){ + mcpl_close_file(mcpl_file); +} + +SourceSite MCPLFileSource::sample(uint64_t* seed) const +{ + size_t i_site = sites_.size() * prn(seed); + return sites_[i_site]; +} + +void MCPLFileSource::read_source_bank(vector &sites_) +{ + sites_.resize(n_sites); + for (int i=0;ipdgcode; + while ( pdg!=2112 && pdg!=22 && pdg!=11 && pdg!=-11) { + mcpl_particle=mcpl_read(mcpl_file); + pdg=mcpl_particle->pdgcode; + //should check for file exhaustion. This could happen if particles are other than + //neutrons, photons, electrons, or positrons. + } + + switch(pdg){ + case 2112: + omc_particle_.particle=ParticleType::neutron; + break; + case 22: + omc_particle_.particle=ParticleType::photon; + break; + case 11: + omc_particle_.particle=ParticleType::electron; + break; + case -11: + omc_particle_.particle=ParticleType::positron; + break; + } + + //particle is good, convert to openmc-formalism + omc_particle_.r.x=mcpl_particle->position[0]; + omc_particle_.r.y=mcpl_particle->position[1]; + omc_particle_.r.z=mcpl_particle->position[2]; + + omc_particle_.u.x=mcpl_particle->direction[0]; + omc_particle_.u.y=mcpl_particle->direction[1]; + omc_particle_.u.z=mcpl_particle->direction[2]; + + //mcpl stores kinetic energy in MeV + omc_particle_.E=mcpl_particle->ekin*1e6; + //mcpl stores time in ms + omc_particle_.time=mcpl_particle->time*1e-3; + omc_particle_.wgt=mcpl_particle->weight; + omc_particle_.delayed_group=0; + return omc_particle_; +} +#endif //OPENMC_MCPL +======= +>>>>>>> 380cfc150b449ef56debb5261caa010a52c42bdd +======= +#endif +>>>>>>> 71568d4f4 (refactor MCPL file read part of FileSource) +>>>>>>> 55f2be19e (refactor MCPL file read part of FileSource) + //============================================================================== // Non-member functions //============================================================================== From e3fbeac636c2e9a47599c60e04b2a1ba4d9ba46d Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 6 Sep 2022 02:22:21 +0200 Subject: [PATCH 056/146] wip add MCPL-out to openmc code for writing a source_bank/point compiles but is untested --- src/source.cpp | 6 ------ src/state_point.cpp | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index bd76969d17..f205a0a256 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -457,12 +457,6 @@ SourceSite MCPLFileSource::read_single_particle() const return omc_particle_; } #endif //OPENMC_MCPL -======= ->>>>>>> 380cfc150b449ef56debb5261caa010a52c42bdd -======= -#endif ->>>>>>> 71568d4f4 (refactor MCPL file read part of FileSource) ->>>>>>> 55f2be19e (refactor MCPL file read part of FileSource) //============================================================================== // Non-member functions diff --git a/src/state_point.cpp b/src/state_point.cpp index 7c1a454476..31979c0c56 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -642,6 +642,7 @@ void write_mcpl_source_point(const char *filename, bool surf_source_bank) } #endif + void write_source_bank(hid_t group_id, bool surf_source_bank) { hid_t banktype = h5banktype(); From 3b7c4f6d2f141311cba5ad9e5f773b3bc3381852 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 4 Oct 2022 10:11:06 +0200 Subject: [PATCH 057/146] do not define these functions if no MCPL present --- src/state_point.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index 31979c0c56..7c1a454476 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -642,7 +642,6 @@ void write_mcpl_source_point(const char *filename, bool surf_source_bank) } #endif - void write_source_bank(hid_t group_id, bool surf_source_bank) { hid_t banktype = h5banktype(); From 982377b0cdfc573469aad799852a0f2dd50b2e68 Mon Sep 17 00:00:00 2001 From: erkn Date: Wed, 5 Oct 2022 14:31:05 +0200 Subject: [PATCH 058/146] fix misnamed variable and remove accientally committed code --- src/source.cpp | 169 ++----------------------------------------------- 1 file changed, 4 insertions(+), 165 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index e1891c5e94..e35734747f 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -308,16 +308,16 @@ FileSource::FileSource(mcpl_file_t mcpl_file) switch(pdg){ case 2112: - omc_particle_.particle=ParticleType::neutron; + site_.particle=ParticleType::neutron; break; case 22: - omc_particle_.particle=ParticleType::photon; + site_.particle=ParticleType::photon; break; case 11: - omc_particle_.particle=ParticleType::electron; + site_.particle=ParticleType::electron; break; case -11: - omc_particle_.particle=ParticleType::positron; + site_.particle=ParticleType::positron; break; } @@ -401,167 +401,6 @@ CustomSourceWrapper::~CustomSourceWrapper() #endif } -<<<<<<< HEAD -<<<<<<< HEAD -#ifdef OPENMC_MCPL -//=========================================================================== -// Read particles from an MCPL-file -//=========================================================================== -MCPLFileSource::MCPLFileSource(std::string path) -{ - // Check if source file exists - if (!file_exists(path)) { - fatal_error(fmt::format("Source file '{}' does not exist.", path)); - } - - // Read the source from a binary file instead of sampling from some - // assumed source distribution - write_message(6, "Reading mcpl source file from {}",path); - - // Open the mcpl file - mcpl_file = mcpl_open_file(path.c_str()); - - //do checks on the mcpl_file to see if particles are many enough. - // should model this on the example source shown in the docs. - n_sites=mcpl_hdr_nparticles(mcpl_file); - - read_source_bank(sites_); -} -<<<<<<< HEAD - -MCPLFileSource::~MCPLFileSource(){ - mcpl_close_file(mcpl_file); -} - -SourceSite MCPLFileSource::sample(uint64_t* seed) const -{ - size_t i_site = sites_.size() * prn(seed); - return sites_[i_site]; -} - -void MCPLFileSource::read_source_bank(vector &sites_) -{ - sites_.resize(n_sites); - for (int i=0;ipdgcode; - while ( pdg!=2112 && pdg!=22 && pdg!=11 && pdg!=-11) { - mcpl_particle=mcpl_read(mcpl_file); - pdg=mcpl_particle->pdgcode; - //should check for file exhaustion. This could happen if particles are other than - //neutrons, photons, electrons, or positrons. - } - - switch(pdg){ - case 2112: - omc_particle_.particle=ParticleType::neutron; - break; - case 22: - omc_particle_.particle=ParticleType::photon; - break; - case 11: - omc_particle_.particle=ParticleType::electron; - break; - case -11: - omc_particle_.particle=ParticleType::positron; - break; - } - - //particle is good, convert to openmc-formalism - omc_particle_.r.x=mcpl_particle->position[0]; - omc_particle_.r.y=mcpl_particle->position[1]; - omc_particle_.r.z=mcpl_particle->position[2]; - - omc_particle_.u.x=mcpl_particle->direction[0]; - omc_particle_.u.y=mcpl_particle->direction[1]; - omc_particle_.u.z=mcpl_particle->direction[2]; - - //mcpl stores kinetic energy in MeV - omc_particle_.E=mcpl_particle->ekin*1e6; - //mcpl stores time in ms - omc_particle_.time=mcpl_particle->time*1e-3; - omc_particle_.wgt=mcpl_particle->weight; - omc_particle_.delayed_group=0; - return omc_particle_; -} -#endif //OPENMC_MCPL - -MCPLFileSource::~MCPLFileSource(){ - mcpl_close_file(mcpl_file); -} - -SourceSite MCPLFileSource::sample(uint64_t* seed) const -{ - size_t i_site = sites_.size() * prn(seed); - return sites_[i_site]; -} - -void MCPLFileSource::read_source_bank(vector &sites_) -{ - sites_.resize(n_sites); - for (int i=0;ipdgcode; - while ( pdg!=2112 && pdg!=22 && pdg!=11 && pdg!=-11) { - mcpl_particle=mcpl_read(mcpl_file); - pdg=mcpl_particle->pdgcode; - //should check for file exhaustion. This could happen if particles are other than - //neutrons, photons, electrons, or positrons. - } - - switch(pdg){ - case 2112: - omc_particle_.particle=ParticleType::neutron; - break; - case 22: - omc_particle_.particle=ParticleType::photon; - break; - case 11: - omc_particle_.particle=ParticleType::electron; - break; - case -11: - omc_particle_.particle=ParticleType::positron; - break; - } - - //particle is good, convert to openmc-formalism - omc_particle_.r.x=mcpl_particle->position[0]; - omc_particle_.r.y=mcpl_particle->position[1]; - omc_particle_.r.z=mcpl_particle->position[2]; - - omc_particle_.u.x=mcpl_particle->direction[0]; - omc_particle_.u.y=mcpl_particle->direction[1]; - omc_particle_.u.z=mcpl_particle->direction[2]; - - //mcpl stores kinetic energy in MeV - omc_particle_.E=mcpl_particle->ekin*1e6; - //mcpl stores time in ms - omc_particle_.time=mcpl_particle->time*1e-3; - omc_particle_.wgt=mcpl_particle->weight; - omc_particle_.delayed_group=0; - return omc_particle_; -} -#endif //OPENMC_MCPL //============================================================================== // Non-member functions From 12f088a5ce68c639c9772574eb69c4be5de452fe Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Thu, 6 Oct 2022 01:33:21 +0200 Subject: [PATCH 059/146] must have a full filename --- src/simulation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simulation.cpp b/src/simulation.cpp index 353ef99265..2c9e7e8566 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -408,7 +408,7 @@ void finalize_batch() } if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ - auto filename = settings::path_output + ".mcpl"; + auto filename = settings::path_output + "surface_source.mcpl"; write_mcpl_source_point(filename.c_str(), true); } From 0706a0eca305c8fc4a0a5cbfb0c5b6e46099753e Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 11 Oct 2022 00:46:32 +0200 Subject: [PATCH 060/146] fix malformed format string --- src/state_point.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index 7c1a454476..e197ee162a 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -625,9 +625,9 @@ void write_mcpl_source_point(const char *filename, bool surf_source_bank) //write_attribute(file_id, "filetype", "source"); //write header stuff (oopy in xml-files as binary blobs for instance)) if (VERSION_DEV){ - line=fmt::format("OpenMC {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_RELEASE}-development"); + line=fmt::format("OpenMC {0}.{1}.{2}-development",VERSION_MAJOR,VERSION_MINOR,VERSION_RELEASE); } else { - line=fmt::format("OpenMC {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_RELEASE}"); + line=fmt::format("OpenMC {0}.{1}.{2}",VERSION_MAJOR,VERSION_MINOR,VERSION_RELEASE); } mcpl_hdr_set_srcname(file_id,line.c_str()); } From aeadaf0b2f1a59fcd2c3f8cb3ad8fa7dab36e342 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 11 Oct 2022 00:48:44 +0200 Subject: [PATCH 061/146] fix typo causing unit length errors --- src/state_point.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index e197ee162a..a8a4be034e 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -802,9 +802,11 @@ void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) p.position[1]=_site->r.y; p.position[2]=_site->r.z; + //mcpl requires that the direction vector is unit length + //which is also the case in openmc p.direction[0]=_site->u.x; p.direction[1]=_site->u.y; - p.direction[2]=_site->u.x; + p.direction[2]=_site->u.z; //mcpl stores kinetic energy in MeV p.ekin=_site->E*1e-6; From 72251eb30a996e6aaa9672292a1483c69d53a652 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 11 Oct 2022 02:00:33 +0200 Subject: [PATCH 062/146] enable mcpl surf_source_write in the python layer --- openmc/settings.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/openmc/settings.py b/openmc/settings.py index 2d81216599..45ff0edc68 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -165,6 +165,7 @@ class Settings: banked (int) :max_particles: Maximum number of particles to be banked on surfaces per process (int) + :mcpl: Output in the form of an MCPL-file (bool) survival_biasing : bool Indicate whether survival biasing is to be used tabular_legendre : dict @@ -643,7 +644,7 @@ class Settings: cv.check_type('surface source writing options', surf_source_write, Mapping) for key, value in surf_source_write.items(): cv.check_value('surface source writing key', key, - ('surface_ids', 'max_particles')) + ('surface_ids', 'max_particles', 'mcpl')) if key == 'surface_ids': cv.check_type('surface ids for source banking', value, Iterable, Integral) @@ -655,6 +656,9 @@ class Settings: value, Integral) cv.check_greater_than('maximum particle banks on surfaces per process', value, 0) + elif key == 'mcpl': + cv.check_type('write to an MCPL-format file', value, bool) + self._surf_source_write = surf_source_write @confidence_intervals.setter @@ -1023,6 +1027,9 @@ class Settings: if 'max_particles' in self._surf_source_write: subelement = ET.SubElement(element, "max_particles") subelement.text = str(self._surf_source_write['max_particles']) + if 'mcpl' in self._surf_source_write: + subelement = ET.SubElement(element, "mcpl") + subelement.text = str(self._surf_source_write['mcpl']).lower() def _create_confidence_intervals(self, root): if self._confidence_intervals is not None: From bf0c5d7f9a8d118e4770d4ed4ca184c93aa30896 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 22 Jun 2022 22:50:07 +0200 Subject: [PATCH 063/146] add placeholder skeleton for MCPL-input --- include/openmc/source.h | 19 +++++++++++++++++++ src/source.cpp | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/openmc/source.h b/include/openmc/source.h index 04b9ff8563..0f1965cb8d 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -110,6 +110,25 @@ private: vector sites_; //!< Source sites from a file }; +//============================================================================== +// MCPL-file input source +//============================================================================== +class MCPLFileSource : public Source { +public: + // Constructors, destructors + MCPLFileSource(std::string path); + ~MCPLFileSource(); + + // Defer implementation to custom source library + SourceSite sample(uint64_t* seed) const override + +private: + vector sites_; //! Date: Thu, 23 Jun 2022 11:34:53 +0200 Subject: [PATCH 064/146] include mcpl header --- src/source.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/source.cpp b/src/source.cpp index 1e84f8334c..7c1184602a 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -33,6 +33,10 @@ #include "openmc/state_point.h" #include "openmc/xml_interface.h" +#ifdef HAS_MCPL +#include +#endif + namespace openmc { //============================================================================== From 249a554980801a3c2cc3be336369c95c0e447436 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Thu, 23 Jun 2022 11:35:46 +0200 Subject: [PATCH 065/146] declarations of MCPL-internals --- include/openmc/source.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/include/openmc/source.h b/include/openmc/source.h index 0f1965cb8d..24a3d10aed 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -119,11 +119,20 @@ public: MCPLFileSource(std::string path); ~MCPLFileSource(); - // Defer implementation to custom source library - SourceSite sample(uint64_t* seed) const override + // Properties + ParticleType particle_type() const { return particle_; } + + //! Sample from the external source distribution + //! \param[inout] seed Pseudorandom seed pointer + //! \return Site read from MCPL-file + SourceSite sample(uint64_t* seed) const override; private: + ParticleType particle_ {ParticleType::neutron}; //!< Type of particle emitted vector sites_; //! Date: Thu, 23 Jun 2022 11:37:05 +0200 Subject: [PATCH 066/146] internals of sample and constructor --- src/source.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 7c1184602a..3dfd007078 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -383,7 +383,7 @@ CustomSourceWrapper::~CustomSourceWrapper() } //=========================================================================== -// Read an MCPL-file +// Read particles from an MCPL-file //=========================================================================== MCPLFileSource::MCPLFileSource(std::string path) { @@ -394,12 +394,55 @@ MCPLFileSource::MCPLFileSource(std::string path) // Read the source from a binary file instead of sampling from some // assumed source distribution - write_message(6, "Reading source file from {}...", path); + write_message(6, "Reading mcpl source file from {}",path); // Open the mcpl file - id_t file_id = mcpl_open(path.c_str) - + mcpl_file = mcpl_open(path.c_str); + //do checks on the mcpl_file to see if particles are many enough. + // should model this on the example source shown in the docs. + uint64_t nparticles=mcpl_hdr_nparticles(mcpl_file); + +} + +MCPLFileSource::~MCPLFilsSource(){ + mcpl_close_file(mcpl_file); +} + +SourceSite MCPLFileSource::sample(uint64_t *seed){ + SourceSite omc_particle; + mcpl_particle *mcpl_particle; + //extract particle from mcpl-file + mcpl_particle=mcpl_reazd(mcplfile); + // check if it is a neutron or a photon. otherwise skip + while ( mcpl_particle->pdgcode!=2112 && mcpl_particle->pdgcode!=22 ) + { + mcpl_particle(mcpl_read(mcplfile); + //check for file exhaustion + } + + if(mcpl_particle->pdgcode=2112) { + omc_particle_=ParticleType::neutron; + } else { + omc_particle_=Particletype::photon; + } + + //particle is good, convert to openmc-formalism + omc_particle.r.x=mcpl_particle.x; + omc_particle.r.y=mcpl_particle.y; + omc_particle.r.z=mcpl_particle.z; + + omc_particle.u.x=mcpl_particle->direction[0]; + omc_particle.u.y=mcpl_particle->direction[1]; + omc_particle.u.z=mcpl_particle->direction[2]; + + //mcpl stores particles in MeV + omc_particle.E=mcpl_particle->ekin*1e6; + + omc_particle.t=mcpl_particle->time*1e-3; + omc_particle.wgt=mcpl_particle->weight; + omc_particle.delayed_group=0; + return omc_particle; } From 999acbba9a9f69648e9b91198fe4ff0792838b1d Mon Sep 17 00:00:00 2001 From: erkn Date: Mon, 27 Jun 2022 23:25:35 +0200 Subject: [PATCH 067/146] (wip): skeleton for input only test --- .../regression_tests/source_mcpl_file/test.py | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 tests/regression_tests/source_mcpl_file/test.py diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py new file mode 100644 index 0000000000..5a6a87d878 --- /dev/null +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -0,0 +1,52 @@ +import pathlib as pl +import os +import shutil +import subprocess +import textwrap + +import openmc +import pytest + +from tests.testing_harness import TestHarness + +def model(): + subprocess.run(['gcc','-o gen_dummt_mcpl.out','-lm','-lmcpl','gen_dummy_mcpl.c'] ) + subprocess.run(['./gen_dummy_mcpl.out']) + +class SourceMCPLFileTestHarness(TestHarness): + def execute_test(self): + """Run OpenMC with the appropriate arguments and check the outputs.""" + try: + self._create_input() + self._run_openmc() + self._test_output_created() + results = self._get_results() + self._write_results(results) + self._compare_results() + finally: + self._cleanup() + + def update_results(self): + """Update the results_true using the current version of OpenMC.""" + try: + self._create_input() + self._run_openmc() + self._test_output_created() + results = self._get_results() + self._write_results(results) + self._overwrite_results() + finally: + self._cleanup() + + def _test_output_created(self): + """Check that the output files were created""" + stat epoint = glob.glob(os.path.join(os.getcwd(), self._sp_name)) + assert len(statepoint) == 1, 'Either multiple or no statepoint files ' \ + 'exist.' + assert statepoint[0].endswith('h5'), \ + 'statepoint file does not end with h5.' + +def test_mcpl_source_file(): + harness = SourceMCPLFileTestHarness('statepoint.10.h5') + harness.main() + From 3e805cce158630e70df95abb5d20368983339031 Mon Sep 17 00:00:00 2001 From: erkn Date: Mon, 27 Jun 2022 23:26:01 +0200 Subject: [PATCH 068/146] c-prog to generate a dummy mcpl --- .../source_mcpl_file/gen_dummy_mcpl.c | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c diff --git a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c new file mode 100644 index 0000000000..7b5a933f18 --- /dev/null +++ b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include + +const int batches=10; +const int particles=10000; + +double rand01(){ + double r=rand()/((double) RAND_MAX); + return r; +} + + +int main(int argc, char **argv){ + char outfilename[128]; + snprintf(outfilename,127,"source.%d.mcpl",batches); + + /*generate an mcpl_header_of sorts*/ + mcpl_outfile_t outfile=mcpl_create_outfile(outfilename); + mcpl_particle_t *particle, Particle; + + char line[256]; + snprintf(line,255,"gen_dummy_mcpl.c"); + mcpl_hdr_set_srcname(outfile,line); + mcpl_enable_universal_pdgcode(outfile,2112);/*all particles are neutrons*/ + snprintf(line,255,"Dummy MCPL-file for testing OpenMC mcpl input"); + mcpl_hdr_add_comment(outfile,line); + + /*also add the instrument file and the command line as blobs*/ + FILE *fp; + if( (fp=fopen("gen_dummy_mcpl.c","rb"))!=NULL){ + unsigned char *buffer; + int size,status; + /*find the file size by seeking to end, "tell" the position, and then go back again*/ + fseek(fp, 0L, SEEK_END); + size = ftell(fp); // get current file pointer + fseek(fp, 0L, SEEK_SET); // seek back to beginning of file + if ( size && (buffer=malloc(size))!=NULL){ + if (size!=(fread(buffer,1,size,fp))){ + fprintf(stderr,"Warning: c source generator file not read cleanly\n"); + } + mcpl_hdr_add_data(outfile, "mcpl_point_source_file_generator", size, buffer); + free(buffer); + } + fclose(fp); + } else { + fprintf(stderr,"Warning: could not open c source generator file, hence not embedded.\n"); + } + + + /*the main particle loop*/ + particle=&Particle; + int i; + for (i=0;iposition[0]=0; + particle->position[1]=0; + particle->position[2]=0; + + /*generate a random direction on unit sphere*/ + double nrm=2.0; + double vx,vy,vz; + int iter=0; + do { + if(iter>100){ + printf("warning: exceeed max random vector attempts: at loop %d -> %g %d\n",i,nrm,iter); + } + vx=rand01()*2.0-1.0; + vy=rand01()*2.0-1.0; + vz=rand01()*2.0-1.0; + nrm=(vx*vx + vy*vy + vz*vz); + iter++; + } while (nrm>1.0); + vx/=sqrt(nrm); + vy/=sqrt(nrm); + vz/=sqrt(nrm); + particle->direction[0]=vx; + particle->direction[1]=vy; + particle->direction[2]=vz; + + /*generate the kinetic energy (in MeV) of the particle*/ + particle->ekin=1e-3; + + /*set time=0*/ + particle->time=0; + /*set weight*/ + particle->weight=1; + + particle->userflags=0; + mcpl_add_particle(outfile,particle); + } + mcpl_closeandgzip_outfile(outfile); +} From c6b42e828cf8bf9bccf77d296976ff83902fb346 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 5 Jul 2022 01:30:07 +0200 Subject: [PATCH 069/146] don't zip the output-file --- .../source_mcpl_file/gen_dummy_mcpl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c index 7b5a933f18..f35a07fc44 100644 --- a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c +++ b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c @@ -54,20 +54,20 @@ int main(int argc, char **argv){ int i; for (i=0;iposition[0]=0; particle->position[1]=0; particle->position[2]=0; - + /*generate a random direction on unit sphere*/ double nrm=2.0; double vx,vy,vz; int iter=0; do { if(iter>100){ - printf("warning: exceeed max random vector attempts: at loop %d -> %g %d\n",i,nrm,iter); + printf("Warning: Exceeded max random vector attempts: at loop %d -> %g %d\n",i,nrm,iter); } vx=rand01()*2.0-1.0; vy=rand01()*2.0-1.0; @@ -82,9 +82,9 @@ int main(int argc, char **argv){ particle->direction[1]=vy; particle->direction[2]=vz; - /*generate the kinetic energy (in MeV) of the particle*/ + /*generate the kinetic energy (in MeV) of the particle*/ particle->ekin=1e-3; - + /*set time=0*/ particle->time=0; /*set weight*/ @@ -93,5 +93,5 @@ int main(int argc, char **argv){ particle->userflags=0; mcpl_add_particle(outfile,particle); } - mcpl_closeandgzip_outfile(outfile); + mcpl_close_outfile(outfile); } From b2f83857e4af32848570abc33985a40587e77489 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 5 Jul 2022 01:53:14 +0200 Subject: [PATCH 070/146] now compiles fine if mcpl is indeed installed --- .../regression_tests/source_mcpl_file/test.py | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py index 5a6a87d878..0adf67f1aa 100644 --- a/tests/regression_tests/source_mcpl_file/test.py +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -3,16 +3,13 @@ import os import shutil import subprocess import textwrap - +import glob import openmc import pytest from tests.testing_harness import TestHarness -def model(): - subprocess.run(['gcc','-o gen_dummt_mcpl.out','-lm','-lmcpl','gen_dummy_mcpl.c'] ) - subprocess.run(['./gen_dummy_mcpl.out']) - + class SourceMCPLFileTestHarness(TestHarness): def execute_test(self): """Run OpenMC with the appropriate arguments and check the outputs.""" @@ -26,6 +23,10 @@ class SourceMCPLFileTestHarness(TestHarness): finally: self._cleanup() + def _create_input(self): + subprocess.run(['gcc','-o','gen_dummy_mcpl.out','gen_dummy_mcpl.c','-lm','-lmcpl']) + subprocess.run(['./gen_dummy_mcpl.out']) + def update_results(self): """Update the results_true using the current version of OpenMC.""" try: @@ -40,13 +41,19 @@ class SourceMCPLFileTestHarness(TestHarness): def _test_output_created(self): """Check that the output files were created""" - stat epoint = glob.glob(os.path.join(os.getcwd(), self._sp_name)) + statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name)) assert len(statepoint) == 1, 'Either multiple or no statepoint files ' \ 'exist.' assert statepoint[0].endswith('h5'), \ 'statepoint file does not end with h5.' + def _cleanup(self): + super()._cleanup() + source_mcpl=glob.glob(os.path.join(os.getcwd(),'source*.mcpl')) + for f in source_mcpl: + if (os.path.exists(f)): + os.remove(f) + def test_mcpl_source_file(): harness = SourceMCPLFileTestHarness('statepoint.10.h5') harness.main() - From 005189bfdfa9f956139af45c6504e22d2eb8659c Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Mon, 11 Jul 2022 09:49:29 +0200 Subject: [PATCH 071/146] fix misprints --- src/source.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 3dfd007078..3ef5ae16f0 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -413,7 +413,7 @@ SourceSite MCPLFileSource::sample(uint64_t *seed){ SourceSite omc_particle; mcpl_particle *mcpl_particle; //extract particle from mcpl-file - mcpl_particle=mcpl_reazd(mcplfile); + mcpl_particle=mcpl_read(mcplfile); // check if it is a neutron or a photon. otherwise skip while ( mcpl_particle->pdgcode!=2112 && mcpl_particle->pdgcode!=22 ) { @@ -421,9 +421,9 @@ SourceSite MCPLFileSource::sample(uint64_t *seed){ //check for file exhaustion } - if(mcpl_particle->pdgcode=2112) { + if(mcpl_particle->pdgcode==2112) { omc_particle_=ParticleType::neutron; - } else { + } else if (mcpl_particle->pdgcode==22){ omc_particle_=Particletype::photon; } @@ -436,9 +436,9 @@ SourceSite MCPLFileSource::sample(uint64_t *seed){ omc_particle.u.y=mcpl_particle->direction[1]; omc_particle.u.z=mcpl_particle->direction[2]; - //mcpl stores particles in MeV + //mcpl stores kinetic energy in MeV omc_particle.E=mcpl_particle->ekin*1e6; - + //mcpl stores time in ms omc_particle.t=mcpl_particle->time*1e-3; omc_particle.wgt=mcpl_particle->weight; omc_particle.delayed_group=0; From 935396e40bf97a6ba4a9dcf2dcac30b5a80056ba Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 12 Jul 2022 13:48:55 +0200 Subject: [PATCH 072/146] add necessary xmls --- tests/regression_tests/source_mcpl_file/geometry.xml | 8 ++++++++ tests/regression_tests/source_mcpl_file/materials.xml | 9 +++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/regression_tests/source_mcpl_file/geometry.xml create mode 100644 tests/regression_tests/source_mcpl_file/materials.xml diff --git a/tests/regression_tests/source_mcpl_file/geometry.xml b/tests/regression_tests/source_mcpl_file/geometry.xml new file mode 100644 index 0000000000..bc56030e18 --- /dev/null +++ b/tests/regression_tests/source_mcpl_file/geometry.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/regression_tests/source_mcpl_file/materials.xml b/tests/regression_tests/source_mcpl_file/materials.xml new file mode 100644 index 0000000000..2472a74717 --- /dev/null +++ b/tests/regression_tests/source_mcpl_file/materials.xml @@ -0,0 +1,9 @@ + + + + + + + + + From e87ebfebc29b07f9ca575629364165fc129ed512 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 12 Jul 2022 13:49:56 +0200 Subject: [PATCH 073/146] set seed to make test deteministic --- tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c index f35a07fc44..61eea95c6f 100644 --- a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c +++ b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c @@ -52,6 +52,7 @@ int main(int argc, char **argv){ /*the main particle loop*/ particle=&Particle; int i; + srand(1234); for (i=0;i Date: Tue, 12 Jul 2022 13:50:35 +0200 Subject: [PATCH 074/146] test target result --- tests/regression_tests/source_mcpl_file/results_true.dat | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/regression_tests/source_mcpl_file/results_true.dat diff --git a/tests/regression_tests/source_mcpl_file/results_true.dat b/tests/regression_tests/source_mcpl_file/results_true.dat new file mode 100644 index 0000000000..f2209006a1 --- /dev/null +++ b/tests/regression_tests/source_mcpl_file/results_true.dat @@ -0,0 +1,2 @@ +k-combined: +3.017557E-01 3.398770E-03 From c21ff938c79bd905bb0f6e60c7abbf960b3d87f3 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 12 Jul 2022 13:50:53 +0200 Subject: [PATCH 075/146] yet another necessary file --- tests/regression_tests/source_mcpl_file/settings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/regression_tests/source_mcpl_file/settings.xml diff --git a/tests/regression_tests/source_mcpl_file/settings.xml b/tests/regression_tests/source_mcpl_file/settings.xml new file mode 100644 index 0000000000..8b1510e0ce --- /dev/null +++ b/tests/regression_tests/source_mcpl_file/settings.xml @@ -0,0 +1,11 @@ + + + + 10 + 5 + 1000 + + + source.10.mcpl + + From a123d239ddf016167cef9c99add91c5f665ac19c Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 12 Jul 2022 14:40:01 +0200 Subject: [PATCH 076/146] add a check that the test input got created as intended --- tests/regression_tests/source_mcpl_file/test.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py index 0adf67f1aa..922ddddd31 100644 --- a/tests/regression_tests/source_mcpl_file/test.py +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -15,6 +15,7 @@ class SourceMCPLFileTestHarness(TestHarness): """Run OpenMC with the appropriate arguments and check the outputs.""" try: self._create_input() + self._test_input_created() self._run_openmc() self._test_output_created() results = self._get_results() @@ -31,6 +32,7 @@ class SourceMCPLFileTestHarness(TestHarness): """Update the results_true using the current version of OpenMC.""" try: self._create_input() + self._test_input_created() self._run_openmc() self._test_output_created() results = self._get_results() @@ -39,6 +41,14 @@ class SourceMCPLFileTestHarness(TestHarness): finally: self._cleanup() + def _test_input_created(self): + """Check that the input mcpl.file was generated as it should""" + mcplfile=glob.glob(os.path.join(os.getcwd(),'source.10.mcpl')) + assert len(mcplfile) == 1, 'Either multiple or no mcpl files ' \ + 'exist.' + assert mcplfile[0].endswith('mcpl'), \ + 'output file does not end with mcpl.' + def _test_output_created(self): """Check that the output files were created""" statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name)) @@ -55,5 +65,5 @@ class SourceMCPLFileTestHarness(TestHarness): os.remove(f) def test_mcpl_source_file(): - harness = SourceMCPLFileTestHarness('statepoint.10.h5') + harness = SourceMCPLFileTestHarness('source.10.mcpl') harness.main() From 1509420c214275d2c27b458caefdfc943cd413de Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 13 Jul 2022 10:25:55 +0200 Subject: [PATCH 077/146] fix bugs and finalize interface to MCPL --- include/openmc/source.h | 22 +++++++------ src/source.cpp | 73 +++++++++++++++++++++++++---------------- 2 files changed, 57 insertions(+), 38 deletions(-) diff --git a/include/openmc/source.h b/include/openmc/source.h index 24a3d10aed..0c944aef93 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -14,6 +14,10 @@ #include "openmc/particle.h" #include "openmc/vector.h" +#ifdef OPENMC_MCPL +#include +#endif + namespace openmc { //============================================================================== @@ -110,6 +114,7 @@ private: vector sites_; //!< Source sites from a file }; +#ifdef OPENMC_MCPL //============================================================================== // MCPL-file input source //============================================================================== @@ -119,24 +124,21 @@ public: MCPLFileSource(std::string path); ~MCPLFileSource(); - // Properties - ParticleType particle_type() const { return particle_; } - + // Methods //! Sample from the external source distribution //! \param[inout] seed Pseudorandom seed pointer //! \return Site read from MCPL-file - SourceSite sample(uint64_t* seed) const override; + SourceSite sample(uint64_t* seed) const; private: - ParticleType particle_ {ParticleType::neutron}; //!< Type of particle emitted + SourceSite read_single_particle() const; + void read_source_bank(vector &sites_); + vector sites_; //! #endif @@ -382,6 +382,7 @@ CustomSourceWrapper::~CustomSourceWrapper() #endif } +#ifdef OPENMC_MCPL //=========================================================================== // Read particles from an MCPL-file //=========================================================================== @@ -397,54 +398,70 @@ MCPLFileSource::MCPLFileSource(std::string path) write_message(6, "Reading mcpl source file from {}",path); // Open the mcpl file - mcpl_file = mcpl_open(path.c_str); + mcpl_file = mcpl_open_file(path.c_str()); //do checks on the mcpl_file to see if particles are many enough. // should model this on the example source shown in the docs. - uint64_t nparticles=mcpl_hdr_nparticles(mcpl_file); + n_sites=mcpl_hdr_nparticles(mcpl_file); + read_source_bank(sites_); } -MCPLFileSource::~MCPLFilsSource(){ +MCPLFileSource::~MCPLFileSource(){ mcpl_close_file(mcpl_file); } -SourceSite MCPLFileSource::sample(uint64_t *seed){ - SourceSite omc_particle; - mcpl_particle *mcpl_particle; +SourceSite MCPLFileSource::sample(uint64_t* seed) const +{ + size_t i_site = sites_.size() * prn(seed); + return sites_[i_site]; +} + +void MCPLFileSource::read_source_bank(vector &sites_) +{ + sites_.resize(n_sites); + for (int i=0;ipdgcode!=2112 && mcpl_particle->pdgcode!=22 ) - { - mcpl_particle(mcpl_read(mcplfile); - //check for file exhaustion + mcpl_particle=mcpl_read(mcpl_file); + // check if it is a neutron or a photon. otherwise skip + while ( mcpl_particle->pdgcode!=2112 && mcpl_particle->pdgcode!=22 ) { + mcpl_particle=mcpl_read(mcpl_file); + //should check for file exhaustion This could happen if particles are other than + //neutrons or photons } if(mcpl_particle->pdgcode==2112) { - omc_particle_=ParticleType::neutron; - } else if (mcpl_particle->pdgcode==22){ - omc_particle_=Particletype::photon; + omc_particle_.particle=ParticleType::neutron; + } else if (mcpl_particle->pdgcode==22) { + omc_particle_.particle=ParticleType::photon; } //particle is good, convert to openmc-formalism - omc_particle.r.x=mcpl_particle.x; - omc_particle.r.y=mcpl_particle.y; - omc_particle.r.z=mcpl_particle.z; + omc_particle_.r.x=mcpl_particle->position[0]; + omc_particle_.r.y=mcpl_particle->position[1]; + omc_particle_.r.z=mcpl_particle->position[2]; - omc_particle.u.x=mcpl_particle->direction[0]; - omc_particle.u.y=mcpl_particle->direction[1]; - omc_particle.u.z=mcpl_particle->direction[2]; + omc_particle_.u.x=mcpl_particle->direction[0]; + omc_particle_.u.y=mcpl_particle->direction[1]; + omc_particle_.u.z=mcpl_particle->direction[2]; //mcpl stores kinetic energy in MeV - omc_particle.E=mcpl_particle->ekin*1e6; + omc_particle_.E=mcpl_particle->ekin*1e6; //mcpl stores time in ms - omc_particle.t=mcpl_particle->time*1e-3; - omc_particle.wgt=mcpl_particle->weight; - omc_particle.delayed_group=0; - return omc_particle; + omc_particle_.time=mcpl_particle->time*1e-3; + omc_particle_.wgt=mcpl_particle->weight; + omc_particle_.delayed_group=0; + return omc_particle_; } - +#endif //OPENMC_MCPL //============================================================================== // Non-member functions From 2cbcd53f077b3afc7d01e0ebfe70ba1e0790fe39 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 13 Jul 2022 10:26:24 +0200 Subject: [PATCH 078/146] add an option to turn on mcpl-support --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 521b46cfc6..1408e85afc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ option(OPENMC_ENABLE_COVERAGE "Compile with coverage analysis flags" option(OPENMC_USE_DAGMC "Enable support for DAGMC (CAD) geometry" OFF) option(OPENMC_USE_LIBMESH "Enable support for libMesh unstructured mesh tallies" OFF) option(OPENMC_USE_MPI "Enable MPI" OFF) +option(OPENMC_USE_MCPL "Enable MPCPL" OFF) # Warnings for deprecated options foreach(OLD_OPT IN ITEMS "openmp" "profile" "coverage" "dagmc" "libmesh") @@ -185,6 +186,10 @@ if(OPENMC_ENABLE_COVERAGE) list(APPEND ldflags --coverage) endif() +if(OPENMC_USE_MCPL) + list(APPEND ldflags -lmcpl) +endif() + # Show flags being used message(STATUS "OpenMC C++ flags: ${cxxflags}") message(STATUS "OpenMC Linker flags: ${ldflags}") @@ -439,6 +444,10 @@ endif() if (OPENMC_USE_MPI) target_compile_definitions(libopenmc PUBLIC -DOPENMC_MPI) endif() +if(OPENMC_USE_MCPL) + target_compile_definitions(libopenmc PUBLIC -DOPENMC_MCPL) +endif() + # Set git SHA1 hash as a compile definition if(GIT_FOUND) From 46e648cf383df7b7b72b4f1f5c389f3c191c69a1 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 13 Jul 2022 10:27:18 +0200 Subject: [PATCH 079/146] add a source type to the settings interface --- src/settings.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/settings.cpp b/src/settings.cpp index eb0d4936c7..12e0a80509 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -430,6 +430,9 @@ void read_settings_xml() if (check_for_node(node, "file")) { auto path = get_node_value(node, "file", false, true); model::external_sources.push_back(make_unique(path)); + } else if (check_for_node(node, "mcpl")) { + auto path = get_node_value(node, "mcpl", false, true); + model::external_sources.push_back(make_unique(path)); } else if (check_for_node(node, "library")) { // Get shared library path and parameters auto path = get_node_value(node, "library", false, true); From 96ae7b4228798549d1bb969777a73f926ba19465 Mon Sep 17 00:00:00 2001 From: erkn Date: Sat, 9 Jul 2022 16:31:00 +0200 Subject: [PATCH 080/146] fix misprints --- src/source.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source.cpp b/src/source.cpp index bdfe5349c8..4b27bdc7eb 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -392,7 +392,7 @@ MCPLFileSource::MCPLFileSource(std::string path) if (!file_exists(path)) { fatal_error(fmt::format("Source file '{}' does not exist.", path)); } - + // Read the source from a binary file instead of sampling from some // assumed source distribution write_message(6, "Reading mcpl source file from {}",path); From 2fa445193870a1bd6818fd82d1ea755e890c2309 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 13 Jul 2022 12:13:10 +0200 Subject: [PATCH 081/146] only add mcpl-support if OPENMC_MCPL is defined --- src/settings.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/settings.cpp b/src/settings.cpp index 12e0a80509..d419cab06f 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -430,9 +430,11 @@ void read_settings_xml() if (check_for_node(node, "file")) { auto path = get_node_value(node, "file", false, true); model::external_sources.push_back(make_unique(path)); +#ifdef OPENMC_MCPL } else if (check_for_node(node, "mcpl")) { auto path = get_node_value(node, "mcpl", false, true); model::external_sources.push_back(make_unique(path)); +#endif } else if (check_for_node(node, "library")) { // Get shared library path and parameters auto path = get_node_value(node, "library", false, true); From 2773add0473f28d225c1ad9efbc6fcc9e97230ed Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 13 Jul 2022 14:13:33 +0200 Subject: [PATCH 082/146] needed to avoid name clashes with other tests --- tests/regression_tests/source_mcpl_file/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/regression_tests/source_mcpl_file/__init__.py diff --git a/tests/regression_tests/source_mcpl_file/__init__.py b/tests/regression_tests/source_mcpl_file/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From bb8c022d77f8e22ad3d856edeb2b1a16a6311067 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 13 Jul 2022 20:55:53 +0200 Subject: [PATCH 083/146] fail without tripping the entire test-process --- tests/regression_tests/source_mcpl_file/test.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py index 922ddddd31..f55a769047 100644 --- a/tests/regression_tests/source_mcpl_file/test.py +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -1,11 +1,6 @@ -import pathlib as pl import os -import shutil import subprocess -import textwrap import glob -import openmc -import pytest from tests.testing_harness import TestHarness @@ -25,7 +20,8 @@ class SourceMCPLFileTestHarness(TestHarness): self._cleanup() def _create_input(self): - subprocess.run(['gcc','-o','gen_dummy_mcpl.out','gen_dummy_mcpl.c','-lm','-lmcpl']) + compiled=subprocess.run(['gcc','-o','gen_dummy_mcpl.out','gen_dummy_mcpl.c','-lm','-lmcpl']) + assert compiled==0, 'Could not compile mcpl-file generator code' subprocess.run(['./gen_dummy_mcpl.out']) def update_results(self): From 2730f1954f154df24ed7171e9dda39e4325c1b2c Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 6 Sep 2022 09:11:41 +0200 Subject: [PATCH 084/146] allow electrons and positrons as well --- src/source.cpp | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 4b27bdc7eb..cfcd79e0a6 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -429,19 +429,30 @@ SourceSite MCPLFileSource::read_single_particle() const { SourceSite omc_particle_; const mcpl_particle_t *mcpl_particle; - //extract particle from mcpl-file + // extract particle from mcpl-file mcpl_particle=mcpl_read(mcpl_file); - // check if it is a neutron or a photon. otherwise skip - while ( mcpl_particle->pdgcode!=2112 && mcpl_particle->pdgcode!=22 ) { + // check if it is a neutron, photon, electron, or positron. Otherwise skip. + int pdg=mcpl_particle->pdgcode; + while ( pdg!=2112 && pdg!=22 && pdg!=11 && pdg!=-11) { mcpl_particle=mcpl_read(mcpl_file); - //should check for file exhaustion This could happen if particles are other than - //neutrons or photons + pdg=mcpl_particle->pdgcode; + //should check for file exhaustion. This could happen if particles are other than + //neutrons, photons, electrons, or positrons. } - if(mcpl_particle->pdgcode==2112) { - omc_particle_.particle=ParticleType::neutron; - } else if (mcpl_particle->pdgcode==22) { - omc_particle_.particle=ParticleType::photon; + switch(pdg){ + case 2112: + omc_particle_.particle=ParticleType::neutron; + break; + case 22: + omc_particle_.particle=ParticleType::photon; + break; + case 11: + omc_particle_.particle=ParticleType::electron; + break; + case -11: + omc_particle_.particle=ParticleType::positron; + break; } //particle is good, convert to openmc-formalism From 3b052f03cfce7605bf96641346800022e462a02a Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 6 Sep 2022 09:12:01 +0200 Subject: [PATCH 085/146] expose a python function to check for mcpl --- openmc/lib/__init__.py | 3 +++ src/source.cpp | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/openmc/lib/__init__.py b/openmc/lib/__init__.py index c14b0d9c28..1e337fc073 100644 --- a/openmc/lib/__init__.py +++ b/openmc/lib/__init__.py @@ -48,6 +48,9 @@ def _coord_levels(): def _libmesh_enabled(): return c_bool.in_dll(_dll, "LIBMESH_ENABLED").value +def _mcpl_enabled(): + return c_bool.in_dll(_dll, "MCPL_ENABLED").value + from .error import * from .core import * from .nuclide import * diff --git a/src/source.cpp b/src/source.cpp index cfcd79e0a6..dbfcd1ceba 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -43,6 +43,12 @@ namespace openmc { // Global variables //============================================================================== +#ifdef OPENMC_MCPL +const bool MCPL_ENABLED = true; +#else +const bool MCPL_ENABLED = false; +#endif + namespace model { vector> external_sources; From 5640bdb9eb25bc5675928490ef4bf925e9155ae1 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Fri, 15 Jul 2022 21:35:59 +0200 Subject: [PATCH 086/146] fix typo Co-authored-by: Paul Romano --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1408e85afc..32beb41ecd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ option(OPENMC_ENABLE_COVERAGE "Compile with coverage analysis flags" option(OPENMC_USE_DAGMC "Enable support for DAGMC (CAD) geometry" OFF) option(OPENMC_USE_LIBMESH "Enable support for libMesh unstructured mesh tallies" OFF) option(OPENMC_USE_MPI "Enable MPI" OFF) -option(OPENMC_USE_MCPL "Enable MPCPL" OFF) +option(OPENMC_USE_MCPL "Enable MCPL" OFF) # Warnings for deprecated options foreach(OLD_OPT IN ITEMS "openmp" "profile" "coverage" "dagmc" "libmesh") From 95338eada002270c437906cb55607945dabe39b0 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 9 Aug 2022 08:12:19 +0200 Subject: [PATCH 087/146] refactor MCPL file read part of FileSource A new constructor is added to FileSource that reads from a given MCPL-file. --- include/openmc/source.h | 30 +-------- src/settings.cpp | 2 +- src/source.cpp | 139 ++++++++++++++-------------------------- 3 files changed, 52 insertions(+), 119 deletions(-) diff --git a/include/openmc/source.h b/include/openmc/source.h index 0c944aef93..bb7e2d55f7 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -106,7 +106,9 @@ class FileSource : public Source { public: // Constructors explicit FileSource(std::string path); - +#ifdef OPENMC_MCPL + explicit FileSource(mcpl_file_t mcpl_file); +#endif // Methods SourceSite sample(uint64_t* seed) const override; @@ -114,32 +116,6 @@ private: vector sites_; //!< Source sites from a file }; -#ifdef OPENMC_MCPL -//============================================================================== -// MCPL-file input source -//============================================================================== -class MCPLFileSource : public Source { -public: - // Constructors, destructors - MCPLFileSource(std::string path); - ~MCPLFileSource(); - - // Methods - //! Sample from the external source distribution - //! \param[inout] seed Pseudorandom seed pointer - //! \return Site read from MCPL-file - SourceSite sample(uint64_t* seed) const; - -private: - SourceSite read_single_particle() const; - void read_source_bank(vector &sites_); - - vector sites_; //!(path)); + model::external_sources.push_back(make_unique(mcpl_open_file(path.c_str()))); #endif } else if (check_for_node(node, "library")) { // Get shared library path and parameters diff --git a/src/source.cpp b/src/source.cpp index dbfcd1ceba..e43f03929b 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -329,6 +329,54 @@ FileSource::FileSource(std::string path) file_close(file_id); } +#ifdef OPENMC_MCPL +FileSource::FileSource(mcpl_file_t mcpl_file) +{ + //do checks on the mcpl_file to see if particles are many enough. + // should model this on the example source shown in the docs. + size_t n_sites=mcpl_hdr_nparticles(mcpl_file); + + sites_.resize(n_sites); + for (int i=0;ipdgcode!=2112 && mcpl_particle->pdgcode!=22 ) { + mcpl_particle=mcpl_read(mcpl_file); + //should check for file exhaustion This could happen if particles are other than + //neutrons or photons + } + + if(mcpl_particle->pdgcode==2112) { + site_.particle=ParticleType::neutron; + } else if (mcpl_particle->pdgcode==22) { + site_.particle=ParticleType::photon; + } + + //particle is good, convert to openmc-formalism + site_.r.x=mcpl_particle->position[0]; + site_.r.y=mcpl_particle->position[1]; + site_.r.z=mcpl_particle->position[2]; + + site_.u.x=mcpl_particle->direction[0]; + site_.u.y=mcpl_particle->direction[1]; + site_.u.z=mcpl_particle->direction[2]; + + //mcpl stores kinetic energy in MeV + site_.E=mcpl_particle->ekin*1e6; + //mcpl stores time in ms + site_.time=mcpl_particle->time*1e-3; + site_.wgt=mcpl_particle->weight; + site_.delayed_group=0; + sites_[i]=site_; + } + mcpl_close_file(mcpl_file); +} +#endif //OPENMC_MCPL + SourceSite FileSource::sample(uint64_t* seed) const { size_t i_site = sites_.size() * prn(seed); @@ -388,97 +436,6 @@ CustomSourceWrapper::~CustomSourceWrapper() #endif } -#ifdef OPENMC_MCPL -//=========================================================================== -// Read particles from an MCPL-file -//=========================================================================== -MCPLFileSource::MCPLFileSource(std::string path) -{ - // Check if source file exists - if (!file_exists(path)) { - fatal_error(fmt::format("Source file '{}' does not exist.", path)); - } - - // Read the source from a binary file instead of sampling from some - // assumed source distribution - write_message(6, "Reading mcpl source file from {}",path); - - // Open the mcpl file - mcpl_file = mcpl_open_file(path.c_str()); - - //do checks on the mcpl_file to see if particles are many enough. - // should model this on the example source shown in the docs. - n_sites=mcpl_hdr_nparticles(mcpl_file); - - read_source_bank(sites_); -} - -MCPLFileSource::~MCPLFileSource(){ - mcpl_close_file(mcpl_file); -} - -SourceSite MCPLFileSource::sample(uint64_t* seed) const -{ - size_t i_site = sites_.size() * prn(seed); - return sites_[i_site]; -} - -void MCPLFileSource::read_source_bank(vector &sites_) -{ - sites_.resize(n_sites); - for (int i=0;ipdgcode; - while ( pdg!=2112 && pdg!=22 && pdg!=11 && pdg!=-11) { - mcpl_particle=mcpl_read(mcpl_file); - pdg=mcpl_particle->pdgcode; - //should check for file exhaustion. This could happen if particles are other than - //neutrons, photons, electrons, or positrons. - } - - switch(pdg){ - case 2112: - omc_particle_.particle=ParticleType::neutron; - break; - case 22: - omc_particle_.particle=ParticleType::photon; - break; - case 11: - omc_particle_.particle=ParticleType::electron; - break; - case -11: - omc_particle_.particle=ParticleType::positron; - break; - } - - //particle is good, convert to openmc-formalism - omc_particle_.r.x=mcpl_particle->position[0]; - omc_particle_.r.y=mcpl_particle->position[1]; - omc_particle_.r.z=mcpl_particle->position[2]; - - omc_particle_.u.x=mcpl_particle->direction[0]; - omc_particle_.u.y=mcpl_particle->direction[1]; - omc_particle_.u.z=mcpl_particle->direction[2]; - - //mcpl stores kinetic energy in MeV - omc_particle_.E=mcpl_particle->ekin*1e6; - //mcpl stores time in ms - omc_particle_.time=mcpl_particle->time*1e-3; - omc_particle_.wgt=mcpl_particle->weight; - omc_particle_.delayed_group=0; - return omc_particle_; -} -#endif //OPENMC_MCPL //============================================================================== // Non-member functions From 5462216deba46d017db7905a312f0ed458cde6a7 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 6 Sep 2022 02:22:21 +0200 Subject: [PATCH 088/146] wip add MCPL-out to openmc code for writing a source_bank/point compiles but is untested --- include/openmc/state_point.h | 9 +++ src/state_point.cpp | 125 +++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/include/openmc/state_point.h b/include/openmc/state_point.h index 5ada2bf88d..2d92c935a6 100644 --- a/include/openmc/state_point.h +++ b/include/openmc/state_point.h @@ -9,6 +9,10 @@ #include "openmc/particle.h" #include "openmc/vector.h" +#ifdef OPENMC_MCPL +#include +#endif + namespace openmc { void load_state_point(); @@ -21,5 +25,10 @@ void write_tally_results_nr(hid_t file_id); void restart_set_keff(); void write_unstructured_mesh_results(); +#ifdef OPENMC_MCPL +void write_mcpl_source_point(const char *filename_, bool surf_source_bank = false); +void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank); +#endif + } // namespace openmc #endif // OPENMC_STATE_POINT_H diff --git a/src/state_point.cpp b/src/state_point.cpp index 470dd77182..dfbd7f65c5 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -28,6 +28,10 @@ #include "openmc/timer.h" #include "openmc/vector.h" +#ifdef OPENMC_MCPL +#include +#endif + namespace openmc { extern "C" int openmc_statepoint_write(const char* filename, bool* write_source) @@ -599,6 +603,45 @@ void write_source_point(const char* filename, bool surf_source_bank) file_close(file_id); } +void write_mcpl_point(const char *filename, bool surf_source_bank) +{ + std::string filename_; + if (filename) { + filename_ = filename; + } else { + // Determine width for zero padding + int w = std::to_string(settings::n_max_batches).size(); + + filename_ = fmt::format("{0}source.{1:0{2}}.mcpl", settings::path_output, + simulation::current_batch, w); + } + + mcpl_outfile_t file_id; + + std::string line; + if (mpi::master) { + // this must be rewritten: file_open is h5-specific + file_id = mcpl_create_outfile(filename_.c_str()); + //write_attribute(file_id, "filetype", "source"); + //write header stuff (oopy in xml-files as binary blobs for instance)) + if (VERSION_DEV){ + line=fmt::format("OpenMC {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_RELEASE}-development"); + } else { + line=fmt::format("OpenMC {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_RELEASE}"); + } + mcpl_hdr_set_srcname(file_id,line.c_str()); + } + + write_mcpl_source_bank(file_id, surf_source_bank); + + if (mpi::master) { + //change this - this is h5 specific + mcpl_closeandgzip_outfile(file_id); + } + +} + + void write_source_bank(hid_t group_id, bool surf_source_bank) { hid_t banktype = h5banktype(); @@ -715,6 +758,88 @@ void write_source_bank(hid_t group_id, bool surf_source_bank) H5Tclose(banktype); } +void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) +{ + int64_t dims_size = settings::n_particles; + int64_t count_size = simulation::work_per_rank; + + // Set vectors for source bank and starting bank index of each process + vector* bank_index = &simulation::work_index; + vector* source_bank = &simulation::source_bank; + vector surf_source_index_vector; + vector surf_source_bank_vector; + + if(surf_source_bank) { + surf_source_index_vector = calculate_surf_source_size(); + dims_size = surf_source_index_vector[mpi::n_procs]; + count_size = simulation::surf_source_bank.size(); + + bank_index = &surf_source_index_vector; + + // Copy data in a SharedArray into a vector. + surf_source_bank_vector.resize(count_size); + surf_source_bank_vector.assign(simulation::surf_source_bank.data(), + simulation::surf_source_bank.data() + count_size); + source_bank = &surf_source_bank_vector; + } + + if (mpi::master) { + //write particles from the master node + //loop over the other nodes and receive data - then write those. + for (int i = 0; i < mpi::n_procs; ++i) { +#ifdef OPENMC_MPI + if (i>0) + MPI_Recv(source_bank->data(), count[0], mpi::source_site, i, i, + mpi::intracomm, MPI_STATUS_IGNORE); +#endif + //now write the source_banke data again. + for (vector::iterator _site=source_bank->begin(); _site!=source_bank->end();_site++){ + //particle is now at the iterator + //write it to the mcpl-file + mcpl_particle_t p; + p.position[0]=_site->r.x; + p.position[1]=_site->r.y; + p.position[2]=_site->r.z; + + p.direction[0]=_site->u.x; + p.direction[1]=_site->u.y; + p.direction[2]=_site->u.x; + + //mcpl stores kinetic energy in MeV + p.ekin=_site->E*1e-6; + + p.time=_site->time*1e3; + + p.weight=_site->wgt; + + switch(_site->particle){ + case ParticleType::neutron: + p.pdgcode=2112; + break; + case ParticleType::photon: + p.pdgcode=22; + break; + case ParticleType::electron: + p.pdgcode=11; + break; + case ParticleType::positron: + p.pdgcode=-11; + break; + } + + mcpl_add_particle(file_id,&p); + } + } + } else { +#ifdef OPENMC_MPI + MPI_Send(source_bank->data(), count_size, mpi::source_site, 0, mpi::rank, + mpi::intracomm); +#endif + } + +} + + // Determine member names of a compound HDF5 datatype std::string dtype_member_names(hid_t dtype_id) { From 1519f4f3e6acc5d91dbbb7c952589a2fe39e5537 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 6 Sep 2022 23:06:19 +0200 Subject: [PATCH 089/146] add a trigger to simulation control --- src/simulation.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/simulation.cpp b/src/simulation.cpp index d7292cb9d9..9c19c2106d 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -407,6 +407,13 @@ void finalize_batch() auto filename = settings::path_output + "surface_source.h5"; write_source_point(filename.c_str(), true); } + + if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ + auto filename = settings::path_output + ".mcpl"; + write_mcplt_source_point(filename.c_str(), true); + } + + } void initialize_generation() From f76e416ee64524ef06705db4f2fa306e4be472f1 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 5 Oct 2022 10:56:36 +0200 Subject: [PATCH 090/146] use find_package instead - MCPL now supports this --- CMakeLists.txt | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 32beb41ecd..24018eb0f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,6 +159,13 @@ if(${HDF5_VERSION} VERSION_GREATER_EQUAL 1.12.0) list(APPEND cxxflags -DH5Oget_info_by_idx_vers=1 -DH5O_info_t_vers=1) endif() +#=============================================================================== +# MCPL +#=============================================================================== +if (OPENMC_USE_MCPL) + find_package(MCPL REQUIRED) +endif() + #=============================================================================== # Set compile/link flags based on which compiler is being used #=============================================================================== @@ -186,10 +193,6 @@ if(OPENMC_ENABLE_COVERAGE) list(APPEND ldflags --coverage) endif() -if(OPENMC_USE_MCPL) - list(APPEND ldflags -lmcpl) -endif() - # Show flags being used message(STATUS "OpenMC C++ flags: ${cxxflags}") message(STATUS "OpenMC Linker flags: ${ldflags}") @@ -444,10 +447,6 @@ endif() if (OPENMC_USE_MPI) target_compile_definitions(libopenmc PUBLIC -DOPENMC_MPI) endif() -if(OPENMC_USE_MCPL) - target_compile_definitions(libopenmc PUBLIC -DOPENMC_MCPL) -endif() - # Set git SHA1 hash as a compile definition if(GIT_FOUND) @@ -491,6 +490,11 @@ if (OPENMC_USE_MPI) target_link_libraries(libopenmc MPI::MPI_CXX) endif() +if (OPENMC_USE_MCPL) + target_compile_definitions(libopenmc PUBLIC OPENMC_MCPL) + target_link_libraries(libopenmc MCPL::mcpl) +endif() + #=============================================================================== # openmc executable #=============================================================================== From b6aa2dc429bf7545826991c426bf0843624c7377 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 5 Oct 2022 10:59:02 +0200 Subject: [PATCH 091/146] add mcpl-output settings --- include/openmc/settings.h | 1 + src/settings.cpp | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/openmc/settings.h b/include/openmc/settings.h index 1e061b235b..66825867d8 100644 --- a/include/openmc/settings.h +++ b/include/openmc/settings.h @@ -48,6 +48,7 @@ extern bool source_latest; //!< write latest source at each batch? extern bool source_separate; //!< write source to separate file? extern bool source_write; //!< write source in HDF5 files? extern bool surf_source_write; //!< write surface source file? +extern bool surf_mcpl_write; //!< write surface mcpl file? extern bool surf_source_read; //!< read surface source file? extern bool survival_biasing; //!< use survival biasing? extern bool temperature_multipole; //!< use multipole data? diff --git a/src/settings.cpp b/src/settings.cpp index 11dd96e025..d1762596c6 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -61,6 +61,7 @@ bool source_latest {false}; bool source_separate {false}; bool source_write {true}; bool surf_source_write {false}; +bool surf_mcpl_write {false}; bool surf_source_read {false}; bool survival_biasing {false}; bool temperature_multipole {false}; @@ -682,9 +683,14 @@ void read_settings_xml() max_surface_particles = std::stoll(get_node_value(node_ssw, "max_particles")); } +#ifdef OPENMC_MCPL + if(check_for_node(node_ssw, "mcpl")){ + surf_mcpl_write=true; + } +#endif } - // If source is not seperate and is to be written out in the statepoint file, + // If source is not separate and is to be written out in the statepoint file, // make sure that the sourcepoint batch numbers are contained in the // statepoint list if (!source_separate) { From 22ce618601c8dbefd4759c51d50b7a17ba09dbba Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 5 Oct 2022 10:59:28 +0200 Subject: [PATCH 092/146] fix typo --- src/simulation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simulation.cpp b/src/simulation.cpp index 9c19c2106d..fcb115849d 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -410,7 +410,7 @@ void finalize_batch() if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ auto filename = settings::path_output + ".mcpl"; - write_mcplt_source_point(filename.c_str(), true); + write_mcpl_source_point(filename.c_str(), true); } From 76e726b527c1b738b8b5842999e69ec4d6c4c57d Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 5 Oct 2022 11:00:39 +0200 Subject: [PATCH 093/146] add cond. compilation guards for MCPL functions --- src/state_point.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index dfbd7f65c5..14a5411283 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -603,7 +603,8 @@ void write_source_point(const char* filename, bool surf_source_bank) file_close(file_id); } -void write_mcpl_point(const char *filename, bool surf_source_bank) +#ifdef OPENMC_MCPL +void write_mcpl_source_point(const char *filename, bool surf_source_bank) { std::string filename_; if (filename) { @@ -640,7 +641,7 @@ void write_mcpl_point(const char *filename, bool surf_source_bank) } } - +#endif void write_source_bank(hid_t group_id, bool surf_source_bank) { @@ -758,6 +759,7 @@ void write_source_bank(hid_t group_id, bool surf_source_bank) H5Tclose(banktype); } +#ifdef OPENMC_MCPL void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) { int64_t dims_size = settings::n_particles; @@ -838,7 +840,7 @@ void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) } } - +#endif // Determine member names of a compound HDF5 datatype std::string dtype_member_names(hid_t dtype_id) From bdc76d95fce06f3e94dea3afa9b8305309958179 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Fri, 16 Sep 2022 16:07:22 +0200 Subject: [PATCH 094/146] refactor MCPL file read part of FileSource A new constructor is added to FileSource that reads from a given MCPL-file. --- src/source.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/source.cpp b/src/source.cpp index e43f03929b..cf584e12ea 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -437,6 +437,79 @@ CustomSourceWrapper::~CustomSourceWrapper() } +MCPLFileSource::~MCPLFileSource(){ + mcpl_close_file(mcpl_file); +} + +SourceSite MCPLFileSource::sample(uint64_t* seed) const +{ + size_t i_site = sites_.size() * prn(seed); + return sites_[i_site]; +} + +void MCPLFileSource::read_source_bank(vector &sites_) +{ + sites_.resize(n_sites); + for (int i=0;ipdgcode; + while ( pdg!=2112 && pdg!=22 && pdg!=11 && pdg!=-11) { + mcpl_particle=mcpl_read(mcpl_file); + pdg=mcpl_particle->pdgcode; + //should check for file exhaustion. This could happen if particles are other than + //neutrons, photons, electrons, or positrons. + } + + switch(pdg){ + case 2112: + omc_particle_.particle=ParticleType::neutron; + break; + case 22: + omc_particle_.particle=ParticleType::photon; + break; + case 11: + omc_particle_.particle=ParticleType::electron; + break; + case -11: + omc_particle_.particle=ParticleType::positron; + break; + } + + //particle is good, convert to openmc-formalism + omc_particle_.r.x=mcpl_particle->position[0]; + omc_particle_.r.y=mcpl_particle->position[1]; + omc_particle_.r.z=mcpl_particle->position[2]; + + omc_particle_.u.x=mcpl_particle->direction[0]; + omc_particle_.u.y=mcpl_particle->direction[1]; + omc_particle_.u.z=mcpl_particle->direction[2]; + + //mcpl stores kinetic energy in MeV + omc_particle_.E=mcpl_particle->ekin*1e6; + //mcpl stores time in ms + omc_particle_.time=mcpl_particle->time*1e-3; + omc_particle_.wgt=mcpl_particle->weight; + omc_particle_.delayed_group=0; + return omc_particle_; +} +#endif //OPENMC_MCPL +======= +>>>>>>> 380cfc150b449ef56debb5261caa010a52c42bdd +======= +#endif +>>>>>>> 71568d4f4 (refactor MCPL file read part of FileSource) +>>>>>>> 55f2be19e (refactor MCPL file read part of FileSource) + //============================================================================== // Non-member functions //============================================================================== From 6bceb7c30c05509823a7b0a6cb2e518d3a7ff5e4 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 6 Sep 2022 02:22:21 +0200 Subject: [PATCH 095/146] wip add MCPL-out to openmc code for writing a source_bank/point compiles but is untested --- src/source.cpp | 6 ------ src/state_point.cpp | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index cf584e12ea..99ec3a74d1 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -503,12 +503,6 @@ SourceSite MCPLFileSource::read_single_particle() const return omc_particle_; } #endif //OPENMC_MCPL -======= ->>>>>>> 380cfc150b449ef56debb5261caa010a52c42bdd -======= -#endif ->>>>>>> 71568d4f4 (refactor MCPL file read part of FileSource) ->>>>>>> 55f2be19e (refactor MCPL file read part of FileSource) //============================================================================== // Non-member functions diff --git a/src/state_point.cpp b/src/state_point.cpp index 14a5411283..1b133a1215 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -643,6 +643,7 @@ void write_mcpl_source_point(const char *filename, bool surf_source_bank) } #endif + void write_source_bank(hid_t group_id, bool surf_source_bank) { hid_t banktype = h5banktype(); From 56cddd25e2d8540da5356fbbe8f3bbde13ce11b5 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 4 Oct 2022 10:11:06 +0200 Subject: [PATCH 096/146] do not define these functions if no MCPL present --- src/state_point.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index 1b133a1215..14a5411283 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -643,7 +643,6 @@ void write_mcpl_source_point(const char *filename, bool surf_source_bank) } #endif - void write_source_bank(hid_t group_id, bool surf_source_bank) { hid_t banktype = h5banktype(); From 3c33ec3b9fc513794e7e683620fbce99aedb9bcb Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 9 Aug 2022 08:12:19 +0200 Subject: [PATCH 097/146] refactor MCPL file read part of FileSource A new constructor is added to FileSource that reads from a given MCPL-file. --- src/source.cpp | 67 -------------------------------------------------- 1 file changed, 67 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 99ec3a74d1..e43f03929b 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -437,73 +437,6 @@ CustomSourceWrapper::~CustomSourceWrapper() } -MCPLFileSource::~MCPLFileSource(){ - mcpl_close_file(mcpl_file); -} - -SourceSite MCPLFileSource::sample(uint64_t* seed) const -{ - size_t i_site = sites_.size() * prn(seed); - return sites_[i_site]; -} - -void MCPLFileSource::read_source_bank(vector &sites_) -{ - sites_.resize(n_sites); - for (int i=0;ipdgcode; - while ( pdg!=2112 && pdg!=22 && pdg!=11 && pdg!=-11) { - mcpl_particle=mcpl_read(mcpl_file); - pdg=mcpl_particle->pdgcode; - //should check for file exhaustion. This could happen if particles are other than - //neutrons, photons, electrons, or positrons. - } - - switch(pdg){ - case 2112: - omc_particle_.particle=ParticleType::neutron; - break; - case 22: - omc_particle_.particle=ParticleType::photon; - break; - case 11: - omc_particle_.particle=ParticleType::electron; - break; - case -11: - omc_particle_.particle=ParticleType::positron; - break; - } - - //particle is good, convert to openmc-formalism - omc_particle_.r.x=mcpl_particle->position[0]; - omc_particle_.r.y=mcpl_particle->position[1]; - omc_particle_.r.z=mcpl_particle->position[2]; - - omc_particle_.u.x=mcpl_particle->direction[0]; - omc_particle_.u.y=mcpl_particle->direction[1]; - omc_particle_.u.z=mcpl_particle->direction[2]; - - //mcpl stores kinetic energy in MeV - omc_particle_.E=mcpl_particle->ekin*1e6; - //mcpl stores time in ms - omc_particle_.time=mcpl_particle->time*1e-3; - omc_particle_.wgt=mcpl_particle->weight; - omc_particle_.delayed_group=0; - return omc_particle_; -} -#endif //OPENMC_MCPL - //============================================================================== // Non-member functions //============================================================================== From 52cf6823e6c1df7dbcc30b0c860412dc124a18a3 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 6 Sep 2022 02:22:21 +0200 Subject: [PATCH 098/146] wip add MCPL-out to openmc code for writing a source_bank/point compiles but is untested --- src/state_point.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/state_point.cpp b/src/state_point.cpp index 14a5411283..1b133a1215 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -643,6 +643,7 @@ void write_mcpl_source_point(const char *filename, bool surf_source_bank) } #endif + void write_source_bank(hid_t group_id, bool surf_source_bank) { hid_t banktype = h5banktype(); From 9d7105ebc7ff43d973f55d59a815d62be0a8ba5b Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 6 Sep 2022 02:22:21 +0200 Subject: [PATCH 099/146] wip add MCPL-out to openmc code for writing a source_bank/point compiles but is untested --- src/state_point.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index 1b133a1215..c41c3dd53d 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -603,6 +603,7 @@ void write_source_point(const char* filename, bool surf_source_bank) file_close(file_id); } + #ifdef OPENMC_MCPL void write_mcpl_source_point(const char *filename, bool surf_source_bank) { @@ -641,8 +642,8 @@ void write_mcpl_source_point(const char *filename, bool surf_source_bank) } } -#endif +#endif void write_source_bank(hid_t group_id, bool surf_source_bank) { From cd9eb5b1b237bbd420b7c2eef93023d3e1f1e20b Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Tue, 6 Sep 2022 23:06:19 +0200 Subject: [PATCH 100/146] add a trigger to simulation control --- src/simulation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/simulation.cpp b/src/simulation.cpp index fcb115849d..7fda9d5239 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -408,10 +408,10 @@ void finalize_batch() write_source_point(filename.c_str(), true); } - if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ - auto filename = settings::path_output + ".mcpl"; - write_mcpl_source_point(filename.c_str(), true); - } +if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ + auto filename = settings::path_output + ".mcpl"; + write_mcpl_source_point(filename.c_str(), true); +} } From 8b783749341798cc9c8bc71d0ab374297824f1fc Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 5 Oct 2022 10:59:28 +0200 Subject: [PATCH 101/146] fix typo --- src/simulation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/simulation.cpp b/src/simulation.cpp index 7fda9d5239..fcb115849d 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -408,10 +408,10 @@ void finalize_batch() write_source_point(filename.c_str(), true); } -if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ - auto filename = settings::path_output + ".mcpl"; - write_mcpl_source_point(filename.c_str(), true); -} + if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ + auto filename = settings::path_output + ".mcpl"; + write_mcpl_source_point(filename.c_str(), true); + } } From 172fec23568ae6793c2b23c1b54e02c6b01483d7 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 5 Oct 2022 11:00:39 +0200 Subject: [PATCH 102/146] add cond. compilation guards for MCPL functions --- src/state_point.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index c41c3dd53d..14a5411283 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -603,7 +603,6 @@ void write_source_point(const char* filename, bool surf_source_bank) file_close(file_id); } - #ifdef OPENMC_MCPL void write_mcpl_source_point(const char *filename, bool surf_source_bank) { @@ -642,7 +641,6 @@ void write_mcpl_source_point(const char *filename, bool surf_source_bank) } } - #endif void write_source_bank(hid_t group_id, bool surf_source_bank) From 9065bdac3aeafe0d411c2d4a26ef873e39cb4c40 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Fri, 16 Sep 2022 16:07:22 +0200 Subject: [PATCH 103/146] refactor MCPL file read part of FileSource A new constructor is added to FileSource that reads from a given MCPL-file. --- src/source.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/source.cpp b/src/source.cpp index e43f03929b..3e1ddb3f38 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -436,7 +436,6 @@ CustomSourceWrapper::~CustomSourceWrapper() #endif } - //============================================================================== // Non-member functions //============================================================================== From 28cd0c5d3ae44a1ab3fe11f3ced08d6589530aa6 Mon Sep 17 00:00:00 2001 From: erkn Date: Wed, 5 Oct 2022 14:31:05 +0200 Subject: [PATCH 104/146] fix misnamed variable and remove accientally committed code --- src/source.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 3e1ddb3f38..d3037386b2 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -350,10 +350,19 @@ FileSource::FileSource(mcpl_file_t mcpl_file) //neutrons or photons } - if(mcpl_particle->pdgcode==2112) { - site_.particle=ParticleType::neutron; - } else if (mcpl_particle->pdgcode==22) { - site_.particle=ParticleType::photon; + switch(pdg){ + case 2112: + site_.particle=ParticleType::neutron; + break; + case 22: + site_.particle=ParticleType::photon; + break; + case 11: + site_.particle=ParticleType::electron; + break; + case -11: + site_.particle=ParticleType::positron; + break; } //particle is good, convert to openmc-formalism From 6e523fa1f8ca0b6eef6a5e110fc7ceb86446d8f6 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Thu, 6 Oct 2022 01:33:21 +0200 Subject: [PATCH 105/146] must have a full filename --- src/simulation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simulation.cpp b/src/simulation.cpp index fcb115849d..82fce7c221 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -409,7 +409,7 @@ void finalize_batch() } if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ - auto filename = settings::path_output + ".mcpl"; + auto filename = settings::path_output + "surface_source.mcpl"; write_mcpl_source_point(filename.c_str(), true); } From 93a9270efcf0697db410c21d184b4e0d933da875 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 11 Oct 2022 00:46:32 +0200 Subject: [PATCH 106/146] fix malformed format string --- src/state_point.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index 14a5411283..acae2e8d01 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -626,9 +626,9 @@ void write_mcpl_source_point(const char *filename, bool surf_source_bank) //write_attribute(file_id, "filetype", "source"); //write header stuff (oopy in xml-files as binary blobs for instance)) if (VERSION_DEV){ - line=fmt::format("OpenMC {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_RELEASE}-development"); + line=fmt::format("OpenMC {0}.{1}.{2}-development",VERSION_MAJOR,VERSION_MINOR,VERSION_RELEASE); } else { - line=fmt::format("OpenMC {VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_RELEASE}"); + line=fmt::format("OpenMC {0}.{1}.{2}",VERSION_MAJOR,VERSION_MINOR,VERSION_RELEASE); } mcpl_hdr_set_srcname(file_id,line.c_str()); } From 59a949de362f5133c43971636bcb71a557ae03e0 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 11 Oct 2022 00:48:44 +0200 Subject: [PATCH 107/146] fix typo causing unit length errors --- src/state_point.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index acae2e8d01..fb915484b3 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -803,9 +803,11 @@ void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) p.position[1]=_site->r.y; p.position[2]=_site->r.z; + //mcpl requires that the direction vector is unit length + //which is also the case in openmc p.direction[0]=_site->u.x; p.direction[1]=_site->u.y; - p.direction[2]=_site->u.x; + p.direction[2]=_site->u.z; //mcpl stores kinetic energy in MeV p.ekin=_site->E*1e-6; From 7759028d803d052f220abbc00a876a1c33b00949 Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 11 Oct 2022 02:00:33 +0200 Subject: [PATCH 108/146] enable mcpl surf_source_write in the python layer --- openmc/settings.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/openmc/settings.py b/openmc/settings.py index ad5a9b28ae..0937a3e480 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -171,6 +171,7 @@ class Settings: banked (int) :max_particles: Maximum number of particles to be banked on surfaces per process (int) + :mcpl: Output in the form of an MCPL-file (bool) survival_biasing : bool Indicate whether survival biasing is to be used tabular_legendre : dict @@ -652,7 +653,7 @@ class Settings: cv.check_type('surface source writing options', surf_source_write, Mapping) for key, value in surf_source_write.items(): cv.check_value('surface source writing key', key, - ('surface_ids', 'max_particles')) + ('surface_ids', 'max_particles', 'mcpl')) if key == 'surface_ids': cv.check_type('surface ids for source banking', value, Iterable, Integral) @@ -664,6 +665,9 @@ class Settings: value, Integral) cv.check_greater_than('maximum particle banks on surfaces per process', value, 0) + elif key == 'mcpl': + cv.check_type('write to an MCPL-format file', value, bool) + self._surf_source_write = surf_source_write @confidence_intervals.setter @@ -1032,6 +1036,9 @@ class Settings: if 'max_particles' in self._surf_source_write: subelement = ET.SubElement(element, "max_particles") subelement.text = str(self._surf_source_write['max_particles']) + if 'mcpl' in self._surf_source_write: + subelement = ET.SubElement(element, "mcpl") + subelement.text = str(self._surf_source_write['mcpl']).lower() def _create_confidence_intervals(self, root): if self._confidence_intervals is not None: From e3f1bdaca1f5144563c4ceac45f10e4b0b5b7963 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 12 Oct 2022 19:30:38 +0200 Subject: [PATCH 109/146] enable mcpl from the python layer if the source filename ends with mcpl use that --- openmc/source.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openmc/source.py b/openmc/source.py index 48e14f6f71..fdb2d5bc25 100644 --- a/openmc/source.py +++ b/openmc/source.py @@ -223,7 +223,10 @@ class Source: if self.particle != 'neutron': element.set("particle", self.particle) if self.file is not None: - element.set("file", self.file) + if (self.file.endswith('.mcpl')): + element.set("mcpl", self.file) + else: + element.set("file", self.file) if self.library is not None: element.set("library", self.library) if self.parameters is not None: From ca396268b586719df5638057b9161dbb2cdb048a Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 12 Oct 2022 19:32:09 +0200 Subject: [PATCH 110/146] protect against compilation wo mcpl --- src/simulation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/simulation.cpp b/src/simulation.cpp index 82fce7c221..d90c33ffd6 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -407,12 +407,12 @@ void finalize_batch() auto filename = settings::path_output + "surface_source.h5"; write_source_point(filename.c_str(), true); } - +#ifdef OPENMC_MCPL if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ auto filename = settings::path_output + "surface_source.mcpl"; write_mcpl_source_point(filename.c_str(), true); } - +#endif } From 94fb5f8fa6818f88c9fcf9007535a80846cb6c2d Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 12 Oct 2022 19:32:40 +0200 Subject: [PATCH 111/146] enable MPI mpi-nodes are gathered sequentially (as for h5) --- src/state_point.cpp | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index fb915484b3..983147c62e 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -786,30 +786,40 @@ void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) } if (mpi::master) { - //write particles from the master node + // Particles are writeen to disk from the master node only + + // Save source bank sites since the array is overwritten below +#ifdef OPENMC_MPI + vector temp_source {source_bank->begin(), source_bank->end()}; +#endif + //loop over the other nodes and receive data - then write those. for (int i = 0; i < mpi::n_procs; ++i) { + // number of particles for node node i + size_t count[] { + static_cast((*bank_index)[i + 1] - (*bank_index)[i])}; + #ifdef OPENMC_MPI if (i>0) MPI_Recv(source_bank->data(), count[0], mpi::source_site, i, i, mpi::intracomm, MPI_STATUS_IGNORE); #endif - //now write the source_banke data again. + // now write the source_bank data again. for (vector::iterator _site=source_bank->begin(); _site!=source_bank->end();_site++){ - //particle is now at the iterator - //write it to the mcpl-file + // particle is now at the iterator + // write it to the mcpl-file mcpl_particle_t p; p.position[0]=_site->r.x; p.position[1]=_site->r.y; p.position[2]=_site->r.z; - //mcpl requires that the direction vector is unit length - //which is also the case in openmc + // mcpl requires that the direction vector is unit length + // which is also the case in openmc p.direction[0]=_site->u.x; p.direction[1]=_site->u.y; p.direction[2]=_site->u.z; - //mcpl stores kinetic energy in MeV + // mcpl stores kinetic energy in MeV p.ekin=_site->E*1e-6; p.time=_site->time*1e3; @@ -834,6 +844,10 @@ void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) mcpl_add_particle(file_id,&p); } } +#ifdef OPENMC_MPI + // Restore state of source bank + std::copy(temp_source.begin(), temp_source.end(), source_bank->begin()); +#endif } else { #ifdef OPENMC_MPI MPI_Send(source_bank->data(), count_size, mpi::source_site, 0, mpi::rank, From 81fa3b45a35595f4913845d5cc1a4580e173d0d7 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Thu, 13 Oct 2022 23:09:12 +0200 Subject: [PATCH 112/146] mcpl-file output simimlar to regular source output file --- include/openmc/settings.h | 1 + src/settings.cpp | 1 + src/simulation.cpp | 14 ++++++++++++++ 3 files changed, 16 insertions(+) diff --git a/include/openmc/settings.h b/include/openmc/settings.h index 66825867d8..5b755784e4 100644 --- a/include/openmc/settings.h +++ b/include/openmc/settings.h @@ -47,6 +47,7 @@ extern "C" bool run_CE; //!< run with continuous-energy data? extern bool source_latest; //!< write latest source at each batch? extern bool source_separate; //!< write source to separate file? extern bool source_write; //!< write source in HDF5 files? +extern bool source_mcpl_write; //!< write source in mcpl files? extern bool surf_source_write; //!< write surface source file? extern bool surf_mcpl_write; //!< write surface mcpl file? extern bool surf_source_read; //!< read surface source file? diff --git a/src/settings.cpp b/src/settings.cpp index d1762596c6..7aed383da1 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -60,6 +60,7 @@ bool run_CE {true}; bool source_latest {false}; bool source_separate {false}; bool source_write {true}; +bool source_mcpl_write {true}; bool surf_source_write {false}; bool surf_mcpl_write {false}; bool surf_source_read {false}; diff --git a/src/simulation.cpp b/src/simulation.cpp index d90c33ffd6..70053a9a89 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -399,6 +399,20 @@ void finalize_batch() auto filename = settings::path_output + "source.h5"; write_source_point(filename.c_str()); } + +#ifdef OPENMC_MCPL + if (contains(settings::sourcepoint_batch, simulation::current_batch) && + settings::source_mcpl_write && settings::source_separate) { + write_mcpl_source_point(nullptr); + } + + // Write a continously-overwritten source point if requested. + if (settings::source_latest && setting::source_mcpl_write) { + auto filename = settings::path_output + "source.mcpl"; + write_mcpl_source_point(filename.c_str()); + } +#endif + } // Write out surface source if requested. From 5da08f6b0e1aa687b242bab32facdd5f29cf0d9d Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Fri, 14 Oct 2022 01:40:52 +0200 Subject: [PATCH 113/146] fix logic to avoid writing both kinds of source file --- src/settings.cpp | 3 +++ src/simulation.cpp | 43 +++++++++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/settings.cpp b/src/settings.cpp index 7aed383da1..9098eb6205 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -654,6 +654,9 @@ void read_settings_xml() if (check_for_node(node_sp, "write")) { source_write = get_node_value_bool(node_sp, "write"); } + if (check_for_node(node_sp, "mcpl")) { + source_write = get_node_value_bool(node_sp, "mcpl"); + } if (check_for_node(node_sp, "overwrite_latest")) { source_latest = get_node_value_bool(node_sp, "overwrite_latest"); source_separate = source_latest; diff --git a/src/simulation.cpp b/src/simulation.cpp index 70053a9a89..d7cc2237d5 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -389,30 +389,33 @@ void finalize_batch() if (settings::run_mode == RunMode::EIGENVALUE) { // Write out a separate source point if it's been specified for this batch - if (contains(settings::sourcepoint_batch, simulation::current_batch) && - settings::source_write && settings::source_separate) { - write_source_point(nullptr); - } - - // Write a continously-overwritten source point if requested. - if (settings::source_latest) { - auto filename = settings::path_output + "source.h5"; - write_source_point(filename.c_str()); - } - #ifdef OPENMC_MCPL - if (contains(settings::sourcepoint_batch, simulation::current_batch) && - settings::source_mcpl_write && settings::source_separate) { - write_mcpl_source_point(nullptr); - } + if(! settings::source_mcpl_write) { +#endif + if (contains(settings::sourcepoint_batch, simulation::current_batch) && + settings::source_write && settings::source_separate) { + write_source_point(nullptr); + } - // Write a continously-overwritten source point if requested. - if (settings::source_latest && setting::source_mcpl_write) { - auto filename = settings::path_output + "source.mcpl"; - write_mcpl_source_point(filename.c_str()); + // Write a continously-overwritten source point if requested. + if (settings::source_latest) { + auto filename = settings::path_output + "source.h5"; + write_source_point(filename.c_str()); + } +#ifdef OPENMC_MCPL + } else { + if (contains(settings::sourcepoint_batch, simulation::current_batch) && + settings::source_mcpl_write && settings::source_separate) { + write_mcpl_source_point(nullptr); + } + + // Write a continously-overwritten source point if requested. + if (settings::source_latest && settings::source_mcpl_write) { + auto filename = settings::path_output + "source.mcpl"; + write_mcpl_source_point(filename.c_str()); + } } #endif - } // Write out surface source if requested. From 344efa8de6454998dd55d00d6f213946d266cadf Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Fri, 14 Oct 2022 01:41:21 +0200 Subject: [PATCH 114/146] don't compress by default --- src/state_point.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index 983147c62e..d0fe92bdf5 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -637,7 +637,7 @@ void write_mcpl_source_point(const char *filename, bool surf_source_bank) if (mpi::master) { //change this - this is h5 specific - mcpl_closeandgzip_outfile(file_id); + mcpl_close_outfile(file_id); } } From 04edce7dc29543fe4e8f730f9ee516ae87c61195 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Fri, 14 Oct 2022 01:41:44 +0200 Subject: [PATCH 115/146] do read and write regression test almost dientical to source_file reg. test --- .../source_mcpl_file/results_true.dat | 2 +- .../source_mcpl_file/settings.xml | 6 +- .../regression_tests/source_mcpl_file/test.py | 146 +++++++++++------- 3 files changed, 97 insertions(+), 57 deletions(-) diff --git a/tests/regression_tests/source_mcpl_file/results_true.dat b/tests/regression_tests/source_mcpl_file/results_true.dat index f2209006a1..19460623f5 100644 --- a/tests/regression_tests/source_mcpl_file/results_true.dat +++ b/tests/regression_tests/source_mcpl_file/results_true.dat @@ -1,2 +1,2 @@ k-combined: -3.017557E-01 3.398770E-03 +3.039964E-01 3.654869E-04 diff --git a/tests/regression_tests/source_mcpl_file/settings.xml b/tests/regression_tests/source_mcpl_file/settings.xml index 8b1510e0ce..47b010bffe 100644 --- a/tests/regression_tests/source_mcpl_file/settings.xml +++ b/tests/regression_tests/source_mcpl_file/settings.xml @@ -1,11 +1,15 @@ + + 10 5 1000 - source.10.mcpl + + -4 -4 -4 4 4 4 + diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py index f55a769047..a005fc2d83 100644 --- a/tests/regression_tests/source_mcpl_file/test.py +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -1,65 +1,101 @@ -import os -import subprocess +#!/usr/bin/env python + import glob +import os -from tests.testing_harness import TestHarness +from tests.testing_harness import * -class SourceMCPLFileTestHarness(TestHarness): - def execute_test(self): - """Run OpenMC with the appropriate arguments and check the outputs.""" - try: - self._create_input() - self._test_input_created() - self._run_openmc() - self._test_output_created() - results = self._get_results() - self._write_results(results) - self._compare_results() - finally: - self._cleanup() +settings1=""" + + + + + 10 + 5 + 1000 + + + + -4 -4 -4 4 4 4 + + + +""" - def _create_input(self): - compiled=subprocess.run(['gcc','-o','gen_dummy_mcpl.out','gen_dummy_mcpl.c','-lm','-lmcpl']) - assert compiled==0, 'Could not compile mcpl-file generator code' - subprocess.run(['./gen_dummy_mcpl.out']) +settings2 = """ + + + 10 + 5 + 1000 + + + source.10.{0} + + +""" - def update_results(self): - """Update the results_true using the current version of OpenMC.""" - try: - self._create_input() - self._test_input_created() - self._run_openmc() - self._test_output_created() - results = self._get_results() - self._write_results(results) - self._overwrite_results() - finally: - self._cleanup() - def _test_input_created(self): - """Check that the input mcpl.file was generated as it should""" - mcplfile=glob.glob(os.path.join(os.getcwd(),'source.10.mcpl')) - assert len(mcplfile) == 1, 'Either multiple or no mcpl files ' \ - 'exist.' - assert mcplfile[0].endswith('mcpl'), \ - 'output file does not end with mcpl.' +class SourceFileTestHarness(TestHarness): + def execute_test(self): + """Run OpenMC with the appropriate arguments and check the outputs.""" + try: + self._run_openmc() + self._test_output_created() + self._run_openmc_restart() + results = self._get_results() + self._write_results(results) + self._compare_results() + finally: + self._cleanup() - def _test_output_created(self): - """Check that the output files were created""" - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name)) - assert len(statepoint) == 1, 'Either multiple or no statepoint files ' \ - 'exist.' - assert statepoint[0].endswith('h5'), \ - 'statepoint file does not end with h5.' + def update_results(self): + """Update the results_true using the current version of OpenMC.""" + try: + self._run_openmc() + self._test_output_created() + self._run_openmc_restart() + results = self._get_results() + self._write_results(results) + self._overwrite_results() + finally: + self._cleanup() - def _cleanup(self): - super()._cleanup() - source_mcpl=glob.glob(os.path.join(os.getcwd(),'source*.mcpl')) - for f in source_mcpl: - if (os.path.exists(f)): - os.remove(f) + def _test_output_created(self): + """Make sure statepoint and source files have been created.""" + statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name)) + assert len(statepoint) == 1, 'Either multiple or no statepoint files ' \ + 'exist.' + assert statepoint[0].endswith('h5'), \ + 'Statepoint file is not a HDF5 file.' -def test_mcpl_source_file(): - harness = SourceMCPLFileTestHarness('source.10.mcpl') - harness.main() + source = glob.glob(os.path.join(os.getcwd(), 'source.10.mcpl*')) + assert len(source) == 1, 'Either multiple or no source files exist.' + assert source[0].endswith('mcpl') or source[0].endswith('mcpl.gz'), \ + 'Source file is not a MCPL file.' + + def _run_openmc_restart(self): + # Get the name of the source file. + source = glob.glob(os.path.join(os.getcwd(), 'source.10.*')) + + # Write the new settings.xml file. + with open('settings.xml','w') as fh: + fh.write(settings2.format(source[0].split('.')[-1])) + + # Run OpenMC. + self._run_openmc() + + def _cleanup(self): + TestHarness._cleanup(self) + output = glob.glob(os.path.join(os.getcwd(), 'source.*')) + #for f in output: + # if os.path.exists(f): + # os.remove(f) + with open('settings.xml','w') as fh: + fh.write(settings1) + + +def test_source_file(): + harness = SourceFileTestHarness('statepoint.10.h5') + harness.main() From e224adf4313056e8dfb8700126d7329511de0721 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 16 Nov 2022 10:31:15 +0100 Subject: [PATCH 116/146] follow source code conventions Co-authored-by: Paul Romano --- include/openmc/state_point.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/openmc/state_point.h b/include/openmc/state_point.h index 2d92c935a6..698ed2c93a 100644 --- a/include/openmc/state_point.h +++ b/include/openmc/state_point.h @@ -26,7 +26,7 @@ void restart_set_keff(); void write_unstructured_mesh_results(); #ifdef OPENMC_MCPL -void write_mcpl_source_point(const char *filename_, bool surf_source_bank = false); +void write_mcpl_source_point(const char* filename, bool surf_source_bank = false); void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank); #endif From b2320ae1d477d7f3d932a406eb2989eee5cf37e3 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 16 Nov 2022 13:42:25 +0100 Subject: [PATCH 117/146] not needed since mcpl-file is created by openmc --- .../source_mcpl_file/gen_dummy_mcpl.c | 98 ------------------- 1 file changed, 98 deletions(-) delete mode 100644 tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c diff --git a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c b/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c deleted file mode 100644 index 61eea95c6f..0000000000 --- a/tests/regression_tests/source_mcpl_file/gen_dummy_mcpl.c +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include -#include -#include - -const int batches=10; -const int particles=10000; - -double rand01(){ - double r=rand()/((double) RAND_MAX); - return r; -} - - -int main(int argc, char **argv){ - char outfilename[128]; - snprintf(outfilename,127,"source.%d.mcpl",batches); - - /*generate an mcpl_header_of sorts*/ - mcpl_outfile_t outfile=mcpl_create_outfile(outfilename); - mcpl_particle_t *particle, Particle; - - char line[256]; - snprintf(line,255,"gen_dummy_mcpl.c"); - mcpl_hdr_set_srcname(outfile,line); - mcpl_enable_universal_pdgcode(outfile,2112);/*all particles are neutrons*/ - snprintf(line,255,"Dummy MCPL-file for testing OpenMC mcpl input"); - mcpl_hdr_add_comment(outfile,line); - - /*also add the instrument file and the command line as blobs*/ - FILE *fp; - if( (fp=fopen("gen_dummy_mcpl.c","rb"))!=NULL){ - unsigned char *buffer; - int size,status; - /*find the file size by seeking to end, "tell" the position, and then go back again*/ - fseek(fp, 0L, SEEK_END); - size = ftell(fp); // get current file pointer - fseek(fp, 0L, SEEK_SET); // seek back to beginning of file - if ( size && (buffer=malloc(size))!=NULL){ - if (size!=(fread(buffer,1,size,fp))){ - fprintf(stderr,"Warning: c source generator file not read cleanly\n"); - } - mcpl_hdr_add_data(outfile, "mcpl_point_source_file_generator", size, buffer); - free(buffer); - } - fclose(fp); - } else { - fprintf(stderr,"Warning: could not open c source generator file, hence not embedded.\n"); - } - - - /*the main particle loop*/ - particle=&Particle; - int i; - srand(1234); - for (i=0;iposition[0]=0; - particle->position[1]=0; - particle->position[2]=0; - - /*generate a random direction on unit sphere*/ - double nrm=2.0; - double vx,vy,vz; - int iter=0; - do { - if(iter>100){ - printf("Warning: Exceeded max random vector attempts: at loop %d -> %g %d\n",i,nrm,iter); - } - vx=rand01()*2.0-1.0; - vy=rand01()*2.0-1.0; - vz=rand01()*2.0-1.0; - nrm=(vx*vx + vy*vy + vz*vz); - iter++; - } while (nrm>1.0); - vx/=sqrt(nrm); - vy/=sqrt(nrm); - vz/=sqrt(nrm); - particle->direction[0]=vx; - particle->direction[1]=vy; - particle->direction[2]=vz; - - /*generate the kinetic energy (in MeV) of the particle*/ - particle->ekin=1e-3; - - /*set time=0*/ - particle->time=0; - /*set weight*/ - particle->weight=1; - - particle->userflags=0; - mcpl_add_particle(outfile,particle); - } - mcpl_close_outfile(outfile); -} From 3e60d51f904ca413030716aa1882866bebab8c23 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 16 Nov 2022 13:54:08 +0100 Subject: [PATCH 118/146] from_xml mcpl-settings functionality --- openmc/settings.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openmc/settings.py b/openmc/settings.py index 0937a3e480..b2c184f780 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -1341,13 +1341,15 @@ class Settings: def _surf_source_write_from_xml_element(self, root): elem = root.find('surf_source_write') if elem is not None: - for key in ('surface_ids', 'max_particles'): + for key in ('surface_ids', 'max_particles','mcpl'): value = get_text(elem, key) if value is not None: if key == 'surface_ids': value = [int(x) for x in value.split()] elif key in ('max_particles'): value = int(value) + elif key == 'mcpl': + value = True self.surf_source_write[key] = value def _confidence_intervals_from_xml_element(self, root): From 6442de68348eefe5f26ba9a0c74fd082067e95fd Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Fri, 18 Nov 2022 23:26:24 +0100 Subject: [PATCH 119/146] remove unneccessary initialization Co-authored-by: Paul Romano --- src/source.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/source.cpp b/src/source.cpp index 1c46e4939c..67a4a511da 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -381,7 +381,6 @@ FileSource::FileSource(mcpl_file_t mcpl_file) //mcpl stores time in ms site_.time=mcpl_particle->time*1e-3; site_.wgt=mcpl_particle->weight; - site_.delayed_group=0; sites_[i]=site_; } mcpl_close_file(mcpl_file); From a299dcc56b4d79e73a996ed3c47baaa2729fd795 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 16 Nov 2022 14:02:01 +0100 Subject: [PATCH 120/146] add a documentation entry to surf_source_write --- docs/source/io_formats/settings.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/source/io_formats/settings.rst b/docs/source/io_formats/settings.rst index 1a8f63716f..285dfa2290 100644 --- a/docs/source/io_formats/settings.rst +++ b/docs/source/io_formats/settings.rst @@ -767,6 +767,15 @@ certain surfaces and write out the source bank in a separate file called *Default*: None + :mcpl: + An optional boolean which indicates if the banked particle should + be written to a file in the MCPL-format (documented in mcpl_). + instead of the native hdf5-based format. + + *Default*: false + + .. _mcpl: https://mctools.github.io/mcpl/mcpl.pdf + ------------------------------ ```` Element ------------------------------ From a40cc14d8ebb08da619b2d9fcaa9fc58adca1efa Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Sat, 19 Nov 2022 00:33:04 +0100 Subject: [PATCH 121/146] check in the c++-layer if it's an mcpl-file --- src/settings.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/settings.cpp b/src/settings.cpp index 9098eb6205..0ca430de62 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -431,12 +431,13 @@ void read_settings_xml() for (pugi::xml_node node : root.children("source")) { if (check_for_node(node, "file")) { auto path = get_node_value(node, "file", false, true); - model::external_sources.push_back(make_unique(path)); #ifdef OPENMC_MCPL - } else if (check_for_node(node, "mcpl")) { - auto path = get_node_value(node, "mcpl", false, true); - model::external_sources.push_back(make_unique(mcpl_open_file(path.c_str()))); + if ( (path.size() >= 5 && path.compare(path.size()-5,5,".mcpl")==0 ) || + (path.size() >= 8 && path.compare(path.size()-8,8,".mcpl.gz")==0 ) ) { + model::external_sources.push_back(make_unique(mcpl_open_file(path.c_str()))); + } else #endif + model::external_sources.push_back(make_unique(path)); } else if (check_for_node(node, "library")) { // Get shared library path and parameters auto path = get_node_value(node, "library", false, true); From 8bfb1af81e874a6e9b55c59a12e816f071592ab0 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Sat, 19 Nov 2022 01:41:02 +0100 Subject: [PATCH 122/146] remove unneccessary in-code comments --- src/state_point.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/state_point.cpp b/src/state_point.cpp index d0fe92bdf5..3ee5f13b39 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -621,10 +621,7 @@ void write_mcpl_source_point(const char *filename, bool surf_source_bank) std::string line; if (mpi::master) { - // this must be rewritten: file_open is h5-specific file_id = mcpl_create_outfile(filename_.c_str()); - //write_attribute(file_id, "filetype", "source"); - //write header stuff (oopy in xml-files as binary blobs for instance)) if (VERSION_DEV){ line=fmt::format("OpenMC {0}.{1}.{2}-development",VERSION_MAJOR,VERSION_MINOR,VERSION_RELEASE); } else { From 727161f95ab8364a04499de060e25fcdc28d474a Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Sat, 19 Nov 2022 01:44:47 +0100 Subject: [PATCH 123/146] remove some in-code comments --- src/source.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 1c46e4939c..2e6335aad2 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -332,8 +332,6 @@ FileSource::FileSource(std::string path) #ifdef OPENMC_MCPL FileSource::FileSource(mcpl_file_t mcpl_file) { - //do checks on the mcpl_file to see if particles are many enough. - // should model this on the example source shown in the docs. size_t n_sites=mcpl_hdr_nparticles(mcpl_file); sites_.resize(n_sites); @@ -348,8 +346,6 @@ FileSource::FileSource(mcpl_file_t mcpl_file) while ( pdg!=2112 && pdg!=22 && pdg!=11 && pdg!=-11) { mcpl_particle=mcpl_read(mcpl_file); pdg=mcpl_particle->pdgcode; - //should check for file exhaustion. This could happen if particles are other than - //neutrons, photons, electrons, or positrons. } switch(pdg){ From ccbef891ef7d2585b21b7bd5dd0e76d872017210 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Sat, 19 Nov 2022 01:49:31 +0100 Subject: [PATCH 124/146] update to doc-string --- docs/source/io_formats/settings.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/source/io_formats/settings.rst b/docs/source/io_formats/settings.rst index 285dfa2290..a162e8de6d 100644 --- a/docs/source/io_formats/settings.rst +++ b/docs/source/io_formats/settings.rst @@ -768,9 +768,10 @@ certain surfaces and write out the source bank in a separate file called *Default*: None :mcpl: - An optional boolean which indicates if the banked particle should + An optional boolean which indicates if the banked particles should be written to a file in the MCPL-format (documented in mcpl_). - instead of the native hdf5-based format. + instead of the native hdf5-based format.If activated the output + output file name is altered to ``surface_source.mcpl`` *Default*: false From fab1ddac003648e7954ad85b8d4718e7685df0e4 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Sat, 19 Nov 2022 02:19:41 +0100 Subject: [PATCH 125/146] prefer native as default Co-authored-by: Paul Romano --- src/settings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings.cpp b/src/settings.cpp index 9098eb6205..91a13289cf 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -60,7 +60,7 @@ bool run_CE {true}; bool source_latest {false}; bool source_separate {false}; bool source_write {true}; -bool source_mcpl_write {true}; +bool source_mcpl_write {false}; bool surf_source_write {false}; bool surf_mcpl_write {false}; bool surf_source_read {false}; From c9c74f08b2cae9c57f818c4a93abf986514fd809 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Mon, 21 Nov 2022 00:34:30 +0100 Subject: [PATCH 126/146] apply clang-format --- src/source.cpp | 78 +++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 2e6335aad2..af108f3fa9 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -234,7 +234,8 @@ SourceSite IndependentSource::sample(uint64_t* seed) const auto id = (domain_type_ == DomainType::CELL) ? model::cells[coord.cell]->id_ : model::universes[coord.universe]->id_; - if (found = contains(domain_ids_, id)) break; + if (found = contains(domain_ids_, id)) + break; } } } @@ -332,57 +333,57 @@ FileSource::FileSource(std::string path) #ifdef OPENMC_MCPL FileSource::FileSource(mcpl_file_t mcpl_file) { - size_t n_sites=mcpl_hdr_nparticles(mcpl_file); + size_t n_sites = mcpl_hdr_nparticles(mcpl_file); sites_.resize(n_sites); - for (int i=0;ipdgcode; - while ( pdg!=2112 && pdg!=22 && pdg!=11 && pdg!=-11) { - mcpl_particle=mcpl_read(mcpl_file); - pdg=mcpl_particle->pdgcode; + int pdg = mcpl_particle->pdgcode; + while (pdg != 2112 && pdg != 22 && pdg != 11 && pdg != -11) { + mcpl_particle = mcpl_read(mcpl_file); + pdg = mcpl_particle->pdgcode; } - switch(pdg){ - case 2112: - site_.particle=ParticleType::neutron; - break; - case 22: - site_.particle=ParticleType::photon; - break; - case 11: - site_.particle=ParticleType::electron; - break; - case -11: - site_.particle=ParticleType::positron; - break; + switch (pdg) { + case 2112: + site_.particle = ParticleType::neutron; + break; + case 22: + site_.particle = ParticleType::photon; + break; + case 11: + site_.particle = ParticleType::electron; + break; + case -11: + site_.particle = ParticleType::positron; + break; } - //particle is good, convert to openmc-formalism - site_.r.x=mcpl_particle->position[0]; - site_.r.y=mcpl_particle->position[1]; - site_.r.z=mcpl_particle->position[2]; + // particle is good, convert to openmc-formalism + site_.r.x = mcpl_particle->position[0]; + site_.r.y = mcpl_particle->position[1]; + site_.r.z = mcpl_particle->position[2]; - site_.u.x=mcpl_particle->direction[0]; - site_.u.y=mcpl_particle->direction[1]; - site_.u.z=mcpl_particle->direction[2]; + site_.u.x = mcpl_particle->direction[0]; + site_.u.y = mcpl_particle->direction[1]; + site_.u.z = mcpl_particle->direction[2]; - //mcpl stores kinetic energy in MeV - site_.E=mcpl_particle->ekin*1e6; - //mcpl stores time in ms - site_.time=mcpl_particle->time*1e-3; - site_.wgt=mcpl_particle->weight; - site_.delayed_group=0; - sites_[i]=site_; + // mcpl stores kinetic energy in MeV + site_.E = mcpl_particle->ekin * 1e6; + // mcpl stores time in ms + site_.time = mcpl_particle->time * 1e-3; + site_.wgt = mcpl_particle->weight; + site_.delayed_group = 0; + sites_[i] = site_; } mcpl_close_file(mcpl_file); } -#endif //OPENMC_MCPL +#endif // OPENMC_MCPL SourceSite FileSource::sample(uint64_t* seed) const { @@ -443,7 +444,6 @@ CustomSourceWrapper::~CustomSourceWrapper() #endif } - //============================================================================== // Non-member functions //============================================================================== From 2b7fa8fdd2dbe313e14cf2d789f9cad1260d964e Mon Sep 17 00:00:00 2001 From: erkn Date: Tue, 20 Dec 2022 23:58:22 +0100 Subject: [PATCH 127/146] Revert "enable mcpl from the python layer" This reverts commit e3f1bdaca1f5144563c4ceac45f10e4b0b5b7963. There is now a check in the cpp-layer if the file is named .mcpl --- openmc/source.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/openmc/source.py b/openmc/source.py index fdb2d5bc25..48e14f6f71 100644 --- a/openmc/source.py +++ b/openmc/source.py @@ -223,10 +223,7 @@ class Source: if self.particle != 'neutron': element.set("particle", self.particle) if self.file is not None: - if (self.file.endswith('.mcpl')): - element.set("mcpl", self.file) - else: - element.set("file", self.file) + element.set("file", self.file) if self.library is not None: element.set("library", self.library) if self.parameters is not None: From 1ab9aa4b6fddf4e6b7216b7fe993d8c672c22468 Mon Sep 17 00:00:00 2001 From: erkn Date: Wed, 21 Dec 2022 00:14:43 +0100 Subject: [PATCH 128/146] script for installing mcpl as a ci-thing --- tools/ci/gha-install-mcpl.sh | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100755 tools/ci/gha-install-mcpl.sh diff --git a/tools/ci/gha-install-mcpl.sh b/tools/ci/gha-install-mcpl.sh new file mode 100755 index 0000000000..9b8609398a --- /dev/null +++ b/tools/ci/gha-install-mcpl.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -ex +cd $HOME +git clone https://github.com/mctools/mcpl +cd mcpl +mkdir build && cd build +cmake .. && make 2>/dev/null && sudo make install From 9865a129c49ad2b07628d152a2d8865ad6936fd6 Mon Sep 17 00:00:00 2001 From: erkn Date: Wed, 21 Dec 2022 00:22:38 +0100 Subject: [PATCH 129/146] optionally install mcpl depending on environment var --- tools/ci/gha-install.py | 8 ++++++-- tools/ci/gha-install.sh | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/ci/gha-install.py b/tools/ci/gha-install.py index 4c69ba70b0..ea317b5f0a 100644 --- a/tools/ci/gha-install.py +++ b/tools/ci/gha-install.py @@ -19,7 +19,7 @@ def which(program): return None -def install(omp=False, mpi=False, phdf5=False, dagmc=False, libmesh=False): +def install(omp=False, mpi=False, phdf5=False, dagmc=False, libmesh=False, mcpl=False): # Create build directory and change to it shutil.rmtree('build', ignore_errors=True) os.mkdir('build') @@ -54,6 +54,9 @@ def install(omp=False, mpi=False, phdf5=False, dagmc=False, libmesh=False): libmesh_path = os.environ.get('HOME') + '/LIBMESH' cmake_cmd.append('-DCMAKE_PREFIX_PATH=' + libmesh_path) + if mcpl: + cmake_cmd.append('-DOPENMC_USE_MCPL=ON') + # Build in coverage mode for coverage testing cmake_cmd.append('-DOPENMC_ENABLE_COVERAGE=on') @@ -71,9 +74,10 @@ def main(): phdf5 = (os.environ.get('PHDF5') == 'y') dagmc = (os.environ.get('DAGMC') == 'y') libmesh = (os.environ.get('LIBMESH') == 'y') + mcpl = (os.environ.get('MCPL') == 'y') # Build and install - install(omp, mpi, phdf5, dagmc, libmesh) + install(omp, mpi, phdf5, dagmc, libmesh, mcpl) if __name__ == '__main__': main() diff --git a/tools/ci/gha-install.sh b/tools/ci/gha-install.sh index aa40eb90b1..68e825d486 100755 --- a/tools/ci/gha-install.sh +++ b/tools/ci/gha-install.sh @@ -27,6 +27,11 @@ if [[ $LIBMESH = 'y' ]]; then ./tools/ci/gha-install-libmesh.sh fi +# Install mcpl if needed +if [[ $MCPL = 'y' ]]; then + ./tools/ci/gha-install-mcpl.sh +fi + # For MPI configurations, make sure mpi4py and h5py are built against the # correct version of MPI if [[ $MPI == 'y' ]]; then From a50776219fe659be4572a918d4e19bfb9596a5f3 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 21 Dec 2022 11:33:36 +0100 Subject: [PATCH 130/146] resolve conflict w. develop --- src/source.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source.cpp b/src/source.cpp index af108f3fa9..19d1c2a9db 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -234,7 +234,7 @@ SourceSite IndependentSource::sample(uint64_t* seed) const auto id = (domain_type_ == DomainType::CELL) ? model::cells[coord.cell]->id_ : model::universes[coord.universe]->id_; - if (found = contains(domain_ids_, id)) + if ((found = contains(domain_ids_, id))) break; } } From ff48f53595144aa0ecbc1f44f2d28428a7306633 Mon Sep 17 00:00:00 2001 From: erkn Date: Thu, 22 Dec 2022 12:04:29 +0100 Subject: [PATCH 131/146] skip mcpl-test if it is not enabled patterned after the dagmc-tests This required the MCPL_ENABLED symbol to be unmangled --- include/openmc/source.h | 1 + tests/regression_tests/source_mcpl_file/test.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/openmc/source.h b/include/openmc/source.h index bb7e2d55f7..051167b3f6 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -32,6 +32,7 @@ constexpr double EXTSRC_REJECT_FRACTION {0.05}; //============================================================================== // Global variables //============================================================================== +extern "C" const bool MCPL_ENABLED; class Source; diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py index a005fc2d83..0b8e79104e 100644 --- a/tests/regression_tests/source_mcpl_file/test.py +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -1,10 +1,13 @@ #!/usr/bin/env python - +import openmc.lib +import pytest import glob import os from tests.testing_harness import * - +pytestmark = pytest.mark.skipif( + not openmc.lib._mcpl_enabled(), + reason="MCPL is not enabled.") settings1=""" From fe19cfcdd25966c3ab5cce056b9337c50e3e7743 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Thu, 22 Dec 2022 17:16:16 +0100 Subject: [PATCH 132/146] set seed to get a deterministic test and set result --- tests/regression_tests/source_mcpl_file/results_true.dat | 2 +- tests/regression_tests/source_mcpl_file/settings.xml | 1 + tests/regression_tests/source_mcpl_file/test.py | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/regression_tests/source_mcpl_file/results_true.dat b/tests/regression_tests/source_mcpl_file/results_true.dat index 19460623f5..e8f4a20a08 100644 --- a/tests/regression_tests/source_mcpl_file/results_true.dat +++ b/tests/regression_tests/source_mcpl_file/results_true.dat @@ -1,2 +1,2 @@ k-combined: -3.039964E-01 3.654869E-04 +3.004254E-01 8.027600E-04 diff --git a/tests/regression_tests/source_mcpl_file/settings.xml b/tests/regression_tests/source_mcpl_file/settings.xml index 47b010bffe..2e511461f3 100644 --- a/tests/regression_tests/source_mcpl_file/settings.xml +++ b/tests/regression_tests/source_mcpl_file/settings.xml @@ -1,5 +1,6 @@ + 1234 diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py index 0b8e79104e..e87479c5a4 100644 --- a/tests/regression_tests/source_mcpl_file/test.py +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -11,6 +11,7 @@ pytestmark = pytest.mark.skipif( settings1=""" + 1234 From e9c6b03b9e2f5fb50875c64a8a33db8eda1059dd Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Thu, 22 Dec 2022 17:17:50 +0100 Subject: [PATCH 133/146] remove dead code --- tests/regression_tests/source_mcpl_file/test.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py index e87479c5a4..6492783197 100644 --- a/tests/regression_tests/source_mcpl_file/test.py +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -93,9 +93,6 @@ class SourceFileTestHarness(TestHarness): def _cleanup(self): TestHarness._cleanup(self) output = glob.glob(os.path.join(os.getcwd(), 'source.*')) - #for f in output: - # if os.path.exists(f): - # os.remove(f) with open('settings.xml','w') as fh: fh.write(settings1) From 4d7797c25b3932aaa166b4a6b12c4ffebd48d925 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Thu, 22 Dec 2022 17:18:37 +0100 Subject: [PATCH 134/146] mistake assigning the wrong variable --- src/settings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings.cpp b/src/settings.cpp index 5e8eb0e58f..b0829c1bad 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -656,7 +656,7 @@ void read_settings_xml() source_write = get_node_value_bool(node_sp, "write"); } if (check_for_node(node_sp, "mcpl")) { - source_write = get_node_value_bool(node_sp, "mcpl"); + source_mcpl_write = get_node_value_bool(node_sp, "mcpl"); } if (check_for_node(node_sp, "overwrite_latest")) { source_latest = get_node_value_bool(node_sp, "overwrite_latest"); From 51d3a0c2ce6079f18ea479c7efc158148236f5a7 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Thu, 22 Dec 2022 17:19:56 +0100 Subject: [PATCH 135/146] check for mcpl-input is in the cpp-layer now --- tests/regression_tests/source_mcpl_file/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py index 6492783197..60e0ad50f8 100644 --- a/tests/regression_tests/source_mcpl_file/test.py +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -35,7 +35,7 @@ settings2 = """ 1000 - source.10.{0} + source.10.{0} """ From 28521c8384c6e68b6ee0f52a7a44425b4a6306bd Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 22 Dec 2022 10:53:40 -0600 Subject: [PATCH 136/146] Use vector::push_back for building MCPL FileSource --- src/source.cpp | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 19d1c2a9db..4ab087e125 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -335,9 +335,8 @@ FileSource::FileSource(mcpl_file_t mcpl_file) { size_t n_sites = mcpl_hdr_nparticles(mcpl_file); - sites_.resize(n_sites); for (int i = 0; i < n_sites; i++) { - SourceSite site_; + SourceSite site; const mcpl_particle_t* mcpl_particle; // extract particle from mcpl-file @@ -351,36 +350,41 @@ FileSource::FileSource(mcpl_file_t mcpl_file) switch (pdg) { case 2112: - site_.particle = ParticleType::neutron; + site.particle = ParticleType::neutron; break; case 22: - site_.particle = ParticleType::photon; + site.particle = ParticleType::photon; break; case 11: - site_.particle = ParticleType::electron; + site.particle = ParticleType::electron; break; case -11: - site_.particle = ParticleType::positron; + site.particle = ParticleType::positron; break; } - // particle is good, convert to openmc-formalism - site_.r.x = mcpl_particle->position[0]; - site_.r.y = mcpl_particle->position[1]; - site_.r.z = mcpl_particle->position[2]; - - site_.u.x = mcpl_particle->direction[0]; - site_.u.y = mcpl_particle->direction[1]; - site_.u.z = mcpl_particle->direction[2]; + // Copy position and direction + site.r.x = mcpl_particle->position[0]; + site.r.y = mcpl_particle->position[1]; + site.r.z = mcpl_particle->position[2]; + site.u.x = mcpl_particle->direction[0]; + site.u.y = mcpl_particle->direction[1]; + site.u.z = mcpl_particle->direction[2]; // mcpl stores kinetic energy in MeV - site_.E = mcpl_particle->ekin * 1e6; + site.E = mcpl_particle->ekin * 1e6; // mcpl stores time in ms - site_.time = mcpl_particle->time * 1e-3; - site_.wgt = mcpl_particle->weight; - site_.delayed_group = 0; - sites_[i] = site_; + site.time = mcpl_particle->time * 1e-3; + site.wgt = mcpl_particle->weight; + sites_.push_back(site); } + + // Check that some sites were read + if (sites_.empty()) { + fatal_error("MCPL file contained no neutron, photon, electron, or positron " + "source particles."); + } + mcpl_close_file(mcpl_file); } #endif // OPENMC_MCPL From 987293cfffb2934359b0c1f0dcd685eb8140fd63 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 22 Dec 2022 10:57:11 -0600 Subject: [PATCH 137/146] Small fixes and formatting changes --- docs/source/io_formats/settings.rst | 8 ++-- include/openmc/state_point.h | 3 +- openmc/settings.py | 2 +- src/settings.cpp | 17 ++++--- src/simulation.cpp | 10 ++--- src/state_point.cpp | 70 ++++++++++++++--------------- 6 files changed, 57 insertions(+), 53 deletions(-) diff --git a/docs/source/io_formats/settings.rst b/docs/source/io_formats/settings.rst index a162e8de6d..7174c5317a 100644 --- a/docs/source/io_formats/settings.rst +++ b/docs/source/io_formats/settings.rst @@ -768,10 +768,10 @@ certain surfaces and write out the source bank in a separate file called *Default*: None :mcpl: - An optional boolean which indicates if the banked particles should - be written to a file in the MCPL-format (documented in mcpl_). - instead of the native hdf5-based format.If activated the output - output file name is altered to ``surface_source.mcpl`` + An optional boolean which indicates if the banked particles should be + written to a file in the MCPL-format (documented in mcpl_). instead of the + native HDF5-based format. If activated the output file name is changed to + ``surface_source.mcpl``. *Default*: false diff --git a/include/openmc/state_point.h b/include/openmc/state_point.h index 698ed2c93a..7301275542 100644 --- a/include/openmc/state_point.h +++ b/include/openmc/state_point.h @@ -26,7 +26,8 @@ void restart_set_keff(); void write_unstructured_mesh_results(); #ifdef OPENMC_MCPL -void write_mcpl_source_point(const char* filename, bool surf_source_bank = false); +void write_mcpl_source_point( + const char* filename, bool surf_source_bank = false); void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank); #endif diff --git a/openmc/settings.py b/openmc/settings.py index b2c184f780..fd622870c5 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -1349,7 +1349,7 @@ class Settings: elif key in ('max_particles'): value = int(value) elif key == 'mcpl': - value = True + value = value in ('true', '1') self.surf_source_write[key] = value def _confidence_intervals_from_xml_element(self, root): diff --git a/src/settings.cpp b/src/settings.cpp index b0829c1bad..de298c58d1 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -432,12 +432,15 @@ void read_settings_xml() if (check_for_node(node, "file")) { auto path = get_node_value(node, "file", false, true); #ifdef OPENMC_MCPL - if ( (path.size() >= 5 && path.compare(path.size()-5,5,".mcpl")==0 ) || - (path.size() >= 8 && path.compare(path.size()-8,8,".mcpl.gz")==0 ) ) { - model::external_sources.push_back(make_unique(mcpl_open_file(path.c_str()))); - } else -#endif + if (ends_with(path, ".mcpl") || ends_with(path, ".mcpl.gz")) { + model::external_sources.push_back( + make_unique(mcpl_open_file(path.c_str()))); + } else { model::external_sources.push_back(make_unique(path)); + } +#else + model::external_sources.push_back(make_unique(path)); +#endif } else if (check_for_node(node, "library")) { // Get shared library path and parameters auto path = get_node_value(node, "library", false, true); @@ -689,8 +692,8 @@ void read_settings_xml() std::stoll(get_node_value(node_ssw, "max_particles")); } #ifdef OPENMC_MCPL - if(check_for_node(node_ssw, "mcpl")){ - surf_mcpl_write=true; + if (check_for_node(node_ssw, "mcpl")) { + surf_mcpl_write = true; } #endif } diff --git a/src/simulation.cpp b/src/simulation.cpp index d7cc2237d5..2c1d1c988b 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -390,7 +390,7 @@ void finalize_batch() if (settings::run_mode == RunMode::EIGENVALUE) { // Write out a separate source point if it's been specified for this batch #ifdef OPENMC_MCPL - if(! settings::source_mcpl_write) { + if (!settings::source_mcpl_write) { #endif if (contains(settings::sourcepoint_batch, simulation::current_batch) && settings::source_write && settings::source_separate) { @@ -405,8 +405,8 @@ void finalize_batch() #ifdef OPENMC_MCPL } else { if (contains(settings::sourcepoint_batch, simulation::current_batch) && - settings::source_mcpl_write && settings::source_separate) { - write_mcpl_source_point(nullptr); + settings::source_mcpl_write && settings::source_separate) { + write_mcpl_source_point(nullptr); } // Write a continously-overwritten source point if requested. @@ -425,12 +425,12 @@ void finalize_batch() write_source_point(filename.c_str(), true); } #ifdef OPENMC_MCPL - if(settings::surf_mcpl_write && simulation::current_batch == settings::n_batches){ + if (settings::surf_mcpl_write && + simulation::current_batch == settings::n_batches) { auto filename = settings::path_output + "surface_source.mcpl"; write_mcpl_source_point(filename.c_str(), true); } #endif - } void initialize_generation() diff --git a/src/state_point.cpp b/src/state_point.cpp index 3ee5f13b39..9dd0f13747 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -604,7 +604,7 @@ void write_source_point(const char* filename, bool surf_source_bank) } #ifdef OPENMC_MCPL -void write_mcpl_source_point(const char *filename, bool surf_source_bank) +void write_mcpl_source_point(const char* filename, bool surf_source_bank) { std::string filename_; if (filename) { @@ -622,21 +622,21 @@ void write_mcpl_source_point(const char *filename, bool surf_source_bank) std::string line; if (mpi::master) { file_id = mcpl_create_outfile(filename_.c_str()); - if (VERSION_DEV){ - line=fmt::format("OpenMC {0}.{1}.{2}-development",VERSION_MAJOR,VERSION_MINOR,VERSION_RELEASE); + if (VERSION_DEV) { + line = fmt::format("OpenMC {0}.{1}.{2}-development", VERSION_MAJOR, + VERSION_MINOR, VERSION_RELEASE); } else { - line=fmt::format("OpenMC {0}.{1}.{2}",VERSION_MAJOR,VERSION_MINOR,VERSION_RELEASE); + line = fmt::format( + "OpenMC {0}.{1}.{2}", VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE); } - mcpl_hdr_set_srcname(file_id,line.c_str()); + mcpl_hdr_set_srcname(file_id, line.c_str()); } write_mcpl_source_bank(file_id, surf_source_bank); if (mpi::master) { - //change this - this is h5 specific mcpl_close_outfile(file_id); } - } #endif @@ -768,7 +768,7 @@ void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) vector surf_source_index_vector; vector surf_source_bank_vector; - if(surf_source_bank) { + if (surf_source_bank) { surf_source_index_vector = calculate_surf_source_size(); dims_size = surf_source_index_vector[mpi::n_procs]; count_size = simulation::surf_source_bank.size(); @@ -790,55 +790,56 @@ void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) vector temp_source {source_bank->begin(), source_bank->end()}; #endif - //loop over the other nodes and receive data - then write those. + // loop over the other nodes and receive data - then write those. for (int i = 0; i < mpi::n_procs; ++i) { // number of particles for node node i size_t count[] { static_cast((*bank_index)[i + 1] - (*bank_index)[i])}; #ifdef OPENMC_MPI - if (i>0) + if (i > 0) MPI_Recv(source_bank->data(), count[0], mpi::source_site, i, i, mpi::intracomm, MPI_STATUS_IGNORE); #endif // now write the source_bank data again. - for (vector::iterator _site=source_bank->begin(); _site!=source_bank->end();_site++){ + for (vector::iterator _site = source_bank->begin(); + _site != source_bank->end(); _site++) { // particle is now at the iterator // write it to the mcpl-file mcpl_particle_t p; - p.position[0]=_site->r.x; - p.position[1]=_site->r.y; - p.position[2]=_site->r.z; + p.position[0] = _site->r.x; + p.position[1] = _site->r.y; + p.position[2] = _site->r.z; // mcpl requires that the direction vector is unit length // which is also the case in openmc - p.direction[0]=_site->u.x; - p.direction[1]=_site->u.y; - p.direction[2]=_site->u.z; + p.direction[0] = _site->u.x; + p.direction[1] = _site->u.y; + p.direction[2] = _site->u.z; // mcpl stores kinetic energy in MeV - p.ekin=_site->E*1e-6; + p.ekin = _site->E * 1e-6; - p.time=_site->time*1e3; + p.time = _site->time * 1e3; - p.weight=_site->wgt; + p.weight = _site->wgt; - switch(_site->particle){ - case ParticleType::neutron: - p.pdgcode=2112; - break; - case ParticleType::photon: - p.pdgcode=22; - break; - case ParticleType::electron: - p.pdgcode=11; - break; - case ParticleType::positron: - p.pdgcode=-11; - break; + switch (_site->particle) { + case ParticleType::neutron: + p.pdgcode = 2112; + break; + case ParticleType::photon: + p.pdgcode = 22; + break; + case ParticleType::electron: + p.pdgcode = 11; + break; + case ParticleType::positron: + p.pdgcode = -11; + break; } - mcpl_add_particle(file_id,&p); + mcpl_add_particle(file_id, &p); } } #ifdef OPENMC_MPI @@ -851,7 +852,6 @@ void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) mpi::intracomm); #endif } - } #endif From a3065b479c0a47caae6229fa8657da59668be1e9 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 22 Dec 2022 11:33:29 -0600 Subject: [PATCH 138/146] Move FileSource MCPL reading to mcpl_interface.h/cpp --- CMakeLists.txt | 1 + include/openmc/mcpl_interface.h | 25 +++++++++ include/openmc/source.h | 10 +--- src/mcpl_interface.cpp | 93 +++++++++++++++++++++++++++++++++ src/settings.cpp | 11 ++-- src/source.cpp | 69 ------------------------ 6 files changed, 126 insertions(+), 83 deletions(-) create mode 100644 include/openmc/mcpl_interface.h create mode 100644 src/mcpl_interface.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 24018eb0f1..af3a5b4af8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -331,6 +331,7 @@ list(APPEND libopenmc_SOURCES src/lattice.cpp src/material.cpp src/math_functions.cpp + src/mcpl_interface.cpp src/mesh.cpp src/message_passing.cpp src/mgxs.cpp diff --git a/include/openmc/mcpl_interface.h b/include/openmc/mcpl_interface.h new file mode 100644 index 0000000000..89dab16bcb --- /dev/null +++ b/include/openmc/mcpl_interface.h @@ -0,0 +1,25 @@ +#ifndef OPENMC_MCPL_INTERFACE_H +#define OPENMC_MCPL_INTERFACE_H + +#include "openmc/particle_data.h" + +#include +#include + +#ifdef OPENMC_MCPL +#include +#endif + +namespace openmc { + +extern "C" const bool MCPL_ENABLED; + +//! Get a vector of source sites from an MCPL file +// +//! \param[in] path Path to MCPL file +//! \return Vector of source sites +vector mcpl_source_sites(std::string path); + +} // namespace openmc + +#endif // OPENMC_MCPL_INTERFACE_H diff --git a/include/openmc/source.h b/include/openmc/source.h index 051167b3f6..96d659dcb3 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -14,10 +14,6 @@ #include "openmc/particle.h" #include "openmc/vector.h" -#ifdef OPENMC_MCPL -#include -#endif - namespace openmc { //============================================================================== @@ -32,7 +28,6 @@ constexpr double EXTSRC_REJECT_FRACTION {0.05}; //============================================================================== // Global variables //============================================================================== -extern "C" const bool MCPL_ENABLED; class Source; @@ -107,9 +102,8 @@ class FileSource : public Source { public: // Constructors explicit FileSource(std::string path); -#ifdef OPENMC_MCPL - explicit FileSource(mcpl_file_t mcpl_file); -#endif + explicit FileSource(const vector& sites) : sites_ {sites} {} + // Methods SourceSite sample(uint64_t* seed) const override; diff --git a/src/mcpl_interface.cpp b/src/mcpl_interface.cpp new file mode 100644 index 0000000000..d55cc5af7c --- /dev/null +++ b/src/mcpl_interface.cpp @@ -0,0 +1,93 @@ +#include "openmc/mcpl_interface.h" + +#include "openmc/error.h" + +#ifdef OPENMC_MCPL +#include +#endif + +namespace openmc { + +#ifdef OPENMC_MCPL +const bool MCPL_ENABLED = true; +#else +const bool MCPL_ENABLED = false; +#endif + +#ifdef OPENMC_MCPL +SourceSite mcpl_particle_to_site(const mcpl_particle* particle) +{ + SourceSite site; + + switch (particle->pdgcode) { + case 2112: + site.particle = ParticleType::neutron; + break; + case 22: + site.particle = ParticleType::photon; + break; + case 11: + site.particle = ParticleType::electron; + break; + case -11: + site.particle = ParticleType::positron; + break; + } + + // Copy position and direction + site.r.x = mcpl_particle->position[0]; + site.r.y = mcpl_particle->position[1]; + site.r.z = mcpl_particle->position[2]; + site.u.x = mcpl_particle->direction[0]; + site.u.y = mcpl_particle->direction[1]; + site.u.z = mcpl_particle->direction[2]; + + // mcpl stores kinetic energy in MeV + site.E = mcpl_particle->ekin * 1e6; + // mcpl stores time in ms + site.time = mcpl_particle->time * 1e-3; + site.wgt = mcpl_particle->weight; + + return site; +} +#endif + +vector mcpl_source_sites(std::string path) +{ + vector sites; + +#ifdef OPENMC_MCPL + size_t n_sites = mcpl_hdr_nparticles(mcpl_file); + + for (int i = 0; i < n_sites; i++) { + SourceSite site; + + // Extract particle from mcpl-file, checking if it is a neutron, photon, + // electron, or positron. Otherwise skip. + const mcpl_particle_t* particle; + int pdg = 0; + while (pdg != 2112 && pdg != 22 && pdg != 11 && pdg != -11) { + particle = mcpl_read(mcpl_file); + pdg = mcpl_particle->pdgcode; + } + + // Convert to source site and add to vector + sites.push_back(mcpl_particle_to_site(particle)); + } + + // Check that some sites were read + if (sites_.empty()) { + fatal_error("MCPL file contained no neutron, photon, electron, or positron " + "source particles."); + } + + mcpl_close_file(mcpl_file); +#else + fatal_error( + "Your build of OpenMC does not support reading MCPL source files."); +#endif + + return sites; +} + +} // namespace openmc diff --git a/src/settings.cpp b/src/settings.cpp index de298c58d1..bc31e2c4d0 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -18,6 +18,7 @@ #include "openmc/eigenvalue.h" #include "openmc/error.h" #include "openmc/file_utils.h" +#include "openmc/mcpl_interface.h" #include "openmc/mesh.h" #include "openmc/message_passing.h" #include "openmc/output.h" @@ -431,16 +432,14 @@ void read_settings_xml() for (pugi::xml_node node : root.children("source")) { if (check_for_node(node, "file")) { auto path = get_node_value(node, "file", false, true); -#ifdef OPENMC_MCPL if (ends_with(path, ".mcpl") || ends_with(path, ".mcpl.gz")) { - model::external_sources.push_back( - make_unique(mcpl_open_file(path.c_str()))); +#ifdef OPENMC_MCPL + auto sites = mcpl_source_sites(path); + model::external_sources.push_back(make_unique(sites)); +#endif } else { model::external_sources.push_back(make_unique(path)); } -#else - model::external_sources.push_back(make_unique(path)); -#endif } else if (check_for_node(node, "library")) { // Get shared library path and parameters auto path = get_node_value(node, "library", false, true); diff --git a/src/source.cpp b/src/source.cpp index 4ab087e125..d201e3c033 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -33,22 +33,12 @@ #include "openmc/state_point.h" #include "openmc/xml_interface.h" -#ifdef OPENMC_MCPL -#include -#endif - namespace openmc { //============================================================================== // Global variables //============================================================================== -#ifdef OPENMC_MCPL -const bool MCPL_ENABLED = true; -#else -const bool MCPL_ENABLED = false; -#endif - namespace model { vector> external_sources; @@ -330,65 +320,6 @@ FileSource::FileSource(std::string path) file_close(file_id); } -#ifdef OPENMC_MCPL -FileSource::FileSource(mcpl_file_t mcpl_file) -{ - size_t n_sites = mcpl_hdr_nparticles(mcpl_file); - - for (int i = 0; i < n_sites; i++) { - SourceSite site; - - const mcpl_particle_t* mcpl_particle; - // extract particle from mcpl-file - mcpl_particle = mcpl_read(mcpl_file); - // check if it is a neutron, photon, electron, or positron. Otherwise skip. - int pdg = mcpl_particle->pdgcode; - while (pdg != 2112 && pdg != 22 && pdg != 11 && pdg != -11) { - mcpl_particle = mcpl_read(mcpl_file); - pdg = mcpl_particle->pdgcode; - } - - switch (pdg) { - case 2112: - site.particle = ParticleType::neutron; - break; - case 22: - site.particle = ParticleType::photon; - break; - case 11: - site.particle = ParticleType::electron; - break; - case -11: - site.particle = ParticleType::positron; - break; - } - - // Copy position and direction - site.r.x = mcpl_particle->position[0]; - site.r.y = mcpl_particle->position[1]; - site.r.z = mcpl_particle->position[2]; - site.u.x = mcpl_particle->direction[0]; - site.u.y = mcpl_particle->direction[1]; - site.u.z = mcpl_particle->direction[2]; - - // mcpl stores kinetic energy in MeV - site.E = mcpl_particle->ekin * 1e6; - // mcpl stores time in ms - site.time = mcpl_particle->time * 1e-3; - site.wgt = mcpl_particle->weight; - sites_.push_back(site); - } - - // Check that some sites were read - if (sites_.empty()) { - fatal_error("MCPL file contained no neutron, photon, electron, or positron " - "source particles."); - } - - mcpl_close_file(mcpl_file); -} -#endif // OPENMC_MCPL - SourceSite FileSource::sample(uint64_t* seed) const { size_t i_site = sites_.size() * prn(seed); From 361b3486efa4c078e87a1c29f76e6ab4a1edc58e Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 22 Dec 2022 12:27:56 -0600 Subject: [PATCH 139/146] Move remainder of MCPL-related code to mcpl_interface.h/cpp --- CMakeLists.txt | 1 + include/openmc/mcpl_interface.h | 19 +++- include/openmc/state_point.h | 10 -- src/mcpl_interface.cpp | 185 +++++++++++++++++++++++++++++--- src/settings.cpp | 18 +++- src/simulation.cpp | 7 +- src/state_point.cpp | 140 ------------------------ 7 files changed, 201 insertions(+), 179 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index af3a5b4af8..466816b300 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,6 +164,7 @@ endif() #=============================================================================== if (OPENMC_USE_MCPL) find_package(MCPL REQUIRED) + message(STATUS "Found MCPL: ${MCPL_DIR} (found version \"${MCPL_VERSION}\")") endif() #=============================================================================== diff --git a/include/openmc/mcpl_interface.h b/include/openmc/mcpl_interface.h index 89dab16bcb..c931f17743 100644 --- a/include/openmc/mcpl_interface.h +++ b/include/openmc/mcpl_interface.h @@ -6,20 +6,31 @@ #include #include -#ifdef OPENMC_MCPL -#include -#endif - namespace openmc { +//============================================================================== +// Constants +//============================================================================== + extern "C" const bool MCPL_ENABLED; +//============================================================================== +// Functions +//============================================================================== + //! Get a vector of source sites from an MCPL file // //! \param[in] path Path to MCPL file //! \return Vector of source sites vector 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); + } // namespace openmc #endif // OPENMC_MCPL_INTERFACE_H diff --git a/include/openmc/state_point.h b/include/openmc/state_point.h index 7301275542..5ada2bf88d 100644 --- a/include/openmc/state_point.h +++ b/include/openmc/state_point.h @@ -9,10 +9,6 @@ #include "openmc/particle.h" #include "openmc/vector.h" -#ifdef OPENMC_MCPL -#include -#endif - namespace openmc { void load_state_point(); @@ -25,11 +21,5 @@ void write_tally_results_nr(hid_t file_id); void restart_set_keff(); void write_unstructured_mesh_results(); -#ifdef OPENMC_MCPL -void write_mcpl_source_point( - const char* filename, bool surf_source_bank = false); -void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank); -#endif - } // namespace openmc #endif // OPENMC_STATE_POINT_H diff --git a/src/mcpl_interface.cpp b/src/mcpl_interface.cpp index d55cc5af7c..e9bc648303 100644 --- a/src/mcpl_interface.cpp +++ b/src/mcpl_interface.cpp @@ -1,6 +1,13 @@ #include "openmc/mcpl_interface.h" +#include "openmc/bank.h" #include "openmc/error.h" +#include "openmc/message_passing.h" +#include "openmc/settings.h" +#include "openmc/simulation.h" +#include "openmc/state_point.h" + +#include #ifdef OPENMC_MCPL #include @@ -8,14 +15,22 @@ namespace openmc { +//============================================================================== +// Constants +//============================================================================== + #ifdef OPENMC_MCPL const bool MCPL_ENABLED = true; #else const bool MCPL_ENABLED = false; #endif +//============================================================================== +// Functions +//============================================================================== + #ifdef OPENMC_MCPL -SourceSite mcpl_particle_to_site(const mcpl_particle* particle) +SourceSite mcpl_particle_to_site(const mcpl_particle_t* particle) { SourceSite site; @@ -35,40 +50,42 @@ SourceSite mcpl_particle_to_site(const mcpl_particle* particle) } // Copy position and direction - site.r.x = mcpl_particle->position[0]; - site.r.y = mcpl_particle->position[1]; - site.r.z = mcpl_particle->position[2]; - site.u.x = mcpl_particle->direction[0]; - site.u.y = mcpl_particle->direction[1]; - site.u.z = mcpl_particle->direction[2]; + site.r.x = particle->position[0]; + site.r.y = particle->position[1]; + site.r.z = particle->position[2]; + site.u.x = particle->direction[0]; + site.u.y = particle->direction[1]; + site.u.z = particle->direction[2]; // mcpl stores kinetic energy in MeV - site.E = mcpl_particle->ekin * 1e6; + site.E = particle->ekin * 1e6; // mcpl stores time in ms - site.time = mcpl_particle->time * 1e-3; - site.wgt = mcpl_particle->weight; + site.time = particle->time * 1e-3; + site.wgt = particle->weight; return site; } #endif +//============================================================================== + vector mcpl_source_sites(std::string path) { vector sites; #ifdef OPENMC_MCPL + // Open MCPL file and determine number of particles + auto mcpl_file = mcpl_open_file(path.c_str()); size_t n_sites = mcpl_hdr_nparticles(mcpl_file); for (int i = 0; i < n_sites; i++) { - SourceSite site; - // Extract particle from mcpl-file, checking if it is a neutron, photon, // electron, or positron. Otherwise skip. const mcpl_particle_t* particle; int pdg = 0; while (pdg != 2112 && pdg != 22 && pdg != 11 && pdg != -11) { particle = mcpl_read(mcpl_file); - pdg = mcpl_particle->pdgcode; + pdg = particle->pdgcode; } // Convert to source site and add to vector @@ -76,7 +93,7 @@ vector mcpl_source_sites(std::string path) } // Check that some sites were read - if (sites_.empty()) { + if (sites.empty()) { fatal_error("MCPL file contained no neutron, photon, electron, or positron " "source particles."); } @@ -90,4 +107,144 @@ vector mcpl_source_sites(std::string path) return sites; } +//============================================================================== + +#ifdef OPENMC_MCPL +void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) +{ + int64_t dims_size = settings::n_particles; + int64_t count_size = simulation::work_per_rank; + + // Set vectors for source bank and starting bank index of each process + vector* bank_index = &simulation::work_index; + vector* source_bank = &simulation::source_bank; + vector surf_source_index_vector; + vector surf_source_bank_vector; + + if (surf_source_bank) { + surf_source_index_vector = calculate_surf_source_size(); + dims_size = surf_source_index_vector[mpi::n_procs]; + count_size = simulation::surf_source_bank.size(); + + bank_index = &surf_source_index_vector; + + // Copy data in a SharedArray into a vector. + surf_source_bank_vector.resize(count_size); + surf_source_bank_vector.assign(simulation::surf_source_bank.data(), + simulation::surf_source_bank.data() + count_size); + source_bank = &surf_source_bank_vector; + } + + if (mpi::master) { + // Particles are writeen to disk from the master node only + + // Save source bank sites since the array is overwritten below +#ifdef OPENMC_MPI + vector temp_source {source_bank->begin(), source_bank->end()}; +#endif + + // loop over the other nodes and receive data - then write those. + for (int i = 0; i < mpi::n_procs; ++i) { + // number of particles for node node i + size_t count[] { + static_cast((*bank_index)[i + 1] - (*bank_index)[i])}; + +#ifdef OPENMC_MPI + if (i > 0) + MPI_Recv(source_bank->data(), count[0], mpi::source_site, i, i, + mpi::intracomm, MPI_STATUS_IGNORE); +#endif + // now write the source_bank data again. + for (vector::iterator _site = source_bank->begin(); + _site != source_bank->end(); _site++) { + // particle is now at the iterator + // write it to the mcpl-file + mcpl_particle_t p; + p.position[0] = _site->r.x; + p.position[1] = _site->r.y; + p.position[2] = _site->r.z; + + // mcpl requires that the direction vector is unit length + // which is also the case in openmc + p.direction[0] = _site->u.x; + p.direction[1] = _site->u.y; + p.direction[2] = _site->u.z; + + // mcpl stores kinetic energy in MeV + p.ekin = _site->E * 1e-6; + + p.time = _site->time * 1e3; + + p.weight = _site->wgt; + + switch (_site->particle) { + case ParticleType::neutron: + p.pdgcode = 2112; + break; + case ParticleType::photon: + p.pdgcode = 22; + break; + case ParticleType::electron: + p.pdgcode = 11; + break; + case ParticleType::positron: + p.pdgcode = -11; + break; + } + + mcpl_add_particle(file_id, &p); + } + } +#ifdef OPENMC_MPI + // Restore state of source bank + std::copy(temp_source.begin(), temp_source.end(), source_bank->begin()); +#endif + } else { +#ifdef OPENMC_MPI + MPI_Send(source_bank->data(), count_size, mpi::source_site, 0, mpi::rank, + mpi::intracomm); +#endif + } +} +#endif + +//============================================================================== + +void write_mcpl_source_point(const char* filename, bool surf_source_bank) +{ + std::string filename_; + if (filename) { + filename_ = filename; + } else { + // Determine width for zero padding + int w = std::to_string(settings::n_max_batches).size(); + + filename_ = fmt::format("{0}source.{1:0{2}}.mcpl", settings::path_output, + simulation::current_batch, w); + } + +#ifdef OPENMC_MCPL + mcpl_outfile_t file_id; + + std::string line; + if (mpi::master) { + file_id = mcpl_create_outfile(filename_.c_str()); + if (VERSION_DEV) { + line = fmt::format("OpenMC {0}.{1}.{2}-development", VERSION_MAJOR, + VERSION_MINOR, VERSION_RELEASE); + } else { + line = fmt::format( + "OpenMC {0}.{1}.{2}", VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE); + } + mcpl_hdr_set_srcname(file_id, line.c_str()); + } + + write_mcpl_source_bank(file_id, surf_source_bank); + + if (mpi::master) { + mcpl_close_outfile(file_id); + } +#endif +} + } // namespace openmc diff --git a/src/settings.cpp b/src/settings.cpp index bc31e2c4d0..cb39d0c8b2 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -433,10 +433,8 @@ void read_settings_xml() if (check_for_node(node, "file")) { auto path = get_node_value(node, "file", false, true); if (ends_with(path, ".mcpl") || ends_with(path, ".mcpl.gz")) { -#ifdef OPENMC_MCPL auto sites = mcpl_source_sites(path); model::external_sources.push_back(make_unique(sites)); -#endif } else { model::external_sources.push_back(make_unique(path)); } @@ -659,6 +657,12 @@ void read_settings_xml() } if (check_for_node(node_sp, "mcpl")) { source_mcpl_write = get_node_value_bool(node_sp, "mcpl"); + + // Make sure MCPL support is enabled + if (source_mcpl_write && !MCPL_ENABLED) { + fatal_error( + "Your build of OpenMC does not support writing MCPL source files."); + } } if (check_for_node(node_sp, "overwrite_latest")) { source_latest = get_node_value_bool(node_sp, "overwrite_latest"); @@ -690,11 +694,15 @@ void read_settings_xml() max_surface_particles = std::stoll(get_node_value(node_ssw, "max_particles")); } -#ifdef OPENMC_MCPL if (check_for_node(node_ssw, "mcpl")) { - surf_mcpl_write = true; + surf_mcpl_write = get_node_value_bool(node_ssw, "mcpl"); + + // Make sure MCPL support is enabled + if (surf_mcpl_write && !MCPL_ENABLED) { + fatal_error("Your build of OpenMC does not support writing MCPL " + "surface source files."); + } } -#endif } // If source is not separate and is to be written out in the statepoint file, diff --git a/src/simulation.cpp b/src/simulation.cpp index 2c1d1c988b..497b26124b 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -8,6 +8,7 @@ #include "openmc/event.h" #include "openmc/geometry_aux.h" #include "openmc/material.h" +#include "openmc/mcpl_interface.h" #include "openmc/message_passing.h" #include "openmc/nuclide.h" #include "openmc/output.h" @@ -389,9 +390,7 @@ void finalize_batch() if (settings::run_mode == RunMode::EIGENVALUE) { // Write out a separate source point if it's been specified for this batch -#ifdef OPENMC_MCPL if (!settings::source_mcpl_write) { -#endif if (contains(settings::sourcepoint_batch, simulation::current_batch) && settings::source_write && settings::source_separate) { write_source_point(nullptr); @@ -402,7 +401,6 @@ void finalize_batch() auto filename = settings::path_output + "source.h5"; write_source_point(filename.c_str()); } -#ifdef OPENMC_MCPL } else { if (contains(settings::sourcepoint_batch, simulation::current_batch) && settings::source_mcpl_write && settings::source_separate) { @@ -415,7 +413,6 @@ void finalize_batch() write_mcpl_source_point(filename.c_str()); } } -#endif } // Write out surface source if requested. @@ -424,13 +421,11 @@ void finalize_batch() auto filename = settings::path_output + "surface_source.h5"; write_source_point(filename.c_str(), true); } -#ifdef OPENMC_MCPL if (settings::surf_mcpl_write && simulation::current_batch == settings::n_batches) { auto filename = settings::path_output + "surface_source.mcpl"; write_mcpl_source_point(filename.c_str(), true); } -#endif } void initialize_generation() diff --git a/src/state_point.cpp b/src/state_point.cpp index 9dd0f13747..470dd77182 100644 --- a/src/state_point.cpp +++ b/src/state_point.cpp @@ -28,10 +28,6 @@ #include "openmc/timer.h" #include "openmc/vector.h" -#ifdef OPENMC_MCPL -#include -#endif - namespace openmc { extern "C" int openmc_statepoint_write(const char* filename, bool* write_source) @@ -603,43 +599,6 @@ void write_source_point(const char* filename, bool surf_source_bank) file_close(file_id); } -#ifdef OPENMC_MCPL -void write_mcpl_source_point(const char* filename, bool surf_source_bank) -{ - std::string filename_; - if (filename) { - filename_ = filename; - } else { - // Determine width for zero padding - int w = std::to_string(settings::n_max_batches).size(); - - filename_ = fmt::format("{0}source.{1:0{2}}.mcpl", settings::path_output, - simulation::current_batch, w); - } - - mcpl_outfile_t file_id; - - std::string line; - if (mpi::master) { - file_id = mcpl_create_outfile(filename_.c_str()); - if (VERSION_DEV) { - line = fmt::format("OpenMC {0}.{1}.{2}-development", VERSION_MAJOR, - VERSION_MINOR, VERSION_RELEASE); - } else { - line = fmt::format( - "OpenMC {0}.{1}.{2}", VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE); - } - mcpl_hdr_set_srcname(file_id, line.c_str()); - } - - write_mcpl_source_bank(file_id, surf_source_bank); - - if (mpi::master) { - mcpl_close_outfile(file_id); - } -} -#endif - void write_source_bank(hid_t group_id, bool surf_source_bank) { hid_t banktype = h5banktype(); @@ -756,105 +715,6 @@ void write_source_bank(hid_t group_id, bool surf_source_bank) H5Tclose(banktype); } -#ifdef OPENMC_MCPL -void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) -{ - int64_t dims_size = settings::n_particles; - int64_t count_size = simulation::work_per_rank; - - // Set vectors for source bank and starting bank index of each process - vector* bank_index = &simulation::work_index; - vector* source_bank = &simulation::source_bank; - vector surf_source_index_vector; - vector surf_source_bank_vector; - - if (surf_source_bank) { - surf_source_index_vector = calculate_surf_source_size(); - dims_size = surf_source_index_vector[mpi::n_procs]; - count_size = simulation::surf_source_bank.size(); - - bank_index = &surf_source_index_vector; - - // Copy data in a SharedArray into a vector. - surf_source_bank_vector.resize(count_size); - surf_source_bank_vector.assign(simulation::surf_source_bank.data(), - simulation::surf_source_bank.data() + count_size); - source_bank = &surf_source_bank_vector; - } - - if (mpi::master) { - // Particles are writeen to disk from the master node only - - // Save source bank sites since the array is overwritten below -#ifdef OPENMC_MPI - vector temp_source {source_bank->begin(), source_bank->end()}; -#endif - - // loop over the other nodes and receive data - then write those. - for (int i = 0; i < mpi::n_procs; ++i) { - // number of particles for node node i - size_t count[] { - static_cast((*bank_index)[i + 1] - (*bank_index)[i])}; - -#ifdef OPENMC_MPI - if (i > 0) - MPI_Recv(source_bank->data(), count[0], mpi::source_site, i, i, - mpi::intracomm, MPI_STATUS_IGNORE); -#endif - // now write the source_bank data again. - for (vector::iterator _site = source_bank->begin(); - _site != source_bank->end(); _site++) { - // particle is now at the iterator - // write it to the mcpl-file - mcpl_particle_t p; - p.position[0] = _site->r.x; - p.position[1] = _site->r.y; - p.position[2] = _site->r.z; - - // mcpl requires that the direction vector is unit length - // which is also the case in openmc - p.direction[0] = _site->u.x; - p.direction[1] = _site->u.y; - p.direction[2] = _site->u.z; - - // mcpl stores kinetic energy in MeV - p.ekin = _site->E * 1e-6; - - p.time = _site->time * 1e3; - - p.weight = _site->wgt; - - switch (_site->particle) { - case ParticleType::neutron: - p.pdgcode = 2112; - break; - case ParticleType::photon: - p.pdgcode = 22; - break; - case ParticleType::electron: - p.pdgcode = 11; - break; - case ParticleType::positron: - p.pdgcode = -11; - break; - } - - mcpl_add_particle(file_id, &p); - } - } -#ifdef OPENMC_MPI - // Restore state of source bank - std::copy(temp_source.begin(), temp_source.end(), source_bank->begin()); -#endif - } else { -#ifdef OPENMC_MPI - MPI_Send(source_bank->data(), count_size, mpi::source_site, 0, mpi::rank, - mpi::intracomm); -#endif - } -} -#endif - // Determine member names of a compound HDF5 datatype std::string dtype_member_names(hid_t dtype_id) { From 9ae44b3fd1e9c6e26c3f5089c9382a7fe97eb48e Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 22 Dec 2022 12:43:31 -0600 Subject: [PATCH 140/146] Rearragne MCPL source writing logic --- src/simulation.cpp | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/src/simulation.cpp b/src/simulation.cpp index 497b26124b..2f07f8124f 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -390,27 +390,23 @@ void finalize_batch() if (settings::run_mode == RunMode::EIGENVALUE) { // Write out a separate source point if it's been specified for this batch - if (!settings::source_mcpl_write) { - if (contains(settings::sourcepoint_batch, simulation::current_batch) && - settings::source_write && settings::source_separate) { + if (contains(settings::sourcepoint_batch, simulation::current_batch) && + settings::source_write && settings::source_separate) { + if (settings::source_mcpl_write) { + write_mcpl_source_point(nullptr); + } else { write_source_point(nullptr); } + } - // Write a continously-overwritten source point if requested. - if (settings::source_latest) { - auto filename = settings::path_output + "source.h5"; - write_source_point(filename.c_str()); - } - } else { - if (contains(settings::sourcepoint_batch, simulation::current_batch) && - settings::source_mcpl_write && settings::source_separate) { - write_mcpl_source_point(nullptr); - } - - // Write a continously-overwritten source point if requested. - if (settings::source_latest && settings::source_mcpl_write) { + // Write a continously-overwritten source point if requested. + if (settings::source_latest) { + if (settings::source_mcpl_write) { auto filename = settings::path_output + "source.mcpl"; write_mcpl_source_point(filename.c_str()); + } else { + auto filename = settings::path_output + "source.h5"; + write_source_point(filename.c_str()); } } } @@ -418,13 +414,13 @@ void finalize_batch() // Write out surface source if requested. if (settings::surf_source_write && simulation::current_batch == settings::n_batches) { - auto filename = settings::path_output + "surface_source.h5"; - write_source_point(filename.c_str(), true); - } - if (settings::surf_mcpl_write && - simulation::current_batch == settings::n_batches) { - auto filename = settings::path_output + "surface_source.mcpl"; - write_mcpl_source_point(filename.c_str(), true); + if (settings::surf_mcpl_write) { + auto filename = settings::path_output + "surface_source.mcpl"; + write_mcpl_source_point(filename.c_str(), true); + } else { + auto filename = settings::path_output + "surface_source.h5"; + write_source_point(filename.c_str(), true); + } } } From eeab41a19d8bbe1617f6abb63ff8bb2f89dd24f3 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 22 Dec 2022 14:03:26 -0600 Subject: [PATCH 141/146] Build against MCPL in CI by default --- tools/ci/gha-install.py | 12 ++++-------- tools/ci/gha-install.sh | 6 ++---- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/tools/ci/gha-install.py b/tools/ci/gha-install.py index ea317b5f0a..83e5afac79 100644 --- a/tools/ci/gha-install.py +++ b/tools/ci/gha-install.py @@ -19,14 +19,14 @@ def which(program): return None -def install(omp=False, mpi=False, phdf5=False, dagmc=False, libmesh=False, mcpl=False): +def install(omp=False, mpi=False, phdf5=False, dagmc=False, libmesh=False): # Create build directory and change to it shutil.rmtree('build', ignore_errors=True) os.mkdir('build') os.chdir('build') - # Build in debug mode by default - cmake_cmd = ['cmake', '-DCMAKE_BUILD_TYPE=Debug'] + # Build in debug mode by default with support for MCPL + cmake_cmd = ['cmake', '-DCMAKE_BUILD_TYPE=Debug', '-DOPENMC_USE_MCPL=on'] # Turn off OpenMP if specified if not omp: @@ -54,9 +54,6 @@ def install(omp=False, mpi=False, phdf5=False, dagmc=False, libmesh=False, mcpl= libmesh_path = os.environ.get('HOME') + '/LIBMESH' cmake_cmd.append('-DCMAKE_PREFIX_PATH=' + libmesh_path) - if mcpl: - cmake_cmd.append('-DOPENMC_USE_MCPL=ON') - # Build in coverage mode for coverage testing cmake_cmd.append('-DOPENMC_ENABLE_COVERAGE=on') @@ -74,10 +71,9 @@ def main(): phdf5 = (os.environ.get('PHDF5') == 'y') dagmc = (os.environ.get('DAGMC') == 'y') libmesh = (os.environ.get('LIBMESH') == 'y') - mcpl = (os.environ.get('MCPL') == 'y') # Build and install - install(omp, mpi, phdf5, dagmc, libmesh, mcpl) + install(omp, mpi, phdf5, dagmc, libmesh) if __name__ == '__main__': main() diff --git a/tools/ci/gha-install.sh b/tools/ci/gha-install.sh index 68e825d486..75fa0ca703 100755 --- a/tools/ci/gha-install.sh +++ b/tools/ci/gha-install.sh @@ -27,10 +27,8 @@ if [[ $LIBMESH = 'y' ]]; then ./tools/ci/gha-install-libmesh.sh fi -# Install mcpl if needed -if [[ $MCPL = 'y' ]]; then - ./tools/ci/gha-install-mcpl.sh -fi +# Install MCPL +./tools/ci/gha-install-mcpl.sh # For MPI configurations, make sure mpi4py and h5py are built against the # correct version of MPI From 47848b79abe964be913095397d1d5aaf2780d28c Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 22 Dec 2022 14:34:37 -0600 Subject: [PATCH 142/146] Allow Settings.sourcepoint['mcpl'] to be set --- docs/source/io_formats/settings.rst | 14 +++++++++++--- openmc/settings.py | 12 ++++++++++-- tests/unit_tests/test_settings.py | 4 ++-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/docs/source/io_formats/settings.rst b/docs/source/io_formats/settings.rst index 7174c5317a..01b1852ca2 100644 --- a/docs/source/io_formats/settings.rst +++ b/docs/source/io_formats/settings.rst @@ -732,6 +732,14 @@ attributes/sub-elements: *Default*: false + :mcpl: + If this element is set to "true", the source point file containing the + source bank will be written as an MCPL_ file name ``source.mcpl`` instead of + an HDF5 file. This option is only applicable if the ```` element + is set to true. + + *Default*: false + ------------------------------ ```` Element ------------------------------ @@ -769,13 +777,13 @@ certain surfaces and write out the source bank in a separate file called :mcpl: An optional boolean which indicates if the banked particles should be - written to a file in the MCPL-format (documented in mcpl_). instead of the - native HDF5-based format. If activated the output file name is changed to + written to a file in the MCPL_-format instead of the native HDF5-based + format. If activated the output file name is changed to ``surface_source.mcpl``. *Default*: false - .. _mcpl: https://mctools.github.io/mcpl/mcpl.pdf + .. _MCPL: https://mctools.github.io/mcpl/mcpl.pdf ------------------------------ ```` Element diff --git a/openmc/settings.py b/openmc/settings.py index fd622870c5..cc0ca29645 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -156,6 +156,7 @@ class Settings: :separate: bool indicating whether the source should be written as a separate file :write: bool indicating whether or not to write the source + :mcpl: bool indicating whether to write the source as an MCPL file statepoint : dict Options for writing state points. Acceptable keys are: @@ -620,6 +621,8 @@ class Settings: cv.check_type('sourcepoint write', value, bool) elif key == 'overwrite': cv.check_type('sourcepoint overwrite', value, bool) + elif key == 'mcpl': + cv.check_type('sourcepoint mcpl', value, bool) else: raise ValueError(f"Unknown key '{key}' encountered when " "setting sourcepoint options.") @@ -1019,6 +1022,11 @@ class Settings: subelement = ET.SubElement(element, "overwrite_latest") subelement.text = str(self._sourcepoint['overwrite']).lower() + if 'mcpl' in self._sourcepoint: + subelement = ET.SubElement(element, "mcpl") + subelement.text = str(self._sourcepoint['mcpl']).lower() + + def _create_surf_source_read_subelement(self, root): if self._surf_source_read: element = ET.SubElement(root, "surf_source_read") @@ -1319,10 +1327,10 @@ class Settings: def _sourcepoint_from_xml_element(self, root): elem = root.find('source_point') if elem is not None: - for key in ('separate', 'write', 'overwrite_latest', 'batches'): + for key in ('separate', 'write', 'overwrite_latest', 'batches', 'mcpl'): value = get_text(elem, key) if value is not None: - if key in ('separate', 'write'): + if key in ('separate', 'write', 'mcpl'): value = value in ('true', '1') elif key == 'overwrite_latest': value = value in ('true', '1') diff --git a/tests/unit_tests/test_settings.py b/tests/unit_tests/test_settings.py index 7678711a43..f1ae581923 100644 --- a/tests/unit_tests/test_settings.py +++ b/tests/unit_tests/test_settings.py @@ -17,7 +17,7 @@ def test_export_to_xml(run_in_tmpdir): s.output = {'summary': True, 'tallies': False, 'path': 'here'} s.verbosity = 7 s.sourcepoint = {'batches': [50, 150, 500, 1000], 'separate': True, - 'write': True, 'overwrite': True} + 'write': True, 'overwrite': True, 'mcpl': True} s.statepoint = {'batches': [50, 150, 500, 1000]} s.surf_source_read = {'path': 'surface_source_1.h5'} s.surf_source_write = {'surface_ids': [2], 'max_particles': 200} @@ -75,7 +75,7 @@ def test_export_to_xml(run_in_tmpdir): assert s.output == {'summary': True, 'tallies': False, 'path': 'here'} assert s.verbosity == 7 assert s.sourcepoint == {'batches': [50, 150, 500, 1000], 'separate': True, - 'write': True, 'overwrite': True} + 'write': True, 'overwrite': True, 'mcpl': True} assert s.statepoint == {'batches': [50, 150, 500, 1000]} assert s.surf_source_read == {'path': 'surface_source_1.h5'} assert s.surf_source_write == {'surface_ids': [2], 'max_particles': 200} From 731eff8817520773670d8a56c3ee4fbf7962cca9 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 22 Dec 2022 14:43:58 -0600 Subject: [PATCH 143/146] Update source_mcpl_file test result --- tests/regression_tests/source_mcpl_file/results_true.dat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/regression_tests/source_mcpl_file/results_true.dat b/tests/regression_tests/source_mcpl_file/results_true.dat index e8f4a20a08..5651efde70 100644 --- a/tests/regression_tests/source_mcpl_file/results_true.dat +++ b/tests/regression_tests/source_mcpl_file/results_true.dat @@ -1,2 +1,2 @@ k-combined: -3.004254E-01 8.027600E-04 +2.943088E-01 2.093028E-03 From ddbd61cc97ee2767d81f93b62542a3d367be1c85 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 22 Dec 2022 14:49:47 -0600 Subject: [PATCH 144/146] Formatting fixes --- CMakeLists.txt | 1 + openmc/settings.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 466816b300..c6c2257830 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,6 +162,7 @@ endif() #=============================================================================== # MCPL #=============================================================================== + if (OPENMC_USE_MCPL) find_package(MCPL REQUIRED) message(STATUS "Found MCPL: ${MCPL_DIR} (found version \"${MCPL_VERSION}\")") diff --git a/openmc/settings.py b/openmc/settings.py index cc0ca29645..e445655ca2 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -1026,7 +1026,6 @@ class Settings: subelement = ET.SubElement(element, "mcpl") subelement.text = str(self._sourcepoint['mcpl']).lower() - def _create_surf_source_read_subelement(self, root): if self._surf_source_read: element = ET.SubElement(root, "surf_source_read") From a0d8541a0164e19732ff3ce50b94ae9f83e0da13 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 22 Dec 2022 22:27:03 -0600 Subject: [PATCH 145/146] Make sure OpenMCConfig.cmake.in includes MCPL --- cmake/OpenMCConfig.cmake.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/OpenMCConfig.cmake.in b/cmake/OpenMCConfig.cmake.in index d0e2beb827..1e35083050 100644 --- a/cmake/OpenMCConfig.cmake.in +++ b/cmake/OpenMCConfig.cmake.in @@ -25,3 +25,7 @@ endif() if(@OPENMC_USE_MPI@) find_package(MPI REQUIRED) endif() + +if(@OPENMC_USE_MCPL@) + find_package(MCPL REQUIRED) +endif() From 954a2bdcdaf47cfbf778f0e07e0c4ab3fba17175 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 23 Dec 2022 11:12:22 -0600 Subject: [PATCH 146/146] Fix source definition in source_mcpl_file test --- include/openmc/mcpl_interface.h | 2 +- src/mcpl_interface.cpp | 31 +++++++++---------- .../source_mcpl_file/results_true.dat | 2 +- .../source_mcpl_file/settings.xml | 1 - .../regression_tests/source_mcpl_file/test.py | 3 +- 5 files changed, 17 insertions(+), 22 deletions(-) diff --git a/include/openmc/mcpl_interface.h b/include/openmc/mcpl_interface.h index c931f17743..64f15c13ab 100644 --- a/include/openmc/mcpl_interface.h +++ b/include/openmc/mcpl_interface.h @@ -2,9 +2,9 @@ #define OPENMC_MCPL_INTERFACE_H #include "openmc/particle_data.h" +#include "openmc/vector.h" #include -#include namespace openmc { diff --git a/src/mcpl_interface.cpp b/src/mcpl_interface.cpp index e9bc648303..a388914782 100644 --- a/src/mcpl_interface.cpp +++ b/src/mcpl_interface.cpp @@ -6,6 +6,7 @@ #include "openmc/settings.h" #include "openmc/simulation.h" #include "openmc/state_point.h" +#include "openmc/vector.h" #include @@ -57,9 +58,8 @@ SourceSite mcpl_particle_to_site(const mcpl_particle_t* particle) site.u.y = particle->direction[1]; site.u.z = particle->direction[2]; - // mcpl stores kinetic energy in MeV + // MCPL stores kinetic energy in [MeV], time in [ms] site.E = particle->ekin * 1e6; - // mcpl stores time in ms site.time = particle->time * 1e-3; site.wgt = particle->weight; @@ -155,29 +155,26 @@ void write_mcpl_source_bank(mcpl_outfile_t file_id, bool surf_source_bank) mpi::intracomm, MPI_STATUS_IGNORE); #endif // now write the source_bank data again. - for (vector::iterator _site = source_bank->begin(); - _site != source_bank->end(); _site++) { + for (const auto& site : *source_bank) { // particle is now at the iterator // write it to the mcpl-file mcpl_particle_t p; - p.position[0] = _site->r.x; - p.position[1] = _site->r.y; - p.position[2] = _site->r.z; + p.position[0] = site.r.x; + p.position[1] = site.r.y; + p.position[2] = site.r.z; // mcpl requires that the direction vector is unit length // which is also the case in openmc - p.direction[0] = _site->u.x; - p.direction[1] = _site->u.y; - p.direction[2] = _site->u.z; + p.direction[0] = site.u.x; + p.direction[1] = site.u.y; + p.direction[2] = site.u.z; - // mcpl stores kinetic energy in MeV - p.ekin = _site->E * 1e-6; + // MCPL stores kinetic energy in [MeV], time in [ms] + p.ekin = site.E * 1e-6; + p.time = site.time * 1e3; + p.weight = site.wgt; - p.time = _site->time * 1e3; - - p.weight = _site->wgt; - - switch (_site->particle) { + switch (site.particle) { case ParticleType::neutron: p.pdgcode = 2112; break; diff --git a/tests/regression_tests/source_mcpl_file/results_true.dat b/tests/regression_tests/source_mcpl_file/results_true.dat index 5651efde70..0a98e9d8cc 100644 --- a/tests/regression_tests/source_mcpl_file/results_true.dat +++ b/tests/regression_tests/source_mcpl_file/results_true.dat @@ -1,2 +1,2 @@ k-combined: -2.943088E-01 2.093028E-03 +3.009416E-01 3.229999E-03 diff --git a/tests/regression_tests/source_mcpl_file/settings.xml b/tests/regression_tests/source_mcpl_file/settings.xml index 2e511461f3..47b010bffe 100644 --- a/tests/regression_tests/source_mcpl_file/settings.xml +++ b/tests/regression_tests/source_mcpl_file/settings.xml @@ -1,6 +1,5 @@ - 1234 diff --git a/tests/regression_tests/source_mcpl_file/test.py b/tests/regression_tests/source_mcpl_file/test.py index 60e0ad50f8..84ec005ae1 100644 --- a/tests/regression_tests/source_mcpl_file/test.py +++ b/tests/regression_tests/source_mcpl_file/test.py @@ -11,7 +11,6 @@ pytestmark = pytest.mark.skipif( settings1=""" - 1234 @@ -35,7 +34,7 @@ settings2 = """ 1000 - source.10.{0} + source.10.{} """