From debc085cf692cb4f2a8a9585d0acfe4a7b06bfb9 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 22 Jun 2022 22:50:07 +0200 Subject: [PATCH 01/31] 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 18fddc689..cadbfe93b 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 02/31] include mcpl header --- src/source.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/source.cpp b/src/source.cpp index cd8b5e574..5e26fa0a8 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 03/31] 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 cadbfe93b..69dd47eae 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 04/31] 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 5e26fa0a8..231f355fc 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 05/31] (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 000000000..5a6a87d87 --- /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 06/31] 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 000000000..7b5a933f1 --- /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 07/31] 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 7b5a933f1..f35a07fc4 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 08/31] 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 5a6a87d87..0adf67f1a 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 09/31] 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 18fddc689..cadbfe93b 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 10/31] include mcpl header --- src/source.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/source.cpp b/src/source.cpp index cd8b5e574..5e26fa0a8 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 11/31] 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 cadbfe93b..69dd47eae 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 12/31] 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 5e26fa0a8..231f355fc 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 13/31] (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 000000000..5a6a87d87 --- /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 14/31] 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 000000000..7b5a933f1 --- /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 15/31] 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 7b5a933f1..f35a07fc4 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 16/31] 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 5a6a87d87..0adf67f1a 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 17/31] fix misprints --- src/source.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 231f355fc..37e580b18 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 18/31] fix misprints --- src/source.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/source.cpp b/src/source.cpp index 231f355fc..9ec1ff798 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 19/31] 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 000000000..bc56030e1 --- /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 000000000..2472a7471 --- /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 20/31] 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 f35a07fc4..61eea95c6 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 21/31] 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 000000000..f2209006a --- /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 22/31] 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 000000000..8b1510e0c --- /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 23/31] 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 0adf67f1a..922ddddd3 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 24/31] 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 69dd47eae..4d7ec104a 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 25/31] 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 85dcd7084..6af9643cd 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 26/31] 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 eb0d4936c..12e0a8050 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 27/31] 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 12e0a8050..d419cab06 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 28/31] 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 000000000..e69de29bb From eff690fd90032abd0d4a5e68f5babcc38c476de1 Mon Sep 17 00:00:00 2001 From: Erik B Knudsen Date: Wed, 13 Jul 2022 20:55:53 +0200 Subject: [PATCH 29/31] 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 922ddddd3..f55a76904 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 30/31] 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 6af9643cd..be56f1c12 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 31/31] 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 4d7ec104a..5c2dae931 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 82978f103..49e51c4b1 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