Merge pull request #1735 from pshriwise/libmesh_umesh2

Support for libMesh unstructured mesh filters
This commit is contained in:
Paul Romano 2021-04-08 15:30:38 -05:00 committed by GitHub
commit d37034b1d2
52 changed files with 28036 additions and 26468 deletions

View file

@ -30,6 +30,7 @@ jobs:
mpi: [n, y]
omp: [n, y]
dagmc: [n]
libmesh: [n]
event: [n]
vectfit: [n]
@ -44,6 +45,14 @@ jobs:
python-version: 3.8
mpi: y
omp: y
- libmesh: y
python-version: 3.8
mpi: y
omp: y
- libmesh: y
python-version: 3.8
mpi: n
omp: y
- event: y
python-version: 3.8
omp: y
@ -53,7 +62,8 @@ jobs:
omp: n
mpi: y
name: 'Python ${{ matrix.python-version }} (omp=${{ matrix.omp }},
mpi=${{ matrix.mpi }}, dagmc=${{ matrix.dagmc }}, event=${{ matrix.event }}
mpi=${{ matrix.mpi }}, dagmc=${{ matrix.dagmc }},
libmesh=${{ matrix.libmesh }}, event=${{ matrix.event }}
vectfit=${{ matrix.vectfit }})'
env:
@ -63,6 +73,7 @@ jobs:
DAGMC: ${{ matrix.dagmc }}
EVENT: ${{ matrix.event }}
VECTFIT: ${{ matrix.vectfit }}
LIBMESH: ${{ matrix.libmesh }}
steps:
-
@ -73,7 +84,6 @@ jobs:
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
-
name: Environment Variables
run: |
@ -88,6 +98,8 @@ jobs:
sudo apt -y update
sudo apt install -y mpich \
libmpich-dev \
libnetcdf-dev \
libpnetcdf-dev \
libhdf5-serial-dev \
libhdf5-mpich-dev \
libeigen3-dev
@ -101,7 +113,6 @@ jobs:
name: before
shell: bash
run: $GITHUB_WORKSPACE/tools/ci/gha-before-script.sh
-
name: test
shell: bash

View file

@ -25,12 +25,13 @@ endif()
# Command line options
#===============================================================================
option(openmp "Enable shared-memory parallelism with OpenMP" ON)
option(profile "Compile with profiling flags" OFF)
option(debug "Compile with debug flags" OFF)
option(optimize "Turn on all compiler optimization flags" OFF)
option(coverage "Compile with coverage analysis flags" OFF)
option(dagmc "Enable support for DAGMC (CAD) geometry" OFF)
option(openmp "Enable shared-memory parallelism with OpenMP" ON)
option(profile "Compile with profiling flags" OFF)
option(debug "Compile with debug flags" OFF)
option(optimize "Turn on all compiler optimization flags" OFF)
option(coverage "Compile with coverage analysis flags" OFF)
option(dagmc "Enable support for DAGMC (CAD) geometry" OFF)
option(libmesh "Enable support for libMesh unstructured mesh tallies" OFF)
#===============================================================================
# MPI for distributed-memory parallelism
@ -67,6 +68,13 @@ else()
message(STATUS "Did not find pugixml, will use submodule instead")
endif()
#===============================================================================
# libMesh Unstructured Mesh Support
#===============================================================================
if(libmesh)
find_package(LIBMESH REQUIRED)
endif()
#===============================================================================
# HDF5 for binary output
#===============================================================================
@ -405,6 +413,11 @@ if(dagmc)
target_link_libraries(libopenmc dagmc-shared uwuw-shared)
endif()
if(libmesh)
target_compile_definitions(libopenmc PRIVATE LIBMESH)
target_link_libraries(libopenmc PkgConfig::LIBMESH)
endif()
#===============================================================================
# openmc executable
#===============================================================================

View file

@ -0,0 +1,21 @@
# Finds the libMesh installation using CMake's PkgConfig
# module and creates a libmesh imported target
if(${CMAKE_VERSION} VERSION_LESS 3.12.0)
message(FATAL_ERROR "OpenMC builds with libMesh support require CMake version 3.12.0 or greater.")
endif()
set(LIBMESH_PC_FILE libmesh)
# if the METHOD variable is present, check specifically for
# the libMesh .pc file for that build type
if(DEFINED ENV{METHOD})
set(LIBMESH_PC_FILE libmesh-$ENV{METHOD})
message(STATUS "Using environment variable METHOD to determine libMesh build: ${LIBMESH_PC_FILE}")
endif()
include(FindPkgConfig)
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${LIBMESH_PC}")
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH True)
pkg_check_modules(LIBMESH REQUIRED ${LIBMESH_PC_FILE}>=1.6.0 IMPORTED_TARGET)
pkg_get_variable(LIBMESH_PREFIX ${LIBMESH_PC_FILE} prefix)

View file

@ -9,6 +9,13 @@ if(@DAGMC_FOUND@)
find_package(DAGMC REQUIRED HINTS @DAGMC_DIR@)
endif()
if(@LIBMESH_FOUND@)
include(FindPkgConfig)
list(APPEND CMAKE_PREFIX_PATH @LIBMESH_PREFIX@)
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH True)
pkg_check_modules(LIBMESH REQUIRED @LIBMESH_PC_FILE@>=1.6.0 IMPORTED_TARGET)
endif()
if(NOT TARGET OpenMC::libopenmc)
include("${OpenMC_CMAKE_DIR}/OpenMCTargets.cmake")
endif()

View file

@ -338,7 +338,11 @@ attributes/sub-elements:
:z_grid:
The mesh divisions along the z-axis. (For rectilinear mesh only.)
:mesh_file:
:library:
The mesh library used to represent an unstructured mesh. This can be either
"moab" or "libmesh". (For unstructured mesh only.)
:filename:
The name of the mesh file to be loaded at runtime. (For unstructured mesh
only.)

View file

@ -230,17 +230,34 @@ Prerequisites
sudo apt install mpich libmpich-dev
sudo apt install openmpi-bin libopenmpi-dev
* git_ version control software for obtaining source code
* DAGMC_ toolkit for simulation using CAD-based geometries
OpenMC supports particle tracking in CAD-based geometries via the Direct
Accelerated Geometry Monte Carlo (DAGMC) toolkit (`installation
instructions
<https://svalinn.github.io/DAGMC/install/dag_multiple.html>`_). For use in
OpenMC, only the ``MOAB_DIR`` and ``BUILD_TALLY`` variables need to be
specified in the CMake configuration step.
instructions <https://svalinn.github.io/DAGMC/install/openmc.html>`_). For
use in OpenMC, only the ``MOAB_DIR`` and ``BUILD_TALLY`` variables need to
be specified in the CMake configuration step when building DAGMC. This
option also allows unstructured mesh tallies on tetrahedral MOAB meshes.
In addition to turning this option on, the path to the DAGMC installation
should be specified as part of the ``CMAKE_PREFIX_PATH`` variable::
* git_ version control software for obtaining source code
cmake -Ddagmc=on -DCMAKE_PREFIX_PATH=/path/to/dagmc/installation
* libMesh_ mesh library framework for numerical simulations of partial differential equations
This optional dependency enables support for unstructured mesh tally
filters using libMesh meshes. Any 3D element type supported by libMesh can
be used, but the implementation is currently restricted to collision
estimators. In addition to turning this option on, the path to the libMesh
installation should be specified as part of the ``CMAKE_PREFIX_PATH``
variable.::
CXX=mpicxx cmake -Dlibmesh=on -DCMAKE_PREFIX_PATH=/path/to/libmesh/installation
Note that libMesh is most commonly compiled with MPI support. If that
is the case, then OpenMC should be compiled with MPI support as well.
.. _gcc: https://gcc.gnu.org/
.. _CMake: https://cmake.org
@ -248,6 +265,7 @@ Prerequisites
.. _MPICH: https://www.mpich.org
.. _HDF5: https://www.hdfgroup.org/solutions/hdf5/
.. _DAGMC: https://svalinn.github.io/DAGMC/index.html
.. _libMesh: https://libmesh.github.io/
Obtaining the Source
--------------------
@ -318,10 +336,14 @@ openmp
being used must support OpenMP. (Default: on)
dagmc
Enables use of CAD-based DAGMC_ geometries. Please see the note about DAGMC in
the optional dependencies list for more information on this feature. The
installation directory for DAGMC should also be defined as `DAGMC_ROOT` in the
CMake configuration command. (Default: off)
Enables use of CAD-based DAGMC_ geometries and MOAB_ unstructured mesh
tallies. Please see the note about DAGMC in the optional dependencies list
for more information on this feature. The installation directory for DAGMC
should also be defined as `DAGMC_ROOT` in the CMake configuration command.
(Default: off)
libmesh
Enables the use of unstructured mesh tallies with libMesh_. (Default: off)
coverage
Compile and link code instrumented for coverage analysis. This is typically

File diff suppressed because one or more lines are too long

View file

@ -244,20 +244,24 @@
"\n",
" | The OpenMC Monte Carlo Code\n",
" Copyright | 2011-2020 MIT and OpenMC contributors\n",
" License | http://openmc.readthedocs.io/en/latest/license.html\n",
" Version | 0.12.0-dev\n",
" Git SHA1 | c9cbdb7c70b202e847c7169f9e5602f110a43853\n",
" Date/Time | 2020-04-24 09:25:02\n",
" OpenMP Threads | 8\n",
" License | https://docs.openmc.org/en/latest/license.html\n",
" Version | 0.12.1-dev\n",
" Git SHA1 | 8ae407c90e927af62bfdc8f150e96bfd5d7b2ec2\n",
" Date/Time | 2021-01-06 09:17:05\n",
" MPI Processes | 1\n",
" OpenMP Threads | 2\n",
"\n",
" Reading settings XML file...\n",
" Reading cross sections XML file...\n",
" Reading materials XML file...\n",
" Reading DAGMC geometry...\n",
"Set overlap thickness = 0\n",
"Set numerical precision = 0.001\n",
"Loading file dagmc.h5m\n",
"Initializing the GeomQueryTool...\n",
"Using faceting tolerance: 0.001\n",
"Building OBB Tree...\n",
"Building acceleration data structures...\n",
"Implicit Complement assumed to be Vacuum\n",
" Reading N14 from /home/shriwise/opt/openmc/xs/nndc_hdf5/N14.h5\n",
" Reading N15 from /home/shriwise/opt/openmc/xs/nndc_hdf5/N15.h5\n",
" Reading O16 from /home/shriwise/opt/openmc/xs/nndc_hdf5/O16.h5\n",
@ -291,12 +295,11 @@
" Reading Mo98 from /home/shriwise/opt/openmc/xs/nndc_hdf5/Mo98.h5\n",
" Reading P31 from /home/shriwise/opt/openmc/xs/nndc_hdf5/P31.h5\n",
" Reading Mn55 from /home/shriwise/opt/openmc/xs/nndc_hdf5/Mn55.h5\n",
" Maximum neutron transport energy: 20000000.000000 eV for N15\n",
" Minimum neutron data temperature: 294.000000 K\n",
" Maximum neutron data temperature: 294.000000 K\n",
" Reading tallies XML file...\n",
" Minimum neutron data temperature: 294.0 K\n",
" Maximum neutron data temperature: 294.0 K\n",
" Preparing distributed cell instances...\n",
" Writing summary.h5 file...\n",
" Maximum neutron transport energy: 20000000.0 eV for N15\n",
"\n",
" ===============> FIXED SOURCE TRANSPORT SIMULATION <===============\n",
"\n",
@ -311,20 +314,19 @@
" Simulating batch 9\n",
" Simulating batch 10\n",
" Creating state point statepoint.10.h5...\n",
" WARNING: Skipping unstructured mesh writing for tally 1. More than one filter\n",
" is present on the tally.\n",
"\n",
" =======================> TIMING STATISTICS <=======================\n",
"\n",
" Total time for initialization = 4.3651e+01 seconds\n",
" Reading cross sections = 2.1907e+00 seconds\n",
" Total time in simulation = 3.4743e-01 seconds\n",
" Time in transport only = 2.9555e-01 seconds\n",
" Time in active batches = 3.4743e-01 seconds\n",
" Time accumulating tallies = 7.6575e-03 seconds\n",
" Total time for finalization = 2.2273e-01 seconds\n",
" Total time elapsed = 4.4224e+01 seconds\n",
" Calculation Rate (active) = 2878.27 particles/second\n",
" Total time for initialization = 2.4196e+01 seconds\n",
" Reading cross sections = 2.1428e+00 seconds\n",
" Total time in simulation = 1.9512e-01 seconds\n",
" Time in transport only = 1.9269e-01 seconds\n",
" Time in active batches = 1.9512e-01 seconds\n",
" Time accumulating tallies = 2.0220e-06 seconds\n",
" Time writing statepoints = 2.2461e-03 seconds\n",
" Total time for finalization = 1.8940e-06 seconds\n",
" Total time elapsed = 2.4401e+01 seconds\n",
" Calculation Rate (active) = 5125.02 particles/second\n",
"\n",
" ============================> RESULTS <============================\n",
"\n",
@ -350,7 +352,7 @@
"metadata": {},
"outputs": [],
"source": [
"unstructured_mesh = openmc.UnstructuredMesh(\"manifold.h5m\")\n",
"unstructured_mesh = openmc.UnstructuredMesh(\"manifold.h5m\", library='moab')\n",
"\n",
"mesh_filter = openmc.MeshFilter(unstructured_mesh)\n",
"\n",
@ -399,8 +401,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"manifold_flux.vtk tally_1.100.vtk tally_1.200.vtk\r\n",
"manifold.vtk\t tally_1.10.vtk\r\n"
"tally_1.200.vtk\r\n"
]
}
],
@ -495,7 +496,7 @@
"text": [
"<?xml version='1.0' encoding='utf-8'?>\r\n",
"<tallies>\r\n",
" <mesh id=\"1\" type=\"unstructured\">\r\n",
" <mesh id=\"1\" library=\"moab\" type=\"unstructured\">\r\n",
" <filename>manifold.h5m</filename>\r\n",
" </mesh>\r\n",
" <filter id=\"1\" type=\"mesh\">\r\n",
@ -562,16 +563,7 @@
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/shriwise/.pyenv/versions/3.7.3/lib/python3.7/site-packages/vtk/util/numpy_support.py:137: FutureWarning: Conversion of the second argument of issubdtype from `complex` to `np.complexfloating` is deprecated. In future, it will be treated as `np.complex128 == np.dtype(complex).type`.\n",
" assert not numpy.issubdtype(z.dtype, complex), \\\n"
]
}
],
"outputs": [],
"source": [
"data_dict = {'Flux 0 - 1 MeV' : thermal_flux,\n",
" 'Flux 1 - 5 MeV' : fast_flux,\n",
@ -596,8 +588,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"manifold_flux.vtk tally_1.100.vtk tally_1.200.vtk\r\n",
"manifold.vtk\t tally_1.10.vtk\r\n"
"manifold.vtk tally_1.200.vtk\r\n"
]
}
],
@ -647,7 +638,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3"
"version": "3.7.3"
}
},
"nbformat": 4,

View file

@ -47,6 +47,7 @@ extern "C" {
int openmc_get_mesh_index(int32_t id, int32_t* index);
int openmc_get_n_batches(int* n_batches, bool get_max_batches);
int openmc_get_nuclide_index(const char name[], int* index);
int openmc_add_unstructured_mesh(const char filename[], const char library[], int* id);
int64_t openmc_get_seed();
int openmc_get_tally_index(int32_t id, int32_t* index);
void openmc_get_tally_next_id(int32_t* id);

View file

@ -3,7 +3,7 @@
#define OPENMC_DAGMC_H
namespace openmc {
extern "C" const bool dagmc_enabled;
extern "C" const bool DAGMC_ENABLED;
}
#ifdef DAGMC

View file

@ -22,12 +22,26 @@
#include "moab/GeomUtil.hpp"
#endif
#ifdef LIBMESH
#include "libmesh/bounding_box.h"
#include "libmesh/dof_map.h"
#include "libmesh/elem.h"
#include "libmesh/equation_systems.h"
#include "libmesh/exodusII_io.h"
#include "libmesh/explicit_system.h"
#include "libmesh/libmesh.h"
#include "libmesh/mesh.h"
#include "libmesh/point.h"
#endif
namespace openmc {
//==============================================================================
// Global variables
//==============================================================================
extern "C" const bool LIBMESH_ENABLED;
class Mesh;
namespace model {
@ -37,6 +51,13 @@ extern std::vector<std::unique_ptr<Mesh>> meshes;
} // namespace model
#ifdef LIBMESH
namespace settings {
// used when creating new libMesh::Mesh instances
extern std::unique_ptr<libMesh::LibMeshInit> libmesh_init;
extern const libMesh::Parallel::Communicator* libmesh_comm;
}
#endif
class Mesh
{
@ -75,6 +96,9 @@ public:
//! Get the number of mesh cell surfaces.
virtual int n_surface_bins() const = 0;
//! Set the mesh ID
void set_id(int32_t id=-1);
//! Write mesh data to an HDF5 group
//
//! \param[in] group HDF5 group
@ -91,7 +115,9 @@ public:
virtual std::pair<std::vector<double>, std::vector<double>>
plot(Position plot_ll, Position plot_ur) const = 0;
//! Get a label for the mesh bin
//! Return a string representation of the mesh bin
//
//! \param[in] bin Mesh bin to generate a label for
virtual std::string bin_label(int bin) const = 0;
// Data members
@ -208,8 +234,18 @@ public:
void to_hdf5(hid_t group) const override;
// Data members
// New methods
//! Count number of bank sites in each mesh bin / energy bin
//
//! \param[in] bank Array of bank sites
//! \param[out] Whether any bank sites are outside the mesh
//! \return Array indicating number of sites in each mesh/energy bin
xt::xtensor<double, 1> count_sites(const Particle::Bank* bank,
int64_t length,
bool* outside) const;
// Data members
double volume_frac_; //!< Volume fraction of each mesh element
xt::xtensor<double, 1> width_; //!< Width of each mesh element
};
@ -243,72 +279,112 @@ public:
int set_grid();
};
#ifdef DAGMC
// Abstract class for unstructured meshes
class UnstructuredMesh : public Mesh {
public:
UnstructuredMesh() = default;
UnstructuredMesh(pugi::xml_node);
~UnstructuredMesh() = default;
// Constructors
UnstructuredMesh() {};
UnstructuredMesh(pugi::xml_node node);
UnstructuredMesh(const std::string& filename);
// Methods
//! Add a variable to the mesh instance
virtual void add_score(const std::string& var_name) = 0;
//! Remove tally data from the instance
virtual void remove_scores() = 0;
//! Set the value of a bin for a variable on the internal
// mesh instance
virtual void set_score_data(const std::string& var_name,
const std::vector<double>& values,
const std::vector<double>& std_dev) = 0;
//! Write the unstructured mesh to file
//
//! \param[in] filename Base of the file to write
virtual void write(const std::string& base_filename) const = 0;
//! Retrieve a centroid for the mesh cell
//
//! \param[in] bin Bin to return the centroid for
//! \return The centroid of the bin
virtual Position centroid(int bin) const = 0;
//! Get the volume of a mesh bin
//
//! \param[in] bin Bin to return the volume for
//! \return Volume of the bin
virtual double volume(int bin) const = 0;
//! Get the library used for this unstructured mesh
virtual std::string library() const = 0;
std::string bin_label(int bin) const override;
void surface_bins_crossed(const Particle& p,
std::vector<int>& bins) const override;
void to_hdf5(hid_t group) const override;
// Data members
bool output_ {true}; //!< Write tallies onto the unstructured mesh at the end of a run
std::string filename_; //!< Path to unstructured mesh file
private:
//! Setup method for the mesh. Builds data structures,
//! sets up element mapping, creates bounding boxes, etc.
virtual void initialize() = 0;
};
#ifdef DAGMC
class MOABMesh : public UnstructuredMesh {
public:
// Constructors
MOABMesh() = default;
MOABMesh(pugi::xml_node);
MOABMesh(const std::string& filename);
void bins_crossed(const Particle& p,
std::vector<int>& bins,
std::vector<double>& lengths) const override;
std::pair<std::vector<double>, std::vector<double>>
plot(Position plot_ll, Position plot_ur) const override;
//! Determine which surface bins were crossed by a particle.
//
//! \param[in] p Particle to check
//! \param[out] bins Surface bins that were crossed
void surface_bins_crossed(const Particle& p, std::vector<int>& bins) const;
//! Write mesh data to an HDF5 group.
//
//! \param[in] group HDF5 group
void to_hdf5(hid_t group) const;
//! Get bin at a given position.
//
//! \param[in] r Position to get bin for
//! \return Mesh bin
int get_bin(Position r) const;
int n_bins() const override;
int n_surface_bins() const override;
//! Retrieve a centroid for the mesh cell
//
// \param[in] tet MOAB EntityHandle of the tetrahedron
// \return The centroid of the element
Position centroid(moab::EntityHandle tet) const;
std::pair<std::vector<double>, std::vector<double>>
plot(Position plot_ll, Position plot_ur) const override;
//! Return a string represntation of the mesh bin
//
//! \param[in] bin Mesh bin to generate a label for
std::string bin_label(int bin) const override;
std::string library() const override;
//! Add a score to the mesh instance
void add_score(std::string score) const;
void add_score(const std::string& score) override;
//! Remove a score from the mesh instance
void remove_score(std::string score) const;
void remove_scores() override;
//! Set data for a score
void set_score_data(const std::string& score,
std::vector<double> values,
std::vector<double> std_dev) const;
const std::vector<double>& values,
const std::vector<double>& std_dev) override;
//! Write the mesh with any current tally data
void write(std::string base_filename) const;
void write(const std::string& base_filename) const;
std::string filename_; //!< Path to unstructured mesh file
Position centroid(int bin) const override;
double volume(int bin) const override;
private:
void initialize() override;
//! Find all intersections with faces of the mesh.
//
//! \param[in] start Staring location
@ -399,17 +475,77 @@ private:
std::pair<moab::Tag, moab::Tag>
get_score_tags(std::string score) const;
// data members
// Data members
moab::Range ehs_; //!< Range of tetrahedra EntityHandle's in the mesh
moab::EntityHandle tetset_; //!< EntitySet containing all tetrahedra
moab::EntityHandle kdtree_root_; //!< Root of the MOAB KDTree
std::unique_ptr<moab::Interface> mbi_; //!< MOAB instance
std::unique_ptr<moab::AdaptiveKDTree> kdtree_; //!< MOAB KDTree instance
std::vector<moab::Matrix3> baryc_data_; //!< Barycentric data for tetrahedra
std::vector<std::string> tag_names_; //!< Names of score tags added to the mesh
};
#endif
#ifdef LIBMESH
class LibMesh : public UnstructuredMesh {
public:
// Constructors
LibMesh(pugi::xml_node node);
LibMesh(const std::string& filename);
// Methods
void bins_crossed(const Particle& p,
std::vector<int>& bins,
std::vector<double>& lengths) const override;
int get_bin(Position r) const override;
int n_bins() const override;
int n_surface_bins() const override;
std::pair<std::vector<double>, std::vector<double>>
plot(Position plot_ll, Position plot_ur) const override;
void add_score(const std::string& var_name) override;
void remove_scores() override;
void set_score_data(const std::string& var_name,
const std::vector<double>& values,
const std::vector<double>& std_dev) override;
void write(const std::string& base_filename) const override;
Position centroid(int bin) const override;
double volume(int bin) const override;
std::string library() const override;
private:
void initialize() override;
//! Translate a bin value to an element reference
const libMesh::Elem& get_element_from_bin(int bin) const;
//! Translate an element pointer to a bin index
int get_bin_from_element(const libMesh::Elem* elem) const;
// Data members
std::unique_ptr<libMesh::Mesh> m_; //!< pointer to the libMesh mesh instance
std::vector<std::unique_ptr<libMesh::PointLocatorBase>> pl_; //!< per-thread point locators
std::unique_ptr<libMesh::EquationSystems> equation_systems_; //!< pointer to the equation systems of the mesh
std::string eq_system_name_; //!< name of the equation system holding OpenMC results
std::unordered_map<std::string, unsigned int> variable_map_; //!< mapping of variable names (tally scores) to libMesh variable numbers
libMesh::BoundingBox bbox_; //!< bounding box of the mesh
libMesh::dof_id_type first_element_id_; //!< id of the first element in the mesh
};
#endif
//==============================================================================
// Non-member functions
//==============================================================================

View file

@ -22,6 +22,7 @@ namespace openmc {
namespace settings {
// Boolean flags
extern bool assume_separate; //!< assume tallies are spatially separate?
extern bool check_overlaps; //!< check overlaps in geometry?

View file

@ -18,10 +18,7 @@ void write_source_bank(hid_t group_id, bool surf_source_bank);
void read_source_bank(hid_t group_id, std::vector<Particle::Bank>& sites, bool distribute);
void write_tally_results_nr(hid_t file_id);
void restart_set_keff();
#ifdef DAGMC
void write_unstructured_mesh_results();
#endif
} // namespace openmc
#endif // OPENMC_STATE_POINT_H

View file

@ -30,7 +30,7 @@ namespace model {
} // namespace model
//==============================================================================
//! Coordinates for an axis-aligned cube that bounds a geometric object.
//! Coordinates for an axis-aligned cuboid bounding a geometric object.
//==============================================================================
struct BoundingBox

View file

@ -75,6 +75,9 @@ public:
//! A string representing the i-th score on this tally
std::string score_name(int score_idx) const;
//! A string representing the i-th nuclide on this tally
std::string nuclide_name(int nuclide_idx) const;
//----------------------------------------------------------------------------
// Major public data members.

View file

@ -40,11 +40,14 @@ else:
def _dagmc_enabled():
return c_bool.in_dll(_dll, "dagmc_enabled").value
return c_bool.in_dll(_dll, "DAGMC_ENABLED").value
def _coord_levels():
return c_int.in_dll(_dll, "n_coord_levels").value
def _libmesh_enabled():
return c_bool.in_dll(_dll, "LIBMESH_ENABLED").value
from .error import *
from .core import *
from .nuclide import *

View file

@ -605,6 +605,8 @@ class UnstructuredMesh(MeshBase):
Unique identifier for the mesh
name : str
Name of the mesh
size : int
Number of elements in the unstructured mesh
Attributes
----------
@ -614,6 +616,11 @@ class UnstructuredMesh(MeshBase):
Name of the mesh
filename : str
Name of the file containing the unstructured mesh
library : str
Mesh library used for the unstructured mesh tally
output : bool
Indicates whether or not automatic tally output should
be generated for this mesh
volumes : Iterable of float
Volumes of the unstructured mesh elements
total_volume : float
@ -622,12 +629,13 @@ class UnstructuredMesh(MeshBase):
An iterable of element centroid coordinates, e.g. [(0.0, 0.0, 0.0),
(1.0, 1.0, 1.0), ...]
"""
def __init__(self, filename, mesh_id=None, name=''):
def __init__(self, filename, library, mesh_id=None, name=''):
super().__init__(mesh_id, name)
self.filename = filename
self._volumes = None
self._centroids = None
self.library = library
self._output = True
@property
def filename(self):
@ -638,6 +646,33 @@ class UnstructuredMesh(MeshBase):
cv.check_type('Unstructured Mesh filename', filename, str)
self._filename = filename
@property
def library(self):
return self._library
@library.setter
def library(self, lib):
cv.check_value('Unstructured mesh library', lib, ('moab', 'libmesh'))
self._library = lib
@property
def size(self):
return self._size
@size.setter
def size(self, size):
cv.check_type("Unstructured mesh size", size, Integral)
self._size = size
@property
def output(self):
return self._output
@output.setter
def output(self, val):
cv.check_type("Unstructured mesh output value", val, bool)
self._output = val
@property
def volumes(self):
return self._volumes
@ -670,7 +705,9 @@ class UnstructuredMesh(MeshBase):
def __repr__(self):
string = super().__repr__()
return string + '{: <16}=\t{}\n'.format('\tFilename', self.filename)
string += '{: <16}=\t{}\n'.format('\tFilename', self.filename)
string += '{: <16}=\t{}\n'.format('\tMesh Library', self.mesh_lib)
return string
def write_data_to_vtk(self, filename, datasets, volume_normalization=True):
"""Map data to the unstructured mesh element centroids
@ -761,12 +798,14 @@ class UnstructuredMesh(MeshBase):
def from_hdf5(cls, group):
mesh_id = int(group.name.split('/')[-1].lstrip('mesh '))
filename = group['filename'][()].decode()
library = group['library'][()].decode()
mesh = cls(filename, mesh_id=mesh_id)
mesh = cls(filename, library, mesh_id=mesh_id)
vol_data = group['volumes'][()]
centroids = group['centroids'][()]
mesh.volumes = np.reshape(vol_data, (vol_data.shape[0],))
mesh.centroids = np.reshape(centroids, (vol_data.shape[0], 3))
mesh.size = mesh.volumes.size
return mesh
@ -783,7 +822,7 @@ class UnstructuredMesh(MeshBase):
element = ET.Element("mesh")
element.set("id", str(self._id))
element.set("type", "unstructured")
element.set("library", self._library)
subelement = ET.SubElement(element, "filename")
subelement.text = self.filename
@ -805,7 +844,6 @@ class UnstructuredMesh(MeshBase):
"""
mesh_id = int(get_text(elem, 'id'))
filename = get_text(elem, 'filename')
library = get_text(elem, 'library')
mesh = cls(filename, mesh_id)
return mesh
return cls(filename, library, mesh_id)

View file

@ -2,6 +2,7 @@
"""Python script to plot tally data generated by OpenMC."""
import os
import sys
import argparse
@ -19,11 +20,18 @@ from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import numpy as np
from openmc import StatePoint, MeshFilter
from openmc import StatePoint, MeshFilter, UnstructuredMesh
_COMBOBOX_SELECTED = '<<ComboboxSelected>>'
def mesh_filter_check(filter):
"""
Check that the filter is a usable mesh filter
"""
return isinstance(filter, MeshFilter) and not isinstance(filter.mesh, UnstructuredMesh)
class MeshPlotter(tk.Frame):
def __init__(self, parent, filename):
super().__init__(parent)
@ -289,10 +297,17 @@ class MeshPlotter(tk.Frame):
# Create StatePoint object and read in data
self.datafile = StatePoint(filename)
meshes = self.datafile.meshes
if any(isinstance(m, UnstructuredMesh) for m in meshes.values()):
warn_msg = "Unstructured meshes are present in the" \
" statepoint file but are not currently" \
" supported by this script"
messagebox.showwarning("Unstructured Meshes", message=warn_msg)
# Find which tallies are mesh tallies
self.meshTallies = []
for itally, tally in self.datafile.tallies.items():
if any([isinstance(f, MeshFilter) for f in tally.filters]):
if any([mesh_filter_check(f) for f in tally.filters]):
self.meshTallies.append(itally)
if not self.meshTallies:

View file

@ -26,9 +26,9 @@
namespace openmc {
#ifdef DAGMC
const bool dagmc_enabled = true;
const bool DAGMC_ENABLED = true;
#else
const bool dagmc_enabled = false;
const bool DAGMC_ENABLED = false;
#endif
}

View file

@ -137,6 +137,10 @@ int openmc_finalize()
// Deallocate arrays
free_memory();
#ifdef LIBMESH
settings::libmesh_init.reset();
#endif
// Free all MPI types
#ifdef OPENMC_MPI
if (mpi::bank != MPI_DATATYPE_NULL) MPI_Type_free(&mpi::bank);

View file

@ -3,6 +3,7 @@
#include <cstddef>
#include <cstdlib> // for getenv
#include <cstring>
#include <memory>
#include <string>
#include <vector>
@ -32,6 +33,10 @@
#include "openmc/thermal.h"
#include "openmc/timer.h"
#ifdef LIBMESH
#include "libmesh/libmesh.h"
#endif
int openmc_init(int argc, char* argv[], const void* intracomm)
{
@ -54,6 +59,32 @@ int openmc_init(int argc, char* argv[], const void* intracomm)
int err = parse_command_line(argc, argv);
if (err) return err;
#ifdef LIBMESH
#ifdef _OPENMP
int n_threads = omp_get_max_threads();
#else
int n_threads = 1;
#endif
// initialize libMesh if it hasn't been initialized already
// (if initialized externally, the libmesh_init object needs to be provided also)
if (!settings::libmesh_init && !libMesh::initialized()) {
#ifdef OPENMC_MPI
// pass command line args, empty MPI communicator, and number of threads.
// Because libMesh was not initialized, we assume that OpenMC is the primary
// application and that its main MPI comm should be used.
settings::libmesh_init = std::make_unique<libMesh::LibMeshInit>(argc, argv, comm, n_threads);
#else
// pass command line args, empty MPI communicator, and number of threads
settings::libmesh_init = std::make_unique<libMesh::LibMeshInit>(argc, argv, 0, n_threads);
#endif
settings::libmesh_comm = &(settings::libmesh_init->comm());
}
#endif
// Start total and initialization timer
simulation::time_total.start();
simulation::time_initialize.start();

View file

@ -1,14 +1,17 @@
#include "openmc/mesh.h"
#include <algorithm> // for copy, equal, min, min_element
#include <cstddef> // for size_t
#include <cmath> // for ceil
#include <memory> // for allocator
#include <string>
#include <gsl/gsl>
#ifdef OPENMC_MPI
#include "mpi.h"
#endif
#ifdef _OPENMP
#include <omp.h>
#endif
#include <fmt/core.h> // for fmt
#include "xtensor/xbuilder.hpp"
#include "xtensor/xeval.hpp"
@ -20,19 +23,33 @@
#include "openmc/capi.h"
#include "openmc/constants.h"
#include "openmc/error.h"
#include "openmc/file_utils.h"
#include "openmc/hdf5_interface.h"
#include "openmc/message_passing.h"
#include "openmc/search.h"
#include "openmc/settings.h"
#include "openmc/tallies/tally.h"
#include "openmc/tallies/filter.h"
#include "openmc/xml_interface.h"
#ifdef LIBMESH
#include "libmesh/mesh_tools.h"
#include "libmesh/numeric_vector.h"
#endif
namespace openmc {
//==============================================================================
// Global variables
//==============================================================================
#ifdef LIBMESH
const bool LIBMESH_ENABLED = true;
#else
const bool LIBMESH_ENABLED = false;
#endif
namespace model {
std::unordered_map<int32_t, int32_t> mesh_map;
@ -40,6 +57,13 @@ std::vector<std::unique_ptr<Mesh>> meshes;
} // namespace model
#ifdef LIBMESH
namespace settings {
std::unique_ptr<libMesh::LibMeshInit> libmesh_init;
const libMesh::Parallel::Communicator* libmesh_comm {nullptr};
}
#endif
//==============================================================================
// Helper functions
//==============================================================================
@ -84,6 +108,35 @@ Mesh::Mesh(pugi::xml_node node)
}
}
void
Mesh::set_id(int32_t id) {
Expects(id >=0 || id == C_NONE);
// Clear entry in mesh map in case one was already assigned
if (id_ != C_NONE) {
model::mesh_map.erase(id_);
id_ = C_NONE;
}
// Ensure no other mesh has the same ID
if (model::mesh_map.find(id) != model::mesh_map.end()) {
throw std::runtime_error{fmt::format("Two meshes have the same ID: {}", id)};
}
// If no ID is specified, auto-assign the next ID in the sequence
if (id == C_NONE) {
id = 0;
for (const auto& m : model::meshes) {
id = std::max(id, m->id_);
}
++id;
}
// Update ID and entry in the mesh map
id_ = id;
model::mesh_map[id] = model::meshes.size() - 1;
}
//==============================================================================
// Structured Mesh implementation
//==============================================================================
@ -102,6 +155,73 @@ StructuredMesh::bin_label(int bin) const {
}
}
//==============================================================================
// Unstructured Mesh implementation
//==============================================================================
UnstructuredMesh::UnstructuredMesh(pugi::xml_node node) : Mesh(node) {
n_dimension_ = 3;
// check the mesh type
if (check_for_node(node, "type")) {
auto temp = get_node_value(node, "type", true, true);
if (temp != "unstructured") {
fatal_error(fmt::format("Invalid mesh type: {}", temp));
}
}
// get the filename of the unstructured mesh to load
if (check_for_node(node, "filename")) {
filename_ = get_node_value(node, "filename");
if (!file_exists(filename_)) {
fatal_error("Mesh file '" + filename_ + "' does not exist!");
}
}
else {
fatal_error(fmt::format("No filename supplied for unstructured mesh with ID: {}", id_));
}
// check if mesh tally data should be written with
// statepoint files
if (check_for_node(node, "output")) {
output_ = get_node_value_bool(node, "output");
}
}
void
UnstructuredMesh::surface_bins_crossed(const Particle& p,
std::vector<int>& bins) const {
fatal_error("Unstructured mesh surface tallies are not implemented.");
}
std::string
UnstructuredMesh::bin_label(int bin) const {
return fmt::format("Mesh Index ({})", bin);
};
void
UnstructuredMesh::to_hdf5(hid_t group) const
{
hid_t mesh_group = create_group(group, fmt::format("mesh {}", id_));
write_dataset(mesh_group, "type", "unstructured");
write_dataset(mesh_group, "filename", filename_);
write_dataset(mesh_group, "library", this->library());
// write volume of each element
std::vector<double> tet_vols;
xt::xtensor<double, 2> centroids({static_cast<size_t>(this->n_bins()), 3});
for (int i = 0; i < this->n_bins(); i++) {
tet_vols.emplace_back(this->volume(i));
auto c = this->centroid(i);
xt::view(centroids, i, xt::all()) = xt::xarray<double>({c.x, c.y, c.z});
}
write_dataset(mesh_group, "volumes", tet_vols);
write_dataset(mesh_group, "centroids", centroids);
close_group(mesh_group);
}
void StructuredMesh::get_indices(Position r, int* ijk, bool* in_mesh) const
{
*in_mesh = true;
@ -874,6 +994,62 @@ void RegularMesh::to_hdf5(hid_t group) const
close_group(mesh_group);
}
xt::xtensor<double, 1>
RegularMesh::count_sites(const Particle::Bank* bank,
int64_t length,
bool* outside) const
{
// Determine shape of array for counts
std::size_t m = this->n_bins();
std::vector<std::size_t> shape = {m};
// Create array of zeros
xt::xarray<double> cnt {shape, 0.0};
bool outside_ = false;
for (int64_t i = 0; i < length; i++) {
const auto& site = bank[i];
// determine scoring bin for entropy mesh
int mesh_bin = get_bin(site.r);
// if outside mesh, skip particle
if (mesh_bin < 0) {
outside_ = true;
continue;
}
// Add to appropriate bin
cnt(mesh_bin) += site.wgt;
}
// Create copy of count data. Since ownership will be acquired by xtensor,
// std::allocator must be used to avoid Valgrind mismatched free() / delete
// warnings.
int total = cnt.size();
double* cnt_reduced = std::allocator<double>{}.allocate(total);
#ifdef OPENMC_MPI
// collect values from all processors
MPI_Reduce(cnt.data(), cnt_reduced, total, MPI_DOUBLE, MPI_SUM, 0,
mpi::intracomm);
// Check if there were sites outside the mesh for any processor
if (outside) {
MPI_Reduce(&outside_, outside, 1, MPI_C_BOOL, MPI_LOR, 0, mpi::intracomm);
}
#else
std::copy(cnt.data(), cnt.data() + total, cnt_reduced);
if (outside) *outside = outside_;
#endif
// Adapt reduced values in array back into an xarray
auto arr = xt::adapt(cnt_reduced, total, xt::acquire_ownership(), shape);
xt::xarray<double> counts = arr;
return counts;
}
//==============================================================================
// RectilinearMesh implementation
//==============================================================================
@ -1217,6 +1393,43 @@ openmc_extend_meshes(int32_t n, const char* type, int32_t* index_start,
return 0;
}
//! Adds a new unstructured mesh to OpenMC
extern "C" int openmc_add_unstructured_mesh(const char filename[],
const char library[],
int* id)
{
std::string lib_name(library);
std::string mesh_file(filename);
bool valid_lib = false;
#ifdef DAGMC
if (lib_name == "moab") {
model::meshes.push_back(std::move(std::make_unique<MOABMesh>(mesh_file)));
valid_lib = true;
}
#endif
#ifdef LIBMESH
if (lib_name == "libmesh") {
model::meshes.push_back(std::move(std::make_unique<LibMesh>(mesh_file)));
valid_lib = true;
}
#endif
if (!valid_lib) {
set_errmsg(fmt::format("Mesh library {} is not supported "
"by this build of OpenMC", lib_name));
return OPENMC_E_INVALID_ARGUMENT;
}
// auto-assign new ID
model::meshes.back()->set_id(-1);
*id = model::meshes.back()->id_;
return 0;
}
//! Return the index in the meshes array of a mesh with a given ID
extern "C" int
openmc_get_mesh_index(int32_t id, int32_t* index)
@ -1374,27 +1587,16 @@ openmc_rectilinear_mesh_set_grid(int32_t index, const double* grid_x,
#ifdef DAGMC
UnstructuredMesh::UnstructuredMesh(pugi::xml_node node) : Mesh(node)
{
// unstructured always assumed to be 3D
n_dimension_ = 3;
MOABMesh::MOABMesh(pugi::xml_node node) : UnstructuredMesh(node) {
initialize();
}
// check the mesh type
if (check_for_node(node, "type")) {
auto temp = get_node_value(node, "type", true, true);
if (temp != "unstructured") {
fatal_error("Invalid mesh type: " + temp);
}
}
// get the filename of the unstructured mesh to load
if (check_for_node(node, "filename")) {
filename_ = get_node_value(node, "filename");
} else {
fatal_error("No filename supplied for unstructured mesh with ID: " +
std::to_string(id_));
}
MOABMesh::MOABMesh(const std::string& filename) {
filename_ = filename;
initialize();
}
void MOABMesh::initialize() {
// create MOAB instance
mbi_ = std::make_unique<moab::Core>();
// load unstructured mesh file
@ -1432,7 +1634,7 @@ UnstructuredMesh::UnstructuredMesh(pugi::xml_node node) : Mesh(node)
}
void
UnstructuredMesh::build_kdtree(const moab::Range& all_tets)
MOABMesh::build_kdtree(const moab::Range& all_tets)
{
moab::Range all_tris;
int adj_dim = 2;
@ -1467,10 +1669,10 @@ UnstructuredMesh::build_kdtree(const moab::Range& all_tets)
}
void
UnstructuredMesh::intersect_track(const moab::CartVect& start,
const moab::CartVect& dir,
double track_len,
std::vector<double>& hits) const {
MOABMesh::intersect_track(const moab::CartVect& start,
const moab::CartVect& dir,
double track_len,
std::vector<double>& hits) const {
hits.clear();
moab::ErrorCode rval;
@ -1494,12 +1696,13 @@ UnstructuredMesh::intersect_track(const moab::CartVect& start,
// sorts by first component of std::pair by default
std::sort(hits.begin(), hits.end());
}
void
UnstructuredMesh::bins_crossed(const Particle& p,
std::vector<int>& bins,
std::vector<double>& lengths) const
MOABMesh::bins_crossed(const Particle& p,
std::vector<int>& bins,
std::vector<double>& lengths) const
{
Position last_r{p.r_last_};
Position r{p.r()};
@ -1574,7 +1777,7 @@ UnstructuredMesh::bins_crossed(const Particle& p,
};
moab::EntityHandle
UnstructuredMesh::get_tet(const Position& r) const
MOABMesh::get_tet(const Position& r) const
{
moab::CartVect pos(r.x, r.y, r.z);
// find the leaf of the kd-tree for this position
@ -1601,29 +1804,35 @@ UnstructuredMesh::get_tet(const Position& r) const
return 0;
}
double UnstructuredMesh::tet_volume(moab::EntityHandle tet) const {
std::vector<moab::EntityHandle> conn;
moab::ErrorCode rval = mbi_->get_connectivity(&tet, 1, conn);
if (rval != moab::MB_SUCCESS) {
fatal_error("Failed to get tet connectivity");
}
moab::CartVect p[4];
rval = mbi_->get_coords(conn.data(), conn.size(), p[0].array());
if (rval != moab::MB_SUCCESS) {
fatal_error("Failed to get tet coords");
}
return 1.0 / 6.0 * (((p[1] - p[0]) * (p[2] - p[0])) % (p[3] - p[0]));
double MOABMesh::volume(int bin) const
{
return tet_volume(get_ent_handle_from_bin(bin));
}
void UnstructuredMesh::surface_bins_crossed(const Particle& p, std::vector<int>& bins) const {
// TODO: Implement triangle crossings here
throw std::runtime_error{"Unstructured mesh surface tallies are not implemented."};
std::string MOABMesh::library() const
{
return "moab";
}
int
UnstructuredMesh::get_bin(Position r) const {
double MOABMesh::tet_volume(moab::EntityHandle tet) const
{
std::vector<moab::EntityHandle> conn;
moab::ErrorCode rval = mbi_->get_connectivity(&tet, 1, conn);
if (rval != moab::MB_SUCCESS) {
fatal_error("Failed to get tet connectivity");
}
moab::CartVect p[4];
rval = mbi_->get_coords(conn.data(), conn.size(), p[0].array());
if (rval != moab::MB_SUCCESS) {
fatal_error("Failed to get tet coords");
}
return 1.0 / 6.0 * (((p[1] - p[0]) * (p[2] - p[0])) % (p[3] - p[0]));
}
int MOABMesh::get_bin(Position r) const
{
moab::EntityHandle tet = get_tet(r);
if (tet == 0) {
return -1;
@ -1633,7 +1842,7 @@ UnstructuredMesh::get_bin(Position r) const {
}
void
UnstructuredMesh::compute_barycentric_data(const moab::Range& tets) {
MOABMesh::compute_barycentric_data(const moab::Range& tets) {
moab::ErrorCode rval;
baryc_data_.clear();
@ -1662,32 +1871,10 @@ UnstructuredMesh::compute_barycentric_data(const moab::Range& tets) {
}
}
void
UnstructuredMesh::to_hdf5(hid_t group) const
{
hid_t mesh_group = create_group(group, fmt::format("mesh {}", id_));
write_dataset(mesh_group, "type", "unstructured");
write_dataset(mesh_group, "filename", filename_);
// write volume and centroid of each tet
std::vector<double> tet_vols;
xt::xtensor<double, 2> centroids({ehs_.size(), 3});
for (int i = 0; i < ehs_.size(); i++) {
const auto& eh = ehs_[i];
tet_vols.emplace_back(this->tet_volume(eh));
Position c = this->centroid(eh);
xt::view(centroids, i, xt::all()) = xt::xarray<double>({c.x, c.y, c.z});
}
write_dataset(mesh_group, "volumes", tet_vols);
write_dataset(mesh_group, "centroids", centroids);
close_group(mesh_group);
}
bool
UnstructuredMesh::point_in_tet(const moab::CartVect& r, moab::EntityHandle tet) const {
MOABMesh::point_in_tet(const moab::CartVect& r,
moab::EntityHandle tet) const
{
moab::ErrorCode rval;
@ -1722,7 +1909,8 @@ UnstructuredMesh::point_in_tet(const moab::CartVect& r, moab::EntityHandle tet)
}
int
UnstructuredMesh::get_bin_from_index(int idx) const {
MOABMesh::get_bin_from_index(int idx) const
{
if (idx >= n_bins()) {
fatal_error(fmt::format("Invalid bin index: {}", idx));
}
@ -1730,25 +1918,29 @@ UnstructuredMesh::get_bin_from_index(int idx) const {
}
int
UnstructuredMesh::get_index(const Position& r,
bool* in_mesh) const {
MOABMesh::get_index(const Position& r,
bool* in_mesh) const
{
int bin = get_bin(r);
*in_mesh = bin != -1;
return bin;
}
int UnstructuredMesh::get_index_from_bin(int bin) const {
int MOABMesh::get_index_from_bin(int bin) const
{
return bin;
}
std::pair<std::vector<double>, std::vector<double>>
UnstructuredMesh::plot(Position plot_ll, Position plot_ur) const {
MOABMesh::plot(Position plot_ll, Position plot_ur) const
{
// TODO: Implement mesh lines
return {};
}
int
UnstructuredMesh::get_bin_from_ent_handle(moab::EntityHandle eh) const {
MOABMesh::get_bin_from_ent_handle(moab::EntityHandle eh) const
{
int bin = eh - ehs_[0];
if (bin >= n_bins()) {
fatal_error(fmt::format("Invalid bin: {}", bin));
@ -1757,18 +1949,21 @@ UnstructuredMesh::get_bin_from_ent_handle(moab::EntityHandle eh) const {
}
moab::EntityHandle
UnstructuredMesh::get_ent_handle_from_bin(int bin) const {
MOABMesh::get_ent_handle_from_bin(int bin) const
{
if (bin >= n_bins()) {
fatal_error(fmt::format("Invalid bin index: ", bin));
}
return ehs_[bin];
return ehs_[0] + bin;
}
int UnstructuredMesh::n_bins() const {
int MOABMesh::n_bins() const
{
return ehs_.size();
}
int UnstructuredMesh::n_surface_bins() const {
int MOABMesh::n_surface_bins() const
{
// collect all triangles in the set of tets for this mesh
moab::Range tris;
moab::ErrorCode rval;
@ -1781,9 +1976,12 @@ int UnstructuredMesh::n_surface_bins() const {
}
Position
UnstructuredMesh::centroid(moab::EntityHandle tet) const {
MOABMesh::centroid(int bin) const
{
moab::ErrorCode rval;
auto tet = this->get_ent_handle_from_bin(bin);
// look up the tet connectivity
std::vector<moab::EntityHandle> conn;
rval = mbi_->get_connectivity(&tet, 1, conn);
@ -1810,13 +2008,9 @@ UnstructuredMesh::centroid(moab::EntityHandle tet) const {
return {centroid[0], centroid[1], centroid[2]};
}
std::string
UnstructuredMesh::bin_label(int bin) const {
return fmt::format("Mesh Index ({})", bin);
};
std::pair<moab::Tag, moab::Tag>
UnstructuredMesh::get_score_tags(std::string score) const {
MOABMesh::get_score_tags(std::string score) const
{
moab::ErrorCode rval;
// add a tag to the mesh
// all scores are treated as a single value
@ -1858,52 +2052,51 @@ UnstructuredMesh::get_score_tags(std::string score) const {
}
void
UnstructuredMesh::add_score(std::string score) const {
auto score_tags = this->get_score_tags(score);
MOABMesh::add_score(const std::string& score)
{
auto score_tags = get_score_tags(score);
tag_names_.push_back(score);
}
void UnstructuredMesh::remove_score(std::string score) const {
auto value_name = score + "_mean";
moab::Tag tag;
moab::ErrorCode rval = mbi_->tag_get_handle(value_name.c_str(), tag);
if (rval != moab::MB_SUCCESS) return;
void MOABMesh::remove_scores()
{
for (const auto& name : tag_names_) {
auto value_name = name + "_mean";
moab::Tag tag;
moab::ErrorCode rval = mbi_->tag_get_handle(value_name.c_str(), tag);
if (rval != moab::MB_SUCCESS) return;
rval = mbi_->tag_delete(tag);
if (rval != moab::MB_SUCCESS) {
auto msg = fmt::format("Failed to delete mesh tag for the score {}"
" on unstructured mesh {}", score, id_);
fatal_error(msg);
}
rval = mbi_->tag_delete(tag);
if (rval != moab::MB_SUCCESS) {
auto msg = fmt::format("Failed to delete mesh tag for the score {}"
" on unstructured mesh {}", name, id_);
fatal_error(msg);
}
auto std_dev_name = score + "_std_dev";
rval = mbi_->tag_get_handle(std_dev_name.c_str(), tag);
if (rval != moab::MB_SUCCESS) {
auto msg = fmt::format("Std. Dev. mesh tag does not exist for the score {}"
" on unstructured mesh {}", score, id_);
}
auto std_dev_name = name + "_std_dev";
rval = mbi_->tag_get_handle(std_dev_name.c_str(), tag);
if (rval != moab::MB_SUCCESS) {
auto msg = fmt::format("Std. Dev. mesh tag does not exist for the score {}"
" on unstructured mesh {}", name, id_);
}
rval = mbi_->tag_delete(tag);
if (rval != moab::MB_SUCCESS) {
auto msg = fmt::format("Failed to delete mesh tag for the score {}"
" on unstructured mesh {}", score, id_);
fatal_error(msg);
rval = mbi_->tag_delete(tag);
if (rval != moab::MB_SUCCESS) {
auto msg = fmt::format("Failed to delete mesh tag for the score {}"
" on unstructured mesh {}", name, id_);
fatal_error(msg);
}
}
tag_names_.clear();
}
void
UnstructuredMesh::set_score_data(const std::string& score,
std::vector<double> values,
std::vector<double> std_dev) const {
MOABMesh::set_score_data(const std::string& score,
const std::vector<double>& values,
const std::vector<double>& std_dev)
{
auto score_tags = this->get_score_tags(score);
// normalize tally values by element volume
for (int i = 0; i < ehs_.size(); i++) {
auto eh = this->get_ent_handle_from_bin(i);
double volume = this->tet_volume(eh);
values[i] /= volume;
std_dev[i] /= volume;
}
moab::ErrorCode rval;
// set the score value
rval = mbi_->tag_set_data(score_tags.first, ehs_, values.data());
@ -1923,7 +2116,8 @@ UnstructuredMesh::set_score_data(const std::string& score,
}
void
UnstructuredMesh::write(std::string base_filename) const {
MOABMesh::write(const std::string& base_filename) const
{
// add extension to the base name
auto filename = base_filename + ".vtk";
write_message(5, "Writing unstructured mesh {}...", filename);
@ -1942,6 +2136,226 @@ UnstructuredMesh::write(std::string base_filename) const {
#endif
#ifdef LIBMESH
LibMesh::LibMesh(pugi::xml_node node) : UnstructuredMesh(node)
{
initialize();
}
LibMesh::LibMesh(const std::string& filename)
{
filename_ = filename;
initialize();
}
void LibMesh::initialize()
{
if (!settings::libmesh_comm) {
fatal_error("Attempting to use an unstructured mesh without a libMesh communicator.");
}
// assuming that unstructured meshes used in OpenMC are 3D
n_dimension_ = 3;
m_ = std::make_unique<libMesh::Mesh>(*settings::libmesh_comm, n_dimension_);
m_->read(filename_);
m_->prepare_for_use();
// ensure that the loaded mesh is 3 dimensional
if(m_->mesh_dimension() != n_dimension_) {
fatal_error(fmt::format("Mesh file {} specified for use in an unstructured mesh is not a 3D mesh.", filename_));
}
// create an equation system for storing values
eq_system_name_ = fmt::format("mesh_{}_system", id_);
equation_systems_ = std::make_unique<libMesh::EquationSystems>(*m_);
libMesh::ExplicitSystem& eq_sys =
equation_systems_->add_system<libMesh::ExplicitSystem>(eq_system_name_);
#ifdef _OPENMP
int n_threads = omp_get_max_threads();
#else
int n_threads = 1;
#endif
for (int i = 0; i < n_threads; i++) {
pl_.emplace_back(m_->sub_point_locator());
pl_.back()->set_contains_point_tol(FP_COINCIDENT);
pl_.back()->enable_out_of_mesh_mode();
}
// store first element in the mesh to use as an offset for bin indices
auto first_elem = *m_->elements_begin();
first_element_id_ = first_elem->id();
// bounding box for the mesh for quick rejection checks
bbox_ = libMesh::MeshTools::create_bounding_box(*m_);
}
Position
LibMesh::centroid(int bin) const
{
const auto& elem = this->get_element_from_bin(bin);
auto centroid = elem.centroid();
return {centroid(0), centroid(1), centroid(2)};
}
std::string LibMesh::library() const { return "libmesh"; }
int LibMesh::n_bins() const
{
return m_->n_elem();
}
int LibMesh::n_surface_bins() const
{
int n_bins = 0;
for (int i = 0; i < this->n_bins(); i++) {
const libMesh::Elem& e = get_element_from_bin(i);
n_bins += e.n_faces();
// if this is a boundary element, it will only be visited once,
// the number of surface bins is incremented to
for (auto neighbor_ptr : e.neighbor_ptr_range()) {
// null neighbor pointer indicates a boundary face
if (!neighbor_ptr) { n_bins++; }
}
}
return n_bins;
}
void
LibMesh::add_score(const std::string& var_name)
{
// check if this is a new variable
std::string value_name = var_name + "_mean";
if (!variable_map_.count(value_name)) {
auto& eqn_sys = equation_systems_->get_system(eq_system_name_);
auto var_num = eqn_sys.add_variable(value_name, libMesh::CONSTANT, libMesh::MONOMIAL);
variable_map_[value_name] = var_num;
}
std::string std_dev_name = var_name + "_std_dev";
// check if this is a new variable
if (!variable_map_.count(std_dev_name)) {
auto& eqn_sys = equation_systems_->get_system(eq_system_name_);
auto var_num = eqn_sys.add_variable(std_dev_name, libMesh::CONSTANT, libMesh::MONOMIAL);
variable_map_[std_dev_name] = var_num;
}
}
void
LibMesh::remove_scores()
{
auto& eqn_sys = equation_systems_->get_system(eq_system_name_);
eqn_sys.clear();
variable_map_.clear();
}
void
LibMesh::set_score_data(const std::string& var_name,
const std::vector<double>& values,
const std::vector<double>& std_dev)
{
auto& eqn_sys = equation_systems_->get_system(eq_system_name_);
if (!eqn_sys.is_initialized()) { equation_systems_->init(); }
const libMesh::DofMap& dof_map = eqn_sys.get_dof_map();
// look up the value variable
std::string value_name = var_name + "_mean";
unsigned int value_num = variable_map_.at(value_name);
// look up the std dev variable
std::string std_dev_name = var_name + "_std_dev";
unsigned int std_dev_num = variable_map_.at(std_dev_name);
for (auto it = m_->local_elements_begin(); it != m_->local_elements_end(); it++) {
auto bin = get_bin_from_element(*it);
// set value
std::vector<libMesh::dof_id_type> value_dof_indices;
dof_map.dof_indices(*it, value_dof_indices, value_num);
Ensures(value_dof_indices.size() == 1);
eqn_sys.solution->set(value_dof_indices[0], values.at(bin));
// set std dev
std::vector<libMesh::dof_id_type> std_dev_dof_indices;
dof_map.dof_indices(*it, std_dev_dof_indices, std_dev_num);
Ensures(std_dev_dof_indices.size() == 1);
eqn_sys.solution->set(std_dev_dof_indices[0], std_dev.at(bin));
}
}
void LibMesh::write(const std::string& filename) const
{
write_message(fmt::format("Writing file: {}.e for unstructured mesh {}", filename, this->id_));
libMesh::ExodusII_IO exo(*m_);
std::set<std::string> systems_out = {eq_system_name_};
exo.write_discontinuous_exodusII(filename + ".e", *equation_systems_, &systems_out);
}
void
LibMesh::bins_crossed(const Particle& p,
std::vector<int>& bins,
std::vector<double>& lengths) const
{
// TODO: Implement triangle crossings here
fatal_error("Tracklength tallies on libMesh instances are not implemented.");
}
int
LibMesh::get_bin(Position r) const
{
// look-up a tet using the point locator
libMesh::Point p(r.x, r.y, r.z);
// quick rejection check
if (!bbox_.contains_point(p)) { return -1; }
#ifdef _OPENMP
int thread_num = omp_get_thread_num();
#else
int thread_num = 0;
#endif
const auto& point_locator = pl_.at(thread_num);
const auto elem_ptr = (*point_locator)(p);
return elem_ptr ? get_bin_from_element(elem_ptr) : -1;
}
int
LibMesh::get_bin_from_element(const libMesh::Elem* elem) const
{
int bin = elem->id() - first_element_id_;
if (bin >= n_bins() || bin < 0) {
fatal_error(fmt::format("Invalid bin: {}", bin));
}
return bin;
}
std::pair<std::vector<double>, std::vector<double>>
LibMesh::plot(Position plot_ll, Position plot_ur) const
{
return {};
}
const libMesh::Elem&
LibMesh::get_element_from_bin(int bin) const
{
return m_->elem_ref(bin);
}
double LibMesh::volume(int bin) const
{
return m_->elem_ref(bin).volume();
}
#endif // LIBMESH
//==============================================================================
// Non-member functions
//==============================================================================
@ -1956,18 +2370,27 @@ void read_meshes(pugi::xml_node root)
mesh_type = "regular";
}
// determine the mesh library to use
std::string mesh_lib;
if (check_for_node(node, "library")) {
mesh_lib = get_node_value(node, "library", true, true);
}
// Read mesh and add to vector
if (mesh_type == "regular") {
model::meshes.push_back(std::make_unique<RegularMesh>(node));
} else if (mesh_type == "rectilinear") {
model::meshes.push_back(std::make_unique<RectilinearMesh>(node));
#ifdef DAGMC
} else if (mesh_type == "unstructured") {
model::meshes.push_back(std::make_unique<UnstructuredMesh>(node));
#else
} else if (mesh_type == "unstructured") {
fatal_error("Unstructured mesh support is disabled.");
} else if (mesh_type == "unstructured" && mesh_lib == "moab") {
model::meshes.push_back(std::make_unique<MOABMesh>(node));
#endif
#ifdef LIBMESH
} else if (mesh_type == "unstructured" && mesh_lib == "libmesh") {
model::meshes.push_back(std::make_unique<LibMesh>(node));
#endif
} else if (mesh_type == "unstructured") {
fatal_error("Unstructured mesh support is not enabled or the mesh library is invalid.");
} else {
fatal_error("Invalid mesh type: " + mesh_type);
}

View file

@ -167,11 +167,6 @@ openmc_statepoint_write(const char* filename, bool* write_source)
tally_ids.push_back(tally->id_);
write_attribute(tallies_group, "ids", tally_ids);
#ifdef DAGMC
// write unstructured mesh tallies to VTK if possible
write_unstructured_mesh_results();
#endif
// Write all tally information except results
for (const auto& tally : model::tallies) {
hid_t tally_group = create_group(tallies_group,
@ -315,6 +310,11 @@ openmc_statepoint_write(const char* filename, bool* write_source)
if (mpi::master || parallel) file_close(file_id);
}
#if defined(LIBMESH) || defined(DAGMC)
// write unstructured mesh tally files
write_unstructured_mesh_results();
#endif
simulation::time_statepoint.stop();
return 0;
@ -770,7 +770,6 @@ void read_source_bank(hid_t group_id, std::vector<Particle::Bank>& sites, bool d
H5Tclose(banktype);
}
#ifdef DAGMC
void write_unstructured_mesh_results() {
for (auto& tally : model::tallies) {
@ -787,6 +786,8 @@ void write_unstructured_mesh_results() {
if (!umesh) continue;
if (!umesh->output_) continue;
// if this tally has more than one filter, print
// warning and skip writing the mesh
if (tally->filters().size() > 1) {
@ -798,58 +799,75 @@ void write_unstructured_mesh_results() {
int n_realizations = tally->n_realizations_;
// write each score/nuclide combination for this tally
for (int i_score = 0; i_score < tally->scores_.size(); i_score++) {
for (int i_nuc = 0; i_nuc < tally->nuclides_.size(); i_nuc++) {
for (int score_idx = 0; score_idx < tally->scores_.size(); score_idx++) {
for (int nuc_idx = 0; nuc_idx < tally->nuclides_.size(); nuc_idx++) {
// combine the score and nuclide into a name for the value
auto score_str = fmt::format("{}_{}",
tally->score_name(score_idx),
tally->nuclide_name(nuc_idx));
// add this score to the mesh
// (this is in a separate loop because all variables need to be added
// to libMesh's equation system before any are initialized, which
// happens in set_score_data)
umesh->add_score(score_str);
}
}
for (int score_idx = 0; score_idx < tally->scores_.size(); score_idx++) {
for (int nuc_idx = 0; nuc_idx < tally->nuclides_.size(); nuc_idx++) {
// combine the score and nuclide into a name for the value
auto score_str = fmt::format("{}_{}",
tally->score_name(score_idx),
tally->nuclide_name(nuc_idx));
// index for this nuclide and score
int nuc_score_idx = i_score + i_nuc*tally->scores_.size();
int nuc_score_idx = score_idx + nuc_idx*tally->scores_.size();
// construct result vectors
std::vector<double> mean_vec, std_dev_vec;
std::vector<double> mean_vec(umesh->n_bins()),
std_dev_vec(umesh->n_bins());
for (int j = 0; j < tally->results_.shape()[0]; j++) {
// mean
// get the volume for this bin
double volume = umesh->volume(j);
// compute the mean
double mean = tally->results_(j, nuc_score_idx, TallyResult::SUM) / n_realizations;
mean_vec.push_back(mean);
// std. dev.
mean_vec.at(j) = mean / volume;
// compute the standard deviation
double sum_sq = tally->results_(j , nuc_score_idx, TallyResult::SUM_SQ);
double std_dev {0.0};
if (n_realizations > 1) {
double std_dev = sum_sq/n_realizations - mean*mean;
std_dev = sum_sq/n_realizations - mean*mean;
std_dev = std::sqrt(std_dev / (n_realizations - 1));
std_dev_vec.push_back(std_dev);
} else {
std_dev_vec.push_back(0.0);
}
std_dev_vec[j] = std_dev / volume;
}
// generate a name for the value
std::string nuclide_name = "total"; // start with total by default
if (tally->nuclides_[i_nuc] > -1) {
nuclide_name = data::nuclides[tally->nuclides_[i_nuc]]->name_;
}
std::string score_name = tally->score_name(i_score);
auto score_str = fmt::format("{}_{}", score_name, nuclide_name);
tally_scores.push_back(score_str);
#ifdef OPENMC_MPI
MPI_Bcast(mean_vec.data(), mean_vec.size(), MPI_DOUBLE, 0, mpi::intracomm);
MPI_Bcast(std_dev_vec.data(), std_dev_vec.size(), MPI_DOUBLE, 0, mpi::intracomm);
#endif
// set the data for this score
umesh->set_score_data(score_str, mean_vec, std_dev_vec);
}
}
// Generate a file name based on the tally id
// and the current batch number
int w = std::to_string(settings::n_max_batches).size();
size_t batch_width {std::to_string(settings::n_max_batches).size()};
std::string filename = fmt::format("tally_{0}.{1:0{2}}",
tally->id_,
simulation::current_batch,
w);
batch_width);
if (umesh->library() == "moab" && !mpi::master) continue;
// Write the unstructured mesh and data to file
umesh->write(filename);
for (const auto& score : tally_scores) { umesh->remove_score(score); }
umesh->remove_scores();
}
}
}
#endif
void write_tally_results_nr(hid_t file_id)
{

View file

@ -282,6 +282,21 @@ Tally::Tally(pugi::xml_node node)
"Invalid estimator '{}' on tally {}", est, id_)};
}
}
#ifdef LIBMESH
// ensure a tracklength tally isn't used with a libMesh filter
for (auto i : this->filters_) {
auto df = dynamic_cast<MeshFilter*>(model::tally_filters[i].get());
if (df) {
auto lm = dynamic_cast<LibMesh*>(model::meshes[df->mesh()].get());
if (lm && estimator_ == TallyEstimator::TRACKLENGTH) {
fatal_error("A tracklength estimator cannot be used with "
"an unstructured LibMesh tally.");
}
}
}
#endif
}
Tally::~Tally()
@ -662,6 +677,17 @@ Tally::score_name(int score_idx) const {
return reaction_name(scores_[score_idx]);
}
std::string
Tally::nuclide_name(int nuclide_idx) const {
if (nuclide_idx < 0 || nuclide_idx >= nuclides_.size()) {
fatal_error("Index in nuclides array is out of bounds");
}
int nuclide = nuclides_.at(nuclide_idx);
if (nuclide == -1) { return "total"; }
return data::nuclides.at(nuclide)->name_;
}
//==============================================================================
// Non-member functions
//==============================================================================

View file

@ -45,7 +45,7 @@
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>fixed source</run_mode>
<particles>100</particles>
<particles>1000</particles>
<batches>10</batches>
<source strength="1.0">
<space origin="0.0 0.0 0.0" type="spherical">
@ -57,7 +57,6 @@
<parameters>0.0 1.0</parameters>
</phi>
</space>
<angle reference_uvw="-1.0 0.0 0.0" type="monodirectional" />
<energy type="discrete">
<parameters>15000000.0 1.0</parameters>
</energy>
@ -70,8 +69,8 @@
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="2" type="unstructured">
<filename>test_mesh_tets_w_holes.h5m</filename>
<mesh id="2" library="libmesh" type="unstructured">
<filename>test_mesh_tets_w_holes.e</filename>
</mesh>
<filter id="1" type="mesh">
<bins>1</bins>

View file

@ -1,34 +1,34 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="4" material="4" name="fuel" region="19 -20 21 -22 23 -24" universe="2" />
<cell id="5" material="5" name="clad" region="(-19 | 20 | -21 | 22 | -23 | 24) (25 -26 27 -28 29 -30)" universe="2" />
<cell id="6" material="6" name="water" region="(-25 | 26 | -27 | 28 | -29 | 30) (31 -32 33 -34 35 -36)" universe="2" />
<surface coeffs="-5.0" id="19" name="minimum x" type="x-plane" />
<surface coeffs="5.0" id="20" name="maximum x" type="x-plane" />
<surface coeffs="-5.0" id="21" name="minimum y" type="y-plane" />
<surface coeffs="5.0" id="22" name="maximum y" type="y-plane" />
<surface coeffs="-5.0" id="23" name="minimum z" type="z-plane" />
<surface coeffs="5.0" id="24" name="maximum z" type="z-plane" />
<surface coeffs="-6.0" id="25" name="minimum x" type="x-plane" />
<surface coeffs="6.0" id="26" name="maximum x" type="x-plane" />
<surface coeffs="-6.0" id="27" name="minimum y" type="y-plane" />
<surface coeffs="6.0" id="28" name="maximum y" type="y-plane" />
<surface coeffs="-6.0" id="29" name="minimum z" type="z-plane" />
<surface coeffs="6.0" id="30" name="maximum z" type="z-plane" />
<surface boundary="vacuum" coeffs="-15" id="31" name="minimum x" type="x-plane" />
<surface boundary="vacuum" coeffs="15" id="32" name="maximum x" type="x-plane" />
<surface boundary="vacuum" coeffs="-15" id="33" name="minimum y" type="y-plane" />
<surface boundary="vacuum" coeffs="15" id="34" name="maximum y" type="y-plane" />
<surface boundary="vacuum" coeffs="-15" id="35" name="minimum z" type="z-plane" />
<surface boundary="vacuum" coeffs="15" id="36" name="maximum z" type="z-plane" />
<cell id="1" material="1" name="fuel" region="1 -2 3 -4 5 -6" universe="1" />
<cell id="2" material="2" name="clad" region="(-1 | 2 | -3 | 4 | -5 | 6) (7 -8 9 -10 11 -12)" universe="1" />
<cell id="3" material="3" name="water" region="(-7 | 8 | -9 | 10 | -11 | 12) (13 -14 15 -16 17 -18)" universe="1" />
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane" />
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane" />
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane" />
<surface coeffs="5.0" id="4" name="maximum y" type="y-plane" />
<surface coeffs="-5.0" id="5" name="minimum z" type="z-plane" />
<surface coeffs="5.0" id="6" name="maximum z" type="z-plane" />
<surface coeffs="-6.0" id="7" name="minimum x" type="x-plane" />
<surface coeffs="6.0" id="8" name="maximum x" type="x-plane" />
<surface coeffs="-6.0" id="9" name="minimum y" type="y-plane" />
<surface coeffs="6.0" id="10" name="maximum y" type="y-plane" />
<surface coeffs="-6.0" id="11" name="minimum z" type="z-plane" />
<surface coeffs="6.0" id="12" name="maximum z" type="z-plane" />
<surface boundary="vacuum" coeffs="-15" id="13" name="minimum x" type="x-plane" />
<surface boundary="vacuum" coeffs="15" id="14" name="maximum x" type="x-plane" />
<surface boundary="vacuum" coeffs="-15" id="15" name="minimum y" type="y-plane" />
<surface boundary="vacuum" coeffs="15" id="16" name="maximum y" type="y-plane" />
<surface boundary="vacuum" coeffs="-15" id="17" name="minimum z" type="z-plane" />
<surface boundary="vacuum" coeffs="15" id="18" name="maximum z" type="z-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<material depletable="true" id="4" name="fuel">
<material depletable="true" id="1" name="fuel">
<density units="g/cc" value="4.5" />
<nuclide ao="1.0" name="U235" />
</material>
<material id="5" name="zircaloy">
<material id="2" name="zircaloy">
<density units="g/cc" value="5.77" />
<nuclide ao="0.5145" name="Zr90" />
<nuclide ao="0.1122" name="Zr91" />
@ -36,7 +36,7 @@
<nuclide ao="0.1738" name="Zr94" />
<nuclide ao="0.028" name="Zr96" />
</material>
<material id="6" name="water">
<material id="3" name="water">
<density units="atom/b-cm" value="0.07416" />
<nuclide ao="2.0" name="H1" />
<nuclide ao="1.0" name="O16" />
@ -45,7 +45,7 @@
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>fixed source</run_mode>
<particles>100</particles>
<particles>1000</particles>
<batches>10</batches>
<source strength="1.0">
<space origin="0.0 0.0 0.0" type="spherical">
@ -57,7 +57,6 @@
<parameters>0.0 1.0</parameters>
</phi>
</space>
<angle reference_uvw="-1.0 0.0 0.0" type="monodirectional" />
<energy type="discrete">
<parameters>15000000.0 1.0</parameters>
</energy>
@ -65,27 +64,27 @@
</settings>
<?xml version='1.0' encoding='utf-8'?>
<tallies>
<mesh id="3">
<mesh id="1">
<dimension>10 10 10</dimension>
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="4" type="unstructured">
<filename>test_mesh_tets.h5m</filename>
<mesh id="2" library="libmesh" type="unstructured">
<filename>test_mesh_tets.e</filename>
</mesh>
<filter id="3" type="mesh">
<bins>3</bins>
<filter id="1" type="mesh">
<bins>1</bins>
</filter>
<filter id="4" type="mesh">
<bins>4</bins>
<filter id="2" type="mesh">
<bins>2</bins>
</filter>
<tally id="3" name="regular mesh tally">
<filters>3</filters>
<tally id="1" name="regular mesh tally">
<filters>1</filters>
<scores>flux</scores>
<estimator>collision</estimator>
</tally>
<tally id="4" name="unstructured mesh tally">
<filters>4</filters>
<tally id="2" name="unstructured mesh tally">
<filters>2</filters>
<scores>flux</scores>
<estimator>collision</estimator>
</tally>

View file

@ -0,0 +1,91 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="1" material="1" name="fuel" region="1 -2 3 -4 5 -6" universe="1" />
<cell id="2" material="2" name="clad" region="(-1 | 2 | -3 | 4 | -5 | 6) (7 -8 9 -10 11 -12)" universe="1" />
<cell id="3" material="3" name="water" region="(-7 | 8 | -9 | 10 | -11 | 12) (13 -14 15 -16 17 -18)" universe="1" />
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane" />
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane" />
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane" />
<surface coeffs="5.0" id="4" name="maximum y" type="y-plane" />
<surface coeffs="-5.0" id="5" name="minimum z" type="z-plane" />
<surface coeffs="5.0" id="6" name="maximum z" type="z-plane" />
<surface coeffs="-6.0" id="7" name="minimum x" type="x-plane" />
<surface coeffs="6.0" id="8" name="maximum x" type="x-plane" />
<surface coeffs="-6.0" id="9" name="minimum y" type="y-plane" />
<surface coeffs="6.0" id="10" name="maximum y" type="y-plane" />
<surface coeffs="-6.0" id="11" name="minimum z" type="z-plane" />
<surface coeffs="6.0" id="12" name="maximum z" type="z-plane" />
<surface boundary="vacuum" coeffs="-10" id="13" name="minimum x" type="x-plane" />
<surface boundary="vacuum" coeffs="10" id="14" name="maximum x" type="x-plane" />
<surface boundary="vacuum" coeffs="-10" id="15" name="minimum y" type="y-plane" />
<surface boundary="vacuum" coeffs="10" id="16" name="maximum y" type="y-plane" />
<surface boundary="vacuum" coeffs="-10" id="17" name="minimum z" type="z-plane" />
<surface boundary="vacuum" coeffs="10" id="18" name="maximum z" type="z-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<material depletable="true" id="1" name="fuel">
<density units="g/cc" value="4.5" />
<nuclide ao="1.0" name="U235" />
</material>
<material id="2" name="zircaloy">
<density units="g/cc" value="5.77" />
<nuclide ao="0.5145" name="Zr90" />
<nuclide ao="0.1122" name="Zr91" />
<nuclide ao="0.1715" name="Zr92" />
<nuclide ao="0.1738" name="Zr94" />
<nuclide ao="0.028" name="Zr96" />
</material>
<material id="3" name="water">
<density units="atom/b-cm" value="0.07416" />
<nuclide ao="2.0" name="H1" />
<nuclide ao="1.0" name="O16" />
</material>
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>fixed source</run_mode>
<particles>1000</particles>
<batches>10</batches>
<source strength="1.0">
<space origin="0.0 0.0 0.0" type="spherical">
<r parameters="0.0 0.0" type="uniform" />
<theta type="discrete">
<parameters>0.0 1.0</parameters>
</theta>
<phi type="discrete">
<parameters>0.0 1.0</parameters>
</phi>
</space>
<energy type="discrete">
<parameters>15000000.0 1.0</parameters>
</energy>
</source>
</settings>
<?xml version='1.0' encoding='utf-8'?>
<tallies>
<mesh id="1">
<dimension>10 10 10</dimension>
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="2" library="moab" type="unstructured">
<filename>test_mesh_tets_w_holes.e</filename>
</mesh>
<filter id="1" type="mesh">
<bins>1</bins>
</filter>
<filter id="2" type="mesh">
<bins>2</bins>
</filter>
<tally id="1" name="regular mesh tally">
<filters>1</filters>
<scores>flux</scores>
<estimator>collision</estimator>
</tally>
<tally id="2" name="unstructured mesh tally">
<filters>2</filters>
<scores>flux</scores>
<estimator>collision</estimator>
</tally>
</tallies>

View file

@ -0,0 +1,91 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="1" material="1" name="fuel" region="1 -2 3 -4 5 -6" universe="1" />
<cell id="2" material="2" name="clad" region="(-1 | 2 | -3 | 4 | -5 | 6) (7 -8 9 -10 11 -12)" universe="1" />
<cell id="3" material="3" name="water" region="(-7 | 8 | -9 | 10 | -11 | 12) (13 -14 15 -16 17 -18)" universe="1" />
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane" />
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane" />
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane" />
<surface coeffs="5.0" id="4" name="maximum y" type="y-plane" />
<surface coeffs="-5.0" id="5" name="minimum z" type="z-plane" />
<surface coeffs="5.0" id="6" name="maximum z" type="z-plane" />
<surface coeffs="-6.0" id="7" name="minimum x" type="x-plane" />
<surface coeffs="6.0" id="8" name="maximum x" type="x-plane" />
<surface coeffs="-6.0" id="9" name="minimum y" type="y-plane" />
<surface coeffs="6.0" id="10" name="maximum y" type="y-plane" />
<surface coeffs="-6.0" id="11" name="minimum z" type="z-plane" />
<surface coeffs="6.0" id="12" name="maximum z" type="z-plane" />
<surface boundary="vacuum" coeffs="-10" id="13" name="minimum x" type="x-plane" />
<surface boundary="vacuum" coeffs="10" id="14" name="maximum x" type="x-plane" />
<surface boundary="vacuum" coeffs="-10" id="15" name="minimum y" type="y-plane" />
<surface boundary="vacuum" coeffs="10" id="16" name="maximum y" type="y-plane" />
<surface boundary="vacuum" coeffs="-10" id="17" name="minimum z" type="z-plane" />
<surface boundary="vacuum" coeffs="10" id="18" name="maximum z" type="z-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<material depletable="true" id="1" name="fuel">
<density units="g/cc" value="4.5" />
<nuclide ao="1.0" name="U235" />
</material>
<material id="2" name="zircaloy">
<density units="g/cc" value="5.77" />
<nuclide ao="0.5145" name="Zr90" />
<nuclide ao="0.1122" name="Zr91" />
<nuclide ao="0.1715" name="Zr92" />
<nuclide ao="0.1738" name="Zr94" />
<nuclide ao="0.028" name="Zr96" />
</material>
<material id="3" name="water">
<density units="atom/b-cm" value="0.07416" />
<nuclide ao="2.0" name="H1" />
<nuclide ao="1.0" name="O16" />
</material>
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>fixed source</run_mode>
<particles>1000</particles>
<batches>10</batches>
<source strength="1.0">
<space origin="0.0 0.0 0.0" type="spherical">
<r parameters="0.0 0.0" type="uniform" />
<theta type="discrete">
<parameters>0.0 1.0</parameters>
</theta>
<phi type="discrete">
<parameters>0.0 1.0</parameters>
</phi>
</space>
<energy type="discrete">
<parameters>15000000.0 1.0</parameters>
</energy>
</source>
</settings>
<?xml version='1.0' encoding='utf-8'?>
<tallies>
<mesh id="1">
<dimension>10 10 10</dimension>
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="2" library="moab" type="unstructured">
<filename>test_mesh_tets.e</filename>
</mesh>
<filter id="1" type="mesh">
<bins>1</bins>
</filter>
<filter id="2" type="mesh">
<bins>2</bins>
</filter>
<tally id="1" name="regular mesh tally">
<filters>1</filters>
<scores>flux</scores>
<estimator>collision</estimator>
</tally>
<tally id="2" name="unstructured mesh tally">
<filters>2</filters>
<scores>flux</scores>
<estimator>collision</estimator>
</tally>
</tallies>

View file

@ -0,0 +1,91 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="1" material="1" name="fuel" region="1 -2 3 -4 5 -6" universe="1" />
<cell id="2" material="2" name="clad" region="(-1 | 2 | -3 | 4 | -5 | 6) (7 -8 9 -10 11 -12)" universe="1" />
<cell id="3" material="3" name="water" region="(-7 | 8 | -9 | 10 | -11 | 12) (13 -14 15 -16 17 -18)" universe="1" />
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane" />
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane" />
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane" />
<surface coeffs="5.0" id="4" name="maximum y" type="y-plane" />
<surface coeffs="-5.0" id="5" name="minimum z" type="z-plane" />
<surface coeffs="5.0" id="6" name="maximum z" type="z-plane" />
<surface coeffs="-6.0" id="7" name="minimum x" type="x-plane" />
<surface coeffs="6.0" id="8" name="maximum x" type="x-plane" />
<surface coeffs="-6.0" id="9" name="minimum y" type="y-plane" />
<surface coeffs="6.0" id="10" name="maximum y" type="y-plane" />
<surface coeffs="-6.0" id="11" name="minimum z" type="z-plane" />
<surface coeffs="6.0" id="12" name="maximum z" type="z-plane" />
<surface boundary="vacuum" coeffs="-15" id="13" name="minimum x" type="x-plane" />
<surface boundary="vacuum" coeffs="15" id="14" name="maximum x" type="x-plane" />
<surface boundary="vacuum" coeffs="-15" id="15" name="minimum y" type="y-plane" />
<surface boundary="vacuum" coeffs="15" id="16" name="maximum y" type="y-plane" />
<surface boundary="vacuum" coeffs="-15" id="17" name="minimum z" type="z-plane" />
<surface boundary="vacuum" coeffs="15" id="18" name="maximum z" type="z-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<material depletable="true" id="1" name="fuel">
<density units="g/cc" value="4.5" />
<nuclide ao="1.0" name="U235" />
</material>
<material id="2" name="zircaloy">
<density units="g/cc" value="5.77" />
<nuclide ao="0.5145" name="Zr90" />
<nuclide ao="0.1122" name="Zr91" />
<nuclide ao="0.1715" name="Zr92" />
<nuclide ao="0.1738" name="Zr94" />
<nuclide ao="0.028" name="Zr96" />
</material>
<material id="3" name="water">
<density units="atom/b-cm" value="0.07416" />
<nuclide ao="2.0" name="H1" />
<nuclide ao="1.0" name="O16" />
</material>
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>fixed source</run_mode>
<particles>1000</particles>
<batches>10</batches>
<source strength="1.0">
<space origin="0.0 0.0 0.0" type="spherical">
<r parameters="0.0 0.0" type="uniform" />
<theta type="discrete">
<parameters>0.0 1.0</parameters>
</theta>
<phi type="discrete">
<parameters>0.0 1.0</parameters>
</phi>
</space>
<energy type="discrete">
<parameters>15000000.0 1.0</parameters>
</energy>
</source>
</settings>
<?xml version='1.0' encoding='utf-8'?>
<tallies>
<mesh id="1">
<dimension>10 10 10</dimension>
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="2" library="moab" type="unstructured">
<filename>test_mesh_tets_w_holes.e</filename>
</mesh>
<filter id="1" type="mesh">
<bins>1</bins>
</filter>
<filter id="2" type="mesh">
<bins>2</bins>
</filter>
<tally id="1" name="regular mesh tally">
<filters>1</filters>
<scores>flux</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="2" name="unstructured mesh tally">
<filters>2</filters>
<scores>flux</scores>
<estimator>tracklength</estimator>
</tally>
</tallies>

View file

@ -0,0 +1,91 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="1" material="1" name="fuel" region="1 -2 3 -4 5 -6" universe="1" />
<cell id="2" material="2" name="clad" region="(-1 | 2 | -3 | 4 | -5 | 6) (7 -8 9 -10 11 -12)" universe="1" />
<cell id="3" material="3" name="water" region="(-7 | 8 | -9 | 10 | -11 | 12) (13 -14 15 -16 17 -18)" universe="1" />
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane" />
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane" />
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane" />
<surface coeffs="5.0" id="4" name="maximum y" type="y-plane" />
<surface coeffs="-5.0" id="5" name="minimum z" type="z-plane" />
<surface coeffs="5.0" id="6" name="maximum z" type="z-plane" />
<surface coeffs="-6.0" id="7" name="minimum x" type="x-plane" />
<surface coeffs="6.0" id="8" name="maximum x" type="x-plane" />
<surface coeffs="-6.0" id="9" name="minimum y" type="y-plane" />
<surface coeffs="6.0" id="10" name="maximum y" type="y-plane" />
<surface coeffs="-6.0" id="11" name="minimum z" type="z-plane" />
<surface coeffs="6.0" id="12" name="maximum z" type="z-plane" />
<surface boundary="vacuum" coeffs="-15" id="13" name="minimum x" type="x-plane" />
<surface boundary="vacuum" coeffs="15" id="14" name="maximum x" type="x-plane" />
<surface boundary="vacuum" coeffs="-15" id="15" name="minimum y" type="y-plane" />
<surface boundary="vacuum" coeffs="15" id="16" name="maximum y" type="y-plane" />
<surface boundary="vacuum" coeffs="-15" id="17" name="minimum z" type="z-plane" />
<surface boundary="vacuum" coeffs="15" id="18" name="maximum z" type="z-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<material depletable="true" id="1" name="fuel">
<density units="g/cc" value="4.5" />
<nuclide ao="1.0" name="U235" />
</material>
<material id="2" name="zircaloy">
<density units="g/cc" value="5.77" />
<nuclide ao="0.5145" name="Zr90" />
<nuclide ao="0.1122" name="Zr91" />
<nuclide ao="0.1715" name="Zr92" />
<nuclide ao="0.1738" name="Zr94" />
<nuclide ao="0.028" name="Zr96" />
</material>
<material id="3" name="water">
<density units="atom/b-cm" value="0.07416" />
<nuclide ao="2.0" name="H1" />
<nuclide ao="1.0" name="O16" />
</material>
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>fixed source</run_mode>
<particles>1000</particles>
<batches>10</batches>
<source strength="1.0">
<space origin="0.0 0.0 0.0" type="spherical">
<r parameters="0.0 0.0" type="uniform" />
<theta type="discrete">
<parameters>0.0 1.0</parameters>
</theta>
<phi type="discrete">
<parameters>0.0 1.0</parameters>
</phi>
</space>
<energy type="discrete">
<parameters>15000000.0 1.0</parameters>
</energy>
</source>
</settings>
<?xml version='1.0' encoding='utf-8'?>
<tallies>
<mesh id="1">
<dimension>10 10 10</dimension>
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="2" library="moab" type="unstructured">
<filename>test_mesh_tets.e</filename>
</mesh>
<filter id="1" type="mesh">
<bins>1</bins>
</filter>
<filter id="2" type="mesh">
<bins>2</bins>
</filter>
<tally id="1" name="regular mesh tally">
<filters>1</filters>
<scores>flux</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="2" name="unstructured mesh tally">
<filters>2</filters>
<scores>flux</scores>
<estimator>tracklength</estimator>
</tally>
</tallies>

View file

@ -0,0 +1,91 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="1" material="1" name="fuel" region="1 -2 3 -4 5 -6" universe="1" />
<cell id="2" material="2" name="clad" region="(-1 | 2 | -3 | 4 | -5 | 6) (7 -8 9 -10 11 -12)" universe="1" />
<cell id="3" material="3" name="water" region="(-7 | 8 | -9 | 10 | -11 | 12) (13 -14 15 -16 17 -18)" universe="1" />
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane" />
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane" />
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane" />
<surface coeffs="5.0" id="4" name="maximum y" type="y-plane" />
<surface coeffs="-5.0" id="5" name="minimum z" type="z-plane" />
<surface coeffs="5.0" id="6" name="maximum z" type="z-plane" />
<surface coeffs="-6.0" id="7" name="minimum x" type="x-plane" />
<surface coeffs="6.0" id="8" name="maximum x" type="x-plane" />
<surface coeffs="-6.0" id="9" name="minimum y" type="y-plane" />
<surface coeffs="6.0" id="10" name="maximum y" type="y-plane" />
<surface coeffs="-6.0" id="11" name="minimum z" type="z-plane" />
<surface coeffs="6.0" id="12" name="maximum z" type="z-plane" />
<surface boundary="vacuum" coeffs="-10" id="13" name="minimum x" type="x-plane" />
<surface boundary="vacuum" coeffs="10" id="14" name="maximum x" type="x-plane" />
<surface boundary="vacuum" coeffs="-10" id="15" name="minimum y" type="y-plane" />
<surface boundary="vacuum" coeffs="10" id="16" name="maximum y" type="y-plane" />
<surface boundary="vacuum" coeffs="-10" id="17" name="minimum z" type="z-plane" />
<surface boundary="vacuum" coeffs="10" id="18" name="maximum z" type="z-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<material depletable="true" id="1" name="fuel">
<density units="g/cc" value="4.5" />
<nuclide ao="1.0" name="U235" />
</material>
<material id="2" name="zircaloy">
<density units="g/cc" value="5.77" />
<nuclide ao="0.5145" name="Zr90" />
<nuclide ao="0.1122" name="Zr91" />
<nuclide ao="0.1715" name="Zr92" />
<nuclide ao="0.1738" name="Zr94" />
<nuclide ao="0.028" name="Zr96" />
</material>
<material id="3" name="water">
<density units="atom/b-cm" value="0.07416" />
<nuclide ao="2.0" name="H1" />
<nuclide ao="1.0" name="O16" />
</material>
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>fixed source</run_mode>
<particles>1000</particles>
<batches>10</batches>
<source strength="1.0">
<space origin="0.0 0.0 0.0" type="spherical">
<r parameters="0.0 0.0" type="uniform" />
<theta type="discrete">
<parameters>0.0 1.0</parameters>
</theta>
<phi type="discrete">
<parameters>0.0 1.0</parameters>
</phi>
</space>
<energy type="discrete">
<parameters>15000000.0 1.0</parameters>
</energy>
</source>
</settings>
<?xml version='1.0' encoding='utf-8'?>
<tallies>
<mesh id="1">
<dimension>10 10 10</dimension>
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="2" library="moab" type="unstructured">
<filename>test_mesh_tets_w_holes.e</filename>
</mesh>
<filter id="1" type="mesh">
<bins>1</bins>
</filter>
<filter id="2" type="mesh">
<bins>2</bins>
</filter>
<tally id="1" name="regular mesh tally">
<filters>1</filters>
<scores>flux</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="2" name="unstructured mesh tally">
<filters>2</filters>
<scores>flux</scores>
<estimator>tracklength</estimator>
</tally>
</tallies>

View file

@ -0,0 +1,91 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="1" material="1" name="fuel" region="1 -2 3 -4 5 -6" universe="1" />
<cell id="2" material="2" name="clad" region="(-1 | 2 | -3 | 4 | -5 | 6) (7 -8 9 -10 11 -12)" universe="1" />
<cell id="3" material="3" name="water" region="(-7 | 8 | -9 | 10 | -11 | 12) (13 -14 15 -16 17 -18)" universe="1" />
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane" />
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane" />
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane" />
<surface coeffs="5.0" id="4" name="maximum y" type="y-plane" />
<surface coeffs="-5.0" id="5" name="minimum z" type="z-plane" />
<surface coeffs="5.0" id="6" name="maximum z" type="z-plane" />
<surface coeffs="-6.0" id="7" name="minimum x" type="x-plane" />
<surface coeffs="6.0" id="8" name="maximum x" type="x-plane" />
<surface coeffs="-6.0" id="9" name="minimum y" type="y-plane" />
<surface coeffs="6.0" id="10" name="maximum y" type="y-plane" />
<surface coeffs="-6.0" id="11" name="minimum z" type="z-plane" />
<surface coeffs="6.0" id="12" name="maximum z" type="z-plane" />
<surface boundary="vacuum" coeffs="-10" id="13" name="minimum x" type="x-plane" />
<surface boundary="vacuum" coeffs="10" id="14" name="maximum x" type="x-plane" />
<surface boundary="vacuum" coeffs="-10" id="15" name="minimum y" type="y-plane" />
<surface boundary="vacuum" coeffs="10" id="16" name="maximum y" type="y-plane" />
<surface boundary="vacuum" coeffs="-10" id="17" name="minimum z" type="z-plane" />
<surface boundary="vacuum" coeffs="10" id="18" name="maximum z" type="z-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<material depletable="true" id="1" name="fuel">
<density units="g/cc" value="4.5" />
<nuclide ao="1.0" name="U235" />
</material>
<material id="2" name="zircaloy">
<density units="g/cc" value="5.77" />
<nuclide ao="0.5145" name="Zr90" />
<nuclide ao="0.1122" name="Zr91" />
<nuclide ao="0.1715" name="Zr92" />
<nuclide ao="0.1738" name="Zr94" />
<nuclide ao="0.028" name="Zr96" />
</material>
<material id="3" name="water">
<density units="atom/b-cm" value="0.07416" />
<nuclide ao="2.0" name="H1" />
<nuclide ao="1.0" name="O16" />
</material>
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>fixed source</run_mode>
<particles>1000</particles>
<batches>10</batches>
<source strength="1.0">
<space origin="0.0 0.0 0.0" type="spherical">
<r parameters="0.0 0.0" type="uniform" />
<theta type="discrete">
<parameters>0.0 1.0</parameters>
</theta>
<phi type="discrete">
<parameters>0.0 1.0</parameters>
</phi>
</space>
<energy type="discrete">
<parameters>15000000.0 1.0</parameters>
</energy>
</source>
</settings>
<?xml version='1.0' encoding='utf-8'?>
<tallies>
<mesh id="1">
<dimension>10 10 10</dimension>
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="2" library="moab" type="unstructured">
<filename>test_mesh_tets.e</filename>
</mesh>
<filter id="1" type="mesh">
<bins>1</bins>
</filter>
<filter id="2" type="mesh">
<bins>2</bins>
</filter>
<tally id="1" name="regular mesh tally">
<filters>1</filters>
<scores>flux</scores>
<estimator>tracklength</estimator>
</tally>
<tally id="2" name="unstructured mesh tally">
<filters>2</filters>
<scores>flux</scores>
<estimator>tracklength</estimator>
</tally>
</tallies>

View file

@ -1,34 +1,34 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="7" material="7" name="fuel" region="37 -38 39 -40 41 -42" universe="3" />
<cell id="8" material="8" name="clad" region="(-37 | 38 | -39 | 40 | -41 | 42) (43 -44 45 -46 47 -48)" universe="3" />
<cell id="9" material="9" name="water" region="(-43 | 44 | -45 | 46 | -47 | 48) (49 -50 51 -52 53 -54)" universe="3" />
<surface coeffs="-5.0" id="37" name="minimum x" type="x-plane" />
<surface coeffs="5.0" id="38" name="maximum x" type="x-plane" />
<surface coeffs="-5.0" id="39" name="minimum y" type="y-plane" />
<surface coeffs="5.0" id="40" name="maximum y" type="y-plane" />
<surface coeffs="-5.0" id="41" name="minimum z" type="z-plane" />
<surface coeffs="5.0" id="42" name="maximum z" type="z-plane" />
<surface coeffs="-6.0" id="43" name="minimum x" type="x-plane" />
<surface coeffs="6.0" id="44" name="maximum x" type="x-plane" />
<surface coeffs="-6.0" id="45" name="minimum y" type="y-plane" />
<surface coeffs="6.0" id="46" name="maximum y" type="y-plane" />
<surface coeffs="-6.0" id="47" name="minimum z" type="z-plane" />
<surface coeffs="6.0" id="48" name="maximum z" type="z-plane" />
<surface boundary="vacuum" coeffs="-10" id="49" name="minimum x" type="x-plane" />
<surface boundary="vacuum" coeffs="10" id="50" name="maximum x" type="x-plane" />
<surface boundary="vacuum" coeffs="-10" id="51" name="minimum y" type="y-plane" />
<surface boundary="vacuum" coeffs="10" id="52" name="maximum y" type="y-plane" />
<surface boundary="vacuum" coeffs="-10" id="53" name="minimum z" type="z-plane" />
<surface boundary="vacuum" coeffs="10" id="54" name="maximum z" type="z-plane" />
<cell id="1" material="1" name="fuel" region="1 -2 3 -4 5 -6" universe="1" />
<cell id="2" material="2" name="clad" region="(-1 | 2 | -3 | 4 | -5 | 6) (7 -8 9 -10 11 -12)" universe="1" />
<cell id="3" material="3" name="water" region="(-7 | 8 | -9 | 10 | -11 | 12) (13 -14 15 -16 17 -18)" universe="1" />
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane" />
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane" />
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane" />
<surface coeffs="5.0" id="4" name="maximum y" type="y-plane" />
<surface coeffs="-5.0" id="5" name="minimum z" type="z-plane" />
<surface coeffs="5.0" id="6" name="maximum z" type="z-plane" />
<surface coeffs="-6.0" id="7" name="minimum x" type="x-plane" />
<surface coeffs="6.0" id="8" name="maximum x" type="x-plane" />
<surface coeffs="-6.0" id="9" name="minimum y" type="y-plane" />
<surface coeffs="6.0" id="10" name="maximum y" type="y-plane" />
<surface coeffs="-6.0" id="11" name="minimum z" type="z-plane" />
<surface coeffs="6.0" id="12" name="maximum z" type="z-plane" />
<surface boundary="vacuum" coeffs="-10" id="13" name="minimum x" type="x-plane" />
<surface boundary="vacuum" coeffs="10" id="14" name="maximum x" type="x-plane" />
<surface boundary="vacuum" coeffs="-10" id="15" name="minimum y" type="y-plane" />
<surface boundary="vacuum" coeffs="10" id="16" name="maximum y" type="y-plane" />
<surface boundary="vacuum" coeffs="-10" id="17" name="minimum z" type="z-plane" />
<surface boundary="vacuum" coeffs="10" id="18" name="maximum z" type="z-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<material depletable="true" id="7" name="fuel">
<material depletable="true" id="1" name="fuel">
<density units="g/cc" value="4.5" />
<nuclide ao="1.0" name="U235" />
</material>
<material id="8" name="zircaloy">
<material id="2" name="zircaloy">
<density units="g/cc" value="5.77" />
<nuclide ao="0.5145" name="Zr90" />
<nuclide ao="0.1122" name="Zr91" />
@ -36,7 +36,7 @@
<nuclide ao="0.1738" name="Zr94" />
<nuclide ao="0.028" name="Zr96" />
</material>
<material id="9" name="water">
<material id="3" name="water">
<density units="atom/b-cm" value="0.07416" />
<nuclide ao="2.0" name="H1" />
<nuclide ao="1.0" name="O16" />
@ -45,7 +45,7 @@
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>fixed source</run_mode>
<particles>100</particles>
<particles>1000</particles>
<batches>10</batches>
<source strength="1.0">
<space origin="0.0 0.0 0.0" type="spherical">
@ -57,7 +57,6 @@
<parameters>0.0 1.0</parameters>
</phi>
</space>
<angle reference_uvw="-1.0 0.0 0.0" type="monodirectional" />
<energy type="discrete">
<parameters>15000000.0 1.0</parameters>
</energy>
@ -65,27 +64,27 @@
</settings>
<?xml version='1.0' encoding='utf-8'?>
<tallies>
<mesh id="5">
<mesh id="1">
<dimension>10 10 10</dimension>
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="6" type="unstructured">
<filename>test_mesh_tets_w_holes.h5m</filename>
<mesh id="2" library="libmesh" type="unstructured">
<filename>test_mesh_tets_w_holes.e</filename>
</mesh>
<filter id="5" type="mesh">
<bins>5</bins>
<filter id="1" type="mesh">
<bins>1</bins>
</filter>
<filter id="6" type="mesh">
<bins>6</bins>
<filter id="2" type="mesh">
<bins>2</bins>
</filter>
<tally id="5" name="regular mesh tally">
<filters>5</filters>
<tally id="1" name="regular mesh tally">
<filters>1</filters>
<scores>flux</scores>
<estimator>collision</estimator>
</tally>
<tally id="6" name="unstructured mesh tally">
<filters>6</filters>
<tally id="2" name="unstructured mesh tally">
<filters>2</filters>
<scores>flux</scores>
<estimator>collision</estimator>
</tally>

View file

@ -1,34 +1,34 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="10" material="10" name="fuel" region="55 -56 57 -58 59 -60" universe="4" />
<cell id="11" material="11" name="clad" region="(-55 | 56 | -57 | 58 | -59 | 60) (61 -62 63 -64 65 -66)" universe="4" />
<cell id="12" material="12" name="water" region="(-61 | 62 | -63 | 64 | -65 | 66) (67 -68 69 -70 71 -72)" universe="4" />
<surface coeffs="-5.0" id="55" name="minimum x" type="x-plane" />
<surface coeffs="5.0" id="56" name="maximum x" type="x-plane" />
<surface coeffs="-5.0" id="57" name="minimum y" type="y-plane" />
<surface coeffs="5.0" id="58" name="maximum y" type="y-plane" />
<surface coeffs="-5.0" id="59" name="minimum z" type="z-plane" />
<surface coeffs="5.0" id="60" name="maximum z" type="z-plane" />
<surface coeffs="-6.0" id="61" name="minimum x" type="x-plane" />
<surface coeffs="6.0" id="62" name="maximum x" type="x-plane" />
<surface coeffs="-6.0" id="63" name="minimum y" type="y-plane" />
<surface coeffs="6.0" id="64" name="maximum y" type="y-plane" />
<surface coeffs="-6.0" id="65" name="minimum z" type="z-plane" />
<surface coeffs="6.0" id="66" name="maximum z" type="z-plane" />
<surface boundary="vacuum" coeffs="-10" id="67" name="minimum x" type="x-plane" />
<surface boundary="vacuum" coeffs="10" id="68" name="maximum x" type="x-plane" />
<surface boundary="vacuum" coeffs="-10" id="69" name="minimum y" type="y-plane" />
<surface boundary="vacuum" coeffs="10" id="70" name="maximum y" type="y-plane" />
<surface boundary="vacuum" coeffs="-10" id="71" name="minimum z" type="z-plane" />
<surface boundary="vacuum" coeffs="10" id="72" name="maximum z" type="z-plane" />
<cell id="1" material="1" name="fuel" region="1 -2 3 -4 5 -6" universe="1" />
<cell id="2" material="2" name="clad" region="(-1 | 2 | -3 | 4 | -5 | 6) (7 -8 9 -10 11 -12)" universe="1" />
<cell id="3" material="3" name="water" region="(-7 | 8 | -9 | 10 | -11 | 12) (13 -14 15 -16 17 -18)" universe="1" />
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane" />
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane" />
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane" />
<surface coeffs="5.0" id="4" name="maximum y" type="y-plane" />
<surface coeffs="-5.0" id="5" name="minimum z" type="z-plane" />
<surface coeffs="5.0" id="6" name="maximum z" type="z-plane" />
<surface coeffs="-6.0" id="7" name="minimum x" type="x-plane" />
<surface coeffs="6.0" id="8" name="maximum x" type="x-plane" />
<surface coeffs="-6.0" id="9" name="minimum y" type="y-plane" />
<surface coeffs="6.0" id="10" name="maximum y" type="y-plane" />
<surface coeffs="-6.0" id="11" name="minimum z" type="z-plane" />
<surface coeffs="6.0" id="12" name="maximum z" type="z-plane" />
<surface boundary="vacuum" coeffs="-10" id="13" name="minimum x" type="x-plane" />
<surface boundary="vacuum" coeffs="10" id="14" name="maximum x" type="x-plane" />
<surface boundary="vacuum" coeffs="-10" id="15" name="minimum y" type="y-plane" />
<surface boundary="vacuum" coeffs="10" id="16" name="maximum y" type="y-plane" />
<surface boundary="vacuum" coeffs="-10" id="17" name="minimum z" type="z-plane" />
<surface boundary="vacuum" coeffs="10" id="18" name="maximum z" type="z-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<material depletable="true" id="10" name="fuel">
<material depletable="true" id="1" name="fuel">
<density units="g/cc" value="4.5" />
<nuclide ao="1.0" name="U235" />
</material>
<material id="11" name="zircaloy">
<material id="2" name="zircaloy">
<density units="g/cc" value="5.77" />
<nuclide ao="0.5145" name="Zr90" />
<nuclide ao="0.1122" name="Zr91" />
@ -36,7 +36,7 @@
<nuclide ao="0.1738" name="Zr94" />
<nuclide ao="0.028" name="Zr96" />
</material>
<material id="12" name="water">
<material id="3" name="water">
<density units="atom/b-cm" value="0.07416" />
<nuclide ao="2.0" name="H1" />
<nuclide ao="1.0" name="O16" />
@ -45,7 +45,7 @@
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>fixed source</run_mode>
<particles>100</particles>
<particles>1000</particles>
<batches>10</batches>
<source strength="1.0">
<space origin="0.0 0.0 0.0" type="spherical">
@ -57,7 +57,6 @@
<parameters>0.0 1.0</parameters>
</phi>
</space>
<angle reference_uvw="-1.0 0.0 0.0" type="monodirectional" />
<energy type="discrete">
<parameters>15000000.0 1.0</parameters>
</energy>
@ -65,27 +64,27 @@
</settings>
<?xml version='1.0' encoding='utf-8'?>
<tallies>
<mesh id="7">
<mesh id="1">
<dimension>10 10 10</dimension>
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="8" type="unstructured">
<filename>test_mesh_tets.h5m</filename>
<mesh id="2" library="libmesh" type="unstructured">
<filename>test_mesh_tets.e</filename>
</mesh>
<filter id="7" type="mesh">
<bins>7</bins>
<filter id="1" type="mesh">
<bins>1</bins>
</filter>
<filter id="8" type="mesh">
<bins>8</bins>
<filter id="2" type="mesh">
<bins>2</bins>
</filter>
<tally id="7" name="regular mesh tally">
<filters>7</filters>
<tally id="1" name="regular mesh tally">
<filters>1</filters>
<scores>flux</scores>
<estimator>collision</estimator>
</tally>
<tally id="8" name="unstructured mesh tally">
<filters>8</filters>
<tally id="2" name="unstructured mesh tally">
<filters>2</filters>
<scores>flux</scores>
<estimator>collision</estimator>
</tally>

View file

@ -70,8 +70,8 @@
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="10" type="unstructured">
<filename>test_mesh_tets_w_holes.h5m</filename>
<mesh id="10" library="moab" type="unstructured">
<filename>test_mesh_tets_w_holes.exo</filename>
</mesh>
<filter id="9" type="mesh">
<bins>9</bins>

View file

@ -70,8 +70,8 @@
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="12" type="unstructured">
<filename>test_mesh_tets.h5m</filename>
<mesh id="12" library="moab" type="unstructured">
<filename>test_mesh_tets.exo</filename>
</mesh>
<filter id="11" type="mesh">
<bins>11</bins>

View file

@ -70,8 +70,8 @@
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="14" type="unstructured">
<filename>test_mesh_tets_w_holes.h5m</filename>
<mesh id="14" library="moab" type="unstructured">
<filename>test_mesh_tets_w_holes.exo</filename>
</mesh>
<filter id="13" type="mesh">
<bins>13</bins>

View file

@ -70,8 +70,8 @@
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="16" type="unstructured">
<filename>test_mesh_tets.h5m</filename>
<mesh id="16" library="moab" type="unstructured">
<filename>test_mesh_tets.exo</filename>
</mesh>
<filter id="15" type="mesh">
<bins>15</bins>

View file

@ -0,0 +1,91 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="1" material="1" name="fuel" region="1 -2 3 -4 5 -6" universe="1" />
<cell id="2" material="2" name="clad" region="(-1 | 2 | -3 | 4 | -5 | 6) (7 -8 9 -10 11 -12)" universe="1" />
<cell id="3" material="3" name="water" region="(-7 | 8 | -9 | 10 | -11 | 12) (13 -14 15 -16 17 -18)" universe="1" />
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane" />
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane" />
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane" />
<surface coeffs="5.0" id="4" name="maximum y" type="y-plane" />
<surface coeffs="-5.0" id="5" name="minimum z" type="z-plane" />
<surface coeffs="5.0" id="6" name="maximum z" type="z-plane" />
<surface coeffs="-6.0" id="7" name="minimum x" type="x-plane" />
<surface coeffs="6.0" id="8" name="maximum x" type="x-plane" />
<surface coeffs="-6.0" id="9" name="minimum y" type="y-plane" />
<surface coeffs="6.0" id="10" name="maximum y" type="y-plane" />
<surface coeffs="-6.0" id="11" name="minimum z" type="z-plane" />
<surface coeffs="6.0" id="12" name="maximum z" type="z-plane" />
<surface boundary="vacuum" coeffs="-15" id="13" name="minimum x" type="x-plane" />
<surface boundary="vacuum" coeffs="15" id="14" name="maximum x" type="x-plane" />
<surface boundary="vacuum" coeffs="-15" id="15" name="minimum y" type="y-plane" />
<surface boundary="vacuum" coeffs="15" id="16" name="maximum y" type="y-plane" />
<surface boundary="vacuum" coeffs="-15" id="17" name="minimum z" type="z-plane" />
<surface boundary="vacuum" coeffs="15" id="18" name="maximum z" type="z-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<material depletable="true" id="1" name="fuel">
<density units="g/cc" value="4.5" />
<nuclide ao="1.0" name="U235" />
</material>
<material id="2" name="zircaloy">
<density units="g/cc" value="5.77" />
<nuclide ao="0.5145" name="Zr90" />
<nuclide ao="0.1122" name="Zr91" />
<nuclide ao="0.1715" name="Zr92" />
<nuclide ao="0.1738" name="Zr94" />
<nuclide ao="0.028" name="Zr96" />
</material>
<material id="3" name="water">
<density units="atom/b-cm" value="0.07416" />
<nuclide ao="2.0" name="H1" />
<nuclide ao="1.0" name="O16" />
</material>
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>fixed source</run_mode>
<particles>1000</particles>
<batches>10</batches>
<source strength="1.0">
<space origin="0.0 0.0 0.0" type="spherical">
<r parameters="0.0 0.0" type="uniform" />
<theta type="discrete">
<parameters>0.0 1.0</parameters>
</theta>
<phi type="discrete">
<parameters>0.0 1.0</parameters>
</phi>
</space>
<energy type="discrete">
<parameters>15000000.0 1.0</parameters>
</energy>
</source>
</settings>
<?xml version='1.0' encoding='utf-8'?>
<tallies>
<mesh id="1">
<dimension>10 10 10</dimension>
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="2" library="moab" type="unstructured">
<filename>test_mesh_tets_w_holes.e</filename>
</mesh>
<filter id="1" type="mesh">
<bins>1</bins>
</filter>
<filter id="2" type="mesh">
<bins>2</bins>
</filter>
<tally id="1" name="regular mesh tally">
<filters>1</filters>
<scores>flux</scores>
<estimator>collision</estimator>
</tally>
<tally id="2" name="unstructured mesh tally">
<filters>2</filters>
<scores>flux</scores>
<estimator>collision</estimator>
</tally>
</tallies>

View file

@ -0,0 +1,91 @@
<?xml version='1.0' encoding='utf-8'?>
<geometry>
<cell id="1" material="1" name="fuel" region="1 -2 3 -4 5 -6" universe="1" />
<cell id="2" material="2" name="clad" region="(-1 | 2 | -3 | 4 | -5 | 6) (7 -8 9 -10 11 -12)" universe="1" />
<cell id="3" material="3" name="water" region="(-7 | 8 | -9 | 10 | -11 | 12) (13 -14 15 -16 17 -18)" universe="1" />
<surface coeffs="-5.0" id="1" name="minimum x" type="x-plane" />
<surface coeffs="5.0" id="2" name="maximum x" type="x-plane" />
<surface coeffs="-5.0" id="3" name="minimum y" type="y-plane" />
<surface coeffs="5.0" id="4" name="maximum y" type="y-plane" />
<surface coeffs="-5.0" id="5" name="minimum z" type="z-plane" />
<surface coeffs="5.0" id="6" name="maximum z" type="z-plane" />
<surface coeffs="-6.0" id="7" name="minimum x" type="x-plane" />
<surface coeffs="6.0" id="8" name="maximum x" type="x-plane" />
<surface coeffs="-6.0" id="9" name="minimum y" type="y-plane" />
<surface coeffs="6.0" id="10" name="maximum y" type="y-plane" />
<surface coeffs="-6.0" id="11" name="minimum z" type="z-plane" />
<surface coeffs="6.0" id="12" name="maximum z" type="z-plane" />
<surface boundary="vacuum" coeffs="-15" id="13" name="minimum x" type="x-plane" />
<surface boundary="vacuum" coeffs="15" id="14" name="maximum x" type="x-plane" />
<surface boundary="vacuum" coeffs="-15" id="15" name="minimum y" type="y-plane" />
<surface boundary="vacuum" coeffs="15" id="16" name="maximum y" type="y-plane" />
<surface boundary="vacuum" coeffs="-15" id="17" name="minimum z" type="z-plane" />
<surface boundary="vacuum" coeffs="15" id="18" name="maximum z" type="z-plane" />
</geometry>
<?xml version='1.0' encoding='utf-8'?>
<materials>
<material depletable="true" id="1" name="fuel">
<density units="g/cc" value="4.5" />
<nuclide ao="1.0" name="U235" />
</material>
<material id="2" name="zircaloy">
<density units="g/cc" value="5.77" />
<nuclide ao="0.5145" name="Zr90" />
<nuclide ao="0.1122" name="Zr91" />
<nuclide ao="0.1715" name="Zr92" />
<nuclide ao="0.1738" name="Zr94" />
<nuclide ao="0.028" name="Zr96" />
</material>
<material id="3" name="water">
<density units="atom/b-cm" value="0.07416" />
<nuclide ao="2.0" name="H1" />
<nuclide ao="1.0" name="O16" />
</material>
</materials>
<?xml version='1.0' encoding='utf-8'?>
<settings>
<run_mode>fixed source</run_mode>
<particles>1000</particles>
<batches>10</batches>
<source strength="1.0">
<space origin="0.0 0.0 0.0" type="spherical">
<r parameters="0.0 0.0" type="uniform" />
<theta type="discrete">
<parameters>0.0 1.0</parameters>
</theta>
<phi type="discrete">
<parameters>0.0 1.0</parameters>
</phi>
</space>
<energy type="discrete">
<parameters>15000000.0 1.0</parameters>
</energy>
</source>
</settings>
<?xml version='1.0' encoding='utf-8'?>
<tallies>
<mesh id="1">
<dimension>10 10 10</dimension>
<lower_left>-10.0 -10.0 -10.0</lower_left>
<upper_right>10.0 10.0 10.0</upper_right>
</mesh>
<mesh id="2" library="moab" type="unstructured">
<filename>test_mesh_tets.e</filename>
</mesh>
<filter id="1" type="mesh">
<bins>1</bins>
</filter>
<filter id="2" type="mesh">
<bins>2</bins>
</filter>
<tally id="1" name="regular mesh tally">
<filters>1</filters>
<scores>flux</scores>
<estimator>collision</estimator>
</tally>
<tally id="2" name="unstructured mesh tally">
<filters>2</filters>
<scores>flux</scores>
<estimator>collision</estimator>
</tally>
</tallies>

File diff suppressed because it is too large Load diff

View file

@ -9,10 +9,6 @@ import numpy as np
import pytest
from tests.testing_harness import PyAPITestHarness
pytestmark = pytest.mark.skipif(
not openmc.lib._dagmc_enabled(),
reason="Mesh library is not enabled.")
TETS_PER_VOXEL = 12
@ -62,17 +58,20 @@ class UnstructuredMeshTest(PyAPITestHarness):
def _cleanup(self):
super()._cleanup()
output = glob.glob('tally*.vtk')
output += glob.glob('tally*.e')
for f in output:
if os.path.exists(f):
os.remove(f)
param_values = (['collision', 'tracklength'], # estimators
param_values = (['libmesh', 'moab'], # mesh libraries
['collision', 'tracklength'], # estimators
[True, False], # geometry outside of the mesh
[(333, 90, 77), None]) # location of holes in the mesh
test_cases = []
for i, (estimator, ext_geom, holes) in enumerate(product(*param_values)):
test_cases.append({'estimator' : estimator,
for i, (lib, estimator, ext_geom, holes) in enumerate(product(*param_values)):
test_cases.append({'library' : lib,
'estimator' : estimator,
'external_geom' : ext_geom,
'holes' : holes,
'inputs_true' : 'inputs_true{}.dat'.format(i)})
@ -81,6 +80,20 @@ for i, (estimator, ext_geom, holes) in enumerate(product(*param_values)):
@pytest.mark.parametrize("test_opts", test_cases)
def test_unstructured_mesh(test_opts):
openmc.reset_auto_ids()
# skip the test if the library is not enabled
if test_opts['library'] == 'moab' and not openmc.lib._dagmc_enabled():
pytest.skip("DAGMC (and MOAB) mesh not enbaled in this build.")
if test_opts['library'] == 'libmesh' and not openmc.lib._libmesh_enabled():
pytest.skip("LibMesh is not enabled in this build.")
# skip the tracklength test for libmesh
if test_opts['library'] == 'libmesh' and \
test_opts['estimator'] == 'tracklength':
pytest.skip("Tracklength tallies are not supported using libmesh.")
### Materials ###
materials = openmc.Materials()
@ -176,7 +189,7 @@ def test_unstructured_mesh(test_opts):
### Tallies ###
# create meshes
# create meshes and mesh filters
regular_mesh = openmc.RegularMesh()
regular_mesh.dimension = (10, 10, 10)
regular_mesh.lower_left = (-10.0, -10.0, -10.0)
@ -185,12 +198,11 @@ def test_unstructured_mesh(test_opts):
regular_mesh_filter = openmc.MeshFilter(mesh=regular_mesh)
if test_opts['holes']:
mesh_filename = "test_mesh_tets_w_holes.h5m"
mesh_filename = "test_mesh_tets_w_holes.e"
else:
mesh_filename = "test_mesh_tets.h5m"
mesh_filename = "test_mesh_tets.e"
uscd_mesh = openmc.UnstructuredMesh(mesh_filename)
uscd_mesh.mesh_lib = 'moab'
uscd_mesh = openmc.UnstructuredMesh(mesh_filename, test_opts['library'])
uscd_filter = openmc.MeshFilter(mesh=uscd_mesh)
# create tallies
@ -211,7 +223,7 @@ def test_unstructured_mesh(test_opts):
### Settings ###
settings = openmc.Settings()
settings.run_mode = 'fixed source'
settings.particles = 100
settings.particles = 1000
settings.batches = 10
# source setup
@ -220,9 +232,8 @@ def test_unstructured_mesh(test_opts):
phi = openmc.stats.Discrete(x=[0.0], p=[1.0])
space = openmc.stats.SphericalIndependent(r, theta, phi)
angle = openmc.stats.Monodirectional((-1.0, 0.0, 0.0))
energy = openmc.stats.Discrete(x=[15.e+06], p=[1.0])
source = openmc.Source(space=space, energy=energy, angle=angle)
source = openmc.Source(space=space, energy=energy)
settings.source = source
model = openmc.model.Model(geometry=geometry,

View file

@ -0,0 +1 @@
test_mesh_tets.exo

View file

@ -0,0 +1 @@
test_mesh_tets_w_holes.exo

View file

@ -19,7 +19,7 @@ cd $HOME
mkdir MOAB && cd MOAB
git clone -b $MOAB_BRANCH $MOAB_REPO
mkdir build && cd build
cmake ../moab -DENABLE_HDF5=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=$MOAB_INSTALL_DIR -DENABLE_BLASLAPACK=OFF
cmake ../moab -DENABLE_HDF5=ON -DENABLE_NETCDF=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=$MOAB_INSTALL_DIR -DENABLE_BLASLAPACK=OFF
make -j && make -j install
rm -rf $HOME/MOAB/moab $HOME/MOAB/build

22
tools/ci/gha-install-libmesh.sh Executable file
View file

@ -0,0 +1,22 @@
#!/bin/bash
set -ex
# libMESH install
pushd $HOME
mkdir LIBMESH && cd LIBMESH
git clone https://github.com/libmesh/libmesh -b v1.6.0 --recurse-submodules
mkdir build && cd build
export METHODS="opt"
if [[ $MPI == 'y' ]]; then
../libmesh/configure --prefix=$HOME/LIBMESH CXX=mpicxx CC=mpicc FC=mpifort F77=mpif77 \
--enable-exodus --disable-netcdf-4 --disable-eigen --disable-lapack
else
../libmesh/configure --prefix=$HOME/LIBMESH --enable-exodus --disable-netcdf-4 --disable-eigen --disable-lapack --disable-mpi
fi
make -j4 install
export LIBMESH_PC=$HOME/LIBMESH/lib/pkgconfig/
rm -rf $HOME/LIBMESH/build
popd

View file

@ -19,7 +19,7 @@ def which(program):
return None
def install(omp=False, mpi=False, phdf5=False, dagmc=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')
@ -49,6 +49,11 @@ def install(omp=False, mpi=False, phdf5=False, dagmc=False):
cmake_cmd.append('-Ddagmc=ON')
cmake_cmd.append('-DCMAKE_PREFIX_PATH=~/DAGMC')
if libmesh:
cmake_cmd.append('-Dlibmesh=ON')
libmesh_path = os.environ.get('HOME') + '/LIBMESH'
cmake_cmd.append('-DCMAKE_PREFIX_PATH=' + libmesh_path)
# Build in coverage mode for coverage testing
cmake_cmd.append('-Dcoverage=on')
@ -65,9 +70,10 @@ def main():
mpi = (os.environ.get('MPI') == 'y')
phdf5 = (os.environ.get('PHDF5') == 'y')
dagmc = (os.environ.get('DAGMC') == 'y')
libmesh = (os.environ.get('LIBMESH') == 'y')
# Build and install
install(omp, mpi, phdf5, dagmc)
install(omp, mpi, phdf5, dagmc, libmesh)
if __name__ == '__main__':
main()

View file

@ -19,6 +19,11 @@ if [[ $VECTFIT = 'y' ]]; then
./tools/ci/gha-install-vectfit.sh
fi
# Install libMesh if needed
if [[ $LIBMESH = 'y' ]]; then
./tools/ci/gha-install-libmesh.sh
fi
# Install mpi4py for MPI configurations
if [[ $MPI == 'y' ]]; then
pip install --no-binary=mpi4py mpi4py