From 91ccc4da0051a3d1f75286bbc4c2305cd720867f Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Tue, 8 Aug 2017 18:10:53 -0400 Subject: [PATCH 01/74] Implement z planes and cylinders in C++ --- CMakeLists.txt | 5 +- src/geometry.F90 | 47 +++++++- src/input_xml.F90 | 9 ++ src/surface_header.C | 280 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 338 insertions(+), 3 deletions(-) create mode 100644 src/surface_header.C diff --git a/CMakeLists.txt b/CMakeLists.txt index c5150745b6..200d836fe1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -436,7 +436,10 @@ set(LIBOPENMC_FORTRAN_SRC ) set(LIBOPENMC_CXX_SRC src/random_lcg.h - src/random_lcg.cpp) + src/random_lcg.cpp + src/surface_header.C + src/pugixml/pugixml.hpp + src/pugixml/pugixml.cpp) add_library(libopenmc SHARED ${LIBOPENMC_FORTRAN_SRC} ${LIBOPENMC_CXX_SRC}) set_target_properties(libopenmc PROPERTIES OUTPUT_NAME openmc) add_executable(${program} src/main.F90) diff --git a/src/geometry.F90 b/src/geometry.F90 index ced62e6813..bc1eca2ae9 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -10,8 +10,33 @@ module geometry use stl_vector, only: VectorInt use string, only: to_str + use, intrinsic :: ISO_C_BINDING + implicit none + interface + function surface_sense_c(surf_ind, xyz, uvw) & + bind(C, name='surface_sense') result(sense) + use ISO_C_BINDING + implicit none + integer(C_INT), value :: surf_ind; + real(C_DOUBLE) :: xyz(3); + real(C_DOUBLE) :: uvw(3); + logical(C_BOOL) :: sense; + end function surface_sense_c + + function surface_distance_c(surf_ind, xyz, uvw, coincident) & + bind(C, name='surface_distance') result(d) + use ISO_C_BINDING + implicit none + integer(C_INT), value :: surf_ind; + real(C_DOUBLE) :: xyz(3); + real(C_DOUBLE) :: uvw(3); + logical(C_BOOL), value :: coincident; + real(C_DOUBLE) :: d; + end function surface_distance_c + end interface + contains !=============================================================================== @@ -28,7 +53,8 @@ contains ! expression using a stack, similar to how a RPN calculator would work. !=============================================================================== - pure function cell_contains(c, p) result(in_cell) + !pure function cell_contains(c, p) result(in_cell) + function cell_contains(c, p) result(in_cell) type(Cell), intent(in) :: c type(Particle), intent(in) :: p logical :: in_cell @@ -40,7 +66,8 @@ contains end if end function cell_contains - pure function simple_cell_contains(c, p) result(in_cell) + !pure function simple_cell_contains(c, p) result(in_cell) + function simple_cell_contains(c, p) result(in_cell) type(Cell), intent(in) :: c type(Particle), intent(in) :: p logical :: in_cell @@ -48,6 +75,7 @@ contains integer :: i integer :: token logical :: actual_sense ! sense of particle wrt surface + logical :: alt_sense in_cell = .true. do i = 1, size(c%rpn) @@ -65,6 +93,15 @@ contains else actual_sense = surfaces(abs(token))%obj%sense(& p%coord(p%n_coord)%xyz, p%coord(p%n_coord)%uvw) + alt_sense = surface_sense_c(abs(token)-1, & + p%coord(p%n_coord)%xyz, p%coord(p%n_coord)%uvw) + if (actual_sense .neqv. alt_sense) then + write(*, *) surfaces(abs(token)) % obj % id + write(*, *) p % coord (p % n_coord) % xyz + write(*, *) p % coord (p % n_coord) % uvw + write(*, *) actual_sense, alt_sense + call fatal_error("") + end if if (actual_sense .neqv. (token > 0)) then in_cell = .false. exit @@ -484,6 +521,7 @@ contains type(Cell), pointer :: c class(Surface), pointer :: surf class(Lattice), pointer :: lat + real(8) :: d_alt ! inialize distance to infinity (huge) dist = INFINITY @@ -519,6 +557,11 @@ contains ! Calculate distance to surface surf => surfaces(index_surf) % obj d = surf % distance(p % coord(j) % xyz, p % coord(j) % uvw, coincident) + d_alt = surface_distance_c(index_surf-1, p % coord(j) % xyz, & + p % coord(j) % uvw, logical(coincident, kind=C_BOOL)) + if (d /= d_alt) then + write(*, *) d, d_alt + end if ! Check if calculated distance is new minimum if (d < d_surf) then diff --git a/src/input_xml.F90 b/src/input_xml.F90 index bd56422cb5..4994ff76bc 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -48,6 +48,14 @@ module input_xml implicit none save + interface + subroutine read_surfaces(node_ptr) bind(C, name='read_surfaces') + use ISO_C_BINDING + implicit none + type(C_PTR) :: node_ptr + end subroutine read_surfaces + end interface + contains !=============================================================================== @@ -966,6 +974,7 @@ contains ! get pointer to list of xml call get_node_list(root, "surface", node_surf_list) + call read_surfaces(root % ptr) ! Get number of tags n_surfaces = size(node_surf_list) diff --git a/src/surface_header.C b/src/surface_header.C new file mode 100644 index 0000000000..08287da88a --- /dev/null +++ b/src/surface_header.C @@ -0,0 +1,280 @@ +#include // For strcmp +#include +#include // For numeric_limits +#include // For fabs +#include "pugixml/pugixml.hpp" + +//============================================================================== +// Constants +//============================================================================== + +const double FP_COINCIDENT = 1e-12; +const double INFTY = std::numeric_limits::max(); + +//============================================================================== +// Global array of surfaces +//============================================================================== + +class Surface; +Surface **surfaces_c; + +//============================================================================== +// SURFACE type defines a first- or second-order surface that can be used to +// construct closed volumes (cells) +//============================================================================== + +class Surface +{ + int id; // Unique ID + int neighbor_pos[], // List of cells on positive side + neighbor_neg[]; // List of cells on negative side + int bc; // Boundary condition + //TODO: swith that zero to a NONE constant. + int i_periodic = 0; // Index of corresponding periodic surface + char name[104]; // User-defined name + +public: + bool sense(double xyz[3], double uvw[3]); + void reflect(double xyz[3], double uvw[3]); + virtual double evaluate(double xyz[3]) = 0; + virtual double distance(double xyz[3], double uvw[3], bool coincident) = 0; + virtual void normal(double xyz[3], double uvw[3]) = 0; +}; + +bool +Surface::sense(double xyz[3], double uvw[3]) +{ + // Evaluate the surface equation at the particle's coordinates to determine + // which side the particle is on. + const double f = evaluate(xyz); + + // Check which side of surface the point is on. + bool s; + if (fabs(f) < FP_COINCIDENT) + { + // Particle may be coincident with this surface. To determine the sense, we + // look at the direction of the particle relative to the surface normal (by + // default in the positive direction) via their dot product. + double norm[3]; + normal(xyz, norm); + s = (uvw[0] * norm[0] + uvw[1] * norm[1] + uvw[2] * norm[2] > 0.0); + } + else + { + s = (f > 0.0); + } + return s; +} + +void +Surface::reflect(double xyz[3], double uvw[3]) +{ + + // Determine projection of direction onto normal and squared magnitude of + // normal. + double norm[3]; + normal(xyz, norm); + const double projection = norm[0]*uvw[0] + norm[1]*uvw[1] + norm[2]*uvw[2]; + const double magnitude = norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]; + + // Reflect direction according to normal. + uvw[0] -= 2.0 * projection / magnitude * norm[0]; + uvw[1] -= 2.0 * projection / magnitude * norm[1]; + uvw[2] -= 2.0 * projection / magnitude * norm[2]; +} + +//============================================================================== + +class SurfaceZPlane : public Surface +{ + double z0; +public: + SurfaceZPlane(pugi::xml_node surf_node); + double evaluate(double xyz[3]); + double distance(double xyz[3], double uvw[3], bool coincident); + void normal(double xyz[3], double uvw[3]); +}; + +SurfaceZPlane::SurfaceZPlane(pugi::xml_node surf_node) +{ + const char *coeffs = surf_node.attribute("coeffs").value(); + int stat = sscanf(coeffs, "%lf", &z0); + if (stat != 1) + { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +double +SurfaceZPlane::evaluate(double xyz[3]) +{ + double f = xyz[2] - z0; + return f; +} + +double +SurfaceZPlane::distance(double xyz[3], double uvw[3], bool coincident) +{ + double f = z0 - xyz[2]; + double d; + if (coincident or fabs(f) < FP_COINCIDENT or uvw[2] == 0.0) + { + d = INFTY; + } + else + { + d = f / uvw[2]; + if (d < 0.0) d = INFTY; + } + return d; +} + +void +SurfaceZPlane::normal(double xyz[3], double uvw[3]) +{ + uvw[0] = 0.0; + uvw[1] = 0.0; + uvw[2] = 1.0; +} + +//============================================================================== + +class SurfaceZCylinder : public Surface +{ + double x0, y0, r; +public: + SurfaceZCylinder(pugi::xml_node surf_node); + double evaluate(double xyz[3]); + double distance(double xyz[3], double uvw[3], bool coincident); + void normal(double xyz[3], double uvw[3]); +}; + +SurfaceZCylinder::SurfaceZCylinder(pugi::xml_node surf_node) +{ + const char *coeffs = surf_node.attribute("coeffs").value(); + int stat = sscanf(coeffs, "%lf %lf %lf", &x0, &y0, &r); + if (stat != 3) + { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +double +SurfaceZCylinder::evaluate(double xyz[3]) +{ + const double x = xyz[0] - x0; + const double y = xyz[1] - y0; + double f = x*x + y*y - r*r; + return f; +} + +double +SurfaceZCylinder::distance(double xyz[3], double uvw[3], bool coincident) +{ + double a = 1.0 - uvw[2]*uvw[2]; // u^2 + v^2 + + if (a == 0.0) return INFTY; + + double x = xyz[0] - x0; + double y = xyz[1] - y0; + double k = x*uvw[0] + y*uvw[1]; + double c = x*x + y*y - r*r; + double quad = k*k - a*c; + + if (quad < 0.0) + { + // No intersection with cylinder. + return INFTY; + } + else if (coincident or fabs(c) < FP_COINCIDENT) + { + // Particle is on the cylinder, thus one distance is positive/negative + // and the other is zero. The sign of k determines if we are facing in or + // out. + if (k >= 0.0) return INFTY; + else return (-k + sqrt(quad)) / a; + } + else if (c < 0.0) + { + // Particle is inside the cylinder, thus one distance must be negative + // and one must be positive. The positive distance will be the one with + // negative sign on sqrt(quad) + return (-k + sqrt(quad)) / a; + } + else + { + // Particle is outside the cylinder, thus both distances are either + // positive or negative. If positive, the smaller distance is the one + // with positive sign on sqrt(quad) + + double d = (-k - sqrt(quad)) / a; + if (d < 0.0) return INFTY; + return d; + } +} + +void +SurfaceZCylinder::normal(double xyz[3], double uvw[3]) +{ + uvw[0] = 2.0 * (xyz[0] - x0); + uvw[1] = 2.0 * (xyz[1] - y0); + uvw[2] = 0.0; +} + +//============================================================================== + +extern "C" void +read_surfaces(pugi::xml_node *node) +{ + // Count the number of surfaces. + int n_surfaces = 0; + for (pugi::xml_node surf_node = node->child("surface"); surf_node; + surf_node = surf_node.next_sibling("surface")) + { + n_surfaces += 1; + } + + // Allocate the array of Surface pointers. + surfaces_c = new Surface* [n_surfaces]; + + // Loop over XML surface elements and populate the array. + { + pugi::xml_node surf_node; + int i_surf; + for (surf_node = node->child("surface"), i_surf = 0; surf_node; + surf_node = surf_node.next_sibling("surface"), i_surf++) + { + if (surf_node.attribute("type")) + { + const pugi::char_t *surf_type = surf_node.attribute("type").value(); + if (strcmp(surf_type, "z-cylinder") == 0) + { + surfaces_c[i_surf] = new SurfaceZCylinder(surf_node); + } + else if (strcmp(surf_type, "z-plane") == 0) + { + surfaces_c[i_surf] = new SurfaceZPlane(surf_node); + } + else + { + std::cout << "Call error or handle uppercase here!" << std::endl; + std::cout << surf_type << std::endl; + } + } + } + } +} + +//============================================================================== + +extern "C" bool +surface_sense(int surf_ind, double xyz[3], double uvw[3]) +{ + return surfaces_c[surf_ind]->sense(xyz, uvw); +} + +extern "C" double +surface_distance(int surf_ind, double xyz[3], double uvw[3], bool coincident) +{ + return surfaces_c[surf_ind]->distance(xyz, uvw, coincident); +} From c5708e6932b37f34a29274dbc6c98a34e74c66cf Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Thu, 18 Jan 2018 21:16:50 -0500 Subject: [PATCH 02/74] Move brackets to match proposed C++ styleguide --- src/surface_header.C | 90 +++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 60 deletions(-) diff --git a/src/surface_header.C b/src/surface_header.C index 08287da88a..34ac7cf336 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -23,8 +23,7 @@ Surface **surfaces_c; // construct closed volumes (cells) //============================================================================== -class Surface -{ +class Surface { int id; // Unique ID int neighbor_pos[], // List of cells on positive side neighbor_neg[]; // List of cells on negative side @@ -42,34 +41,28 @@ public: }; bool -Surface::sense(double xyz[3], double uvw[3]) -{ +Surface::sense(double xyz[3], double uvw[3]) { // Evaluate the surface equation at the particle's coordinates to determine // which side the particle is on. const double f = evaluate(xyz); // Check which side of surface the point is on. bool s; - if (fabs(f) < FP_COINCIDENT) - { + if (fabs(f) < FP_COINCIDENT) { // Particle may be coincident with this surface. To determine the sense, we // look at the direction of the particle relative to the surface normal (by // default in the positive direction) via their dot product. double norm[3]; normal(xyz, norm); s = (uvw[0] * norm[0] + uvw[1] * norm[1] + uvw[2] * norm[2] > 0.0); - } - else - { + } else { s = (f > 0.0); } return s; } void -Surface::reflect(double xyz[3], double uvw[3]) -{ - +Surface::reflect(double xyz[3], double uvw[3]) { // Determine projection of direction onto normal and squared magnitude of // normal. double norm[3]; @@ -85,8 +78,7 @@ Surface::reflect(double xyz[3], double uvw[3]) //============================================================================== -class SurfaceZPlane : public Surface -{ +class SurfaceZPlane : public Surface { double z0; public: SurfaceZPlane(pugi::xml_node surf_node); @@ -95,26 +87,22 @@ public: void normal(double xyz[3], double uvw[3]); }; -SurfaceZPlane::SurfaceZPlane(pugi::xml_node surf_node) -{ +SurfaceZPlane::SurfaceZPlane(pugi::xml_node surf_node) { const char *coeffs = surf_node.attribute("coeffs").value(); int stat = sscanf(coeffs, "%lf", &z0); - if (stat != 1) - { + if (stat != 1) { std::cout << "Something went wrong reading surface coeffs!" << std::endl; } } double -SurfaceZPlane::evaluate(double xyz[3]) -{ +SurfaceZPlane::evaluate(double xyz[3]) { double f = xyz[2] - z0; return f; } double -SurfaceZPlane::distance(double xyz[3], double uvw[3], bool coincident) -{ +SurfaceZPlane::distance(double xyz[3], double uvw[3], bool coincident) { double f = z0 - xyz[2]; double d; if (coincident or fabs(f) < FP_COINCIDENT or uvw[2] == 0.0) @@ -130,8 +118,7 @@ SurfaceZPlane::distance(double xyz[3], double uvw[3], bool coincident) } void -SurfaceZPlane::normal(double xyz[3], double uvw[3]) -{ +SurfaceZPlane::normal(double xyz[3], double uvw[3]) { uvw[0] = 0.0; uvw[1] = 0.0; uvw[2] = 1.0; @@ -139,8 +126,7 @@ SurfaceZPlane::normal(double xyz[3], double uvw[3]) //============================================================================== -class SurfaceZCylinder : public Surface -{ +class SurfaceZCylinder : public Surface { double x0, y0, r; public: SurfaceZCylinder(pugi::xml_node surf_node); @@ -149,19 +135,16 @@ public: void normal(double xyz[3], double uvw[3]); }; -SurfaceZCylinder::SurfaceZCylinder(pugi::xml_node surf_node) -{ +SurfaceZCylinder::SurfaceZCylinder(pugi::xml_node surf_node) { const char *coeffs = surf_node.attribute("coeffs").value(); int stat = sscanf(coeffs, "%lf %lf %lf", &x0, &y0, &r); - if (stat != 3) - { + if (stat != 3) { std::cout << "Something went wrong reading surface coeffs!" << std::endl; } } double -SurfaceZCylinder::evaluate(double xyz[3]) -{ +SurfaceZCylinder::evaluate(double xyz[3]) { const double x = xyz[0] - x0; const double y = xyz[1] - y0; double f = x*x + y*y - r*r; @@ -169,8 +152,7 @@ SurfaceZCylinder::evaluate(double xyz[3]) } double -SurfaceZCylinder::distance(double xyz[3], double uvw[3], bool coincident) -{ +SurfaceZCylinder::distance(double xyz[3], double uvw[3], bool coincident) { double a = 1.0 - uvw[2]*uvw[2]; // u^2 + v^2 if (a == 0.0) return INFTY; @@ -181,32 +163,27 @@ SurfaceZCylinder::distance(double xyz[3], double uvw[3], bool coincident) double c = x*x + y*y - r*r; double quad = k*k - a*c; - if (quad < 0.0) - { + if (quad < 0.0) { // No intersection with cylinder. return INFTY; - } - else if (coincident or fabs(c) < FP_COINCIDENT) - { + + } else if (coincident or fabs(c) < FP_COINCIDENT) { // Particle is on the cylinder, thus one distance is positive/negative // and the other is zero. The sign of k determines if we are facing in or // out. if (k >= 0.0) return INFTY; else return (-k + sqrt(quad)) / a; - } - else if (c < 0.0) - { + + } else if (c < 0.0) { // Particle is inside the cylinder, thus one distance must be negative // and one must be positive. The positive distance will be the one with // negative sign on sqrt(quad) return (-k + sqrt(quad)) / a; - } - else - { + + } else { // Particle is outside the cylinder, thus both distances are either // positive or negative. If positive, the smaller distance is the one // with positive sign on sqrt(quad) - double d = (-k - sqrt(quad)) / a; if (d < 0.0) return INFTY; return d; @@ -214,8 +191,7 @@ SurfaceZCylinder::distance(double xyz[3], double uvw[3], bool coincident) } void -SurfaceZCylinder::normal(double xyz[3], double uvw[3]) -{ +SurfaceZCylinder::normal(double xyz[3], double uvw[3]) { uvw[0] = 2.0 * (xyz[0] - x0); uvw[1] = 2.0 * (xyz[1] - y0); uvw[2] = 0.0; @@ -224,13 +200,11 @@ SurfaceZCylinder::normal(double xyz[3], double uvw[3]) //============================================================================== extern "C" void -read_surfaces(pugi::xml_node *node) -{ +read_surfaces(pugi::xml_node *node) { // Count the number of surfaces. int n_surfaces = 0; for (pugi::xml_node surf_node = node->child("surface"); surf_node; - surf_node = surf_node.next_sibling("surface")) - { + surf_node = surf_node.next_sibling("surface")) { n_surfaces += 1; } @@ -242,10 +216,8 @@ read_surfaces(pugi::xml_node *node) pugi::xml_node surf_node; int i_surf; for (surf_node = node->child("surface"), i_surf = 0; surf_node; - surf_node = surf_node.next_sibling("surface"), i_surf++) - { - if (surf_node.attribute("type")) - { + surf_node = surf_node.next_sibling("surface"), i_surf++) { + if (surf_node.attribute("type")) { const pugi::char_t *surf_type = surf_node.attribute("type").value(); if (strcmp(surf_type, "z-cylinder") == 0) { @@ -268,13 +240,11 @@ read_surfaces(pugi::xml_node *node) //============================================================================== extern "C" bool -surface_sense(int surf_ind, double xyz[3], double uvw[3]) -{ +surface_sense(int surf_ind, double xyz[3], double uvw[3]) { return surfaces_c[surf_ind]->sense(xyz, uvw); } extern "C" double -surface_distance(int surf_ind, double xyz[3], double uvw[3], bool coincident) -{ +surface_distance(int surf_ind, double xyz[3], double uvw[3], bool coincident) { return surfaces_c[surf_ind]->distance(xyz, uvw, coincident); } From 4cd335f6a93b21d5010e9f9981093a05a5d8435e Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 11 Aug 2017 22:05:33 -0400 Subject: [PATCH 03/74] Add x-, y- planes and cylinders to C++ Introudce templated generic functions to reduce code repetition for surfaces --- src/surface_header.C | 358 +++++++++++++++++++++++++++++++++---------- 1 file changed, 276 insertions(+), 82 deletions(-) diff --git a/src/surface_header.C b/src/surface_header.C index 34ac7cf336..f62be77ab3 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -33,36 +33,34 @@ class Surface { char name[104]; // User-defined name public: - bool sense(double xyz[3], double uvw[3]); - void reflect(double xyz[3], double uvw[3]); - virtual double evaluate(double xyz[3]) = 0; - virtual double distance(double xyz[3], double uvw[3], bool coincident) = 0; - virtual void normal(double xyz[3], double uvw[3]) = 0; + bool sense(const double xyz[3], const double uvw[3]) const; + void reflect(const double xyz[3], double uvw[3]) const; + virtual double evaluate(const double xyz[3]) const = 0; + virtual double distance(const double xyz[3], const double uvw[3], + bool coincident) const = 0; + virtual void normal(const double xyz[3], double uvw[3]) const = 0; }; bool -Surface::sense(double xyz[3], double uvw[3]) { +Surface::sense(const double xyz[3], const double uvw[3]) const { // Evaluate the surface equation at the particle's coordinates to determine // which side the particle is on. const double f = evaluate(xyz); // Check which side of surface the point is on. - bool s; if (fabs(f) < FP_COINCIDENT) { // Particle may be coincident with this surface. To determine the sense, we // look at the direction of the particle relative to the surface normal (by // default in the positive direction) via their dot product. double norm[3]; normal(xyz, norm); - s = (uvw[0] * norm[0] + uvw[1] * norm[1] + uvw[2] * norm[2] > 0.0); - } else { - s = (f > 0.0); + return uvw[0] * norm[0] + uvw[1] * norm[1] + uvw[2] * norm[2] > 0.0; } - return s; + return f > 0.0; } void -Surface::reflect(double xyz[3], double uvw[3]) { +Surface::reflect(const double xyz[3], double uvw[3]) const { // Determine projection of direction onto normal and squared magnitude of // normal. double norm[3]; @@ -76,15 +74,113 @@ Surface::reflect(double xyz[3], double uvw[3]) { uvw[2] -= 2.0 * projection / magnitude * norm[2]; } +//============================================================================== +// Generic functions for X-, Y-, and Z-, planes +//============================================================================== + +template double +axis_aligned_plane_evaluate(const double xyz[3], double offset) { + return xyz[i] - offset;} + +template double +axis_aligned_plane_distance(const double xyz[3], const double uvw[3], + bool coincident, double offset) { + const double f = offset - xyz[i]; + if (coincident or fabs(f) < FP_COINCIDENT or uvw[i] == 0.0) return INFTY; + const double d = f / uvw[i]; + if (d < 0.0) return INFTY; + return d; +} + +template void +axis_aligned_plane_normal(const double xyz[3], double uvw[3]) { + uvw[i1] = 1.0; + uvw[i2] = 0.0; + uvw[i3] = 0.0; +} + +//============================================================================== +// SurfaceXPlane +//============================================================================== + +class SurfaceXPlane : public Surface { + double x0; +public: + SurfaceXPlane(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + const bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; +}; + +SurfaceXPlane::SurfaceXPlane(pugi::xml_node surf_node) { + const char *coeffs = surf_node.attribute("coeffs").value(); + int stat = sscanf(coeffs, "%lf", &x0); + if (stat != 1) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +inline double SurfaceXPlane::evaluate(const double xyz[3]) const { + return axis_aligned_plane_evaluate<0>(xyz, x0); +} + +inline double SurfaceXPlane::distance(const double xyz[3], const double uvw[3], + bool coincident) const { + return axis_aligned_plane_distance<0>(xyz, uvw, coincident, x0); +} + +inline void SurfaceXPlane::normal(const double xyz[3], double uvw[3]) const { + axis_aligned_plane_normal<0, 1, 2>(xyz, uvw); +} + +//============================================================================== +// SurfaceYPlane +//============================================================================== + +class SurfaceYPlane : public Surface { + double y0; +public: + SurfaceYPlane(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; +}; + +SurfaceYPlane::SurfaceYPlane(pugi::xml_node surf_node) { + const char *coeffs = surf_node.attribute("coeffs").value(); + int stat = sscanf(coeffs, "%lf", &y0); + if (stat != 1) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +inline double SurfaceYPlane::evaluate(const double xyz[3]) const { + return axis_aligned_plane_evaluate<1>(xyz, y0); +} + +inline double SurfaceYPlane::distance(const double xyz[3], const double uvw[3], + bool coincident) const { + return axis_aligned_plane_distance<1>(xyz, uvw, coincident, y0); +} + +inline void SurfaceYPlane::normal(const double xyz[3], double uvw[3]) const { + axis_aligned_plane_normal<1, 0, 2>(xyz, uvw); +} + +//============================================================================== +// SurfaceZPlane //============================================================================== class SurfaceZPlane : public Surface { double z0; public: SurfaceZPlane(pugi::xml_node surf_node); - double evaluate(double xyz[3]); - double distance(double xyz[3], double uvw[3], bool coincident); - void normal(double xyz[3], double uvw[3]); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; }; SurfaceZPlane::SurfaceZPlane(pugi::xml_node surf_node) { @@ -95,73 +191,49 @@ SurfaceZPlane::SurfaceZPlane(pugi::xml_node surf_node) { } } -double -SurfaceZPlane::evaluate(double xyz[3]) { - double f = xyz[2] - z0; - return f; +inline double SurfaceZPlane::evaluate(const double xyz[3]) const { + return axis_aligned_plane_evaluate<2>(xyz, z0); } -double -SurfaceZPlane::distance(double xyz[3], double uvw[3], bool coincident) { - double f = z0 - xyz[2]; - double d; - if (coincident or fabs(f) < FP_COINCIDENT or uvw[2] == 0.0) - { - d = INFTY; - } - else - { - d = f / uvw[2]; - if (d < 0.0) d = INFTY; - } - return d; +inline double SurfaceZPlane::distance(const double xyz[3], const double uvw[3], + bool coincident) const { + return axis_aligned_plane_distance<2>(xyz, uvw, coincident, z0); } -void -SurfaceZPlane::normal(double xyz[3], double uvw[3]) { - uvw[0] = 0.0; - uvw[1] = 0.0; - uvw[2] = 1.0; +inline void SurfaceZPlane::normal(const double xyz[3], double uvw[3]) const { + axis_aligned_plane_normal<2, 0, 1>(xyz, uvw); } +//============================================================================== +// SurfacePlane //============================================================================== -class SurfaceZCylinder : public Surface { - double x0, y0, r; -public: - SurfaceZCylinder(pugi::xml_node surf_node); - double evaluate(double xyz[3]); - double distance(double xyz[3], double uvw[3], bool coincident); - void normal(double xyz[3], double uvw[3]); -}; +// TODO -SurfaceZCylinder::SurfaceZCylinder(pugi::xml_node surf_node) { - const char *coeffs = surf_node.attribute("coeffs").value(); - int stat = sscanf(coeffs, "%lf %lf %lf", &x0, &y0, &r); - if (stat != 3) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; - } +//============================================================================== +// Generic functions for X-, Y-, and Z-, cylinders +//============================================================================== + +template double +axis_aligned_cylinder_evaluate(const double xyz[3], double offset1, + double offset2, double radius) { + const double xyz1 = xyz[i1] - offset1; + const double xyz2 = xyz[i2] - offset2; + return xyz1*xyz1 + xyz2*xyz2 - radius*radius; } -double -SurfaceZCylinder::evaluate(double xyz[3]) { - const double x = xyz[0] - x0; - const double y = xyz[1] - y0; - double f = x*x + y*y - r*r; - return f; -} - -double -SurfaceZCylinder::distance(double xyz[3], double uvw[3], bool coincident) { - double a = 1.0 - uvw[2]*uvw[2]; // u^2 + v^2 +template double +axis_aligned_cylinder_distance(const double xyz[3], const double uvw[3], + double offset1, double offset2, double radius, bool coincident) { + const double a = 1.0 - uvw[i1]*uvw[i1]; // u^2 + v^2 if (a == 0.0) return INFTY; - double x = xyz[0] - x0; - double y = xyz[1] - y0; - double k = x*uvw[0] + y*uvw[1]; - double c = x*x + y*y - r*r; - double quad = k*k - a*c; + const double xyz2 = xyz[i2] - offset1; + const double xyz3 = xyz[i3] - offset2; + const double k = xyz2 * uvw[i2] + xyz3 * uvw[i3]; + const double c = xyz2*xyz2 + xyz3*xyz3 - radius*radius; + const double quad = k*k - a*c; if (quad < 0.0) { // No intersection with cylinder. @@ -190,11 +262,123 @@ SurfaceZCylinder::distance(double xyz[3], double uvw[3], bool coincident) { } } -void -SurfaceZCylinder::normal(double xyz[3], double uvw[3]) { - uvw[0] = 2.0 * (xyz[0] - x0); - uvw[1] = 2.0 * (xyz[1] - y0); - uvw[2] = 0.0; +template void +axis_aligned_cylinder_normal(const double xyz[3], double uvw[3], double offset1, + double offset2) { + uvw[i2] = 2.0 * (xyz[i2] - offset1); + uvw[i3] = 2.0 * (xyz[i3] - offset2); + uvw[i1] = 0.0; +} + +//============================================================================== +// SurfaceXCylinder +//============================================================================== + +class SurfaceXCylinder : public Surface { + double y0, z0, r; +public: + SurfaceXCylinder(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; +}; + +SurfaceXCylinder::SurfaceXCylinder(pugi::xml_node surf_node) { + const char *coeffs = surf_node.attribute("coeffs").value(); + int stat = sscanf(coeffs, "%lf %lf %lf", &y0, &z0, &r); + if (stat != 3) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +inline double +SurfaceXCylinder::evaluate(const double xyz[3]) const { + return axis_aligned_cylinder_evaluate<1, 2>(xyz, y0, z0, r); +} + +inline double SurfaceXCylinder::distance(const double xyz[3], + const double uvw[3], bool coincident) const { + return axis_aligned_cylinder_distance<0, 1, 2>(xyz, uvw, coincident, y0, z0, + r); +} + +inline void SurfaceXCylinder::normal(const double xyz[3], double uvw[3]) const { + axis_aligned_cylinder_normal<0, 1, 2>(xyz, uvw, y0, z0); +} + +//============================================================================== +// SurfaceYCylinder +//============================================================================== + +class SurfaceYCylinder : public Surface { + double x0, z0, r; +public: + SurfaceYCylinder(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; +}; + +SurfaceYCylinder::SurfaceYCylinder(pugi::xml_node surf_node) { + const char *coeffs = surf_node.attribute("coeffs").value(); + int stat = sscanf(coeffs, "%lf %lf %lf", &x0, &z0, &r); + if (stat != 3) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +inline double +SurfaceYCylinder::evaluate(const double xyz[3]) const { + return axis_aligned_cylinder_evaluate<0, 2>(xyz, x0, z0, r); +} + +inline double SurfaceYCylinder::distance(const double xyz[3], + const double uvw[3], bool coincident) const { + return axis_aligned_cylinder_distance<1, 0, 2>(xyz, uvw, coincident, x0, z0, + r); +} + +inline void SurfaceYCylinder::normal(const double xyz[3], double uvw[3]) const { + axis_aligned_cylinder_normal<1, 0, 2>(xyz, uvw, x0, z0); +} + +//============================================================================== +// SurfaceZCylinder +//============================================================================== + +class SurfaceZCylinder : public Surface { + double x0, y0, r; +public: + SurfaceZCylinder(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; +}; + +SurfaceZCylinder::SurfaceZCylinder(pugi::xml_node surf_node) { + const char *coeffs = surf_node.attribute("coeffs").value(); + int stat = sscanf(coeffs, "%lf %lf %lf", &x0, &y0, &r); + if (stat != 3) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +inline double +SurfaceZCylinder::evaluate(const double xyz[3]) const { + return axis_aligned_cylinder_evaluate<0, 1>(xyz, x0, y0, r); +} + +inline double SurfaceZCylinder::distance(const double xyz[3], + const double uvw[3], bool coincident) const { + return axis_aligned_cylinder_distance<2, 0, 1>(xyz, uvw, coincident, x0, y0, + r); +} + +inline void SurfaceZCylinder::normal(const double xyz[3], double uvw[3]) const { + axis_aligned_cylinder_normal<2, 0, 1>(xyz, uvw, x0, y0); } //============================================================================== @@ -219,16 +403,26 @@ read_surfaces(pugi::xml_node *node) { surf_node = surf_node.next_sibling("surface"), i_surf++) { if (surf_node.attribute("type")) { const pugi::char_t *surf_type = surf_node.attribute("type").value(); - if (strcmp(surf_type, "z-cylinder") == 0) - { - surfaces_c[i_surf] = new SurfaceZCylinder(surf_node); - } - else if (strcmp(surf_type, "z-plane") == 0) - { + + if (strcmp(surf_type, "x-plane") == 0) { + surfaces_c[i_surf] = new SurfaceXPlane(surf_node); + + } else if (strcmp(surf_type, "y-plane") == 0) { + surfaces_c[i_surf] = new SurfaceYPlane(surf_node); + + } else if (strcmp(surf_type, "z-plane") == 0) { surfaces_c[i_surf] = new SurfaceZPlane(surf_node); - } - else - { + + } else if (strcmp(surf_type, "x-cylinder") == 0) { + surfaces_c[i_surf] = new SurfaceXCylinder(surf_node); + + } else if (strcmp(surf_type, "y-cylinder") == 0) { + surfaces_c[i_surf] = new SurfaceYCylinder(surf_node); + + } else if (strcmp(surf_type, "z-cylinder") == 0) { + surfaces_c[i_surf] = new SurfaceZCylinder(surf_node); + + } else { std::cout << "Call error or handle uppercase here!" << std::endl; std::cout << surf_type << std::endl; } From 303ee3486e001e7ea3452775fc4ee142022b7320 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 11 Aug 2017 22:38:38 -0400 Subject: [PATCH 04/74] Add SurfaceSphere to C++ --- src/surface_header.C | 113 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 108 insertions(+), 5 deletions(-) diff --git a/src/surface_header.C b/src/surface_header.C index f62be77ab3..42fb948af1 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -243,20 +243,23 @@ axis_aligned_cylinder_distance(const double xyz[3], const double uvw[3], // Particle is on the cylinder, thus one distance is positive/negative // and the other is zero. The sign of k determines if we are facing in or // out. - if (k >= 0.0) return INFTY; - else return (-k + sqrt(quad)) / a; + if (k >= 0.0) { + return INFTY; + } else { + return (-k + sqrt(quad)) / a; + } } else if (c < 0.0) { // Particle is inside the cylinder, thus one distance must be negative // and one must be positive. The positive distance will be the one with - // negative sign on sqrt(quad) + // negative sign on sqrt(quad). return (-k + sqrt(quad)) / a; } else { // Particle is outside the cylinder, thus both distances are either // positive or negative. If positive, the smaller distance is the one - // with positive sign on sqrt(quad) - double d = (-k - sqrt(quad)) / a; + // with positive sign on sqrt(quad). + const double d = (-k - sqrt(quad)) / a; if (d < 0.0) return INFTY; return d; } @@ -381,6 +384,103 @@ inline void SurfaceZCylinder::normal(const double xyz[3], double uvw[3]) const { axis_aligned_cylinder_normal<2, 0, 1>(xyz, uvw, x0, y0); } +//============================================================================== +// SurfaceSphere +//============================================================================== + +class SurfaceSphere : public Surface { + double x0, y0, z0, r; +public: + SurfaceSphere(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; +}; + +SurfaceSphere::SurfaceSphere(pugi::xml_node surf_node) { + const char *coeffs = surf_node.attribute("coeffs").value(); + int stat = sscanf(coeffs, "%lf %lf %lf %lf", &x0, &y0, &z0, &r); + if (stat != 4) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +double SurfaceSphere::evaluate(const double xyz[3]) const { + const double x = xyz[0] - x0; + const double y = xyz[1] - y0; + const double z = xyz[2] - z0; + return x*x + y*y + z*z - r*r; +} + +double SurfaceSphere::distance(const double xyz[3], const double uvw[3], + bool coincident) const { + const double x = xyz[0] - x0; + const double y = xyz[1] - y0; + const double z = xyz[2] - z0; + const double k = x*uvw[0] + y*uvw[1] + z*uvw[2]; + const double c = x*x + y*y + z*z - r*r; + const double quad = k*k - c; + + if (quad < 0.0) { + // No intersection with sphere. + return INFTY; + + } else if (coincident or fabs(c) < FP_COINCIDENT) { + // Particle is on the sphere, thus one distance is positive/negative and + // the other is zero. The sign of k determines if we are facing in or out. + if (k >= 0.0) { + return INFTY; + } else { + return -k + sqrt(quad); + } + + } else if (c < 0.0) { + // Particle is inside the sphere, thus one distance must be negative and + // one must be positive. The positive distance will be the one with + // negative sign on sqrt(quad) + return -k + sqrt(quad); + + } else { + // Particle is outside the sphere, thus both distances are either positive + // or negative. If positive, the smaller distance is the one with positive + // sign on sqrt(quad). + const double d = -k - sqrt(quad); + if (d < 0.0) return INFTY; + return d; + } +} + +inline void SurfaceSphere::normal(const double xyz[3], double uvw[3]) const { + uvw[0] = 2.0 * (xyz[0] - x0); + uvw[1] = 2.0 * (xyz[1] - y0); + uvw[2] = 2.0 * (xyz[2] - z0); +} + +//============================================================================== +// SurfaceXCone +//============================================================================== + +// TODO + +//============================================================================== +// SurfaceYCone +//============================================================================== + +// TODO + +//============================================================================== +// SurfaceZCone +//============================================================================== + +// TODO + +//============================================================================== +// SurfaceQuadric +//============================================================================== + +// TODO + //============================================================================== extern "C" void @@ -422,6 +522,9 @@ read_surfaces(pugi::xml_node *node) { } else if (strcmp(surf_type, "z-cylinder") == 0) { surfaces_c[i_surf] = new SurfaceZCylinder(surf_node); + } else if (strcmp(surf_type, "sphere") == 0) { + surfaces_c[i_surf] = new SurfaceSphere(surf_node); + } else { std::cout << "Call error or handle uppercase here!" << std::endl; std::cout << surf_type << std::endl; From 2d0938284b28db1e007797c2ad5368404d2fd6f2 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sat, 12 Aug 2017 17:29:44 -0400 Subject: [PATCH 05/74] Add remaining surfaces to C++ --- src/surface_header.C | 355 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 340 insertions(+), 15 deletions(-) diff --git a/src/surface_header.C b/src/surface_header.C index 42fb948af1..397be2cff2 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -75,7 +75,7 @@ Surface::reflect(const double xyz[3], double uvw[3]) const { } //============================================================================== -// Generic functions for X-, Y-, and Z-, planes +// Generic functions for x-, y-, and z-, planes //============================================================================== template double @@ -104,6 +104,7 @@ axis_aligned_plane_normal(const double xyz[3], double uvw[3]) { //============================================================================== class SurfaceXPlane : public Surface { + // x = x0 double x0; public: SurfaceXPlane(pugi::xml_node surf_node); @@ -139,6 +140,7 @@ inline void SurfaceXPlane::normal(const double xyz[3], double uvw[3]) const { //============================================================================== class SurfaceYPlane : public Surface { + // y = y0 double y0; public: SurfaceYPlane(pugi::xml_node surf_node); @@ -174,6 +176,7 @@ inline void SurfaceYPlane::normal(const double xyz[3], double uvw[3]) const { //============================================================================== class SurfaceZPlane : public Surface { + // z = z0 double z0; public: SurfaceZPlane(pugi::xml_node surf_node); @@ -208,10 +211,53 @@ inline void SurfaceZPlane::normal(const double xyz[3], double uvw[3]) const { // SurfacePlane //============================================================================== -// TODO +class SurfacePlane : public Surface { + // Ax + By + Cz = D + double A, B, C, D; +public: + SurfacePlane(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + const bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; +}; + +SurfacePlane::SurfacePlane(pugi::xml_node surf_node) { + const char *coeffs = surf_node.attribute("coeffs").value(); + int stat = sscanf(coeffs, "%lf %lf %lf %lf", &A, &B, &C, &D); + if (stat != 4) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +double +SurfacePlane::evaluate(const double xyz[3]) const { + return A*xyz[0] + B*xyz[1] + C*xyz[2] - D; +} + +double +SurfacePlane::distance(const double xyz[3], const double uvw[3], + bool coincident) const { + const double f = A*xyz[0] + B*xyz[1] + C*xyz[2] - D; + const double projection = A*uvw[0] + B*uvw[1] + C*uvw[2]; + if (coincident or fabs(f) < FP_COINCIDENT or projection == 0.0) { + return INFTY; + } else { + const double d = -f / projection; + if (d < 0.0) return INFTY; + return d; + } +} + +void +SurfacePlane::normal(const double xyz[3], double uvw[3]) const { + uvw[0] = A; + uvw[1] = B; + uvw[2] = C; +} //============================================================================== -// Generic functions for X-, Y-, and Z-, cylinders +// Generic functions for x-, y-, and z-, cylinders //============================================================================== template double @@ -224,9 +270,8 @@ axis_aligned_cylinder_evaluate(const double xyz[3], double offset1, template double axis_aligned_cylinder_distance(const double xyz[3], const double uvw[3], - double offset1, double offset2, double radius, bool coincident) { + bool coincident, double offset1, double offset2, double radius) { const double a = 1.0 - uvw[i1]*uvw[i1]; // u^2 + v^2 - if (a == 0.0) return INFTY; const double xyz2 = xyz[i2] - offset1; @@ -277,7 +322,10 @@ axis_aligned_cylinder_normal(const double xyz[3], double uvw[3], double offset1, // SurfaceXCylinder //============================================================================== +// TODO: Test this implementation! + class SurfaceXCylinder : public Surface { + // (y - y0)^2 + (z - z0)^2 = R^2 double y0, z0, r; public: SurfaceXCylinder(pugi::xml_node surf_node); @@ -295,8 +343,7 @@ SurfaceXCylinder::SurfaceXCylinder(pugi::xml_node surf_node) { } } -inline double -SurfaceXCylinder::evaluate(const double xyz[3]) const { +inline double SurfaceXCylinder::evaluate(const double xyz[3]) const { return axis_aligned_cylinder_evaluate<1, 2>(xyz, y0, z0, r); } @@ -314,7 +361,10 @@ inline void SurfaceXCylinder::normal(const double xyz[3], double uvw[3]) const { // SurfaceYCylinder //============================================================================== +// TODO: Test this implementation! + class SurfaceYCylinder : public Surface { + // (x - x0)^2 + (z - z0)^2 = R^2 double x0, z0, r; public: SurfaceYCylinder(pugi::xml_node surf_node); @@ -332,8 +382,7 @@ SurfaceYCylinder::SurfaceYCylinder(pugi::xml_node surf_node) { } } -inline double -SurfaceYCylinder::evaluate(const double xyz[3]) const { +inline double SurfaceYCylinder::evaluate(const double xyz[3]) const { return axis_aligned_cylinder_evaluate<0, 2>(xyz, x0, z0, r); } @@ -352,6 +401,7 @@ inline void SurfaceYCylinder::normal(const double xyz[3], double uvw[3]) const { //============================================================================== class SurfaceZCylinder : public Surface { + // (x - x0)^2 + (y - y0)^2 = R^2 double x0, y0, r; public: SurfaceZCylinder(pugi::xml_node surf_node); @@ -369,8 +419,7 @@ SurfaceZCylinder::SurfaceZCylinder(pugi::xml_node surf_node) { } } -inline double -SurfaceZCylinder::evaluate(const double xyz[3]) const { +inline double SurfaceZCylinder::evaluate(const double xyz[3]) const { return axis_aligned_cylinder_evaluate<0, 1>(xyz, x0, y0, r); } @@ -389,6 +438,7 @@ inline void SurfaceZCylinder::normal(const double xyz[3], double uvw[3]) const { //============================================================================== class SurfaceSphere : public Surface { + // (x - x0)^2 + (y - y0)^2 + (z - z0)^2 = R^2 double x0, y0, z0, r; public: SurfaceSphere(pugi::xml_node surf_node); @@ -457,29 +507,289 @@ inline void SurfaceSphere::normal(const double xyz[3], double uvw[3]) const { uvw[2] = 2.0 * (xyz[2] - z0); } +//============================================================================== +// Generic functions for x-, y-, and z-, cones +//============================================================================== + +template double +axis_aligned_cone_evaluate(const double xyz[3], double offset1, + double offset2, double offset3, double radius_sq) { + const double xyz1 = xyz[i1] - offset1; + const double xyz2 = xyz[i2] - offset2; + const double xyz3 = xyz[i3] - offset3; + return xyz2*xyz2 + xyz3*xyz3 - radius_sq*xyz1*xyz1; +} + +template double +axis_aligned_cone_distance(const double xyz[3], const double uvw[3], + bool coincident, double offset1, double offset2, double offset3, + double radius_sq) { + const double xyz1 = xyz[i1] - offset1; + const double xyz2 = xyz[i2] - offset2; + const double xyz3 = xyz[i3] - offset3; + const double a = uvw[i2]*uvw[i2] + uvw[i3]*uvw[i3] + - radius_sq*uvw[i1]*uvw[i1]; + const double k = xyz2*uvw[i2] + xyz3*uvw[i3] - radius_sq*xyz1*uvw[i1]; + const double c = xyz2*xyz2 + xyz3*xyz3 - radius_sq*xyz1*xyz1; + double quad = k*k - a*c; + + double d; + + if (quad < 0.0) { + // No intersection with cone. + return INFTY; + + } else if (coincident or fabs(c) < FP_COINCIDENT) { + // Particle is on the cone, thus one distance is positive/negative + // and the other is zero. The sign of k determines if we are facing in or + // out. + if (k >= 0.0) { + d = (-k - sqrt(quad)) / a; + } else { + d = (-k + sqrt(quad)) / a; + } + + } else { + // Calculate both solutions to the quadratic. + quad = sqrt(quad); + d = (-k - quad) / a; + const double b = (-k + quad) / a; + + // Determine the smallest positive solution. + if (d < 0.0) { + if (b > 0.0) d = b; + } else { + if (b > 0.0) { + if (b < d) d = b; + } + } + } + + // If the distance was negative, set boundary distance to infinity. + if (d <= 0.0) return INFTY; + return d; +} + +template void +axis_aligned_cone_normal(const double xyz[3], double uvw[3], double offset1, + double offset2, double offset3, double radius_sq) { + uvw[i1] = -2.0 * radius_sq * (xyz[i1] - offset1); + uvw[i2] = 2.0 * (xyz[i2] - offset2); + uvw[i3] = 2.0 * (xyz[i3] - offset3); +} + //============================================================================== // SurfaceXCone //============================================================================== -// TODO +// TODO: Test this implementation! + +class SurfaceXCone : public Surface { + // (y - y0)^2 + (z - z0)^2 = R^2*(x - x0)^2 + double x0, y0, z0, r_sq; +public: + SurfaceXCone(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; +}; + +SurfaceXCone::SurfaceXCone(pugi::xml_node surf_node) { + const char *coeffs = surf_node.attribute("coeffs").value(); + int stat = sscanf(coeffs, "%lf %lf %lf %lf", &x0, &y0, &z0, &r_sq); + if (stat != 4) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +inline double SurfaceXCone::evaluate(const double xyz[3]) const { + return axis_aligned_cone_evaluate<0, 1, 2>(xyz, x0, y0, z0, r_sq); +} + +inline double SurfaceXCone::distance(const double xyz[3], + const double uvw[3], bool coincident) const { + return axis_aligned_cone_distance<0, 1, 2>(xyz, uvw, coincident, x0, y0, z0, + r_sq); +} + +inline void SurfaceXCone::normal(const double xyz[3], double uvw[3]) const { + axis_aligned_cone_normal<0, 1, 2>(xyz, uvw, x0, y0, z0, r_sq); +} //============================================================================== // SurfaceYCone //============================================================================== -// TODO +// TODO: Test this implementation! + +class SurfaceYCone : public Surface { + // (x - x0)^2 + (z - z0)^2 = R^2*(y - y0)^2 + double x0, y0, z0, r_sq; +public: + SurfaceYCone(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; +}; + +SurfaceYCone::SurfaceYCone(pugi::xml_node surf_node) { + const char *coeffs = surf_node.attribute("coeffs").value(); + int stat = sscanf(coeffs, "%lf %lf %lf %lf", &x0, &y0, &z0, &r_sq); + if (stat != 4) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +inline double SurfaceYCone::evaluate(const double xyz[3]) const { + return axis_aligned_cone_evaluate<1, 0, 2>(xyz, y0, x0, z0, r_sq); +} + +inline double SurfaceYCone::distance(const double xyz[3], + const double uvw[3], bool coincident) const { + return axis_aligned_cone_distance<1, 0, 2>(xyz, uvw, coincident, y0, x0, z0, + r_sq); +} + +inline void SurfaceYCone::normal(const double xyz[3], double uvw[3]) const { + axis_aligned_cone_normal<1, 0, 2>(xyz, uvw, y0, x0, z0, r_sq); +} //============================================================================== // SurfaceZCone //============================================================================== -// TODO +class SurfaceZCone : public Surface { + // (x - x0)^2 + (y - y0)^2 = R^2*(z - z0)^2 + double x0, y0, z0, r_sq; +public: + SurfaceZCone(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; +}; + +SurfaceZCone::SurfaceZCone(pugi::xml_node surf_node) { + const char *coeffs = surf_node.attribute("coeffs").value(); + int stat = sscanf(coeffs, "%lf %lf %lf %lf", &x0, &y0, &z0, &r_sq); + if (stat != 4) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +inline double SurfaceZCone::evaluate(const double xyz[3]) const { + return axis_aligned_cone_evaluate<2, 0, 1>(xyz, z0, x0, y0, r_sq); +} + +inline double SurfaceZCone::distance(const double xyz[3], + const double uvw[3], bool coincident) const { + return axis_aligned_cone_distance<2, 0, 1>(xyz, uvw, coincident, z0, x0, y0, + r_sq); +} + +inline void SurfaceZCone::normal(const double xyz[3], double uvw[3]) const { + axis_aligned_cone_normal<2, 0, 1>(xyz, uvw, z0, x0, y0, r_sq); +} //============================================================================== // SurfaceQuadric //============================================================================== -// TODO +class SurfaceQuadric : public Surface { + // Ax^2 + By^2 + Cz^2 + Dxy + Eyz + Fxz + Gx + Hy + Jz + K = 0 + double A, B, C, D, E, F, G, H, J, K; +public: + SurfaceQuadric(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; +}; + +SurfaceQuadric::SurfaceQuadric(pugi::xml_node surf_node) { + const char *coeffs = surf_node.attribute("coeffs").value(); + int stat = sscanf(coeffs, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", + &A, &B, &C, &D, &E, &F, &G, &H, &J, &K); + if (stat != 10) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +double +SurfaceQuadric::evaluate(const double xyz[3]) const { + const double &x = xyz[0]; + const double &y = xyz[1]; + const double &z = xyz[2]; + return x*(A*x + D*y + G) + + y*(B*y + E*z + H) + + z*(C*z + F*x + J) + K; +} + +double +SurfaceQuadric::distance(const double xyz[3], + const double uvw[3], bool coincident) const { + const double &x = xyz[0]; + const double &y = xyz[1]; + const double &z = xyz[2]; + const double &u = uvw[0]; + const double &v = uvw[1]; + const double &w = uvw[2]; + + const double a = A*u*u + B*v*v + C*w*w + D*u*v + E*v*w + F*u*w; + const double k = (A*u*x + B*v*y + C*w*z + 0.5*(D*(u*y + v*x) + + E*(v*z + w*y) + F*(w*x + u*z) + G*u + H*v + J*w)); + const double c = A*x*x + B*y*y + C*z*z + D*x*y + E*y*z + F*x*z + G*x + H*y + + J*z + K; + double quad = k*k - a*c; + + double d; + + if (quad < 0.0) { + // No intersection with surface. + return INFTY; + + } else if (coincident or fabs(c) < FP_COINCIDENT) { + // Particle is on the surface, thus one distance is positive/negative and + // the other is zero. The sign of k determines which distance is zero and + // which is not. + if (k >= 0.0) { + d = (-k - sqrt(quad)) / a; + } else { + d = (-k + sqrt(quad)) / a; + } + + } else { + // Calculate both solutions to the quadratic. + quad = sqrt(quad); + d = (-k - quad) / a; + double b = (-k + quad) / a; + + // Determine the smallest positive solution. + if (d < 0.0) { + if (b > 0.0) d = b; + } else { + if (b > 0.0) { + if (b < d) d = b; + } + } + } + + // If the distance was negative, set boundary distance to infinity. + if (d <= 0.0) return INFTY; + return d; +} + +void +SurfaceQuadric::normal(const double xyz[3], double uvw[3]) const { + const double &x = xyz[0]; + const double &y = xyz[1]; + const double &z = xyz[2]; + uvw[0] = 2.0*A*x + D*y + F*z + G; + uvw[1] = 2.0*B*y + D*x + E*z + H; + uvw[2] = 2.0*C*z + E*y + F*x + J; +} //============================================================================== @@ -513,6 +823,9 @@ read_surfaces(pugi::xml_node *node) { } else if (strcmp(surf_type, "z-plane") == 0) { surfaces_c[i_surf] = new SurfaceZPlane(surf_node); + } else if (strcmp(surf_type, "plane") == 0) { + surfaces_c[i_surf] = new SurfacePlane(surf_node); + } else if (strcmp(surf_type, "x-cylinder") == 0) { surfaces_c[i_surf] = new SurfaceXCylinder(surf_node); @@ -525,6 +838,18 @@ read_surfaces(pugi::xml_node *node) { } else if (strcmp(surf_type, "sphere") == 0) { surfaces_c[i_surf] = new SurfaceSphere(surf_node); + } else if (strcmp(surf_type, "x-cone") == 0) { + surfaces_c[i_surf] = new SurfaceXCone(surf_node); + + } else if (strcmp(surf_type, "y-cone") == 0) { + surfaces_c[i_surf] = new SurfaceYCone(surf_node); + + } else if (strcmp(surf_type, "z-cone") == 0) { + surfaces_c[i_surf] = new SurfaceZCone(surf_node); + + } else if (strcmp(surf_type, "quadric") == 0) { + surfaces_c[i_surf] = new SurfaceQuadric(surf_node); + } else { std::cout << "Call error or handle uppercase here!" << std::endl; std::cout << surf_type << std::endl; From d4a1f1834b42c78f574525e564a09a537071b3ca Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sat, 2 Sep 2017 18:44:06 -0400 Subject: [PATCH 06/74] Handle both XML nodes and attributes in C++ surfs --- src/surface_header.C | 213 +++++++++++++++++++++++++------------------ 1 file changed, 123 insertions(+), 90 deletions(-) diff --git a/src/surface_header.C b/src/surface_header.C index 397be2cff2..3ac3d3c532 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -18,6 +18,82 @@ const double INFTY = std::numeric_limits::max(); class Surface; Surface **surfaces_c; +//============================================================================== +// Helper functions +//============================================================================== + +void read_coeffs(pugi::xml_node surf_node, double &c1) +{ + const char *coeffs; + if (surf_node.attribute("coeffs")) { + coeffs = surf_node.attribute("coeffs").value(); + } else if (surf_node.child("coeffs")) { + coeffs = surf_node.child_value("coeffs"); + } else { + std::cout << "ERROR: Found a surface with no coefficients" << std::endl; + } + + int stat = sscanf(coeffs, "%lf", &c1); + if (stat != 1) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +void read_coeffs(pugi::xml_node surf_node, double &c1, double &c2, double &c3) +{ + const char *coeffs; + if (surf_node.attribute("coeffs")) { + coeffs = surf_node.attribute("coeffs").value(); + } else if (surf_node.child("coeffs")) { + coeffs = surf_node.child_value("coeffs"); + } else { + std::cout << "ERROR: Found a surface with no coefficients" << std::endl; + } + + int stat = sscanf(coeffs, "%lf %lf %lf", &c1, &c2, &c3); + if (stat != 3) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +void read_coeffs(pugi::xml_node surf_node, double &c1, double &c2, double &c3, + double &c4) +{ + const char *coeffs; + if (surf_node.attribute("coeffs")) { + coeffs = surf_node.attribute("coeffs").value(); + } else if (surf_node.child("coeffs")) { + coeffs = surf_node.child_value("coeffs"); + } else { + std::cout << "ERROR: Found a surface with no coefficients" << std::endl; + } + + int stat = sscanf(coeffs, "%lf %lf %lf %lf", &c1, &c2, &c3, &c4); + if (stat != 4) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + +void read_coeffs(pugi::xml_node surf_node, double &c1, double &c2, double &c3, + double &c4, double &c5, double &c6, double &c7, double &c8, + double &c9, double &c10) +{ + const char *coeffs; + if (surf_node.attribute("coeffs")) { + coeffs = surf_node.attribute("coeffs").value(); + } else if (surf_node.child("coeffs")) { + coeffs = surf_node.child_value("coeffs"); + } else { + std::cout << "ERROR: Found a surface with no coefficients" << std::endl; + } + + int stat = sscanf(coeffs, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", + &c1, &c2, &c3, &c4, &c5, &c6, &c7, &c8, &c9, &c10); + if (stat != 10) { + std::cout << "Something went wrong reading surface coeffs!" << std::endl; + } +} + //============================================================================== // SURFACE type defines a first- or second-order surface that can be used to // construct closed volumes (cells) @@ -115,11 +191,7 @@ public: }; SurfaceXPlane::SurfaceXPlane(pugi::xml_node surf_node) { - const char *coeffs = surf_node.attribute("coeffs").value(); - int stat = sscanf(coeffs, "%lf", &x0); - if (stat != 1) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; - } + read_coeffs(surf_node, x0); } inline double SurfaceXPlane::evaluate(const double xyz[3]) const { @@ -151,11 +223,7 @@ public: }; SurfaceYPlane::SurfaceYPlane(pugi::xml_node surf_node) { - const char *coeffs = surf_node.attribute("coeffs").value(); - int stat = sscanf(coeffs, "%lf", &y0); - if (stat != 1) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; - } + read_coeffs(surf_node, y0); } inline double SurfaceYPlane::evaluate(const double xyz[3]) const { @@ -187,11 +255,7 @@ public: }; SurfaceZPlane::SurfaceZPlane(pugi::xml_node surf_node) { - const char *coeffs = surf_node.attribute("coeffs").value(); - int stat = sscanf(coeffs, "%lf", &z0); - if (stat != 1) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; - } + read_coeffs(surf_node, z0); } inline double SurfaceZPlane::evaluate(const double xyz[3]) const { @@ -223,11 +287,7 @@ public: }; SurfacePlane::SurfacePlane(pugi::xml_node surf_node) { - const char *coeffs = surf_node.attribute("coeffs").value(); - int stat = sscanf(coeffs, "%lf %lf %lf %lf", &A, &B, &C, &D); - if (stat != 4) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; - } + read_coeffs(surf_node, A, B, C, D); } double @@ -336,11 +396,7 @@ public: }; SurfaceXCylinder::SurfaceXCylinder(pugi::xml_node surf_node) { - const char *coeffs = surf_node.attribute("coeffs").value(); - int stat = sscanf(coeffs, "%lf %lf %lf", &y0, &z0, &r); - if (stat != 3) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; - } + read_coeffs(surf_node, y0, z0, r); } inline double SurfaceXCylinder::evaluate(const double xyz[3]) const { @@ -375,11 +431,7 @@ public: }; SurfaceYCylinder::SurfaceYCylinder(pugi::xml_node surf_node) { - const char *coeffs = surf_node.attribute("coeffs").value(); - int stat = sscanf(coeffs, "%lf %lf %lf", &x0, &z0, &r); - if (stat != 3) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; - } + read_coeffs(surf_node, x0, z0, r); } inline double SurfaceYCylinder::evaluate(const double xyz[3]) const { @@ -412,11 +464,7 @@ public: }; SurfaceZCylinder::SurfaceZCylinder(pugi::xml_node surf_node) { - const char *coeffs = surf_node.attribute("coeffs").value(); - int stat = sscanf(coeffs, "%lf %lf %lf", &x0, &y0, &r); - if (stat != 3) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; - } + read_coeffs(surf_node, x0, y0, r); } inline double SurfaceZCylinder::evaluate(const double xyz[3]) const { @@ -449,11 +497,7 @@ public: }; SurfaceSphere::SurfaceSphere(pugi::xml_node surf_node) { - const char *coeffs = surf_node.attribute("coeffs").value(); - int stat = sscanf(coeffs, "%lf %lf %lf %lf", &x0, &y0, &z0, &r); - if (stat != 4) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; - } + read_coeffs(surf_node, x0, y0, z0, r); } double SurfaceSphere::evaluate(const double xyz[3]) const { @@ -596,11 +640,7 @@ public: }; SurfaceXCone::SurfaceXCone(pugi::xml_node surf_node) { - const char *coeffs = surf_node.attribute("coeffs").value(); - int stat = sscanf(coeffs, "%lf %lf %lf %lf", &x0, &y0, &z0, &r_sq); - if (stat != 4) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; - } + read_coeffs(surf_node, x0, y0, z0, r_sq); } inline double SurfaceXCone::evaluate(const double xyz[3]) const { @@ -635,11 +675,7 @@ public: }; SurfaceYCone::SurfaceYCone(pugi::xml_node surf_node) { - const char *coeffs = surf_node.attribute("coeffs").value(); - int stat = sscanf(coeffs, "%lf %lf %lf %lf", &x0, &y0, &z0, &r_sq); - if (stat != 4) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; - } + read_coeffs(surf_node, x0, y0, z0, r_sq); } inline double SurfaceYCone::evaluate(const double xyz[3]) const { @@ -672,11 +708,7 @@ public: }; SurfaceZCone::SurfaceZCone(pugi::xml_node surf_node) { - const char *coeffs = surf_node.attribute("coeffs").value(); - int stat = sscanf(coeffs, "%lf %lf %lf %lf", &x0, &y0, &z0, &r_sq); - if (stat != 4) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; - } + read_coeffs(surf_node, x0, y0, z0, r_sq); } inline double SurfaceZCone::evaluate(const double xyz[3]) const { @@ -709,12 +741,7 @@ public: }; SurfaceQuadric::SurfaceQuadric(pugi::xml_node surf_node) { - const char *coeffs = surf_node.attribute("coeffs").value(); - int stat = sscanf(coeffs, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", - &A, &B, &C, &D, &E, &F, &G, &H, &J, &K); - if (stat != 10) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; - } + read_coeffs(surf_node, A, B, C, D, E, F, G, H, J, K); } double @@ -811,49 +838,55 @@ read_surfaces(pugi::xml_node *node) { int i_surf; for (surf_node = node->child("surface"), i_surf = 0; surf_node; surf_node = surf_node.next_sibling("surface"), i_surf++) { + const pugi::char_t *surf_type; if (surf_node.attribute("type")) { - const pugi::char_t *surf_type = surf_node.attribute("type").value(); + surf_type = surf_node.attribute("type").value(); + } else if (surf_node.child("type")) { + surf_type = surf_node.child_value("type"); + } else { + std::cout << "ERROR: Found a surface with no type attribute/node" + << std::endl; + } - if (strcmp(surf_type, "x-plane") == 0) { - surfaces_c[i_surf] = new SurfaceXPlane(surf_node); + if (strcmp(surf_type, "x-plane") == 0) { + surfaces_c[i_surf] = new SurfaceXPlane(surf_node); - } else if (strcmp(surf_type, "y-plane") == 0) { - surfaces_c[i_surf] = new SurfaceYPlane(surf_node); + } else if (strcmp(surf_type, "y-plane") == 0) { + surfaces_c[i_surf] = new SurfaceYPlane(surf_node); - } else if (strcmp(surf_type, "z-plane") == 0) { - surfaces_c[i_surf] = new SurfaceZPlane(surf_node); + } else if (strcmp(surf_type, "z-plane") == 0) { + surfaces_c[i_surf] = new SurfaceZPlane(surf_node); - } else if (strcmp(surf_type, "plane") == 0) { - surfaces_c[i_surf] = new SurfacePlane(surf_node); + } else if (strcmp(surf_type, "plane") == 0) { + surfaces_c[i_surf] = new SurfacePlane(surf_node); - } else if (strcmp(surf_type, "x-cylinder") == 0) { - surfaces_c[i_surf] = new SurfaceXCylinder(surf_node); + } else if (strcmp(surf_type, "x-cylinder") == 0) { + surfaces_c[i_surf] = new SurfaceXCylinder(surf_node); - } else if (strcmp(surf_type, "y-cylinder") == 0) { - surfaces_c[i_surf] = new SurfaceYCylinder(surf_node); + } else if (strcmp(surf_type, "y-cylinder") == 0) { + surfaces_c[i_surf] = new SurfaceYCylinder(surf_node); - } else if (strcmp(surf_type, "z-cylinder") == 0) { - surfaces_c[i_surf] = new SurfaceZCylinder(surf_node); + } else if (strcmp(surf_type, "z-cylinder") == 0) { + surfaces_c[i_surf] = new SurfaceZCylinder(surf_node); - } else if (strcmp(surf_type, "sphere") == 0) { - surfaces_c[i_surf] = new SurfaceSphere(surf_node); + } else if (strcmp(surf_type, "sphere") == 0) { + surfaces_c[i_surf] = new SurfaceSphere(surf_node); - } else if (strcmp(surf_type, "x-cone") == 0) { - surfaces_c[i_surf] = new SurfaceXCone(surf_node); + } else if (strcmp(surf_type, "x-cone") == 0) { + surfaces_c[i_surf] = new SurfaceXCone(surf_node); - } else if (strcmp(surf_type, "y-cone") == 0) { - surfaces_c[i_surf] = new SurfaceYCone(surf_node); + } else if (strcmp(surf_type, "y-cone") == 0) { + surfaces_c[i_surf] = new SurfaceYCone(surf_node); - } else if (strcmp(surf_type, "z-cone") == 0) { - surfaces_c[i_surf] = new SurfaceZCone(surf_node); + } else if (strcmp(surf_type, "z-cone") == 0) { + surfaces_c[i_surf] = new SurfaceZCone(surf_node); - } else if (strcmp(surf_type, "quadric") == 0) { - surfaces_c[i_surf] = new SurfaceQuadric(surf_node); + } else if (strcmp(surf_type, "quadric") == 0) { + surfaces_c[i_surf] = new SurfaceQuadric(surf_node); - } else { - std::cout << "Call error or handle uppercase here!" << std::endl; - std::cout << surf_type << std::endl; - } + } else { + std::cout << "Call error or handle uppercase here!" << std::endl; + std::cout << surf_type << std::endl; } } } From 57dbb70d0c2b123cb2938eba7187204bd9fe9991 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sat, 2 Sep 2017 19:12:46 -0400 Subject: [PATCH 07/74] Add test code for C++ surface normals --- src/geometry.F90 | 18 ++++++++++++++++++ src/surface_header.C | 5 +++++ 2 files changed, 23 insertions(+) diff --git a/src/geometry.F90 b/src/geometry.F90 index bc1eca2ae9..8a449a284b 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -35,6 +35,15 @@ module geometry logical(C_BOOL), value :: coincident; real(C_DOUBLE) :: d; end function surface_distance_c + + subroutine surface_normal_c(surf_ind, xyz, uvw) & + bind(C, name='surface_normal') + use ISO_C_BINDING + implicit none + integer(C_INT), value :: surf_ind; + real(C_DOUBLE) :: xyz(3); + real(C_DOUBLE) :: uvw(3); + end subroutine surface_normal_c end interface contains @@ -76,6 +85,7 @@ contains integer :: token logical :: actual_sense ! sense of particle wrt surface logical :: alt_sense + real(8) :: uvw1(3), uvw2(3) in_cell = .true. do i = 1, size(c%rpn) @@ -102,6 +112,14 @@ contains write(*, *) actual_sense, alt_sense call fatal_error("") end if + uvw1 = surfaces(abs(token))%obj%normal(p%coord(p%n_coord)%xyz) + call surface_normal_c(abs(token)-1, p%coord(p%n_coord)%xyz, uvw2) + if (.not. all(uvw1 - uvw2 == ZERO)) then + write(*, *) "Surface normals don't match" + write(*, *) uvw1 + write(*, *) uvw2 + call fatal_error("") + end if if (actual_sense .neqv. (token > 0)) then in_cell = .false. exit diff --git a/src/surface_header.C b/src/surface_header.C index 3ac3d3c532..43209fc803 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -903,3 +903,8 @@ extern "C" double surface_distance(int surf_ind, double xyz[3], double uvw[3], bool coincident) { return surfaces_c[surf_ind]->distance(xyz, uvw, coincident); } + +extern "C" void +surface_normal(int surf_ind, double xyz[3], double uvw[3]) { + return surfaces_c[surf_ind]->normal(xyz, uvw); +} From 3752fea1e9e3c45baf5aebf410ebc595f032596f Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Sun, 3 Sep 2017 13:28:04 -0400 Subject: [PATCH 08/74] Use Doxygen-style comments for C++ surface code --- src/surface_header.C | 195 ++++++++++++++++++++++++++++--------------- 1 file changed, 126 insertions(+), 69 deletions(-) diff --git a/src/surface_header.C b/src/surface_header.C index 43209fc803..297335827c 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -1,9 +1,12 @@ #include // For strcmp -#include #include // For numeric_limits #include // For fabs + #include "pugixml/pugixml.hpp" +// DEBUGGING +#include + //============================================================================== // Constants //============================================================================== @@ -19,20 +22,24 @@ class Surface; Surface **surfaces_c; //============================================================================== -// Helper functions +// Helper functions for reading the "coeffs" node of an XML surface element //============================================================================== +const char* get_coeff_str(pugi::xml_node surf_node) +{ + if (surf_node.attribute("coeffs")) { + return surf_node.attribute("coeffs").value(); + } else if (surf_node.child("coeffs")) { + return surf_node.child_value("coeffs"); + } else { + std::cout << "ERROR: Found a surface with no coefficients" << std::endl; + return NULL; + } +} + void read_coeffs(pugi::xml_node surf_node, double &c1) { - const char *coeffs; - if (surf_node.attribute("coeffs")) { - coeffs = surf_node.attribute("coeffs").value(); - } else if (surf_node.child("coeffs")) { - coeffs = surf_node.child_value("coeffs"); - } else { - std::cout << "ERROR: Found a surface with no coefficients" << std::endl; - } - + const char *coeffs = get_coeff_str(surf_node); int stat = sscanf(coeffs, "%lf", &c1); if (stat != 1) { std::cout << "Something went wrong reading surface coeffs!" << std::endl; @@ -41,15 +48,7 @@ void read_coeffs(pugi::xml_node surf_node, double &c1) void read_coeffs(pugi::xml_node surf_node, double &c1, double &c2, double &c3) { - const char *coeffs; - if (surf_node.attribute("coeffs")) { - coeffs = surf_node.attribute("coeffs").value(); - } else if (surf_node.child("coeffs")) { - coeffs = surf_node.child_value("coeffs"); - } else { - std::cout << "ERROR: Found a surface with no coefficients" << std::endl; - } - + const char *coeffs = get_coeff_str(surf_node); int stat = sscanf(coeffs, "%lf %lf %lf", &c1, &c2, &c3); if (stat != 3) { std::cout << "Something went wrong reading surface coeffs!" << std::endl; @@ -59,15 +58,7 @@ void read_coeffs(pugi::xml_node surf_node, double &c1, double &c2, double &c3) void read_coeffs(pugi::xml_node surf_node, double &c1, double &c2, double &c3, double &c4) { - const char *coeffs; - if (surf_node.attribute("coeffs")) { - coeffs = surf_node.attribute("coeffs").value(); - } else if (surf_node.child("coeffs")) { - coeffs = surf_node.child_value("coeffs"); - } else { - std::cout << "ERROR: Found a surface with no coefficients" << std::endl; - } - + const char *coeffs = get_coeff_str(surf_node); int stat = sscanf(coeffs, "%lf %lf %lf %lf", &c1, &c2, &c3, &c4); if (stat != 4) { std::cout << "Something went wrong reading surface coeffs!" << std::endl; @@ -78,15 +69,7 @@ void read_coeffs(pugi::xml_node surf_node, double &c1, double &c2, double &c3, double &c4, double &c5, double &c6, double &c7, double &c8, double &c9, double &c10) { - const char *coeffs; - if (surf_node.attribute("coeffs")) { - coeffs = surf_node.attribute("coeffs").value(); - } else if (surf_node.child("coeffs")) { - coeffs = surf_node.child_value("coeffs"); - } else { - std::cout << "ERROR: Found a surface with no coefficients" << std::endl; - } - + const char *coeffs = get_coeff_str(surf_node); int stat = sscanf(coeffs, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", &c1, &c2, &c3, &c4, &c5, &c6, &c7, &c8, &c9, &c10); if (stat != 10) { @@ -95,25 +78,52 @@ void read_coeffs(pugi::xml_node surf_node, double &c1, double &c2, double &c3, } //============================================================================== -// SURFACE type defines a first- or second-order surface that can be used to -// construct closed volumes (cells) +//! A geometry primitive used to define regions of 3D space. //============================================================================== class Surface { - int id; // Unique ID - int neighbor_pos[], // List of cells on positive side - neighbor_neg[]; // List of cells on negative side - int bc; // Boundary condition - //TODO: swith that zero to a NONE constant. - int i_periodic = 0; // Index of corresponding periodic surface - char name[104]; // User-defined name - public: + int id; //!< Unique ID + int neighbor_pos[], //!< List of cells on positive side + neighbor_neg[]; //!< List of cells on negative side + int bc; //!< Boundary condition + //TODO: switch that zero to a NONE constant. + int i_periodic = 0; //!< Index of corresponding periodic surface + char name[104]; //!< User-defined name + + //! Determine which side of a surface a point lies on. + //! @param xyz[3] The 3D Cartesian coordinate of a point. + //! @param uvw[3] A direction used to "break ties" and pick a sense when the + //! point is very close to the surface. + //! @return True if the point is on the "positive" side of the surface and + //! false otherwise. bool sense(const double xyz[3], const double uvw[3]) const; + + //! Determine the direction of a ray reflected from the surface. + //! @param xyz[3] The point at which the ray is incident. + //! @param uvw[3] A direction. This is both an input and an output parameter. + //! It specifies the icident direction on input and the reflected direction + //! on output. void reflect(const double xyz[3], double uvw[3]) const; + + //! Evaluate the equation describing the surface. + //! + //! Surfaces can be described by some function f(x, y, z) = 0. This member + //! function evaluates that mathematical function. + //! @param xyz[3] A 3D Cartesian coordinate. virtual double evaluate(const double xyz[3]) const = 0; + + //! Compute the distance between a point and the surface along a ray. + //! @param xyz[3] A 3D Cartesian coordinate. + //! @param uvw[3] The direction of the ray. + //! @param coincident A hint to the code that the given point should lie + //! exactly on the surface. virtual double distance(const double xyz[3], const double uvw[3], bool coincident) const = 0; + + //! Compute the local outward normal direction of the surface. + //! @param xyz[3] A 3D Cartesian coordinate. + //! @param uvw[3] This output argument provides the normal. virtual void normal(const double xyz[3], double uvw[3]) const = 0; }; @@ -151,13 +161,16 @@ Surface::reflect(const double xyz[3], double uvw[3]) const { } //============================================================================== -// Generic functions for x-, y-, and z-, planes +// Generic functions for x-, y-, and z-, planes. //============================================================================== +// The template parameter indicates the axis normal to the plane. template double axis_aligned_plane_evaluate(const double xyz[3], double offset) { - return xyz[i] - offset;} + return xyz[i] - offset; +} +// The template parameter indicates the axis normal to the plane. template double axis_aligned_plane_distance(const double xyz[3], const double uvw[3], bool coincident, double offset) { @@ -168,6 +181,8 @@ axis_aligned_plane_distance(const double xyz[3], const double uvw[3], return d; } +// The first template parameter indicates the axis normal to the plane. The +// other two parameters indicate the other two axes. template void axis_aligned_plane_normal(const double xyz[3], double uvw[3]) { uvw[i1] = 1.0; @@ -177,10 +192,12 @@ axis_aligned_plane_normal(const double xyz[3], double uvw[3]) { //============================================================================== // SurfaceXPlane +//! A plane perpendicular to the x-axis. +// +//! The plane is described by the equation \f$x - x_0 = 0\f$ //============================================================================== class SurfaceXPlane : public Surface { - // x = x0 double x0; public: SurfaceXPlane(pugi::xml_node surf_node); @@ -209,10 +226,12 @@ inline void SurfaceXPlane::normal(const double xyz[3], double uvw[3]) const { //============================================================================== // SurfaceYPlane +//! A plane perpendicular to the y-axis. +// +//! The plane is described by the equation \f$y - y_0 = 0\f$ //============================================================================== class SurfaceYPlane : public Surface { - // y = y0 double y0; public: SurfaceYPlane(pugi::xml_node surf_node); @@ -241,10 +260,12 @@ inline void SurfaceYPlane::normal(const double xyz[3], double uvw[3]) const { //============================================================================== // SurfaceZPlane +//! A plane perpendicular to the z-axis. +// +//! The plane is described by the equation \f$z - z_0 = 0\f$ //============================================================================== class SurfaceZPlane : public Surface { - // z = z0 double z0; public: SurfaceZPlane(pugi::xml_node surf_node); @@ -273,10 +294,12 @@ inline void SurfaceZPlane::normal(const double xyz[3], double uvw[3]) const { //============================================================================== // SurfacePlane +//! A general plane. +// +//! The plane is described by the equation \f$A x + B y + C z - D = 0\f$ //============================================================================== class SurfacePlane : public Surface { - // Ax + By + Cz = D double A, B, C, D; public: SurfacePlane(pugi::xml_node surf_node); @@ -320,6 +343,9 @@ SurfacePlane::normal(const double xyz[3], double uvw[3]) const { // Generic functions for x-, y-, and z-, cylinders //============================================================================== +// The template parameters indicate the axes perpendicular to the axis of the +// cylinder. offset1 and offset2 should correspond with i1 and i2, +// respectively. template double axis_aligned_cylinder_evaluate(const double xyz[3], double offset1, double offset2, double radius) { @@ -328,6 +354,9 @@ axis_aligned_cylinder_evaluate(const double xyz[3], double offset1, return xyz1*xyz1 + xyz2*xyz2 - radius*radius; } +// The first template parameter indicates which axis the cylinder is aligned to. +// The other two parameters indicate the other two axes. offset1 and offset2 +// should correspond with i2 and i3, respectively. template double axis_aligned_cylinder_distance(const double xyz[3], const double uvw[3], bool coincident, double offset1, double offset2, double radius) { @@ -370,6 +399,9 @@ axis_aligned_cylinder_distance(const double xyz[3], const double uvw[3], } } +// The first template parameter indicates which axis the cylinder is aligned to. +// The other two parameters indicate the other two axes. offset1 and offset2 +// should correspond with i2 and i3, respectively. template void axis_aligned_cylinder_normal(const double xyz[3], double uvw[3], double offset1, double offset2) { @@ -380,12 +412,13 @@ axis_aligned_cylinder_normal(const double xyz[3], double uvw[3], double offset1, //============================================================================== // SurfaceXCylinder +//! A cylinder aligned along the x-axis. +// +//! The cylinder is described by the equation +//! \f$(y - y_0)^2 + (z - z_0)^2 - R^2 = 0\f$ //============================================================================== -// TODO: Test this implementation! - class SurfaceXCylinder : public Surface { - // (y - y0)^2 + (z - z0)^2 = R^2 double y0, z0, r; public: SurfaceXCylinder(pugi::xml_node surf_node); @@ -415,12 +448,13 @@ inline void SurfaceXCylinder::normal(const double xyz[3], double uvw[3]) const { //============================================================================== // SurfaceYCylinder +//! A cylinder aligned along the y-axis. +// +//! The cylinder is described by the equation +//! \f$(x - x_0)^2 + (z - z_0)^2 - R^2 = 0\f$ //============================================================================== -// TODO: Test this implementation! - class SurfaceYCylinder : public Surface { - // (x - x0)^2 + (z - z0)^2 = R^2 double x0, z0, r; public: SurfaceYCylinder(pugi::xml_node surf_node); @@ -450,10 +484,13 @@ inline void SurfaceYCylinder::normal(const double xyz[3], double uvw[3]) const { //============================================================================== // SurfaceZCylinder +//! A cylinder aligned along the z-axis. +// +//! The cylinder is described by the equation +//! \f$(x - x_0)^2 + (y - y_0)^2 - R^2 = 0\f$ //============================================================================== class SurfaceZCylinder : public Surface { - // (x - x0)^2 + (y - y0)^2 = R^2 double x0, y0, r; public: SurfaceZCylinder(pugi::xml_node surf_node); @@ -483,10 +520,13 @@ inline void SurfaceZCylinder::normal(const double xyz[3], double uvw[3]) const { //============================================================================== // SurfaceSphere +//! A sphere. +// +//! The cylinder is described by the equation +//! \f$(x - x_0)^2 + (y - y_0)^2 + (z - z_0)^2 - R^2 = 0\f$ //============================================================================== class SurfaceSphere : public Surface { - // (x - x0)^2 + (y - y0)^2 + (z - z0)^2 = R^2 double x0, y0, z0, r; public: SurfaceSphere(pugi::xml_node surf_node); @@ -555,6 +595,9 @@ inline void SurfaceSphere::normal(const double xyz[3], double uvw[3]) const { // Generic functions for x-, y-, and z-, cones //============================================================================== +// The first template parameter indicates which axis the cone is aligned to. +// The other two parameters indicate the other two axes. offset1, offset2, +// and offset3 should correspond with i1, i2, and i3, respectively. template double axis_aligned_cone_evaluate(const double xyz[3], double offset1, double offset2, double offset3, double radius_sq) { @@ -564,6 +607,9 @@ axis_aligned_cone_evaluate(const double xyz[3], double offset1, return xyz2*xyz2 + xyz3*xyz3 - radius_sq*xyz1*xyz1; } +// The first template parameter indicates which axis the cone is aligned to. +// The other two parameters indicate the other two axes. offset1, offset2, +// and offset3 should correspond with i1, i2, and i3, respectively. template double axis_aligned_cone_distance(const double xyz[3], const double uvw[3], bool coincident, double offset1, double offset2, double offset3, @@ -614,6 +660,9 @@ axis_aligned_cone_distance(const double xyz[3], const double uvw[3], return d; } +// The first template parameter indicates which axis the cone is aligned to. +// The other two parameters indicate the other two axes. offset1, offset2, +// and offset3 should correspond with i1, i2, and i3, respectively. template void axis_aligned_cone_normal(const double xyz[3], double uvw[3], double offset1, double offset2, double offset3, double radius_sq) { @@ -624,12 +673,13 @@ axis_aligned_cone_normal(const double xyz[3], double uvw[3], double offset1, //============================================================================== // SurfaceXCone +//! A cone aligned along the x-axis. +// +//! The cylinder is described by the equation +//! \f$(y - y_0)^2 + (z - z_0)^2 - R^2 (x - x_0)^2 = 0\f$ //============================================================================== -// TODO: Test this implementation! - class SurfaceXCone : public Surface { - // (y - y0)^2 + (z - z0)^2 = R^2*(x - x0)^2 double x0, y0, z0, r_sq; public: SurfaceXCone(pugi::xml_node surf_node); @@ -659,12 +709,13 @@ inline void SurfaceXCone::normal(const double xyz[3], double uvw[3]) const { //============================================================================== // SurfaceYCone +//! A cone aligned along the y-axis. +// +//! The cylinder is described by the equation +//! \f$(x - x_0)^2 + (z - z_0)^2 - R^2 (y - y_0)^2 = 0\f$ //============================================================================== -// TODO: Test this implementation! - class SurfaceYCone : public Surface { - // (x - x0)^2 + (z - z0)^2 = R^2*(y - y0)^2 double x0, y0, z0, r_sq; public: SurfaceYCone(pugi::xml_node surf_node); @@ -694,10 +745,13 @@ inline void SurfaceYCone::normal(const double xyz[3], double uvw[3]) const { //============================================================================== // SurfaceZCone +//! A cone aligned along the z-axis. +// +//! The cylinder is described by the equation +//! \f$(x - x_0)^2 + (y - y_0)^2 - R^2 (z - z_0)^2 = 0\f$ //============================================================================== class SurfaceZCone : public Surface { - // (x - x0)^2 + (y - y0)^2 = R^2*(z - z0)^2 double x0, y0, z0, r_sq; public: SurfaceZCone(pugi::xml_node surf_node); @@ -727,6 +781,9 @@ inline void SurfaceZCone::normal(const double xyz[3], double uvw[3]) const { //============================================================================== // SurfaceQuadric +//! A general surface described by a quadratic equation. +// +//! \f$A x^2 + B y^2 + C z^2 + D x y + E y z + F x z + G x + H y + J z + K = 0\f$ //============================================================================== class SurfaceQuadric : public Surface { From 72cb25e6776280fef9eb4d42e6cf712a9a36cf91 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Mon, 11 Sep 2017 16:42:40 -0400 Subject: [PATCH 09/74] Use consistent brace placement in C++ --- src/surface_header.C | 228 ++++++++++++++++++++++++++++--------------- 1 file changed, 152 insertions(+), 76 deletions(-) diff --git a/src/surface_header.C b/src/surface_header.C index 297335827c..6992c2e2ac 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -81,7 +81,8 @@ void read_coeffs(pugi::xml_node surf_node, double &c1, double &c2, double &c3, //! A geometry primitive used to define regions of 3D space. //============================================================================== -class Surface { +class Surface +{ public: int id; //!< Unique ID int neighbor_pos[], //!< List of cells on positive side @@ -128,7 +129,8 @@ public: }; bool -Surface::sense(const double xyz[3], const double uvw[3]) const { +Surface::sense(const double xyz[3], const double uvw[3]) const +{ // Evaluate the surface equation at the particle's coordinates to determine // which side the particle is on. const double f = evaluate(xyz); @@ -146,7 +148,8 @@ Surface::sense(const double xyz[3], const double uvw[3]) const { } void -Surface::reflect(const double xyz[3], double uvw[3]) const { +Surface::reflect(const double xyz[3], double uvw[3]) const +{ // Determine projection of direction onto normal and squared magnitude of // normal. double norm[3]; @@ -166,14 +169,16 @@ Surface::reflect(const double xyz[3], double uvw[3]) const { // The template parameter indicates the axis normal to the plane. template double -axis_aligned_plane_evaluate(const double xyz[3], double offset) { +axis_aligned_plane_evaluate(const double xyz[3], double offset) +{ return xyz[i] - offset; } // The template parameter indicates the axis normal to the plane. template double axis_aligned_plane_distance(const double xyz[3], const double uvw[3], - bool coincident, double offset) { + bool coincident, double offset) +{ const double f = offset - xyz[i]; if (coincident or fabs(f) < FP_COINCIDENT or uvw[i] == 0.0) return INFTY; const double d = f / uvw[i]; @@ -184,7 +189,8 @@ axis_aligned_plane_distance(const double xyz[3], const double uvw[3], // The first template parameter indicates the axis normal to the plane. The // other two parameters indicate the other two axes. template void -axis_aligned_plane_normal(const double xyz[3], double uvw[3]) { +axis_aligned_plane_normal(const double xyz[3], double uvw[3]) +{ uvw[i1] = 1.0; uvw[i2] = 0.0; uvw[i3] = 0.0; @@ -197,7 +203,8 @@ axis_aligned_plane_normal(const double xyz[3], double uvw[3]) { //! The plane is described by the equation \f$x - x_0 = 0\f$ //============================================================================== -class SurfaceXPlane : public Surface { +class SurfaceXPlane : public Surface +{ double x0; public: SurfaceXPlane(pugi::xml_node surf_node); @@ -207,20 +214,24 @@ public: void normal(const double xyz[3], double uvw[3]) const; }; -SurfaceXPlane::SurfaceXPlane(pugi::xml_node surf_node) { +SurfaceXPlane::SurfaceXPlane(pugi::xml_node surf_node) +{ read_coeffs(surf_node, x0); } -inline double SurfaceXPlane::evaluate(const double xyz[3]) const { +inline double SurfaceXPlane::evaluate(const double xyz[3]) const +{ return axis_aligned_plane_evaluate<0>(xyz, x0); } inline double SurfaceXPlane::distance(const double xyz[3], const double uvw[3], - bool coincident) const { + bool coincident) const +{ return axis_aligned_plane_distance<0>(xyz, uvw, coincident, x0); } -inline void SurfaceXPlane::normal(const double xyz[3], double uvw[3]) const { +inline void SurfaceXPlane::normal(const double xyz[3], double uvw[3]) const +{ axis_aligned_plane_normal<0, 1, 2>(xyz, uvw); } @@ -231,7 +242,8 @@ inline void SurfaceXPlane::normal(const double xyz[3], double uvw[3]) const { //! The plane is described by the equation \f$y - y_0 = 0\f$ //============================================================================== -class SurfaceYPlane : public Surface { +class SurfaceYPlane : public Surface +{ double y0; public: SurfaceYPlane(pugi::xml_node surf_node); @@ -241,20 +253,24 @@ public: void normal(const double xyz[3], double uvw[3]) const; }; -SurfaceYPlane::SurfaceYPlane(pugi::xml_node surf_node) { +SurfaceYPlane::SurfaceYPlane(pugi::xml_node surf_node) +{ read_coeffs(surf_node, y0); } -inline double SurfaceYPlane::evaluate(const double xyz[3]) const { +inline double SurfaceYPlane::evaluate(const double xyz[3]) const +{ return axis_aligned_plane_evaluate<1>(xyz, y0); } inline double SurfaceYPlane::distance(const double xyz[3], const double uvw[3], - bool coincident) const { + bool coincident) const +{ return axis_aligned_plane_distance<1>(xyz, uvw, coincident, y0); } -inline void SurfaceYPlane::normal(const double xyz[3], double uvw[3]) const { +inline void SurfaceYPlane::normal(const double xyz[3], double uvw[3]) const +{ axis_aligned_plane_normal<1, 0, 2>(xyz, uvw); } @@ -265,7 +281,8 @@ inline void SurfaceYPlane::normal(const double xyz[3], double uvw[3]) const { //! The plane is described by the equation \f$z - z_0 = 0\f$ //============================================================================== -class SurfaceZPlane : public Surface { +class SurfaceZPlane : public Surface +{ double z0; public: SurfaceZPlane(pugi::xml_node surf_node); @@ -275,20 +292,24 @@ public: void normal(const double xyz[3], double uvw[3]) const; }; -SurfaceZPlane::SurfaceZPlane(pugi::xml_node surf_node) { +SurfaceZPlane::SurfaceZPlane(pugi::xml_node surf_node) +{ read_coeffs(surf_node, z0); } -inline double SurfaceZPlane::evaluate(const double xyz[3]) const { +inline double SurfaceZPlane::evaluate(const double xyz[3]) const +{ return axis_aligned_plane_evaluate<2>(xyz, z0); } inline double SurfaceZPlane::distance(const double xyz[3], const double uvw[3], - bool coincident) const { + bool coincident) const +{ return axis_aligned_plane_distance<2>(xyz, uvw, coincident, z0); } -inline void SurfaceZPlane::normal(const double xyz[3], double uvw[3]) const { +inline void SurfaceZPlane::normal(const double xyz[3], double uvw[3]) const +{ axis_aligned_plane_normal<2, 0, 1>(xyz, uvw); } @@ -299,7 +320,8 @@ inline void SurfaceZPlane::normal(const double xyz[3], double uvw[3]) const { //! The plane is described by the equation \f$A x + B y + C z - D = 0\f$ //============================================================================== -class SurfacePlane : public Surface { +class SurfacePlane : public Surface +{ double A, B, C, D; public: SurfacePlane(pugi::xml_node surf_node); @@ -309,18 +331,21 @@ public: void normal(const double xyz[3], double uvw[3]) const; }; -SurfacePlane::SurfacePlane(pugi::xml_node surf_node) { +SurfacePlane::SurfacePlane(pugi::xml_node surf_node) +{ read_coeffs(surf_node, A, B, C, D); } double -SurfacePlane::evaluate(const double xyz[3]) const { +SurfacePlane::evaluate(const double xyz[3]) const +{ return A*xyz[0] + B*xyz[1] + C*xyz[2] - D; } double SurfacePlane::distance(const double xyz[3], const double uvw[3], - bool coincident) const { + bool coincident) const +{ const double f = A*xyz[0] + B*xyz[1] + C*xyz[2] - D; const double projection = A*uvw[0] + B*uvw[1] + C*uvw[2]; if (coincident or fabs(f) < FP_COINCIDENT or projection == 0.0) { @@ -333,7 +358,8 @@ SurfacePlane::distance(const double xyz[3], const double uvw[3], } void -SurfacePlane::normal(const double xyz[3], double uvw[3]) const { +SurfacePlane::normal(const double xyz[3], double uvw[3]) const +{ uvw[0] = A; uvw[1] = B; uvw[2] = C; @@ -348,7 +374,8 @@ SurfacePlane::normal(const double xyz[3], double uvw[3]) const { // respectively. template double axis_aligned_cylinder_evaluate(const double xyz[3], double offset1, - double offset2, double radius) { + double offset2, double radius) +{ const double xyz1 = xyz[i1] - offset1; const double xyz2 = xyz[i2] - offset2; return xyz1*xyz1 + xyz2*xyz2 - radius*radius; @@ -359,7 +386,8 @@ axis_aligned_cylinder_evaluate(const double xyz[3], double offset1, // should correspond with i2 and i3, respectively. template double axis_aligned_cylinder_distance(const double xyz[3], const double uvw[3], - bool coincident, double offset1, double offset2, double radius) { + bool coincident, double offset1, double offset2, double radius) +{ const double a = 1.0 - uvw[i1]*uvw[i1]; // u^2 + v^2 if (a == 0.0) return INFTY; @@ -404,7 +432,8 @@ axis_aligned_cylinder_distance(const double xyz[3], const double uvw[3], // should correspond with i2 and i3, respectively. template void axis_aligned_cylinder_normal(const double xyz[3], double uvw[3], double offset1, - double offset2) { + double offset2) +{ uvw[i2] = 2.0 * (xyz[i2] - offset1); uvw[i3] = 2.0 * (xyz[i3] - offset2); uvw[i1] = 0.0; @@ -418,7 +447,8 @@ axis_aligned_cylinder_normal(const double xyz[3], double uvw[3], double offset1, //! \f$(y - y_0)^2 + (z - z_0)^2 - R^2 = 0\f$ //============================================================================== -class SurfaceXCylinder : public Surface { +class SurfaceXCylinder : public Surface +{ double y0, z0, r; public: SurfaceXCylinder(pugi::xml_node surf_node); @@ -428,21 +458,25 @@ public: void normal(const double xyz[3], double uvw[3]) const; }; -SurfaceXCylinder::SurfaceXCylinder(pugi::xml_node surf_node) { +SurfaceXCylinder::SurfaceXCylinder(pugi::xml_node surf_node) +{ read_coeffs(surf_node, y0, z0, r); } -inline double SurfaceXCylinder::evaluate(const double xyz[3]) const { +inline double SurfaceXCylinder::evaluate(const double xyz[3]) const +{ return axis_aligned_cylinder_evaluate<1, 2>(xyz, y0, z0, r); } inline double SurfaceXCylinder::distance(const double xyz[3], - const double uvw[3], bool coincident) const { + const double uvw[3], bool coincident) const +{ return axis_aligned_cylinder_distance<0, 1, 2>(xyz, uvw, coincident, y0, z0, r); } -inline void SurfaceXCylinder::normal(const double xyz[3], double uvw[3]) const { +inline void SurfaceXCylinder::normal(const double xyz[3], double uvw[3]) const +{ axis_aligned_cylinder_normal<0, 1, 2>(xyz, uvw, y0, z0); } @@ -454,7 +488,8 @@ inline void SurfaceXCylinder::normal(const double xyz[3], double uvw[3]) const { //! \f$(x - x_0)^2 + (z - z_0)^2 - R^2 = 0\f$ //============================================================================== -class SurfaceYCylinder : public Surface { +class SurfaceYCylinder : public Surface +{ double x0, z0, r; public: SurfaceYCylinder(pugi::xml_node surf_node); @@ -464,21 +499,25 @@ public: void normal(const double xyz[3], double uvw[3]) const; }; -SurfaceYCylinder::SurfaceYCylinder(pugi::xml_node surf_node) { +SurfaceYCylinder::SurfaceYCylinder(pugi::xml_node surf_node) +{ read_coeffs(surf_node, x0, z0, r); } -inline double SurfaceYCylinder::evaluate(const double xyz[3]) const { +inline double SurfaceYCylinder::evaluate(const double xyz[3]) const +{ return axis_aligned_cylinder_evaluate<0, 2>(xyz, x0, z0, r); } inline double SurfaceYCylinder::distance(const double xyz[3], - const double uvw[3], bool coincident) const { + const double uvw[3], bool coincident) const +{ return axis_aligned_cylinder_distance<1, 0, 2>(xyz, uvw, coincident, x0, z0, r); } -inline void SurfaceYCylinder::normal(const double xyz[3], double uvw[3]) const { +inline void SurfaceYCylinder::normal(const double xyz[3], double uvw[3]) const +{ axis_aligned_cylinder_normal<1, 0, 2>(xyz, uvw, x0, z0); } @@ -490,7 +529,8 @@ inline void SurfaceYCylinder::normal(const double xyz[3], double uvw[3]) const { //! \f$(x - x_0)^2 + (y - y_0)^2 - R^2 = 0\f$ //============================================================================== -class SurfaceZCylinder : public Surface { +class SurfaceZCylinder : public Surface +{ double x0, y0, r; public: SurfaceZCylinder(pugi::xml_node surf_node); @@ -500,21 +540,25 @@ public: void normal(const double xyz[3], double uvw[3]) const; }; -SurfaceZCylinder::SurfaceZCylinder(pugi::xml_node surf_node) { +SurfaceZCylinder::SurfaceZCylinder(pugi::xml_node surf_node) +{ read_coeffs(surf_node, x0, y0, r); } -inline double SurfaceZCylinder::evaluate(const double xyz[3]) const { +inline double SurfaceZCylinder::evaluate(const double xyz[3]) const +{ return axis_aligned_cylinder_evaluate<0, 1>(xyz, x0, y0, r); } inline double SurfaceZCylinder::distance(const double xyz[3], - const double uvw[3], bool coincident) const { + const double uvw[3], bool coincident) const +{ return axis_aligned_cylinder_distance<2, 0, 1>(xyz, uvw, coincident, x0, y0, r); } -inline void SurfaceZCylinder::normal(const double xyz[3], double uvw[3]) const { +inline void SurfaceZCylinder::normal(const double xyz[3], double uvw[3]) const +{ axis_aligned_cylinder_normal<2, 0, 1>(xyz, uvw, x0, y0); } @@ -526,7 +570,8 @@ inline void SurfaceZCylinder::normal(const double xyz[3], double uvw[3]) const { //! \f$(x - x_0)^2 + (y - y_0)^2 + (z - z_0)^2 - R^2 = 0\f$ //============================================================================== -class SurfaceSphere : public Surface { +class SurfaceSphere : public Surface +{ double x0, y0, z0, r; public: SurfaceSphere(pugi::xml_node surf_node); @@ -536,11 +581,13 @@ public: void normal(const double xyz[3], double uvw[3]) const; }; -SurfaceSphere::SurfaceSphere(pugi::xml_node surf_node) { +SurfaceSphere::SurfaceSphere(pugi::xml_node surf_node) +{ read_coeffs(surf_node, x0, y0, z0, r); } -double SurfaceSphere::evaluate(const double xyz[3]) const { +double SurfaceSphere::evaluate(const double xyz[3]) const +{ const double x = xyz[0] - x0; const double y = xyz[1] - y0; const double z = xyz[2] - z0; @@ -548,7 +595,8 @@ double SurfaceSphere::evaluate(const double xyz[3]) const { } double SurfaceSphere::distance(const double xyz[3], const double uvw[3], - bool coincident) const { + bool coincident) const +{ const double x = xyz[0] - x0; const double y = xyz[1] - y0; const double z = xyz[2] - z0; @@ -585,7 +633,8 @@ double SurfaceSphere::distance(const double xyz[3], const double uvw[3], } } -inline void SurfaceSphere::normal(const double xyz[3], double uvw[3]) const { +inline void SurfaceSphere::normal(const double xyz[3], double uvw[3]) const +{ uvw[0] = 2.0 * (xyz[0] - x0); uvw[1] = 2.0 * (xyz[1] - y0); uvw[2] = 2.0 * (xyz[2] - z0); @@ -600,7 +649,8 @@ inline void SurfaceSphere::normal(const double xyz[3], double uvw[3]) const { // and offset3 should correspond with i1, i2, and i3, respectively. template double axis_aligned_cone_evaluate(const double xyz[3], double offset1, - double offset2, double offset3, double radius_sq) { + double offset2, double offset3, double radius_sq) +{ const double xyz1 = xyz[i1] - offset1; const double xyz2 = xyz[i2] - offset2; const double xyz3 = xyz[i3] - offset3; @@ -613,7 +663,8 @@ axis_aligned_cone_evaluate(const double xyz[3], double offset1, template double axis_aligned_cone_distance(const double xyz[3], const double uvw[3], bool coincident, double offset1, double offset2, double offset3, - double radius_sq) { + double radius_sq) +{ const double xyz1 = xyz[i1] - offset1; const double xyz2 = xyz[i2] - offset2; const double xyz3 = xyz[i3] - offset3; @@ -665,7 +716,8 @@ axis_aligned_cone_distance(const double xyz[3], const double uvw[3], // and offset3 should correspond with i1, i2, and i3, respectively. template void axis_aligned_cone_normal(const double xyz[3], double uvw[3], double offset1, - double offset2, double offset3, double radius_sq) { + double offset2, double offset3, double radius_sq) +{ uvw[i1] = -2.0 * radius_sq * (xyz[i1] - offset1); uvw[i2] = 2.0 * (xyz[i2] - offset2); uvw[i3] = 2.0 * (xyz[i3] - offset3); @@ -679,7 +731,8 @@ axis_aligned_cone_normal(const double xyz[3], double uvw[3], double offset1, //! \f$(y - y_0)^2 + (z - z_0)^2 - R^2 (x - x_0)^2 = 0\f$ //============================================================================== -class SurfaceXCone : public Surface { +class SurfaceXCone : public Surface +{ double x0, y0, z0, r_sq; public: SurfaceXCone(pugi::xml_node surf_node); @@ -689,21 +742,25 @@ public: void normal(const double xyz[3], double uvw[3]) const; }; -SurfaceXCone::SurfaceXCone(pugi::xml_node surf_node) { +SurfaceXCone::SurfaceXCone(pugi::xml_node surf_node) +{ read_coeffs(surf_node, x0, y0, z0, r_sq); } -inline double SurfaceXCone::evaluate(const double xyz[3]) const { +inline double SurfaceXCone::evaluate(const double xyz[3]) const +{ return axis_aligned_cone_evaluate<0, 1, 2>(xyz, x0, y0, z0, r_sq); } inline double SurfaceXCone::distance(const double xyz[3], - const double uvw[3], bool coincident) const { + const double uvw[3], bool coincident) const +{ return axis_aligned_cone_distance<0, 1, 2>(xyz, uvw, coincident, x0, y0, z0, r_sq); } -inline void SurfaceXCone::normal(const double xyz[3], double uvw[3]) const { +inline void SurfaceXCone::normal(const double xyz[3], double uvw[3]) const +{ axis_aligned_cone_normal<0, 1, 2>(xyz, uvw, x0, y0, z0, r_sq); } @@ -715,7 +772,8 @@ inline void SurfaceXCone::normal(const double xyz[3], double uvw[3]) const { //! \f$(x - x_0)^2 + (z - z_0)^2 - R^2 (y - y_0)^2 = 0\f$ //============================================================================== -class SurfaceYCone : public Surface { +class SurfaceYCone : public Surface +{ double x0, y0, z0, r_sq; public: SurfaceYCone(pugi::xml_node surf_node); @@ -725,21 +783,25 @@ public: void normal(const double xyz[3], double uvw[3]) const; }; -SurfaceYCone::SurfaceYCone(pugi::xml_node surf_node) { +SurfaceYCone::SurfaceYCone(pugi::xml_node surf_node) +{ read_coeffs(surf_node, x0, y0, z0, r_sq); } -inline double SurfaceYCone::evaluate(const double xyz[3]) const { +inline double SurfaceYCone::evaluate(const double xyz[3]) const +{ return axis_aligned_cone_evaluate<1, 0, 2>(xyz, y0, x0, z0, r_sq); } inline double SurfaceYCone::distance(const double xyz[3], - const double uvw[3], bool coincident) const { + const double uvw[3], bool coincident) const +{ return axis_aligned_cone_distance<1, 0, 2>(xyz, uvw, coincident, y0, x0, z0, r_sq); } -inline void SurfaceYCone::normal(const double xyz[3], double uvw[3]) const { +inline void SurfaceYCone::normal(const double xyz[3], double uvw[3]) const +{ axis_aligned_cone_normal<1, 0, 2>(xyz, uvw, y0, x0, z0, r_sq); } @@ -751,7 +813,8 @@ inline void SurfaceYCone::normal(const double xyz[3], double uvw[3]) const { //! \f$(x - x_0)^2 + (y - y_0)^2 - R^2 (z - z_0)^2 = 0\f$ //============================================================================== -class SurfaceZCone : public Surface { +class SurfaceZCone : public Surface +{ double x0, y0, z0, r_sq; public: SurfaceZCone(pugi::xml_node surf_node); @@ -761,21 +824,25 @@ public: void normal(const double xyz[3], double uvw[3]) const; }; -SurfaceZCone::SurfaceZCone(pugi::xml_node surf_node) { +SurfaceZCone::SurfaceZCone(pugi::xml_node surf_node) +{ read_coeffs(surf_node, x0, y0, z0, r_sq); } -inline double SurfaceZCone::evaluate(const double xyz[3]) const { +inline double SurfaceZCone::evaluate(const double xyz[3]) const +{ return axis_aligned_cone_evaluate<2, 0, 1>(xyz, z0, x0, y0, r_sq); } inline double SurfaceZCone::distance(const double xyz[3], - const double uvw[3], bool coincident) const { + const double uvw[3], bool coincident) const +{ return axis_aligned_cone_distance<2, 0, 1>(xyz, uvw, coincident, z0, x0, y0, r_sq); } -inline void SurfaceZCone::normal(const double xyz[3], double uvw[3]) const { +inline void SurfaceZCone::normal(const double xyz[3], double uvw[3]) const +{ axis_aligned_cone_normal<2, 0, 1>(xyz, uvw, z0, x0, y0, r_sq); } @@ -786,7 +853,8 @@ inline void SurfaceZCone::normal(const double xyz[3], double uvw[3]) const { //! \f$A x^2 + B y^2 + C z^2 + D x y + E y z + F x z + G x + H y + J z + K = 0\f$ //============================================================================== -class SurfaceQuadric : public Surface { +class SurfaceQuadric : public Surface +{ // Ax^2 + By^2 + Cz^2 + Dxy + Eyz + Fxz + Gx + Hy + Jz + K = 0 double A, B, C, D, E, F, G, H, J, K; public: @@ -797,12 +865,14 @@ public: void normal(const double xyz[3], double uvw[3]) const; }; -SurfaceQuadric::SurfaceQuadric(pugi::xml_node surf_node) { +SurfaceQuadric::SurfaceQuadric(pugi::xml_node surf_node) +{ read_coeffs(surf_node, A, B, C, D, E, F, G, H, J, K); } double -SurfaceQuadric::evaluate(const double xyz[3]) const { +SurfaceQuadric::evaluate(const double xyz[3]) const +{ const double &x = xyz[0]; const double &y = xyz[1]; const double &z = xyz[2]; @@ -813,7 +883,8 @@ SurfaceQuadric::evaluate(const double xyz[3]) const { double SurfaceQuadric::distance(const double xyz[3], - const double uvw[3], bool coincident) const { + const double uvw[3], bool coincident) const +{ const double &x = xyz[0]; const double &y = xyz[1]; const double &z = xyz[2]; @@ -866,7 +937,8 @@ SurfaceQuadric::distance(const double xyz[3], } void -SurfaceQuadric::normal(const double xyz[3], double uvw[3]) const { +SurfaceQuadric::normal(const double xyz[3], double uvw[3]) const +{ const double &x = xyz[0]; const double &y = xyz[1]; const double &z = xyz[2]; @@ -878,7 +950,8 @@ SurfaceQuadric::normal(const double xyz[3], double uvw[3]) const { //============================================================================== extern "C" void -read_surfaces(pugi::xml_node *node) { +read_surfaces(pugi::xml_node *node) +{ // Count the number of surfaces. int n_surfaces = 0; for (pugi::xml_node surf_node = node->child("surface"); surf_node; @@ -952,16 +1025,19 @@ read_surfaces(pugi::xml_node *node) { //============================================================================== extern "C" bool -surface_sense(int surf_ind, double xyz[3], double uvw[3]) { +surface_sense(int surf_ind, double xyz[3], double uvw[3]) +{ return surfaces_c[surf_ind]->sense(xyz, uvw); } extern "C" double -surface_distance(int surf_ind, double xyz[3], double uvw[3], bool coincident) { +surface_distance(int surf_ind, double xyz[3], double uvw[3], bool coincident) +{ return surfaces_c[surf_ind]->distance(xyz, uvw, coincident); } extern "C" void -surface_normal(int surf_ind, double xyz[3], double uvw[3]) { +surface_normal(int surf_ind, double xyz[3], double uvw[3]) +{ return surfaces_c[surf_ind]->normal(xyz, uvw); } From 163b6e3de5a7235e1152926880e5474ec44af8fb Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Wed, 11 Oct 2017 16:58:00 -0400 Subject: [PATCH 10/74] Remove Fortran code for surface distance and sense --- src/geometry.F90 | 67 ++--- src/surface_header.C | 2 +- src/surface_header.F90 | 560 +---------------------------------------- 3 files changed, 23 insertions(+), 606 deletions(-) diff --git a/src/geometry.F90 b/src/geometry.F90 index 8a449a284b..873582dec9 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -15,34 +15,34 @@ module geometry implicit none interface - function surface_sense_c(surf_ind, xyz, uvw) & + pure function surface_sense_c(surf_ind, xyz, uvw) & bind(C, name='surface_sense') result(sense) use ISO_C_BINDING implicit none - integer(C_INT), value :: surf_ind; - real(C_DOUBLE) :: xyz(3); - real(C_DOUBLE) :: uvw(3); - logical(C_BOOL) :: sense; + integer(C_INT), intent(in), value :: surf_ind; + real(C_DOUBLE), intent(in) :: xyz(3); + real(C_DOUBLE), intent(in) :: uvw(3); + logical(C_BOOL) :: sense; end function surface_sense_c - function surface_distance_c(surf_ind, xyz, uvw, coincident) & + pure function surface_distance_c(surf_ind, xyz, uvw, coincident) & bind(C, name='surface_distance') result(d) use ISO_C_BINDING implicit none - integer(C_INT), value :: surf_ind; - real(C_DOUBLE) :: xyz(3); - real(C_DOUBLE) :: uvw(3); - logical(C_BOOL), value :: coincident; - real(C_DOUBLE) :: d; + integer(C_INT), intent(in), value :: surf_ind; + real(C_DOUBLE), intent(in) :: xyz(3); + real(C_DOUBLE), intent(in) :: uvw(3); + logical(C_BOOL), intent(in), value :: coincident; + real(C_DOUBLE) :: d; end function surface_distance_c - subroutine surface_normal_c(surf_ind, xyz, uvw) & + pure subroutine surface_normal_c(surf_ind, xyz, uvw) & bind(C, name='surface_normal') use ISO_C_BINDING implicit none - integer(C_INT), value :: surf_ind; - real(C_DOUBLE) :: xyz(3); - real(C_DOUBLE) :: uvw(3); + integer(C_INT), intent(in), value :: surf_ind; + real(C_DOUBLE), intent(in) :: xyz(3); + real(C_DOUBLE), intent(out) :: uvw(3); end subroutine surface_normal_c end interface @@ -62,8 +62,7 @@ contains ! expression using a stack, similar to how a RPN calculator would work. !=============================================================================== - !pure function cell_contains(c, p) result(in_cell) - function cell_contains(c, p) result(in_cell) + pure function cell_contains(c, p) result(in_cell) type(Cell), intent(in) :: c type(Particle), intent(in) :: p logical :: in_cell @@ -75,8 +74,7 @@ contains end if end function cell_contains - !pure function simple_cell_contains(c, p) result(in_cell) - function simple_cell_contains(c, p) result(in_cell) + pure function simple_cell_contains(c, p) result(in_cell) type(Cell), intent(in) :: c type(Particle), intent(in) :: p logical :: in_cell @@ -84,8 +82,6 @@ contains integer :: i integer :: token logical :: actual_sense ! sense of particle wrt surface - logical :: alt_sense - real(8) :: uvw1(3), uvw2(3) in_cell = .true. do i = 1, size(c%rpn) @@ -101,25 +97,8 @@ contains in_cell = .false. exit else - actual_sense = surfaces(abs(token))%obj%sense(& + actual_sense = surface_sense_c(abs(token)-1, & p%coord(p%n_coord)%xyz, p%coord(p%n_coord)%uvw) - alt_sense = surface_sense_c(abs(token)-1, & - p%coord(p%n_coord)%xyz, p%coord(p%n_coord)%uvw) - if (actual_sense .neqv. alt_sense) then - write(*, *) surfaces(abs(token)) % obj % id - write(*, *) p % coord (p % n_coord) % xyz - write(*, *) p % coord (p % n_coord) % uvw - write(*, *) actual_sense, alt_sense - call fatal_error("") - end if - uvw1 = surfaces(abs(token))%obj%normal(p%coord(p%n_coord)%xyz) - call surface_normal_c(abs(token)-1, p%coord(p%n_coord)%xyz, uvw2) - if (.not. all(uvw1 - uvw2 == ZERO)) then - write(*, *) "Surface normals don't match" - write(*, *) uvw1 - write(*, *) uvw2 - call fatal_error("") - end if if (actual_sense .neqv. (token > 0)) then in_cell = .false. exit @@ -167,7 +146,7 @@ contains elseif (-token == p%surface) then stack(i_stack) = .false. else - actual_sense = surfaces(abs(token))%obj%sense(& + actual_sense = surface_sense_c(abs(token)-1, & p%coord(p%n_coord)%xyz, p%coord(p%n_coord)%uvw) stack(i_stack) = (actual_sense .eqv. (token > 0)) end if @@ -539,7 +518,6 @@ contains type(Cell), pointer :: c class(Surface), pointer :: surf class(Lattice), pointer :: lat - real(8) :: d_alt ! inialize distance to infinity (huge) dist = INFINITY @@ -573,13 +551,8 @@ contains if (index_surf >= OP_UNION) cycle ! Calculate distance to surface - surf => surfaces(index_surf) % obj - d = surf % distance(p % coord(j) % xyz, p % coord(j) % uvw, coincident) - d_alt = surface_distance_c(index_surf-1, p % coord(j) % xyz, & + d = surface_distance_c(index_surf-1, p % coord(j) % xyz, & p % coord(j) % uvw, logical(coincident, kind=C_BOOL)) - if (d /= d_alt) then - write(*, *) d, d_alt - end if ! Check if calculated distance is new minimum if (d < d_surf) then diff --git a/src/surface_header.C b/src/surface_header.C index 6992c2e2ac..cf200e5e46 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -33,7 +33,7 @@ const char* get_coeff_str(pugi::xml_node surf_node) return surf_node.child_value("coeffs"); } else { std::cout << "ERROR: Found a surface with no coefficients" << std::endl; - return NULL; + return nullptr; } } diff --git a/src/surface_header.F90 b/src/surface_header.F90 index ed4ef86e09..b0da37c1e0 100644 --- a/src/surface_header.F90 +++ b/src/surface_header.F90 @@ -21,10 +21,8 @@ module surface_header integer :: i_periodic = NONE ! Index of corresponding periodic surface character(len=104) :: name = "" ! User-defined name contains - procedure :: sense procedure :: reflect procedure(surface_evaluate_), deferred :: evaluate - procedure(surface_distance_), deferred :: distance procedure(surface_normal_), deferred :: normal end type Surface @@ -36,15 +34,6 @@ module surface_header real(8) :: f end function surface_evaluate_ - pure function surface_distance_(this, xyz, uvw, coincident) result(d) - import Surface - class(Surface), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8), intent(in) :: uvw(3) - logical, intent(in) :: coincident - real(8) :: d - end function surface_distance_ - pure function surface_normal_(this, xyz) result(uvw) import Surface class(Surface), intent(in) :: this @@ -63,8 +52,8 @@ module surface_header !=============================================================================== ! All the derived types below are extensions of the abstract Surface type. They -! inherent the reflect() and sense() type-bound procedures and must implement -! evaluate(), distance(), and normal() +! inherent the reflect() type-bound procedure and must implement evaluate(), +! and normal() !=============================================================================== type, extends(Surface) :: SurfaceXPlane @@ -72,7 +61,6 @@ module surface_header real(8) :: x0 contains procedure :: evaluate => x_plane_evaluate - procedure :: distance => x_plane_distance procedure :: normal => x_plane_normal end type SurfaceXPlane @@ -81,7 +69,6 @@ module surface_header real(8) :: y0 contains procedure :: evaluate => y_plane_evaluate - procedure :: distance => y_plane_distance procedure :: normal => y_plane_normal end type SurfaceYPlane @@ -90,7 +77,6 @@ module surface_header real(8) :: z0 contains procedure :: evaluate => z_plane_evaluate - procedure :: distance => z_plane_distance procedure :: normal => z_plane_normal end type SurfaceZPlane @@ -102,7 +88,6 @@ module surface_header real(8) :: D contains procedure :: evaluate => plane_evaluate - procedure :: distance => plane_distance procedure :: normal => plane_normal end type SurfacePlane @@ -113,7 +98,6 @@ module surface_header real(8) :: r contains procedure :: evaluate => x_cylinder_evaluate - procedure :: distance => x_cylinder_distance procedure :: normal => x_cylinder_normal end type SurfaceXCylinder @@ -124,7 +108,6 @@ module surface_header real(8) :: r contains procedure :: evaluate => y_cylinder_evaluate - procedure :: distance => y_cylinder_distance procedure :: normal => y_cylinder_normal end type SurfaceYCylinder @@ -135,7 +118,6 @@ module surface_header real(8) :: r contains procedure :: evaluate => z_cylinder_evaluate - procedure :: distance => z_cylinder_distance procedure :: normal => z_cylinder_normal end type SurfaceZCylinder @@ -147,7 +129,6 @@ module surface_header real(8) :: r contains procedure :: evaluate => sphere_evaluate - procedure :: distance => sphere_distance procedure :: normal => sphere_normal end type SurfaceSphere @@ -159,7 +140,6 @@ module surface_header real(8) :: r2 contains procedure :: evaluate => x_cone_evaluate - procedure :: distance => x_cone_distance procedure :: normal => x_cone_normal end type SurfaceXCone @@ -171,7 +151,6 @@ module surface_header real(8) :: r2 contains procedure :: evaluate => y_cone_evaluate - procedure :: distance => y_cone_distance procedure :: normal => y_cone_normal end type SurfaceYCone @@ -183,7 +162,6 @@ module surface_header real(8) :: r2 contains procedure :: evaluate => z_cone_evaluate - procedure :: distance => z_cone_distance procedure :: normal => z_cone_normal end type SurfaceZCone @@ -192,7 +170,6 @@ module surface_header real(8) :: A, B, C, D, E, F, G, H, J, K contains procedure :: evaluate => quadric_evaluate - procedure :: distance => quadric_distance procedure :: normal => quadric_normal end type SurfaceQuadric @@ -205,36 +182,6 @@ module surface_header contains -!=============================================================================== -! SENSE determines whether a point is on the 'positive' or 'negative' side of a -! surface. This routine is crucial for determining what cell a particular point -! is in. The positive side is indicated by a returned value of .true. and the -! negative side is indicated by a returned value of .false. -!=============================================================================== - - pure function sense(this, xyz, uvw) result(s) - class(Surface), intent(in) :: this ! surface - real(8), intent(in) :: xyz(3) - real(8), intent(in) :: uvw(3) - logical :: s ! sense of particle - - real(8) :: f ! surface function evaluated at point - - ! Evaluate the surface equation at the particle's coordinates to determine - ! which side the particle is on - f = this%evaluate(xyz) - - ! Check which side of surface the point is on - if (abs(f) < FP_COINCIDENT) then - ! Particle may be coincident with this surface. To determine the sense, we - ! look at the direction of the particle relative to the surface normal (by - ! default in the positive direction) via their dot product. - s = (dot_product(uvw, this%normal(xyz)) > ZERO) - else - s = (f > ZERO) - end if - end function sense - !=============================================================================== ! REFLECT determines the direction a particle will travel if it is specularly ! reflected from the surface at a given position and direction. The position is @@ -275,24 +222,6 @@ contains f = xyz(1) - this%x0 end function x_plane_evaluate - pure function x_plane_distance(this, xyz, uvw, coincident) result(d) - class(SurfaceXPlane), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8), intent(in) :: uvw(3) - logical, intent(in) :: coincident - real(8) :: d - - real(8) :: f - - f = this%x0 - xyz(1) - if (coincident .or. abs(f) < FP_COINCIDENT .or. uvw(1) == ZERO) then - d = INFINITY - else - d = f/uvw(1) - if (d < ZERO) d = INFINITY - end if - end function x_plane_distance - pure function x_plane_normal(this, xyz) result(uvw) class(SurfaceXPlane), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -313,24 +242,6 @@ contains f = xyz(2) - this%y0 end function y_plane_evaluate - pure function y_plane_distance(this, xyz, uvw, coincident) result(d) - class(SurfaceYPlane), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8), intent(in) :: uvw(3) - logical, intent(in) :: coincident - real(8) :: d - - real(8) :: f - - f = this%y0 - xyz(2) - if (coincident .or. abs(f) < FP_COINCIDENT .or. uvw(2) == ZERO) then - d = INFINITY - else - d = f/uvw(2) - if (d < ZERO) d = INFINITY - end if - end function y_plane_distance - pure function y_plane_normal(this, xyz) result(uvw) class(SurfaceYPlane), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -353,24 +264,6 @@ contains end function z_plane_evaluate - pure function z_plane_distance(this, xyz, uvw, coincident) result(d) - class(SurfaceZPlane), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8), intent(in) :: uvw(3) - logical, intent(in) :: coincident - real(8) :: d - - real(8) :: f - - f = this%z0 - xyz(3) - if (coincident .or. abs(f) < FP_COINCIDENT .or. uvw(3) == ZERO) then - d = INFINITY - else - d = f/uvw(3) - if (d < ZERO) d = INFINITY - end if - end function z_plane_distance - pure function z_plane_normal(this, xyz) result(uvw) class(SurfaceZPlane), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -391,26 +284,6 @@ contains f = this%A*xyz(1) + this%B*xyz(2) + this%C*xyz(3) - this%D end function plane_evaluate - pure function plane_distance(this, xyz, uvw, coincident) result(d) - class(SurfacePlane), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8), intent(in) :: uvw(3) - logical, intent(in) :: coincident - real(8) :: d - - real(8) :: f - real(8) :: projection - - f = this%A*xyz(1) + this%B*xyz(2) + this%C*xyz(3) - this%D - projection = this%A*uvw(1) + this%B*uvw(2) + this%C*uvw(3) - if (coincident .or. abs(f) < FP_COINCIDENT .or. projection == ZERO) then - d = INFINITY - else - d = -f/projection - if (d < ZERO) d = INFINITY - end if - end function plane_distance - pure function plane_normal(this, xyz) result(uvw) class(SurfacePlane), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -435,60 +308,6 @@ contains f = y*y + z*z - this%r*this%r end function x_cylinder_evaluate - pure function x_cylinder_distance(this, xyz, uvw, coincident) result(d) - class(SurfaceXCylinder), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8), intent(in) :: uvw(3) - logical, intent(in) :: coincident - real(8) :: d - - real(8) :: y, z, k, a, c, quad - - a = ONE - uvw(1)*uvw(1) ! v^2 + w^2 - if (a == ZERO) then - d = INFINITY - else - y = xyz(2) - this%y0 - z = xyz(3) - this%z0 - k = y*uvw(2) + z*uvw(3) - c = y*y + z*z - this%r*this%r - quad = k*k - a*c - - if (quad < ZERO) then - ! no intersection with cylinder - - d = INFINITY - - elseif (coincident .or. abs(c) < FP_COINCIDENT) then - ! particle is on the cylinder, thus one distance is positive/negative - ! and the other is zero. The sign of k determines if we are facing in or - ! out - - if (k >= ZERO) then - d = INFINITY - else - d = (-k + sqrt(quad))/a - end if - - elseif (c < ZERO) then - ! particle is inside the cylinder, thus one distance must be negative - ! and one must be positive. The positive distance will be the one with - ! negative sign on sqrt(quad) - - d = (-k + sqrt(quad))/a - - else - ! particle is outside the cylinder, thus both distances are either - ! positive or negative. If positive, the smaller distance is the one - ! with positive sign on sqrt(quad) - - d = (-k - sqrt(quad))/a - if (d < ZERO) d = INFINITY - - end if - end if - end function x_cylinder_distance - pure function x_cylinder_normal(this, xyz) result(uvw) class(SurfaceXCylinder), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -515,60 +334,6 @@ contains f = x*x + z*z - this%r*this%r end function y_cylinder_evaluate - pure function y_cylinder_distance(this, xyz, uvw, coincident) result(d) - class(SurfaceYCylinder), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8), intent(in) :: uvw(3) - logical, intent(in) :: coincident - real(8) :: d - - real(8) :: x, z, k, a, c, quad - - a = ONE - uvw(2)*uvw(2) ! u^2 + w^2 - if (a == ZERO) then - d = INFINITY - else - x = xyz(1) - this%x0 - z = xyz(3) - this%z0 - k = x*uvw(1) + z*uvw(3) - c = x*x + z*z - this%r*this%r - quad = k*k - a*c - - if (quad < ZERO) then - ! no intersection with cylinder - - d = INFINITY - - elseif (coincident .or. abs(c) < FP_COINCIDENT) then - ! particle is on the cylinder, thus one distance is positive/negative - ! and the other is zero. The sign of k determines if we are facing in or - ! out - - if (k >= ZERO) then - d = INFINITY - else - d = (-k + sqrt(quad))/a - end if - - elseif (c < ZERO) then - ! particle is inside the cylinder, thus one distance must be negative - ! and one must be positive. The positive distance will be the one with - ! negative sign on sqrt(quad) - - d = (-k + sqrt(quad))/a - - else - ! particle is outside the cylinder, thus both distances are either - ! positive or negative. If positive, the smaller distance is the one - ! with positive sign on sqrt(quad) - - d = (-k - sqrt(quad))/a - if (d < ZERO) d = INFINITY - - end if - end if - end function y_cylinder_distance - pure function y_cylinder_normal(this, xyz) result(uvw) class(SurfaceYCylinder), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -595,60 +360,6 @@ contains f = x*x + y*y - this%r*this%r end function z_cylinder_evaluate - pure function z_cylinder_distance(this, xyz, uvw, coincident) result(d) - class(SurfaceZCylinder), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8), intent(in) :: uvw(3) - logical, intent(in) :: coincident - real(8) :: d - - real(8) :: x, y, k, a, c, quad - - a = ONE - uvw(3)*uvw(3) ! u^2 + v^2 - if (a == ZERO) then - d = INFINITY - else - x = xyz(1) - this%x0 - y = xyz(2) - this%y0 - k = x*uvw(1) + y*uvw(2) - c = x*x + y*y - this%r*this%r - quad = k*k - a*c - - if (quad < ZERO) then - ! no intersection with cylinder - - d = INFINITY - - elseif (coincident .or. abs(c) < FP_COINCIDENT) then - ! particle is on the cylinder, thus one distance is positive/negative - ! and the other is zero. The sign of k determines if we are facing in or - ! out - - if (k >= ZERO) then - d = INFINITY - else - d = (-k + sqrt(quad))/a - end if - - elseif (c < ZERO) then - ! particle is inside the cylinder, thus one distance must be negative - ! and one must be positive. The positive distance will be the one with - ! negative sign on sqrt(quad) - - d = (-k + sqrt(quad))/a - - else - ! particle is outside the cylinder, thus both distances are either - ! positive or negative. If positive, the smaller distance is the one - ! with positive sign on sqrt(quad) - - d = (-k - sqrt(quad))/a - if (d < ZERO) d = INFINITY - - end if - end if - end function z_cylinder_distance - pure function z_cylinder_normal(this, xyz) result(uvw) class(SurfaceZCylinder), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -676,55 +387,6 @@ contains f = x*x + y*y + z*z - this%r*this%r end function sphere_evaluate - pure function sphere_distance(this, xyz, uvw, coincident) result(d) - class(SurfaceSphere), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8), intent(in) :: uvw(3) - logical, intent(in) :: coincident - real(8) :: d - - real(8) :: x, y, z, k, c, quad - - x = xyz(1) - this%x0 - y = xyz(2) - this%y0 - z = xyz(3) - this%z0 - k = x*uvw(1) + y*uvw(2) + z*uvw(3) - c = x*x + y*y + z*z - this%r*this%r - quad = k*k - c - - if (quad < ZERO) then - ! no intersection with sphere - - d = INFINITY - - elseif (coincident .or. abs(c) < FP_COINCIDENT) then - ! particle is on the sphere, thus one distance is positive/negative and - ! the other is zero. The sign of k determines if we are facing in or out - - if (k >= ZERO) then - d = INFINITY - else - d = -k + sqrt(quad) - end if - - elseif (c < ZERO) then - ! particle is inside the sphere, thus one distance must be negative and - ! one must be positive. The positive distance will be the one with - ! negative sign on sqrt(quad) - - d = -k + sqrt(quad) - - else - ! particle is outside the sphere, thus both distances are either positive - ! or negative. If positive, the smaller distance is the one with positive - ! sign on sqrt(quad) - - d = -k - sqrt(quad) - if (d < ZERO) d = INFINITY - - end if - end function sphere_distance - pure function sphere_normal(this, xyz) result(uvw) class(SurfaceSphere), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -750,59 +412,6 @@ contains f = y*y + z*z - this%r2*x*x end function x_cone_evaluate - pure function x_cone_distance(this, xyz, uvw, coincident) result(d) - class(SurfaceXCone), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8), intent(in) :: uvw(3) - logical, intent(in) :: coincident - real(8) :: d - - real(8) :: x, y, z, k, a, b, c, quad - - x = xyz(1) - this%x0 - y = xyz(2) - this%y0 - z = xyz(3) - this%z0 - a = uvw(2)*uvw(2) + uvw(3)*uvw(3) - this%r2*uvw(1)*uvw(1) - k = y*uvw(2) + z*uvw(3) - this%r2*x*uvw(1) - c = y*y + z*z - this%r2*x*x - quad = k*k - a*c - - if (quad < ZERO) then - ! no intersection with cone - - d = INFINITY - - elseif (coincident .or. abs(c) < FP_COINCIDENT) then - ! particle is on the cone, thus one distance is positive/negative and the - ! other is zero. The sign of k determines which distance is zero and which - ! is not. - - if (k >= ZERO) then - d = (-k - sqrt(quad))/a - else - d = (-k + sqrt(quad))/a - end if - - else - ! calculate both solutions to the quadratic - quad = sqrt(quad) - d = (-k - quad)/a - b = (-k + quad)/a - - ! determine the smallest positive solution - if (d < ZERO) then - if (b > ZERO) then - d = b - end if - else - if (b > ZERO) d = min(d, b) - end if - end if - - ! If the distance was negative, set boundary distance to infinity - if (d <= ZERO) d = INFINITY - end function x_cone_distance - pure function x_cone_normal(this, xyz) result(uvw) class(SurfaceXCone), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -830,59 +439,6 @@ contains f = x*x + z*z - this%r2*y*y end function y_cone_evaluate - pure function y_cone_distance(this, xyz, uvw, coincident) result(d) - class(SurfaceYCone), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8), intent(in) :: uvw(3) - logical, intent(in) :: coincident - real(8) :: d - - real(8) :: x, y, z, k, a, b, c, quad - - x = xyz(1) - this%x0 - y = xyz(2) - this%y0 - z = xyz(3) - this%z0 - a = uvw(1)*uvw(1) + uvw(3)*uvw(3) - this%r2*uvw(2)*uvw(2) - k = x*uvw(1) + z*uvw(3) - this%r2*y*uvw(2) - c = x*x + z*z - this%r2*y*y - quad = k*k - a*c - - if (quad < ZERO) then - ! no intersection with cone - - d = INFINITY - - elseif (coincident .or. abs(c) < FP_COINCIDENT) then - ! particle is on the cone, thus one distance is positive/negative and the - ! other is zero. The sign of k determines which distance is zero and which - ! is not. - - if (k >= ZERO) then - d = (-k - sqrt(quad))/a - else - d = (-k + sqrt(quad))/a - end if - - else - ! calculate both solutions to the quadratic - quad = sqrt(quad) - d = (-k - quad)/a - b = (-k + quad)/a - - ! determine the smallest positive solution - if (d < ZERO) then - if (b > ZERO) then - d = b - end if - else - if (b > ZERO) d = min(d, b) - end if - end if - - ! If the distance was negative, set boundary distance to infinity - if (d <= ZERO) d = INFINITY - end function y_cone_distance - pure function y_cone_normal(this, xyz) result(uvw) class(SurfaceYCone), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -910,59 +466,6 @@ contains f = x*x + y*y - this%r2*z*z end function z_cone_evaluate - pure function z_cone_distance(this, xyz, uvw, coincident) result(d) - class(SurfaceZCone), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8), intent(in) :: uvw(3) - logical, intent(in) :: coincident - real(8) :: d - - real(8) :: x, y, z, k, a, b, c, quad - - x = xyz(1) - this%x0 - y = xyz(2) - this%y0 - z = xyz(3) - this%z0 - a = uvw(1)*uvw(1) + uvw(2)*uvw(2) - this%r2*uvw(3)*uvw(3) - k = x*uvw(1) + y*uvw(2) - this%r2*z*uvw(3) - c = x*x + y*y - this%r2*z*z - quad = k*k - a*c - - if (quad < ZERO) then - ! no intersection with cone - - d = INFINITY - - elseif (coincident .or. abs(c) < FP_COINCIDENT) then - ! particle is on the cone, thus one distance is positive/negative and the - ! other is zero. The sign of k determines which distance is zero and which - ! is not. - - if (k >= ZERO) then - d = (-k - sqrt(quad))/a - else - d = (-k + sqrt(quad))/a - end if - - else - ! calculate both solutions to the quadratic - quad = sqrt(quad) - d = (-k - quad)/a - b = (-k + quad)/a - - ! determine the smallest positive solution - if (d < ZERO) then - if (b > ZERO) then - d = b - end if - else - if (b > ZERO) d = min(d, b) - end if - end if - - ! If the distance was negative, set boundary distance to infinity - if (d <= ZERO) d = INFINITY - end function z_cone_distance - pure function z_cone_normal(this, xyz) result(uvw) class(SurfaceZCone), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -989,65 +492,6 @@ contains end associate end function quadric_evaluate - pure function quadric_distance(this, xyz, uvw, coincident) result(d) - class(SurfaceQuadric), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8), intent(in) :: uvw(3) - logical, intent(in) :: coincident - real(8) :: d - - real(8) :: a, k, c - real(8) :: quad, b - - associate (x => xyz(1), y => xyz(2), z => xyz(3), & - u => uvw(1), v => uvw(2), w => uvw(3)) - - a = this%A*u*u + this%B*v*v + this%C*w*w + this%D*u*v + this%E*v*w + & - this%F*u*w - k = (this%A*u*x + this%B*v*y + this%C*w*z + HALF*(this%D*(u*y + v*x) + & - this%E*(v*z + w*y) + this%F*(w*x + u*z) + this%G*u + this%H*v + & - this%J*w)) - c = this%A*x*x + this%B*y*y + this%C*z*z + this%D*x*y + this%E*y*z + & - this%F*x*z + this%G*x + this%H*y + this%J*z + this%K - quad = k*k - a*c - - if (quad < ZERO) then - ! no intersection with surface - - d = INFINITY - - elseif (coincident .or. abs(c) < FP_COINCIDENT) then - ! particle is on the surface, thus one distance is positive/negative and - ! the other is zero. The sign of k determines which distance is zero and - ! which is not. - - if (k >= ZERO) then - d = (-k - sqrt(quad))/a - else - d = (-k + sqrt(quad))/a - end if - - else - ! calculate both solutions to the quadratic - quad = sqrt(quad) - d = (-k - quad)/a - b = (-k + quad)/a - - ! determine the smallest positive solution - if (d < ZERO) then - if (b > ZERO) then - d = b - end if - else - if (b > ZERO) d = min(d, b) - end if - end if - - ! If the distance was negative, set boundary distance to infinity - if (d <= ZERO) d = INFINITY - end associate - end function quadric_distance - pure function quadric_normal(this, xyz) result(uvw) class(SurfaceQuadric), intent(in) :: this real(8), intent(in) :: xyz(3) From 38aa76c9dc9cdab0c10f35c2355d20f9842b65bc Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 19 Jan 2018 00:54:39 -0500 Subject: [PATCH 11/74] Implement C++ periodic BCs --- src/geometry.F90 | 11 +++ src/surface_header.C | 136 +++++++++++++++++++++++++++++++++-- src/surface_header.F90 | 157 +---------------------------------------- src/tracking.F90 | 63 +---------------- 4 files changed, 145 insertions(+), 222 deletions(-) diff --git a/src/geometry.F90 b/src/geometry.F90 index 873582dec9..a0a19f1bfc 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -44,6 +44,17 @@ module geometry real(C_DOUBLE), intent(in) :: xyz(3); real(C_DOUBLE), intent(out) :: uvw(3); end subroutine surface_normal_c + + function surface_periodic_c(surf_ind1, surf_ind2, xyz, uvw) & + bind(C, name="surface_periodic") result(rotational) + use ISO_C_BINDING + implicit none + integer(C_INT), intent(in), value :: surf_ind1; + integer(C_INT), intent(in), value :: surf_ind2; + real(C_DOUBLE), intent(inout) :: xyz(3); + real(C_DOUBLE), intent(inout) :: uvw(3); + logical(C_BOOL) :: rotational + end function surface_periodic_c end interface contains diff --git a/src/surface_header.C b/src/surface_header.C index cf200e5e46..23fe5adb35 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -5,6 +5,7 @@ #include "pugixml/pugixml.hpp" // DEBUGGING +#include #include //============================================================================== @@ -89,14 +90,14 @@ public: neighbor_neg[]; //!< List of cells on negative side int bc; //!< Boundary condition //TODO: switch that zero to a NONE constant. - int i_periodic = 0; //!< Index of corresponding periodic surface + //int i_periodic = 0; //!< Index of corresponding periodic surface char name[104]; //!< User-defined name //! Determine which side of a surface a point lies on. //! @param xyz[3] The 3D Cartesian coordinate of a point. //! @param uvw[3] A direction used to "break ties" and pick a sense when the //! point is very close to the surface. - //! @return True if the point is on the "positive" side of the surface and + //! @return true if the point is on the "positive" side of the surface and //! false otherwise. bool sense(const double xyz[3], const double uvw[3]) const; @@ -163,6 +164,29 @@ Surface::reflect(const double xyz[3], double uvw[3]) const uvw[2] -= 2.0 * projection / magnitude * norm[2]; } +//============================================================================== +//! A `Surface` that supports periodic boundary conditions. +//! +//! Translational periodicity is supported for the `XPlane`, `YPlane`, `ZPlane`, +//! and `Plane` types. Rotational periodicity is supported for +//! `XPlane`-`YPlane` pairs. +//============================================================================== + +class PeriodicSurface : public Surface +{ +public: + //! Translate a particle onto this surface from a periodic partner surface. + //! @param other A pointer to the partner surface in this periodic BC. + //! @param xyz[3] A point on the partner surface that will be translated onto + //! this surface. + //! @param uvw[3] A direction that will be rotated for systems with rotational + //! periodicity. + //! @return true if this surface and its partner make a rotationally-periodic + //! boundary condition. + virtual bool periodic_translate(PeriodicSurface *other, double xyz[3], + double uvw[3]) const = 0; +}; + //============================================================================== // Generic functions for x-, y-, and z-, planes. //============================================================================== @@ -203,7 +227,7 @@ axis_aligned_plane_normal(const double xyz[3], double uvw[3]) //! The plane is described by the equation \f$x - x_0 = 0\f$ //============================================================================== -class SurfaceXPlane : public Surface +class SurfaceXPlane : public PeriodicSurface { double x0; public: @@ -212,6 +236,8 @@ public: double distance(const double xyz[3], const double uvw[3], const bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) + const; }; SurfaceXPlane::SurfaceXPlane(pugi::xml_node surf_node) @@ -235,6 +261,32 @@ inline void SurfaceXPlane::normal(const double xyz[3], double uvw[3]) const axis_aligned_plane_normal<0, 1, 2>(xyz, uvw); } +bool SurfaceXPlane::periodic_translate(PeriodicSurface *other, double xyz[3], + double uvw[3]) const +{ + double other_norm[3]; + other->normal(xyz, other_norm); + if (other_norm[0] == 1 and other_norm[1] == 0 and other_norm[2] == 0) { + xyz[0] = x0; + return false; + } else { + // Assume the partner is an YPlane (the only supported partner). Use the + // evaluate function to find y0, then adjust xyz and uvw for rotational + // symmetry. + double xyz_test[3] {0, 0, 0}; + double y0 = -other->evaluate(xyz_test); + xyz[1] = xyz[0] - x0 + y0; + xyz[0] = x0; + xyz[2] = xyz[2]; + + double u = uvw[0]; + uvw[0] = -uvw[1]; + uvw[1] = u; + + return true; + } +}; + //============================================================================== // SurfaceYPlane //! A plane perpendicular to the y-axis. @@ -242,7 +294,7 @@ inline void SurfaceXPlane::normal(const double xyz[3], double uvw[3]) const //! The plane is described by the equation \f$y - y_0 = 0\f$ //============================================================================== -class SurfaceYPlane : public Surface +class SurfaceYPlane : public PeriodicSurface { double y0; public: @@ -251,6 +303,8 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) + const; }; SurfaceYPlane::SurfaceYPlane(pugi::xml_node surf_node) @@ -274,6 +328,32 @@ inline void SurfaceYPlane::normal(const double xyz[3], double uvw[3]) const axis_aligned_plane_normal<1, 0, 2>(xyz, uvw); } +bool SurfaceYPlane::periodic_translate(PeriodicSurface *other, double xyz[3], + double uvw[3]) const +{ + double other_norm[3]; + other->normal(xyz, other_norm); + if (other_norm[0] == 0 and other_norm[1] == 1 and other_norm[2] == 0) { + // The periodic partner is also aligned along y. Just change the y coord. + xyz[1] = y0; + return false; + } else { + // Assume the partner is an XPlane (the only supported partner). Use the + // evaluate function to find x0, then adjust xyz and uvw for rotational + // symmetry. + double xyz_test[3] {0, 0, 0}; + double x0 = -other->evaluate(xyz_test); + xyz[0] = xyz[1] - y0 + x0; + xyz[1] = y0; + + double u = uvw[0]; + uvw[0] = uvw[1]; + uvw[1] = -u; + + return true; + } +}; + //============================================================================== // SurfaceZPlane //! A plane perpendicular to the z-axis. @@ -281,7 +361,7 @@ inline void SurfaceYPlane::normal(const double xyz[3], double uvw[3]) const //! The plane is described by the equation \f$z - z_0 = 0\f$ //============================================================================== -class SurfaceZPlane : public Surface +class SurfaceZPlane : public PeriodicSurface { double z0; public: @@ -290,6 +370,8 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) + const; }; SurfaceZPlane::SurfaceZPlane(pugi::xml_node surf_node) @@ -313,6 +395,14 @@ inline void SurfaceZPlane::normal(const double xyz[3], double uvw[3]) const axis_aligned_plane_normal<2, 0, 1>(xyz, uvw); } +bool SurfaceZPlane::periodic_translate(PeriodicSurface *other, double xyz[3], + double uvw[3]) const +{ + // Assume the other plane is aligned along z. Just change the z coord. + xyz[2] = z0; + return false; +}; + //============================================================================== // SurfacePlane //! A general plane. @@ -320,7 +410,7 @@ inline void SurfaceZPlane::normal(const double xyz[3], double uvw[3]) const //! The plane is described by the equation \f$A x + B y + C z - D = 0\f$ //============================================================================== -class SurfacePlane : public Surface +class SurfacePlane : public PeriodicSurface { double A, B, C, D; public: @@ -329,6 +419,8 @@ public: double distance(const double xyz[3], const double uvw[3], const bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) + const; }; SurfacePlane::SurfacePlane(pugi::xml_node surf_node) @@ -365,6 +457,22 @@ SurfacePlane::normal(const double xyz[3], double uvw[3]) const uvw[2] = C; } +bool SurfacePlane::periodic_translate(PeriodicSurface *other, double xyz[3], + double uvw[3]) const +{ + // This function assumes the other plane shares this plane's normal direction. + + // Determine the distance to intersection. + double d = evaluate(xyz) / (A*A + B*B + C*C); + + // Move the particle that distance along the normal vector. + xyz[0] -= d * A; + xyz[1] -= d * B; + xyz[2] -= d * C; + + return false; +} + //============================================================================== // Generic functions for x-, y-, and z-, cylinders //============================================================================== @@ -1041,3 +1149,19 @@ surface_normal(int surf_ind, double xyz[3], double uvw[3]) { return surfaces_c[surf_ind]->normal(xyz, uvw); } + +extern "C" bool +surface_periodic(int surf_ind1, int surf_ind2, double xyz[3], double uvw[3]) +{ + // Hopefully this function has only been called on a pair of surfaces that + // support periodic BCs (checking should have been done when reading the + // geometry XML). Downcast the surfaces to the PeriodicSurface type so we + // can call the periodic_translate method. + Surface *surf1_gen = surfaces_c[surf_ind1]; + PeriodicSurface *surf1 = dynamic_cast(surf1_gen); + Surface *surf2_gen = surfaces_c[surf_ind2]; + PeriodicSurface *surf2 = dynamic_cast(surf2_gen); + + // Call the type-bound methods. + return surf2->periodic_translate(surf1, xyz, uvw); +} diff --git a/src/surface_header.F90 b/src/surface_header.F90 index b0da37c1e0..d9a00170ba 100644 --- a/src/surface_header.F90 +++ b/src/surface_header.F90 @@ -22,18 +22,10 @@ module surface_header character(len=104) :: name = "" ! User-defined name contains procedure :: reflect - procedure(surface_evaluate_), deferred :: evaluate procedure(surface_normal_), deferred :: normal end type Surface abstract interface - pure function surface_evaluate_(this, xyz) result(f) - import Surface - class(Surface), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: f - end function surface_evaluate_ - pure function surface_normal_(this, xyz) result(uvw) import Surface class(Surface), intent(in) :: this @@ -52,15 +44,13 @@ module surface_header !=============================================================================== ! All the derived types below are extensions of the abstract Surface type. They -! inherent the reflect() type-bound procedure and must implement evaluate(), -! and normal() +! inherent the reflect() type-bound procedure and must implement normal() !=============================================================================== type, extends(Surface) :: SurfaceXPlane ! x = x0 real(8) :: x0 contains - procedure :: evaluate => x_plane_evaluate procedure :: normal => x_plane_normal end type SurfaceXPlane @@ -68,7 +58,6 @@ module surface_header ! y = y0 real(8) :: y0 contains - procedure :: evaluate => y_plane_evaluate procedure :: normal => y_plane_normal end type SurfaceYPlane @@ -76,7 +65,6 @@ module surface_header ! z = z0 real(8) :: z0 contains - procedure :: evaluate => z_plane_evaluate procedure :: normal => z_plane_normal end type SurfaceZPlane @@ -87,7 +75,6 @@ module surface_header real(8) :: C real(8) :: D contains - procedure :: evaluate => plane_evaluate procedure :: normal => plane_normal end type SurfacePlane @@ -97,7 +84,6 @@ module surface_header real(8) :: z0 real(8) :: r contains - procedure :: evaluate => x_cylinder_evaluate procedure :: normal => x_cylinder_normal end type SurfaceXCylinder @@ -107,7 +93,6 @@ module surface_header real(8) :: z0 real(8) :: r contains - procedure :: evaluate => y_cylinder_evaluate procedure :: normal => y_cylinder_normal end type SurfaceYCylinder @@ -117,7 +102,6 @@ module surface_header real(8) :: y0 real(8) :: r contains - procedure :: evaluate => z_cylinder_evaluate procedure :: normal => z_cylinder_normal end type SurfaceZCylinder @@ -128,7 +112,6 @@ module surface_header real(8) :: z0 real(8) :: r contains - procedure :: evaluate => sphere_evaluate procedure :: normal => sphere_normal end type SurfaceSphere @@ -139,7 +122,6 @@ module surface_header real(8) :: z0 real(8) :: r2 contains - procedure :: evaluate => x_cone_evaluate procedure :: normal => x_cone_normal end type SurfaceXCone @@ -150,7 +132,6 @@ module surface_header real(8) :: z0 real(8) :: r2 contains - procedure :: evaluate => y_cone_evaluate procedure :: normal => y_cone_normal end type SurfaceYCone @@ -161,7 +142,6 @@ module surface_header real(8) :: z0 real(8) :: r2 contains - procedure :: evaluate => z_cone_evaluate procedure :: normal => z_cone_normal end type SurfaceZCone @@ -169,7 +149,6 @@ module surface_header ! Ax^2 + By^2 + Cz^2 + Dxy + Eyz + Fxz + Gx + Hy + Jz + K = 0 real(8) :: A, B, C, D, E, F, G, H, J, K contains - procedure :: evaluate => quadric_evaluate procedure :: normal => quadric_normal end type SurfaceQuadric @@ -214,14 +193,6 @@ contains ! SurfaceXPlane Implementation !=============================================================================== - pure function x_plane_evaluate(this, xyz) result(f) - class(SurfaceXPlane), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: f - - f = xyz(1) - this%x0 - end function x_plane_evaluate - pure function x_plane_normal(this, xyz) result(uvw) class(SurfaceXPlane), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -234,14 +205,6 @@ contains ! SurfaceYPlane Implementation !=============================================================================== - pure function y_plane_evaluate(this, xyz) result(f) - class(SurfaceYPlane), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: f - - f = xyz(2) - this%y0 - end function y_plane_evaluate - pure function y_plane_normal(this, xyz) result(uvw) class(SurfaceYPlane), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -254,16 +217,6 @@ contains ! SurfaceZPlane Implementation !=============================================================================== - pure function z_plane_evaluate(this, xyz) result(f) - - class(SurfaceZPlane), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: f - - f = xyz(3) - this%z0 - - end function z_plane_evaluate - pure function z_plane_normal(this, xyz) result(uvw) class(SurfaceZPlane), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -276,14 +229,6 @@ contains ! SurfacePlane Implementation !=============================================================================== - pure function plane_evaluate(this, xyz) result(f) - class(SurfacePlane), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: f - - f = this%A*xyz(1) + this%B*xyz(2) + this%C*xyz(3) - this%D - end function plane_evaluate - pure function plane_normal(this, xyz) result(uvw) class(SurfacePlane), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -296,18 +241,6 @@ contains ! SurfaceXCylinder Implementation !=============================================================================== - pure function x_cylinder_evaluate(this, xyz) result(f) - class(SurfaceXCylinder), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: f - - real(8) :: y, z - - y = xyz(2) - this%y0 - z = xyz(3) - this%z0 - f = y*y + z*z - this%r*this%r - end function x_cylinder_evaluate - pure function x_cylinder_normal(this, xyz) result(uvw) class(SurfaceXCylinder), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -322,18 +255,6 @@ contains ! SurfaceYCylinder Implementation !=============================================================================== - pure function y_cylinder_evaluate(this, xyz) result(f) - class(SurfaceYCylinder), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: f - - real(8) :: x, z - - x = xyz(1) - this%x0 - z = xyz(3) - this%z0 - f = x*x + z*z - this%r*this%r - end function y_cylinder_evaluate - pure function y_cylinder_normal(this, xyz) result(uvw) class(SurfaceYCylinder), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -348,18 +269,6 @@ contains ! SurfaceZCylinder Implementation !=============================================================================== - pure function z_cylinder_evaluate(this, xyz) result(f) - class(SurfaceZCylinder), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: f - - real(8) :: x, y - - x = xyz(1) - this%x0 - y = xyz(2) - this%y0 - f = x*x + y*y - this%r*this%r - end function z_cylinder_evaluate - pure function z_cylinder_normal(this, xyz) result(uvw) class(SurfaceZCylinder), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -374,19 +283,6 @@ contains ! SurfaceSphere Implementation !=============================================================================== - pure function sphere_evaluate(this, xyz) result(f) - class(SurfaceSphere), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: f - - real(8) :: x, y, z - - x = xyz(1) - this%x0 - y = xyz(2) - this%y0 - z = xyz(3) - this%z0 - f = x*x + y*y + z*z - this%r*this%r - end function sphere_evaluate - pure function sphere_normal(this, xyz) result(uvw) class(SurfaceSphere), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -399,19 +295,6 @@ contains ! SurfaceXCone Implementation !=============================================================================== - pure function x_cone_evaluate(this, xyz) result(f) - class(SurfaceXCone), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: f - - real(8) :: x, y, z - - x = xyz(1) - this%x0 - y = xyz(2) - this%y0 - z = xyz(3) - this%z0 - f = y*y + z*z - this%r2*x*x - end function x_cone_evaluate - pure function x_cone_normal(this, xyz) result(uvw) class(SurfaceXCone), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -426,19 +309,6 @@ contains ! SurfaceYCone Implementation !=============================================================================== - pure function y_cone_evaluate(this, xyz) result(f) - class(SurfaceYCone), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: f - - real(8) :: x, y, z - - x = xyz(1) - this%x0 - y = xyz(2) - this%y0 - z = xyz(3) - this%z0 - f = x*x + z*z - this%r2*y*y - end function y_cone_evaluate - pure function y_cone_normal(this, xyz) result(uvw) class(SurfaceYCone), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -453,19 +323,6 @@ contains ! SurfaceZCone Implementation !=============================================================================== - pure function z_cone_evaluate(this, xyz) result(f) - class(SurfaceZCone), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: f - - real(8) :: x, y, z - - x = xyz(1) - this%x0 - y = xyz(2) - this%y0 - z = xyz(3) - this%z0 - f = x*x + y*y - this%r2*z*z - end function z_cone_evaluate - pure function z_cone_normal(this, xyz) result(uvw) class(SurfaceZCone), intent(in) :: this real(8), intent(in) :: xyz(3) @@ -480,18 +337,6 @@ contains ! SurfaceQuadric Implementation !=============================================================================== - pure function quadric_evaluate(this, xyz) result(f) - class(SurfaceQuadric), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: f - - associate (x => xyz(1), y => xyz(2), z => xyz(3)) - f = x*(this%A*x + this%D*y + this%G) + & - y*(this%B*y + this%E*z + this%H) + & - z*(this%C*z + this%F*x + this%J) + this%K - end associate - end function quadric_evaluate - pure function quadric_normal(this, xyz) result(uvw) class(SurfaceQuadric), intent(in) :: this real(8), intent(in) :: xyz(3) diff --git a/src/tracking.F90 b/src/tracking.F90 index 65769a7f18..4f0f110bc7 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -5,7 +5,7 @@ module tracking use error, only: fatal_error, warning, write_message use geometry_header, only: cells use geometry, only: find_cell, distance_to_boundary, cross_lattice, & - check_cell_overlap + check_cell_overlap, surface_periodic_c use message_passing use mgxs_header use nuclide_header @@ -290,7 +290,6 @@ contains real(8) :: v ! y-component of direction real(8) :: w ! z-component of direction real(8) :: norm ! "norm" of surface normal - real(8) :: d ! distance between point and plane real(8) :: xyz(3) ! Saved global coordinate integer :: i_surface ! index in surfaces logical :: rotational ! if rotational periodic BC applied @@ -412,64 +411,8 @@ contains p % coord(1) % xyz = xyz end if - rotational = .false. - select type (surf) - type is (SurfaceXPlane) - select type (opposite => surfaces(surf % i_periodic) % obj) - type is (SurfaceXPlane) - p % coord(1) % xyz(1) = opposite % x0 - type is (SurfaceYPlane) - rotational = .true. - - ! Rotate direction - u = p % coord(1) % uvw(1) - v = p % coord(1) % uvw(2) - p % coord(1) % uvw(1) = v - p % coord(1) % uvw(2) = -u - - ! Rotate position - p % coord(1) % xyz(1) = surf % x0 + p % coord(1) % xyz(2) - opposite % y0 - p % coord(1) % xyz(2) = opposite % y0 - end select - - type is (SurfaceYPlane) - select type (opposite => surfaces(surf % i_periodic) % obj) - type is (SurfaceYPlane) - p % coord(1) % xyz(2) = opposite % y0 - type is (SurfaceXPlane) - rotational = .true. - - ! Rotate direction - u = p % coord(1) % uvw(1) - v = p % coord(1) % uvw(2) - p % coord(1) % uvw(1) = -v - p % coord(1) % uvw(2) = u - - ! Rotate position - p % coord(1) % xyz(2) = surf % y0 + p % coord(1) % xyz(1) - opposite % x0 - p % coord(1) % xyz(1) = opposite % x0 - end select - - type is (SurfaceZPlane) - select type (opposite => surfaces(surf % i_periodic) % obj) - type is (SurfaceZPlane) - p % coord(1) % xyz(3) = opposite % z0 - end select - - type is (SurfacePlane) - select type (opposite => surfaces(surf % i_periodic) % obj) - type is (SurfacePlane) - ! Get surface normal for opposite plane - xyz(:) = opposite % normal(p % coord(1) % xyz) - - ! Determine distance to plane - norm = xyz(1)*xyz(1) + xyz(2)*xyz(2) + xyz(3)*xyz(3) - d = opposite % evaluate(p % coord(1) % xyz) / norm - - ! Move particle along normal vector based on distance - p % coord(1) % xyz(:) = p % coord(1) % xyz(:) - d*xyz - end select - end select + rotational = surface_periodic_c(i_surface-1, surf % i_periodic-1, & + p % coord(1) % xyz, p % coord(1) % uvw) ! Reassign particle's surface if (rotational) then From 7af296902bbb9ae7b0409eafb5060feacfb1d2ec Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 19 Jan 2018 01:27:04 -0500 Subject: [PATCH 12/74] Remove Fortran surface reflection code --- src/geometry.F90 | 15 ++- src/surface_header.C | 14 ++- src/surface_header.F90 | 226 +---------------------------------------- src/tracking.F90 | 5 +- 4 files changed, 26 insertions(+), 234 deletions(-) diff --git a/src/geometry.F90 b/src/geometry.F90 index a0a19f1bfc..c19a6c8dd7 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -25,6 +25,15 @@ module geometry logical(C_BOOL) :: sense; end function surface_sense_c + pure subroutine surface_reflect_c(surf_ind, xyz, uvw) & + bind(C, name='surface_reflect') + use ISO_C_BINDING + implicit none + integer(C_INT), intent(in), value :: surf_ind; + real(C_DOUBLE), intent(in) :: xyz(3); + real(C_DOUBLE), intent(inout) :: uvw(3); + end subroutine surface_reflect_c + pure function surface_distance_c(surf_ind, xyz, uvw, coincident) & bind(C, name='surface_distance') result(d) use ISO_C_BINDING @@ -525,6 +534,7 @@ contains real(8) :: d_surf ! distance to surface real(8) :: x0,y0,z0 ! coefficients for surface real(8) :: xyz_cross(3) ! coordinates at projected surface crossing + real(8) :: surf_uvw(3) ! surface normal direction logical :: coincident ! is particle on surface? type(Cell), pointer :: c class(Surface), pointer :: surf @@ -782,9 +792,8 @@ contains ! traveling into if the surface is crossed if (.not. c % simple) then xyz_cross(:) = p % coord(j) % xyz + d_surf*p % coord(j) % uvw - surf => surfaces(abs(level_surf_cross)) % obj - if (dot_product(p % coord(j) % uvw, & - surf % normal(xyz_cross)) > ZERO) then + call surface_normal_c(abs(level_surf_cross)-1, xyz_cross, surf_uvw) + if (dot_product(p % coord(j) % uvw, surf_uvw) > ZERO) then surface_crossed = abs(level_surf_cross) else surface_crossed = -abs(level_surf_cross) diff --git a/src/surface_header.C b/src/surface_header.C index 23fe5adb35..45fb62399e 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -233,8 +233,8 @@ class SurfaceXPlane : public PeriodicSurface public: SurfaceXPlane(pugi::xml_node surf_node); double evaluate(const double xyz[3]) const; - double distance(const double xyz[3], const double uvw[3], - const bool coincident) const; + double distance(const double xyz[3], const double uvw[3], bool coincident) + const; void normal(const double xyz[3], double uvw[3]) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; @@ -416,8 +416,8 @@ class SurfacePlane : public PeriodicSurface public: SurfacePlane(pugi::xml_node surf_node); double evaluate(const double xyz[3]) const; - double distance(const double xyz[3], const double uvw[3], - const bool coincident) const; + double distance(const double xyz[3], const double uvw[3], bool coincident) + const; void normal(const double xyz[3], double uvw[3]) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; @@ -1138,6 +1138,12 @@ surface_sense(int surf_ind, double xyz[3], double uvw[3]) return surfaces_c[surf_ind]->sense(xyz, uvw); } +extern "C" void +surface_reflect(int surf_ind, double xyz[3], double uvw[3]) +{ + surfaces_c[surf_ind]->reflect(xyz, uvw); +} + extern "C" double surface_distance(int surf_ind, double xyz[3], double uvw[3], bool coincident) { diff --git a/src/surface_header.F90 b/src/surface_header.F90 index d9a00170ba..d632903871 100644 --- a/src/surface_header.F90 +++ b/src/surface_header.F90 @@ -2,7 +2,7 @@ module surface_header use, intrinsic :: ISO_C_BINDING - use constants, only: NONE, ONE, TWO, ZERO, HALF, INFINITY, FP_COINCIDENT + use constants, only: NONE use dict_header, only: DictIntInt implicit none @@ -20,20 +20,8 @@ module surface_header integer :: bc ! Boundary condition integer :: i_periodic = NONE ! Index of corresponding periodic surface character(len=104) :: name = "" ! User-defined name - contains - procedure :: reflect - procedure(surface_normal_), deferred :: normal end type Surface - abstract interface - pure function surface_normal_(this, xyz) result(uvw) - import Surface - class(Surface), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: uvw(3) - end function surface_normal_ - end interface - !=============================================================================== ! SURFACECONTAINER allows us to store an array of different types of surfaces !=============================================================================== @@ -50,22 +38,16 @@ module surface_header type, extends(Surface) :: SurfaceXPlane ! x = x0 real(8) :: x0 - contains - procedure :: normal => x_plane_normal end type SurfaceXPlane type, extends(Surface) :: SurfaceYPlane ! y = y0 real(8) :: y0 - contains - procedure :: normal => y_plane_normal end type SurfaceYPlane type, extends(Surface) :: SurfaceZPlane ! z = z0 real(8) :: z0 - contains - procedure :: normal => z_plane_normal end type SurfaceZPlane type, extends(Surface) :: SurfacePlane @@ -74,8 +56,6 @@ module surface_header real(8) :: B real(8) :: C real(8) :: D - contains - procedure :: normal => plane_normal end type SurfacePlane type, extends(Surface) :: SurfaceXCylinder @@ -83,8 +63,6 @@ module surface_header real(8) :: y0 real(8) :: z0 real(8) :: r - contains - procedure :: normal => x_cylinder_normal end type SurfaceXCylinder type, extends(Surface) :: SurfaceYCylinder @@ -92,8 +70,6 @@ module surface_header real(8) :: x0 real(8) :: z0 real(8) :: r - contains - procedure :: normal => y_cylinder_normal end type SurfaceYCylinder type, extends(Surface) :: SurfaceZCylinder @@ -101,8 +77,6 @@ module surface_header real(8) :: x0 real(8) :: y0 real(8) :: r - contains - procedure :: normal => z_cylinder_normal end type SurfaceZCylinder type, extends(Surface) :: SurfaceSphere @@ -111,8 +85,6 @@ module surface_header real(8) :: y0 real(8) :: z0 real(8) :: r - contains - procedure :: normal => sphere_normal end type SurfaceSphere type, extends(Surface) :: SurfaceXCone @@ -121,8 +93,6 @@ module surface_header real(8) :: y0 real(8) :: z0 real(8) :: r2 - contains - procedure :: normal => x_cone_normal end type SurfaceXCone type, extends(Surface) :: SurfaceYCone @@ -131,8 +101,6 @@ module surface_header real(8) :: y0 real(8) :: z0 real(8) :: r2 - contains - procedure :: normal => y_cone_normal end type SurfaceYCone type, extends(Surface) :: SurfaceZCone @@ -141,15 +109,11 @@ module surface_header real(8) :: y0 real(8) :: z0 real(8) :: r2 - contains - procedure :: normal => z_cone_normal end type SurfaceZCone type, extends(Surface) :: SurfaceQuadric ! Ax^2 + By^2 + Cz^2 + Dxy + Eyz + Fxz + Gx + Hy + Jz + K = 0 real(8) :: A, B, C, D, E, F, G, H, J, K - contains - procedure :: normal => quadric_normal end type SurfaceQuadric integer(C_INT32_T), bind(C) :: n_surfaces ! # of surfaces @@ -161,194 +125,6 @@ module surface_header contains -!=============================================================================== -! REFLECT determines the direction a particle will travel if it is specularly -! reflected from the surface at a given position and direction. The position is -! needed because the reflection is performed using the surface normal, which -! depends on the position for second-order surfaces. -!=============================================================================== - - pure subroutine reflect(this, xyz, uvw) - class(Surface), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8), intent(inout) :: uvw(3) - - real(8) :: projection - real(8) :: magnitude - real(8) :: n(3) - - ! Construct normal vector - n(:) = this%normal(xyz) - - ! Determine projection of direction onto normal and squared magnitude of - ! normal - projection = n(1)*uvw(1) + n(2)*uvw(2) + n(3)*uvw(3) - magnitude = n(1)*n(1) + n(2)*n(2) + n(3)*n(3) - - ! Reflect direction according to normal - uvw(:) = uvw - TWO*projection/magnitude * n - end subroutine reflect - -!=============================================================================== -! SurfaceXPlane Implementation -!=============================================================================== - - pure function x_plane_normal(this, xyz) result(uvw) - class(SurfaceXPlane), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: uvw(3) - - uvw(:) = [ONE, ZERO, ZERO] - end function x_plane_normal - -!=============================================================================== -! SurfaceYPlane Implementation -!=============================================================================== - - pure function y_plane_normal(this, xyz) result(uvw) - class(SurfaceYPlane), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: uvw(3) - - uvw(:) = [ZERO, ONE, ZERO] - end function y_plane_normal - -!=============================================================================== -! SurfaceZPlane Implementation -!=============================================================================== - - pure function z_plane_normal(this, xyz) result(uvw) - class(SurfaceZPlane), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: uvw(3) - - uvw(:) = [ZERO, ZERO, ONE] - end function z_plane_normal - -!=============================================================================== -! SurfacePlane Implementation -!=============================================================================== - - pure function plane_normal(this, xyz) result(uvw) - class(SurfacePlane), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: uvw(3) - - uvw(:) = [this%A, this%B, this%C] - end function plane_normal - -!=============================================================================== -! SurfaceXCylinder Implementation -!=============================================================================== - - pure function x_cylinder_normal(this, xyz) result(uvw) - class(SurfaceXCylinder), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: uvw(3) - - uvw(1) = ZERO - uvw(2) = TWO*(xyz(2) - this%y0) - uvw(3) = TWO*(xyz(3) - this%z0) - end function x_cylinder_normal - -!=============================================================================== -! SurfaceYCylinder Implementation -!=============================================================================== - - pure function y_cylinder_normal(this, xyz) result(uvw) - class(SurfaceYCylinder), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: uvw(3) - - uvw(1) = TWO*(xyz(1) - this%x0) - uvw(2) = ZERO - uvw(3) = TWO*(xyz(3) - this%z0) - end function y_cylinder_normal - -!=============================================================================== -! SurfaceZCylinder Implementation -!=============================================================================== - - pure function z_cylinder_normal(this, xyz) result(uvw) - class(SurfaceZCylinder), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: uvw(3) - - uvw(1) = TWO*(xyz(1) - this%x0) - uvw(2) = TWO*(xyz(2) - this%y0) - uvw(3) = ZERO - end function z_cylinder_normal - -!=============================================================================== -! SurfaceSphere Implementation -!=============================================================================== - - pure function sphere_normal(this, xyz) result(uvw) - class(SurfaceSphere), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: uvw(3) - - uvw(:) = TWO*(xyz - [this%x0, this%y0, this%z0]) - end function sphere_normal - -!=============================================================================== -! SurfaceXCone Implementation -!=============================================================================== - - pure function x_cone_normal(this, xyz) result(uvw) - class(SurfaceXCone), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: uvw(3) - - uvw(1) = -TWO*this%r2*(xyz(1) - this%x0) - uvw(2) = TWO*(xyz(2) - this%y0) - uvw(3) = TWO*(xyz(3) - this%z0) - end function x_cone_normal - -!=============================================================================== -! SurfaceYCone Implementation -!=============================================================================== - - pure function y_cone_normal(this, xyz) result(uvw) - class(SurfaceYCone), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: uvw(3) - - uvw(1) = TWO*(xyz(1) - this%x0) - uvw(2) = -TWO*this%r2*(xyz(2) - this%y0) - uvw(3) = TWO*(xyz(3) - this%z0) - end function y_cone_normal - -!=============================================================================== -! SurfaceZCone Implementation -!=============================================================================== - - pure function z_cone_normal(this, xyz) result(uvw) - class(SurfaceZCone), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: uvw(3) - - uvw(1) = TWO*(xyz(1) - this%x0) - uvw(2) = TWO*(xyz(2) - this%y0) - uvw(3) = -TWO*this%r2*(xyz(3) - this%z0) - end function z_cone_normal - -!=============================================================================== -! SurfaceQuadric Implementation -!=============================================================================== - - pure function quadric_normal(this, xyz) result(uvw) - class(SurfaceQuadric), intent(in) :: this - real(8), intent(in) :: xyz(3) - real(8) :: uvw(3) - - associate (x => xyz(1), y => xyz(2), z => xyz(3)) - uvw(1) = TWO*this%A*x + this%D*y + this%F*z + this%G - uvw(2) = TWO*this%B*y + this%D*x + this%E*z + this%H - uvw(3) = TWO*this%C*z + this%E*y + this%F*x + this%J - end associate - end function quadric_normal - !=============================================================================== ! FREE_MEMORY_SURFACES deallocates global arrays defined in this module !=============================================================================== diff --git a/src/tracking.F90 b/src/tracking.F90 index 4f0f110bc7..d616212ec6 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -5,7 +5,8 @@ module tracking use error, only: fatal_error, warning, write_message use geometry_header, only: cells use geometry, only: find_cell, distance_to_boundary, cross_lattice, & - check_cell_overlap, surface_periodic_c + check_cell_overlap, surface_reflect_c, & + surface_periodic_c use message_passing use mgxs_header use nuclide_header @@ -354,7 +355,7 @@ contains end if ! Reflect particle off surface - call surf%reflect(p%coord(1)%xyz, p%coord(1)%uvw) + call surface_reflect_c(i_surface-1, p%coord(1)%xyz, p%coord(1)%uvw) ! Make sure new particle direction is normalized u = p%coord(1)%uvw(1) From 57991b271db4828e8fbc92fbdf78b5892f83fb7d Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 19 Jan 2018 18:12:57 -0500 Subject: [PATCH 13/74] Start moving surface->summary.h5 to C++ --- CMakeLists.txt | 5 +- src/api.F90 | 2 +- src/cmfd_execute.F90 | 8 +- src/eigenvalue.F90 | 18 ++-- src/error.F90 | 4 +- src/geometry.F90 | 1 - src/hdf5_interface.F90 | 4 +- src/hdf5_interface.h | 47 ++++++++++ src/initialize.F90 | 12 +-- src/input_xml.F90 | 80 +++-------------- src/main.F90 | 8 +- src/mesh.F90 | 4 +- src/message_passing.F90 | 6 +- src/output.F90 | 2 +- src/simulation.F90 | 8 +- src/source.F90 | 2 +- src/state_point.F90 | 18 ++-- src/summary.F90 | 92 +++----------------- src/surface_header.C | 184 +++++++++++++++++++++++++++++++++++++++- src/surface_header.F90 | 45 ---------- src/tallies/tally.F90 | 4 +- src/tallies/trigger.F90 | 2 +- src/volume_calc.F90 | 6 +- 23 files changed, 311 insertions(+), 251 deletions(-) create mode 100644 src/hdf5_interface.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 200d836fe1..58fb55e799 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,14 +48,14 @@ add_definitions(-DMAX_COORD=${maxcoord}) set(MPI_ENABLED FALSE) if($ENV{FC} MATCHES "(mpi[^/]*|ftn)$") message("-- Detected MPI wrapper: $ENV{FC}") - add_definitions(-DMPI) + add_definitions(-DOPENMC_MPI) set(MPI_ENABLED TRUE) endif() # Check for Fortran 2008 MPI interface if(MPI_ENABLED AND mpif08) message("-- Using Fortran 2008 MPI bindings") - add_definitions(-DMPIF08) + add_definitions(-DOPENMC_MPIF08) endif() #=============================================================================== @@ -435,6 +435,7 @@ set(LIBOPENMC_FORTRAN_SRC src/tallies/trigger_header.F90 ) set(LIBOPENMC_CXX_SRC + src/hdf5_interface.h src/random_lcg.h src/random_lcg.cpp src/surface_header.C diff --git a/src/api.F90 b/src/api.F90 index eb9a996950..5d56b857ca 100644 --- a/src/api.F90 +++ b/src/api.F90 @@ -171,7 +171,7 @@ contains ! Close FORTRAN interface. call h5close_f(err) -#ifdef MPI +#ifdef OPENMC_MPI ! Free all MPI types call MPI_TYPE_FREE(MPI_BANK, err) #endif diff --git a/src/cmfd_execute.F90 b/src/cmfd_execute.F90 index 9cdb751a40..af8d57a807 100644 --- a/src/cmfd_execute.F90 +++ b/src/cmfd_execute.F90 @@ -105,7 +105,7 @@ contains real(8) :: hxyz(3) ! cell dimensions of current ijk cell real(8) :: vol ! volume of cell real(8),allocatable :: source(:,:,:,:) ! tmp source array for entropy -#ifdef MPI +#ifdef OPENMC_MPI integer :: mpi_err ! MPI error code #endif @@ -197,7 +197,7 @@ contains end if -#ifdef MPI +#ifdef OPENMC_MPI ! Broadcast full source to all procs call MPI_BCAST(cmfd % cmfd_src, n, MPI_REAL8, 0, mpi_intracomm, mpi_err) #endif @@ -234,7 +234,7 @@ contains real(8) :: norm ! normalization factor logical :: outside ! any source sites outside mesh logical :: in_mesh ! source site is inside mesh -#ifdef MPI +#ifdef OPENMC_MPI integer :: mpi_err #endif @@ -291,7 +291,7 @@ contains if (.not. cmfd_feedback) return ! Broadcast weight factors to all procs -#ifdef MPI +#ifdef OPENMC_MPI call MPI_BCAST(cmfd % weightfactors, ng*nx*ny*nz, MPI_REAL8, 0, & mpi_intracomm, mpi_err) #endif diff --git a/src/eigenvalue.F90 b/src/eigenvalue.F90 index 27ae4063ea..7a11d1fb48 100644 --- a/src/eigenvalue.F90 +++ b/src/eigenvalue.F90 @@ -42,11 +42,11 @@ contains type(Bank), save, allocatable :: & & temp_sites(:) ! local array of extra sites on each node -#ifdef MPI +#ifdef OPENMC_MPI integer :: mpi_err ! MPI error code integer(8) :: n ! number of sites to send/recv integer :: neighbor ! processor to send/recv data from -#ifdef MPIF08 +#ifdef OPENMC_MPIF08 type(MPI_Request) :: request(20) #else integer :: request(20) ! communication request for send/recving sites @@ -66,7 +66,7 @@ contains ! fission bank its own sites starts in order to ensure reproducibility by ! skipping ahead to the proper seed. -#ifdef MPI +#ifdef OPENMC_MPI start = 0_8 call MPI_EXSCAN(n_bank, start, 1, MPI_INTEGER8, MPI_SUM, & mpi_intracomm, mpi_err) @@ -148,7 +148,7 @@ contains ! neighboring processors, we have to perform an ALLGATHER to determine the ! indices for all processors -#ifdef MPI +#ifdef OPENMC_MPI ! First do an exclusive scan to get the starting indices for start = 0_8 call MPI_EXSCAN(index_temp, start, 1, MPI_INTEGER8, MPI_SUM, & @@ -191,7 +191,7 @@ contains call time_bank_sample % stop() call time_bank_sendrecv % start() -#ifdef MPI +#ifdef OPENMC_MPI ! ========================================================================== ! SEND BANK SITES TO NEIGHBORS @@ -343,14 +343,14 @@ contains subroutine calculate_generation_keff() real(8) :: keff_reduced -#ifdef MPI +#ifdef OPENMC_MPI integer :: mpi_err ! MPI error code #endif ! Get keff for this generation by subtracting off the starting value keff_generation = global_tallies(RESULT_VALUE, K_TRACKLENGTH) - keff_generation -#ifdef MPI +#ifdef OPENMC_MPI ! Combine values across all processors call MPI_ALLREDUCE(keff_generation, keff_reduced, 1, MPI_REAL8, & MPI_SUM, mpi_intracomm, mpi_err) @@ -584,7 +584,7 @@ contains real(8) :: total ! total weight in source bank logical :: sites_outside ! were there sites outside the ufs mesh? -#ifdef MPI +#ifdef OPENMC_MPI integer :: n ! total number of ufs mesh cells integer :: mpi_err ! MPI error code #endif @@ -608,7 +608,7 @@ contains call fatal_error("Source sites outside of the UFS mesh!") end if -#ifdef MPI +#ifdef OPENMC_MPI ! Send source fraction to all processors n = product(m % dimension) call MPI_BCAST(source_frac, n, MPI_REAL8, 0, mpi_intracomm, mpi_err) diff --git a/src/error.F90 b/src/error.F90 index 27004d729a..ae02e0897d 100644 --- a/src/error.F90 +++ b/src/error.F90 @@ -128,7 +128,7 @@ contains integer :: line_wrap ! length of line integer :: length ! length of message integer :: indent ! length of indentation -#ifdef MPI +#ifdef OPENMC_MPI integer :: mpi_err #endif @@ -180,7 +180,7 @@ contains end if end do -#ifdef MPI +#ifdef OPENMC_MPI ! Abort MPI call MPI_ABORT(mpi_intracomm, code, mpi_err) #endif diff --git a/src/geometry.F90 b/src/geometry.F90 index c19a6c8dd7..f1feb3ba30 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -537,7 +537,6 @@ contains real(8) :: surf_uvw(3) ! surface normal direction logical :: coincident ! is particle on surface? type(Cell), pointer :: c - class(Surface), pointer :: surf class(Lattice), pointer :: lat ! inialize distance to infinity (huge) diff --git a/src/hdf5_interface.F90 b/src/hdf5_interface.F90 index e8c39b923c..410149d9e7 100644 --- a/src/hdf5_interface.F90 +++ b/src/hdf5_interface.F90 @@ -124,7 +124,7 @@ contains ! Setup file access property list with parallel I/O access call h5pcreate_f(H5P_FILE_ACCESS_F, plist, hdf5_err) #ifdef PHDF5 -#ifdef MPIF08 +#ifdef OPENMC_MPIF08 call h5pset_fapl_mpio_f(plist, mpi_intracomm%MPI_VAL, & MPI_INFO_NULL%MPI_VAL, hdf5_err) #else @@ -174,7 +174,7 @@ contains ! Setup file access property list with parallel I/O access call h5pcreate_f(H5P_FILE_ACCESS_F, plist, hdf5_err) #ifdef PHDF5 -#ifdef MPIF08 +#ifdef OPENMC_MPIF08 call h5pset_fapl_mpio_f(plist, mpi_intracomm%MPI_VAL, & MPI_INFO_NULL%MPI_VAL, hdf5_err) #else diff --git a/src/hdf5_interface.h b/src/hdf5_interface.h new file mode 100644 index 0000000000..38bb7d88bc --- /dev/null +++ b/src/hdf5_interface.h @@ -0,0 +1,47 @@ +#ifndef HDF5_INTERFACE_H +#define HDF5_INTERFACE_H + +#include // For std::array +#include // For strlen + +#include "hdf5.h" + + +template void +write_double_1D(hid_t group_id, char const *name, + std::array &buffer) +{ + hsize_t dims[1]{array_len}; + hid_t dataspace = H5Screate_simple(1, dims, NULL); + + hid_t dataset = H5Dcreate(group_id, name, H5T_NATIVE_DOUBLE, dataspace, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + H5Dwrite(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, + &buffer[0]); + + H5Sclose(dataspace); + H5Dclose(dataset); +} + + +void +write_string(hid_t group_id, char const *name, char const *buffer) +{ + size_t buffer_len = strlen(buffer); + hid_t datatype = H5Tcopy(H5T_C_S1); + H5Tset_size(datatype, buffer_len); + + hid_t dataspace = H5Screate(H5S_SCALAR); + + hid_t dataset = H5Dcreate(group_id, name, datatype, dataspace, + H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + + H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer); + + H5Tclose(datatype); + H5Sclose(dataspace); + H5Dclose(dataset); +} + +#endif //HDF5_INTERFACE_H diff --git a/src/initialize.F90 b/src/initialize.F90 index dd7894f96b..2af93627ea 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -52,8 +52,8 @@ contains ! Copy the communicator to a new variable. This is done to avoid changing ! the signature of this subroutine. If MPI is being used but no communicator ! was passed, assume MPI_COMM_WORLD. -#ifdef MPI -#ifdef MPIF08 +#ifdef OPENMC_MPI +#ifdef OPENMC_MPIF08 type(MPI_Comm), intent(in) :: comm ! MPI intracommunicator if (present(intracomm)) then comm % MPI_VAL = intracomm @@ -74,7 +74,7 @@ contains call time_total%start() call time_initialize%start() -#ifdef MPI +#ifdef OPENMC_MPI ! Setup MPI call initialize_mpi(comm) #endif @@ -108,7 +108,7 @@ contains end subroutine openmc_init -#ifdef MPI +#ifdef OPENMC_MPI !=============================================================================== ! INITIALIZE_MPI starts up the Message Passing Interface (MPI) and determines ! the number of processors the problem is being run with as well as the rank of @@ -116,7 +116,7 @@ contains !=============================================================================== subroutine initialize_mpi(intracomm) -#ifdef MPIF08 +#ifdef OPENMC_MPIF08 type(MPI_Comm), intent(in) :: intracomm ! MPI intracommunicator #else integer, intent(in) :: intracomm ! MPI intracommunicator @@ -124,7 +124,7 @@ contains integer :: mpi_err ! MPI error code integer :: bank_blocks(5) ! Count for each datatype -#ifdef MPIF08 +#ifdef OPENMC_MPIF08 type(MPI_Datatype) :: bank_types(5) #else integer :: bank_types(5) ! Datatypes diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 4994ff76bc..462b9708f9 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -54,7 +54,7 @@ module input_xml implicit none type(C_PTR) :: node_ptr end subroutine read_surfaces - end interface + end interface contains @@ -1081,77 +1081,23 @@ contains select type(s) type is (SurfaceXPlane) - s%x0 = coeffs(1) - ! Determine outer surfaces - xmin = min(xmin, s % x0) - xmax = max(xmax, s % x0) - if (xmin == s % x0) i_xmin = i - if (xmax == s % x0) i_xmax = i + xmin = min(xmin, coeffs(1)) + xmax = max(xmax, coeffs(1)) + if (xmin == coeffs(1)) i_xmin = i + if (xmax == coeffs(1)) i_xmax = i type is (SurfaceYPlane) - s%y0 = coeffs(1) - ! Determine outer surfaces - ymin = min(ymin, s % y0) - ymax = max(ymax, s % y0) - if (ymin == s % y0) i_ymin = i - if (ymax == s % y0) i_ymax = i + ymin = min(ymin, coeffs(1)) + ymax = max(ymax, coeffs(1)) + if (ymin == coeffs(1)) i_ymin = i + if (ymax == coeffs(1)) i_ymax = i type is (SurfaceZPlane) - s%z0 = coeffs(1) - ! Determine outer surfaces - zmin = min(zmin, s % z0) - zmax = max(zmax, s % z0) - if (zmin == s % z0) i_zmin = i - if (zmax == s % z0) i_zmax = i - type is (SurfacePlane) - s%A = coeffs(1) - s%B = coeffs(2) - s%C = coeffs(3) - s%D = coeffs(4) - type is (SurfaceXCylinder) - s%y0 = coeffs(1) - s%z0 = coeffs(2) - s%r = coeffs(3) - type is (SurfaceYCylinder) - s%x0 = coeffs(1) - s%z0 = coeffs(2) - s%r = coeffs(3) - type is (SurfaceZCylinder) - s%x0 = coeffs(1) - s%y0 = coeffs(2) - s%r = coeffs(3) - type is (SurfaceSphere) - s%x0 = coeffs(1) - s%y0 = coeffs(2) - s%z0 = coeffs(3) - s%r = coeffs(4) - type is (SurfaceXCone) - s%x0 = coeffs(1) - s%y0 = coeffs(2) - s%z0 = coeffs(3) - s%r2 = coeffs(4) - type is (SurfaceYCone) - s%x0 = coeffs(1) - s%y0 = coeffs(2) - s%z0 = coeffs(3) - s%r2 = coeffs(4) - type is (SurfaceZCone) - s%x0 = coeffs(1) - s%y0 = coeffs(2) - s%z0 = coeffs(3) - s%r2 = coeffs(4) - type is (SurfaceQuadric) - s%A = coeffs(1) - s%B = coeffs(2) - s%C = coeffs(3) - s%D = coeffs(4) - s%E = coeffs(5) - s%F = coeffs(6) - s%G = coeffs(7) - s%H = coeffs(8) - s%J = coeffs(9) - s%K = coeffs(10) + zmin = min(zmin, coeffs(1)) + zmax = max(zmax, coeffs(1)) + if (zmin == coeffs(1)) i_zmin = i + if (zmax == coeffs(1)) i_zmax = i end select ! No longer need coefficients diff --git a/src/main.F90 b/src/main.F90 index d8e52643c1..120bdd1e0c 100644 --- a/src/main.F90 +++ b/src/main.F90 @@ -9,13 +9,13 @@ program main implicit none -#ifdef MPI +#ifdef OPENMC_MPI integer :: mpi_err ! MPI error code #endif ! Initialize run -- when run with MPI, pass communicator -#ifdef MPI -#ifdef MPIF08 +#ifdef OPENMC_MPI +#ifdef OPENMC_MPIF08 call openmc_init(MPI_COMM_WORLD % MPI_VAL) #else call openmc_init(MPI_COMM_WORLD) @@ -39,7 +39,7 @@ program main ! finalize run call openmc_finalize() -#ifdef MPI +#ifdef OPENMC_MPI ! If MPI is in use and enabled, terminate it call MPI_FINALIZE(mpi_err) #endif diff --git a/src/mesh.F90 b/src/mesh.F90 index e997890a4a..790dc7d889 100644 --- a/src/mesh.F90 +++ b/src/mesh.F90 @@ -34,7 +34,7 @@ contains integer :: n ! number of energy groups / size integer :: mesh_bin ! mesh bin integer :: e_bin ! energy bin -#ifdef MPI +#ifdef OPENMC_MPI integer :: mpi_err ! MPI error code #endif logical :: outside ! was any site outside mesh? @@ -86,7 +86,7 @@ contains cnt_(e_bin, mesh_bin) = cnt_(e_bin, mesh_bin) + bank_array(i) % wgt end do FISSION_SITES -#ifdef MPI +#ifdef OPENMC_MPI ! collect values from all processors n = size(cnt_) call MPI_REDUCE(cnt_, cnt, n, MPI_REAL8, MPI_SUM, 0, mpi_intracomm, mpi_err) diff --git a/src/message_passing.F90 b/src/message_passing.F90 index 0f2b94d1af..7391a632c7 100644 --- a/src/message_passing.F90 +++ b/src/message_passing.F90 @@ -1,7 +1,7 @@ module message_passing -#ifdef MPI -#ifdef MPIF08 +#ifdef OPENMC_MPI +#ifdef OPENMC_MPIF08 use mpi_f08 #else use mpi @@ -16,7 +16,7 @@ module message_passing integer :: rank = 0 ! rank of process logical :: master = .true. ! master process? logical :: mpi_enabled = .false. ! is MPI in use and initialized? -#ifdef MPIF08 +#ifdef OPENMC_MPIF08 type(MPI_Datatype) :: MPI_BANK ! MPI datatype for fission bank type(MPI_Comm) :: mpi_intracomm ! MPI intra-communicator #else diff --git a/src/output.F90 b/src/output.F90 index 9a144721dc..1b7cae121e 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -88,7 +88,7 @@ contains ! Write the date and time write(UNIT=OUTPUT_UNIT, FMT='(9X,"Date/Time | ",A)') time_stamp() -#ifdef MPI +#ifdef OPENMC_MPI ! Write number of processors write(UNIT=OUTPUT_UNIT, FMT='(5X,"MPI Processes | ",A)') & trim(to_str(n_procs)) diff --git a/src/simulation.F90 b/src/simulation.F90 index ef29e7832b..24e9b29fc3 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -320,7 +320,7 @@ contains subroutine finalize_batch() -#ifdef MPI +#ifdef OPENMC_MPI integer :: mpi_err ! MPI error code #endif @@ -342,7 +342,7 @@ contains ! Check_triggers if (master) call check_triggers() -#ifdef MPI +#ifdef OPENMC_MPI call MPI_BCAST(satisfy_triggers, 1, MPI_LOGICAL, 0, & mpi_intracomm, mpi_err) #endif @@ -469,7 +469,7 @@ contains subroutine openmc_simulation_finalize() bind(C) integer :: i ! loop index -#ifdef MPI +#ifdef OPENMC_MPI integer :: n ! size of arrays integer :: mpi_err ! MPI error code integer(8) :: temp @@ -494,7 +494,7 @@ contains ! Increment total number of generations total_gen = total_gen + current_batch*gen_per_batch -#ifdef MPI +#ifdef OPENMC_MPI ! Broadcast tally results so that each process has access to results if (allocated(tallies)) then do i = 1, size(tallies) diff --git a/src/source.F90 b/src/source.F90 index 557120e979..5beecd8870 100644 --- a/src/source.F90 +++ b/src/source.F90 @@ -1,7 +1,7 @@ module source use hdf5, only: HID_T -#ifdef MPI +#ifdef OPENMC_MPI use message_passing #endif diff --git a/src/state_point.F90 b/src/state_point.F90 index f7a8928987..ba7bcef19d 100644 --- a/src/state_point.F90 +++ b/src/state_point.F90 @@ -523,7 +523,7 @@ contains integer(HID_T) :: tallies_group, tally_group real(8), allocatable :: tally_temp(:,:,:) ! contiguous array of results real(8), target :: global_temp(3,N_GLOBAL_TALLIES) -#ifdef MPI +#ifdef OPENMC_MPI integer :: mpi_err ! MPI error code real(8) :: dummy ! temporary receive buffer for non-root reduces #endif @@ -543,7 +543,7 @@ contains end if -#ifdef MPI +#ifdef OPENMC_MPI ! Reduce global tallies n_bins = size(global_tallies) call MPI_REDUCE(global_tallies, global_temp, n_bins, MPI_REAL8, MPI_SUM, & @@ -586,7 +586,7 @@ contains ! The MPI_IN_PLACE specifier allows the master to copy values into ! a receive buffer without having a temporary variable -#ifdef MPI +#ifdef OPENMC_MPI call MPI_REDUCE(MPI_IN_PLACE, tally_temp, n_bins, MPI_REAL8, & MPI_SUM, 0, mpi_intracomm, mpi_err) #endif @@ -610,7 +610,7 @@ contains deallocate(dummy_tally % results) else ! Receive buffer not significant at other processors -#ifdef MPI +#ifdef OPENMC_MPI call MPI_REDUCE(tally_temp, dummy, n_bins, MPI_REAL8, MPI_SUM, & 0, mpi_intracomm, mpi_err) #endif @@ -849,7 +849,7 @@ contains integer(HID_T) :: plist ! property list #else integer :: i -#ifdef MPI +#ifdef OPENMC_MPI integer :: mpi_err ! MPI error code type(Bank), allocatable, target :: temp_source(:) #endif @@ -897,7 +897,7 @@ contains dspace, dset, hdf5_err) ! Save source bank sites since the souce_bank array is overwritten below -#ifdef MPI +#ifdef OPENMC_MPI allocate(temp_source(work)) temp_source(:) = source_bank(:) #endif @@ -907,7 +907,7 @@ contains dims(1) = work_index(i+1) - work_index(i) call h5screate_simple_f(1, dims, memspace, hdf5_err) -#ifdef MPI +#ifdef OPENMC_MPI ! Receive source sites from other processes if (i > 0) then call MPI_RECV(source_bank, int(dims(1)), MPI_BANK, i, i, & @@ -933,12 +933,12 @@ contains call h5dclose_f(dset, hdf5_err) ! Restore state of source bank -#ifdef MPI +#ifdef OPENMC_MPI source_bank(:) = temp_source(:) deallocate(temp_source) #endif else -#ifdef MPI +#ifdef OPENMC_MPI call MPI_SEND(source_bank, int(work), MPI_BANK, 0, rank, & mpi_intracomm, mpi_err) #endif diff --git a/src/summary.F90 b/src/summary.F90 index 0f45ef1bbd..ca72764073 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -24,6 +24,17 @@ module summary public :: write_summary + interface + subroutine surface_to_hdf5_c(surf_ind, group) & + bind(C, name='surface_to_hdf5') + use ISO_C_BINDING + use hdf5 + implicit none + integer(C_INT), intent(in), value :: surf_ind + integer(HID_T), intent(in), value :: group + end subroutine surface_to_hdf5_c + end interface + contains !=============================================================================== @@ -125,7 +136,6 @@ contains integer(HID_T) :: surfaces_group, surface_group integer(HID_T) :: universes_group, univ_group integer(HID_T) :: lattices_group, lattice_group - real(8), allocatable :: coeffs(:) character(:), allocatable :: region_spec type(Cell), pointer :: c class(Surface), pointer :: s @@ -245,87 +255,11 @@ contains surface_group = create_group(surfaces_group, "surface " // & trim(to_str(s%id))) + call surface_to_hdf5_c(i-1, surface_group) + ! Write name for this surface call write_dataset(surface_group, "name", s%name) - ! Write surface type - select type (s) - type is (SurfaceXPlane) - call write_dataset(surface_group, "type", "x-plane") - allocate(coeffs(1)) - coeffs(1) = s%x0 - - type is (SurfaceYPlane) - call write_dataset(surface_group, "type", "y-plane") - allocate(coeffs(1)) - coeffs(1) = s%y0 - - type is (SurfaceZPlane) - call write_dataset(surface_group, "type", "z-plane") - allocate(coeffs(1)) - coeffs(1) = s%z0 - - type is (SurfacePlane) - call write_dataset(surface_group, "type", "plane") - allocate(coeffs(4)) - coeffs(:) = [s%A, s%B, s%C, s%D] - - type is (SurfaceXCylinder) - call write_dataset(surface_group, "type", "x-cylinder") - allocate(coeffs(3)) - coeffs(:) = [s%y0, s%z0, s%r] - - type is (SurfaceYCylinder) - call write_dataset(surface_group, "type", "y-cylinder") - allocate(coeffs(3)) - coeffs(:) = [s%x0, s%z0, s%r] - - type is (SurfaceZCylinder) - call write_dataset(surface_group, "type", "z-cylinder") - allocate(coeffs(3)) - coeffs(:) = [s%x0, s%y0, s%r] - - type is (SurfaceSphere) - call write_dataset(surface_group, "type", "sphere") - allocate(coeffs(4)) - coeffs(:) = [s%x0, s%y0, s%z0, s%r] - - type is (SurfaceXCone) - call write_dataset(surface_group, "type", "x-cone") - allocate(coeffs(4)) - coeffs(:) = [s%x0, s%y0, s%z0, s%r2] - - type is (SurfaceYCone) - call write_dataset(surface_group, "type", "y-cone") - allocate(coeffs(4)) - coeffs(:) = [s%x0, s%y0, s%z0, s%r2] - - type is (SurfaceZCone) - call write_dataset(surface_group, "type", "z-cone") - allocate(coeffs(4)) - coeffs(:) = [s%x0, s%y0, s%z0, s%r2] - - type is (SurfaceQuadric) - call write_dataset(surface_group, "type", "quadric") - allocate(coeffs(10)) - coeffs(:) = [s%A, s%B, s%C, s%D, s%E, s%F, s%G, s%H, s%J, s%K] - - end select - call write_dataset(surface_group, "coefficients", coeffs) - deallocate(coeffs) - - ! Write boundary type - select case (s%bc) - case (BC_TRANSMIT) - call write_dataset(surface_group, "boundary_type", "transmission") - case (BC_VACUUM) - call write_dataset(surface_group, "boundary_type", "vacuum") - case (BC_REFLECT) - call write_dataset(surface_group, "boundary_type", "reflective") - case (BC_PERIODIC) - call write_dataset(surface_group, "boundary_type", "periodic") - end select - call close_group(surface_group) end do SURFACE_LOOP diff --git a/src/surface_header.C b/src/surface_header.C index 45fb62399e..db53c8982e 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -1,8 +1,12 @@ +#include // For std::array #include // For strcmp #include // For numeric_limits #include // For fabs #include "pugixml/pugixml.hpp" +#include "hdf5.h" + +#include "hdf5_interface.h" // DEBUGGING #include @@ -15,6 +19,11 @@ const double FP_COINCIDENT = 1e-12; const double INFTY = std::numeric_limits::max(); +const int BC_TRANSMIT{0}; +const int BC_VACUUM{1}; +const int BC_REFLECT{2}; +const int BC_PERIODIC{3}; + //============================================================================== // Global array of surfaces //============================================================================== @@ -127,6 +136,13 @@ public: //! @param xyz[3] A 3D Cartesian coordinate. //! @param uvw[3] This output argument provides the normal. virtual void normal(const double xyz[3], double uvw[3]) const = 0; + + //! Write all information needed to reconstruct the surface to an HDF5 group. + //! @param group_id An HDF5 group id. + virtual void to_hdf5(hid_t group_id) const = 0; + +protected: + void write_bc_to_hdf5(hid_t group_id) const; }; bool @@ -164,6 +180,25 @@ Surface::reflect(const double xyz[3], double uvw[3]) const uvw[2] -= 2.0 * projection / magnitude * norm[2]; } +void +Surface::write_bc_to_hdf5(hid_t group_id) const +{ + switch(bc) { + case BC_TRANSMIT : + write_string(group_id, "boundary_type", "transmission"); + break; + case BC_VACUUM : + write_string(group_id, "boundary_type", "vacuum"); + break; + case BC_REFLECT : + write_string(group_id, "boundary_type", "reflective"); + break; + case BC_PERIODIC : + write_string(group_id, "boundary_type", "periodic"); + break; + } +} + //============================================================================== //! A `Surface` that supports periodic boundary conditions. //! @@ -236,6 +271,7 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; }; @@ -261,6 +297,14 @@ inline void SurfaceXPlane::normal(const double xyz[3], double uvw[3]) const axis_aligned_plane_normal<0, 1, 2>(xyz, uvw); } +void SurfaceXPlane::to_hdf5(hid_t group_id) const +{ + write_string(group_id, "type", "x-plane"); + std::array coeffs{{x0}}; + write_double_1D(group_id, "coefficients", coeffs); + write_bc_to_hdf5(group_id); +} + bool SurfaceXPlane::periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const { @@ -285,7 +329,7 @@ bool SurfaceXPlane::periodic_translate(PeriodicSurface *other, double xyz[3], return true; } -}; +} //============================================================================== // SurfaceYPlane @@ -303,6 +347,7 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; }; @@ -328,6 +373,14 @@ inline void SurfaceYPlane::normal(const double xyz[3], double uvw[3]) const axis_aligned_plane_normal<1, 0, 2>(xyz, uvw); } +void SurfaceYPlane::to_hdf5(hid_t group_id) const +{ + write_string(group_id, "type", "y-plane"); + std::array coeffs{{y0}}; + write_double_1D(group_id, "coefficients", coeffs); + write_bc_to_hdf5(group_id); +} + bool SurfaceYPlane::periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const { @@ -352,7 +405,7 @@ bool SurfaceYPlane::periodic_translate(PeriodicSurface *other, double xyz[3], return true; } -}; +} //============================================================================== // SurfaceZPlane @@ -370,6 +423,7 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; }; @@ -395,13 +449,21 @@ inline void SurfaceZPlane::normal(const double xyz[3], double uvw[3]) const axis_aligned_plane_normal<2, 0, 1>(xyz, uvw); } +void SurfaceZPlane::to_hdf5(hid_t group_id) const +{ + write_string(group_id, "type", "z-plane"); + std::array coeffs{{z0}}; + write_double_1D(group_id, "coefficients", coeffs); + write_bc_to_hdf5(group_id); +} + bool SurfaceZPlane::periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const { // Assume the other plane is aligned along z. Just change the z coord. xyz[2] = z0; return false; -}; +} //============================================================================== // SurfacePlane @@ -419,6 +481,7 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; }; @@ -457,6 +520,14 @@ SurfacePlane::normal(const double xyz[3], double uvw[3]) const uvw[2] = C; } +void SurfacePlane::to_hdf5(hid_t group_id) const +{ + write_string(group_id, "type", "plane"); + std::array coeffs{{A, B, C, D}}; + write_double_1D(group_id, "coefficients", coeffs); + write_bc_to_hdf5(group_id); +} + bool SurfacePlane::periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const { @@ -564,6 +635,7 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5(hid_t group_id) const; }; SurfaceXCylinder::SurfaceXCylinder(pugi::xml_node surf_node) @@ -588,6 +660,15 @@ inline void SurfaceXCylinder::normal(const double xyz[3], double uvw[3]) const axis_aligned_cylinder_normal<0, 1, 2>(xyz, uvw, y0, z0); } + +void SurfaceXCylinder::to_hdf5(hid_t group_id) const +{ + write_string(group_id, "type", "x-cylinder"); + std::array coeffs{{y0, z0, r}}; + write_double_1D(group_id, "coefficients", coeffs); + write_bc_to_hdf5(group_id); +} + //============================================================================== // SurfaceYCylinder //! A cylinder aligned along the y-axis. @@ -605,6 +686,7 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5(hid_t group_id) const; }; SurfaceYCylinder::SurfaceYCylinder(pugi::xml_node surf_node) @@ -629,6 +711,14 @@ inline void SurfaceYCylinder::normal(const double xyz[3], double uvw[3]) const axis_aligned_cylinder_normal<1, 0, 2>(xyz, uvw, x0, z0); } +void SurfaceYCylinder::to_hdf5(hid_t group_id) const +{ + write_string(group_id, "type", "y-cylinder"); + std::array coeffs{{x0, z0, r}}; + write_double_1D(group_id, "coefficients", coeffs); + write_bc_to_hdf5(group_id); +} + //============================================================================== // SurfaceZCylinder //! A cylinder aligned along the z-axis. @@ -646,6 +736,7 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5(hid_t group_id) const; }; SurfaceZCylinder::SurfaceZCylinder(pugi::xml_node surf_node) @@ -670,6 +761,14 @@ inline void SurfaceZCylinder::normal(const double xyz[3], double uvw[3]) const axis_aligned_cylinder_normal<2, 0, 1>(xyz, uvw, x0, y0); } +void SurfaceZCylinder::to_hdf5(hid_t group_id) const +{ + write_string(group_id, "type", "z-cylinder"); + std::array coeffs{{x0, y0, r}}; + write_double_1D(group_id, "coefficients", coeffs); + write_bc_to_hdf5(group_id); +} + //============================================================================== // SurfaceSphere //! A sphere. @@ -687,6 +786,7 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5(hid_t group_id) const; }; SurfaceSphere::SurfaceSphere(pugi::xml_node surf_node) @@ -748,6 +848,14 @@ inline void SurfaceSphere::normal(const double xyz[3], double uvw[3]) const uvw[2] = 2.0 * (xyz[2] - z0); } +void SurfaceSphere::to_hdf5(hid_t group_id) const +{ + write_string(group_id, "type", "sphere"); + std::array coeffs{{x0, y0, z0, r}}; + write_double_1D(group_id, "coefficients", coeffs); + write_bc_to_hdf5(group_id); +} + //============================================================================== // Generic functions for x-, y-, and z-, cones //============================================================================== @@ -848,6 +956,7 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5(hid_t group_id) const; }; SurfaceXCone::SurfaceXCone(pugi::xml_node surf_node) @@ -872,6 +981,14 @@ inline void SurfaceXCone::normal(const double xyz[3], double uvw[3]) const axis_aligned_cone_normal<0, 1, 2>(xyz, uvw, x0, y0, z0, r_sq); } +void SurfaceXCone::to_hdf5(hid_t group_id) const +{ + write_string(group_id, "type", "x-cone"); + std::array coeffs{{x0, y0, z0, r_sq}}; + write_double_1D(group_id, "coefficients", coeffs); + write_bc_to_hdf5(group_id); +} + //============================================================================== // SurfaceYCone //! A cone aligned along the y-axis. @@ -889,6 +1006,7 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5(hid_t group_id) const; }; SurfaceYCone::SurfaceYCone(pugi::xml_node surf_node) @@ -913,6 +1031,14 @@ inline void SurfaceYCone::normal(const double xyz[3], double uvw[3]) const axis_aligned_cone_normal<1, 0, 2>(xyz, uvw, y0, x0, z0, r_sq); } +void SurfaceYCone::to_hdf5(hid_t group_id) const +{ + write_string(group_id, "type", "y-cone"); + std::array coeffs{{x0, y0, z0, r_sq}}; + write_double_1D(group_id, "coefficients", coeffs); + write_bc_to_hdf5(group_id); +} + //============================================================================== // SurfaceZCone //! A cone aligned along the z-axis. @@ -930,6 +1056,7 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5(hid_t group_id) const; }; SurfaceZCone::SurfaceZCone(pugi::xml_node surf_node) @@ -954,6 +1081,14 @@ inline void SurfaceZCone::normal(const double xyz[3], double uvw[3]) const axis_aligned_cone_normal<2, 0, 1>(xyz, uvw, z0, x0, y0, r_sq); } +void SurfaceZCone::to_hdf5(hid_t group_id) const +{ + write_string(group_id, "type", "z-cone"); + std::array coeffs{{x0, y0, z0, r_sq}}; + write_double_1D(group_id, "coefficients", coeffs); + write_bc_to_hdf5(group_id); +} + //============================================================================== // SurfaceQuadric //! A general surface described by a quadratic equation. @@ -971,6 +1106,7 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5(hid_t group_id) const; }; SurfaceQuadric::SurfaceQuadric(pugi::xml_node surf_node) @@ -1055,6 +1191,14 @@ SurfaceQuadric::normal(const double xyz[3], double uvw[3]) const uvw[2] = 2.0*C*z + E*y + F*x + J; } +void SurfaceQuadric::to_hdf5(hid_t group_id) const +{ + write_string(group_id, "type", "quadric"); + std::array coeffs{{A, B, C, D, E, F, G, H, J, K}}; + write_double_1D(group_id, "coefficients", coeffs); + write_bc_to_hdf5(group_id); +} + //============================================================================== extern "C" void @@ -1084,6 +1228,7 @@ read_surfaces(pugi::xml_node *node) } else { std::cout << "ERROR: Found a surface with no type attribute/node" << std::endl; + //TODO: call fatal_error } if (strcmp(surf_type, "x-plane") == 0) { @@ -1125,6 +1270,33 @@ read_surfaces(pugi::xml_node *node) } else { std::cout << "Call error or handle uppercase here!" << std::endl; std::cout << surf_type << std::endl; + //TODO: call fatal_error + } + + const pugi::char_t *surf_bc{""}; + if (surf_node.attribute("boundary")) { + surf_bc = surf_node.attribute("boundary").value(); + } else if (surf_node.child("boundary")) { + surf_bc = surf_node.attribute("boundary").value(); + } + + if (strcmp(surf_bc, "transmission") == 0 + or strcmp(surf_bc, "transmit") == 0 + or strcmp(surf_bc, "") == 0) { + surfaces_c[i_surf]->bc = BC_TRANSMIT; + + } else if (strcmp(surf_bc, "vacuum") == 0) { + surfaces_c[i_surf]->bc = BC_VACUUM; + + } else if (strcmp(surf_bc, "reflective") == 0 + or strcmp(surf_bc, "reflect") == 0 + or strcmp(surf_bc, "reflecting") == 0) { + surfaces_c[i_surf]->bc = BC_REFLECT; + } else if (strcmp(surf_bc, "periodic") == 0) { + surfaces_c[i_surf]->bc = BC_PERIODIC; + } else { + std::cout << "Unknown boundary condition" << std::endl; + //TODO: call fatal_error } } } @@ -1156,6 +1328,12 @@ surface_normal(int surf_ind, double xyz[3], double uvw[3]) return surfaces_c[surf_ind]->normal(xyz, uvw); } +extern "C" void +surface_to_hdf5(int surf_ind, hid_t group) +{ + surfaces_c[surf_ind]->to_hdf5(group); +} + extern "C" bool surface_periodic(int surf_ind1, int surf_ind2, double xyz[3], double uvw[3]) { diff --git a/src/surface_header.F90 b/src/surface_header.F90 index d632903871..98e2423b62 100644 --- a/src/surface_header.F90 +++ b/src/surface_header.F90 @@ -36,84 +36,39 @@ module surface_header !=============================================================================== type, extends(Surface) :: SurfaceXPlane - ! x = x0 - real(8) :: x0 end type SurfaceXPlane type, extends(Surface) :: SurfaceYPlane - ! y = y0 - real(8) :: y0 end type SurfaceYPlane type, extends(Surface) :: SurfaceZPlane - ! z = z0 - real(8) :: z0 end type SurfaceZPlane type, extends(Surface) :: SurfacePlane - ! Ax + By + Cz = D - real(8) :: A - real(8) :: B - real(8) :: C - real(8) :: D end type SurfacePlane type, extends(Surface) :: SurfaceXCylinder - ! (y - y0)^2 + (z - z0)^2 = R^2 - real(8) :: y0 - real(8) :: z0 - real(8) :: r end type SurfaceXCylinder type, extends(Surface) :: SurfaceYCylinder - ! (x - x0)^2 + (z - z0)^2 = R^2 - real(8) :: x0 - real(8) :: z0 - real(8) :: r end type SurfaceYCylinder type, extends(Surface) :: SurfaceZCylinder - ! (x - x0)^2 + (y - y0)^2 = R^2 - real(8) :: x0 - real(8) :: y0 - real(8) :: r end type SurfaceZCylinder type, extends(Surface) :: SurfaceSphere - ! (x - x0)^2 + (y - y0)^2 + (z - z0)^2 = R^2 - real(8) :: x0 - real(8) :: y0 - real(8) :: z0 - real(8) :: r end type SurfaceSphere type, extends(Surface) :: SurfaceXCone - ! (y - y0)^2 + (z - z0)^2 = R^2*(x - x0)^2 - real(8) :: x0 - real(8) :: y0 - real(8) :: z0 - real(8) :: r2 end type SurfaceXCone type, extends(Surface) :: SurfaceYCone - ! (x - x0)^2 + (z - z0)^2 = R^2*(y - y0)^2 - real(8) :: x0 - real(8) :: y0 - real(8) :: z0 - real(8) :: r2 end type SurfaceYCone type, extends(Surface) :: SurfaceZCone - ! (x - x0)^2 + (y - y0)^2 = R^2*(z - z0)^2 - real(8) :: x0 - real(8) :: y0 - real(8) :: z0 - real(8) :: r2 end type SurfaceZCone type, extends(Surface) :: SurfaceQuadric - ! Ax^2 + By^2 + Cz^2 + Dxy + Eyz + Fxz + Gx + Hy + Jz + K = 0 - real(8) :: A, B, C, D, E, F, G, H, J, K end type SurfaceQuadric integer(C_INT32_T), bind(C) :: n_surfaces ! # of surfaces diff --git a/src/tallies/tally.F90 b/src/tallies/tally.F90 index 7684a36aa6..7c234f1735 100644 --- a/src/tallies/tally.F90 +++ b/src/tallies/tally.F90 @@ -4241,7 +4241,7 @@ contains real(C_DOUBLE) :: k_tra ! Copy of batch tracklength estimate of keff real(C_DOUBLE) :: val -#ifdef MPI +#ifdef OPENMC_MPI ! Combine tally results onto master process if (reduce_tallies) call reduce_tally_results() #endif @@ -4289,7 +4289,7 @@ contains ! REDUCE_TALLY_RESULTS collects all the results from tallies onto one processor !=============================================================================== -#ifdef MPI +#ifdef OPENMC_MPI subroutine reduce_tally_results() integer :: i diff --git a/src/tallies/trigger.F90 b/src/tallies/trigger.F90 index 9e9b06d205..ee2259ed48 100644 --- a/src/tallies/trigger.F90 +++ b/src/tallies/trigger.F90 @@ -2,7 +2,7 @@ module trigger use, intrinsic :: ISO_C_BINDING -#ifdef MPI +#ifdef OPENMC_MPI use message_passing #endif diff --git a/src/volume_calc.F90 b/src/volume_calc.F90 index 5985a236b3..07dc5b4184 100644 --- a/src/volume_calc.F90 +++ b/src/volume_calc.F90 @@ -136,7 +136,7 @@ contains integer :: total_hits ! total hits for a single domain (summed over materials) integer :: min_samples ! minimum number of samples per process integer :: remainder ! leftover samples from uneven divide -#ifdef MPI +#ifdef OPENMC_MPI integer :: mpi_err ! MPI error code integer :: m ! index over materials integer :: n ! number of materials @@ -279,7 +279,7 @@ contains total_hits = 0 if (master) then -#ifdef MPI +#ifdef OPENMC_MPI do j = 1, n_procs - 1 call MPI_RECV(n, 1, MPI_INTEGER, j, 0, mpi_intracomm, & MPI_STATUS_IGNORE, mpi_err) @@ -341,7 +341,7 @@ contains end do else -#ifdef MPI +#ifdef OPENMC_MPI n = master_indices(i_domain) % size() allocate(data(2*n)) do k = 0, n - 1 From 7624888df34577b9ed735039ff5b33bab8c0e44c Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Tue, 23 Jan 2018 12:37:28 -0500 Subject: [PATCH 14/74] Finish C++ surface->summary.h5 capability --- CMakeLists.txt | 1 + src/constants.F90 | 15 ++- src/error.F90 | 8 ++ src/error.h | 21 ++++ src/hdf5_interface.h | 44 +++++++- src/summary.F90 | 11 +- src/surface_header.C | 263 +++++++++++++++++++++++++++---------------- 7 files changed, 243 insertions(+), 120 deletions(-) create mode 100644 src/error.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 58fb55e799..e59713755f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -435,6 +435,7 @@ set(LIBOPENMC_FORTRAN_SRC src/tallies/trigger_header.F90 ) set(LIBOPENMC_CXX_SRC + src/error.h src/hdf5_interface.h src/random_lcg.h src/random_lcg.cpp diff --git a/src/constants.F90 b/src/constants.F90 index 331a644f09..3334a4cc76 100644 --- a/src/constants.F90 +++ b/src/constants.F90 @@ -43,9 +43,9 @@ module constants real(8), parameter :: TINY_BIT = 1e-8_8 ! User for precision in geometry - real(8), parameter :: FP_PRECISION = 1e-14_8 - real(8), parameter :: FP_REL_PRECISION = 1e-5_8 - real(8), parameter :: FP_COINCIDENT = 1e-12_8 + real(C_DOUBLE), bind(C, name='FP_PRECISION') :: FP_PRECISION = 1e-14_8 + real(C_DOUBLE), bind(C, name='FP_REL_PRECISION') :: FP_REL_PRECISION = 1e-5_8 + real(C_DOUBLE), bind(C, name='FP_COINCIDENT') :: FP_COINCIDENT = 1e-12_8 ! Maximum number of collisions/crossings integer, parameter :: MAX_EVENTS = 1000000 @@ -95,11 +95,10 @@ module constants ! GEOMETRY-RELATED CONSTANTS ! Boundary conditions - integer, parameter :: & - BC_TRANSMIT = 0, & ! Transmission boundary condition (default) - BC_VACUUM = 1, & ! Vacuum boundary condition - BC_REFLECT = 2, & ! Reflecting boundary condition - BC_PERIODIC = 3 ! Periodic boundary condition + integer(C_INT), bind(C, name="BC_TRANSMIT") :: BC_TRANSMIT + integer(C_INT), bind(C, name="BC_VACUUM") :: BC_VACUUM + integer(C_INT), bind(C, name="BC_REFLECT") :: BC_REFLECT + integer(C_INT), bind(C, name="BC_PERIODIC") :: BC_PERIODIC ! Logical operators for cell definitions integer, parameter :: & diff --git a/src/error.F90 b/src/error.F90 index ae02e0897d..cba1372917 100644 --- a/src/error.F90 +++ b/src/error.F90 @@ -194,6 +194,14 @@ contains end subroutine fatal_error + subroutine fatal_error_from_c(message, message_len) bind(C) + integer(C_INT), intent(in), value :: message_len + character(C_CHAR), intent(in) :: message(message_len) + character(message_len+1) :: message_out + write(message_out, *) message + call fatal_error(message_out) + end subroutine + !=============================================================================== ! WRITE_MESSAGE displays an informational message to the log file and the ! standard output stream. diff --git a/src/error.h b/src/error.h new file mode 100644 index 0000000000..77f0252e13 --- /dev/null +++ b/src/error.h @@ -0,0 +1,21 @@ +#ifndef ERROR_H +#define ERROR_H + +#include + + +extern "C" void fatal_error_from_c(const char *message, int message_len); + + +void fatal_error(const char *message) +{ + fatal_error_from_c(message, strlen(message)); +} + + +void fatal_error(const std::string &message) +{ + fatal_error_from_c(message.c_str(), message.length()); +} + +#endif // ERROR_H diff --git a/src/hdf5_interface.h b/src/hdf5_interface.h index 38bb7d88bc..2cded21f64 100644 --- a/src/hdf5_interface.h +++ b/src/hdf5_interface.h @@ -1,11 +1,44 @@ #ifndef HDF5_INTERFACE_H #define HDF5_INTERFACE_H -#include // For std::array -#include // For strlen +#include +#include #include "hdf5.h" +#include "error.h" + + +hid_t +create_group(hid_t parent_id, char const *name) +{ + hid_t out = H5Gcreate(parent_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (out < 0) { + std::string err_msg{"Failed to create HDF5 group \""}; + err_msg += name; + err_msg += "\""; + fatal_error(err_msg); + } + return out; +} + + +hid_t +create_group(hid_t parent_id, const std::string &name) +{ + return create_group(parent_id, name.c_str()); +} + + +void +close_group(hid_t group_id) +{ + herr_t err = H5Gclose(group_id); + if (err < 0) { + fatal_error("Failed to close HDF5 group"); + } +} + template void write_double_1D(hid_t group_id, char const *name, @@ -44,4 +77,11 @@ write_string(hid_t group_id, char const *name, char const *buffer) H5Dclose(dataset); } + +void +write_string(hid_t group_id, char const *name, const std::string &buffer) +{ + write_string(group_id, name, buffer.c_str()); +} + #endif //HDF5_INTERFACE_H diff --git a/src/summary.F90 b/src/summary.F90 index ca72764073..77bded9837 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -251,16 +251,7 @@ contains ! Write information on each surface SURFACE_LOOP: do i = 1, n_surfaces - s => surfaces(i)%obj - surface_group = create_group(surfaces_group, "surface " // & - trim(to_str(s%id))) - - call surface_to_hdf5_c(i-1, surface_group) - - ! Write name for this surface - call write_dataset(surface_group, "name", s%name) - - call close_group(surface_group) + call surface_to_hdf5_c(i-1, surfaces_group) end do SURFACE_LOOP call close_group(surfaces_group) diff --git a/src/surface_header.C b/src/surface_header.C index db53c8982e..4cfda86efa 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -1,3 +1,4 @@ +#include // for std::transform #include // For std::array #include // For strcmp #include // For numeric_limits @@ -6,23 +7,61 @@ #include "pugixml/pugixml.hpp" #include "hdf5.h" +#include "error.h" #include "hdf5_interface.h" // DEBUGGING #include #include +bool +check_for_node(const pugi::xml_node &node, const char *name) +{ + if (node.attribute(name)) { + return true; + } else if (node.child(name)) { + return true; + } else { + return false; + } +} + +std::string +get_node_value(const pugi::xml_node &node, const char *name) +{ + const pugi::char_t *value_char; + if (node.attribute(name)) { + value_char = node.attribute(name).value(); + } else if (node.child(name)) { + value_char = node.child_value(name); + } else { + std::string err_msg("Node \""); + err_msg += name; + err_msg += "\" is not a memeber of the \""; + err_msg += node.name(); + err_msg += "\" XML node"; + fatal_error(err_msg); + } + + std::string value(value_char); + std::transform(value.begin(), value.end(), value.begin(), ::tolower); + return value; +} + //============================================================================== // Constants //============================================================================== -const double FP_COINCIDENT = 1e-12; -const double INFTY = std::numeric_limits::max(); +//extern "C" const double FP_COINCIDENT{1e-12}; +//extern "C" const double INFTY{std::numeric_limits::max()}; +extern "C" double FP_COINCIDENT; +//extern "C" double INFTY; +const double INFTY{std::numeric_limits::max()}; -const int BC_TRANSMIT{0}; -const int BC_VACUUM{1}; -const int BC_REFLECT{2}; -const int BC_PERIODIC{3}; +extern "C" const int BC_TRANSMIT{0}; +extern "C" const int BC_VACUUM{1}; +extern "C" const int BC_REFLECT{2}; +extern "C" const int BC_PERIODIC{3}; //============================================================================== // Global array of surfaces @@ -95,12 +134,14 @@ class Surface { public: int id; //!< Unique ID - int neighbor_pos[], //!< List of cells on positive side - neighbor_neg[]; //!< List of cells on negative side + //int neighbor_pos[], //!< List of cells on positive side + // neighbor_neg[]; //!< List of cells on negative side int bc; //!< Boundary condition //TODO: switch that zero to a NONE constant. //int i_periodic = 0; //!< Index of corresponding periodic surface - char name[104]; //!< User-defined name + std::string name{""}; //!< User-defined name + + Surface(pugi::xml_node surf_node); //! Determine which side of a surface a point lies on. //! @param xyz[3] The 3D Cartesian coordinate of a point. @@ -139,12 +180,54 @@ public: //! Write all information needed to reconstruct the surface to an HDF5 group. //! @param group_id An HDF5 group id. - virtual void to_hdf5(hid_t group_id) const = 0; + void to_hdf5(hid_t group_id) const; protected: - void write_bc_to_hdf5(hid_t group_id) const; + virtual void to_hdf5_inner(hid_t group_id) const = 0; }; +Surface::Surface(pugi::xml_node surf_node) +{ + if (check_for_node(surf_node, "id")) { + id = stoi(get_node_value(surf_node, "id")); + } else { + fatal_error("Must specify id of surface in geometry XML file."); + } + //TODO: check for duplicate IDs + + if (check_for_node(surf_node, "name")) { + name = get_node_value(surf_node, "name"); + } + + if (check_for_node(surf_node, "boundary")) { + std::string surf_bc = get_node_value(surf_node, "boundary"); + + if (surf_bc.compare("transmission") == 0 + or surf_bc.compare("transmit") == 0 + or surf_bc.compare("") == 0) { + bc = BC_TRANSMIT; + + } else if (surf_bc.compare("vacuum") == 0) { + bc = BC_VACUUM; + + } else if (surf_bc.compare("reflective") == 0 + or surf_bc.compare("reflect") == 0 + or surf_bc.compare("reflecting") == 0) { + bc = BC_REFLECT; + } else if (surf_bc.compare("periodic") == 0) { + bc = BC_PERIODIC; + } else { + std::string err_msg("Unknown boundary condition \""); + err_msg += surf_bc + "\" specified on surface " + std::to_string(id); + fatal_error(err_msg); + } + + } else { + bc = BC_TRANSMIT; + } + +} + bool Surface::sense(const double xyz[3], const double uvw[3]) const { @@ -181,22 +264,35 @@ Surface::reflect(const double xyz[3], double uvw[3]) const } void -Surface::write_bc_to_hdf5(hid_t group_id) const +Surface::to_hdf5(hid_t group_id) const { + std::string group_name{"surface "}; + group_name += std::to_string(id); + + hid_t surf_group = create_group(group_id, group_name); + switch(bc) { case BC_TRANSMIT : - write_string(group_id, "boundary_type", "transmission"); + write_string(surf_group, "boundary_type", "transmission"); break; case BC_VACUUM : - write_string(group_id, "boundary_type", "vacuum"); + write_string(surf_group, "boundary_type", "vacuum"); break; case BC_REFLECT : - write_string(group_id, "boundary_type", "reflective"); + write_string(surf_group, "boundary_type", "reflective"); break; case BC_PERIODIC : - write_string(group_id, "boundary_type", "periodic"); + write_string(surf_group, "boundary_type", "periodic"); break; } + + if (name.compare("")) { + write_string(surf_group, "name", name); + } + + to_hdf5_inner(surf_group); + + close_group(surf_group); } //============================================================================== @@ -210,6 +306,8 @@ Surface::write_bc_to_hdf5(hid_t group_id) const class PeriodicSurface : public Surface { public: + PeriodicSurface(pugi::xml_node surf_node) : Surface(surf_node) {} + //! Translate a particle onto this surface from a periodic partner surface. //! @param other A pointer to the partner surface in this periodic BC. //! @param xyz[3] A point on the partner surface that will be translated onto @@ -271,12 +369,13 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5(hid_t group_id) const; + void to_hdf5_inner(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; }; SurfaceXPlane::SurfaceXPlane(pugi::xml_node surf_node) + : PeriodicSurface(surf_node) { read_coeffs(surf_node, x0); } @@ -297,12 +396,11 @@ inline void SurfaceXPlane::normal(const double xyz[3], double uvw[3]) const axis_aligned_plane_normal<0, 1, 2>(xyz, uvw); } -void SurfaceXPlane::to_hdf5(hid_t group_id) const +void SurfaceXPlane::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "x-plane"); std::array coeffs{{x0}}; write_double_1D(group_id, "coefficients", coeffs); - write_bc_to_hdf5(group_id); } bool SurfaceXPlane::periodic_translate(PeriodicSurface *other, double xyz[3], @@ -347,12 +445,13 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5(hid_t group_id) const; + void to_hdf5_inner(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; }; SurfaceYPlane::SurfaceYPlane(pugi::xml_node surf_node) + : PeriodicSurface(surf_node) { read_coeffs(surf_node, y0); } @@ -373,12 +472,11 @@ inline void SurfaceYPlane::normal(const double xyz[3], double uvw[3]) const axis_aligned_plane_normal<1, 0, 2>(xyz, uvw); } -void SurfaceYPlane::to_hdf5(hid_t group_id) const +void SurfaceYPlane::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "y-plane"); std::array coeffs{{y0}}; write_double_1D(group_id, "coefficients", coeffs); - write_bc_to_hdf5(group_id); } bool SurfaceYPlane::periodic_translate(PeriodicSurface *other, double xyz[3], @@ -423,12 +521,13 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5(hid_t group_id) const; + void to_hdf5_inner(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; }; SurfaceZPlane::SurfaceZPlane(pugi::xml_node surf_node) + : PeriodicSurface(surf_node) { read_coeffs(surf_node, z0); } @@ -449,12 +548,11 @@ inline void SurfaceZPlane::normal(const double xyz[3], double uvw[3]) const axis_aligned_plane_normal<2, 0, 1>(xyz, uvw); } -void SurfaceZPlane::to_hdf5(hid_t group_id) const +void SurfaceZPlane::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "z-plane"); std::array coeffs{{z0}}; write_double_1D(group_id, "coefficients", coeffs); - write_bc_to_hdf5(group_id); } bool SurfaceZPlane::periodic_translate(PeriodicSurface *other, double xyz[3], @@ -481,12 +579,13 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5(hid_t group_id) const; + void to_hdf5_inner(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; }; SurfacePlane::SurfacePlane(pugi::xml_node surf_node) + : PeriodicSurface(surf_node) { read_coeffs(surf_node, A, B, C, D); } @@ -520,12 +619,11 @@ SurfacePlane::normal(const double xyz[3], double uvw[3]) const uvw[2] = C; } -void SurfacePlane::to_hdf5(hid_t group_id) const +void SurfacePlane::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "plane"); std::array coeffs{{A, B, C, D}}; write_double_1D(group_id, "coefficients", coeffs); - write_bc_to_hdf5(group_id); } bool SurfacePlane::periodic_translate(PeriodicSurface *other, double xyz[3], @@ -635,10 +733,11 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5(hid_t group_id) const; + void to_hdf5_inner(hid_t group_id) const; }; SurfaceXCylinder::SurfaceXCylinder(pugi::xml_node surf_node) + : Surface(surf_node) { read_coeffs(surf_node, y0, z0, r); } @@ -661,12 +760,11 @@ inline void SurfaceXCylinder::normal(const double xyz[3], double uvw[3]) const } -void SurfaceXCylinder::to_hdf5(hid_t group_id) const +void SurfaceXCylinder::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "x-cylinder"); std::array coeffs{{y0, z0, r}}; write_double_1D(group_id, "coefficients", coeffs); - write_bc_to_hdf5(group_id); } //============================================================================== @@ -686,10 +784,11 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5(hid_t group_id) const; + void to_hdf5_inner(hid_t group_id) const; }; SurfaceYCylinder::SurfaceYCylinder(pugi::xml_node surf_node) + : Surface(surf_node) { read_coeffs(surf_node, x0, z0, r); } @@ -711,12 +810,11 @@ inline void SurfaceYCylinder::normal(const double xyz[3], double uvw[3]) const axis_aligned_cylinder_normal<1, 0, 2>(xyz, uvw, x0, z0); } -void SurfaceYCylinder::to_hdf5(hid_t group_id) const +void SurfaceYCylinder::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "y-cylinder"); std::array coeffs{{x0, z0, r}}; write_double_1D(group_id, "coefficients", coeffs); - write_bc_to_hdf5(group_id); } //============================================================================== @@ -736,10 +834,11 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5(hid_t group_id) const; + void to_hdf5_inner(hid_t group_id) const; }; SurfaceZCylinder::SurfaceZCylinder(pugi::xml_node surf_node) + : Surface(surf_node) { read_coeffs(surf_node, x0, y0, r); } @@ -761,12 +860,11 @@ inline void SurfaceZCylinder::normal(const double xyz[3], double uvw[3]) const axis_aligned_cylinder_normal<2, 0, 1>(xyz, uvw, x0, y0); } -void SurfaceZCylinder::to_hdf5(hid_t group_id) const +void SurfaceZCylinder::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "z-cylinder"); std::array coeffs{{x0, y0, r}}; write_double_1D(group_id, "coefficients", coeffs); - write_bc_to_hdf5(group_id); } //============================================================================== @@ -786,10 +884,11 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5(hid_t group_id) const; + void to_hdf5_inner(hid_t group_id) const; }; SurfaceSphere::SurfaceSphere(pugi::xml_node surf_node) + : Surface(surf_node) { read_coeffs(surf_node, x0, y0, z0, r); } @@ -848,12 +947,11 @@ inline void SurfaceSphere::normal(const double xyz[3], double uvw[3]) const uvw[2] = 2.0 * (xyz[2] - z0); } -void SurfaceSphere::to_hdf5(hid_t group_id) const +void SurfaceSphere::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "sphere"); std::array coeffs{{x0, y0, z0, r}}; write_double_1D(group_id, "coefficients", coeffs); - write_bc_to_hdf5(group_id); } //============================================================================== @@ -956,10 +1054,11 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5(hid_t group_id) const; + void to_hdf5_inner(hid_t group_id) const; }; SurfaceXCone::SurfaceXCone(pugi::xml_node surf_node) + : Surface(surf_node) { read_coeffs(surf_node, x0, y0, z0, r_sq); } @@ -981,12 +1080,11 @@ inline void SurfaceXCone::normal(const double xyz[3], double uvw[3]) const axis_aligned_cone_normal<0, 1, 2>(xyz, uvw, x0, y0, z0, r_sq); } -void SurfaceXCone::to_hdf5(hid_t group_id) const +void SurfaceXCone::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "x-cone"); std::array coeffs{{x0, y0, z0, r_sq}}; write_double_1D(group_id, "coefficients", coeffs); - write_bc_to_hdf5(group_id); } //============================================================================== @@ -1006,10 +1104,11 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5(hid_t group_id) const; + void to_hdf5_inner(hid_t group_id) const; }; SurfaceYCone::SurfaceYCone(pugi::xml_node surf_node) + : Surface(surf_node) { read_coeffs(surf_node, x0, y0, z0, r_sq); } @@ -1031,12 +1130,11 @@ inline void SurfaceYCone::normal(const double xyz[3], double uvw[3]) const axis_aligned_cone_normal<1, 0, 2>(xyz, uvw, y0, x0, z0, r_sq); } -void SurfaceYCone::to_hdf5(hid_t group_id) const +void SurfaceYCone::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "y-cone"); std::array coeffs{{x0, y0, z0, r_sq}}; write_double_1D(group_id, "coefficients", coeffs); - write_bc_to_hdf5(group_id); } //============================================================================== @@ -1056,10 +1154,11 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5(hid_t group_id) const; + void to_hdf5_inner(hid_t group_id) const; }; SurfaceZCone::SurfaceZCone(pugi::xml_node surf_node) + : Surface(surf_node) { read_coeffs(surf_node, x0, y0, z0, r_sq); } @@ -1081,12 +1180,11 @@ inline void SurfaceZCone::normal(const double xyz[3], double uvw[3]) const axis_aligned_cone_normal<2, 0, 1>(xyz, uvw, z0, x0, y0, r_sq); } -void SurfaceZCone::to_hdf5(hid_t group_id) const +void SurfaceZCone::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "z-cone"); std::array coeffs{{x0, y0, z0, r_sq}}; write_double_1D(group_id, "coefficients", coeffs); - write_bc_to_hdf5(group_id); } //============================================================================== @@ -1106,10 +1204,11 @@ public: double distance(const double xyz[3], const double uvw[3], bool coincident) const; void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5(hid_t group_id) const; + void to_hdf5_inner(hid_t group_id) const; }; SurfaceQuadric::SurfaceQuadric(pugi::xml_node surf_node) + : Surface(surf_node) { read_coeffs(surf_node, A, B, C, D, E, F, G, H, J, K); } @@ -1191,12 +1290,11 @@ SurfaceQuadric::normal(const double xyz[3], double uvw[3]) const uvw[2] = 2.0*C*z + E*y + F*x + J; } -void SurfaceQuadric::to_hdf5(hid_t group_id) const +void SurfaceQuadric::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "quadric"); std::array coeffs{{A, B, C, D, E, F, G, H, J, K}}; write_double_1D(group_id, "coefficients", coeffs); - write_bc_to_hdf5(group_id); } //============================================================================== @@ -1220,51 +1318,42 @@ read_surfaces(pugi::xml_node *node) int i_surf; for (surf_node = node->child("surface"), i_surf = 0; surf_node; surf_node = surf_node.next_sibling("surface"), i_surf++) { - const pugi::char_t *surf_type; - if (surf_node.attribute("type")) { - surf_type = surf_node.attribute("type").value(); - } else if (surf_node.child("type")) { - surf_type = surf_node.child_value("type"); - } else { - std::cout << "ERROR: Found a surface with no type attribute/node" - << std::endl; - //TODO: call fatal_error - } + std::string surf_type = get_node_value(surf_node, "type"); - if (strcmp(surf_type, "x-plane") == 0) { + if (surf_type.compare("x-plane") == 0) { surfaces_c[i_surf] = new SurfaceXPlane(surf_node); - } else if (strcmp(surf_type, "y-plane") == 0) { + } else if (surf_type.compare("y-plane") == 0) { surfaces_c[i_surf] = new SurfaceYPlane(surf_node); - } else if (strcmp(surf_type, "z-plane") == 0) { + } else if (surf_type.compare("z-plane") == 0) { surfaces_c[i_surf] = new SurfaceZPlane(surf_node); - } else if (strcmp(surf_type, "plane") == 0) { + } else if (surf_type.compare("plane") == 0) { surfaces_c[i_surf] = new SurfacePlane(surf_node); - } else if (strcmp(surf_type, "x-cylinder") == 0) { + } else if (surf_type.compare("x-cylinder") == 0) { surfaces_c[i_surf] = new SurfaceXCylinder(surf_node); - } else if (strcmp(surf_type, "y-cylinder") == 0) { + } else if (surf_type.compare("y-cylinder") == 0) { surfaces_c[i_surf] = new SurfaceYCylinder(surf_node); - } else if (strcmp(surf_type, "z-cylinder") == 0) { + } else if (surf_type.compare("z-cylinder") == 0) { surfaces_c[i_surf] = new SurfaceZCylinder(surf_node); - } else if (strcmp(surf_type, "sphere") == 0) { + } else if (surf_type.compare("sphere") == 0) { surfaces_c[i_surf] = new SurfaceSphere(surf_node); - } else if (strcmp(surf_type, "x-cone") == 0) { + } else if (surf_type.compare("x-cone") == 0) { surfaces_c[i_surf] = new SurfaceXCone(surf_node); - } else if (strcmp(surf_type, "y-cone") == 0) { + } else if (surf_type.compare("y-cone") == 0) { surfaces_c[i_surf] = new SurfaceYCone(surf_node); - } else if (strcmp(surf_type, "z-cone") == 0) { + } else if (surf_type.compare("z-cone") == 0) { surfaces_c[i_surf] = new SurfaceZCone(surf_node); - } else if (strcmp(surf_type, "quadric") == 0) { + } else if (surf_type.compare("quadric") == 0) { surfaces_c[i_surf] = new SurfaceQuadric(surf_node); } else { @@ -1272,32 +1361,6 @@ read_surfaces(pugi::xml_node *node) std::cout << surf_type << std::endl; //TODO: call fatal_error } - - const pugi::char_t *surf_bc{""}; - if (surf_node.attribute("boundary")) { - surf_bc = surf_node.attribute("boundary").value(); - } else if (surf_node.child("boundary")) { - surf_bc = surf_node.attribute("boundary").value(); - } - - if (strcmp(surf_bc, "transmission") == 0 - or strcmp(surf_bc, "transmit") == 0 - or strcmp(surf_bc, "") == 0) { - surfaces_c[i_surf]->bc = BC_TRANSMIT; - - } else if (strcmp(surf_bc, "vacuum") == 0) { - surfaces_c[i_surf]->bc = BC_VACUUM; - - } else if (strcmp(surf_bc, "reflective") == 0 - or strcmp(surf_bc, "reflect") == 0 - or strcmp(surf_bc, "reflecting") == 0) { - surfaces_c[i_surf]->bc = BC_REFLECT; - } else if (strcmp(surf_bc, "periodic") == 0) { - surfaces_c[i_surf]->bc = BC_PERIODIC; - } else { - std::cout << "Unknown boundary condition" << std::endl; - //TODO: call fatal_error - } } } } From afe2f619c8dd855e9ff0503e4eb9af944b2fba3d Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Tue, 23 Jan 2018 15:21:21 -0500 Subject: [PATCH 15/74] Improve surface coeff error handling --- src/input_xml.F90 | 7 --- src/surface_header.C | 134 ++++++++++++++++++++++++++++++------------- 2 files changed, 95 insertions(+), 46 deletions(-) diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 462b9708f9..3f22522c2a 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -1068,13 +1068,6 @@ contains ! surface coordinates. n = node_word_count(node_surf, "coeffs") - if (n < coeffs_reqd) then - call fatal_error("Not enough coefficients specified for surface: " & - // trim(to_str(s%id))) - elseif (n > coeffs_reqd) then - call fatal_error("Too many coefficients specified for surface: " & - // trim(to_str(s%id))) - end if allocate(coeffs(n)) call get_node_array(node_surf, "coeffs", coeffs) diff --git a/src/surface_header.C b/src/surface_header.C index 4cfda86efa..565352623a 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -74,55 +74,111 @@ Surface **surfaces_c; // Helper functions for reading the "coeffs" node of an XML surface element //============================================================================== -const char* get_coeff_str(pugi::xml_node surf_node) +int word_count(const std::string &text) { - if (surf_node.attribute("coeffs")) { - return surf_node.attribute("coeffs").value(); - } else if (surf_node.child("coeffs")) { - return surf_node.child_value("coeffs"); - } else { - std::cout << "ERROR: Found a surface with no coefficients" << std::endl; - return nullptr; + bool in_word = false; + int count{0}; + for (auto c = text.begin(); c != text.end(); c++) { + switch(*c) { + case ' ' : + case '\t' : + case '\r' : + case '\n' : + if (in_word) { + in_word = false; + count++; + } + break; + default : + in_word = true; + } } + if (in_word) count++; + return count; } -void read_coeffs(pugi::xml_node surf_node, double &c1) +void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1) { - const char *coeffs = get_coeff_str(surf_node); - int stat = sscanf(coeffs, "%lf", &c1); + // Check the given number of coefficients. + std::string coeffs = get_node_value(surf_node, "coeffs"); + int n_words = word_count(coeffs); + if (n_words != 1) { + std::string err_msg{"Surface "}; + err_msg += std::to_string(surf_id); + err_msg += " expects 1 coeff but was given "; + err_msg += std::to_string(n_words); + fatal_error(err_msg); + } + + // Parse the coefficients. + int stat = sscanf(coeffs.c_str(), "%lf", &c1); if (stat != 1) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; + fatal_error("Something went wrong reading surface coeffs"); } } -void read_coeffs(pugi::xml_node surf_node, double &c1, double &c2, double &c3) +void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2, + double &c3) { - const char *coeffs = get_coeff_str(surf_node); - int stat = sscanf(coeffs, "%lf %lf %lf", &c1, &c2, &c3); + // Check the given number of coefficients. + std::string coeffs = get_node_value(surf_node, "coeffs"); + int n_words = word_count(coeffs); + if (n_words != 3) { + std::string err_msg{"Surface "}; + err_msg += std::to_string(surf_id); + err_msg += " expects 3 coeffs but was given "; + err_msg += std::to_string(n_words); + fatal_error(err_msg); + } + + // Parse the coefficients. + int stat = sscanf(coeffs.c_str(), "%lf %lf %lf", &c1, &c2, &c3); if (stat != 3) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; + fatal_error("Something went wrong reading surface coeffs"); } } -void read_coeffs(pugi::xml_node surf_node, double &c1, double &c2, double &c3, - double &c4) +void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2, + double &c3, double &c4) { - const char *coeffs = get_coeff_str(surf_node); - int stat = sscanf(coeffs, "%lf %lf %lf %lf", &c1, &c2, &c3, &c4); + // Check the given number of coefficients. + std::string coeffs = get_node_value(surf_node, "coeffs"); + int n_words = word_count(coeffs); + if (n_words != 4) { + std::string err_msg{"Surface "}; + err_msg += std::to_string(surf_id); + err_msg += " expects 4 coeffs but was given "; + err_msg += std::to_string(n_words); + fatal_error(err_msg); + } + + // Parse the coefficients. + int stat = sscanf(coeffs.c_str(), "%lf %lf %lf %lf", &c1, &c2, &c3, &c4); if (stat != 4) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; + fatal_error("Something went wrong reading surface coeffs"); } } -void read_coeffs(pugi::xml_node surf_node, double &c1, double &c2, double &c3, - double &c4, double &c5, double &c6, double &c7, double &c8, - double &c9, double &c10) +void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2, + double &c3, double &c4, double &c5, double &c6, double &c7, + double &c8, double &c9, double &c10) { - const char *coeffs = get_coeff_str(surf_node); - int stat = sscanf(coeffs, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", + // Check the given number of coefficients. + std::string coeffs = get_node_value(surf_node, "coeffs"); + int n_words = word_count(coeffs); + if (n_words != 10) { + std::string err_msg{"Surface "}; + err_msg += std::to_string(surf_id); + err_msg += " expects 10 coeffs but was given "; + err_msg += std::to_string(n_words); + fatal_error(err_msg); + } + + // Parse the coefficients. + int stat = sscanf(coeffs.c_str(), "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", &c1, &c2, &c3, &c4, &c5, &c6, &c7, &c8, &c9, &c10); if (stat != 10) { - std::cout << "Something went wrong reading surface coeffs!" << std::endl; + fatal_error("Something went wrong reading surface coeffs"); } } @@ -377,7 +433,7 @@ public: SurfaceXPlane::SurfaceXPlane(pugi::xml_node surf_node) : PeriodicSurface(surf_node) { - read_coeffs(surf_node, x0); + read_coeffs(surf_node, id, x0); } inline double SurfaceXPlane::evaluate(const double xyz[3]) const @@ -453,7 +509,7 @@ public: SurfaceYPlane::SurfaceYPlane(pugi::xml_node surf_node) : PeriodicSurface(surf_node) { - read_coeffs(surf_node, y0); + read_coeffs(surf_node, id, y0); } inline double SurfaceYPlane::evaluate(const double xyz[3]) const @@ -529,7 +585,7 @@ public: SurfaceZPlane::SurfaceZPlane(pugi::xml_node surf_node) : PeriodicSurface(surf_node) { - read_coeffs(surf_node, z0); + read_coeffs(surf_node, id, z0); } inline double SurfaceZPlane::evaluate(const double xyz[3]) const @@ -587,7 +643,7 @@ public: SurfacePlane::SurfacePlane(pugi::xml_node surf_node) : PeriodicSurface(surf_node) { - read_coeffs(surf_node, A, B, C, D); + read_coeffs(surf_node, id, A, B, C, D); } double @@ -739,7 +795,7 @@ public: SurfaceXCylinder::SurfaceXCylinder(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, y0, z0, r); + read_coeffs(surf_node, id, y0, z0, r); } inline double SurfaceXCylinder::evaluate(const double xyz[3]) const @@ -790,7 +846,7 @@ public: SurfaceYCylinder::SurfaceYCylinder(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, x0, z0, r); + read_coeffs(surf_node, id, x0, z0, r); } inline double SurfaceYCylinder::evaluate(const double xyz[3]) const @@ -840,7 +896,7 @@ public: SurfaceZCylinder::SurfaceZCylinder(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, x0, y0, r); + read_coeffs(surf_node, id, x0, y0, r); } inline double SurfaceZCylinder::evaluate(const double xyz[3]) const @@ -890,7 +946,7 @@ public: SurfaceSphere::SurfaceSphere(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, x0, y0, z0, r); + read_coeffs(surf_node, id, x0, y0, z0, r); } double SurfaceSphere::evaluate(const double xyz[3]) const @@ -1060,7 +1116,7 @@ public: SurfaceXCone::SurfaceXCone(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, x0, y0, z0, r_sq); + read_coeffs(surf_node, id, x0, y0, z0, r_sq); } inline double SurfaceXCone::evaluate(const double xyz[3]) const @@ -1110,7 +1166,7 @@ public: SurfaceYCone::SurfaceYCone(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, x0, y0, z0, r_sq); + read_coeffs(surf_node, id, x0, y0, z0, r_sq); } inline double SurfaceYCone::evaluate(const double xyz[3]) const @@ -1160,7 +1216,7 @@ public: SurfaceZCone::SurfaceZCone(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, x0, y0, z0, r_sq); + read_coeffs(surf_node, id, x0, y0, z0, r_sq); } inline double SurfaceZCone::evaluate(const double xyz[3]) const @@ -1210,7 +1266,7 @@ public: SurfaceQuadric::SurfaceQuadric(pugi::xml_node surf_node) : Surface(surf_node) { - read_coeffs(surf_node, A, B, C, D, E, F, G, H, J, K); + read_coeffs(surf_node, id, A, B, C, D, E, F, G, H, J, K); } double From 164e6c0ef4c7732a6245da2597fb6ff229deefe5 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Tue, 23 Jan 2018 18:29:05 -0500 Subject: [PATCH 16/74] Move more Surface implementation to C++ --- src/geometry.F90 | 20 ++- src/input_xml.F90 | 168 +--------------------- src/output.F90 | 2 +- src/summary.F90 | 5 +- src/surface_header.C | 201 +++++++++++++++++++++++++-- src/surface_header.F90 | 55 +------- src/tallies/tally_filter_surface.F90 | 2 +- src/tracking.F90 | 12 +- 8 files changed, 217 insertions(+), 248 deletions(-) diff --git a/src/geometry.F90 b/src/geometry.F90 index f1feb3ba30..d1519f8d21 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -54,16 +54,24 @@ module geometry real(C_DOUBLE), intent(out) :: uvw(3); end subroutine surface_normal_c - function surface_periodic_c(surf_ind1, surf_ind2, xyz, uvw) & + function surface_periodic_c(surf_ind1, xyz, uvw) & bind(C, name="surface_periodic") result(rotational) use ISO_C_BINDING implicit none integer(C_INT), intent(in), value :: surf_ind1; - integer(C_INT), intent(in), value :: surf_ind2; real(C_DOUBLE), intent(inout) :: xyz(3); real(C_DOUBLE), intent(inout) :: uvw(3); logical(C_BOOL) :: rotational end function surface_periodic_c + + function surface_i_periodic_c(surf_ind) bind(C, name="surface_i_periodic") & + result(i_periodic) + use ISO_C_BINDING + implicit none + integer(C_INT), intent(in), value :: surf_ind + integer(C_INT) :: i_periodic + end function + end interface contains @@ -857,15 +865,15 @@ contains ! Copy positive neighbors to Surface instance n = neighbor_pos(i)%size() if (n > 0) then - allocate(surfaces(i)%obj%neighbor_pos(n)) - surfaces(i)%obj%neighbor_pos(:) = neighbor_pos(i)%data(1:n) + allocate(surfaces(i)%neighbor_pos(n)) + surfaces(i)%neighbor_pos(:) = neighbor_pos(i)%data(1:n) end if ! Copy negative neighbors to Surface instance n = neighbor_neg(i)%size() if (n > 0) then - allocate(surfaces(i)%obj%neighbor_neg(n)) - surfaces(i)%obj%neighbor_neg(:) = neighbor_neg(i)%data(1:n) + allocate(surfaces(i)%neighbor_neg(n)) + surfaces(i)%neighbor_neg(:) = neighbor_neg(i)%data(1:n) end if end do diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 3f22522c2a..9b6e1c6fce 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -919,12 +919,8 @@ contains integer :: id integer :: univ_id integer :: n_cells_in_univ - integer :: coeffs_reqd - integer :: i_xmin, i_xmax, i_ymin, i_ymax, i_zmin, i_zmax - real(8) :: xmin, xmax, ymin, ymax, zmin, zmax integer, allocatable :: temp_int_array(:) real(8) :: phi, theta, psi - real(8), allocatable :: coeffs(:) logical :: file_exists logical :: boundary_exists character(MAX_LINE_LEN) :: filename @@ -984,13 +980,6 @@ contains call fatal_error("No surfaces found in geometry.xml!") end if - xmin = INFINITY - xmax = -INFINITY - ymin = INFINITY - ymax = -INFINITY - zmin = INFINITY - zmax = -INFINITY - ! Allocate cells array allocate(surfaces(n_surfaces)) @@ -998,52 +987,7 @@ contains ! Get pointer to i-th surface node node_surf = node_surf_list(i) - ! Copy and interpret surface type - word = '' - if (check_for_node(node_surf, "type")) & - call get_node_value(node_surf, "type", word) - select case(to_lower(word)) - case ('x-plane') - coeffs_reqd = 1 - allocate(SurfaceXPlane :: surfaces(i)%obj) - case ('y-plane') - coeffs_reqd = 1 - allocate(SurfaceYPlane :: surfaces(i)%obj) - case ('z-plane') - coeffs_reqd = 1 - allocate(SurfaceZPlane :: surfaces(i)%obj) - case ('plane') - coeffs_reqd = 4 - allocate(SurfacePlane :: surfaces(i)%obj) - case ('x-cylinder') - coeffs_reqd = 3 - allocate(SurfaceXCylinder :: surfaces(i)%obj) - case ('y-cylinder') - coeffs_reqd = 3 - allocate(SurfaceYCylinder :: surfaces(i)%obj) - case ('z-cylinder') - coeffs_reqd = 3 - allocate(SurfaceZCylinder :: surfaces(i)%obj) - case ('sphere') - coeffs_reqd = 4 - allocate(SurfaceSphere :: surfaces(i)%obj) - case ('x-cone') - coeffs_reqd = 4 - allocate(SurfaceXCone :: surfaces(i)%obj) - case ('y-cone') - coeffs_reqd = 4 - allocate(SurfaceYCone :: surfaces(i)%obj) - case ('z-cone') - coeffs_reqd = 4 - allocate(SurfaceZCone :: surfaces(i)%obj) - case ('quadric') - coeffs_reqd = 10 - allocate(SurfaceQuadric :: surfaces(i)%obj) - case default - call fatal_error("Invalid surface type: " // trim(word)) - end select - - s => surfaces(i)%obj + s => surfaces(i) ! Copy data into cells if (check_for_node(node_surf, "id")) then @@ -1058,44 +1002,10 @@ contains // to_str(s%id)) end if - ! Copy surface name - if (check_for_node(node_surf, "name")) then - call get_node_value(node_surf, "name", s%name) - end if - ! Check to make sure that the proper number of coefficients ! have been specified for the given type of surface. Then copy ! surface coordinates. - n = node_word_count(node_surf, "coeffs") - - allocate(coeffs(n)) - call get_node_array(node_surf, "coeffs", coeffs) - - select type(s) - type is (SurfaceXPlane) - ! Determine outer surfaces - xmin = min(xmin, coeffs(1)) - xmax = max(xmax, coeffs(1)) - if (xmin == coeffs(1)) i_xmin = i - if (xmax == coeffs(1)) i_xmax = i - type is (SurfaceYPlane) - ! Determine outer surfaces - ymin = min(ymin, coeffs(1)) - ymax = max(ymax, coeffs(1)) - if (ymin == coeffs(1)) i_ymin = i - if (ymax == coeffs(1)) i_ymax = i - type is (SurfaceZPlane) - ! Determine outer surfaces - zmin = min(zmin, coeffs(1)) - zmax = max(zmax, coeffs(1)) - if (zmin == coeffs(1)) i_zmin = i - if (zmax == coeffs(1)) i_zmax = i - end select - - ! No longer need coefficients - deallocate(coeffs) - ! Boundary conditions word = '' if (check_for_node(node_surf, "boundary")) & @@ -1112,12 +1022,6 @@ contains case ('periodic') s%bc = BC_PERIODIC boundary_exists = .true. - - ! Check for specification of periodic surface - if (check_for_node(node_surf, "periodic_surface_id")) then - call get_node_value(node_surf, "periodic_surface_id", & - s % i_periodic) - end if case default call fatal_error("Unknown boundary condition '" // trim(word) // & &"' specified on surface " // trim(to_str(s%id))) @@ -1134,76 +1038,6 @@ contains end if end if - ! Determine opposite side for periodic boundaries - do i = 1, size(surfaces) - if (surfaces(i) % obj % bc == BC_PERIODIC) then - select type (surf => surfaces(i) % obj) - type is (SurfaceXPlane) - if (surf % i_periodic == NONE) then - if (i == i_xmin) then - surf % i_periodic = i_xmax - elseif (i == i_xmax) then - surf % i_periodic = i_xmin - else - call fatal_error("Periodic boundary condition applied to & - &interior surface.") - end if - else - surf % i_periodic = surface_dict % get(surf % i_periodic) - end if - - type is (SurfaceYPlane) - if (surf % i_periodic == NONE) then - if (i == i_ymin) then - surf % i_periodic = i_ymax - elseif (i == i_ymax) then - surf % i_periodic = i_ymin - else - call fatal_error("Periodic boundary condition applied to & - &interior surface.") - end if - else - surf % i_periodic = surface_dict % get(surf % i_periodic) - end if - - type is (SurfaceZPlane) - if (surf % i_periodic == NONE) then - if (i == i_zmin) then - surf % i_periodic = i_zmax - elseif (i == i_zmax) then - surf % i_periodic = i_zmin - else - call fatal_error("Periodic boundary condition applied to & - &interior surface.") - end if - else - surf % i_periodic = surface_dict % get(surf % i_periodic) - end if - - type is (SurfacePlane) - if (surf % i_periodic == NONE) then - call fatal_error("No matching periodic surface specified for & - &periodic boundary condition on surface " // & - trim(to_str(surf % id)) // ".") - else - surf % i_periodic = surface_dict % get(surf % i_periodic) - end if - - class default - call fatal_error("Periodic boundary condition applied to & - &non-planar surface.") - end select - - ! Make sure opposite surface is also periodic - associate (surf => surfaces(i) % obj) - if (surfaces(surf % i_periodic) % obj % bc /= BC_PERIODIC) then - call fatal_error("Could not find matching surface for periodic & - &boundary on surface " // trim(to_str(surf % id)) // ".") - end if - end associate - end if - end do - ! ========================================================================== ! READ CELLS FROM GEOMETRY.XML diff --git a/src/output.F90 b/src/output.F90 index 1b7cae121e..4113eea472 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -259,7 +259,7 @@ contains ! Print surface if (p % surface /= NONE) then - write(ou,*) ' Surface = ' // to_str(sign(surfaces(i)%obj%id, p % surface)) + write(ou,*) ' Surface = ' // to_str(sign(surfaces(i)%id, p % surface)) end if ! Display weight, energy, grid index, and interpolation factor diff --git a/src/summary.F90 b/src/summary.F90 index 77bded9837..9b82a03967 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -133,12 +133,11 @@ contains real(8), allocatable :: cell_temperatures(:) integer(HID_T) :: geom_group integer(HID_T) :: cells_group, cell_group - integer(HID_T) :: surfaces_group, surface_group + integer(HID_T) :: surfaces_group integer(HID_T) :: universes_group, univ_group integer(HID_T) :: lattices_group, lattice_group character(:), allocatable :: region_spec type(Cell), pointer :: c - class(Surface), pointer :: s class(Lattice), pointer :: lat ! Use H5LT interface to write number of geometry objects @@ -233,7 +232,7 @@ contains region_spec = trim(region_spec) // " |" case default region_spec = trim(region_spec) // " " // to_str(& - sign(surfaces(abs(k))%obj%id, k)) + sign(surfaces(abs(k))%id, k)) end select end do call write_dataset(cell_group, "region", adjustl(region_spec)) diff --git a/src/surface_header.C b/src/surface_header.C index 565352623a..afea2b43d3 100644 --- a/src/surface_header.C +++ b/src/surface_header.C @@ -1,7 +1,8 @@ #include // for std::transform -#include // For std::array +#include #include // For strcmp #include // For numeric_limits +#include #include // For fabs #include "pugixml/pugixml.hpp" @@ -45,6 +46,7 @@ get_node_value(const pugi::xml_node &node, const char *name) std::string value(value_char); std::transform(value.begin(), value.end(), value.begin(), ::tolower); + //TODO: trim whitespace return value; } @@ -57,6 +59,7 @@ get_node_value(const pugi::xml_node &node, const char *name) extern "C" double FP_COINCIDENT; //extern "C" double INFTY; const double INFTY{std::numeric_limits::max()}; +const int C_NONE{-1}; extern "C" const int BC_TRANSMIT{0}; extern "C" const int BC_VACUUM{1}; @@ -70,6 +73,8 @@ extern "C" const int BC_PERIODIC{3}; class Surface; Surface **surfaces_c; +std::map surface_dict; + //============================================================================== // Helper functions for reading the "coeffs" node of an XML surface element //============================================================================== @@ -182,6 +187,19 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2, } } +//============================================================================== +//============================================================================== + +struct BoundingBox +{ + double xmin; + double xmax; + double ymin; + double ymax; + double zmin; + double zmax; +}; + //============================================================================== //! A geometry primitive used to define regions of 3D space. //============================================================================== @@ -193,8 +211,6 @@ public: //int neighbor_pos[], //!< List of cells on positive side // neighbor_neg[]; //!< List of cells on negative side int bc; //!< Boundary condition - //TODO: switch that zero to a NONE constant. - //int i_periodic = 0; //!< Index of corresponding periodic surface std::string name{""}; //!< User-defined name Surface(pugi::xml_node surf_node); @@ -249,7 +265,6 @@ Surface::Surface(pugi::xml_node surf_node) } else { fatal_error("Must specify id of surface in geometry XML file."); } - //TODO: check for duplicate IDs if (check_for_node(surf_node, "name")) { name = get_node_value(surf_node, "name"); @@ -362,7 +377,9 @@ Surface::to_hdf5(hid_t group_id) const class PeriodicSurface : public Surface { public: - PeriodicSurface(pugi::xml_node surf_node) : Surface(surf_node) {} + int i_periodic{C_NONE}; //!< Index of corresponding periodic surface + + PeriodicSurface(pugi::xml_node surf_node); //! Translate a particle onto this surface from a periodic partner surface. //! @param other A pointer to the partner surface in this periodic BC. @@ -374,8 +391,18 @@ public: //! boundary condition. virtual bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const = 0; + + virtual struct BoundingBox bounding_box() const = 0; }; +PeriodicSurface::PeriodicSurface(pugi::xml_node surf_node) + : Surface(surf_node) +{ + if (check_for_node(surf_node, "periodic_surface_id")) { + i_periodic = stoi(get_node_value(surf_node, "periodic_surface_id")); + } +} + //============================================================================== // Generic functions for x-, y-, and z-, planes. //============================================================================== @@ -428,6 +455,7 @@ public: void to_hdf5_inner(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; + struct BoundingBox bounding_box() const; }; SurfaceXPlane::SurfaceXPlane(pugi::xml_node surf_node) @@ -485,6 +513,13 @@ bool SurfaceXPlane::periodic_translate(PeriodicSurface *other, double xyz[3], } } +struct BoundingBox +SurfaceXPlane::bounding_box() const +{ + struct BoundingBox out{x0, x0, -INFTY, INFTY, -INFTY, INFTY}; + return out; +} + //============================================================================== // SurfaceYPlane //! A plane perpendicular to the y-axis. @@ -504,6 +539,7 @@ public: void to_hdf5_inner(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; + struct BoundingBox bounding_box() const; }; SurfaceYPlane::SurfaceYPlane(pugi::xml_node surf_node) @@ -561,6 +597,13 @@ bool SurfaceYPlane::periodic_translate(PeriodicSurface *other, double xyz[3], } } +struct BoundingBox +SurfaceYPlane::bounding_box() const +{ + struct BoundingBox out{-INFTY, INFTY, y0, y0, -INFTY, INFTY}; + return out; +} + //============================================================================== // SurfaceZPlane //! A plane perpendicular to the z-axis. @@ -580,6 +623,7 @@ public: void to_hdf5_inner(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; + struct BoundingBox bounding_box() const; }; SurfaceZPlane::SurfaceZPlane(pugi::xml_node surf_node) @@ -619,6 +663,13 @@ bool SurfaceZPlane::periodic_translate(PeriodicSurface *other, double xyz[3], return false; } +struct BoundingBox +SurfaceZPlane::bounding_box() const +{ + struct BoundingBox out{-INFTY, INFTY, -INFTY, INFTY, z0, z0}; + return out; +} + //============================================================================== // SurfacePlane //! A general plane. @@ -638,6 +689,7 @@ public: void to_hdf5_inner(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; + struct BoundingBox bounding_box() const; }; SurfacePlane::SurfacePlane(pugi::xml_node surf_node) @@ -698,6 +750,13 @@ bool SurfacePlane::periodic_translate(PeriodicSurface *other, double xyz[3], return false; } +struct BoundingBox +SurfacePlane::bounding_box() const +{ + struct BoundingBox out{-INFTY, INFTY, -INFTY, INFTY, -INFTY, INFTY}; + return out; +} + //============================================================================== // Generic functions for x-, y-, and z-, cylinders //============================================================================== @@ -1359,10 +1418,10 @@ extern "C" void read_surfaces(pugi::xml_node *node) { // Count the number of surfaces. - int n_surfaces = 0; + int n_surfaces{0}; for (pugi::xml_node surf_node = node->child("surface"); surf_node; surf_node = surf_node.next_sibling("surface")) { - n_surfaces += 1; + n_surfaces++; } // Allocate the array of Surface pointers. @@ -1413,12 +1472,125 @@ read_surfaces(pugi::xml_node *node) surfaces_c[i_surf] = new SurfaceQuadric(surf_node); } else { - std::cout << "Call error or handle uppercase here!" << std::endl; + std::cout << "Call error here!" << std::endl; std::cout << surf_type << std::endl; //TODO: call fatal_error } } } + + // Fill the surface dictionary. + for (int i_surf = 0; i_surf < n_surfaces; i_surf++) { + int id = surfaces_c[i_surf]->id; + auto in_dict = surface_dict.find(id); + if (in_dict == surface_dict.end()) { + surface_dict[id] = i_surf; + } else { + std::string err_msg{"Two or more surfaces use the same unique ID: "}; + err_msg += std::to_string(id); + fatal_error(err_msg); + } + } + + // Find the global bounding box (of periodic BC surfaces). + double xmin{INFTY}, xmax{-INFTY}, ymin{INFTY}, ymax{-INFTY}, + zmin{INFTY}, zmax{-INFTY}; + int i_xmin, i_xmax, i_ymin, i_ymax, i_zmin, i_zmax; + for (int i_surf = 0; i_surf < n_surfaces; i_surf++) { + if (surfaces_c[i_surf]->bc == BC_PERIODIC) { + // Downcast to the PeriodicSurface type. + Surface *surf_base = surfaces_c[i_surf]; + PeriodicSurface *surf = dynamic_cast(surf_base); + //TODO: check for null pointer + + // See if this surface makes part of the global bounding box. + struct BoundingBox bb = surf->bounding_box(); + if (bb.xmin > -INFTY and bb.xmin < xmin) { + xmin = bb.xmin; + i_xmin = i_surf; + } + if (bb.xmax < INFTY and bb.xmax > xmax) { + xmax = bb.xmax; + i_xmax = i_surf; + } + if (bb.ymin > -INFTY and bb.ymin < ymin) { + ymin = bb.ymin; + i_ymin = i_surf; + } + if (bb.ymax < INFTY and bb.ymax > ymax) { + ymax = bb.ymax; + i_ymax = i_surf; + } + if (bb.zmin > -INFTY and bb.zmin < zmin) { + zmin = bb.zmin; + i_zmin = i_surf; + } + if (bb.zmax < INFTY and bb.zmax > zmax) { + zmax = bb.zmax; + i_zmax = i_surf; + } + } + } + + // Set i_periodic for periodic BC surfaces. + for (int i_surf = 0; i_surf < n_surfaces; i_surf++) { + if (surfaces_c[i_surf]->bc == BC_PERIODIC) { + // Downcast to the PeriodicSurface type. + Surface *surf_base = surfaces_c[i_surf]; + PeriodicSurface *surf = dynamic_cast(surf_base); + + // Also try downcasting to the SurfacePlane type (which must be handled + // differently). + SurfacePlane *surf_p = dynamic_cast(surf); + + if (surf_p == NULL) { + // This is not a SurfacePlane. + if (surf->i_periodic == C_NONE) { + // The user did not specify the matching periodic surface. See if we + // can find the partnered surface from the bounding box information. + if (i_surf == i_xmin) { + surf->i_periodic = i_xmax; + } else if (i_surf == i_xmax) { + surf->i_periodic = i_xmin; + } else if (i_surf == i_ymin) { + surf->i_periodic = i_ymax; + } else if (i_surf == i_ymax) { + surf->i_periodic = i_ymin; + } else if (i_surf == i_zmin) { + surf->i_periodic = i_zmax; + } else if (i_surf == i_zmax) { + surf->i_periodic = i_zmin; + } else { + fatal_error("Periodic boundary condition applied to interior " + "surface"); + } + } else { + // Convert the surface id to an index. + surf->i_periodic = surface_dict[surf->i_periodic]; + } + } else { + // This is a SurfacePlane. We won't try to find it's partner if the + // user didn't specify one. + if (surf->i_periodic == C_NONE) { + std::string err_msg{"No matching periodic surface specified for " + "periodic boundary condition on surface "}; + err_msg += std::to_string(surf->id); + fatal_error(err_msg); + } else { + // Convert the surface id to an index. + surf->i_periodic = surface_dict[surf->i_periodic]; + } + } + + // Make sure the opposite surface is also periodic. + if (surfaces_c[surf->i_periodic]->bc != BC_PERIODIC) { + std::string err_msg{"Could not find matching surface for periodic " + "boundary condition on surface "}; + err_msg += std::to_string(surf->id); + fatal_error(err_msg); + } + } + } } //============================================================================== @@ -1454,17 +1626,24 @@ surface_to_hdf5(int surf_ind, hid_t group) } extern "C" bool -surface_periodic(int surf_ind1, int surf_ind2, double xyz[3], double uvw[3]) +surface_periodic(int surf_ind1, double xyz[3], double uvw[3]) { - // Hopefully this function has only been called on a pair of surfaces that + // Hopefully this function has only been called for a pair of surfaces that // support periodic BCs (checking should have been done when reading the // geometry XML). Downcast the surfaces to the PeriodicSurface type so we // can call the periodic_translate method. Surface *surf1_gen = surfaces_c[surf_ind1]; PeriodicSurface *surf1 = dynamic_cast(surf1_gen); - Surface *surf2_gen = surfaces_c[surf_ind2]; + Surface *surf2_gen = surfaces_c[surf1->i_periodic]; PeriodicSurface *surf2 = dynamic_cast(surf2_gen); // Call the type-bound methods. return surf2->periodic_translate(surf1, xyz, uvw); } + +extern "C" int +surface_i_periodic(int surf_ind) +{ + PeriodicSurface *surf = dynamic_cast(surfaces_c[surf_ind]); + return surf->i_periodic; +} diff --git a/src/surface_header.F90 b/src/surface_header.F90 index 98e2423b62..ffe0a6db41 100644 --- a/src/surface_header.F90 +++ b/src/surface_header.F90 @@ -12,68 +12,17 @@ module surface_header ! construct closed volumes (cells) !=============================================================================== - type, abstract :: Surface + type :: Surface integer :: id ! Unique ID integer, allocatable :: & neighbor_pos(:), & ! List of cells on positive side neighbor_neg(:) ! List of cells on negative side integer :: bc ! Boundary condition - integer :: i_periodic = NONE ! Index of corresponding periodic surface - character(len=104) :: name = "" ! User-defined name end type Surface -!=============================================================================== -! SURFACECONTAINER allows us to store an array of different types of surfaces -!=============================================================================== - - type :: SurfaceContainer - class(Surface), allocatable :: obj - end type SurfaceContainer - -!=============================================================================== -! All the derived types below are extensions of the abstract Surface type. They -! inherent the reflect() type-bound procedure and must implement normal() -!=============================================================================== - - type, extends(Surface) :: SurfaceXPlane - end type SurfaceXPlane - - type, extends(Surface) :: SurfaceYPlane - end type SurfaceYPlane - - type, extends(Surface) :: SurfaceZPlane - end type SurfaceZPlane - - type, extends(Surface) :: SurfacePlane - end type SurfacePlane - - type, extends(Surface) :: SurfaceXCylinder - end type SurfaceXCylinder - - type, extends(Surface) :: SurfaceYCylinder - end type SurfaceYCylinder - - type, extends(Surface) :: SurfaceZCylinder - end type SurfaceZCylinder - - type, extends(Surface) :: SurfaceSphere - end type SurfaceSphere - - type, extends(Surface) :: SurfaceXCone - end type SurfaceXCone - - type, extends(Surface) :: SurfaceYCone - end type SurfaceYCone - - type, extends(Surface) :: SurfaceZCone - end type SurfaceZCone - - type, extends(Surface) :: SurfaceQuadric - end type SurfaceQuadric - integer(C_INT32_T), bind(C) :: n_surfaces ! # of surfaces - type(SurfaceContainer), allocatable, target :: surfaces(:) + type(Surface), allocatable, target :: surfaces(:) ! Dictionary that maps user IDs to indices in 'surfaces' type(DictIntInt) :: surface_dict diff --git a/src/tallies/tally_filter_surface.F90 b/src/tallies/tally_filter_surface.F90 index daecd88917..6a2afa3ec6 100644 --- a/src/tallies/tally_filter_surface.F90 +++ b/src/tallies/tally_filter_surface.F90 @@ -105,7 +105,7 @@ contains integer, intent(in) :: bin character(MAX_LINE_LEN) :: label - label = "Surface " // to_str(surfaces(this % surfaces(bin)) % obj % id) + label = "Surface " // to_str(surfaces(this % surfaces(bin)) % id) end function text_label_surface end module tally_filter_surface diff --git a/src/tracking.F90 b/src/tracking.F90 index d616212ec6..98bca2a279 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -6,7 +6,7 @@ module tracking use geometry_header, only: cells use geometry, only: find_cell, distance_to_boundary, cross_lattice, & check_cell_overlap, surface_reflect_c, & - surface_periodic_c + surface_periodic_c, surface_i_periodic_c use message_passing use mgxs_header use nuclide_header @@ -298,7 +298,7 @@ contains class(Surface), pointer :: surf i_surface = abs(p % surface) - surf => surfaces(i_surface)%obj + surf => surfaces(i_surface) if (verbosity >= 10 .or. trace) then call write_message(" Crossing surface " // trim(to_str(surf % id))) end if @@ -412,14 +412,14 @@ contains p % coord(1) % xyz = xyz end if - rotational = surface_periodic_c(i_surface-1, surf % i_periodic-1, & - p % coord(1) % xyz, p % coord(1) % uvw) + rotational = surface_periodic_c(i_surface-1, p % coord(1) % xyz, & + p % coord(1) % uvw) ! Reassign particle's surface if (rotational) then - p % surface = surf % i_periodic + p % surface = surface_i_periodic_c(i_surface-1) + 1 else - p % surface = sign(surf % i_periodic, p % surface) + p % surface = sign(surface_i_periodic_c(i_surface-1) + 1, p % surface) end if ! Figure out what cell particle is in now From 983cbd48c65df2eb5578dd52d423caed915c26c2 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Tue, 23 Jan 2018 22:26:48 -0500 Subject: [PATCH 17/74] Clean up C++ surface file structure --- CMakeLists.txt | 10 +- src/error.h | 1 + src/{surface_header.C => surface.cpp} | 473 ++------------------------ src/surface.h | 431 +++++++++++++++++++++++ src/xml_interface.h | 52 +++ 5 files changed, 517 insertions(+), 450 deletions(-) rename src/{surface_header.C => surface.cpp} (72%) create mode 100644 src/surface.h create mode 100644 src/xml_interface.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e59713755f..625f001362 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -437,11 +437,13 @@ set(LIBOPENMC_FORTRAN_SRC set(LIBOPENMC_CXX_SRC src/error.h src/hdf5_interface.h - src/random_lcg.h src/random_lcg.cpp - src/surface_header.C - src/pugixml/pugixml.hpp - src/pugixml/pugixml.cpp) + src/random_lcg.h + src/surface.cpp + src/surface.h + src/xml_interface.h + src/pugixml/pugixml.cpp + src/pugixml/pugixml.hpp) add_library(libopenmc SHARED ${LIBOPENMC_FORTRAN_SRC} ${LIBOPENMC_CXX_SRC}) set_target_properties(libopenmc PROPERTIES OUTPUT_NAME openmc) add_executable(${program} src/main.F90) diff --git a/src/error.h b/src/error.h index 77f0252e13..0fd78a6c5c 100644 --- a/src/error.h +++ b/src/error.h @@ -1,6 +1,7 @@ #ifndef ERROR_H #define ERROR_H +#include #include diff --git a/src/surface_header.C b/src/surface.cpp similarity index 72% rename from src/surface_header.C rename to src/surface.cpp index afea2b43d3..ed111b0370 100644 --- a/src/surface_header.C +++ b/src/surface.cpp @@ -1,79 +1,11 @@ -#include // for std::transform #include -#include // For strcmp -#include // For numeric_limits -#include #include // For fabs -#include "pugixml/pugixml.hpp" -#include "hdf5.h" - #include "error.h" #include "hdf5_interface.h" +#include "xml_interface.h" -// DEBUGGING -#include -#include - -bool -check_for_node(const pugi::xml_node &node, const char *name) -{ - if (node.attribute(name)) { - return true; - } else if (node.child(name)) { - return true; - } else { - return false; - } -} - -std::string -get_node_value(const pugi::xml_node &node, const char *name) -{ - const pugi::char_t *value_char; - if (node.attribute(name)) { - value_char = node.attribute(name).value(); - } else if (node.child(name)) { - value_char = node.child_value(name); - } else { - std::string err_msg("Node \""); - err_msg += name; - err_msg += "\" is not a memeber of the \""; - err_msg += node.name(); - err_msg += "\" XML node"; - fatal_error(err_msg); - } - - std::string value(value_char); - std::transform(value.begin(), value.end(), value.begin(), ::tolower); - //TODO: trim whitespace - return value; -} - -//============================================================================== -// Constants -//============================================================================== - -//extern "C" const double FP_COINCIDENT{1e-12}; -//extern "C" const double INFTY{std::numeric_limits::max()}; -extern "C" double FP_COINCIDENT; -//extern "C" double INFTY; -const double INFTY{std::numeric_limits::max()}; -const int C_NONE{-1}; - -extern "C" const int BC_TRANSMIT{0}; -extern "C" const int BC_VACUUM{1}; -extern "C" const int BC_REFLECT{2}; -extern "C" const int BC_PERIODIC{3}; - -//============================================================================== -// Global array of surfaces -//============================================================================== - -class Surface; -Surface **surfaces_c; - -std::map surface_dict; +#include "surface.h" //============================================================================== // Helper functions for reading the "coeffs" node of an XML surface element @@ -84,18 +16,13 @@ int word_count(const std::string &text) bool in_word = false; int count{0}; for (auto c = text.begin(); c != text.end(); c++) { - switch(*c) { - case ' ' : - case '\t' : - case '\r' : - case '\n' : - if (in_word) { - in_word = false; - count++; - } - break; - default : - in_word = true; + if (std::isspace(*c)) { + if (in_word) { + in_word = false; + count++; + } + } else { + in_word = true; } } if (in_word) count++; @@ -188,76 +115,9 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2, } //============================================================================== +// Surface implementation //============================================================================== -struct BoundingBox -{ - double xmin; - double xmax; - double ymin; - double ymax; - double zmin; - double zmax; -}; - -//============================================================================== -//! A geometry primitive used to define regions of 3D space. -//============================================================================== - -class Surface -{ -public: - int id; //!< Unique ID - //int neighbor_pos[], //!< List of cells on positive side - // neighbor_neg[]; //!< List of cells on negative side - int bc; //!< Boundary condition - std::string name{""}; //!< User-defined name - - Surface(pugi::xml_node surf_node); - - //! Determine which side of a surface a point lies on. - //! @param xyz[3] The 3D Cartesian coordinate of a point. - //! @param uvw[3] A direction used to "break ties" and pick a sense when the - //! point is very close to the surface. - //! @return true if the point is on the "positive" side of the surface and - //! false otherwise. - bool sense(const double xyz[3], const double uvw[3]) const; - - //! Determine the direction of a ray reflected from the surface. - //! @param xyz[3] The point at which the ray is incident. - //! @param uvw[3] A direction. This is both an input and an output parameter. - //! It specifies the icident direction on input and the reflected direction - //! on output. - void reflect(const double xyz[3], double uvw[3]) const; - - //! Evaluate the equation describing the surface. - //! - //! Surfaces can be described by some function f(x, y, z) = 0. This member - //! function evaluates that mathematical function. - //! @param xyz[3] A 3D Cartesian coordinate. - virtual double evaluate(const double xyz[3]) const = 0; - - //! Compute the distance between a point and the surface along a ray. - //! @param xyz[3] A 3D Cartesian coordinate. - //! @param uvw[3] The direction of the ray. - //! @param coincident A hint to the code that the given point should lie - //! exactly on the surface. - virtual double distance(const double xyz[3], const double uvw[3], - bool coincident) const = 0; - - //! Compute the local outward normal direction of the surface. - //! @param xyz[3] A 3D Cartesian coordinate. - //! @param uvw[3] This output argument provides the normal. - virtual void normal(const double xyz[3], double uvw[3]) const = 0; - - //! Write all information needed to reconstruct the surface to an HDF5 group. - //! @param group_id An HDF5 group id. - void to_hdf5(hid_t group_id) const; - -protected: - virtual void to_hdf5_inner(hid_t group_id) const = 0; -}; - Surface::Surface(pugi::xml_node surf_node) { if (check_for_node(surf_node, "id")) { @@ -367,34 +227,9 @@ Surface::to_hdf5(hid_t group_id) const } //============================================================================== -//! A `Surface` that supports periodic boundary conditions. -//! -//! Translational periodicity is supported for the `XPlane`, `YPlane`, `ZPlane`, -//! and `Plane` types. Rotational periodicity is supported for -//! `XPlane`-`YPlane` pairs. +// PeriodicSurface implementation //============================================================================== -class PeriodicSurface : public Surface -{ -public: - int i_periodic{C_NONE}; //!< Index of corresponding periodic surface - - PeriodicSurface(pugi::xml_node surf_node); - - //! Translate a particle onto this surface from a periodic partner surface. - //! @param other A pointer to the partner surface in this periodic BC. - //! @param xyz[3] A point on the partner surface that will be translated onto - //! this surface. - //! @param uvw[3] A direction that will be rotated for systems with rotational - //! periodicity. - //! @return true if this surface and its partner make a rotationally-periodic - //! boundary condition. - virtual bool periodic_translate(PeriodicSurface *other, double xyz[3], - double uvw[3]) const = 0; - - virtual struct BoundingBox bounding_box() const = 0; -}; - PeriodicSurface::PeriodicSurface(pugi::xml_node surf_node) : Surface(surf_node) { @@ -437,27 +272,9 @@ axis_aligned_plane_normal(const double xyz[3], double uvw[3]) } //============================================================================== -// SurfaceXPlane -//! A plane perpendicular to the x-axis. -// -//! The plane is described by the equation \f$x - x_0 = 0\f$ +// SurfaceXPlane implementation //============================================================================== -class SurfaceXPlane : public PeriodicSurface -{ - double x0; -public: - SurfaceXPlane(pugi::xml_node surf_node); - double evaluate(const double xyz[3]) const; - double distance(const double xyz[3], const double uvw[3], bool coincident) - const; - void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5_inner(hid_t group_id) const; - bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) - const; - struct BoundingBox bounding_box() const; -}; - SurfaceXPlane::SurfaceXPlane(pugi::xml_node surf_node) : PeriodicSurface(surf_node) { @@ -521,27 +338,9 @@ SurfaceXPlane::bounding_box() const } //============================================================================== -// SurfaceYPlane -//! A plane perpendicular to the y-axis. -// -//! The plane is described by the equation \f$y - y_0 = 0\f$ +// SurfaceYPlane implementation //============================================================================== -class SurfaceYPlane : public PeriodicSurface -{ - double y0; -public: - SurfaceYPlane(pugi::xml_node surf_node); - double evaluate(const double xyz[3]) const; - double distance(const double xyz[3], const double uvw[3], - bool coincident) const; - void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5_inner(hid_t group_id) const; - bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) - const; - struct BoundingBox bounding_box() const; -}; - SurfaceYPlane::SurfaceYPlane(pugi::xml_node surf_node) : PeriodicSurface(surf_node) { @@ -605,27 +404,9 @@ SurfaceYPlane::bounding_box() const } //============================================================================== -// SurfaceZPlane -//! A plane perpendicular to the z-axis. -// -//! The plane is described by the equation \f$z - z_0 = 0\f$ +// SurfaceZPlane implementation //============================================================================== -class SurfaceZPlane : public PeriodicSurface -{ - double z0; -public: - SurfaceZPlane(pugi::xml_node surf_node); - double evaluate(const double xyz[3]) const; - double distance(const double xyz[3], const double uvw[3], - bool coincident) const; - void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5_inner(hid_t group_id) const; - bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) - const; - struct BoundingBox bounding_box() const; -}; - SurfaceZPlane::SurfaceZPlane(pugi::xml_node surf_node) : PeriodicSurface(surf_node) { @@ -671,27 +452,9 @@ SurfaceZPlane::bounding_box() const } //============================================================================== -// SurfacePlane -//! A general plane. -// -//! The plane is described by the equation \f$A x + B y + C z - D = 0\f$ +// SurfacePlane implementation //============================================================================== -class SurfacePlane : public PeriodicSurface -{ - double A, B, C, D; -public: - SurfacePlane(pugi::xml_node surf_node); - double evaluate(const double xyz[3]) const; - double distance(const double xyz[3], const double uvw[3], bool coincident) - const; - void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5_inner(hid_t group_id) const; - bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) - const; - struct BoundingBox bounding_box() const; -}; - SurfacePlane::SurfacePlane(pugi::xml_node surf_node) : PeriodicSurface(surf_node) { @@ -832,25 +595,9 @@ axis_aligned_cylinder_normal(const double xyz[3], double uvw[3], double offset1, } //============================================================================== -// SurfaceXCylinder -//! A cylinder aligned along the x-axis. -// -//! The cylinder is described by the equation -//! \f$(y - y_0)^2 + (z - z_0)^2 - R^2 = 0\f$ +// SurfaceXCylinder implementation //============================================================================== -class SurfaceXCylinder : public Surface -{ - double y0, z0, r; -public: - SurfaceXCylinder(pugi::xml_node surf_node); - double evaluate(const double xyz[3]) const; - double distance(const double xyz[3], const double uvw[3], - bool coincident) const; - void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5_inner(hid_t group_id) const; -}; - SurfaceXCylinder::SurfaceXCylinder(pugi::xml_node surf_node) : Surface(surf_node) { @@ -883,25 +630,9 @@ void SurfaceXCylinder::to_hdf5_inner(hid_t group_id) const } //============================================================================== -// SurfaceYCylinder -//! A cylinder aligned along the y-axis. -// -//! The cylinder is described by the equation -//! \f$(x - x_0)^2 + (z - z_0)^2 - R^2 = 0\f$ +// SurfaceYCylinder implementation //============================================================================== -class SurfaceYCylinder : public Surface -{ - double x0, z0, r; -public: - SurfaceYCylinder(pugi::xml_node surf_node); - double evaluate(const double xyz[3]) const; - double distance(const double xyz[3], const double uvw[3], - bool coincident) const; - void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5_inner(hid_t group_id) const; -}; - SurfaceYCylinder::SurfaceYCylinder(pugi::xml_node surf_node) : Surface(surf_node) { @@ -933,25 +664,9 @@ void SurfaceYCylinder::to_hdf5_inner(hid_t group_id) const } //============================================================================== -// SurfaceZCylinder -//! A cylinder aligned along the z-axis. -// -//! The cylinder is described by the equation -//! \f$(x - x_0)^2 + (y - y_0)^2 - R^2 = 0\f$ +// SurfaceZCylinder implementation //============================================================================== -class SurfaceZCylinder : public Surface -{ - double x0, y0, r; -public: - SurfaceZCylinder(pugi::xml_node surf_node); - double evaluate(const double xyz[3]) const; - double distance(const double xyz[3], const double uvw[3], - bool coincident) const; - void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5_inner(hid_t group_id) const; -}; - SurfaceZCylinder::SurfaceZCylinder(pugi::xml_node surf_node) : Surface(surf_node) { @@ -983,25 +698,9 @@ void SurfaceZCylinder::to_hdf5_inner(hid_t group_id) const } //============================================================================== -// SurfaceSphere -//! A sphere. -// -//! The cylinder is described by the equation -//! \f$(x - x_0)^2 + (y - y_0)^2 + (z - z_0)^2 - R^2 = 0\f$ +// SurfaceSphere implementation //============================================================================== -class SurfaceSphere : public Surface -{ - double x0, y0, z0, r; -public: - SurfaceSphere(pugi::xml_node surf_node); - double evaluate(const double xyz[3]) const; - double distance(const double xyz[3], const double uvw[3], - bool coincident) const; - void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5_inner(hid_t group_id) const; -}; - SurfaceSphere::SurfaceSphere(pugi::xml_node surf_node) : Surface(surf_node) { @@ -1153,25 +852,9 @@ axis_aligned_cone_normal(const double xyz[3], double uvw[3], double offset1, } //============================================================================== -// SurfaceXCone -//! A cone aligned along the x-axis. -// -//! The cylinder is described by the equation -//! \f$(y - y_0)^2 + (z - z_0)^2 - R^2 (x - x_0)^2 = 0\f$ +// SurfaceXCone implementation //============================================================================== -class SurfaceXCone : public Surface -{ - double x0, y0, z0, r_sq; -public: - SurfaceXCone(pugi::xml_node surf_node); - double evaluate(const double xyz[3]) const; - double distance(const double xyz[3], const double uvw[3], - bool coincident) const; - void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5_inner(hid_t group_id) const; -}; - SurfaceXCone::SurfaceXCone(pugi::xml_node surf_node) : Surface(surf_node) { @@ -1203,25 +886,9 @@ void SurfaceXCone::to_hdf5_inner(hid_t group_id) const } //============================================================================== -// SurfaceYCone -//! A cone aligned along the y-axis. -// -//! The cylinder is described by the equation -//! \f$(x - x_0)^2 + (z - z_0)^2 - R^2 (y - y_0)^2 = 0\f$ +// SurfaceYCone implementation //============================================================================== -class SurfaceYCone : public Surface -{ - double x0, y0, z0, r_sq; -public: - SurfaceYCone(pugi::xml_node surf_node); - double evaluate(const double xyz[3]) const; - double distance(const double xyz[3], const double uvw[3], - bool coincident) const; - void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5_inner(hid_t group_id) const; -}; - SurfaceYCone::SurfaceYCone(pugi::xml_node surf_node) : Surface(surf_node) { @@ -1253,25 +920,9 @@ void SurfaceYCone::to_hdf5_inner(hid_t group_id) const } //============================================================================== -// SurfaceZCone -//! A cone aligned along the z-axis. -// -//! The cylinder is described by the equation -//! \f$(x - x_0)^2 + (y - y_0)^2 - R^2 (z - z_0)^2 = 0\f$ +// SurfaceZCone implementation //============================================================================== -class SurfaceZCone : public Surface -{ - double x0, y0, z0, r_sq; -public: - SurfaceZCone(pugi::xml_node surf_node); - double evaluate(const double xyz[3]) const; - double distance(const double xyz[3], const double uvw[3], - bool coincident) const; - void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5_inner(hid_t group_id) const; -}; - SurfaceZCone::SurfaceZCone(pugi::xml_node surf_node) : Surface(surf_node) { @@ -1303,25 +954,9 @@ void SurfaceZCone::to_hdf5_inner(hid_t group_id) const } //============================================================================== -// SurfaceQuadric -//! A general surface described by a quadratic equation. -// -//! \f$A x^2 + B y^2 + C z^2 + D x y + E y z + F x z + G x + H y + J z + K = 0\f$ +// SurfaceQuadric implementation //============================================================================== -class SurfaceQuadric : public Surface -{ - // Ax^2 + By^2 + Cz^2 + Dxy + Eyz + Fxz + Gx + Hy + Jz + K = 0 - double A, B, C, D, E, F, G, H, J, K; -public: - SurfaceQuadric(pugi::xml_node surf_node); - double evaluate(const double xyz[3]) const; - double distance(const double xyz[3], const double uvw[3], - bool coincident) const; - void normal(const double xyz[3], double uvw[3]) const; - void to_hdf5_inner(hid_t group_id) const; -}; - SurfaceQuadric::SurfaceQuadric(pugi::xml_node surf_node) : Surface(surf_node) { @@ -1472,9 +1107,10 @@ read_surfaces(pugi::xml_node *node) surfaces_c[i_surf] = new SurfaceQuadric(surf_node); } else { - std::cout << "Call error here!" << std::endl; - std::cout << surf_type << std::endl; - //TODO: call fatal_error + std::string err_msg{"Invalid surface type, \""}; + err_msg += surf_type; + err_msg += "\""; + fatal_error(err_msg); } } } @@ -1592,58 +1228,3 @@ read_surfaces(pugi::xml_node *node) } } } - -//============================================================================== - -extern "C" bool -surface_sense(int surf_ind, double xyz[3], double uvw[3]) -{ - return surfaces_c[surf_ind]->sense(xyz, uvw); -} - -extern "C" void -surface_reflect(int surf_ind, double xyz[3], double uvw[3]) -{ - surfaces_c[surf_ind]->reflect(xyz, uvw); -} - -extern "C" double -surface_distance(int surf_ind, double xyz[3], double uvw[3], bool coincident) -{ - return surfaces_c[surf_ind]->distance(xyz, uvw, coincident); -} - -extern "C" void -surface_normal(int surf_ind, double xyz[3], double uvw[3]) -{ - return surfaces_c[surf_ind]->normal(xyz, uvw); -} - -extern "C" void -surface_to_hdf5(int surf_ind, hid_t group) -{ - surfaces_c[surf_ind]->to_hdf5(group); -} - -extern "C" bool -surface_periodic(int surf_ind1, double xyz[3], double uvw[3]) -{ - // Hopefully this function has only been called for a pair of surfaces that - // support periodic BCs (checking should have been done when reading the - // geometry XML). Downcast the surfaces to the PeriodicSurface type so we - // can call the periodic_translate method. - Surface *surf1_gen = surfaces_c[surf_ind1]; - PeriodicSurface *surf1 = dynamic_cast(surf1_gen); - Surface *surf2_gen = surfaces_c[surf1->i_periodic]; - PeriodicSurface *surf2 = dynamic_cast(surf2_gen); - - // Call the type-bound methods. - return surf2->periodic_translate(surf1, xyz, uvw); -} - -extern "C" int -surface_i_periodic(int surf_ind) -{ - PeriodicSurface *surf = dynamic_cast(surfaces_c[surf_ind]); - return surf->i_periodic; -} diff --git a/src/surface.h b/src/surface.h new file mode 100644 index 0000000000..22eb798dcb --- /dev/null +++ b/src/surface.h @@ -0,0 +1,431 @@ +#ifndef SURFACE_H +#define SURFACE_H + +#include +#include // For numeric_limits + +#include "hdf5.h" +#include "pugixml/pugixml.hpp" + +//============================================================================== +// Module constants +//============================================================================== + +extern "C" const int BC_TRANSMIT{0}; +extern "C" const int BC_VACUUM{1}; +extern "C" const int BC_REFLECT{2}; +extern "C" const int BC_PERIODIC{3}; + +//============================================================================== +// Constants that should eventually be moved out of this file +//============================================================================== + +extern "C" double FP_COINCIDENT; +const double INFTY{std::numeric_limits::max()}; +const int C_NONE{-1}; + +//============================================================================== +// Global variables +//============================================================================== + +class Surface; +Surface **surfaces_c; + +std::map surface_dict; + +//============================================================================== +//! Coordinates for an axis-aligned cube that bounds a geometric object. +//============================================================================== + +struct BoundingBox +{ + double xmin; + double xmax; + double ymin; + double ymax; + double zmin; + double zmax; +}; + +//============================================================================== +//! A geometry primitive used to define regions of 3D space. +//============================================================================== + +class Surface +{ +public: + int id; //!< Unique ID + //int neighbor_pos[], //!< List of cells on positive side + // neighbor_neg[]; //!< List of cells on negative side + int bc; //!< Boundary condition + std::string name{""}; //!< User-defined name + + Surface(pugi::xml_node surf_node); + + //! Determine which side of a surface a point lies on. + //! @param xyz[3] The 3D Cartesian coordinate of a point. + //! @param uvw[3] A direction used to "break ties" and pick a sense when the + //! point is very close to the surface. + //! @return true if the point is on the "positive" side of the surface and + //! false otherwise. + bool sense(const double xyz[3], const double uvw[3]) const; + + //! Determine the direction of a ray reflected from the surface. + //! @param xyz[3] The point at which the ray is incident. + //! @param uvw[3] A direction. This is both an input and an output parameter. + //! It specifies the icident direction on input and the reflected direction + //! on output. + void reflect(const double xyz[3], double uvw[3]) const; + + //! Evaluate the equation describing the surface. + //! + //! Surfaces can be described by some function f(x, y, z) = 0. This member + //! function evaluates that mathematical function. + //! @param xyz[3] A 3D Cartesian coordinate. + virtual double evaluate(const double xyz[3]) const = 0; + + //! Compute the distance between a point and the surface along a ray. + //! @param xyz[3] A 3D Cartesian coordinate. + //! @param uvw[3] The direction of the ray. + //! @param coincident A hint to the code that the given point should lie + //! exactly on the surface. + virtual double distance(const double xyz[3], const double uvw[3], + bool coincident) const = 0; + + //! Compute the local outward normal direction of the surface. + //! @param xyz[3] A 3D Cartesian coordinate. + //! @param uvw[3] This output argument provides the normal. + virtual void normal(const double xyz[3], double uvw[3]) const = 0; + + //! Write all information needed to reconstruct the surface to an HDF5 group. + //! @param group_id An HDF5 group id. + void to_hdf5(hid_t group_id) const; + +protected: + virtual void to_hdf5_inner(hid_t group_id) const = 0; +}; + +//============================================================================== +//! A `Surface` that supports periodic boundary conditions. +//! +//! Translational periodicity is supported for the `XPlane`, `YPlane`, `ZPlane`, +//! and `Plane` types. Rotational periodicity is supported for +//! `XPlane`-`YPlane` pairs. +//============================================================================== + +class PeriodicSurface : public Surface +{ +public: + int i_periodic{C_NONE}; //!< Index of corresponding periodic surface + + PeriodicSurface(pugi::xml_node surf_node); + + //! Translate a particle onto this surface from a periodic partner surface. + //! @param other A pointer to the partner surface in this periodic BC. + //! @param xyz[3] A point on the partner surface that will be translated onto + //! this surface. + //! @param uvw[3] A direction that will be rotated for systems with rotational + //! periodicity. + //! @return true if this surface and its partner make a rotationally-periodic + //! boundary condition. + virtual bool periodic_translate(PeriodicSurface *other, double xyz[3], + double uvw[3]) const = 0; + + //! Get the bounding box for this surface. + virtual struct BoundingBox bounding_box() const = 0; +}; + +//============================================================================== +//! A plane perpendicular to the x-axis. +// +//! The plane is described by the equation \f$x - x_0 = 0\f$ +//============================================================================== + +class SurfaceXPlane : public PeriodicSurface +{ + double x0; +public: + SurfaceXPlane(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], bool coincident) + const; + void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5_inner(hid_t group_id) const; + bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) + const; + struct BoundingBox bounding_box() const; +}; + +//============================================================================== +//! A plane perpendicular to the y-axis. +// +//! The plane is described by the equation \f$y - y_0 = 0\f$ +//============================================================================== + +class SurfaceYPlane : public PeriodicSurface +{ + double y0; +public: + SurfaceYPlane(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5_inner(hid_t group_id) const; + bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) + const; + struct BoundingBox bounding_box() const; +}; + +//============================================================================== +//! A plane perpendicular to the z-axis. +// +//! The plane is described by the equation \f$z - z_0 = 0\f$ +//============================================================================== + +class SurfaceZPlane : public PeriodicSurface +{ + double z0; +public: + SurfaceZPlane(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5_inner(hid_t group_id) const; + bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) + const; + struct BoundingBox bounding_box() const; +}; + +//============================================================================== +//! A general plane. +// +//! The plane is described by the equation \f$A x + B y + C z - D = 0\f$ +//============================================================================== + +class SurfacePlane : public PeriodicSurface +{ + double A, B, C, D; +public: + SurfacePlane(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], bool coincident) + const; + void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5_inner(hid_t group_id) const; + bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) + const; + struct BoundingBox bounding_box() const; +}; + +//============================================================================== +//! A cylinder aligned along the x-axis. +// +//! The cylinder is described by the equation +//! \f$(y - y_0)^2 + (z - z_0)^2 - R^2 = 0\f$ +//============================================================================== + +class SurfaceXCylinder : public Surface +{ + double y0, z0, r; +public: + SurfaceXCylinder(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5_inner(hid_t group_id) const; +}; + +//============================================================================== +//! A cylinder aligned along the y-axis. +// +//! The cylinder is described by the equation +//! \f$(x - x_0)^2 + (z - z_0)^2 - R^2 = 0\f$ +//============================================================================== + +class SurfaceYCylinder : public Surface +{ + double x0, z0, r; +public: + SurfaceYCylinder(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5_inner(hid_t group_id) const; +}; + +//============================================================================== +//! A cylinder aligned along the z-axis. +// +//! The cylinder is described by the equation +//! \f$(x - x_0)^2 + (y - y_0)^2 - R^2 = 0\f$ +//============================================================================== + +class SurfaceZCylinder : public Surface +{ + double x0, y0, r; +public: + SurfaceZCylinder(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5_inner(hid_t group_id) const; +}; + +//============================================================================== +//! A sphere. +// +//! The cylinder is described by the equation +//! \f$(x - x_0)^2 + (y - y_0)^2 + (z - z_0)^2 - R^2 = 0\f$ +//============================================================================== + +class SurfaceSphere : public Surface +{ + double x0, y0, z0, r; +public: + SurfaceSphere(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5_inner(hid_t group_id) const; +}; + +//============================================================================== +//! A cone aligned along the x-axis. +// +//! The cylinder is described by the equation +//! \f$(y - y_0)^2 + (z - z_0)^2 - R^2 (x - x_0)^2 = 0\f$ +//============================================================================== + +class SurfaceXCone : public Surface +{ + double x0, y0, z0, r_sq; +public: + SurfaceXCone(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5_inner(hid_t group_id) const; +}; + +//============================================================================== +//! A cone aligned along the y-axis. +// +//! The cylinder is described by the equation +//! \f$(x - x_0)^2 + (z - z_0)^2 - R^2 (y - y_0)^2 = 0\f$ +//============================================================================== + +class SurfaceYCone : public Surface +{ + double x0, y0, z0, r_sq; +public: + SurfaceYCone(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5_inner(hid_t group_id) const; +}; + +//============================================================================== +//! A cone aligned along the z-axis. +// +//! The cylinder is described by the equation +//! \f$(x - x_0)^2 + (y - y_0)^2 - R^2 (z - z_0)^2 = 0\f$ +//============================================================================== + +class SurfaceZCone : public Surface +{ + double x0, y0, z0, r_sq; +public: + SurfaceZCone(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5_inner(hid_t group_id) const; +}; + +//============================================================================== +//! A general surface described by a quadratic equation. +// +//! \f$A x^2 + B y^2 + C z^2 + D x y + E y z + F x z + G x + H y + J z + K = 0\f$ +//============================================================================== + +class SurfaceQuadric : public Surface +{ + // Ax^2 + By^2 + Cz^2 + Dxy + Eyz + Fxz + Gx + Hy + Jz + K = 0 + double A, B, C, D, E, F, G, H, J, K; +public: + SurfaceQuadric(pugi::xml_node surf_node); + double evaluate(const double xyz[3]) const; + double distance(const double xyz[3], const double uvw[3], + bool coincident) const; + void normal(const double xyz[3], double uvw[3]) const; + void to_hdf5_inner(hid_t group_id) const; +}; + +//============================================================================== +// Fortran compatibility functions +//============================================================================== + +extern "C" bool +surface_sense(int surf_ind, double xyz[3], double uvw[3]) +{ + return surfaces_c[surf_ind]->sense(xyz, uvw); +} + +extern "C" void +surface_reflect(int surf_ind, double xyz[3], double uvw[3]) +{ + surfaces_c[surf_ind]->reflect(xyz, uvw); +} + +extern "C" double +surface_distance(int surf_ind, double xyz[3], double uvw[3], bool coincident) +{ + return surfaces_c[surf_ind]->distance(xyz, uvw, coincident); +} + +extern "C" void +surface_normal(int surf_ind, double xyz[3], double uvw[3]) +{ + return surfaces_c[surf_ind]->normal(xyz, uvw); +} + +extern "C" void +surface_to_hdf5(int surf_ind, hid_t group) +{ + surfaces_c[surf_ind]->to_hdf5(group); +} + +extern "C" bool +surface_periodic(int surf_ind1, double xyz[3], double uvw[3]) +{ + // Hopefully this function has only been called for a pair of surfaces that + // support periodic BCs (checking should have been done when reading the + // geometry XML). Downcast the surfaces to the PeriodicSurface type so we + // can call the periodic_translate method. + Surface *surf1_gen = surfaces_c[surf_ind1]; + PeriodicSurface *surf1 = dynamic_cast(surf1_gen); + Surface *surf2_gen = surfaces_c[surf1->i_periodic]; + PeriodicSurface *surf2 = dynamic_cast(surf2_gen); + + // Call the type-bound methods. + return surf2->periodic_translate(surf1, xyz, uvw); +} + +extern "C" int +surface_i_periodic(int surf_ind) +{ + PeriodicSurface *surf = dynamic_cast(surfaces_c[surf_ind]); + return surf->i_periodic; +} + +#endif // SURFACE_H diff --git a/src/xml_interface.h b/src/xml_interface.h new file mode 100644 index 0000000000..fbc82e056b --- /dev/null +++ b/src/xml_interface.h @@ -0,0 +1,52 @@ +#ifndef XML_INTERFACE_H +#define XML_INTERFACE_H + +#include // for std::transform +#include + +#include "pugixml/pugixml.hpp" + + +bool +check_for_node(const pugi::xml_node &node, const char *name) +{ + if (node.attribute(name)) { + return true; + } else if (node.child(name)) { + return true; + } else { + return false; + } +} + + +std::string +get_node_value(const pugi::xml_node &node, const char *name) +{ + // Search for either an attribute or child tag and get the data as a char*. + const pugi::char_t *value_char; + if (node.attribute(name)) { + value_char = node.attribute(name).value(); + } else if (node.child(name)) { + value_char = node.child_value(name); + } else { + std::string err_msg("Node \""); + err_msg += name; + err_msg += "\" is not a memeber of the \""; + err_msg += node.name(); + err_msg += "\" XML node"; + fatal_error(err_msg); + } + + // Convert to lowercase string. + std::string value(value_char); + std::transform(value.begin(), value.end(), value.begin(), ::tolower); + + // Remove whitespace. + value.erase(0, value.find_first_not_of(" \t\r\n")); + value.erase(value.find_last_not_of(" \t\r\n") + 1); + + return value; +} + +#endif // XML_INTERFACE_H From 75501a08e931ed64011205bbd612e708eb0bb670 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Wed, 24 Jan 2018 11:56:20 -0500 Subject: [PATCH 18/74] Add C++ Surface pointers to Fortran Surfaces --- src/geometry.F90 | 68 +--------- src/input_xml.F90 | 60 +-------- src/output.F90 | 2 +- src/summary.F90 | 15 +-- src/surface.cpp | 13 +- src/surface.h | 72 +++++------ src/surface_header.F90 | 180 ++++++++++++++++++++++++++- src/tallies/tally_filter_surface.F90 | 2 +- src/tracking.F90 | 43 ++++--- 9 files changed, 252 insertions(+), 203 deletions(-) diff --git a/src/geometry.F90 b/src/geometry.F90 index d1519f8d21..0bacd7b5d1 100644 --- a/src/geometry.F90 +++ b/src/geometry.F90 @@ -14,66 +14,6 @@ module geometry implicit none - interface - pure function surface_sense_c(surf_ind, xyz, uvw) & - bind(C, name='surface_sense') result(sense) - use ISO_C_BINDING - implicit none - integer(C_INT), intent(in), value :: surf_ind; - real(C_DOUBLE), intent(in) :: xyz(3); - real(C_DOUBLE), intent(in) :: uvw(3); - logical(C_BOOL) :: sense; - end function surface_sense_c - - pure subroutine surface_reflect_c(surf_ind, xyz, uvw) & - bind(C, name='surface_reflect') - use ISO_C_BINDING - implicit none - integer(C_INT), intent(in), value :: surf_ind; - real(C_DOUBLE), intent(in) :: xyz(3); - real(C_DOUBLE), intent(inout) :: uvw(3); - end subroutine surface_reflect_c - - pure function surface_distance_c(surf_ind, xyz, uvw, coincident) & - bind(C, name='surface_distance') result(d) - use ISO_C_BINDING - implicit none - integer(C_INT), intent(in), value :: surf_ind; - real(C_DOUBLE), intent(in) :: xyz(3); - real(C_DOUBLE), intent(in) :: uvw(3); - logical(C_BOOL), intent(in), value :: coincident; - real(C_DOUBLE) :: d; - end function surface_distance_c - - pure subroutine surface_normal_c(surf_ind, xyz, uvw) & - bind(C, name='surface_normal') - use ISO_C_BINDING - implicit none - integer(C_INT), intent(in), value :: surf_ind; - real(C_DOUBLE), intent(in) :: xyz(3); - real(C_DOUBLE), intent(out) :: uvw(3); - end subroutine surface_normal_c - - function surface_periodic_c(surf_ind1, xyz, uvw) & - bind(C, name="surface_periodic") result(rotational) - use ISO_C_BINDING - implicit none - integer(C_INT), intent(in), value :: surf_ind1; - real(C_DOUBLE), intent(inout) :: xyz(3); - real(C_DOUBLE), intent(inout) :: uvw(3); - logical(C_BOOL) :: rotational - end function surface_periodic_c - - function surface_i_periodic_c(surf_ind) bind(C, name="surface_i_periodic") & - result(i_periodic) - use ISO_C_BINDING - implicit none - integer(C_INT), intent(in), value :: surf_ind - integer(C_INT) :: i_periodic - end function - - end interface - contains !=============================================================================== @@ -125,7 +65,7 @@ contains in_cell = .false. exit else - actual_sense = surface_sense_c(abs(token)-1, & + actual_sense = surfaces(abs(token)) % sense( & p%coord(p%n_coord)%xyz, p%coord(p%n_coord)%uvw) if (actual_sense .neqv. (token > 0)) then in_cell = .false. @@ -174,7 +114,7 @@ contains elseif (-token == p%surface) then stack(i_stack) = .false. else - actual_sense = surface_sense_c(abs(token)-1, & + actual_sense = surfaces(abs(token)) % sense( & p%coord(p%n_coord)%xyz, p%coord(p%n_coord)%uvw) stack(i_stack) = (actual_sense .eqv. (token > 0)) end if @@ -579,7 +519,7 @@ contains if (index_surf >= OP_UNION) cycle ! Calculate distance to surface - d = surface_distance_c(index_surf-1, p % coord(j) % xyz, & + d = surfaces(index_surf) % distance(p % coord(j) % xyz, & p % coord(j) % uvw, logical(coincident, kind=C_BOOL)) ! Check if calculated distance is new minimum @@ -799,7 +739,7 @@ contains ! traveling into if the surface is crossed if (.not. c % simple) then xyz_cross(:) = p % coord(j) % xyz + d_surf*p % coord(j) % uvw - call surface_normal_c(abs(level_surf_cross)-1, xyz_cross, surf_uvw) + call surfaces(abs(level_surf_cross)) % normal(xyz_cross, surf_uvw) if (dot_product(p % coord(j) % uvw, surf_uvw) > ZERO) then surface_crossed = abs(level_surf_cross) else diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 9b6e1c6fce..55eeca9e14 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -924,19 +924,15 @@ contains logical :: file_exists logical :: boundary_exists character(MAX_LINE_LEN) :: filename - character(MAX_WORD_LEN) :: word character(MAX_WORD_LEN), allocatable :: sarray(:) character(:), allocatable :: region_spec type(Cell), pointer :: c - class(Surface), pointer :: s class(Lattice), pointer :: lat type(XMLDocument) :: doc type(XMLNode) :: root type(XMLNode) :: node_cell - type(XMLNode) :: node_surf type(XMLNode) :: node_lat type(XMLNode), allocatable :: node_cell_list(:) - type(XMLNode), allocatable :: node_surf_list(:) type(XMLNode), allocatable :: node_rlat_list(:) type(XMLNode), allocatable :: node_hlat_list(:) type(VectorInt) :: tokens @@ -968,66 +964,18 @@ contains ! applied to a surface boundary_exists = .false. - ! get pointer to list of xml - call get_node_list(root, "surface", node_surf_list) call read_surfaces(root % ptr) - ! Get number of tags - n_surfaces = size(node_surf_list) - - ! Check for no surfaces - if (n_surfaces == 0) then - call fatal_error("No surfaces found in geometry.xml!") - end if - - ! Allocate cells array + ! Allocate surfaces array allocate(surfaces(n_surfaces)) do i = 1, n_surfaces - ! Get pointer to i-th surface node - node_surf = node_surf_list(i) + surfaces(i) % ptr = surface_pointer_c(i - 1); - s => surfaces(i) + if (surfaces(i) % bc() /= BC_TRANSMIT) boundary_exists = .true. - ! Copy data into cells - if (check_for_node(node_surf, "id")) then - call get_node_value(node_surf, "id", s%id) - else - call fatal_error("Must specify id of surface in geometry XML file.") - end if - - ! Check to make sure 'id' hasn't been used - if (surface_dict % has(s%id)) then - call fatal_error("Two or more surfaces use the same unique ID: " & - // to_str(s%id)) - end if - - ! Check to make sure that the proper number of coefficients - ! have been specified for the given type of surface. Then copy - ! surface coordinates. - - ! Boundary conditions - word = '' - if (check_for_node(node_surf, "boundary")) & - call get_node_value(node_surf, "boundary", word) - select case (to_lower(word)) - case ('transmission', 'transmit', '') - s%bc = BC_TRANSMIT - case ('vacuum') - s%bc = BC_VACUUM - boundary_exists = .true. - case ('reflective', 'reflect', 'reflecting') - s%bc = BC_REFLECT - boundary_exists = .true. - case ('periodic') - s%bc = BC_PERIODIC - boundary_exists = .true. - case default - call fatal_error("Unknown boundary condition '" // trim(word) // & - &"' specified on surface " // trim(to_str(s%id))) - end select ! Add surface to dictionary - call surface_dict % set(s%id, i) + call surface_dict % set(surfaces(i) % id(), i) end do ! Check to make sure a boundary condition was applied to at least one diff --git a/src/output.F90 b/src/output.F90 index 4113eea472..316fe95941 100644 --- a/src/output.F90 +++ b/src/output.F90 @@ -259,7 +259,7 @@ contains ! Print surface if (p % surface /= NONE) then - write(ou,*) ' Surface = ' // to_str(sign(surfaces(i)%id, p % surface)) + write(ou,*) ' Surface = ' // to_str(sign(surfaces(i)%id(), p % surface)) end if ! Display weight, energy, grid index, and interpolation factor diff --git a/src/summary.F90 b/src/summary.F90 index 9b82a03967..3aeb42178b 100644 --- a/src/summary.F90 +++ b/src/summary.F90 @@ -24,17 +24,6 @@ module summary public :: write_summary - interface - subroutine surface_to_hdf5_c(surf_ind, group) & - bind(C, name='surface_to_hdf5') - use ISO_C_BINDING - use hdf5 - implicit none - integer(C_INT), intent(in), value :: surf_ind - integer(HID_T), intent(in), value :: group - end subroutine surface_to_hdf5_c - end interface - contains !=============================================================================== @@ -232,7 +221,7 @@ contains region_spec = trim(region_spec) // " |" case default region_spec = trim(region_spec) // " " // to_str(& - sign(surfaces(abs(k))%id, k)) + sign(surfaces(abs(k))%id(), k)) end select end do call write_dataset(cell_group, "region", adjustl(region_spec)) @@ -250,7 +239,7 @@ contains ! Write information on each surface SURFACE_LOOP: do i = 1, n_surfaces - call surface_to_hdf5_c(i-1, surfaces_group) + call surfaces(i) % to_hdf5(surfaces_group) end do SURFACE_LOOP call close_group(surfaces_group) diff --git a/src/surface.cpp b/src/surface.cpp index ed111b0370..369334d500 100644 --- a/src/surface.cpp +++ b/src/surface.cpp @@ -1053,11 +1053,13 @@ extern "C" void read_surfaces(pugi::xml_node *node) { // Count the number of surfaces. - int n_surfaces{0}; for (pugi::xml_node surf_node = node->child("surface"); surf_node; surf_node = surf_node.next_sibling("surface")) { n_surfaces++; } + if (n_surfaces == 0) { + fatal_error("No surfaces found in geometry.xml!"); + } // Allocate the array of Surface pointers. surfaces_c = new Surface* [n_surfaces]; @@ -1137,7 +1139,14 @@ read_surfaces(pugi::xml_node *node) // Downcast to the PeriodicSurface type. Surface *surf_base = surfaces_c[i_surf]; PeriodicSurface *surf = dynamic_cast(surf_base); - //TODO: check for null pointer + + // Make sure this surface inherits from PeriodicSurface. + if (surf == NULL) { + std::string err_msg{"Periodic boundary condition not supported for " + "surface "}; + err_msg += std::to_string(surf_base->id); + err_msg += ". Periodic BCs are only supported for planar surfaces."; + } // See if this surface makes part of the global bounding box. struct BoundingBox bb = surf->bounding_box(); diff --git a/src/surface.h b/src/surface.h index 22eb798dcb..469d884862 100644 --- a/src/surface.h +++ b/src/surface.h @@ -28,6 +28,8 @@ const int C_NONE{-1}; // Global variables //============================================================================== +int n_surfaces{0}; + class Surface; Surface **surfaces_c; @@ -375,57 +377,43 @@ public: // Fortran compatibility functions //============================================================================== -extern "C" bool -surface_sense(int surf_ind, double xyz[3], double uvw[3]) -{ - return surfaces_c[surf_ind]->sense(xyz, uvw); -} +extern "C" Surface* surface_pointer(int surf_ind) {return surfaces_c[surf_ind];} -extern "C" void -surface_reflect(int surf_ind, double xyz[3], double uvw[3]) -{ - surfaces_c[surf_ind]->reflect(xyz, uvw); -} +extern "C" int surface_id(Surface *surf) {return surf->id;} + +extern "C" int surface_bc(Surface *surf) {return surf->bc;} + +extern "C" bool surface_sense(Surface *surf, double xyz[3], double uvw[3]) +{return surf->sense(xyz, uvw);} + +extern "C" void surface_reflect(Surface *surf, double xyz[3], double uvw[3]) +{surf->reflect(xyz, uvw);} extern "C" double -surface_distance(int surf_ind, double xyz[3], double uvw[3], bool coincident) -{ - return surfaces_c[surf_ind]->distance(xyz, uvw, coincident); -} +surface_distance(Surface *surf, double xyz[3], double uvw[3], bool coincident) +{return surf->distance(xyz, uvw, coincident);} -extern "C" void -surface_normal(int surf_ind, double xyz[3], double uvw[3]) -{ - return surfaces_c[surf_ind]->normal(xyz, uvw); -} +extern "C" void surface_normal(Surface *surf, double xyz[3], double uvw[3]) +{return surf->normal(xyz, uvw);} -extern "C" void -surface_to_hdf5(int surf_ind, hid_t group) -{ - surfaces_c[surf_ind]->to_hdf5(group); -} +extern "C" void surface_to_hdf5(Surface *surf, hid_t group) +{surf->to_hdf5(group);} + +extern "C" int surface_i_periodic(PeriodicSurface *surf) +{return surf->i_periodic;} extern "C" bool -surface_periodic(int surf_ind1, double xyz[3], double uvw[3]) -{ - // Hopefully this function has only been called for a pair of surfaces that - // support periodic BCs (checking should have been done when reading the - // geometry XML). Downcast the surfaces to the PeriodicSurface type so we - // can call the periodic_translate method. - Surface *surf1_gen = surfaces_c[surf_ind1]; - PeriodicSurface *surf1 = dynamic_cast(surf1_gen); - Surface *surf2_gen = surfaces_c[surf1->i_periodic]; - PeriodicSurface *surf2 = dynamic_cast(surf2_gen); +surface_periodic(PeriodicSurface *surf, PeriodicSurface *other, double xyz[3], + double uvw[3]) +{return surf->periodic_translate(other, xyz, uvw);} - // Call the type-bound methods. - return surf2->periodic_translate(surf1, xyz, uvw); -} - -extern "C" int -surface_i_periodic(int surf_ind) +extern "C" void free_memory_surfaces_c() { - PeriodicSurface *surf = dynamic_cast(surfaces_c[surf_ind]); - return surf->i_periodic; + for (int i = 0; i < n_surfaces; i++) {delete surfaces_c[i];} + delete surfaces_c; + surfaces_c = NULL; + n_surfaces = 0; + surface_dict.clear(); } #endif // SURFACE_H diff --git a/src/surface_header.F90 b/src/surface_header.F90 index ffe0a6db41..8985e8406e 100644 --- a/src/surface_header.F90 +++ b/src/surface_header.F90 @@ -1,26 +1,132 @@ module surface_header use, intrinsic :: ISO_C_BINDING + use hdf5 - use constants, only: NONE use dict_header, only: DictIntInt implicit none + interface + pure function surface_pointer_c(surf_ind) & + bind(C, name='surface_pointer') result(ptr) + use ISO_C_BINDING + implicit none + integer(C_INT), intent(in), value :: surf_ind + type(C_PTR) :: ptr + end function surface_pointer_c + + pure function surface_id_c(surf_ptr) bind(C, name='surface_id') result(id) + use ISO_C_BINDING + implicit none + type(C_PTR), intent(in), value :: surf_ptr + integer(C_INT) :: id + end function surface_id_c + + pure function surface_bc_c(surf_ptr) bind(C, name='surface_bc') result(bc) + use ISO_C_BINDING + implicit none + type(C_PTR), intent(in), value :: surf_ptr + integer(C_INT) :: bc + end function surface_bc_c + + pure function surface_sense_c(surf_ptr, xyz, uvw) & + bind(C, name='surface_sense') result(sense) + use ISO_C_BINDING + implicit none + type(C_PTR), intent(in), value :: surf_ptr + real(C_DOUBLE), intent(in) :: xyz(3) + real(C_DOUBLE), intent(in) :: uvw(3) + logical(C_BOOL) :: sense + end function surface_sense_c + + pure subroutine surface_reflect_c(surf_ptr, xyz, uvw) & + bind(C, name='surface_reflect') + use ISO_C_BINDING + implicit none + type(C_PTR), intent(in), value :: surf_ptr + real(C_DOUBLE), intent(in) :: xyz(3); + real(C_DOUBLE), intent(inout) :: uvw(3); + end subroutine surface_reflect_c + + pure function surface_distance_c(surf_ptr, xyz, uvw, coincident) & + bind(C, name='surface_distance') result(d) + use ISO_C_BINDING + implicit none + type(C_PTR), intent(in), value :: surf_ptr + real(C_DOUBLE), intent(in) :: xyz(3); + real(C_DOUBLE), intent(in) :: uvw(3); + logical(C_BOOL), intent(in), value :: coincident; + real(C_DOUBLE) :: d; + end function surface_distance_c + + pure subroutine surface_normal_c(surf_ptr, xyz, uvw) & + bind(C, name='surface_normal') + use ISO_C_BINDING + implicit none + type(C_PTR), intent(in), value :: surf_ptr + real(C_DOUBLE), intent(in) :: xyz(3); + real(C_DOUBLE), intent(out) :: uvw(3); + end subroutine surface_normal_c + + subroutine surface_to_hdf5_c(surf_ptr, group) & + bind(C, name='surface_to_hdf5') + use ISO_C_BINDING + use hdf5 + implicit none + type(C_PTR), intent(in), value :: surf_ptr + integer(HID_T), intent(in), value :: group + end subroutine surface_to_hdf5_c + + pure function surface_i_periodic_c(surf_ptr) & + bind(C, name="surface_i_periodic") result(i_periodic) + use ISO_C_BINDING + implicit none + type(C_PTR), intent(in), value :: surf_ptr + integer(C_INT) :: i_periodic + end function surface_i_periodic_c + + function surface_periodic_c(surf_ptr, other_ptr, xyz, uvw) & + bind(C, name="surface_periodic") result(rotational) + use ISO_C_BINDING + implicit none + type(C_PTR), intent(in), value :: surf_ptr + type(C_PTR), intent(in), value :: other_ptr + real(C_DOUBLE), intent(inout) :: xyz(3); + real(C_DOUBLE), intent(inout) :: uvw(3); + logical(C_BOOL) :: rotational + end function surface_periodic_c + + subroutine free_memory_surfaces_c() bind(C) + end subroutine free_memory_surfaces_c + end interface + !=============================================================================== ! SURFACE type defines a first- or second-order surface that can be used to ! construct closed volumes (cells) !=============================================================================== type :: Surface - integer :: id ! Unique ID integer, allocatable :: & neighbor_pos(:), & ! List of cells on positive side neighbor_neg(:) ! List of cells on negative side - integer :: bc ! Boundary condition + type(C_PTR) :: ptr + + contains + + procedure :: id => surface_id + procedure :: bc => surface_bc + procedure :: sense => surface_sense + procedure :: reflect => surface_reflect + procedure :: distance => surface_distance + procedure :: normal => surface_normal + procedure :: to_hdf5 => surface_to_hdf5 + procedure :: i_periodic => surface_i_periodic + procedure :: periodic_translate => surface_periodic + end type Surface - integer(C_INT32_T), bind(C) :: n_surfaces ! # of surfaces + integer(C_INT), bind(C) :: n_surfaces ! # of surfaces type(Surface), allocatable, target :: surfaces(:) @@ -29,14 +135,78 @@ module surface_header contains + pure function surface_id(this) result(id) + class(Surface), intent(in) :: this + integer(C_INT) :: id + id = surface_id_c(this % ptr) + end function surface_id + + pure function surface_bc(this) result(bc) + class(Surface), intent(in) :: this + integer(C_INT) :: bc + bc = surface_bc_c(this % ptr) + end function surface_bc + + pure function surface_sense(this, xyz, uvw) result(sense) + class(Surface), intent(in) :: this + real(C_DOUBLE), intent(in) :: xyz(3) + real(C_DOUBLE), intent(in) :: uvw(3) + logical(C_BOOL) :: sense + sense = surface_sense_c(this % ptr, xyz, uvw) + end function surface_sense + + pure subroutine surface_reflect(this, xyz, uvw) + class(Surface), intent(in) :: this + real(C_DOUBLE), intent(in) :: xyz(3); + real(C_DOUBLE), intent(inout) :: uvw(3); + call surface_reflect_c(this % ptr, xyz, uvw) + end subroutine surface_reflect + + pure function surface_distance(this, xyz, uvw, coincident) result(d) + class(Surface), intent(in) :: this + real(C_DOUBLE), intent(in) :: xyz(3); + real(C_DOUBLE), intent(in) :: uvw(3); + logical(C_BOOL), intent(in) :: coincident; + real(C_DOUBLE) :: d; + d = surface_distance_c(this % ptr, xyz, uvw, coincident) + end function surface_distance + + pure subroutine surface_normal(this, xyz, uvw) + class(Surface), intent(in) :: this + real(C_DOUBLE), intent(in) :: xyz(3); + real(C_DOUBLE), intent(out) :: uvw(3); + call surface_normal_c(this % ptr, xyz, uvw) + end subroutine surface_normal + + subroutine surface_to_hdf5(this, group) + class(Surface), intent(in) :: this + integer(HID_T), intent(in) :: group + call surface_to_hdf5_c(this % ptr, group) + end subroutine surface_to_hdf5 + + pure function surface_i_periodic(this) result(i_periodic) + class(Surface), intent(in) :: this + integer(C_INT) :: i_periodic + i_periodic = surface_i_periodic_c(this % ptr) + end function surface_i_periodic + + function surface_periodic(this, other, xyz, uvw) result(rotational) + class(Surface), intent(in) :: this + class(Surface), intent(in) :: other + real(C_DOUBLE), intent(inout) :: xyz(3); + real(C_DOUBLE), intent(inout) :: uvw(3); + logical(C_BOOL) :: rotational + rotational = surface_periodic_c(this % ptr, other % ptr, xyz, uvw) + end function surface_periodic + !=============================================================================== ! FREE_MEMORY_SURFACES deallocates global arrays defined in this module !=============================================================================== subroutine free_memory_surfaces() - n_surfaces = 0 if (allocated(surfaces)) deallocate(surfaces) call surface_dict % clear() + call free_memory_surfaces_c() end subroutine free_memory_surfaces end module surface_header diff --git a/src/tallies/tally_filter_surface.F90 b/src/tallies/tally_filter_surface.F90 index 6a2afa3ec6..df3bf36031 100644 --- a/src/tallies/tally_filter_surface.F90 +++ b/src/tallies/tally_filter_surface.F90 @@ -105,7 +105,7 @@ contains integer, intent(in) :: bin character(MAX_LINE_LEN) :: label - label = "Surface " // to_str(surfaces(this % surfaces(bin)) % id) + label = "Surface " // to_str(surfaces(this % surfaces(bin)) % id()) end function text_label_surface end module tally_filter_surface diff --git a/src/tracking.F90 b/src/tracking.F90 index 98bca2a279..75555c7974 100644 --- a/src/tracking.F90 +++ b/src/tracking.F90 @@ -4,9 +4,8 @@ module tracking use cross_section, only: calculate_xs use error, only: fatal_error, warning, write_message use geometry_header, only: cells - use geometry, only: find_cell, distance_to_boundary, cross_lattice, & - check_cell_overlap, surface_reflect_c, & - surface_periodic_c, surface_i_periodic_c + use geometry, only: find_cell, distance_to_boundary, cross_lattice,& + check_cell_overlap use message_passing use mgxs_header use nuclide_header @@ -296,14 +295,15 @@ contains logical :: rotational ! if rotational periodic BC applied logical :: found ! particle found in universe? class(Surface), pointer :: surf + class(Surface), pointer :: surf2 ! periodic partner surface i_surface = abs(p % surface) surf => surfaces(i_surface) if (verbosity >= 10 .or. trace) then - call write_message(" Crossing surface " // trim(to_str(surf % id))) + call write_message(" Crossing surface " // trim(to_str(surf % id()))) end if - if (surf % bc == BC_VACUUM .and. (run_mode /= MODE_PLOTTING)) then + if (surf % bc() == BC_VACUUM .and. (run_mode /= MODE_PLOTTING)) then ! ======================================================================= ! PARTICLE LEAKS OUT OF PROBLEM @@ -328,11 +328,11 @@ contains ! Display message if (verbosity >= 10 .or. trace) then call write_message(" Leaked out of surface " & - &// trim(to_str(surf % id))) + &// trim(to_str(surf % id()))) end if return - elseif (surf % bc == BC_REFLECT .and. (run_mode /= MODE_PLOTTING)) then + elseif (surf % bc() == BC_REFLECT .and. (run_mode /= MODE_PLOTTING)) then ! ======================================================================= ! PARTICLE REFLECTS FROM SURFACE @@ -355,7 +355,7 @@ contains end if ! Reflect particle off surface - call surface_reflect_c(i_surface-1, p%coord(1)%xyz, p%coord(1)%uvw) + call surf % reflect(p%coord(1)%xyz, p%coord(1)%uvw) ! Make sure new particle direction is normalized u = p%coord(1)%uvw(1) @@ -376,7 +376,7 @@ contains call find_cell(p, found) if (.not. found) then call p % mark_as_lost("Couldn't find particle after reflecting& - & from surface " // trim(to_str(surf % id)) // ".") + & from surface " // trim(to_str(surf % id())) // ".") return end if @@ -386,10 +386,10 @@ contains ! Diagnostic message if (verbosity >= 10 .or. trace) then call write_message(" Reflected from surface " & - &// trim(to_str(surf%id))) + &// trim(to_str(surf%id()))) end if return - elseif (surf % bc == BC_PERIODIC .and. run_mode /= MODE_PLOTTING) then + elseif (surf % bc() == BC_PERIODIC .and. run_mode /= MODE_PLOTTING) then ! ======================================================================= ! PERIODIC BOUNDARY @@ -404,7 +404,6 @@ contains ! Score surface currents since reflection causes the direction of the ! particle to change -- artificially move the particle slightly back in ! case the surface crossing is coincident with a mesh boundary - if (active_current_tallies % size() > 0) then xyz = p % coord(1) % xyz p % coord(1) % xyz = p % coord(1) % xyz - TINY_BIT * p % coord(1) % uvw @@ -412,14 +411,19 @@ contains p % coord(1) % xyz = xyz end if - rotational = surface_periodic_c(i_surface-1, p % coord(1) % xyz, & - p % coord(1) % uvw) + ! Get a pointer to the partner periodic surface. Offset the index to + ! correct for C vs. Fortran indexing. + surf2 => surfaces(surf % i_periodic() + 1) + + ! Adjust the particle's location and direction. + rotational = surf2 % periodic_translate(surf, p % coord(1) % xyz, & + p % coord(1) % uvw) ! Reassign particle's surface if (rotational) then - p % surface = surface_i_periodic_c(i_surface-1) + 1 + p % surface = surf % i_periodic() + 1 else - p % surface = sign(surface_i_periodic_c(i_surface-1) + 1, p % surface) + p % surface = sign(surf % i_periodic() + 1, p % surface) end if ! Figure out what cell particle is in now @@ -427,7 +431,8 @@ contains call find_cell(p, found) if (.not. found) then call p % mark_as_lost("Couldn't find particle after hitting & - &periodic boundary on surface " // trim(to_str(surf % id)) // ".") + &periodic boundary on surface " // trim(to_str(surf % id())) & + // ".") return end if @@ -437,7 +442,7 @@ contains ! Diagnostic message if (verbosity >= 10 .or. trace) then call write_message(" Hit periodic boundary on surface " & - // trim(to_str(surf%id))) + // trim(to_str(surf%id()))) end if return end if @@ -484,7 +489,7 @@ contains if (.not. found) then call p % mark_as_lost("After particle " // trim(to_str(p % id)) & - // " crossed surface " // trim(to_str(surf % id)) & + // " crossed surface " // trim(to_str(surf % id())) & // " it could not be located in any cell and it did not leak.") return end if From ced4c05400d3c3b96f8037366163748cd7ab406d Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 26 Jan 2018 13:24:10 -0600 Subject: [PATCH 19/74] Use contiguous derived MPI type to avoid broadcasting counts > 2**31 - 1 --- CMakeLists.txt | 5 ++++- src/simulation.F90 | 21 ++++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 51bdcc4d9f..8104b5fb1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,9 @@ if($ENV{FC} MATCHES "(mpi[^/]*|ftn)$") message("-- Detected MPI wrapper: $ENV{FC}") add_definitions(-DMPI) set(MPI_ENABLED TRUE) + + # Get directory containing MPI wrapper + get_filename_component(MPI_DIR $ENV{FC} DIRECTORY) endif() # Check for Fortran 2008 MPI interface @@ -552,7 +555,7 @@ foreach(test ${TESTS}) add_test(NAME ${TEST_NAME} WORKING_DIRECTORY ${TEST_PATH} COMMAND ${PYTHON_EXECUTABLE} ${TEST_NAME} --exe $ - --mpi_exec $ENV{MPI_DIR}/bin/mpiexec) + --mpi_exec ${MPI_DIR}/mpiexec) else() # Perform a serial test add_test(NAME ${TEST_NAME} diff --git a/src/simulation.F90 b/src/simulation.F90 index ef29e7832b..061ca2fdae 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -472,8 +472,14 @@ contains #ifdef MPI integer :: n ! size of arrays integer :: mpi_err ! MPI error code + integer :: count_per_filter ! number of result values for one filter bin integer(8) :: temp real(8) :: tempr(3) ! temporary array for communication +#ifdef MPIF08 + type(MPI_Datatype) :: result_block +#else + integer :: result_block +#endif #endif ! Skip if simulation was never run @@ -498,9 +504,18 @@ contains ! Broadcast tally results so that each process has access to results if (allocated(tallies)) then do i = 1, size(tallies) - n = size(tallies(i) % obj % results) - call MPI_BCAST(tallies(i) % obj % results, n, MPI_DOUBLE, 0, & - mpi_intracomm, mpi_err) + associate (results => tallies(i) % obj % results) + ! Create a new datatype that consists of all values for a given filter + ! bin and then use that to broadcast. This is done to minimize the + ! chance of the 'count' argument of MPI_BCAST exceeding 2**31 + n = size(results, 3) + count_per_filter = size(results, 1) * size(results, 2) + call MPI_TYPE_CONTIGUOUS(count_per_filter, MPI_DOUBLE, & + result_block, mpi_err) + call MPI_TYPE_COMMIT(result_block, mpi_err) + call MPI_BCAST(results, n, result_block, 0, mpi_intracomm, mpi_err) + call MPI_TYPE_FREE(result_block, mpi_err) + end associate end do end if From 52905d4364bfead5d1c11fb1acbcd7128d08b95d Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Wed, 31 Jan 2018 15:28:36 -0500 Subject: [PATCH 20/74] Address #959 comments --- src/error.F90 | 6 +- src/error.h | 12 +++ src/hdf5_interface.h | 4 + src/random_lcg.cpp | 5 ++ src/random_lcg.h | 4 + src/surface.cpp | 188 ++++++++++++++++++++--------------------- src/surface.h | 24 ++++-- src/surface_header.F90 | 2 +- src/xml_interface.h | 24 +++--- 9 files changed, 147 insertions(+), 122 deletions(-) diff --git a/src/error.F90 b/src/error.F90 index cba1372917..0a5af302d6 100644 --- a/src/error.F90 +++ b/src/error.F90 @@ -195,9 +195,9 @@ contains end subroutine fatal_error subroutine fatal_error_from_c(message, message_len) bind(C) - integer(C_INT), intent(in), value :: message_len - character(C_CHAR), intent(in) :: message(message_len) - character(message_len+1) :: message_out + integer(C_INT), intent(in), value :: message_len + character(kind=C_CHAR), intent(in) :: message(message_len) + character(message_len+1) :: message_out write(message_out, *) message call fatal_error(message_out) end subroutine diff --git a/src/error.h b/src/error.h index 0fd78a6c5c..4c3373b3e3 100644 --- a/src/error.h +++ b/src/error.h @@ -3,6 +3,10 @@ #include #include +#include + + +namespace openmc { extern "C" void fatal_error_from_c(const char *message, int message_len); @@ -19,4 +23,12 @@ void fatal_error(const std::string &message) fatal_error_from_c(message.c_str(), message.length()); } + +void fatal_error(const std::stringstream &message) +{ + std::string out {message.str()}; + fatal_error_from_c(out.c_str(), out.length()); +} + +} // namespace openmc #endif // ERROR_H diff --git a/src/hdf5_interface.h b/src/hdf5_interface.h index 2cded21f64..7ec9ada9b6 100644 --- a/src/hdf5_interface.h +++ b/src/hdf5_interface.h @@ -9,6 +9,9 @@ #include "error.h" +namespace openmc { + + hid_t create_group(hid_t parent_id, char const *name) { @@ -84,4 +87,5 @@ write_string(hid_t group_id, char const *name, const std::string &buffer) write_string(group_id, name, buffer.c_str()); } +} // namespace openmc #endif //HDF5_INTERFACE_H diff --git a/src/random_lcg.cpp b/src/random_lcg.cpp index 047bda8e54..2dcdd86a36 100644 --- a/src/random_lcg.cpp +++ b/src/random_lcg.cpp @@ -2,6 +2,9 @@ #include +namespace openmc { + + // Constants extern "C" const int N_STREAMS {5}; extern "C" const int STREAM_TRACKING {0}; @@ -143,3 +146,5 @@ openmc_set_seed(int64_t new_seed) } return 0; } + +} // namespace openmc diff --git a/src/random_lcg.h b/src/random_lcg.h index 04191254f3..cd065474ea 100644 --- a/src/random_lcg.h +++ b/src/random_lcg.h @@ -3,6 +3,9 @@ #include + +namespace openmc { + //============================================================================== // Module constants. //============================================================================== @@ -82,4 +85,5 @@ extern "C" void prn_set_stream(int n); extern "C" int openmc_set_seed(int64_t new_seed); +} // namespace openmc #endif // RANDOM_LCG_H diff --git a/src/surface.cpp b/src/surface.cpp index 369334d500..16f333f7e1 100644 --- a/src/surface.cpp +++ b/src/surface.cpp @@ -1,11 +1,15 @@ +#include "surface.h" + #include -#include // For fabs +#include #include "error.h" #include "hdf5_interface.h" #include "xml_interface.h" +#include -#include "surface.h" + +namespace openmc { //============================================================================== // Helper functions for reading the "coeffs" node of an XML surface element @@ -14,7 +18,7 @@ int word_count(const std::string &text) { bool in_word = false; - int count{0}; + int count {0}; for (auto c = text.begin(); c != text.end(); c++) { if (std::isspace(*c)) { if (in_word) { @@ -35,10 +39,9 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1) std::string coeffs = get_node_value(surf_node, "coeffs"); int n_words = word_count(coeffs); if (n_words != 1) { - std::string err_msg{"Surface "}; - err_msg += std::to_string(surf_id); - err_msg += " expects 1 coeff but was given "; - err_msg += std::to_string(n_words); + std::stringstream err_msg; + err_msg << "Surface " << surf_id << " expects 1 coeff but was given " + << n_words; fatal_error(err_msg); } @@ -56,10 +59,9 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2, std::string coeffs = get_node_value(surf_node, "coeffs"); int n_words = word_count(coeffs); if (n_words != 3) { - std::string err_msg{"Surface "}; - err_msg += std::to_string(surf_id); - err_msg += " expects 3 coeffs but was given "; - err_msg += std::to_string(n_words); + std::stringstream err_msg; + err_msg << "Surface " << surf_id << " expects 3 coeffs but was given " + << n_words; fatal_error(err_msg); } @@ -77,10 +79,9 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2, std::string coeffs = get_node_value(surf_node, "coeffs"); int n_words = word_count(coeffs); if (n_words != 4) { - std::string err_msg{"Surface "}; - err_msg += std::to_string(surf_id); - err_msg += " expects 4 coeffs but was given "; - err_msg += std::to_string(n_words); + std::stringstream err_msg; + err_msg << "Surface " << surf_id << " expects 4 coeffs but was given " + << n_words; fatal_error(err_msg); } @@ -99,10 +100,9 @@ void read_coeffs(pugi::xml_node surf_node, int surf_id, double &c1, double &c2, std::string coeffs = get_node_value(surf_node, "coeffs"); int n_words = word_count(coeffs); if (n_words != 10) { - std::string err_msg{"Surface "}; - err_msg += std::to_string(surf_id); - err_msg += " expects 10 coeffs but was given "; - err_msg += std::to_string(n_words); + std::stringstream err_msg; + err_msg << "Surface " << surf_id << " expects 10 coeffs but was given " + << n_words; fatal_error(err_msg); } @@ -133,23 +133,21 @@ Surface::Surface(pugi::xml_node surf_node) if (check_for_node(surf_node, "boundary")) { std::string surf_bc = get_node_value(surf_node, "boundary"); - if (surf_bc.compare("transmission") == 0 - or surf_bc.compare("transmit") == 0 - or surf_bc.compare("") == 0) { + if (surf_bc == "transmission" || surf_bc == "transmit" ||surf_bc.empty()) { bc = BC_TRANSMIT; - } else if (surf_bc.compare("vacuum") == 0) { + } else if (surf_bc == "vacuum") { bc = BC_VACUUM; - } else if (surf_bc.compare("reflective") == 0 - or surf_bc.compare("reflect") == 0 - or surf_bc.compare("reflecting") == 0) { + } else if (surf_bc == "reflective" || surf_bc == "reflect" + || surf_bc == "reflecting") { bc = BC_REFLECT; - } else if (surf_bc.compare("periodic") == 0) { + } else if (surf_bc == "periodic") { bc = BC_PERIODIC; } else { - std::string err_msg("Unknown boundary condition \""); - err_msg += surf_bc + "\" specified on surface " + std::to_string(id); + std::stringstream err_msg; + err_msg << "Unknown boundary condition \"" << surf_bc + << "\" specified on surface " << id; fatal_error(err_msg); } @@ -167,7 +165,7 @@ Surface::sense(const double xyz[3], const double uvw[3]) const const double f = evaluate(xyz); // Check which side of surface the point is on. - if (fabs(f) < FP_COINCIDENT) { + if (std::abs(f) < FP_COINCIDENT) { // Particle may be coincident with this surface. To determine the sense, we // look at the direction of the particle relative to the surface normal (by // default in the positive direction) via their dot product. @@ -197,7 +195,7 @@ Surface::reflect(const double xyz[3], double uvw[3]) const void Surface::to_hdf5(hid_t group_id) const { - std::string group_name{"surface "}; + std::string group_name {"surface "}; group_name += std::to_string(id); hid_t surf_group = create_group(group_id, group_name); @@ -217,7 +215,7 @@ Surface::to_hdf5(hid_t group_id) const break; } - if (name.compare("")) { + if (!name.empty()) { write_string(surf_group, "name", name); } @@ -231,7 +229,7 @@ Surface::to_hdf5(hid_t group_id) const //============================================================================== PeriodicSurface::PeriodicSurface(pugi::xml_node surf_node) - : Surface(surf_node) + : Surface {surf_node} { if (check_for_node(surf_node, "periodic_surface_id")) { i_periodic = stoi(get_node_value(surf_node, "periodic_surface_id")); @@ -255,7 +253,7 @@ axis_aligned_plane_distance(const double xyz[3], const double uvw[3], bool coincident, double offset) { const double f = offset - xyz[i]; - if (coincident or fabs(f) < FP_COINCIDENT or uvw[i] == 0.0) return INFTY; + if (coincident or std::abs(f) < FP_COINCIDENT or uvw[i] == 0.0) return INFTY; const double d = f / uvw[i]; if (d < 0.0) return INFTY; return d; @@ -300,7 +298,7 @@ inline void SurfaceXPlane::normal(const double xyz[3], double uvw[3]) const void SurfaceXPlane::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "x-plane"); - std::array coeffs{{x0}}; + std::array coeffs {{x0}}; write_double_1D(group_id, "coefficients", coeffs); } @@ -320,7 +318,6 @@ bool SurfaceXPlane::periodic_translate(PeriodicSurface *other, double xyz[3], double y0 = -other->evaluate(xyz_test); xyz[1] = xyz[0] - x0 + y0; xyz[0] = x0; - xyz[2] = xyz[2]; double u = uvw[0]; uvw[0] = -uvw[1]; @@ -330,10 +327,10 @@ bool SurfaceXPlane::periodic_translate(PeriodicSurface *other, double xyz[3], } } -struct BoundingBox +BoundingBox SurfaceXPlane::bounding_box() const { - struct BoundingBox out{x0, x0, -INFTY, INFTY, -INFTY, INFTY}; + BoundingBox out {x0, x0, -INFTY, INFTY, -INFTY, INFTY}; return out; } @@ -366,7 +363,7 @@ inline void SurfaceYPlane::normal(const double xyz[3], double uvw[3]) const void SurfaceYPlane::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "y-plane"); - std::array coeffs{{y0}}; + std::array coeffs {{y0}}; write_double_1D(group_id, "coefficients", coeffs); } @@ -396,10 +393,10 @@ bool SurfaceYPlane::periodic_translate(PeriodicSurface *other, double xyz[3], } } -struct BoundingBox +BoundingBox SurfaceYPlane::bounding_box() const { - struct BoundingBox out{-INFTY, INFTY, y0, y0, -INFTY, INFTY}; + BoundingBox out {-INFTY, INFTY, y0, y0, -INFTY, INFTY}; return out; } @@ -432,7 +429,7 @@ inline void SurfaceZPlane::normal(const double xyz[3], double uvw[3]) const void SurfaceZPlane::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "z-plane"); - std::array coeffs{{z0}}; + std::array coeffs {{z0}}; write_double_1D(group_id, "coefficients", coeffs); } @@ -444,10 +441,10 @@ bool SurfaceZPlane::periodic_translate(PeriodicSurface *other, double xyz[3], return false; } -struct BoundingBox +BoundingBox SurfaceZPlane::bounding_box() const { - struct BoundingBox out{-INFTY, INFTY, -INFTY, INFTY, z0, z0}; + BoundingBox out {-INFTY, INFTY, -INFTY, INFTY, z0, z0}; return out; } @@ -473,7 +470,7 @@ SurfacePlane::distance(const double xyz[3], const double uvw[3], { const double f = A*xyz[0] + B*xyz[1] + C*xyz[2] - D; const double projection = A*uvw[0] + B*uvw[1] + C*uvw[2]; - if (coincident or fabs(f) < FP_COINCIDENT or projection == 0.0) { + if (coincident or std::abs(f) < FP_COINCIDENT or projection == 0.0) { return INFTY; } else { const double d = -f / projection; @@ -493,7 +490,7 @@ SurfacePlane::normal(const double xyz[3], double uvw[3]) const void SurfacePlane::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "plane"); - std::array coeffs{{A, B, C, D}}; + std::array coeffs {{A, B, C, D}}; write_double_1D(group_id, "coefficients", coeffs); } @@ -513,10 +510,10 @@ bool SurfacePlane::periodic_translate(PeriodicSurface *other, double xyz[3], return false; } -struct BoundingBox +BoundingBox SurfacePlane::bounding_box() const { - struct BoundingBox out{-INFTY, INFTY, -INFTY, INFTY, -INFTY, INFTY}; + BoundingBox out {-INFTY, INFTY, -INFTY, INFTY, -INFTY, INFTY}; return out; } @@ -556,7 +553,7 @@ axis_aligned_cylinder_distance(const double xyz[3], const double uvw[3], // No intersection with cylinder. return INFTY; - } else if (coincident or fabs(c) < FP_COINCIDENT) { + } else if (coincident or std::abs(c) < FP_COINCIDENT) { // Particle is on the cylinder, thus one distance is positive/negative // and the other is zero. The sign of k determines if we are facing in or // out. @@ -625,7 +622,7 @@ inline void SurfaceXCylinder::normal(const double xyz[3], double uvw[3]) const void SurfaceXCylinder::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "x-cylinder"); - std::array coeffs{{y0, z0, r}}; + std::array coeffs {{y0, z0, r}}; write_double_1D(group_id, "coefficients", coeffs); } @@ -659,7 +656,7 @@ inline void SurfaceYCylinder::normal(const double xyz[3], double uvw[3]) const void SurfaceYCylinder::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "y-cylinder"); - std::array coeffs{{x0, z0, r}}; + std::array coeffs {{x0, z0, r}}; write_double_1D(group_id, "coefficients", coeffs); } @@ -693,7 +690,7 @@ inline void SurfaceZCylinder::normal(const double xyz[3], double uvw[3]) const void SurfaceZCylinder::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "z-cylinder"); - std::array coeffs{{x0, y0, r}}; + std::array coeffs {{x0, y0, r}}; write_double_1D(group_id, "coefficients", coeffs); } @@ -729,7 +726,7 @@ double SurfaceSphere::distance(const double xyz[3], const double uvw[3], // No intersection with sphere. return INFTY; - } else if (coincident or fabs(c) < FP_COINCIDENT) { + } else if (coincident or std::abs(c) < FP_COINCIDENT) { // Particle is on the sphere, thus one distance is positive/negative and // the other is zero. The sign of k determines if we are facing in or out. if (k >= 0.0) { @@ -764,7 +761,7 @@ inline void SurfaceSphere::normal(const double xyz[3], double uvw[3]) const void SurfaceSphere::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "sphere"); - std::array coeffs{{x0, y0, z0, r}}; + std::array coeffs {{x0, y0, z0, r}}; write_double_1D(group_id, "coefficients", coeffs); } @@ -808,7 +805,7 @@ axis_aligned_cone_distance(const double xyz[3], const double uvw[3], // No intersection with cone. return INFTY; - } else if (coincident or fabs(c) < FP_COINCIDENT) { + } else if (coincident or std::abs(c) < FP_COINCIDENT) { // Particle is on the cone, thus one distance is positive/negative // and the other is zero. The sign of k determines if we are facing in or // out. @@ -881,7 +878,7 @@ inline void SurfaceXCone::normal(const double xyz[3], double uvw[3]) const void SurfaceXCone::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "x-cone"); - std::array coeffs{{x0, y0, z0, r_sq}}; + std::array coeffs {{x0, y0, z0, r_sq}}; write_double_1D(group_id, "coefficients", coeffs); } @@ -915,7 +912,7 @@ inline void SurfaceYCone::normal(const double xyz[3], double uvw[3]) const void SurfaceYCone::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "y-cone"); - std::array coeffs{{x0, y0, z0, r_sq}}; + std::array coeffs {{x0, y0, z0, r_sq}}; write_double_1D(group_id, "coefficients", coeffs); } @@ -949,7 +946,7 @@ inline void SurfaceZCone::normal(const double xyz[3], double uvw[3]) const void SurfaceZCone::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "z-cone"); - std::array coeffs{{x0, y0, z0, r_sq}}; + std::array coeffs {{x0, y0, z0, r_sq}}; write_double_1D(group_id, "coefficients", coeffs); } @@ -998,7 +995,7 @@ SurfaceQuadric::distance(const double xyz[3], // No intersection with surface. return INFTY; - } else if (coincident or fabs(c) < FP_COINCIDENT) { + } else if (coincident or std::abs(c) < FP_COINCIDENT) { // Particle is on the surface, thus one distance is positive/negative and // the other is zero. The sign of k determines which distance is zero and // which is not. @@ -1043,7 +1040,7 @@ SurfaceQuadric::normal(const double xyz[3], double uvw[3]) const void SurfaceQuadric::to_hdf5_inner(hid_t group_id) const { write_string(group_id, "type", "quadric"); - std::array coeffs{{A, B, C, D, E, F, G, H, J, K}}; + std::array coeffs {{A, B, C, D, E, F, G, H, J, K}}; write_double_1D(group_id, "coefficients", coeffs); } @@ -1053,10 +1050,7 @@ extern "C" void read_surfaces(pugi::xml_node *node) { // Count the number of surfaces. - for (pugi::xml_node surf_node = node->child("surface"); surf_node; - surf_node = surf_node.next_sibling("surface")) { - n_surfaces++; - } + for (pugi::xml_node surf_node: node->children("surface")) {n_surfaces++;} if (n_surfaces == 0) { fatal_error("No surfaces found in geometry.xml!"); } @@ -1072,46 +1066,45 @@ read_surfaces(pugi::xml_node *node) surf_node = surf_node.next_sibling("surface"), i_surf++) { std::string surf_type = get_node_value(surf_node, "type"); - if (surf_type.compare("x-plane") == 0) { + if (surf_type == "x-plane") { surfaces_c[i_surf] = new SurfaceXPlane(surf_node); - } else if (surf_type.compare("y-plane") == 0) { + } else if (surf_type == "y-plane") { surfaces_c[i_surf] = new SurfaceYPlane(surf_node); - } else if (surf_type.compare("z-plane") == 0) { + } else if (surf_type == "z-plane") { surfaces_c[i_surf] = new SurfaceZPlane(surf_node); - } else if (surf_type.compare("plane") == 0) { + } else if (surf_type == "plane") { surfaces_c[i_surf] = new SurfacePlane(surf_node); - } else if (surf_type.compare("x-cylinder") == 0) { + } else if (surf_type == "x-cylinder") { surfaces_c[i_surf] = new SurfaceXCylinder(surf_node); - } else if (surf_type.compare("y-cylinder") == 0) { + } else if (surf_type == "y-cylinder") { surfaces_c[i_surf] = new SurfaceYCylinder(surf_node); - } else if (surf_type.compare("z-cylinder") == 0) { + } else if (surf_type == "z-cylinder") { surfaces_c[i_surf] = new SurfaceZCylinder(surf_node); - } else if (surf_type.compare("sphere") == 0) { + } else if (surf_type == "sphere") { surfaces_c[i_surf] = new SurfaceSphere(surf_node); - } else if (surf_type.compare("x-cone") == 0) { + } else if (surf_type == "x-cone") { surfaces_c[i_surf] = new SurfaceXCone(surf_node); - } else if (surf_type.compare("y-cone") == 0) { + } else if (surf_type == "y-cone") { surfaces_c[i_surf] = new SurfaceYCone(surf_node); - } else if (surf_type.compare("z-cone") == 0) { + } else if (surf_type == "z-cone") { surfaces_c[i_surf] = new SurfaceZCone(surf_node); - } else if (surf_type.compare("quadric") == 0) { + } else if (surf_type == "quadric") { surfaces_c[i_surf] = new SurfaceQuadric(surf_node); } else { - std::string err_msg{"Invalid surface type, \""}; - err_msg += surf_type; - err_msg += "\""; + std::stringstream err_msg; + err_msg << "Invalid surface type, \"" << surf_type << "\""; fatal_error(err_msg); } } @@ -1124,15 +1117,15 @@ read_surfaces(pugi::xml_node *node) if (in_dict == surface_dict.end()) { surface_dict[id] = i_surf; } else { - std::string err_msg{"Two or more surfaces use the same unique ID: "}; - err_msg += std::to_string(id); + std::stringstream err_msg; + err_msg << "Two or more surfaces use the same unique ID: " << id; fatal_error(err_msg); } } // Find the global bounding box (of periodic BC surfaces). - double xmin{INFTY}, xmax{-INFTY}, ymin{INFTY}, ymax{-INFTY}, - zmin{INFTY}, zmax{-INFTY}; + double xmin {INFTY}, xmax {-INFTY}, ymin {INFTY}, ymax {-INFTY}, + zmin {INFTY}, zmax {-INFTY}; int i_xmin, i_xmax, i_ymin, i_ymax, i_zmin, i_zmax; for (int i_surf = 0; i_surf < n_surfaces; i_surf++) { if (surfaces_c[i_surf]->bc == BC_PERIODIC) { @@ -1141,15 +1134,16 @@ read_surfaces(pugi::xml_node *node) PeriodicSurface *surf = dynamic_cast(surf_base); // Make sure this surface inherits from PeriodicSurface. - if (surf == NULL) { - std::string err_msg{"Periodic boundary condition not supported for " - "surface "}; - err_msg += std::to_string(surf_base->id); - err_msg += ". Periodic BCs are only supported for planar surfaces."; + if (!surf) { + std::stringstream err_msg; + err_msg << "Periodic boundary condition not supported for surface " + << surf_base->id + << ". Periodic BCs are only supported for planar surfaces."; + fatal_error(err_msg); } // See if this surface makes part of the global bounding box. - struct BoundingBox bb = surf->bounding_box(); + BoundingBox bb = surf->bounding_box(); if (bb.xmin > -INFTY and bb.xmin < xmin) { xmin = bb.xmin; i_xmin = i_surf; @@ -1188,7 +1182,7 @@ read_surfaces(pugi::xml_node *node) // differently). SurfacePlane *surf_p = dynamic_cast(surf); - if (surf_p == NULL) { + if (!surf_p) { // This is not a SurfacePlane. if (surf->i_periodic == C_NONE) { // The user did not specify the matching periodic surface. See if we @@ -1217,9 +1211,9 @@ read_surfaces(pugi::xml_node *node) // This is a SurfacePlane. We won't try to find it's partner if the // user didn't specify one. if (surf->i_periodic == C_NONE) { - std::string err_msg{"No matching periodic surface specified for " - "periodic boundary condition on surface "}; - err_msg += std::to_string(surf->id); + std::stringstream err_msg; + err_msg << "No matching periodic surface specified for periodic " + "boundary condition on surface " << surf->id; fatal_error(err_msg); } else { // Convert the surface id to an index. @@ -1229,11 +1223,13 @@ read_surfaces(pugi::xml_node *node) // Make sure the opposite surface is also periodic. if (surfaces_c[surf->i_periodic]->bc != BC_PERIODIC) { - std::string err_msg{"Could not find matching surface for periodic " - "boundary condition on surface "}; - err_msg += std::to_string(surf->id); + std::stringstream err_msg; + err_msg << "Could not find matching surface for periodic boundary " + "condition on surface " << surf->id; fatal_error(err_msg); } } } } + +} // namespace openmc diff --git a/src/surface.h b/src/surface.h index 469d884862..72cfd62023 100644 --- a/src/surface.h +++ b/src/surface.h @@ -3,32 +3,37 @@ #include #include // For numeric_limits +#include #include "hdf5.h" #include "pugixml/pugixml.hpp" + +namespace openmc { + //============================================================================== // Module constants //============================================================================== -extern "C" const int BC_TRANSMIT{0}; -extern "C" const int BC_VACUUM{1}; -extern "C" const int BC_REFLECT{2}; -extern "C" const int BC_PERIODIC{3}; +extern "C" const int BC_TRANSMIT {0}; +extern "C" const int BC_VACUUM {1}; +extern "C" const int BC_REFLECT {2}; +extern "C" const int BC_PERIODIC {3}; //============================================================================== // Constants that should eventually be moved out of this file //============================================================================== extern "C" double FP_COINCIDENT; -const double INFTY{std::numeric_limits::max()}; -const int C_NONE{-1}; +constexpr double INFTY{std::numeric_limits::max()}; +constexpr int C_NONE {-1}; //============================================================================== // Global variables //============================================================================== -int n_surfaces{0}; +// Braces force n_surfaces to be defined here, not just declared. +extern "C" {int32_t n_surfaces {0};} class Surface; Surface **surfaces_c; @@ -64,6 +69,8 @@ public: Surface(pugi::xml_node surf_node); + virtual ~Surface() {} + //! Determine which side of a surface a point lies on. //! @param xyz[3] The 3D Cartesian coordinate of a point. //! @param uvw[3] A direction used to "break ties" and pick a sense when the @@ -411,9 +418,10 @@ extern "C" void free_memory_surfaces_c() { for (int i = 0; i < n_surfaces; i++) {delete surfaces_c[i];} delete surfaces_c; - surfaces_c = NULL; + surfaces_c = nullptr; n_surfaces = 0; surface_dict.clear(); } +} // namespace openmc #endif // SURFACE_H diff --git a/src/surface_header.F90 b/src/surface_header.F90 index 8985e8406e..9ed89a14e9 100644 --- a/src/surface_header.F90 +++ b/src/surface_header.F90 @@ -126,7 +126,7 @@ module surface_header end type Surface - integer(C_INT), bind(C) :: n_surfaces ! # of surfaces + integer(C_INT32_T), bind(C) :: n_surfaces ! # of surfaces type(Surface), allocatable, target :: surfaces(:) diff --git a/src/xml_interface.h b/src/xml_interface.h index fbc82e056b..778497562b 100644 --- a/src/xml_interface.h +++ b/src/xml_interface.h @@ -2,26 +2,23 @@ #define XML_INTERFACE_H #include // for std::transform +#include #include #include "pugixml/pugixml.hpp" +namespace openmc { + bool -check_for_node(const pugi::xml_node &node, const char *name) +check_for_node(pugi::xml_node node, const char *name) { - if (node.attribute(name)) { - return true; - } else if (node.child(name)) { - return true; - } else { - return false; - } + return node.attribute(name) || node.child(name); } std::string -get_node_value(const pugi::xml_node &node, const char *name) +get_node_value(pugi::xml_node node, const char *name) { // Search for either an attribute or child tag and get the data as a char*. const pugi::char_t *value_char; @@ -30,11 +27,9 @@ get_node_value(const pugi::xml_node &node, const char *name) } else if (node.child(name)) { value_char = node.child_value(name); } else { - std::string err_msg("Node \""); - err_msg += name; - err_msg += "\" is not a memeber of the \""; - err_msg += node.name(); - err_msg += "\" XML node"; + std::stringstream err_msg; + err_msg << "Node \"" << name << "\" is not a member of the \"" + << node.name() << "\" XML node"; fatal_error(err_msg); } @@ -49,4 +44,5 @@ get_node_value(const pugi::xml_node &node, const char *name) return value; } +} // namespace openmc #endif // XML_INTERFACE_H From 48ac683a0cec3724c80629ac549a0eb4a4f7b4d1 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Wed, 31 Jan 2018 17:52:52 -0500 Subject: [PATCH 21/74] Remove C++/Fortran interoperable "seed" --- openmc/capi/settings.py | 5 ++--- src/api.F90 | 10 +++++----- src/initialize.F90 | 3 +-- src/input_xml.F90 | 2 +- src/random_lcg.F90 | 13 ++++++++----- src/random_lcg.cpp | 5 +++-- src/random_lcg.h | 8 +++++++- src/state_point.F90 | 6 ++++-- tests/unit_tests/test_capi.py | 10 +++++----- 9 files changed, 36 insertions(+), 26 deletions(-) diff --git a/openmc/capi/settings.py b/openmc/capi/settings.py index eede6cf47b..1063d6463e 100644 --- a/openmc/capi/settings.py +++ b/openmc/capi/settings.py @@ -11,8 +11,7 @@ _RUN_MODES = {1: 'fixed source', 5: 'volume'} _dll.openmc_set_seed.argtypes = [c_int64] -_dll.openmc_set_seed.restype = c_int -_dll.openmc_set_seed.errcheck = _error_handler +_dll.openmc_get_seed.restype = c_int64 class _Settings(object): @@ -43,7 +42,7 @@ class _Settings(object): @property def seed(self): - return c_int64.in_dll(_dll, 'seed').value + return _dll.openmc_get_seed() @seed.setter def seed(self, seed): diff --git a/src/api.F90 b/src/api.F90 index 5d56b857ca..f07e5e38a5 100644 --- a/src/api.F90 +++ b/src/api.F90 @@ -18,7 +18,7 @@ module openmc_api use initialize, only: openmc_init use particle_header, only: Particle use plot, only: openmc_plot_geometry - use random_lcg, only: seed, openmc_set_seed + use random_lcg, only: openmc_get_seed, openmc_set_seed use settings use simulation_header use source_header, only: openmc_extend_sources, openmc_source_set_strength @@ -60,6 +60,7 @@ module openmc_api public :: openmc_get_filter_next_id public :: openmc_get_material_index public :: openmc_get_nuclide_index + public :: openmc_get_seed public :: openmc_get_tally_index public :: openmc_global_tallies public :: openmc_hard_reset @@ -79,6 +80,7 @@ module openmc_api public :: openmc_plot_geometry public :: openmc_reset public :: openmc_run + public :: openmc_set_seed public :: openmc_simulation_finalize public :: openmc_simulation_init public :: openmc_source_bank @@ -142,7 +144,7 @@ contains run_CE = .true. run_mode = NONE satisfy_triggers = .false. - seed = 1_8 + call openmc_set_seed(DEFAULT_SEED) source_latest = .false. source_separate = .false. source_write = .true. @@ -228,8 +230,6 @@ contains !=============================================================================== subroutine openmc_hard_reset() bind(C) - integer :: err - ! Reset all tallies and timers call openmc_reset() @@ -238,7 +238,7 @@ contains total_gen = 0 ! Reset the random number generator state - err = openmc_set_seed(1_8) + call openmc_set_seed(DEFAULT_SEED) end subroutine openmc_hard_reset !=============================================================================== diff --git a/src/initialize.F90 b/src/initialize.F90 index 2af93627ea..7b699b9cb7 100644 --- a/src/initialize.F90 +++ b/src/initialize.F90 @@ -44,7 +44,6 @@ contains subroutine openmc_init(intracomm) bind(C) integer, intent(in), optional :: intracomm ! MPI intracommunicator - integer :: err #ifdef _OPENMP character(MAX_WORD_LEN) :: envvar #endif @@ -95,7 +94,7 @@ contains ! Initialize random number generator -- if the user specifies a seed, it ! will be re-initialized later - err = openmc_set_seed(DEFAULT_SEED) + call openmc_set_seed(DEFAULT_SEED) ! Read XML input files call read_input_xml() diff --git a/src/input_xml.F90 b/src/input_xml.F90 index 55eeca9e14..0b7790a51c 100644 --- a/src/input_xml.F90 +++ b/src/input_xml.F90 @@ -349,7 +349,7 @@ contains ! Copy random number seed if specified if (check_for_node(root, "seed")) then call get_node_value(root, "seed", seed) - err = openmc_set_seed(seed) + call openmc_set_seed(seed) end if ! Number of bins for logarithmic grid diff --git a/src/random_lcg.F90 b/src/random_lcg.F90 index 839bd729a9..d64717cf42 100644 --- a/src/random_lcg.F90 +++ b/src/random_lcg.F90 @@ -4,8 +4,6 @@ module random_lcg implicit none - integer(C_INT64_T), bind(C) :: seed - interface function prn() result(pseudo_rn) bind(C) use ISO_C_BINDING @@ -38,11 +36,16 @@ module random_lcg integer(C_INT), value :: n end subroutine prn_set_stream - function openmc_set_seed(new_seed) result(err) bind(C) + function openmc_get_seed() result(seed) bind(C) + use ISO_C_BINDING + implicit none + integer(C_INT64_T) :: seed + end function openmc_get_seed + + subroutine openmc_set_seed(new_seed) bind(C) use ISO_C_BINDING implicit none integer(C_INT64_T), value :: new_seed - integer(C_INT) :: err - end function openmc_set_seed + end subroutine openmc_set_seed end interface end module random_lcg diff --git a/src/random_lcg.cpp b/src/random_lcg.cpp index 2dcdd86a36..2a57316cb6 100644 --- a/src/random_lcg.cpp +++ b/src/random_lcg.cpp @@ -133,7 +133,9 @@ prn_set_stream(int i) // API FUNCTIONS //============================================================================== -extern "C" int +extern "C" int64_t openmc_get_seed() {return seed;} + +extern "C" void openmc_set_seed(int64_t new_seed) { seed = new_seed; @@ -144,7 +146,6 @@ openmc_set_seed(int64_t new_seed) } prn_set_stream(STREAM_TRACKING); } - return 0; } } // namespace openmc diff --git a/src/random_lcg.h b/src/random_lcg.h index cd065474ea..29b3fca47d 100644 --- a/src/random_lcg.h +++ b/src/random_lcg.h @@ -77,13 +77,19 @@ extern "C" void prn_set_stream(int n); // API FUNCTIONS //============================================================================== +//============================================================================== +//! Get OpenMC's master seed. +//============================================================================== + +extern "C" int64_t openmc_get_seed(); + //============================================================================== //! Set OpenMC's master seed. //! @param new_seed The master seed. All other seeds will be derived from this //! one. //============================================================================== -extern "C" int openmc_set_seed(int64_t new_seed); +extern "C" void openmc_set_seed(int64_t new_seed); } // namespace openmc #endif // RANDOM_LCG_H diff --git a/src/state_point.F90 b/src/state_point.F90 index ba7bcef19d..980a7333cd 100644 --- a/src/state_point.F90 +++ b/src/state_point.F90 @@ -26,7 +26,7 @@ module state_point use mgxs_header, only: nuclides_MG use nuclide_header, only: nuclides use output, only: time_stamp - use random_lcg, only: seed + use random_lcg, only: openmc_get_seed, openmc_set_seed use settings use simulation_header use string, only: to_str, count_digits, zero_padded, to_f_string @@ -97,7 +97,7 @@ contains call write_attribute(file_id, "path", path_input) ! Write out random number seed - call write_dataset(file_id, "seed", seed) + call write_dataset(file_id, "seed", openmc_get_seed()) ! Write run information if (run_CE) then @@ -642,6 +642,7 @@ contains integer :: n integer :: int_array(3) integer, allocatable :: array(:) + integer(C_INT64_T) :: seed integer(HID_T) :: file_id integer(HID_T) :: cmfd_group integer(HID_T) :: tallies_group @@ -672,6 +673,7 @@ contains ! Read and overwrite random number seed call read_dataset(seed, file_id, "seed") + call openmc_set_seed(seed) ! It is not impossible for a state point to be generated from a CE run but ! to be loaded in to an MG run (or vice versa), check to prevent that. diff --git a/tests/unit_tests/test_capi.py b/tests/unit_tests/test_capi.py index ba9ac5c9e0..cd24314ad3 100644 --- a/tests/unit_tests/test_capi.py +++ b/tests/unit_tests/test_capi.py @@ -29,11 +29,11 @@ def pincell_model(): yield # Delete generated files - files = ['geometry.xml', 'materials.xml', 'settings.xml', 'tallies.xml', - 'statepoint.10.h5', 'summary.h5', 'test_sp.h5'] - for f in files: - if os.path.exists(f): - os.remove(f) + #files = ['geometry.xml', 'materials.xml', 'settings.xml', 'tallies.xml', + # 'statepoint.10.h5', 'summary.h5', 'test_sp.h5'] + #for f in files: + # if os.path.exists(f): + # os.remove(f) @pytest.fixture(scope='module') From 7acf3f91dbb74c7ca0aad9bedfc2cdc14c2c2463 Mon Sep 17 00:00:00 2001 From: Sterling Harper Date: Fri, 2 Feb 2018 19:56:23 -0500 Subject: [PATCH 22/74] Address #959 comments --- src/surface.cpp | 2 +- src/surface.h | 38 +++++++++++++++++------------------ tests/unit_tests/test_capi.py | 10 ++++----- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/surface.cpp b/src/surface.cpp index 16f333f7e1..9abfd23d2e 100644 --- a/src/surface.cpp +++ b/src/surface.cpp @@ -1,12 +1,12 @@ #include "surface.h" #include +#include #include #include "error.h" #include "hdf5_interface.h" #include "xml_interface.h" -#include namespace openmc { diff --git a/src/surface.h b/src/surface.h index 72cfd62023..627a8fbae2 100644 --- a/src/surface.h +++ b/src/surface.h @@ -67,7 +67,7 @@ public: int bc; //!< Boundary condition std::string name{""}; //!< User-defined name - Surface(pugi::xml_node surf_node); + explicit Surface(pugi::xml_node surf_node); virtual ~Surface() {} @@ -127,7 +127,7 @@ class PeriodicSurface : public Surface public: int i_periodic{C_NONE}; //!< Index of corresponding periodic surface - PeriodicSurface(pugi::xml_node surf_node); + explicit PeriodicSurface(pugi::xml_node surf_node); //! Translate a particle onto this surface from a periodic partner surface. //! @param other A pointer to the partner surface in this periodic BC. @@ -141,7 +141,7 @@ public: double uvw[3]) const = 0; //! Get the bounding box for this surface. - virtual struct BoundingBox bounding_box() const = 0; + virtual BoundingBox bounding_box() const = 0; }; //============================================================================== @@ -154,7 +154,7 @@ class SurfaceXPlane : public PeriodicSurface { double x0; public: - SurfaceXPlane(pugi::xml_node surf_node); + explicit SurfaceXPlane(pugi::xml_node surf_node); double evaluate(const double xyz[3]) const; double distance(const double xyz[3], const double uvw[3], bool coincident) const; @@ -162,7 +162,7 @@ public: void to_hdf5_inner(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; - struct BoundingBox bounding_box() const; + BoundingBox bounding_box() const; }; //============================================================================== @@ -175,7 +175,7 @@ class SurfaceYPlane : public PeriodicSurface { double y0; public: - SurfaceYPlane(pugi::xml_node surf_node); + explicit SurfaceYPlane(pugi::xml_node surf_node); double evaluate(const double xyz[3]) const; double distance(const double xyz[3], const double uvw[3], bool coincident) const; @@ -183,7 +183,7 @@ public: void to_hdf5_inner(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; - struct BoundingBox bounding_box() const; + BoundingBox bounding_box() const; }; //============================================================================== @@ -196,7 +196,7 @@ class SurfaceZPlane : public PeriodicSurface { double z0; public: - SurfaceZPlane(pugi::xml_node surf_node); + explicit SurfaceZPlane(pugi::xml_node surf_node); double evaluate(const double xyz[3]) const; double distance(const double xyz[3], const double uvw[3], bool coincident) const; @@ -204,7 +204,7 @@ public: void to_hdf5_inner(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; - struct BoundingBox bounding_box() const; + BoundingBox bounding_box() const; }; //============================================================================== @@ -217,7 +217,7 @@ class SurfacePlane : public PeriodicSurface { double A, B, C, D; public: - SurfacePlane(pugi::xml_node surf_node); + explicit SurfacePlane(pugi::xml_node surf_node); double evaluate(const double xyz[3]) const; double distance(const double xyz[3], const double uvw[3], bool coincident) const; @@ -225,7 +225,7 @@ public: void to_hdf5_inner(hid_t group_id) const; bool periodic_translate(PeriodicSurface *other, double xyz[3], double uvw[3]) const; - struct BoundingBox bounding_box() const; + BoundingBox bounding_box() const; }; //============================================================================== @@ -239,7 +239,7 @@ class SurfaceXCylinder : public Surface { double y0, z0, r; public: - SurfaceXCylinder(pugi::xml_node surf_node); + explicit SurfaceXCylinder(pugi::xml_node surf_node); double evaluate(const double xyz[3]) const; double distance(const double xyz[3], const double uvw[3], bool coincident) const; @@ -258,7 +258,7 @@ class SurfaceYCylinder : public Surface { double x0, z0, r; public: - SurfaceYCylinder(pugi::xml_node surf_node); + explicit SurfaceYCylinder(pugi::xml_node surf_node); double evaluate(const double xyz[3]) const; double distance(const double xyz[3], const double uvw[3], bool coincident) const; @@ -277,7 +277,7 @@ class SurfaceZCylinder : public Surface { double x0, y0, r; public: - SurfaceZCylinder(pugi::xml_node surf_node); + explicit SurfaceZCylinder(pugi::xml_node surf_node); double evaluate(const double xyz[3]) const; double distance(const double xyz[3], const double uvw[3], bool coincident) const; @@ -296,7 +296,7 @@ class SurfaceSphere : public Surface { double x0, y0, z0, r; public: - SurfaceSphere(pugi::xml_node surf_node); + explicit SurfaceSphere(pugi::xml_node surf_node); double evaluate(const double xyz[3]) const; double distance(const double xyz[3], const double uvw[3], bool coincident) const; @@ -315,7 +315,7 @@ class SurfaceXCone : public Surface { double x0, y0, z0, r_sq; public: - SurfaceXCone(pugi::xml_node surf_node); + explicit SurfaceXCone(pugi::xml_node surf_node); double evaluate(const double xyz[3]) const; double distance(const double xyz[3], const double uvw[3], bool coincident) const; @@ -334,7 +334,7 @@ class SurfaceYCone : public Surface { double x0, y0, z0, r_sq; public: - SurfaceYCone(pugi::xml_node surf_node); + explicit SurfaceYCone(pugi::xml_node surf_node); double evaluate(const double xyz[3]) const; double distance(const double xyz[3], const double uvw[3], bool coincident) const; @@ -353,7 +353,7 @@ class SurfaceZCone : public Surface { double x0, y0, z0, r_sq; public: - SurfaceZCone(pugi::xml_node surf_node); + explicit SurfaceZCone(pugi::xml_node surf_node); double evaluate(const double xyz[3]) const; double distance(const double xyz[3], const double uvw[3], bool coincident) const; @@ -372,7 +372,7 @@ class SurfaceQuadric : public Surface // Ax^2 + By^2 + Cz^2 + Dxy + Eyz + Fxz + Gx + Hy + Jz + K = 0 double A, B, C, D, E, F, G, H, J, K; public: - SurfaceQuadric(pugi::xml_node surf_node); + explicit SurfaceQuadric(pugi::xml_node surf_node); double evaluate(const double xyz[3]) const; double distance(const double xyz[3], const double uvw[3], bool coincident) const; diff --git a/tests/unit_tests/test_capi.py b/tests/unit_tests/test_capi.py index cd24314ad3..ba9ac5c9e0 100644 --- a/tests/unit_tests/test_capi.py +++ b/tests/unit_tests/test_capi.py @@ -29,11 +29,11 @@ def pincell_model(): yield # Delete generated files - #files = ['geometry.xml', 'materials.xml', 'settings.xml', 'tallies.xml', - # 'statepoint.10.h5', 'summary.h5', 'test_sp.h5'] - #for f in files: - # if os.path.exists(f): - # os.remove(f) + files = ['geometry.xml', 'materials.xml', 'settings.xml', 'tallies.xml', + 'statepoint.10.h5', 'summary.h5', 'test_sp.h5'] + for f in files: + if os.path.exists(f): + os.remove(f) @pytest.fixture(scope='module') From cb076c8e4fa81b45e09de37be41362cf17c1d1c9 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sat, 3 Feb 2018 12:38:01 -0600 Subject: [PATCH 23/74] Update ifdef for MPI F08 --- src/simulation.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simulation.F90 b/src/simulation.F90 index faf3c4016a..424c55e9bd 100644 --- a/src/simulation.F90 +++ b/src/simulation.F90 @@ -475,7 +475,7 @@ contains integer :: count_per_filter ! number of result values for one filter bin integer(8) :: temp real(8) :: tempr(3) ! temporary array for communication -#ifdef MPIF08 +#ifdef OPENMC_MPIF08 type(MPI_Datatype) :: result_block #else integer :: result_block From 894ec54ad7659194ed53cc806444e88cd164d649 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 23 Jan 2018 23:01:03 -0600 Subject: [PATCH 24/74] Add unit tests for material classes --- openmc/material.py | 6 +- tests/unit_tests/test_material.py | 128 ++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 tests/unit_tests/test_material.py diff --git a/openmc/material.py b/openmc/material.py index e22fe0b8ba..a59fdaa285 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -15,7 +15,7 @@ from .mixin import IDManagerMixin # Units for density supported by OpenMC -DENSITY_UNITS = ['g/cm3', 'g/cc', 'kg/cm3', 'atom/b-cm', 'atom/cm3', 'sum', +DENSITY_UNITS = ['g/cm3', 'g/cc', 'kg/m3', 'atom/b-cm', 'atom/cm3', 'sum', 'macro'] @@ -49,7 +49,7 @@ class Material(IDManagerMixin): density : float Density of the material (units defined separately) density_units : str - Units used for `density`. Can be one of 'g/cm3', 'g/cc', 'kg/cm3', + Units used for `density`. Can be one of 'g/cm3', 'g/cc', 'kg/m3', 'atom/b-cm', 'atom/cm3', 'sum', or 'macro'. The 'macro' unit only applies in the case of a multi-group calculation. depletable : bool @@ -312,7 +312,7 @@ class Material(IDManagerMixin): Parameters ---------- - units : {'g/cm3', 'g/cc', 'kg/cm3', 'atom/b-cm', 'atom/cm3', 'sum', 'macro'} + units : {'g/cm3', 'g/cc', 'kg/m3', 'atom/b-cm', 'atom/cm3', 'sum', 'macro'} Physical units of density. density : float, optional Value of the density. Must be specified unless units is given as diff --git a/tests/unit_tests/test_material.py b/tests/unit_tests/test_material.py new file mode 100644 index 0000000000..46241e83df --- /dev/null +++ b/tests/unit_tests/test_material.py @@ -0,0 +1,128 @@ +import openmc +import pytest + + +@pytest.fixture(scope='module') +def uo2(): + m = openmc.Material(material_id=100, name='UO2') + m.add_nuclide('U235', 1.0) + m.add_nuclide('O16', 2.0) + m.set_density('g/cm3', 10.0) + m.depletable = True + return m + + +def test_attributes(uo2): + assert uo2.name == 'UO2' + assert uo2.id == 100 + assert uo2.depletable + + +def test_nuclides(uo2): + """Test adding/removing nuclides.""" + m = openmc.Material() + m.add_nuclide('U235', 1.0) + with pytest.raises(ValueError): + m.add_nuclide('H1', '1.0') + with pytest.raises(ValueError): + m.add_nuclide(1.0, 'H1') + with pytest.raises(ValueError): + m.add_nuclide('H1', 1.0, 'oa') + m.remove_nuclide('U235') + + +def test_elements(): + """Test adding elements.""" + m = openmc.Material() + m.add_element('Zr', 1.0) + m.add_element('U', 1.0, enrichment=4.5) + with pytest.raises(ValueError): + m.add_element('U', 1.0, enrichment=100.0) + with pytest.raises(ValueError): + m.add_element('Pu', 1.0, enrichment=3.0) + + +def test_density(): + m = openmc.Material() + for unit in ['g/cm3', 'g/cc', 'kg/m3', 'atom/b-cm', 'atom/cm3']: + m.set_density(unit, 1.0) + with pytest.raises(ValueError): + m.set_density('g/litre', 1.0) + + +def test_salphabeta(): + m = openmc.Material() + m.add_s_alpha_beta('c_H_in_H2O', 0.5) + + +def test_repr(): + m = openmc.Material() + m.add_nuclide('Zr90', 1.0) + m.add_nuclide('H2', 0.5) + m.add_s_alpha_beta('c_D_in_D2O') + m.set_density('sum') + m.temperature = 600.0 + repr(m) + + +def test_macroscopic(): + m = openmc.Material(name='UO2') + m.add_macroscopic('UO2') + with pytest.raises(ValueError): + m.add_nuclide('H1', 1.0) + with pytest.raises(ValueError): + m.add_element('O', 1.0) + with pytest.raises(ValueError): + m.add_macroscopic('Other') + + m2 = openmc.Material() + m2.add_nuclide('He4', 1.0) + with pytest.raises(ValueError): + m2.add_macroscopic('UO2') + + m.remove_macroscopic('UO2') + + +def test_isotropic(): + m = openmc.Material() + m.add_nuclide('U235', 1.0) + m.add_nuclide('O16', 2.0) + m.make_isotropic_in_lab() + assert m.isotropic == ['U235', 'O16'] + m.isotropic = ['O16'] + assert m.isotropic == ['O16'] + + +def test_get_nuclide_densities(uo2): + nucs = uo2.get_nuclide_densities() + for nuc, density, density_type in nucs.values(): + assert nuc in ('U235', 'O16') + assert density > 0 + assert density_type in ('ao', 'wo') + + +def test_get_nuclide_atom_densities(uo2): + nucs = uo2.get_nuclide_atom_densities() + for nuc, density in nucs.values(): + assert nuc in ('U235', 'O16') + assert density > 0 + + +def test_materials(tmpdir): + m1 = openmc.Material() + m1.add_nuclide('U235', 1.0, 'wo') + m1.add_nuclide('O16', 2.0, 'wo') + m1.set_density('g/cm3', 10.0) + m1.depletable = True + m1.temperature = 900.0 + + m2 = openmc.Material() + m2.add_nuclide('H1', 2.0) + m2.add_nuclide('O16', 1.0) + m2.add_s_alpha_beta('c_H_in_H2O') + m2.set_density('kg/m3', 1000.0) + + mats = openmc.Materials([m1, m2]) + mats.cross_sections = '/some/fake/cross_sections.xml' + mats.multipole_library = '/some/awesome/mp_lib/' + mats.export_to_xml(str(tmpdir.join('materials.xml'))) From b81cbc29fb054353742c564c4d5d3b69b07d4b0e Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 24 Jan 2018 13:41:41 -0600 Subject: [PATCH 25/74] Add test for Material.add_volume_information --- src/volume_calc.F90 | 2 +- tests/unit_tests/test_material.py | 48 +++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/volume_calc.F90 b/src/volume_calc.F90 index 07dc5b4184..15c0497699 100644 --- a/src/volume_calc.F90 +++ b/src/volume_calc.F90 @@ -194,7 +194,7 @@ contains if (this % domain_type == FILTER_MATERIAL) then i_material = p % material do i_domain = 1, size(this % domain_id) - if (i_material == materials(i_domain) % id) then + if (materials(i_material) % id == this % domain_id(i_domain)) then call check_hit(i_domain, i_material, indices, hits, n_mat) end if end do diff --git a/tests/unit_tests/test_material.py b/tests/unit_tests/test_material.py index 46241e83df..2da3c797f9 100644 --- a/tests/unit_tests/test_material.py +++ b/tests/unit_tests/test_material.py @@ -1,4 +1,6 @@ import openmc +import openmc.model +import openmc.stats import pytest @@ -12,6 +14,40 @@ def uo2(): return m +@pytest.fixture(scope='module') +def sphere_model(): + model = openmc.model.Model() + + m = openmc.Material() + m.add_nuclide('U235', 1.0) + m.set_density('g/cm3', 1.0) + model.materials.append(m) + + sph = openmc.Sphere(boundary_type='vacuum') + c = openmc.Cell(fill=m, region=-sph) + model.geometry.root_universe = openmc.Universe(cells=[c]) + + model.settings.particles = 100 + model.settings.batches = 10 + model.settings.run_mode = 'fixed source' + model.settings.source = openmc.Source(space=openmc.stats.Point()) + ll, ur = c.region.bounding_box + model.settings.volume_calculations = [ + openmc.VolumeCalculation(domains=[m], samples=1000, + lower_left=ll, upper_right=ur) + ] + return model + + +@pytest.fixture +def run_in_tmpdir(tmpdir): + orig = tmpdir.chdir() + try: + yield + finally: + orig.chdir() + + def test_attributes(uo2): assert uo2.name == 'UO2' assert uo2.id == 100 @@ -93,6 +129,14 @@ def test_isotropic(): assert m.isotropic == ['O16'] +def test_volume(run_in_tmpdir, sphere_model): + """Test adding volume information from a volume calculation.""" + sphere_model.export_to_xml() + openmc.calculate_volumes() + volume_calc = openmc.VolumeCalculation.from_hdf5('volume_1.h5') + sphere_model.materials[0].add_volume_information(volume_calc) + + def test_get_nuclide_densities(uo2): nucs = uo2.get_nuclide_densities() for nuc, density, density_type in nucs.values(): @@ -108,7 +152,7 @@ def test_get_nuclide_atom_densities(uo2): assert density > 0 -def test_materials(tmpdir): +def test_materials(run_in_tmpdir): m1 = openmc.Material() m1.add_nuclide('U235', 1.0, 'wo') m1.add_nuclide('O16', 2.0, 'wo') @@ -125,4 +169,4 @@ def test_materials(tmpdir): mats = openmc.Materials([m1, m2]) mats.cross_sections = '/some/fake/cross_sections.xml' mats.multipole_library = '/some/awesome/mp_lib/' - mats.export_to_xml(str(tmpdir.join('materials.xml'))) + mats.export_to_xml() From 1432742fbfb37a2a1d1682aa795d8090672263c6 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 24 Jan 2018 14:29:31 -0600 Subject: [PATCH 26/74] More tests for material --- tests/unit_tests/test_material.py | 37 ++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/tests/unit_tests/test_material.py b/tests/unit_tests/test_material.py index 2da3c797f9..84627ba8c4 100644 --- a/tests/unit_tests/test_material.py +++ b/tests/unit_tests/test_material.py @@ -1,6 +1,7 @@ import openmc import openmc.model import openmc.stats +import openmc.examples import pytest @@ -101,7 +102,7 @@ def test_repr(): repr(m) -def test_macroscopic(): +def test_macroscopic(run_in_tmpdir): m = openmc.Material(name='UO2') m.add_macroscopic('UO2') with pytest.raises(ValueError): @@ -116,17 +117,37 @@ def test_macroscopic(): with pytest.raises(ValueError): m2.add_macroscopic('UO2') + # Make sure we can remove/add macroscopic m.remove_macroscopic('UO2') + m.add_macroscopic('UO2') + repr(m) + + # Make sure we can export a material with macroscopic data + mats = openmc.Materials([m]) + mats.export_to_xml() + + +def test_paths(): + model = openmc.examples.pwr_assembly() + model.geometry.determine_paths() + fuel = model.materials[0] + assert fuel.num_instances == 264 + assert len(fuel.paths) == 264 def test_isotropic(): - m = openmc.Material() - m.add_nuclide('U235', 1.0) - m.add_nuclide('O16', 2.0) - m.make_isotropic_in_lab() - assert m.isotropic == ['U235', 'O16'] - m.isotropic = ['O16'] - assert m.isotropic == ['O16'] + m1 = openmc.Material() + m1.add_nuclide('U235', 1.0) + m1.add_nuclide('O16', 2.0) + m1.isotropic = ['O16'] + assert m1.isotropic == ['O16'] + + m2 = openmc.Material() + m2.add_nuclide('H1', 1.0) + mats = openmc.Materials([m1, m2]) + mats.make_isotropic_in_lab() + assert m1.isotropic == ['U235', 'O16'] + assert m2.isotropic == ['H1'] def test_volume(run_in_tmpdir, sphere_model): From b0d35268f3ed656498bb40707243d115fe2bf5ea Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 25 Jan 2018 14:04:01 -0600 Subject: [PATCH 27/74] Add unit tests for surfaces --- openmc/surface.py | 2 +- tests/unit_tests/test_surface.py | 258 +++++++++++++++++++++++++++++++ 2 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 tests/unit_tests/test_surface.py diff --git a/openmc/surface.py b/openmc/surface.py index 6c29ed458c..eb44a4fe8d 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -1376,7 +1376,7 @@ class Cone(Surface): @property def r2(self): - return self.coefficients['r2'] + return self.coefficients['R2'] @x0.setter def x0(self, x0): diff --git a/tests/unit_tests/test_surface.py b/tests/unit_tests/test_surface.py new file mode 100644 index 0000000000..ded6cf1f2a --- /dev/null +++ b/tests/unit_tests/test_surface.py @@ -0,0 +1,258 @@ +import numpy as np +import openmc +import pytest + + +def assert_infinite_bb(s): + ll, ur = (-s).bounding_box + assert np.all(np.isinf(ll)) + assert np.all(np.isinf(ur)) + ll, ur = (+s).bounding_box + assert np.all(np.isinf(ll)) + assert np.all(np.isinf(ur)) + + +def test_plane(): + s = openmc.Plane(A=1, B=2, C=-1, D=3, name='my plane') + assert s.a == 1 + assert s.b == 2 + assert s.c == -1 + assert s.d == 3 + assert s.boundary_type == 'transmission' + assert s.name == 'my plane' + assert s.type == 'plane' + + # Generic planes don't have well-defined bounding boxes + assert_infinite_bb(s) + + # evaluate method + x, y, z = (4, 3, 6) + assert s.evaluate((x, y, z)) == pytest.approx(s.a*x + s.b*y + s.c*z - s.d) + + # Make sure repr works + repr(s) + + +def test_xplane(): + s = openmc.XPlane(x0=3., boundary_type='reflective') + assert s.x0 == 3. + assert s.boundary_type == 'reflective' + + # Check bounding box + ll, ur = (+s).bounding_box + assert ll == pytest.approx((3., -np.inf, -np.inf)) + assert np.all(np.isinf(ur)) + ll, ur = (-s).bounding_box + assert ur == pytest.approx((3., np.inf, np.inf)) + assert np.all(np.isinf(ll)) + + # __contains__ on associated half-spaces + assert (5, 0, 0) in +s + assert (5, 0, 0) not in -s + assert (-2, 1, 10) in -s + assert (-2, 1, 10) not in +s + + # evaluate method + assert s.evaluate((5., 0., 0.)) == pytest.approx(2.) + + # Make sure repr works + repr(s) + + +def test_yplane(): + s = openmc.YPlane(y0=3.) + assert s.y0 == 3. + + # Check bounding box + ll, ur = (+s).bounding_box + assert ll == pytest.approx((-np.inf, 3., -np.inf)) + assert np.all(np.isinf(ur)) + ll, ur = s.bounding_box('-') + assert ur == pytest.approx((np.inf, 3., np.inf)) + assert np.all(np.isinf(ll)) + + # __contains__ on associated half-spaces + assert (0, 5, 0) in +s + assert (0, 5, 0) not in -s + assert (-2, 1, 10) in -s + assert (-2, 1, 10) not in +s + + # evaluate method + assert s.evaluate((0., 0., 0.)) == pytest.approx(-3.) + +def test_zplane(): + s = openmc.ZPlane(z0=3.) + assert s.z0 == 3. + + # Check bounding box + ll, ur = (+s).bounding_box + assert ll == pytest.approx((-np.inf, -np.inf, 3.)) + assert np.all(np.isinf(ur)) + ll, ur = (-s).bounding_box + assert ur == pytest.approx((np.inf, np.inf, 3.)) + assert np.all(np.isinf(ll)) + + # __contains__ on associated half-spaces + assert (0, 0, 5) in +s + assert (0, 0, 5) not in -s + assert (-2, 1, -10) in -s + assert (-2, 1, -10) not in +s + + # evaluate method + assert s.evaluate((0., 0., 10.)) == pytest.approx(7.) + + # Make sure repr works + repr(s) + + +def test_xcylinder(): + y, z, r = 3, 5, 2 + s = openmc.XCylinder(y0=y, z0=z, R=r) + assert s.y0 == y + assert s.z0 == z + assert s.r == r + + # Check bounding box + ll, ur = (+s).bounding_box + assert np.all(np.isinf(ll)) + assert np.all(np.isinf(ur)) + ll, ur = (-s).bounding_box + assert ll == pytest.approx((-np.inf, y-r, z-r)) + assert ur == pytest.approx((np.inf, y+r, z+r)) + + # evaluate method + assert s.evaluate((0, y, z)) == pytest.approx(-r**2) + + # Make sure repr works + repr(s) + + +def test_periodic(): + x = openmc.XPlane(boundary_type='periodic') + y = openmc.YPlane(boundary_type='periodic') + x.periodic_surface = y + assert y.periodic_surface == x + with pytest.raises(TypeError): + x.periodic_surface = openmc.Sphere() + + +def test_ycylinder(): + x, z, r = 3, 5, 2 + s = openmc.YCylinder(x0=x, z0=z, R=r) + assert s.x0 == x + assert s.z0 == z + assert s.r == r + + # Check bounding box + ll, ur = (+s).bounding_box + assert np.all(np.isinf(ll)) + assert np.all(np.isinf(ur)) + ll, ur = (-s).bounding_box + assert ll == pytest.approx((x-r, -np.inf, z-r)) + assert ur == pytest.approx((x+r, np.inf, z+r)) + + # evaluate method + assert s.evaluate((x, 0, z)) == pytest.approx(-r**2) + + +def test_zcylinder(): + x, y, r = 3, 5, 2 + s = openmc.ZCylinder(x0=x, y0=y, R=r) + assert s.x0 == x + assert s.y0 == y + assert s.r == r + + # Check bounding box + ll, ur = (+s).bounding_box + assert np.all(np.isinf(ll)) + assert np.all(np.isinf(ur)) + ll, ur = (-s).bounding_box + assert ll == pytest.approx((x-r, y-r, -np.inf)) + assert ur == pytest.approx((x+r, y+r, np.inf)) + + # evaluate method + assert s.evaluate((x, y, 0)) == pytest.approx(-r**2) + + # Make sure repr works + repr(s) + + +def test_sphere(): + x, y, z, r = -3, 5, 6, 2 + s = openmc.Sphere(x0=x, y0=y, z0=z, R=r) + assert s.x0 == x + assert s.y0 == y + assert s.z0 == z + assert s.r == r + + # Check bounding box + ll, ur = (+s).bounding_box + assert np.all(np.isinf(ll)) + assert np.all(np.isinf(ur)) + ll, ur = (-s).bounding_box + assert ll == pytest.approx((x-r, y-r, z-r)) + assert ur == pytest.approx((x+r, y+r, z+r)) + + # evaluate method + assert s.evaluate((x, y, z)) == pytest.approx(-r**2) + + # Make sure repr works + repr(s) + + +def cone_common(apex, r2, cls): + x, y, z = apex + s = cls(x0=x, y0=y, z0=z, R2=r2) + assert s.x0 == x + assert s.y0 == y + assert s.z0 == z + assert s.r2 == r2 + + # Check bounding box + assert_infinite_bb(s) + + # evaluate method -- should be zero at apex + assert s.evaluate((x, y, z)) == pytest.approx(0.0) + + # Make sure repr works + repr(s) + + +def test_xcone(): + apex = (10, 0, 0) + r2 = 4 + cone_common(apex, r2, openmc.XCone) + + +def test_ycone(): + apex = (10, 0, 0) + r2 = 4 + cone_common(apex, r2, openmc.YCone) + + +def test_zcone(): + apex = (10, 0, 0) + r2 = 4 + cone_common(apex, r2, openmc.ZCone) + + +def test_quadric(): + # Make a sphere from a quadric + r = 10.0 + coeffs = {'a': 1, 'b': 1, 'c': 1, 'k': -r**2} + s = openmc.Quadric(**coeffs) + assert s.a == coeffs['a'] + assert s.b == coeffs['b'] + assert s.c == coeffs['c'] + assert s.k == coeffs['k'] + + # All other coeffs should be zero + for coeff in ('d', 'e', 'f', 'g', 'h', 'j'): + assert getattr(s, coeff) == 0.0 + + # Check bounding box + assert_infinite_bb(s) + + # evaluate method + assert s.evaluate((0., 0., 0.)) == pytest.approx(coeffs['k']) + assert s.evaluate((1., 1., 1.)) == pytest.approx(3 + coeffs['k']) From d26165f524d7f2eaed7b4dcb3c0757f78a29bf26 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 25 Jan 2018 16:26:40 -0600 Subject: [PATCH 28/74] Add tests for regions --- openmc/region.py | 8 +- tests/unit_tests/test_region.py | 134 +++++++++++++++++++++++++++++++ tests/unit_tests/test_surface.py | 1 + 3 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 tests/unit_tests/test_region.py diff --git a/openmc/region.py b/openmc/region.py index eeafd28326..54797f5688 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -39,10 +39,8 @@ class Region(object): def __eq__(self, other): if not isinstance(other, type(self)): return False - elif str(self) != str(other): - return False else: - return True + return str(self) == str(other) def __ne__(self, other): return not self == other @@ -463,7 +461,7 @@ class Union(Region, MutableSequence): if memo is None: memo = {} - clone = copy.deepcopy(self) + clone = deepcopy(self) clone[:] = [n.clone(memo) for n in self] return clone @@ -584,6 +582,6 @@ class Complement(Region): if memo is None: memo = {} - clone = copy.deepcopy(self) + clone = deepcopy(self) clone.node = self.node.clone(memo) return clone diff --git a/tests/unit_tests/test_region.py b/tests/unit_tests/test_region.py new file mode 100644 index 0000000000..346ec7d95e --- /dev/null +++ b/tests/unit_tests/test_region.py @@ -0,0 +1,134 @@ +import numpy as np +import pytest +import openmc + + +@pytest.fixture +def reset(): + openmc.reset_auto_ids() + + +def assert_unbounded(region): + ll, ur = region.bounding_box + assert ll == pytest.approx((-np.inf, -np.inf, -np.inf)) + assert ur == pytest.approx((np.inf, np.inf, np.inf)) + + +def test_union(reset): + s1 = openmc.XPlane(surface_id=1, x0=5) + s2 = openmc.XPlane(surface_id=2, x0=-5) + region = +s1 | -s2 + assert isinstance(region, openmc.Union) + + # Check bounding box + assert_unbounded(region) + + # __contains__ + assert (6, 0, 0) in region + assert (-6, 0, 0) in region + assert (0, 0, 0) not in region + + # string representation + assert str(region) == '(1 | -2)' + + # Combining region with intersection + s3 = openmc.YPlane(surface_id=3) + reg2 = region & +s3 + assert (6, 1, 0) in reg2 + assert (6, -1, 0) not in reg2 + assert str(reg2) == '((1 | -2) 3)' + + +def test_intersection(reset): + s1 = openmc.XPlane(surface_id=1, x0=5) + s2 = openmc.XPlane(surface_id=2, x0=-5) + region = -s1 & +s2 + assert isinstance(region, openmc.Intersection) + + # Check bounding box + ll, ur = region.bounding_box + assert ll == pytest.approx((-5, -np.inf, -np.inf)) + assert ur == pytest.approx((5, np.inf, np.inf)) + + # __contains__ + assert (6, 0, 0) not in region + assert (-6, 0, 0) not in region + assert (0, 0, 0) in region + + # string representation + assert str(region) == '(-1 2)' + + # Combining region with union + s3 = openmc.YPlane(surface_id=3) + reg2 = region | +s3 + assert (-6, 2, 0) in reg2 + assert (-6, -2, 0) not in reg2 + assert str(reg2) == '((-1 2) | 3)' + + +def test_complement(reset): + zcyl = openmc.ZCylinder(surface_id=1, R=1.) + z0 = openmc.ZPlane(surface_id=2, z0=-5.) + z1 = openmc.ZPlane(surface_id=3, z0=5.) + outside = +zcyl | -z0 | +z1 + inside = ~outside + outside_equiv = ~(-zcyl & +z0 & -z1) + inside_equiv = ~outside_equiv + + # Check bounding box + for region in (inside, inside_equiv): + ll, ur = region.bounding_box + assert ll == pytest.approx((-1., -1., -5.)) + assert ur == pytest.approx((1., 1., 5.)) + assert_unbounded(outside) + assert_unbounded(outside_equiv) + + # string represention + assert str(inside) == '~(1 | -2 | 3)' + + # evaluate method + assert (0, 0, 0) in inside + assert (0, 0, 0) not in outside + assert (0, 0, 6) not in inside + assert (0, 0, 6) in outside + + +def test_get_surfaces(): + s1 = openmc.XPlane() + s2 = openmc.YPlane() + s3 = openmc.ZPlane() + region = (+s1 & -s2) | +s3 + + # Make sure get_surfaces() returns all surfaces + surfs = set(region.get_surfaces().values()) + assert not (surfs ^ {s1, s2, s3}) + + inverse = ~region + surfs = set(inverse.get_surfaces().values()) + assert not (surfs ^ {s1, s2, s3}) + + +def test_extend_clone(): + s1 = openmc.XPlane() + s2 = openmc.YPlane() + s3 = openmc.ZPlane() + s4 = openmc.ZCylinder() + + # extend intersection + r1 = +s1 & -s2 + r1 &= +s3 & -s4 + assert r1[:] == [+s1, -s2, +s3, -s4] + + # extend union + r2 = +s1 | -s2 + r2 |= +s3 | -s4 + assert r2[:] == [+s1, -s2, +s3, -s4] + + # clone methods + r3 = r1.clone() + assert len(r3) == len(r1) + r4 = r2.clone() + assert len(r4) == len(r2) + + r5 = ~r1 + r6 = r5.clone() diff --git a/tests/unit_tests/test_surface.py b/tests/unit_tests/test_surface.py index ded6cf1f2a..3db84cc053 100644 --- a/tests/unit_tests/test_surface.py +++ b/tests/unit_tests/test_surface.py @@ -80,6 +80,7 @@ def test_yplane(): # evaluate method assert s.evaluate((0., 0., 0.)) == pytest.approx(-3.) + def test_zplane(): s = openmc.ZPlane(z0=3.) assert s.z0 == 3. From 4180d632a466c788d39594918f237c476a51ebbc Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 26 Jan 2018 08:27:28 -0600 Subject: [PATCH 29/74] Add tests for univariate probability distributions --- openmc/stats/univariate.py | 19 ++++--- tests/unit_tests/test_stats.py | 90 ++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 tests/unit_tests/test_stats.py diff --git a/openmc/stats/univariate.py b/openmc/stats/univariate.py index c0476ce45c..38683e6927 100644 --- a/openmc/stats/univariate.py +++ b/openmc/stats/univariate.py @@ -194,12 +194,12 @@ class Maxwell(Univariate): Parameters ---------- theta : float - Effective temperature for distribution + Effective temperature for distribution in eV Attributes ---------- theta : float - Effective temperature for distribution + Effective temperature for distribution in eV """ @@ -250,16 +250,16 @@ class Watt(Univariate): Parameters ---------- a : float - First parameter of distribution + First parameter of distribution in units of eV b : float - Second parameter of distribution + Second parameter of distribution in units of 1/eV Attributes ---------- a : float - First parameter of distribution + First parameter of distribution in units of eV b : float - Second parameter of distribution + Second parameter of distribution in units of 1/eV """ @@ -444,10 +444,9 @@ class Legendre(Univariate): def coefficients(self, coefficients): cv.check_type('Legendre expansion coefficients', coefficients, Iterable, Real) - for l in range(len(coefficients)): - coefficients[l] *= (2.*l + 1.)/2. - self._legendre_polynomial = np.polynomial.legendre.Legendre( - coefficients) + l = np.arange(len(coefficients)) + coeffs = (2.*l + 1.)/2. * np.array(coefficients) + self._legendre_polynomial = np.polynomial.Legendre(coeffs) def to_xml_element(self, element_name): raise NotImplementedError diff --git a/tests/unit_tests/test_stats.py b/tests/unit_tests/test_stats.py new file mode 100644 index 0000000000..cef001526c --- /dev/null +++ b/tests/unit_tests/test_stats.py @@ -0,0 +1,90 @@ +import numpy as np +import pytest +import openmc +import openmc.stats + + +def test_discrete(): + x = [0.0, 1.0, 10.0] + p = [0.3, 0.2, 0.5] + d = openmc.stats.Discrete(x, p) + assert d.x == x + assert d.p == p + assert len(d) == len(x) + d.to_xml_element('distribution') + + # Single point + d2 = openmc.stats.Discrete(1e6, 1.0) + assert d2.x == [1e6] + assert d2.p == [1.0] + assert len(d2) == 1 + + +def test_uniform(): + a, b = 10, 20 + d = openmc.stats.Uniform(a, b) + assert d.a == a + assert d.b == b + assert len(d) == 2 + + t = d.to_tabular() + assert t.x == [a, b] + assert t.p == [1/(b-a), 1/(b-a)] + assert t.interpolation == 'histogram' + + d.to_xml_element('distribution') + + +def test_maxwell(): + theta = 1.2895e6 + d = openmc.stats.Maxwell(theta) + assert d.theta == theta + assert len(d) == 1 + d.to_xml_element('distribution') + + +def test_watt(): + a, b = 0.965e6, 2.29e-6 + d = openmc.stats.Watt(a, b) + assert d.a == a + assert d.b == b + assert len(d) == 2 + d.to_xml_element('distribution') + + +def test_tabular(): + x = [0.0, 5.0, 7.0] + p = [0.1, 0.2, 0.05] + d = openmc.stats.Tabular(x, p, 'linear-linear') + assert d.x == x + assert d.p == p + assert d.interpolation == 'linear-linear' + assert len(d) == len(x) + d.to_xml_element('distribution') + + +def test_legendre(): + # Pu239 elastic scattering at 100 keV + coeffs = [1.000e+0, 1.536e-1, 1.772e-2, 5.945e-4, 3.497e-5, 1.881e-5] + d = openmc.stats.Legendre(coeffs) + assert d.coefficients == pytest.approx(coeffs) + assert len(d) == len(coeffs) + + # Integrating distribution should yield one + mu = np.linspace(-1., 1., 1000) + assert np.trapz(d(mu), mu) == pytest.approx(1.0, rel=1e-4) + + with pytest.raises(NotImplementedError): + d.to_xml_element('distribution') + +def test_mixture(): + d1 = openmc.stats.Uniform(0, 5) + d2 = openmc.stats.Uniform(3, 7) + p = [0.5, 0.5] + mix = openmc.stats.Mixture(p, [d1, d2]) + assert mix.probability == p + assert mix.distribution == [d1, d2] + assert len(mix) == 4 + + with pytest.raises(NotImplementedError): + mix.to_xml_element('distribution') From 058402954f5fedc455723c13b44c326009f5bb95 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 26 Jan 2018 10:50:29 -0600 Subject: [PATCH 30/74] Add tests for multivariate distributions in openmc.stats --- tests/unit_tests/test_stats.py | 89 ++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/tests/unit_tests/test_stats.py b/tests/unit_tests/test_stats.py index cef001526c..3a91ecd8fd 100644 --- a/tests/unit_tests/test_stats.py +++ b/tests/unit_tests/test_stats.py @@ -1,3 +1,5 @@ +from math import pi + import numpy as np import pytest import openmc @@ -77,6 +79,7 @@ def test_legendre(): with pytest.raises(NotImplementedError): d.to_xml_element('distribution') + def test_mixture(): d1 = openmc.stats.Uniform(0, 5) d2 = openmc.stats.Uniform(3, 7) @@ -88,3 +91,89 @@ def test_mixture(): with pytest.raises(NotImplementedError): mix.to_xml_element('distribution') + + +def test_polar_azimuthal(): + # default polar-azimuthal should be uniform in mu and phi + d = openmc.stats.PolarAzimuthal() + assert isinstance(d.mu, openmc.stats.Uniform) + assert d.mu.a == -1. + assert d.mu.b == 1. + assert isinstance(d.phi, openmc.stats.Uniform) + assert d.phi.a == 0. + assert d.phi.b == 2*pi + + mu = openmc.stats.Discrete(1., 1.) + phi = openmc.stats.Discrete(0., 1.) + d = openmc.stats.PolarAzimuthal(mu, phi) + assert d.mu == mu + assert d.phi == phi + + elem = d.to_xml_element() + assert elem.tag == 'angle' + assert elem.attrib['type'] == 'mu-phi' + assert elem.find('mu') is not None + assert elem.find('phi') is not None + + +def test_isotropic(): + d = openmc.stats.Isotropic() + elem = d.to_xml_element() + assert elem.tag == 'angle' + assert elem.attrib['type'] == 'isotropic' + + +def test_monodirectional(): + d = openmc.stats.Monodirectional((1., 0., 0.)) + assert d.reference_uvw == pytest.approx((1., 0., 0.)) + + elem = d.to_xml_element() + assert elem.tag == 'angle' + assert elem.attrib['type'] == 'monodirectional' + + +def test_cartesian(): + x = openmc.stats.Uniform(-10., 10.) + y = openmc.stats.Uniform(-10., 10.) + z = openmc.stats.Uniform(0., 20.) + d = openmc.stats.CartesianIndependent(x, y, z) + assert d.x == x + assert d.y == y + assert d.z == z + + elem = d.to_xml_element() + assert elem.tag == 'space' + assert elem.attrib['type'] == 'cartesian' + assert elem.find('x') is not None + assert elem.find('y') is not None + + +def test_box(): + lower_left = (-10., -10., -10.) + upper_right = (10., 10., 10.) + d = openmc.stats.Box(lower_left, upper_right) + assert d.lower_left == pytest.approx(lower_left) + assert d.upper_right == pytest.approx(upper_right) + assert not d.only_fissionable + + elem = d.to_xml_element() + assert elem.tag == 'space' + assert elem.attrib['type'] == 'box' + assert elem.find('parameters') is not None + + # only fissionable parameter + d2 = openmc.stats.Box(lower_left, upper_right, True) + assert d2.only_fissionable + elem = d2.to_xml_element() + assert elem.attrib['type'] == 'fission' + + +def test_point(): + p = (-4., 2., 10.) + d = openmc.stats.Point(p) + assert d.xyz == pytest.approx(p) + + elem = d.to_xml_element() + assert elem.tag == 'space' + assert elem.attrib['type'] == 'point' + assert elem.find('parameters') is not None From 39cd77a756c6122fae93e5fd2af820d4fd9bb8ef Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 26 Jan 2018 16:01:20 -0600 Subject: [PATCH 31/74] Have Travis install OpenMC during install step and have script call ctest --- .travis.yml | 11 +- tests/run_tests.py | 552 ------------------------------------- tools/ci/travis-install.py | 65 +++++ tools/ci/travis-install.sh | 3 + tools/ci/travis-script.sh | 13 +- 5 files changed, 83 insertions(+), 561 deletions(-) delete mode 100755 tests/run_tests.py create mode 100644 tools/ci/travis-install.py diff --git a/.travis.yml b/.travis.yml index de8b7dcc73..14e2484110 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,18 +18,17 @@ env: global: - FC=gfortran - MPI_DIR=/usr - - PHDF5_DIR=/usr - - HDF5_DIR=/usr + - HDF5_ROOT=/usr - OMP_NUM_THREADS=2 - OPENMC_CROSS_SECTIONS=$HOME/nndc_hdf5/cross_sections.xml - OPENMC_ENDF_DATA=$HOME/endf-b-vii.1 - OPENMC_MULTIPOLE_LIBRARY=$HOME/multipole_lib - PATH=$PATH:$HOME/NJOY2016/build matrix: - - OPENMC_CONFIG="^hdf5-debug$" - - OPENMC_CONFIG="^omp-hdf5-debug$" - - OPENMC_CONFIG="^mpi-hdf5-debug$" - - OPENMC_CONFIG="^phdf5-debug$" + - OMP=n MPI=n PHDF5=n + - OMP=y MPI=n PHDF5=n + - OMP=n MPI=y PHDF5=n + - OMP=n MPI=y PHDF5=y before_install: - sudo add-apt-repository ppa:nschloe/hdf5-backports -y diff --git a/tests/run_tests.py b/tests/run_tests.py deleted file mode 100755 index 6e6b886a50..0000000000 --- a/tests/run_tests.py +++ /dev/null @@ -1,552 +0,0 @@ -#!/usr/bin/env python - -from __future__ import print_function - -import os -import sys -import shutil -import re -import glob -import socket -from subprocess import call, check_output -from collections import OrderedDict -from argparse import ArgumentParser - -# Command line parsing -parser = ArgumentParser() -parser.add_argument('-j', '--parallel', dest='n_procs', default='1', - help="Number of parallel jobs.") -parser.add_argument('-R', '--tests-regex', dest='regex_tests', - help="Run tests matching regular expression. \ - Test names are the directories present in tests folder.\ - This uses standard regex syntax to select tests.") -parser.add_argument('-C', '--build-config', dest='build_config', - help="Build configurations matching regular expression. \ - Specific build configurations can be printed out with \ - optional argument -p, --print. This uses standard \ - regex syntax to select build configurations.") -parser.add_argument('-l', '--list', action="store_true", - dest="list_build_configs", default=False, - help="List out build configurations.") -parser.add_argument("-p", "--project", dest="project", default="", - help="project name for build") -parser.add_argument("-D", "--dashboard", dest="dash", - help="Dash name -- Experimental, Nightly, Continuous") -parser.add_argument("-u", "--update", action="store_true", dest="update", - help="Allow CTest to update repo. (WARNING: may overwrite\ - changes that were not pushed.") -parser.add_argument("-s", "--script", action="store_true", dest="script", - help="Activate CTest scripting mode for coverage, valgrind\ - and dashboard capability.") -args = parser.parse_args() - -# Default compiler paths -FC = 'gfortran' -CC = 'gcc' -CXX = 'g++' -MPI_DIR = '/opt/mpich/3.2-gnu' -HDF5_DIR = '/opt/hdf5/1.8.16-gnu' -PHDF5_DIR = '/opt/phdf5/1.8.16-gnu' - -# Script mode for extra capability -script_mode = False - -# Override default compiler paths if environmental vars are found -if 'FC' in os.environ: - FC = os.environ['FC'] -if 'CC' in os.environ: - CC = os.environ['CC'] -if 'CXX' in os.environ: - CXX = os.environ['CXX'] -if 'MPI_DIR' in os.environ: - MPI_DIR = os.environ['MPI_DIR'] -if 'HDF5_DIR' in os.environ: - HDF5_DIR = os.environ['HDF5_DIR'] -if 'PHDF5_DIR' in os.environ: - PHDF5_DIR = os.environ['PHDF5_DIR'] - -# CTest script template -ctest_str = """set (CTEST_SOURCE_DIRECTORY "{source_dir}") -set (CTEST_BINARY_DIRECTORY "{build_dir}") - -set(CTEST_SITE "{host_name}") -set (CTEST_BUILD_NAME "{build_name}") -set (CTEST_CMAKE_GENERATOR "Unix Makefiles") -set (CTEST_BUILD_OPTIONS "{build_opts}") - -set(CTEST_UPDATE_COMMAND "git") - -set(CTEST_CONFIGURE_COMMAND "${{CMAKE_COMMAND}} -H${{CTEST_SOURCE_DIRECTORY}} -B${{CTEST_BINARY_DIRECTORY}} ${{CTEST_BUILD_OPTIONS}}") -set(CTEST_MEMORYCHECK_COMMAND "{valgrind_cmd}") -set(CTEST_MEMORYCHECK_COMMAND_OPTIONS "--tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes") -#set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE ${{CTEST_SOURCE_DIRECTORY}}/../tests/valgrind.supp) -set(MEM_CHECK {mem_check}) -if(MEM_CHECK) -set(ENV{{MEM_CHECK}} ${{MEM_CHECK}}) -endif() - -set(CTEST_COVERAGE_COMMAND "gcov") -set(COVERAGE {coverage}) -set(ENV{{COVERAGE}} ${{COVERAGE}}) - -{subproject} - -ctest_start("{dashboard}") -ctest_configure(RETURN_VALUE res) -{update} -ctest_build(RETURN_VALUE res) -if(NOT MEM_CHECK) -ctest_test({tests} PARALLEL_LEVEL {n_procs}, RETURN_VALUE res) -endif() -if(MEM_CHECK) -ctest_memcheck({tests} RETURN_VALUE res) -endif(MEM_CHECK) -if(COVERAGE) -ctest_coverage(RETURN_VALUE res) -endif(COVERAGE) -{submit} - -if (res EQUAL 0) -else() -message(FATAL_ERROR "") -endif() -""" - -# Define test data structure -tests = OrderedDict() - - -def cleanup(path): - """Remove generated output files.""" - for dirpath, dirnames, filenames in os.walk(path): - for fname in filenames: - for ext in ['.h5', '.ppm', '.voxel']: - if fname.endswith(ext) and fname != '1d_mgxs.h5': - os.remove(os.path.join(dirpath, fname)) - - -def which(program): - def is_exe(fpath): - return os.path.isfile(fpath) and os.access(fpath, os.X_OK) - - fpath, fname = os.path.split(program) - if fpath: - if is_exe(program): - return program - else: - for path in os.environ["PATH"].split(os.pathsep): - path = path.strip('"') - exe_file = os.path.join(path, program) - if is_exe(exe_file): - return exe_file - return None - - -class Test(object): - def __init__(self, name, debug=False, optimize=False, mpi=False, openmp=False, - phdf5=False, valgrind=False, coverage=False): - self.name = name - self.debug = debug - self.optimize = optimize - self.mpi = mpi - self.openmp = openmp - self.phdf5 = phdf5 - self.valgrind = valgrind - self.coverage = coverage - self.success = True - self.msg = None - self.skipped = False - self.cmake = ['cmake', '-H..', '-Bbuild', - '-DPYTHON_EXECUTABLE=' + sys.executable] - - # Check for MPI - if self.mpi: - if os.path.exists(os.path.join(MPI_DIR, 'bin', 'mpifort')): - self.fc = os.path.join(MPI_DIR, 'bin', 'mpifort') - else: - self.fc = os.path.join(MPI_DIR, 'bin', 'mpif90') - self.cc = os.path.join(MPI_DIR, 'bin', 'mpicc') - self.cxx = os.path.join(MPI_DIR, 'bin', 'mpicxx') - else: - self.fc = FC - self.cc = CC - self.cxx = CXX - - # Sets the build name that will show up on the CDash - def get_build_name(self): - self.build_name = args.project + '_' + self.name - return self.build_name - - # Sets up build options for various tests. It is used both - # in script and non-script modes - def get_build_opts(self): - build_str = "" - if self.debug: - build_str += "-Ddebug=ON " - if self.optimize: - build_str += "-Doptimize=ON " - if not self.openmp: - build_str += "-Dopenmp=OFF " - if self.coverage: - build_str += "-Dcoverage=ON " - if self.phdf5: - build_str += "-DHDF5_PREFER_PARALLEL=ON " - else: - build_str += "-DHDF5_PREFER_PARALLEL=OFF " - self.build_opts = build_str - return self.build_opts - - # Write out the ctest script to tests directory - def create_ctest_script(self, ctest_vars): - with open('ctestscript.run', 'w') as fh: - fh.write(ctest_str.format(**ctest_vars)) - - # Runs the ctest script which performs all the cmake/ctest/cdash - def run_ctest_script(self): - os.environ['FC'] = self.fc - os.environ['CC'] = self.cc - os.environ['CXX'] = self.cxx - if self.mpi: - os.environ['MPI_DIR'] = MPI_DIR - if self.phdf5: - os.environ['HDF5_ROOT'] = PHDF5_DIR - else: - os.environ['HDF5_ROOT'] = HDF5_DIR - rc = call(['ctest', '-S', 'ctestscript.run', '-V']) - if rc != 0: - self.success = False - self.msg = 'Failed on ctest script.' - - # Runs cmake when in non-script mode - def run_cmake(self): - build_opts = self.build_opts.split() - self.cmake += build_opts - - os.environ['FC'] = self.fc - os.environ['CC'] = self.cc - os.environ['CXX'] = self.cxx - if self.mpi: - os.environ['MPI_DIR'] = MPI_DIR - if self.phdf5: - os.environ['HDF5_ROOT'] = PHDF5_DIR - self.cmake.append('-DHDF5_PREFER_PARALLEL=ON') - else: - os.environ['HDF5_ROOT'] = HDF5_DIR - self.cmake.append('-DHDF5_PREFER_PARALLEL=OFF') - rc = call(self.cmake) - if rc != 0: - self.success = False - self.msg = 'Failed on cmake.' - - # Runs make when in non-script mode - def run_make(self): - if not self.success: - return - - # Default make string - make_list = ['make', '-s'] - - # Check for parallel - if args.n_procs is not None: - make_list.append('-j') - make_list.append(args.n_procs) - - # Run make - rc = call(make_list) - if rc != 0: - self.success = False - self.msg = 'Failed on make.' - - # Runs ctest when in non-script mode - def run_ctests(self): - if not self.success: - return - - # Default ctest string - ctest_list = ['ctest'] - - # Check for parallel - if args.n_procs is not None: - ctest_list.append('-j') - ctest_list.append(args.n_procs) - - # Check for subset of tests - if args.regex_tests is not None: - ctest_list.append('-R') - ctest_list.append(args.regex_tests) - - # Run ctests - rc = call(ctest_list) - if rc != 0: - self.success = False - self.msg = 'Failed on testing.' - - -# Simple function to add a test to the global tests dictionary -def add_test(name, debug=False, optimize=False, mpi=False, openmp=False, - phdf5=False, valgrind=False, coverage=False): - tests.update({name: Test(name, debug, optimize, mpi, openmp, phdf5, - valgrind, coverage)}) - -# List of all tests that may be run. User can add -C to command line to specify -# a subset of these configurations -add_test('hdf5-normal') -add_test('hdf5-debug', debug=True) -add_test('hdf5-optimize', optimize=True) -add_test('omp-hdf5-normal', openmp=True) -add_test('omp-hdf5-debug', openmp=True, debug=True) -add_test('omp-hdf5-optimize', openmp=True, optimize=True) -add_test('mpi-hdf5-normal', mpi=True) -add_test('mpi-hdf5-debug', mpi=True, debug=True) -add_test('mpi-hdf5-optimize', mpi=True, optimize=True) -add_test('phdf5-normal', mpi=True, phdf5=True) -add_test('phdf5-debug', mpi=True, phdf5=True, debug=True) -add_test('phdf5-optimize', mpi=True, phdf5=True, optimize=True) -add_test('phdf5-omp-normal', mpi=True, phdf5=True, openmp=True) -add_test('phdf5-omp-debug', mpi=True, phdf5=True, openmp=True, debug=True) -add_test('phdf5-omp-optimize', mpi=True, phdf5=True, openmp=True, optimize=True) -add_test('hdf5-debug_valgrind', debug=True, valgrind=True) -add_test('hdf5-debug_coverage', debug=True, coverage=True) - -# Check to see if we should just print build configuration information to user -if args.list_build_configs: - for key in tests: - print('Configuration Name: {0}'.format(key)) - print(' Debug Flags:..........{0}'.format(tests[key].debug)) - print(' Optimization Flags:...{0}'.format(tests[key].optimize)) - print(' MPI Active:...........{0}'.format(tests[key].mpi)) - print(' OpenMP Active:........{0}'.format(tests[key].openmp)) - print(' Valgrind Test:........{0}'.format(tests[key].valgrind)) - print(' Coverage Test:........{0}\n'.format(tests[key].coverage)) - exit() - -# Delete items of dictionary that don't match regular expression -if args.build_config is not None: - to_delete = [] - for key in tests: - if not re.search(args.build_config, key): - to_delete.append(key) - for key in to_delete: - del tests[key] - -# Check for dashboard and determine whether to push results to server -# Note that there are only 3 basic dashboards: -# Experimental, Nightly, Continuous. On the CDash end, these can be -# reorganized into groups when a hostname, dashboard and build name -# are matched. -if args.dash is None: - dash = 'Experimental' - submit = '' -else: - dash = args.dash - submit = 'ctest_submit()' - -# Check for update command, which will run git fetch/merge and will delete -# any changes to repo that were not pushed to remote origin -update = 'ctest_update()' if args.update else '' - -# Check for CTest scipts mode -# Sets up whether we should use just the basic ctest command or use -# CTest scripting to perform tests. -script_mode = (args.dash is not None or args.script) - -# Setup CTest script vars. Not used in non-script mode -pwd = os.getcwd() -ctest_vars = { - 'source_dir': os.path.join(pwd, os.pardir), - 'build_dir': os.path.join(pwd, 'build'), - 'host_name': socket.gethostname(), - 'dashboard': dash, - 'submit': submit, - 'update': update, - 'n_procs': args.n_procs -} - -# Check project name -subprop = "set_property(GLOBAL PROPERTY SubProject {0})" -if args.project == "": - ctest_vars.update({'subproject': ''}) -elif args.project == 'develop': - ctest_vars.update({'subproject': ''}) -else: - ctest_vars.update({'subproject': subprop.format(args.project)}) - -# Set up default valgrind tests (subset of all tests) -# Currently takes too long to run all the tests with valgrind -# Only used in script mode -valgrind_default_tests = "cmfd_feed|confidence_intervals|\ -density|eigenvalue_genperbatch|energy_grid|entropy|\ -lattice_multiple|output|plotreflective_plane|\ -rotation|salphabetascore_absorption|seed|source_energy_mono|\ -sourcepoint_batch|statepoint_interval|survival_biasing|\ -tally_assumesep|translation|uniform_fs|universe|void" - -# Delete items of dictionary if valgrind or coverage and not in script mode -to_delete = [] -if not script_mode: - for key in tests: - if re.search('valgrind|coverage', key): - to_delete.append(key) - -for key in to_delete: - del tests[key] - -# Check if tests is empty -if not tests: - print('No tests to run.') - exit() - -# Begin testing -shutil.rmtree('build', ignore_errors=True) -cleanup('.') -for key in iter(tests): - test = tests[key] - - # Extra display if not in script mode - if not script_mode: - print('-'*(len(key) + 6)) - print(key + ' tests') - print('-'*(len(key) + 6)) - sys.stdout.flush() - - # Verify fortran compiler exists - if which(test.fc) is None: - test.msg = 'Compiler not found: {0}'.format(test.fc) - test.success = False - continue - - # Verify valgrind command exists - if test.valgrind: - valgrind_cmd = which('valgrind') - if valgrind_cmd is None: - test.msg = 'No valgrind executable found.' - test.success = False - continue - else: - valgrind_cmd = '' - - # Verify gcov/lcov exist - if test.coverage: - if which('gcov') is None: - test.msg = 'No {} executable found.'.format(exe) - test.success = False - continue - - # Set test specific CTest script vars. Not used in non-script mode - ctest_vars.update({'build_name': test.get_build_name()}) - ctest_vars.update({'build_opts': test.get_build_opts()}) - ctest_vars.update({'mem_check': test.valgrind}) - ctest_vars.update({'coverage': test.coverage}) - ctest_vars.update({'valgrind_cmd': valgrind_cmd}) - - # Check for user custom tests - # INCLUDE is a CTest command that allows for a subset - # of tests to be executed. Only used in script mode. - if args.regex_tests is None: - ctest_vars.update({'tests': ''}) - - # No user tests, use default valgrind tests - if test.valgrind: - ctest_vars.update({'tests': 'INCLUDE {0}'. - format(valgrind_default_tests)}) - else: - ctest_vars.update({'tests': 'INCLUDE {0}'. - format(args.regex_tests)}) - - # Main part of code that does the ctest execution. - # It is broken up by two modes, script and non-script - if script_mode: - - # Create ctest script - test.create_ctest_script(ctest_vars) - - # Run test - test.run_ctest_script() - - else: - - # Run CMAKE to configure build - test.run_cmake() - - # Go into build directory - os.chdir('build') - - # Build OpenMC - test.run_make() - - # Run tests - test.run_ctests() - - # Leave build directory - os.chdir(os.pardir) - - # Copy over log file - if script_mode: - logfile = glob.glob('build/Testing/Temporary/LastTest_*.log') - else: - logfile = glob.glob('build/Testing/Temporary/LastTest.log') - if len(logfile) > 0: - logfilename = os.path.split(logfile[0])[1] - logfilename = os.path.splitext(logfilename)[0] - logfilename = logfilename + '_{0}.log'.format(test.name) - shutil.copy(logfile[0], logfilename) - - # For coverage builds, use lcov to generate HTML output - if test.coverage: - if which('lcov') is None or which('genhtml') is None: - print('No lcov/genhtml command found. ' - 'Could not generate coverage report.') - else: - shutil.rmtree('coverage', ignore_errors=True) - call(['lcov', '--directory', '.', '--capture', - '--output-file', 'coverage.info']) - call(['genhtml', '--output-directory', 'coverage', 'coverage.info']) - os.remove('coverage.info') - - if test.valgrind: - # Copy memcheck output to memcheck directory - shutil.rmtree('memcheck', ignore_errors=True) - os.mkdir('memcheck') - memcheck_out = glob.glob('build/Testing/Temporary/MemoryChecker.*.log') - for fname in memcheck_out: - shutil.copy(fname, 'memcheck/') - - # Remove generated XML files - xml_files = check_output(['git', 'ls-files', '.', '--exclude-standard', - '--others']).split() - for f in xml_files: - os.remove(f) - - # Clear build directory and remove binary and hdf5 files - shutil.rmtree('build', ignore_errors=True) - if script_mode: - os.remove('ctestscript.run') - cleanup('.') - -# Print out summary of results -print('\n' + '='*54) -print('Summary of Compilation Option Testing:\n') - -if sys.stdout.isatty(): - OK = '\033[92m' - FAIL = '\033[91m' - ENDC = '\033[0m' - BOLD = '\033[1m' -else: - OK = '' - FAIL = '' - ENDC = '' - BOLD = '' - -return_code = 0 - -for test in tests: - print(test + '.'*(50 - len(test)), end='') - if tests[test].success: - print(BOLD + OK + '[OK]' + ENDC) - else: - print(BOLD + FAIL + '[FAILED]' + ENDC) - print(' '*len(test)+tests[test].msg) - return_code = 1 - -sys.exit(return_code) diff --git a/tools/ci/travis-install.py b/tools/ci/travis-install.py new file mode 100644 index 0000000000..0e4dbdc01b --- /dev/null +++ b/tools/ci/travis-install.py @@ -0,0 +1,65 @@ +import os +import shutil +import subprocess + + +def which(program): + def is_exe(fpath): + return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + + fpath, fname = os.path.split(program) + if fpath: + if is_exe(program): + return program + else: + for path in os.environ["PATH"].split(os.pathsep): + path = path.strip('"') + exe_file = os.path.join(path, program) + if is_exe(exe_file): + return exe_file + return None + + +def install(omp=False, mpi=False, phdf5=False): + # Create build directory and change to it + shutil.rmtree('build', ignore_errors=True) + os.mkdir('build') + os.chdir('build') + + # Build in debug mode by default + cmake_cmd = ['cmake', '-Ddebug=on'] + + # Turn off OpenMP if specified + if not omp: + cmake_cmd.append('-Dopenmp=off') + + # For MPI, we just need to change the Fortran compiler + if mpi: + os.environ['FC'] = 'mpifort' if which('mpifort') else 'mpif90' + + # Tell CMake to prefer parallel HDF5 if specified + if phdf5: + if not mpi: + raise ValueError('Parallel HDF5 must be used in ' + 'conjunction with MPI.') + cmake_cmd.append('-DHDF5_PREFER_PARALLEL=on') + + # Build and install + cmake_cmd.append('..') + subprocess.call(cmake_cmd) + subprocess.call(['make', '-j']) + subprocess.call(['make', 'install']) + + +def main(): + # Convert Travis matrix environment variables into arguments for install() + omp = (os.environ.get('OMP') == 'y') + mpi = (os.environ.get('MPI') == 'y') + phdf5 = (os.environ.get('PHDF5') == 'y') + + # Build and install + install(omp, mpi, phdf5) + + +if __name__ == '__main__': + main() diff --git a/tools/ci/travis-install.sh b/tools/ci/travis-install.sh index 354ae7f7f4..6051f03aa9 100755 --- a/tools/ci/travis-install.sh +++ b/tools/ci/travis-install.sh @@ -15,5 +15,8 @@ if [[ "$TRAVIS_PYTHON_VERSION" == "3.4" ]]; then pip install pandas==0.20.3 fi +# Build and install +python tools/ci/travis-install.py + # Install OpenMC in editable mode pip install -e .[test] diff --git a/tools/ci/travis-script.sh b/tools/ci/travis-script.sh index 978a2811c4..2934cb59a0 100755 --- a/tools/ci/travis-script.sh +++ b/tools/ci/travis-script.sh @@ -1,8 +1,15 @@ #!/bin/bash set -ex -cd tests -if [[ $TRAVIS_PYTHON_VERSION == "3.4" && $OPENMC_CONFIG == '^hdf5-debug$' ]]; then + +# Run regression test suite +cd build +ctest + +# Run source check +cd ../tests +if [[ $TRAVIS_PYTHON_VERSION == "3.4" && $OMP == 'n' && $MPI == 'n' ]]; then ./check_source.py fi -./run_tests.py -C $OPENMC_CONFIG -j 2 + +# Run unit tests pytest --cov=../openmc -v unit_tests/ From c3af1c915b8b799ce59ec1accd124a1595c0cd41 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sun, 28 Jan 2018 15:08:24 -0600 Subject: [PATCH 32/74] Move regression tests into separate directory --- CMakeLists.txt | 8 ++++---- openmc/examples.py | 2 +- .../asymmetric_lattice}/inputs_true.dat | 0 .../asymmetric_lattice}/results_true.dat | 0 .../asymmetric_lattice/test.py} | 2 +- .../cmfd_feed}/cmfd.xml | 0 .../cmfd_feed}/geometry.xml | 0 .../cmfd_feed}/materials.xml | 0 .../cmfd_feed}/results_true.dat | 0 .../cmfd_feed}/settings.xml | 0 .../cmfd_feed}/tallies.xml | 0 .../cmfd_feed/test.py} | 2 +- .../cmfd_nofeed}/cmfd.xml | 0 .../cmfd_nofeed}/geometry.xml | 0 .../cmfd_nofeed}/materials.xml | 0 .../cmfd_nofeed}/results_true.dat | 0 .../cmfd_nofeed}/settings.xml | 0 .../cmfd_nofeed}/tallies.xml | 0 .../cmfd_nofeed/test.py} | 2 +- .../complex_cell}/geometry.xml | 0 .../complex_cell}/materials.xml | 0 .../complex_cell}/results_true.dat | 0 .../complex_cell}/settings.xml | 0 .../complex_cell}/tallies.xml | 0 .../complex_cell/test.py} | 2 +- .../confidence_intervals}/geometry.xml | 0 .../confidence_intervals}/materials.xml | 0 .../confidence_intervals}/results_true.dat | 0 .../confidence_intervals}/settings.xml | 0 .../confidence_intervals}/tallies.xml | 0 .../confidence_intervals/test.py} | 2 +- .../create_fission_neutrons}/inputs_true.dat | 0 .../create_fission_neutrons}/results_true.dat | 0 .../create_fission_neutrons/test.py} | 2 +- .../density}/geometry.xml | 0 .../density}/materials.xml | 0 .../density}/results_true.dat | 0 .../density}/settings.xml | 0 .../density/test.py} | 2 +- .../diff_tally}/inputs_true.dat | 0 .../diff_tally}/results_true.dat | 0 .../diff_tally/test.py} | 2 +- .../distribmat}/inputs_true.dat | 0 .../distribmat}/results_true.dat | 0 .../distribmat/test.py} | 2 +- .../eigenvalue_genperbatch}/geometry.xml | 0 .../eigenvalue_genperbatch}/materials.xml | 0 .../eigenvalue_genperbatch}/results_true.dat | 0 .../eigenvalue_genperbatch}/settings.xml | 0 .../eigenvalue_genperbatch/test.py} | 2 +- .../eigenvalue_no_inactive}/geometry.xml | 0 .../eigenvalue_no_inactive}/materials.xml | 0 .../eigenvalue_no_inactive}/results_true.dat | 0 .../eigenvalue_no_inactive}/settings.xml | 0 .../eigenvalue_no_inactive/test.py} | 2 +- .../energy_cutoff}/inputs_true.dat | 0 .../energy_cutoff}/results_true.dat | 0 .../energy_cutoff/test.py} | 2 +- .../energy_grid}/geometry.xml | 0 .../energy_grid}/materials.xml | 0 .../energy_grid}/results_true.dat | 0 .../energy_grid}/settings.xml | 0 tests/regression_tests/energy_grid/test.py | 11 +++++++++++ .../energy_laws}/geometry.xml | 0 .../energy_laws}/materials.xml | 0 .../energy_laws}/results_true.dat | 0 .../energy_laws}/settings.xml | 0 .../energy_laws/test.py} | 2 +- .../enrichment/test.py} | 1 - .../entropy}/geometry.xml | 0 .../entropy}/materials.xml | 0 .../entropy}/results_true.dat | 0 .../entropy}/settings.xml | 0 .../entropy/test.py} | 2 +- .../filter_distribcell}/case-1/geometry.xml | 0 .../filter_distribcell}/case-1/materials.xml | 0 .../filter_distribcell}/case-1/results_true.dat | 0 .../filter_distribcell}/case-1/settings.xml | 0 .../filter_distribcell}/case-1/tallies.xml | 0 .../filter_distribcell}/case-2/geometry.xml | 0 .../filter_distribcell}/case-2/materials.xml | 0 .../filter_distribcell}/case-2/results_true.dat | 0 .../filter_distribcell}/case-2/settings.xml | 0 .../filter_distribcell}/case-2/tallies.xml | 0 .../filter_distribcell}/case-3/geometry.xml | 0 .../filter_distribcell}/case-3/materials.xml | 0 .../filter_distribcell}/case-3/results_true.dat | 0 .../filter_distribcell}/case-3/settings.xml | 0 .../filter_distribcell}/case-3/tallies.xml | 0 .../filter_distribcell}/case-4/geometry.xml | 0 .../filter_distribcell}/case-4/materials.xml | 0 .../filter_distribcell}/case-4/results_true.dat | 0 .../filter_distribcell}/case-4/settings.xml | 0 .../filter_distribcell}/case-4/tallies.xml | 0 .../filter_distribcell/test.py} | 2 +- .../filter_energyfun}/inputs_true.dat | 0 .../filter_energyfun}/results_true.dat | 0 .../filter_energyfun/test.py} | 2 +- .../filter_mesh}/inputs_true.dat | 0 .../filter_mesh}/results_true.dat | 0 .../filter_mesh/test.py} | 2 +- .../fixed_source}/inputs_true.dat | 0 .../fixed_source}/results_true.dat | 0 .../fixed_source/test.py} | 2 +- .../infinite_cell}/geometry.xml | 0 .../infinite_cell}/materials.xml | 0 .../infinite_cell}/results_true.dat | 0 .../infinite_cell}/settings.xml | 0 tests/regression_tests/infinite_cell/test.py | 11 +++++++++++ .../iso_in_lab}/inputs_true.dat | 0 .../iso_in_lab}/results_true.dat | 0 .../iso_in_lab/test.py} | 2 +- .../lattice}/geometry.xml | 0 .../lattice}/materials.xml | 0 .../lattice}/results_true.dat | 0 .../lattice}/settings.xml | 0 tests/regression_tests/lattice/test.py | 11 +++++++++++ .../lattice_hex}/geometry.xml | 0 .../lattice_hex}/materials.xml | 0 .../lattice_hex}/plots.xml | 0 .../lattice_hex}/results_true.dat | 0 .../lattice_hex}/settings.xml | 0 tests/regression_tests/lattice_hex/test.py | 11 +++++++++++ .../lattice_mixed}/geometry.xml | 0 .../lattice_mixed}/materials.xml | 0 .../lattice_mixed}/plots.xml | 0 .../lattice_mixed}/results_true.dat | 0 .../lattice_mixed}/settings.xml | 0 tests/regression_tests/lattice_mixed/test.py | 11 +++++++++++ .../lattice_multiple}/geometry.xml | 0 .../lattice_multiple}/materials.xml | 0 .../lattice_multiple}/results_true.dat | 0 .../lattice_multiple}/settings.xml | 0 tests/regression_tests/lattice_multiple/test.py | 11 +++++++++++ .../mg_basic}/inputs_true.dat | 2 +- .../mg_basic}/results_true.dat | 0 .../mg_basic/test.py} | 2 +- .../mg_convert}/inputs_true.dat | 0 .../mg_convert}/results_true.dat | 0 .../mg_convert/test.py} | 2 +- .../mg_legendre}/inputs_true.dat | 2 +- .../mg_legendre}/results_true.dat | 0 .../mg_legendre/test.py} | 2 +- .../mg_max_order}/inputs_true.dat | 2 +- .../mg_max_order}/results_true.dat | 0 .../mg_max_order/test.py} | 2 +- .../mg_nuclide}/inputs_true.dat | 2 +- .../mg_nuclide}/results_true.dat | 0 .../mg_nuclide/test.py} | 2 +- .../mg_survival_biasing}/inputs_true.dat | 2 +- .../mg_survival_biasing}/results_true.dat | 0 .../mg_survival_biasing/test.py} | 2 +- .../mg_tallies}/inputs_true.dat | 2 +- .../mg_tallies}/results_true.dat | 0 .../mg_tallies/test.py} | 2 +- .../mgxs_library_ce_to_mg}/inputs_true.dat | 0 .../mgxs_library_ce_to_mg}/results_true.dat | 0 .../mgxs_library_ce_to_mg/test.py} | 2 +- .../mgxs_library_condense}/inputs_true.dat | 0 .../mgxs_library_condense}/results_true.dat | 0 .../mgxs_library_condense/test.py} | 2 +- .../mgxs_library_distribcell}/inputs_true.dat | 0 .../mgxs_library_distribcell}/results_true.dat | 0 .../mgxs_library_distribcell/test.py} | 2 +- .../mgxs_library_hdf5}/inputs_true.dat | 0 .../mgxs_library_hdf5}/results_true.dat | 0 .../mgxs_library_hdf5/test.py} | 2 +- .../mgxs_library_mesh}/inputs_true.dat | 0 .../mgxs_library_mesh}/results_true.dat | 0 .../mgxs_library_mesh/test.py} | 2 +- .../mgxs_library_no_nuclides}/inputs_true.dat | 0 .../mgxs_library_no_nuclides}/results_true.dat | 0 .../mgxs_library_no_nuclides/test.py} | 2 +- .../mgxs_library_nuclides}/inputs_true.dat | 0 .../mgxs_library_nuclides}/results_true.dat | 0 .../mgxs_library_nuclides/test.py} | 2 +- .../multipole}/inputs_true.dat | 0 .../multipole}/results_true.dat | 0 .../multipole/test.py} | 2 +- .../output}/geometry.xml | 0 .../output}/materials.xml | 0 .../output}/results_true.dat | 0 .../output}/settings.xml | 0 .../output/test.py} | 2 +- .../particle_restart_eigval}/geometry.xml | 0 .../particle_restart_eigval}/materials.xml | 0 .../particle_restart_eigval}/results_true.dat | 0 .../particle_restart_eigval}/settings.xml | 0 .../particle_restart_eigval/test.py} | 2 +- .../particle_restart_fixed}/geometry.xml | 0 .../particle_restart_fixed}/materials.xml | 0 .../particle_restart_fixed}/results_true.dat | 0 .../particle_restart_fixed}/settings.xml | 0 .../particle_restart_fixed/test.py} | 2 +- .../periodic}/inputs_true.dat | 0 .../periodic}/results_true.dat | 0 .../periodic/test.py} | 2 +- .../{test_plot => regression_tests/plot}/geometry.xml | 0 .../plot}/materials.xml | 0 tests/{test_plot => regression_tests/plot}/plots.xml | 0 .../plot}/results_true.dat | 0 .../{test_plot => regression_tests/plot}/settings.xml | 0 .../test_plot.py => regression_tests/plot/test.py} | 2 +- .../ptables_off}/geometry.xml | 0 .../ptables_off}/materials.xml | 0 .../ptables_off}/results_true.dat | 0 .../ptables_off}/settings.xml | 0 tests/regression_tests/ptables_off/test.py | 11 +++++++++++ .../quadric_surfaces}/geometry.xml | 0 .../quadric_surfaces}/materials.xml | 0 .../quadric_surfaces}/results_true.dat | 0 .../quadric_surfaces}/settings.xml | 0 tests/regression_tests/quadric_surfaces/test.py | 11 +++++++++++ .../reflective_plane}/geometry.xml | 0 .../reflective_plane}/materials.xml | 0 .../reflective_plane}/results_true.dat | 0 .../reflective_plane}/settings.xml | 0 tests/regression_tests/reflective_plane/test.py | 11 +++++++++++ .../resonance_scattering}/inputs_true.dat | 0 .../resonance_scattering}/results_true.dat | 0 .../resonance_scattering/test.py} | 2 +- .../rotation}/geometry.xml | 0 .../rotation}/materials.xml | 0 .../rotation}/results_true.dat | 0 .../rotation}/settings.xml | 0 tests/regression_tests/rotation/test.py | 11 +++++++++++ .../salphabeta}/inputs_true.dat | 0 .../salphabeta}/results_true.dat | 0 .../salphabeta/test.py} | 2 +- .../score_current}/geometry.xml | 0 .../score_current}/materials.xml | 0 .../score_current}/results_true.dat | 0 .../score_current}/settings.xml | 0 .../score_current}/tallies.xml | 0 .../score_current/test.py} | 2 +- .../{test_seed => regression_tests/seed}/geometry.xml | 0 .../seed}/materials.xml | 0 .../seed}/results_true.dat | 0 .../{test_seed => regression_tests/seed}/settings.xml | 0 tests/regression_tests/seed/test.py | 11 +++++++++++ .../source}/inputs_true.dat | 0 .../source}/results_true.dat | 0 .../source/test.py} | 2 +- .../source_file}/geometry.xml | 0 .../source_file}/materials.xml | 0 .../source_file}/results_true.dat | 0 .../source_file}/settings.xml | 0 .../source_file/test.py} | 2 +- .../sourcepoint_batch}/geometry.xml | 0 .../sourcepoint_batch}/materials.xml | 0 .../sourcepoint_batch}/results_true.dat | 0 .../sourcepoint_batch}/settings.xml | 0 .../sourcepoint_batch/test.py} | 2 +- .../sourcepoint_latest}/geometry.xml | 0 .../sourcepoint_latest}/materials.xml | 0 .../sourcepoint_latest}/results_true.dat | 0 .../sourcepoint_latest}/settings.xml | 0 .../sourcepoint_latest/test.py} | 2 +- .../sourcepoint_restart}/geometry.xml | 0 .../sourcepoint_restart}/materials.xml | 0 .../sourcepoint_restart}/results_true.dat | 0 .../sourcepoint_restart}/settings.xml | 0 .../sourcepoint_restart}/tallies.xml | 0 tests/regression_tests/sourcepoint_restart/test.py | 11 +++++++++++ .../statepoint_batch}/geometry.xml | 0 .../statepoint_batch}/materials.xml | 0 .../statepoint_batch}/results_true.dat | 0 .../statepoint_batch}/settings.xml | 0 .../statepoint_batch/test.py} | 2 +- .../statepoint_restart}/geometry.xml | 0 .../statepoint_restart}/materials.xml | 0 .../statepoint_restart}/results_true.dat | 0 .../statepoint_restart}/settings.xml | 0 .../statepoint_restart}/tallies.xml | 0 .../statepoint_restart/test.py} | 2 +- .../statepoint_sourcesep}/geometry.xml | 0 .../statepoint_sourcesep}/materials.xml | 0 .../statepoint_sourcesep}/results_true.dat | 0 .../statepoint_sourcesep}/settings.xml | 0 .../statepoint_sourcesep/test.py} | 2 +- .../surface_tally}/inputs_true.dat | 0 .../surface_tally}/results_true.dat | 0 .../surface_tally/test.py} | 2 +- .../survival_biasing}/geometry.xml | 0 .../survival_biasing}/materials.xml | 0 .../survival_biasing}/results_true.dat | 0 .../survival_biasing}/settings.xml | 0 .../survival_biasing}/tallies.xml | 0 tests/regression_tests/survival_biasing/test.py | 11 +++++++++++ .../tallies}/inputs_true.dat | 0 .../tallies}/results_true.dat | 0 .../tallies/test.py} | 2 +- .../tally_aggregation}/inputs_true.dat | 0 .../tally_aggregation}/results_true.dat | 0 .../tally_aggregation/test.py} | 2 +- .../tally_arithmetic}/inputs_true.dat | 0 .../tally_arithmetic}/results_true.dat | 0 .../tally_arithmetic/test.py} | 2 +- .../tally_assumesep}/geometry.xml | 0 .../tally_assumesep}/materials.xml | 0 .../tally_assumesep}/results_true.dat | 0 .../tally_assumesep}/settings.xml | 0 .../tally_assumesep}/tallies.xml | 0 tests/regression_tests/tally_assumesep/test.py | 11 +++++++++++ .../tally_nuclides}/geometry.xml | 0 .../tally_nuclides}/materials.xml | 0 .../tally_nuclides}/results_true.dat | 0 .../tally_nuclides}/settings.xml | 0 .../tally_nuclides}/tallies.xml | 0 tests/regression_tests/tally_nuclides/test.py | 11 +++++++++++ .../tally_slice_merge}/inputs_true.dat | 0 .../tally_slice_merge}/results_true.dat | 0 .../tally_slice_merge/test.py} | 2 +- .../trace}/geometry.xml | 0 .../trace}/materials.xml | 0 .../trace}/results_true.dat | 0 .../trace}/settings.xml | 0 tests/regression_tests/trace/test.py | 11 +++++++++++ .../track_output}/geometry.xml | 0 .../track_output}/materials.xml | 0 .../track_output}/results_true.dat | 0 .../track_output}/settings.xml | 0 .../track_output/test.py} | 2 +- .../translation}/geometry.xml | 0 .../translation}/materials.xml | 0 .../translation}/results_true.dat | 0 .../translation}/settings.xml | 0 tests/regression_tests/translation/test.py | 11 +++++++++++ .../trigger_batch_interval}/geometry.xml | 0 .../trigger_batch_interval}/materials.xml | 0 .../trigger_batch_interval}/results_true.dat | 0 .../trigger_batch_interval}/settings.xml | 0 .../trigger_batch_interval}/tallies.xml | 0 .../trigger_batch_interval/test.py} | 2 +- .../trigger_no_batch_interval}/geometry.xml | 0 .../trigger_no_batch_interval}/materials.xml | 0 .../trigger_no_batch_interval}/results_true.dat | 0 .../trigger_no_batch_interval}/settings.xml | 0 .../trigger_no_batch_interval}/tallies.xml | 0 .../trigger_no_batch_interval/test.py} | 2 +- .../trigger_no_status}/geometry.xml | 0 .../trigger_no_status}/materials.xml | 0 .../trigger_no_status}/results_true.dat | 0 .../trigger_no_status}/settings.xml | 0 .../trigger_no_status}/tallies.xml | 0 tests/regression_tests/trigger_no_status/test.py | 11 +++++++++++ .../trigger_tallies}/geometry.xml | 0 .../trigger_tallies}/materials.xml | 0 .../trigger_tallies}/results_true.dat | 0 .../trigger_tallies}/settings.xml | 0 .../trigger_tallies}/tallies.xml | 0 .../trigger_tallies/test.py} | 2 +- .../triso}/inputs_true.dat | 0 .../triso}/results_true.dat | 0 .../test_triso.py => regression_tests/triso/test.py} | 2 +- .../uniform_fs}/geometry.xml | 0 .../uniform_fs}/materials.xml | 0 .../uniform_fs}/results_true.dat | 0 .../uniform_fs}/settings.xml | 0 tests/regression_tests/uniform_fs/test.py | 11 +++++++++++ .../universe}/geometry.xml | 0 .../universe}/materials.xml | 0 .../universe}/results_true.dat | 0 .../universe}/settings.xml | 0 tests/regression_tests/universe/test.py | 11 +++++++++++ .../{test_void => regression_tests/void}/geometry.xml | 0 .../void}/materials.xml | 0 .../void}/results_true.dat | 0 .../{test_void => regression_tests/void}/settings.xml | 0 tests/regression_tests/void/test.py | 11 +++++++++++ .../volume_calc}/inputs_true.dat | 0 .../volume_calc}/results_true.dat | 0 .../volume_calc/test.py} | 2 +- tests/test_complex_cell/test_complex_cell.py | 10 ---------- tests/test_infinite_cell/test_infinite_cell.py | 11 ----------- tests/test_lattice/test_lattice.py | 11 ----------- tests/test_lattice_hex/test_lattice_hex.py | 11 ----------- tests/test_lattice_mixed/test_lattice_mixed.py | 11 ----------- tests/test_lattice_multiple/test_lattice_multiple.py | 11 ----------- tests/test_ptables_off/test_ptables_off.py | 11 ----------- tests/test_quadric_surfaces/test_quadric_surfaces.py | 11 ----------- tests/test_reflective_plane/test_reflective_plane.py | 11 ----------- tests/test_rotation/test_rotation.py | 11 ----------- tests/test_seed/test_seed.py | 11 ----------- .../test_sourcepoint_restart.py | 11 ----------- tests/test_survival_biasing/test_survival_biasing.py | 11 ----------- tests/test_tally_assumesep/test_tally_assumesep.py | 11 ----------- tests/test_tally_nuclides/test_tally_nuclides.py | 11 ----------- tests/test_trace/test_trace.py | 11 ----------- tests/test_translation/test_translation.py | 11 ----------- .../test_trigger_no_status/test_trigger_no_status.py | 11 ----------- tests/test_uniform_fs/test_uniform_fs.py | 11 ----------- tests/test_universe/test_universe.py | 11 ----------- tests/test_void/test_void.py | 11 ----------- 394 files changed, 302 insertions(+), 302 deletions(-) rename tests/{test_asymmetric_lattice => regression_tests/asymmetric_lattice}/inputs_true.dat (100%) rename tests/{test_asymmetric_lattice => regression_tests/asymmetric_lattice}/results_true.dat (100%) rename tests/{test_asymmetric_lattice/test_asymmetric_lattice.py => regression_tests/asymmetric_lattice/test.py} (98%) rename tests/{test_cmfd_feed => regression_tests/cmfd_feed}/cmfd.xml (100%) rename tests/{test_cmfd_feed => regression_tests/cmfd_feed}/geometry.xml (100%) rename tests/{test_cmfd_feed => regression_tests/cmfd_feed}/materials.xml (100%) rename tests/{test_cmfd_feed => regression_tests/cmfd_feed}/results_true.dat (100%) rename tests/{test_cmfd_feed => regression_tests/cmfd_feed}/settings.xml (100%) rename tests/{test_cmfd_feed => regression_tests/cmfd_feed}/tallies.xml (100%) rename tests/{test_cmfd_feed/test_cmfd_feed.py => regression_tests/cmfd_feed/test.py} (77%) rename tests/{test_cmfd_nofeed => regression_tests/cmfd_nofeed}/cmfd.xml (100%) rename tests/{test_cmfd_nofeed => regression_tests/cmfd_nofeed}/geometry.xml (100%) rename tests/{test_cmfd_nofeed => regression_tests/cmfd_nofeed}/materials.xml (100%) rename tests/{test_cmfd_nofeed => regression_tests/cmfd_nofeed}/results_true.dat (100%) rename tests/{test_cmfd_nofeed => regression_tests/cmfd_nofeed}/settings.xml (100%) rename tests/{test_cmfd_nofeed => regression_tests/cmfd_nofeed}/tallies.xml (100%) rename tests/{test_cmfd_nofeed/test_cmfd_nofeed.py => regression_tests/cmfd_nofeed/test.py} (77%) rename tests/{test_complex_cell => regression_tests/complex_cell}/geometry.xml (100%) rename tests/{test_complex_cell => regression_tests/complex_cell}/materials.xml (100%) rename tests/{test_complex_cell => regression_tests/complex_cell}/results_true.dat (100%) rename tests/{test_complex_cell => regression_tests/complex_cell}/settings.xml (100%) rename tests/{test_complex_cell => regression_tests/complex_cell}/tallies.xml (100%) rename tests/{test_confidence_intervals/test_confidence_intervals.py => regression_tests/complex_cell/test.py} (76%) rename tests/{test_confidence_intervals => regression_tests/confidence_intervals}/geometry.xml (100%) rename tests/{test_confidence_intervals => regression_tests/confidence_intervals}/materials.xml (100%) rename tests/{test_confidence_intervals => regression_tests/confidence_intervals}/results_true.dat (100%) rename tests/{test_confidence_intervals => regression_tests/confidence_intervals}/settings.xml (100%) rename tests/{test_confidence_intervals => regression_tests/confidence_intervals}/tallies.xml (100%) rename tests/{test_density/test_density.py => regression_tests/confidence_intervals/test.py} (76%) mode change 100644 => 100755 rename tests/{test_create_fission_neutrons => regression_tests/create_fission_neutrons}/inputs_true.dat (100%) rename tests/{test_create_fission_neutrons => regression_tests/create_fission_neutrons}/results_true.dat (100%) rename tests/{test_create_fission_neutrons/test_create_fission_neutrons.py => regression_tests/create_fission_neutrons/test.py} (97%) rename tests/{test_density => regression_tests/density}/geometry.xml (100%) rename tests/{test_density => regression_tests/density}/materials.xml (100%) rename tests/{test_density => regression_tests/density}/results_true.dat (100%) rename tests/{test_density => regression_tests/density}/settings.xml (100%) rename tests/{test_eigenvalue_no_inactive/test_eigenvalue_no_inactive.py => regression_tests/density/test.py} (76%) rename tests/{test_diff_tally => regression_tests/diff_tally}/inputs_true.dat (100%) rename tests/{test_diff_tally => regression_tests/diff_tally}/results_true.dat (100%) rename tests/{test_diff_tally/test_diff_tally.py => regression_tests/diff_tally/test.py} (98%) rename tests/{test_distribmat => regression_tests/distribmat}/inputs_true.dat (100%) rename tests/{test_distribmat => regression_tests/distribmat}/results_true.dat (100%) rename tests/{test_distribmat/test_distribmat.py => regression_tests/distribmat/test.py} (98%) rename tests/{test_eigenvalue_genperbatch => regression_tests/eigenvalue_genperbatch}/geometry.xml (100%) rename tests/{test_eigenvalue_genperbatch => regression_tests/eigenvalue_genperbatch}/materials.xml (100%) rename tests/{test_eigenvalue_genperbatch => regression_tests/eigenvalue_genperbatch}/results_true.dat (100%) rename tests/{test_eigenvalue_genperbatch => regression_tests/eigenvalue_genperbatch}/settings.xml (100%) rename tests/{test_eigenvalue_genperbatch/test_eigenvalue_genperbatch.py => regression_tests/eigenvalue_genperbatch/test.py} (76%) rename tests/{test_eigenvalue_no_inactive => regression_tests/eigenvalue_no_inactive}/geometry.xml (100%) rename tests/{test_eigenvalue_no_inactive => regression_tests/eigenvalue_no_inactive}/materials.xml (100%) rename tests/{test_eigenvalue_no_inactive => regression_tests/eigenvalue_no_inactive}/results_true.dat (100%) rename tests/{test_eigenvalue_no_inactive => regression_tests/eigenvalue_no_inactive}/settings.xml (100%) rename tests/{test_energy_grid/test_energy_grid.py => regression_tests/eigenvalue_no_inactive/test.py} (76%) rename tests/{test_energy_cutoff => regression_tests/energy_cutoff}/inputs_true.dat (100%) rename tests/{test_energy_cutoff => regression_tests/energy_cutoff}/results_true.dat (100%) rename tests/{test_energy_cutoff/test_energy_cutoff.py => regression_tests/energy_cutoff/test.py} (97%) rename tests/{test_energy_grid => regression_tests/energy_grid}/geometry.xml (100%) rename tests/{test_energy_grid => regression_tests/energy_grid}/materials.xml (100%) rename tests/{test_energy_grid => regression_tests/energy_grid}/results_true.dat (100%) rename tests/{test_energy_grid => regression_tests/energy_grid}/settings.xml (100%) create mode 100644 tests/regression_tests/energy_grid/test.py rename tests/{test_energy_laws => regression_tests/energy_laws}/geometry.xml (100%) rename tests/{test_energy_laws => regression_tests/energy_laws}/materials.xml (100%) rename tests/{test_energy_laws => regression_tests/energy_laws}/results_true.dat (100%) rename tests/{test_energy_laws => regression_tests/energy_laws}/settings.xml (100%) rename tests/{test_energy_laws/test_energy_laws.py => regression_tests/energy_laws/test.py} (93%) rename tests/{test_enrichment/test_enrichment.py => regression_tests/enrichment/test.py} (97%) rename tests/{test_entropy => regression_tests/entropy}/geometry.xml (100%) rename tests/{test_entropy => regression_tests/entropy}/materials.xml (100%) rename tests/{test_entropy => regression_tests/entropy}/results_true.dat (100%) rename tests/{test_entropy => regression_tests/entropy}/settings.xml (100%) rename tests/{test_entropy/test_entropy.py => regression_tests/entropy/test.py} (94%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-1/geometry.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-1/materials.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-1/results_true.dat (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-1/settings.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-1/tallies.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-2/geometry.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-2/materials.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-2/results_true.dat (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-2/settings.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-2/tallies.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-3/geometry.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-3/materials.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-3/results_true.dat (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-3/settings.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-3/tallies.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-4/geometry.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-4/materials.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-4/results_true.dat (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-4/settings.xml (100%) rename tests/{test_filter_distribcell => regression_tests/filter_distribcell}/case-4/tallies.xml (100%) rename tests/{test_filter_distribcell/test_filter_distribcell.py => regression_tests/filter_distribcell/test.py} (98%) rename tests/{test_filter_energyfun => regression_tests/filter_energyfun}/inputs_true.dat (100%) rename tests/{test_filter_energyfun => regression_tests/filter_energyfun}/results_true.dat (100%) rename tests/{test_filter_energyfun/test_filter_energyfun.py => regression_tests/filter_energyfun/test.py} (97%) rename tests/{test_filter_mesh => regression_tests/filter_mesh}/inputs_true.dat (100%) rename tests/{test_filter_mesh => regression_tests/filter_mesh}/results_true.dat (100%) rename tests/{test_filter_mesh/test_filter_mesh.py => regression_tests/filter_mesh/test.py} (97%) rename tests/{test_fixed_source => regression_tests/fixed_source}/inputs_true.dat (100%) rename tests/{test_fixed_source => regression_tests/fixed_source}/results_true.dat (100%) rename tests/{test_fixed_source/test_fixed_source.py => regression_tests/fixed_source/test.py} (97%) rename tests/{test_infinite_cell => regression_tests/infinite_cell}/geometry.xml (100%) rename tests/{test_infinite_cell => regression_tests/infinite_cell}/materials.xml (100%) rename tests/{test_infinite_cell => regression_tests/infinite_cell}/results_true.dat (100%) rename tests/{test_infinite_cell => regression_tests/infinite_cell}/settings.xml (100%) create mode 100644 tests/regression_tests/infinite_cell/test.py rename tests/{test_iso_in_lab => regression_tests/iso_in_lab}/inputs_true.dat (100%) rename tests/{test_iso_in_lab => regression_tests/iso_in_lab}/results_true.dat (100%) rename tests/{test_iso_in_lab/test_iso_in_lab.py => regression_tests/iso_in_lab/test.py} (83%) rename tests/{test_lattice => regression_tests/lattice}/geometry.xml (100%) rename tests/{test_lattice => regression_tests/lattice}/materials.xml (100%) rename tests/{test_lattice => regression_tests/lattice}/results_true.dat (100%) rename tests/{test_lattice => regression_tests/lattice}/settings.xml (100%) create mode 100644 tests/regression_tests/lattice/test.py rename tests/{test_lattice_hex => regression_tests/lattice_hex}/geometry.xml (100%) rename tests/{test_lattice_hex => regression_tests/lattice_hex}/materials.xml (100%) rename tests/{test_lattice_hex => regression_tests/lattice_hex}/plots.xml (100%) rename tests/{test_lattice_hex => regression_tests/lattice_hex}/results_true.dat (100%) rename tests/{test_lattice_hex => regression_tests/lattice_hex}/settings.xml (100%) create mode 100644 tests/regression_tests/lattice_hex/test.py rename tests/{test_lattice_mixed => regression_tests/lattice_mixed}/geometry.xml (100%) rename tests/{test_lattice_mixed => regression_tests/lattice_mixed}/materials.xml (100%) rename tests/{test_lattice_mixed => regression_tests/lattice_mixed}/plots.xml (100%) rename tests/{test_lattice_mixed => regression_tests/lattice_mixed}/results_true.dat (100%) rename tests/{test_lattice_mixed => regression_tests/lattice_mixed}/settings.xml (100%) create mode 100644 tests/regression_tests/lattice_mixed/test.py rename tests/{test_lattice_multiple => regression_tests/lattice_multiple}/geometry.xml (100%) rename tests/{test_lattice_multiple => regression_tests/lattice_multiple}/materials.xml (100%) rename tests/{test_lattice_multiple => regression_tests/lattice_multiple}/results_true.dat (100%) rename tests/{test_lattice_multiple => regression_tests/lattice_multiple}/settings.xml (100%) create mode 100644 tests/regression_tests/lattice_multiple/test.py rename tests/{test_mg_basic => regression_tests/mg_basic}/inputs_true.dat (98%) rename tests/{test_mg_basic => regression_tests/mg_basic}/results_true.dat (100%) rename tests/{test_mg_basic/test_mg_basic.py => regression_tests/mg_basic/test.py} (82%) rename tests/{test_mg_convert => regression_tests/mg_convert}/inputs_true.dat (100%) rename tests/{test_mg_convert => regression_tests/mg_convert}/results_true.dat (100%) rename tests/{test_mg_convert/test_mg_convert.py => regression_tests/mg_convert/test.py} (99%) rename tests/{test_mg_legendre => regression_tests/mg_legendre}/inputs_true.dat (96%) rename tests/{test_mg_legendre => regression_tests/mg_legendre}/results_true.dat (100%) rename tests/{test_mg_legendre/test_mg_legendre.py => regression_tests/mg_legendre/test.py} (85%) rename tests/{test_mg_max_order => regression_tests/mg_max_order}/inputs_true.dat (96%) rename tests/{test_mg_max_order => regression_tests/mg_max_order}/results_true.dat (100%) rename tests/{test_mg_max_order/test_mg_max_order.py => regression_tests/mg_max_order/test.py} (84%) rename tests/{test_mg_nuclide => regression_tests/mg_nuclide}/inputs_true.dat (98%) rename tests/{test_mg_nuclide => regression_tests/mg_nuclide}/results_true.dat (100%) rename tests/{test_mg_nuclide/test_mg_nuclide.py => regression_tests/mg_nuclide/test.py} (82%) rename tests/{test_mg_survival_biasing => regression_tests/mg_survival_biasing}/inputs_true.dat (98%) rename tests/{test_mg_survival_biasing => regression_tests/mg_survival_biasing}/results_true.dat (100%) rename tests/{test_mg_survival_biasing/test_mg_survival_biasing.py => regression_tests/mg_survival_biasing/test.py} (84%) rename tests/{test_mg_tallies => regression_tests/mg_tallies}/inputs_true.dat (99%) rename tests/{test_mg_tallies => regression_tests/mg_tallies}/results_true.dat (100%) rename tests/{test_mg_tallies/test_mg_tallies.py => regression_tests/mg_tallies/test.py} (98%) rename tests/{test_mgxs_library_ce_to_mg => regression_tests/mgxs_library_ce_to_mg}/inputs_true.dat (100%) rename tests/{test_mgxs_library_ce_to_mg => regression_tests/mgxs_library_ce_to_mg}/results_true.dat (100%) rename tests/{test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py => regression_tests/mgxs_library_ce_to_mg/test.py} (98%) rename tests/{test_mgxs_library_condense => regression_tests/mgxs_library_condense}/inputs_true.dat (100%) rename tests/{test_mgxs_library_condense => regression_tests/mgxs_library_condense}/results_true.dat (100%) rename tests/{test_mgxs_library_condense/test_mgxs_library_condense.py => regression_tests/mgxs_library_condense/test.py} (97%) rename tests/{test_mgxs_library_distribcell => regression_tests/mgxs_library_distribcell}/inputs_true.dat (100%) rename tests/{test_mgxs_library_distribcell => regression_tests/mgxs_library_distribcell}/results_true.dat (100%) rename tests/{test_mgxs_library_distribcell/test_mgxs_library_distribcell.py => regression_tests/mgxs_library_distribcell/test.py} (97%) rename tests/{test_mgxs_library_hdf5 => regression_tests/mgxs_library_hdf5}/inputs_true.dat (100%) rename tests/{test_mgxs_library_hdf5 => regression_tests/mgxs_library_hdf5}/results_true.dat (100%) rename tests/{test_mgxs_library_hdf5/test_mgxs_library_hdf5.py => regression_tests/mgxs_library_hdf5/test.py} (98%) rename tests/{test_mgxs_library_mesh => regression_tests/mgxs_library_mesh}/inputs_true.dat (100%) rename tests/{test_mgxs_library_mesh => regression_tests/mgxs_library_mesh}/results_true.dat (100%) rename tests/{test_mgxs_library_mesh/test_mgxs_library_mesh.py => regression_tests/mgxs_library_mesh/test.py} (97%) rename tests/{test_mgxs_library_no_nuclides => regression_tests/mgxs_library_no_nuclides}/inputs_true.dat (100%) rename tests/{test_mgxs_library_no_nuclides => regression_tests/mgxs_library_no_nuclides}/results_true.dat (100%) rename tests/{test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py => regression_tests/mgxs_library_no_nuclides/test.py} (97%) rename tests/{test_mgxs_library_nuclides => regression_tests/mgxs_library_nuclides}/inputs_true.dat (100%) rename tests/{test_mgxs_library_nuclides => regression_tests/mgxs_library_nuclides}/results_true.dat (100%) rename tests/{test_mgxs_library_nuclides/test_mgxs_library_nuclides.py => regression_tests/mgxs_library_nuclides/test.py} (97%) rename tests/{test_multipole => regression_tests/multipole}/inputs_true.dat (100%) rename tests/{test_multipole => regression_tests/multipole}/results_true.dat (100%) rename tests/{test_multipole/test_multipole.py => regression_tests/multipole/test.py} (98%) rename tests/{test_output => regression_tests/output}/geometry.xml (100%) rename tests/{test_output => regression_tests/output}/materials.xml (100%) rename tests/{test_output => regression_tests/output}/results_true.dat (100%) rename tests/{test_output => regression_tests/output}/settings.xml (100%) rename tests/{test_output/test_output.py => regression_tests/output/test.py} (94%) rename tests/{test_particle_restart_eigval => regression_tests/particle_restart_eigval}/geometry.xml (100%) rename tests/{test_particle_restart_eigval => regression_tests/particle_restart_eigval}/materials.xml (100%) rename tests/{test_particle_restart_eigval => regression_tests/particle_restart_eigval}/results_true.dat (100%) rename tests/{test_particle_restart_eigval => regression_tests/particle_restart_eigval}/settings.xml (100%) rename tests/{test_particle_restart_eigval/test_particle_restart_eigval.py => regression_tests/particle_restart_eigval/test.py} (79%) rename tests/{test_particle_restart_fixed => regression_tests/particle_restart_fixed}/geometry.xml (100%) rename tests/{test_particle_restart_fixed => regression_tests/particle_restart_fixed}/materials.xml (100%) rename tests/{test_particle_restart_fixed => regression_tests/particle_restart_fixed}/results_true.dat (100%) rename tests/{test_particle_restart_fixed => regression_tests/particle_restart_fixed}/settings.xml (100%) rename tests/{test_particle_restart_fixed/test_particle_restart_fixed.py => regression_tests/particle_restart_fixed/test.py} (79%) rename tests/{test_periodic => regression_tests/periodic}/inputs_true.dat (100%) rename tests/{test_periodic => regression_tests/periodic}/results_true.dat (100%) rename tests/{test_periodic/test_periodic.py => regression_tests/periodic/test.py} (97%) rename tests/{test_plot => regression_tests/plot}/geometry.xml (100%) rename tests/{test_plot => regression_tests/plot}/materials.xml (100%) rename tests/{test_plot => regression_tests/plot}/plots.xml (100%) rename tests/{test_plot => regression_tests/plot}/results_true.dat (100%) rename tests/{test_plot => regression_tests/plot}/settings.xml (100%) rename tests/{test_plot/test_plot.py => regression_tests/plot/test.py} (97%) rename tests/{test_ptables_off => regression_tests/ptables_off}/geometry.xml (100%) rename tests/{test_ptables_off => regression_tests/ptables_off}/materials.xml (100%) rename tests/{test_ptables_off => regression_tests/ptables_off}/results_true.dat (100%) rename tests/{test_ptables_off => regression_tests/ptables_off}/settings.xml (100%) create mode 100644 tests/regression_tests/ptables_off/test.py rename tests/{test_quadric_surfaces => regression_tests/quadric_surfaces}/geometry.xml (100%) rename tests/{test_quadric_surfaces => regression_tests/quadric_surfaces}/materials.xml (100%) rename tests/{test_quadric_surfaces => regression_tests/quadric_surfaces}/results_true.dat (100%) rename tests/{test_quadric_surfaces => regression_tests/quadric_surfaces}/settings.xml (100%) create mode 100755 tests/regression_tests/quadric_surfaces/test.py rename tests/{test_reflective_plane => regression_tests/reflective_plane}/geometry.xml (100%) rename tests/{test_reflective_plane => regression_tests/reflective_plane}/materials.xml (100%) rename tests/{test_reflective_plane => regression_tests/reflective_plane}/results_true.dat (100%) rename tests/{test_reflective_plane => regression_tests/reflective_plane}/settings.xml (100%) create mode 100644 tests/regression_tests/reflective_plane/test.py rename tests/{test_resonance_scattering => regression_tests/resonance_scattering}/inputs_true.dat (100%) rename tests/{test_resonance_scattering => regression_tests/resonance_scattering}/results_true.dat (100%) rename tests/{test_resonance_scattering/test_resonance_scattering.py => regression_tests/resonance_scattering/test.py} (96%) rename tests/{test_rotation => regression_tests/rotation}/geometry.xml (100%) rename tests/{test_rotation => regression_tests/rotation}/materials.xml (100%) rename tests/{test_rotation => regression_tests/rotation}/results_true.dat (100%) rename tests/{test_rotation => regression_tests/rotation}/settings.xml (100%) create mode 100644 tests/regression_tests/rotation/test.py rename tests/{test_salphabeta => regression_tests/salphabeta}/inputs_true.dat (100%) rename tests/{test_salphabeta => regression_tests/salphabeta}/results_true.dat (100%) rename tests/{test_salphabeta/test_salphabeta.py => regression_tests/salphabeta/test.py} (97%) rename tests/{test_score_current => regression_tests/score_current}/geometry.xml (100%) rename tests/{test_score_current => regression_tests/score_current}/materials.xml (100%) rename tests/{test_score_current => regression_tests/score_current}/results_true.dat (100%) rename tests/{test_score_current => regression_tests/score_current}/settings.xml (100%) rename tests/{test_score_current => regression_tests/score_current}/tallies.xml (100%) rename tests/{test_score_current/test_score_current.py => regression_tests/score_current/test.py} (77%) rename tests/{test_seed => regression_tests/seed}/geometry.xml (100%) rename tests/{test_seed => regression_tests/seed}/materials.xml (100%) rename tests/{test_seed => regression_tests/seed}/results_true.dat (100%) rename tests/{test_seed => regression_tests/seed}/settings.xml (100%) create mode 100644 tests/regression_tests/seed/test.py rename tests/{test_source => regression_tests/source}/inputs_true.dat (100%) rename tests/{test_source => regression_tests/source}/results_true.dat (100%) rename tests/{test_source/test_source.py => regression_tests/source/test.py} (97%) rename tests/{test_source_file => regression_tests/source_file}/geometry.xml (100%) rename tests/{test_source_file => regression_tests/source_file}/materials.xml (100%) rename tests/{test_source_file => regression_tests/source_file}/results_true.dat (100%) rename tests/{test_source_file => regression_tests/source_file}/settings.xml (100%) rename tests/{test_source_file/test_source_file.py => regression_tests/source_file/test.py} (98%) rename tests/{test_sourcepoint_batch => regression_tests/sourcepoint_batch}/geometry.xml (100%) rename tests/{test_sourcepoint_batch => regression_tests/sourcepoint_batch}/materials.xml (100%) rename tests/{test_sourcepoint_batch => regression_tests/sourcepoint_batch}/results_true.dat (100%) rename tests/{test_sourcepoint_batch => regression_tests/sourcepoint_batch}/settings.xml (100%) rename tests/{test_sourcepoint_batch/test_sourcepoint_batch.py => regression_tests/sourcepoint_batch/test.py} (95%) rename tests/{test_sourcepoint_latest => regression_tests/sourcepoint_latest}/geometry.xml (100%) rename tests/{test_sourcepoint_latest => regression_tests/sourcepoint_latest}/materials.xml (100%) rename tests/{test_sourcepoint_latest => regression_tests/sourcepoint_latest}/results_true.dat (100%) rename tests/{test_sourcepoint_latest => regression_tests/sourcepoint_latest}/settings.xml (100%) rename tests/{test_sourcepoint_latest/test_sourcepoint_latest.py => regression_tests/sourcepoint_latest/test.py} (91%) rename tests/{test_sourcepoint_restart => regression_tests/sourcepoint_restart}/geometry.xml (100%) rename tests/{test_sourcepoint_restart => regression_tests/sourcepoint_restart}/materials.xml (100%) rename tests/{test_sourcepoint_restart => regression_tests/sourcepoint_restart}/results_true.dat (100%) rename tests/{test_sourcepoint_restart => regression_tests/sourcepoint_restart}/settings.xml (100%) rename tests/{test_sourcepoint_restart => regression_tests/sourcepoint_restart}/tallies.xml (100%) create mode 100644 tests/regression_tests/sourcepoint_restart/test.py rename tests/{test_statepoint_batch => regression_tests/statepoint_batch}/geometry.xml (100%) rename tests/{test_statepoint_batch => regression_tests/statepoint_batch}/materials.xml (100%) rename tests/{test_statepoint_batch => regression_tests/statepoint_batch}/results_true.dat (100%) rename tests/{test_statepoint_batch => regression_tests/statepoint_batch}/settings.xml (100%) rename tests/{test_statepoint_batch/test_statepoint_batch.py => regression_tests/statepoint_batch/test.py} (91%) rename tests/{test_statepoint_restart => regression_tests/statepoint_restart}/geometry.xml (100%) rename tests/{test_statepoint_restart => regression_tests/statepoint_restart}/materials.xml (100%) rename tests/{test_statepoint_restart => regression_tests/statepoint_restart}/results_true.dat (100%) rename tests/{test_statepoint_restart => regression_tests/statepoint_restart}/settings.xml (100%) rename tests/{test_statepoint_restart => regression_tests/statepoint_restart}/tallies.xml (100%) rename tests/{test_statepoint_restart/test_statepoint_restart.py => regression_tests/statepoint_restart/test.py} (97%) rename tests/{test_statepoint_sourcesep => regression_tests/statepoint_sourcesep}/geometry.xml (100%) rename tests/{test_statepoint_sourcesep => regression_tests/statepoint_sourcesep}/materials.xml (100%) rename tests/{test_statepoint_sourcesep => regression_tests/statepoint_sourcesep}/results_true.dat (100%) rename tests/{test_statepoint_sourcesep => regression_tests/statepoint_sourcesep}/settings.xml (100%) rename tests/{test_statepoint_sourcesep/test_statepoint_sourcesep.py => regression_tests/statepoint_sourcesep/test.py} (94%) rename tests/{test_surface_tally => regression_tests/surface_tally}/inputs_true.dat (100%) rename tests/{test_surface_tally => regression_tests/surface_tally}/results_true.dat (100%) rename tests/{test_surface_tally/test_surface_tally.py => regression_tests/surface_tally/test.py} (99%) rename tests/{test_survival_biasing => regression_tests/survival_biasing}/geometry.xml (100%) rename tests/{test_survival_biasing => regression_tests/survival_biasing}/materials.xml (100%) rename tests/{test_survival_biasing => regression_tests/survival_biasing}/results_true.dat (100%) rename tests/{test_survival_biasing => regression_tests/survival_biasing}/settings.xml (100%) rename tests/{test_survival_biasing => regression_tests/survival_biasing}/tallies.xml (100%) create mode 100644 tests/regression_tests/survival_biasing/test.py rename tests/{test_tallies => regression_tests/tallies}/inputs_true.dat (100%) rename tests/{test_tallies => regression_tests/tallies}/results_true.dat (100%) rename tests/{test_tallies/test_tallies.py => regression_tests/tallies/test.py} (99%) rename tests/{test_tally_aggregation => regression_tests/tally_aggregation}/inputs_true.dat (100%) rename tests/{test_tally_aggregation => regression_tests/tally_aggregation}/results_true.dat (100%) rename tests/{test_tally_aggregation/test_tally_aggregation.py => regression_tests/tally_aggregation/test.py} (97%) rename tests/{test_tally_arithmetic => regression_tests/tally_arithmetic}/inputs_true.dat (100%) rename tests/{test_tally_arithmetic => regression_tests/tally_arithmetic}/results_true.dat (100%) rename tests/{test_tally_arithmetic/test_tally_arithmetic.py => regression_tests/tally_arithmetic/test.py} (98%) rename tests/{test_tally_assumesep => regression_tests/tally_assumesep}/geometry.xml (100%) rename tests/{test_tally_assumesep => regression_tests/tally_assumesep}/materials.xml (100%) rename tests/{test_tally_assumesep => regression_tests/tally_assumesep}/results_true.dat (100%) rename tests/{test_tally_assumesep => regression_tests/tally_assumesep}/settings.xml (100%) rename tests/{test_tally_assumesep => regression_tests/tally_assumesep}/tallies.xml (100%) create mode 100644 tests/regression_tests/tally_assumesep/test.py rename tests/{test_tally_nuclides => regression_tests/tally_nuclides}/geometry.xml (100%) rename tests/{test_tally_nuclides => regression_tests/tally_nuclides}/materials.xml (100%) rename tests/{test_tally_nuclides => regression_tests/tally_nuclides}/results_true.dat (100%) rename tests/{test_tally_nuclides => regression_tests/tally_nuclides}/settings.xml (100%) rename tests/{test_tally_nuclides => regression_tests/tally_nuclides}/tallies.xml (100%) create mode 100644 tests/regression_tests/tally_nuclides/test.py rename tests/{test_tally_slice_merge => regression_tests/tally_slice_merge}/inputs_true.dat (100%) rename tests/{test_tally_slice_merge => regression_tests/tally_slice_merge}/results_true.dat (100%) rename tests/{test_tally_slice_merge/test_tally_slice_merge.py => regression_tests/tally_slice_merge/test.py} (99%) rename tests/{test_trace => regression_tests/trace}/geometry.xml (100%) rename tests/{test_trace => regression_tests/trace}/materials.xml (100%) rename tests/{test_trace => regression_tests/trace}/results_true.dat (100%) rename tests/{test_trace => regression_tests/trace}/settings.xml (100%) create mode 100644 tests/regression_tests/trace/test.py rename tests/{test_track_output => regression_tests/track_output}/geometry.xml (100%) rename tests/{test_track_output => regression_tests/track_output}/materials.xml (100%) rename tests/{test_track_output => regression_tests/track_output}/results_true.dat (100%) rename tests/{test_track_output => regression_tests/track_output}/settings.xml (100%) rename tests/{test_track_output/test_track_output.py => regression_tests/track_output/test.py} (96%) rename tests/{test_translation => regression_tests/translation}/geometry.xml (100%) rename tests/{test_translation => regression_tests/translation}/materials.xml (100%) rename tests/{test_translation => regression_tests/translation}/results_true.dat (100%) rename tests/{test_translation => regression_tests/translation}/settings.xml (100%) create mode 100644 tests/regression_tests/translation/test.py rename tests/{test_trigger_batch_interval => regression_tests/trigger_batch_interval}/geometry.xml (100%) rename tests/{test_trigger_batch_interval => regression_tests/trigger_batch_interval}/materials.xml (100%) rename tests/{test_trigger_batch_interval => regression_tests/trigger_batch_interval}/results_true.dat (100%) rename tests/{test_trigger_batch_interval => regression_tests/trigger_batch_interval}/settings.xml (100%) rename tests/{test_trigger_batch_interval => regression_tests/trigger_batch_interval}/tallies.xml (100%) rename tests/{test_trigger_batch_interval/test_trigger_batch_interval.py => regression_tests/trigger_batch_interval/test.py} (76%) rename tests/{test_trigger_no_batch_interval => regression_tests/trigger_no_batch_interval}/geometry.xml (100%) rename tests/{test_trigger_no_batch_interval => regression_tests/trigger_no_batch_interval}/materials.xml (100%) rename tests/{test_trigger_no_batch_interval => regression_tests/trigger_no_batch_interval}/results_true.dat (100%) rename tests/{test_trigger_no_batch_interval => regression_tests/trigger_no_batch_interval}/settings.xml (100%) rename tests/{test_trigger_no_batch_interval => regression_tests/trigger_no_batch_interval}/tallies.xml (100%) rename tests/{test_trigger_no_batch_interval/test_trigger_no_batch_interval.py => regression_tests/trigger_no_batch_interval/test.py} (76%) rename tests/{test_trigger_no_status => regression_tests/trigger_no_status}/geometry.xml (100%) rename tests/{test_trigger_no_status => regression_tests/trigger_no_status}/materials.xml (100%) rename tests/{test_trigger_no_status => regression_tests/trigger_no_status}/results_true.dat (100%) rename tests/{test_trigger_no_status => regression_tests/trigger_no_status}/settings.xml (100%) rename tests/{test_trigger_no_status => regression_tests/trigger_no_status}/tallies.xml (100%) create mode 100644 tests/regression_tests/trigger_no_status/test.py rename tests/{test_trigger_tallies => regression_tests/trigger_tallies}/geometry.xml (100%) rename tests/{test_trigger_tallies => regression_tests/trigger_tallies}/materials.xml (100%) rename tests/{test_trigger_tallies => regression_tests/trigger_tallies}/results_true.dat (100%) rename tests/{test_trigger_tallies => regression_tests/trigger_tallies}/settings.xml (100%) rename tests/{test_trigger_tallies => regression_tests/trigger_tallies}/tallies.xml (100%) rename tests/{test_trigger_tallies/test_trigger_tallies.py => regression_tests/trigger_tallies/test.py} (76%) rename tests/{test_triso => regression_tests/triso}/inputs_true.dat (100%) rename tests/{test_triso => regression_tests/triso}/results_true.dat (100%) rename tests/{test_triso/test_triso.py => regression_tests/triso/test.py} (98%) rename tests/{test_uniform_fs => regression_tests/uniform_fs}/geometry.xml (100%) rename tests/{test_uniform_fs => regression_tests/uniform_fs}/materials.xml (100%) rename tests/{test_uniform_fs => regression_tests/uniform_fs}/results_true.dat (100%) rename tests/{test_uniform_fs => regression_tests/uniform_fs}/settings.xml (100%) create mode 100644 tests/regression_tests/uniform_fs/test.py rename tests/{test_universe => regression_tests/universe}/geometry.xml (100%) rename tests/{test_universe => regression_tests/universe}/materials.xml (100%) rename tests/{test_universe => regression_tests/universe}/results_true.dat (100%) rename tests/{test_universe => regression_tests/universe}/settings.xml (100%) create mode 100644 tests/regression_tests/universe/test.py rename tests/{test_void => regression_tests/void}/geometry.xml (100%) rename tests/{test_void => regression_tests/void}/materials.xml (100%) rename tests/{test_void => regression_tests/void}/results_true.dat (100%) rename tests/{test_void => regression_tests/void}/settings.xml (100%) create mode 100644 tests/regression_tests/void/test.py rename tests/{test_volume_calc => regression_tests/volume_calc}/inputs_true.dat (100%) rename tests/{test_volume_calc => regression_tests/volume_calc}/results_true.dat (100%) rename tests/{test_volume_calc/test_volume_calc.py => regression_tests/volume_calc/test.py} (98%) delete mode 100755 tests/test_complex_cell/test_complex_cell.py delete mode 100644 tests/test_infinite_cell/test_infinite_cell.py delete mode 100644 tests/test_lattice/test_lattice.py delete mode 100644 tests/test_lattice_hex/test_lattice_hex.py delete mode 100644 tests/test_lattice_mixed/test_lattice_mixed.py delete mode 100644 tests/test_lattice_multiple/test_lattice_multiple.py delete mode 100644 tests/test_ptables_off/test_ptables_off.py delete mode 100755 tests/test_quadric_surfaces/test_quadric_surfaces.py delete mode 100644 tests/test_reflective_plane/test_reflective_plane.py delete mode 100644 tests/test_rotation/test_rotation.py delete mode 100644 tests/test_seed/test_seed.py delete mode 100644 tests/test_sourcepoint_restart/test_sourcepoint_restart.py delete mode 100644 tests/test_survival_biasing/test_survival_biasing.py delete mode 100644 tests/test_tally_assumesep/test_tally_assumesep.py delete mode 100644 tests/test_tally_nuclides/test_tally_nuclides.py delete mode 100644 tests/test_trace/test_trace.py delete mode 100644 tests/test_translation/test_translation.py delete mode 100644 tests/test_trigger_no_status/test_trigger_no_status.py delete mode 100644 tests/test_uniform_fs/test_uniform_fs.py delete mode 100644 tests/test_universe/test_universe.py delete mode 100644 tests/test_void/test_void.py diff --git a/CMakeLists.txt b/CMakeLists.txt index cb4f9bb3d7..5d0fcb0ab3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -531,7 +531,7 @@ endif() include(CTest) # Get a list of all the tests to run -file(GLOB_RECURSE TESTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/test_*.py) +file(GLOB_RECURSE TESTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/test.py) # Loop through all the tests foreach(test ${TESTS}) @@ -552,20 +552,20 @@ foreach(test ${TESTS}) endif() # Add serial test - add_test(NAME ${TEST_NAME} + add_test(NAME ${TEST_PATH} WORKING_DIRECTORY ${TEST_PATH} COMMAND $) else() # Check serial/parallel if (${MPI_ENABLED}) # Preform a parallel test - add_test(NAME ${TEST_NAME} + add_test(NAME ${TEST_PATH} WORKING_DIRECTORY ${TEST_PATH} COMMAND ${PYTHON_EXECUTABLE} ${TEST_NAME} --exe $ --mpi_exec ${MPI_DIR}/mpiexec) else() # Perform a serial test - add_test(NAME ${TEST_NAME} + add_test(NAME ${TEST_PATH} WORKING_DIRECTORY ${TEST_PATH} COMMAND ${PYTHON_EXECUTABLE} ${TEST_NAME} --exe $) endif() diff --git a/openmc/examples.py b/openmc/examples.py index 3d6a068273..d48d26839f 100644 --- a/openmc/examples.py +++ b/openmc/examples.py @@ -587,7 +587,7 @@ def slab_mg(reps=None, as_macro=True): # Define the materials file model.xs_data = xs - model.materials.cross_sections = "../1d_mgxs.h5" + model.materials.cross_sections = "../../1d_mgxs.h5" # Define surfaces. # Assembly/Problem Boundary diff --git a/tests/test_asymmetric_lattice/inputs_true.dat b/tests/regression_tests/asymmetric_lattice/inputs_true.dat similarity index 100% rename from tests/test_asymmetric_lattice/inputs_true.dat rename to tests/regression_tests/asymmetric_lattice/inputs_true.dat diff --git a/tests/test_asymmetric_lattice/results_true.dat b/tests/regression_tests/asymmetric_lattice/results_true.dat similarity index 100% rename from tests/test_asymmetric_lattice/results_true.dat rename to tests/regression_tests/asymmetric_lattice/results_true.dat diff --git a/tests/test_asymmetric_lattice/test_asymmetric_lattice.py b/tests/regression_tests/asymmetric_lattice/test.py similarity index 98% rename from tests/test_asymmetric_lattice/test_asymmetric_lattice.py rename to tests/regression_tests/asymmetric_lattice/test.py index 58c1b22ab5..f7cbf35c62 100644 --- a/tests/test_asymmetric_lattice/test_asymmetric_lattice.py +++ b/tests/regression_tests/asymmetric_lattice/test.py @@ -4,7 +4,7 @@ import os import sys import glob import hashlib -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc diff --git a/tests/test_cmfd_feed/cmfd.xml b/tests/regression_tests/cmfd_feed/cmfd.xml similarity index 100% rename from tests/test_cmfd_feed/cmfd.xml rename to tests/regression_tests/cmfd_feed/cmfd.xml diff --git a/tests/test_cmfd_feed/geometry.xml b/tests/regression_tests/cmfd_feed/geometry.xml similarity index 100% rename from tests/test_cmfd_feed/geometry.xml rename to tests/regression_tests/cmfd_feed/geometry.xml diff --git a/tests/test_cmfd_feed/materials.xml b/tests/regression_tests/cmfd_feed/materials.xml similarity index 100% rename from tests/test_cmfd_feed/materials.xml rename to tests/regression_tests/cmfd_feed/materials.xml diff --git a/tests/test_cmfd_feed/results_true.dat b/tests/regression_tests/cmfd_feed/results_true.dat similarity index 100% rename from tests/test_cmfd_feed/results_true.dat rename to tests/regression_tests/cmfd_feed/results_true.dat diff --git a/tests/test_cmfd_feed/settings.xml b/tests/regression_tests/cmfd_feed/settings.xml similarity index 100% rename from tests/test_cmfd_feed/settings.xml rename to tests/regression_tests/cmfd_feed/settings.xml diff --git a/tests/test_cmfd_feed/tallies.xml b/tests/regression_tests/cmfd_feed/tallies.xml similarity index 100% rename from tests/test_cmfd_feed/tallies.xml rename to tests/regression_tests/cmfd_feed/tallies.xml diff --git a/tests/test_cmfd_feed/test_cmfd_feed.py b/tests/regression_tests/cmfd_feed/test.py similarity index 77% rename from tests/test_cmfd_feed/test_cmfd_feed.py rename to tests/regression_tests/cmfd_feed/test.py index 17bebf68c0..30e61d03f5 100644 --- a/tests/test_cmfd_feed/test_cmfd_feed.py +++ b/tests/regression_tests/cmfd_feed/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import CMFDTestHarness diff --git a/tests/test_cmfd_nofeed/cmfd.xml b/tests/regression_tests/cmfd_nofeed/cmfd.xml similarity index 100% rename from tests/test_cmfd_nofeed/cmfd.xml rename to tests/regression_tests/cmfd_nofeed/cmfd.xml diff --git a/tests/test_cmfd_nofeed/geometry.xml b/tests/regression_tests/cmfd_nofeed/geometry.xml similarity index 100% rename from tests/test_cmfd_nofeed/geometry.xml rename to tests/regression_tests/cmfd_nofeed/geometry.xml diff --git a/tests/test_cmfd_nofeed/materials.xml b/tests/regression_tests/cmfd_nofeed/materials.xml similarity index 100% rename from tests/test_cmfd_nofeed/materials.xml rename to tests/regression_tests/cmfd_nofeed/materials.xml diff --git a/tests/test_cmfd_nofeed/results_true.dat b/tests/regression_tests/cmfd_nofeed/results_true.dat similarity index 100% rename from tests/test_cmfd_nofeed/results_true.dat rename to tests/regression_tests/cmfd_nofeed/results_true.dat diff --git a/tests/test_cmfd_nofeed/settings.xml b/tests/regression_tests/cmfd_nofeed/settings.xml similarity index 100% rename from tests/test_cmfd_nofeed/settings.xml rename to tests/regression_tests/cmfd_nofeed/settings.xml diff --git a/tests/test_cmfd_nofeed/tallies.xml b/tests/regression_tests/cmfd_nofeed/tallies.xml similarity index 100% rename from tests/test_cmfd_nofeed/tallies.xml rename to tests/regression_tests/cmfd_nofeed/tallies.xml diff --git a/tests/test_cmfd_nofeed/test_cmfd_nofeed.py b/tests/regression_tests/cmfd_nofeed/test.py similarity index 77% rename from tests/test_cmfd_nofeed/test_cmfd_nofeed.py rename to tests/regression_tests/cmfd_nofeed/test.py index 17bebf68c0..30e61d03f5 100644 --- a/tests/test_cmfd_nofeed/test_cmfd_nofeed.py +++ b/tests/regression_tests/cmfd_nofeed/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import CMFDTestHarness diff --git a/tests/test_complex_cell/geometry.xml b/tests/regression_tests/complex_cell/geometry.xml similarity index 100% rename from tests/test_complex_cell/geometry.xml rename to tests/regression_tests/complex_cell/geometry.xml diff --git a/tests/test_complex_cell/materials.xml b/tests/regression_tests/complex_cell/materials.xml similarity index 100% rename from tests/test_complex_cell/materials.xml rename to tests/regression_tests/complex_cell/materials.xml diff --git a/tests/test_complex_cell/results_true.dat b/tests/regression_tests/complex_cell/results_true.dat similarity index 100% rename from tests/test_complex_cell/results_true.dat rename to tests/regression_tests/complex_cell/results_true.dat diff --git a/tests/test_complex_cell/settings.xml b/tests/regression_tests/complex_cell/settings.xml similarity index 100% rename from tests/test_complex_cell/settings.xml rename to tests/regression_tests/complex_cell/settings.xml diff --git a/tests/test_complex_cell/tallies.xml b/tests/regression_tests/complex_cell/tallies.xml similarity index 100% rename from tests/test_complex_cell/tallies.xml rename to tests/regression_tests/complex_cell/tallies.xml diff --git a/tests/test_confidence_intervals/test_confidence_intervals.py b/tests/regression_tests/complex_cell/test.py similarity index 76% rename from tests/test_confidence_intervals/test_confidence_intervals.py rename to tests/regression_tests/complex_cell/test.py index b04fcc6eba..43f8e5ff0f 100755 --- a/tests/test_confidence_intervals/test_confidence_intervals.py +++ b/tests/regression_tests/complex_cell/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness diff --git a/tests/test_confidence_intervals/geometry.xml b/tests/regression_tests/confidence_intervals/geometry.xml similarity index 100% rename from tests/test_confidence_intervals/geometry.xml rename to tests/regression_tests/confidence_intervals/geometry.xml diff --git a/tests/test_confidence_intervals/materials.xml b/tests/regression_tests/confidence_intervals/materials.xml similarity index 100% rename from tests/test_confidence_intervals/materials.xml rename to tests/regression_tests/confidence_intervals/materials.xml diff --git a/tests/test_confidence_intervals/results_true.dat b/tests/regression_tests/confidence_intervals/results_true.dat similarity index 100% rename from tests/test_confidence_intervals/results_true.dat rename to tests/regression_tests/confidence_intervals/results_true.dat diff --git a/tests/test_confidence_intervals/settings.xml b/tests/regression_tests/confidence_intervals/settings.xml similarity index 100% rename from tests/test_confidence_intervals/settings.xml rename to tests/regression_tests/confidence_intervals/settings.xml diff --git a/tests/test_confidence_intervals/tallies.xml b/tests/regression_tests/confidence_intervals/tallies.xml similarity index 100% rename from tests/test_confidence_intervals/tallies.xml rename to tests/regression_tests/confidence_intervals/tallies.xml diff --git a/tests/test_density/test_density.py b/tests/regression_tests/confidence_intervals/test.py old mode 100644 new mode 100755 similarity index 76% rename from tests/test_density/test_density.py rename to tests/regression_tests/confidence_intervals/test.py index b04fcc6eba..43f8e5ff0f --- a/tests/test_density/test_density.py +++ b/tests/regression_tests/confidence_intervals/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness diff --git a/tests/test_create_fission_neutrons/inputs_true.dat b/tests/regression_tests/create_fission_neutrons/inputs_true.dat similarity index 100% rename from tests/test_create_fission_neutrons/inputs_true.dat rename to tests/regression_tests/create_fission_neutrons/inputs_true.dat diff --git a/tests/test_create_fission_neutrons/results_true.dat b/tests/regression_tests/create_fission_neutrons/results_true.dat similarity index 100% rename from tests/test_create_fission_neutrons/results_true.dat rename to tests/regression_tests/create_fission_neutrons/results_true.dat diff --git a/tests/test_create_fission_neutrons/test_create_fission_neutrons.py b/tests/regression_tests/create_fission_neutrons/test.py similarity index 97% rename from tests/test_create_fission_neutrons/test_create_fission_neutrons.py rename to tests/regression_tests/create_fission_neutrons/test.py index 87abeda7fe..080a0ab0d8 100755 --- a/tests/test_create_fission_neutrons/test_create_fission_neutrons.py +++ b/tests/regression_tests/create_fission_neutrons/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc diff --git a/tests/test_density/geometry.xml b/tests/regression_tests/density/geometry.xml similarity index 100% rename from tests/test_density/geometry.xml rename to tests/regression_tests/density/geometry.xml diff --git a/tests/test_density/materials.xml b/tests/regression_tests/density/materials.xml similarity index 100% rename from tests/test_density/materials.xml rename to tests/regression_tests/density/materials.xml diff --git a/tests/test_density/results_true.dat b/tests/regression_tests/density/results_true.dat similarity index 100% rename from tests/test_density/results_true.dat rename to tests/regression_tests/density/results_true.dat diff --git a/tests/test_density/settings.xml b/tests/regression_tests/density/settings.xml similarity index 100% rename from tests/test_density/settings.xml rename to tests/regression_tests/density/settings.xml diff --git a/tests/test_eigenvalue_no_inactive/test_eigenvalue_no_inactive.py b/tests/regression_tests/density/test.py similarity index 76% rename from tests/test_eigenvalue_no_inactive/test_eigenvalue_no_inactive.py rename to tests/regression_tests/density/test.py index b04fcc6eba..43f8e5ff0f 100644 --- a/tests/test_eigenvalue_no_inactive/test_eigenvalue_no_inactive.py +++ b/tests/regression_tests/density/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness diff --git a/tests/test_diff_tally/inputs_true.dat b/tests/regression_tests/diff_tally/inputs_true.dat similarity index 100% rename from tests/test_diff_tally/inputs_true.dat rename to tests/regression_tests/diff_tally/inputs_true.dat diff --git a/tests/test_diff_tally/results_true.dat b/tests/regression_tests/diff_tally/results_true.dat similarity index 100% rename from tests/test_diff_tally/results_true.dat rename to tests/regression_tests/diff_tally/results_true.dat diff --git a/tests/test_diff_tally/test_diff_tally.py b/tests/regression_tests/diff_tally/test.py similarity index 98% rename from tests/test_diff_tally/test_diff_tally.py rename to tests/regression_tests/diff_tally/test.py index 02798e70e0..5f1da9c30a 100644 --- a/tests/test_diff_tally/test_diff_tally.py +++ b/tests/regression_tests/diff_tally/test.py @@ -6,7 +6,7 @@ import sys import pandas as pd -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc diff --git a/tests/test_distribmat/inputs_true.dat b/tests/regression_tests/distribmat/inputs_true.dat similarity index 100% rename from tests/test_distribmat/inputs_true.dat rename to tests/regression_tests/distribmat/inputs_true.dat diff --git a/tests/test_distribmat/results_true.dat b/tests/regression_tests/distribmat/results_true.dat similarity index 100% rename from tests/test_distribmat/results_true.dat rename to tests/regression_tests/distribmat/results_true.dat diff --git a/tests/test_distribmat/test_distribmat.py b/tests/regression_tests/distribmat/test.py similarity index 98% rename from tests/test_distribmat/test_distribmat.py rename to tests/regression_tests/distribmat/test.py index 9dd5d319a2..d18bb15430 100644 --- a/tests/test_distribmat/test_distribmat.py +++ b/tests/regression_tests/distribmat/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness, PyAPITestHarness import openmc diff --git a/tests/test_eigenvalue_genperbatch/geometry.xml b/tests/regression_tests/eigenvalue_genperbatch/geometry.xml similarity index 100% rename from tests/test_eigenvalue_genperbatch/geometry.xml rename to tests/regression_tests/eigenvalue_genperbatch/geometry.xml diff --git a/tests/test_eigenvalue_genperbatch/materials.xml b/tests/regression_tests/eigenvalue_genperbatch/materials.xml similarity index 100% rename from tests/test_eigenvalue_genperbatch/materials.xml rename to tests/regression_tests/eigenvalue_genperbatch/materials.xml diff --git a/tests/test_eigenvalue_genperbatch/results_true.dat b/tests/regression_tests/eigenvalue_genperbatch/results_true.dat similarity index 100% rename from tests/test_eigenvalue_genperbatch/results_true.dat rename to tests/regression_tests/eigenvalue_genperbatch/results_true.dat diff --git a/tests/test_eigenvalue_genperbatch/settings.xml b/tests/regression_tests/eigenvalue_genperbatch/settings.xml similarity index 100% rename from tests/test_eigenvalue_genperbatch/settings.xml rename to tests/regression_tests/eigenvalue_genperbatch/settings.xml diff --git a/tests/test_eigenvalue_genperbatch/test_eigenvalue_genperbatch.py b/tests/regression_tests/eigenvalue_genperbatch/test.py similarity index 76% rename from tests/test_eigenvalue_genperbatch/test_eigenvalue_genperbatch.py rename to tests/regression_tests/eigenvalue_genperbatch/test.py index 59a60b63a4..a36c2ae374 100644 --- a/tests/test_eigenvalue_genperbatch/test_eigenvalue_genperbatch.py +++ b/tests/regression_tests/eigenvalue_genperbatch/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness diff --git a/tests/test_eigenvalue_no_inactive/geometry.xml b/tests/regression_tests/eigenvalue_no_inactive/geometry.xml similarity index 100% rename from tests/test_eigenvalue_no_inactive/geometry.xml rename to tests/regression_tests/eigenvalue_no_inactive/geometry.xml diff --git a/tests/test_eigenvalue_no_inactive/materials.xml b/tests/regression_tests/eigenvalue_no_inactive/materials.xml similarity index 100% rename from tests/test_eigenvalue_no_inactive/materials.xml rename to tests/regression_tests/eigenvalue_no_inactive/materials.xml diff --git a/tests/test_eigenvalue_no_inactive/results_true.dat b/tests/regression_tests/eigenvalue_no_inactive/results_true.dat similarity index 100% rename from tests/test_eigenvalue_no_inactive/results_true.dat rename to tests/regression_tests/eigenvalue_no_inactive/results_true.dat diff --git a/tests/test_eigenvalue_no_inactive/settings.xml b/tests/regression_tests/eigenvalue_no_inactive/settings.xml similarity index 100% rename from tests/test_eigenvalue_no_inactive/settings.xml rename to tests/regression_tests/eigenvalue_no_inactive/settings.xml diff --git a/tests/test_energy_grid/test_energy_grid.py b/tests/regression_tests/eigenvalue_no_inactive/test.py similarity index 76% rename from tests/test_energy_grid/test_energy_grid.py rename to tests/regression_tests/eigenvalue_no_inactive/test.py index b04fcc6eba..43f8e5ff0f 100644 --- a/tests/test_energy_grid/test_energy_grid.py +++ b/tests/regression_tests/eigenvalue_no_inactive/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness diff --git a/tests/test_energy_cutoff/inputs_true.dat b/tests/regression_tests/energy_cutoff/inputs_true.dat similarity index 100% rename from tests/test_energy_cutoff/inputs_true.dat rename to tests/regression_tests/energy_cutoff/inputs_true.dat diff --git a/tests/test_energy_cutoff/results_true.dat b/tests/regression_tests/energy_cutoff/results_true.dat similarity index 100% rename from tests/test_energy_cutoff/results_true.dat rename to tests/regression_tests/energy_cutoff/results_true.dat diff --git a/tests/test_energy_cutoff/test_energy_cutoff.py b/tests/regression_tests/energy_cutoff/test.py similarity index 97% rename from tests/test_energy_cutoff/test_energy_cutoff.py rename to tests/regression_tests/energy_cutoff/test.py index 3aa3400c7a..74f7b2ab2a 100755 --- a/tests/test_energy_cutoff/test_energy_cutoff.py +++ b/tests/regression_tests/energy_cutoff/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc diff --git a/tests/test_energy_grid/geometry.xml b/tests/regression_tests/energy_grid/geometry.xml similarity index 100% rename from tests/test_energy_grid/geometry.xml rename to tests/regression_tests/energy_grid/geometry.xml diff --git a/tests/test_energy_grid/materials.xml b/tests/regression_tests/energy_grid/materials.xml similarity index 100% rename from tests/test_energy_grid/materials.xml rename to tests/regression_tests/energy_grid/materials.xml diff --git a/tests/test_energy_grid/results_true.dat b/tests/regression_tests/energy_grid/results_true.dat similarity index 100% rename from tests/test_energy_grid/results_true.dat rename to tests/regression_tests/energy_grid/results_true.dat diff --git a/tests/test_energy_grid/settings.xml b/tests/regression_tests/energy_grid/settings.xml similarity index 100% rename from tests/test_energy_grid/settings.xml rename to tests/regression_tests/energy_grid/settings.xml diff --git a/tests/regression_tests/energy_grid/test.py b/tests/regression_tests/energy_grid/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/energy_grid/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_energy_laws/geometry.xml b/tests/regression_tests/energy_laws/geometry.xml similarity index 100% rename from tests/test_energy_laws/geometry.xml rename to tests/regression_tests/energy_laws/geometry.xml diff --git a/tests/test_energy_laws/materials.xml b/tests/regression_tests/energy_laws/materials.xml similarity index 100% rename from tests/test_energy_laws/materials.xml rename to tests/regression_tests/energy_laws/materials.xml diff --git a/tests/test_energy_laws/results_true.dat b/tests/regression_tests/energy_laws/results_true.dat similarity index 100% rename from tests/test_energy_laws/results_true.dat rename to tests/regression_tests/energy_laws/results_true.dat diff --git a/tests/test_energy_laws/settings.xml b/tests/regression_tests/energy_laws/settings.xml similarity index 100% rename from tests/test_energy_laws/settings.xml rename to tests/regression_tests/energy_laws/settings.xml diff --git a/tests/test_energy_laws/test_energy_laws.py b/tests/regression_tests/energy_laws/test.py similarity index 93% rename from tests/test_energy_laws/test_energy_laws.py rename to tests/regression_tests/energy_laws/test.py index 254126ff30..5180344dab 100644 --- a/tests/test_energy_laws/test_energy_laws.py +++ b/tests/regression_tests/energy_laws/test.py @@ -21,7 +21,7 @@ that use linear-linear interpolation. import glob import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness diff --git a/tests/test_enrichment/test_enrichment.py b/tests/regression_tests/enrichment/test.py similarity index 97% rename from tests/test_enrichment/test_enrichment.py rename to tests/regression_tests/enrichment/test.py index fa65d6dce0..395fafdf56 100644 --- a/tests/test_enrichment/test_enrichment.py +++ b/tests/regression_tests/enrichment/test.py @@ -5,7 +5,6 @@ import sys import numpy as np -sys.path.insert(0, os.pardir) sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from openmc import Material from openmc.data import NATURAL_ABUNDANCE, atomic_mass diff --git a/tests/test_entropy/geometry.xml b/tests/regression_tests/entropy/geometry.xml similarity index 100% rename from tests/test_entropy/geometry.xml rename to tests/regression_tests/entropy/geometry.xml diff --git a/tests/test_entropy/materials.xml b/tests/regression_tests/entropy/materials.xml similarity index 100% rename from tests/test_entropy/materials.xml rename to tests/regression_tests/entropy/materials.xml diff --git a/tests/test_entropy/results_true.dat b/tests/regression_tests/entropy/results_true.dat similarity index 100% rename from tests/test_entropy/results_true.dat rename to tests/regression_tests/entropy/results_true.dat diff --git a/tests/test_entropy/settings.xml b/tests/regression_tests/entropy/settings.xml similarity index 100% rename from tests/test_entropy/settings.xml rename to tests/regression_tests/entropy/settings.xml diff --git a/tests/test_entropy/test_entropy.py b/tests/regression_tests/entropy/test.py similarity index 94% rename from tests/test_entropy/test_entropy.py rename to tests/regression_tests/entropy/test.py index 36e2170af8..bbc6c0c7f4 100644 --- a/tests/test_entropy/test_entropy.py +++ b/tests/regression_tests/entropy/test.py @@ -3,7 +3,7 @@ import glob import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness from openmc import StatePoint diff --git a/tests/test_filter_distribcell/case-1/geometry.xml b/tests/regression_tests/filter_distribcell/case-1/geometry.xml similarity index 100% rename from tests/test_filter_distribcell/case-1/geometry.xml rename to tests/regression_tests/filter_distribcell/case-1/geometry.xml diff --git a/tests/test_filter_distribcell/case-1/materials.xml b/tests/regression_tests/filter_distribcell/case-1/materials.xml similarity index 100% rename from tests/test_filter_distribcell/case-1/materials.xml rename to tests/regression_tests/filter_distribcell/case-1/materials.xml diff --git a/tests/test_filter_distribcell/case-1/results_true.dat b/tests/regression_tests/filter_distribcell/case-1/results_true.dat similarity index 100% rename from tests/test_filter_distribcell/case-1/results_true.dat rename to tests/regression_tests/filter_distribcell/case-1/results_true.dat diff --git a/tests/test_filter_distribcell/case-1/settings.xml b/tests/regression_tests/filter_distribcell/case-1/settings.xml similarity index 100% rename from tests/test_filter_distribcell/case-1/settings.xml rename to tests/regression_tests/filter_distribcell/case-1/settings.xml diff --git a/tests/test_filter_distribcell/case-1/tallies.xml b/tests/regression_tests/filter_distribcell/case-1/tallies.xml similarity index 100% rename from tests/test_filter_distribcell/case-1/tallies.xml rename to tests/regression_tests/filter_distribcell/case-1/tallies.xml diff --git a/tests/test_filter_distribcell/case-2/geometry.xml b/tests/regression_tests/filter_distribcell/case-2/geometry.xml similarity index 100% rename from tests/test_filter_distribcell/case-2/geometry.xml rename to tests/regression_tests/filter_distribcell/case-2/geometry.xml diff --git a/tests/test_filter_distribcell/case-2/materials.xml b/tests/regression_tests/filter_distribcell/case-2/materials.xml similarity index 100% rename from tests/test_filter_distribcell/case-2/materials.xml rename to tests/regression_tests/filter_distribcell/case-2/materials.xml diff --git a/tests/test_filter_distribcell/case-2/results_true.dat b/tests/regression_tests/filter_distribcell/case-2/results_true.dat similarity index 100% rename from tests/test_filter_distribcell/case-2/results_true.dat rename to tests/regression_tests/filter_distribcell/case-2/results_true.dat diff --git a/tests/test_filter_distribcell/case-2/settings.xml b/tests/regression_tests/filter_distribcell/case-2/settings.xml similarity index 100% rename from tests/test_filter_distribcell/case-2/settings.xml rename to tests/regression_tests/filter_distribcell/case-2/settings.xml diff --git a/tests/test_filter_distribcell/case-2/tallies.xml b/tests/regression_tests/filter_distribcell/case-2/tallies.xml similarity index 100% rename from tests/test_filter_distribcell/case-2/tallies.xml rename to tests/regression_tests/filter_distribcell/case-2/tallies.xml diff --git a/tests/test_filter_distribcell/case-3/geometry.xml b/tests/regression_tests/filter_distribcell/case-3/geometry.xml similarity index 100% rename from tests/test_filter_distribcell/case-3/geometry.xml rename to tests/regression_tests/filter_distribcell/case-3/geometry.xml diff --git a/tests/test_filter_distribcell/case-3/materials.xml b/tests/regression_tests/filter_distribcell/case-3/materials.xml similarity index 100% rename from tests/test_filter_distribcell/case-3/materials.xml rename to tests/regression_tests/filter_distribcell/case-3/materials.xml diff --git a/tests/test_filter_distribcell/case-3/results_true.dat b/tests/regression_tests/filter_distribcell/case-3/results_true.dat similarity index 100% rename from tests/test_filter_distribcell/case-3/results_true.dat rename to tests/regression_tests/filter_distribcell/case-3/results_true.dat diff --git a/tests/test_filter_distribcell/case-3/settings.xml b/tests/regression_tests/filter_distribcell/case-3/settings.xml similarity index 100% rename from tests/test_filter_distribcell/case-3/settings.xml rename to tests/regression_tests/filter_distribcell/case-3/settings.xml diff --git a/tests/test_filter_distribcell/case-3/tallies.xml b/tests/regression_tests/filter_distribcell/case-3/tallies.xml similarity index 100% rename from tests/test_filter_distribcell/case-3/tallies.xml rename to tests/regression_tests/filter_distribcell/case-3/tallies.xml diff --git a/tests/test_filter_distribcell/case-4/geometry.xml b/tests/regression_tests/filter_distribcell/case-4/geometry.xml similarity index 100% rename from tests/test_filter_distribcell/case-4/geometry.xml rename to tests/regression_tests/filter_distribcell/case-4/geometry.xml diff --git a/tests/test_filter_distribcell/case-4/materials.xml b/tests/regression_tests/filter_distribcell/case-4/materials.xml similarity index 100% rename from tests/test_filter_distribcell/case-4/materials.xml rename to tests/regression_tests/filter_distribcell/case-4/materials.xml diff --git a/tests/test_filter_distribcell/case-4/results_true.dat b/tests/regression_tests/filter_distribcell/case-4/results_true.dat similarity index 100% rename from tests/test_filter_distribcell/case-4/results_true.dat rename to tests/regression_tests/filter_distribcell/case-4/results_true.dat diff --git a/tests/test_filter_distribcell/case-4/settings.xml b/tests/regression_tests/filter_distribcell/case-4/settings.xml similarity index 100% rename from tests/test_filter_distribcell/case-4/settings.xml rename to tests/regression_tests/filter_distribcell/case-4/settings.xml diff --git a/tests/test_filter_distribcell/case-4/tallies.xml b/tests/regression_tests/filter_distribcell/case-4/tallies.xml similarity index 100% rename from tests/test_filter_distribcell/case-4/tallies.xml rename to tests/regression_tests/filter_distribcell/case-4/tallies.xml diff --git a/tests/test_filter_distribcell/test_filter_distribcell.py b/tests/regression_tests/filter_distribcell/test.py similarity index 98% rename from tests/test_filter_distribcell/test_filter_distribcell.py rename to tests/regression_tests/filter_distribcell/test.py index f0fc270399..320a808a5f 100644 --- a/tests/test_filter_distribcell/test_filter_distribcell.py +++ b/tests/regression_tests/filter_distribcell/test.py @@ -4,7 +4,7 @@ import glob import hashlib import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import * diff --git a/tests/test_filter_energyfun/inputs_true.dat b/tests/regression_tests/filter_energyfun/inputs_true.dat similarity index 100% rename from tests/test_filter_energyfun/inputs_true.dat rename to tests/regression_tests/filter_energyfun/inputs_true.dat diff --git a/tests/test_filter_energyfun/results_true.dat b/tests/regression_tests/filter_energyfun/results_true.dat similarity index 100% rename from tests/test_filter_energyfun/results_true.dat rename to tests/regression_tests/filter_energyfun/results_true.dat diff --git a/tests/test_filter_energyfun/test_filter_energyfun.py b/tests/regression_tests/filter_energyfun/test.py similarity index 97% rename from tests/test_filter_energyfun/test_filter_energyfun.py rename to tests/regression_tests/filter_energyfun/test.py index 7e787edff2..1de522f540 100644 --- a/tests/test_filter_energyfun/test_filter_energyfun.py +++ b/tests/regression_tests/filter_energyfun/test.py @@ -3,7 +3,7 @@ import os import sys import glob -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc diff --git a/tests/test_filter_mesh/inputs_true.dat b/tests/regression_tests/filter_mesh/inputs_true.dat similarity index 100% rename from tests/test_filter_mesh/inputs_true.dat rename to tests/regression_tests/filter_mesh/inputs_true.dat diff --git a/tests/test_filter_mesh/results_true.dat b/tests/regression_tests/filter_mesh/results_true.dat similarity index 100% rename from tests/test_filter_mesh/results_true.dat rename to tests/regression_tests/filter_mesh/results_true.dat diff --git a/tests/test_filter_mesh/test_filter_mesh.py b/tests/regression_tests/filter_mesh/test.py similarity index 97% rename from tests/test_filter_mesh/test_filter_mesh.py rename to tests/regression_tests/filter_mesh/test.py index 7b9e8bd16b..4ad5e9005b 100644 --- a/tests/test_filter_mesh/test_filter_mesh.py +++ b/tests/regression_tests/filter_mesh/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import HashedPyAPITestHarness import openmc diff --git a/tests/test_fixed_source/inputs_true.dat b/tests/regression_tests/fixed_source/inputs_true.dat similarity index 100% rename from tests/test_fixed_source/inputs_true.dat rename to tests/regression_tests/fixed_source/inputs_true.dat diff --git a/tests/test_fixed_source/results_true.dat b/tests/regression_tests/fixed_source/results_true.dat similarity index 100% rename from tests/test_fixed_source/results_true.dat rename to tests/regression_tests/fixed_source/results_true.dat diff --git a/tests/test_fixed_source/test_fixed_source.py b/tests/regression_tests/fixed_source/test.py similarity index 97% rename from tests/test_fixed_source/test_fixed_source.py rename to tests/regression_tests/fixed_source/test.py index db58e2f706..3e28610fb0 100644 --- a/tests/test_fixed_source/test_fixed_source.py +++ b/tests/regression_tests/fixed_source/test.py @@ -4,7 +4,7 @@ import glob import os import sys import numpy as np -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc import openmc.stats diff --git a/tests/test_infinite_cell/geometry.xml b/tests/regression_tests/infinite_cell/geometry.xml similarity index 100% rename from tests/test_infinite_cell/geometry.xml rename to tests/regression_tests/infinite_cell/geometry.xml diff --git a/tests/test_infinite_cell/materials.xml b/tests/regression_tests/infinite_cell/materials.xml similarity index 100% rename from tests/test_infinite_cell/materials.xml rename to tests/regression_tests/infinite_cell/materials.xml diff --git a/tests/test_infinite_cell/results_true.dat b/tests/regression_tests/infinite_cell/results_true.dat similarity index 100% rename from tests/test_infinite_cell/results_true.dat rename to tests/regression_tests/infinite_cell/results_true.dat diff --git a/tests/test_infinite_cell/settings.xml b/tests/regression_tests/infinite_cell/settings.xml similarity index 100% rename from tests/test_infinite_cell/settings.xml rename to tests/regression_tests/infinite_cell/settings.xml diff --git a/tests/regression_tests/infinite_cell/test.py b/tests/regression_tests/infinite_cell/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/infinite_cell/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_iso_in_lab/inputs_true.dat b/tests/regression_tests/iso_in_lab/inputs_true.dat similarity index 100% rename from tests/test_iso_in_lab/inputs_true.dat rename to tests/regression_tests/iso_in_lab/inputs_true.dat diff --git a/tests/test_iso_in_lab/results_true.dat b/tests/regression_tests/iso_in_lab/results_true.dat similarity index 100% rename from tests/test_iso_in_lab/results_true.dat rename to tests/regression_tests/iso_in_lab/results_true.dat diff --git a/tests/test_iso_in_lab/test_iso_in_lab.py b/tests/regression_tests/iso_in_lab/test.py similarity index 83% rename from tests/test_iso_in_lab/test_iso_in_lab.py rename to tests/regression_tests/iso_in_lab/test.py index 60b5bc2dee..8cc9c7b7d7 100644 --- a/tests/test_iso_in_lab/test_iso_in_lab.py +++ b/tests/regression_tests/iso_in_lab/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness diff --git a/tests/test_lattice/geometry.xml b/tests/regression_tests/lattice/geometry.xml similarity index 100% rename from tests/test_lattice/geometry.xml rename to tests/regression_tests/lattice/geometry.xml diff --git a/tests/test_lattice/materials.xml b/tests/regression_tests/lattice/materials.xml similarity index 100% rename from tests/test_lattice/materials.xml rename to tests/regression_tests/lattice/materials.xml diff --git a/tests/test_lattice/results_true.dat b/tests/regression_tests/lattice/results_true.dat similarity index 100% rename from tests/test_lattice/results_true.dat rename to tests/regression_tests/lattice/results_true.dat diff --git a/tests/test_lattice/settings.xml b/tests/regression_tests/lattice/settings.xml similarity index 100% rename from tests/test_lattice/settings.xml rename to tests/regression_tests/lattice/settings.xml diff --git a/tests/regression_tests/lattice/test.py b/tests/regression_tests/lattice/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/lattice/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_lattice_hex/geometry.xml b/tests/regression_tests/lattice_hex/geometry.xml similarity index 100% rename from tests/test_lattice_hex/geometry.xml rename to tests/regression_tests/lattice_hex/geometry.xml diff --git a/tests/test_lattice_hex/materials.xml b/tests/regression_tests/lattice_hex/materials.xml similarity index 100% rename from tests/test_lattice_hex/materials.xml rename to tests/regression_tests/lattice_hex/materials.xml diff --git a/tests/test_lattice_hex/plots.xml b/tests/regression_tests/lattice_hex/plots.xml similarity index 100% rename from tests/test_lattice_hex/plots.xml rename to tests/regression_tests/lattice_hex/plots.xml diff --git a/tests/test_lattice_hex/results_true.dat b/tests/regression_tests/lattice_hex/results_true.dat similarity index 100% rename from tests/test_lattice_hex/results_true.dat rename to tests/regression_tests/lattice_hex/results_true.dat diff --git a/tests/test_lattice_hex/settings.xml b/tests/regression_tests/lattice_hex/settings.xml similarity index 100% rename from tests/test_lattice_hex/settings.xml rename to tests/regression_tests/lattice_hex/settings.xml diff --git a/tests/regression_tests/lattice_hex/test.py b/tests/regression_tests/lattice_hex/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/lattice_hex/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_lattice_mixed/geometry.xml b/tests/regression_tests/lattice_mixed/geometry.xml similarity index 100% rename from tests/test_lattice_mixed/geometry.xml rename to tests/regression_tests/lattice_mixed/geometry.xml diff --git a/tests/test_lattice_mixed/materials.xml b/tests/regression_tests/lattice_mixed/materials.xml similarity index 100% rename from tests/test_lattice_mixed/materials.xml rename to tests/regression_tests/lattice_mixed/materials.xml diff --git a/tests/test_lattice_mixed/plots.xml b/tests/regression_tests/lattice_mixed/plots.xml similarity index 100% rename from tests/test_lattice_mixed/plots.xml rename to tests/regression_tests/lattice_mixed/plots.xml diff --git a/tests/test_lattice_mixed/results_true.dat b/tests/regression_tests/lattice_mixed/results_true.dat similarity index 100% rename from tests/test_lattice_mixed/results_true.dat rename to tests/regression_tests/lattice_mixed/results_true.dat diff --git a/tests/test_lattice_mixed/settings.xml b/tests/regression_tests/lattice_mixed/settings.xml similarity index 100% rename from tests/test_lattice_mixed/settings.xml rename to tests/regression_tests/lattice_mixed/settings.xml diff --git a/tests/regression_tests/lattice_mixed/test.py b/tests/regression_tests/lattice_mixed/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/lattice_mixed/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_lattice_multiple/geometry.xml b/tests/regression_tests/lattice_multiple/geometry.xml similarity index 100% rename from tests/test_lattice_multiple/geometry.xml rename to tests/regression_tests/lattice_multiple/geometry.xml diff --git a/tests/test_lattice_multiple/materials.xml b/tests/regression_tests/lattice_multiple/materials.xml similarity index 100% rename from tests/test_lattice_multiple/materials.xml rename to tests/regression_tests/lattice_multiple/materials.xml diff --git a/tests/test_lattice_multiple/results_true.dat b/tests/regression_tests/lattice_multiple/results_true.dat similarity index 100% rename from tests/test_lattice_multiple/results_true.dat rename to tests/regression_tests/lattice_multiple/results_true.dat diff --git a/tests/test_lattice_multiple/settings.xml b/tests/regression_tests/lattice_multiple/settings.xml similarity index 100% rename from tests/test_lattice_multiple/settings.xml rename to tests/regression_tests/lattice_multiple/settings.xml diff --git a/tests/regression_tests/lattice_multiple/test.py b/tests/regression_tests/lattice_multiple/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/lattice_multiple/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_mg_basic/inputs_true.dat b/tests/regression_tests/mg_basic/inputs_true.dat similarity index 98% rename from tests/test_mg_basic/inputs_true.dat rename to tests/regression_tests/mg_basic/inputs_true.dat index 220b1de240..a0efdbde0f 100644 --- a/tests/test_mg_basic/inputs_true.dat +++ b/tests/regression_tests/mg_basic/inputs_true.dat @@ -32,7 +32,7 @@ - ../1d_mgxs.h5 + ../../1d_mgxs.h5 diff --git a/tests/test_mg_basic/results_true.dat b/tests/regression_tests/mg_basic/results_true.dat similarity index 100% rename from tests/test_mg_basic/results_true.dat rename to tests/regression_tests/mg_basic/results_true.dat diff --git a/tests/test_mg_basic/test_mg_basic.py b/tests/regression_tests/mg_basic/test.py similarity index 82% rename from tests/test_mg_basic/test_mg_basic.py rename to tests/regression_tests/mg_basic/test.py index 21871efd72..054503f9ab 100644 --- a/tests/test_mg_basic/test_mg_basic.py +++ b/tests/regression_tests/mg_basic/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness from openmc.examples import slab_mg diff --git a/tests/test_mg_convert/inputs_true.dat b/tests/regression_tests/mg_convert/inputs_true.dat similarity index 100% rename from tests/test_mg_convert/inputs_true.dat rename to tests/regression_tests/mg_convert/inputs_true.dat diff --git a/tests/test_mg_convert/results_true.dat b/tests/regression_tests/mg_convert/results_true.dat similarity index 100% rename from tests/test_mg_convert/results_true.dat rename to tests/regression_tests/mg_convert/results_true.dat diff --git a/tests/test_mg_convert/test_mg_convert.py b/tests/regression_tests/mg_convert/test.py similarity index 99% rename from tests/test_mg_convert/test_mg_convert.py rename to tests/regression_tests/mg_convert/test.py index 36bfe5338b..45f701ff11 100755 --- a/tests/test_mg_convert/test_mg_convert.py +++ b/tests/regression_tests/mg_convert/test.py @@ -3,7 +3,7 @@ import os import sys import hashlib -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) import numpy as np diff --git a/tests/test_mg_legendre/inputs_true.dat b/tests/regression_tests/mg_legendre/inputs_true.dat similarity index 96% rename from tests/test_mg_legendre/inputs_true.dat rename to tests/regression_tests/mg_legendre/inputs_true.dat index 9b63fb944c..7548080955 100644 --- a/tests/test_mg_legendre/inputs_true.dat +++ b/tests/regression_tests/mg_legendre/inputs_true.dat @@ -14,7 +14,7 @@ - ../1d_mgxs.h5 + ../../1d_mgxs.h5 diff --git a/tests/test_mg_legendre/results_true.dat b/tests/regression_tests/mg_legendre/results_true.dat similarity index 100% rename from tests/test_mg_legendre/results_true.dat rename to tests/regression_tests/mg_legendre/results_true.dat diff --git a/tests/test_mg_legendre/test_mg_legendre.py b/tests/regression_tests/mg_legendre/test.py similarity index 85% rename from tests/test_mg_legendre/test_mg_legendre.py rename to tests/regression_tests/mg_legendre/test.py index eee0f0800f..2e574afb61 100644 --- a/tests/test_mg_legendre/test_mg_legendre.py +++ b/tests/regression_tests/mg_legendre/test.py @@ -3,7 +3,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness from openmc.examples import slab_mg diff --git a/tests/test_mg_max_order/inputs_true.dat b/tests/regression_tests/mg_max_order/inputs_true.dat similarity index 96% rename from tests/test_mg_max_order/inputs_true.dat rename to tests/regression_tests/mg_max_order/inputs_true.dat index 3954bc73a7..023d468d4f 100644 --- a/tests/test_mg_max_order/inputs_true.dat +++ b/tests/regression_tests/mg_max_order/inputs_true.dat @@ -14,7 +14,7 @@ - ../1d_mgxs.h5 + ../../1d_mgxs.h5 diff --git a/tests/test_mg_max_order/results_true.dat b/tests/regression_tests/mg_max_order/results_true.dat similarity index 100% rename from tests/test_mg_max_order/results_true.dat rename to tests/regression_tests/mg_max_order/results_true.dat diff --git a/tests/test_mg_max_order/test_mg_max_order.py b/tests/regression_tests/mg_max_order/test.py similarity index 84% rename from tests/test_mg_max_order/test_mg_max_order.py rename to tests/regression_tests/mg_max_order/test.py index 8ac0f58785..21fd2c0b64 100644 --- a/tests/test_mg_max_order/test_mg_max_order.py +++ b/tests/regression_tests/mg_max_order/test.py @@ -3,7 +3,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness from openmc.examples import slab_mg diff --git a/tests/test_mg_nuclide/inputs_true.dat b/tests/regression_tests/mg_nuclide/inputs_true.dat similarity index 98% rename from tests/test_mg_nuclide/inputs_true.dat rename to tests/regression_tests/mg_nuclide/inputs_true.dat index d42b15480d..e11b9e3f07 100644 --- a/tests/test_mg_nuclide/inputs_true.dat +++ b/tests/regression_tests/mg_nuclide/inputs_true.dat @@ -32,7 +32,7 @@ - ../1d_mgxs.h5 + ../../1d_mgxs.h5 diff --git a/tests/test_mg_nuclide/results_true.dat b/tests/regression_tests/mg_nuclide/results_true.dat similarity index 100% rename from tests/test_mg_nuclide/results_true.dat rename to tests/regression_tests/mg_nuclide/results_true.dat diff --git a/tests/test_mg_nuclide/test_mg_nuclide.py b/tests/regression_tests/mg_nuclide/test.py similarity index 82% rename from tests/test_mg_nuclide/test_mg_nuclide.py rename to tests/regression_tests/mg_nuclide/test.py index 0f3c9dd6d7..d1c06cd417 100644 --- a/tests/test_mg_nuclide/test_mg_nuclide.py +++ b/tests/regression_tests/mg_nuclide/test.py @@ -3,7 +3,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness from openmc.examples import slab_mg diff --git a/tests/test_mg_survival_biasing/inputs_true.dat b/tests/regression_tests/mg_survival_biasing/inputs_true.dat similarity index 98% rename from tests/test_mg_survival_biasing/inputs_true.dat rename to tests/regression_tests/mg_survival_biasing/inputs_true.dat index 057af68105..4bc79d48e3 100644 --- a/tests/test_mg_survival_biasing/inputs_true.dat +++ b/tests/regression_tests/mg_survival_biasing/inputs_true.dat @@ -32,7 +32,7 @@ - ../1d_mgxs.h5 + ../../1d_mgxs.h5 diff --git a/tests/test_mg_survival_biasing/results_true.dat b/tests/regression_tests/mg_survival_biasing/results_true.dat similarity index 100% rename from tests/test_mg_survival_biasing/results_true.dat rename to tests/regression_tests/mg_survival_biasing/results_true.dat diff --git a/tests/test_mg_survival_biasing/test_mg_survival_biasing.py b/tests/regression_tests/mg_survival_biasing/test.py similarity index 84% rename from tests/test_mg_survival_biasing/test_mg_survival_biasing.py rename to tests/regression_tests/mg_survival_biasing/test.py index 9886ad3e49..2669201c0e 100644 --- a/tests/test_mg_survival_biasing/test_mg_survival_biasing.py +++ b/tests/regression_tests/mg_survival_biasing/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness from openmc.examples import slab_mg diff --git a/tests/test_mg_tallies/inputs_true.dat b/tests/regression_tests/mg_tallies/inputs_true.dat similarity index 99% rename from tests/test_mg_tallies/inputs_true.dat rename to tests/regression_tests/mg_tallies/inputs_true.dat index 0c71689aea..7b5067014f 100644 --- a/tests/test_mg_tallies/inputs_true.dat +++ b/tests/regression_tests/mg_tallies/inputs_true.dat @@ -32,7 +32,7 @@ - ../1d_mgxs.h5 + ../../1d_mgxs.h5 diff --git a/tests/test_mg_tallies/results_true.dat b/tests/regression_tests/mg_tallies/results_true.dat similarity index 100% rename from tests/test_mg_tallies/results_true.dat rename to tests/regression_tests/mg_tallies/results_true.dat diff --git a/tests/test_mg_tallies/test_mg_tallies.py b/tests/regression_tests/mg_tallies/test.py similarity index 98% rename from tests/test_mg_tallies/test_mg_tallies.py rename to tests/regression_tests/mg_tallies/test.py index aeafae3182..ec7081e2ad 100644 --- a/tests/test_mg_tallies/test_mg_tallies.py +++ b/tests/regression_tests/mg_tallies/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import HashedPyAPITestHarness import openmc from openmc.examples import slab_mg diff --git a/tests/test_mgxs_library_ce_to_mg/inputs_true.dat b/tests/regression_tests/mgxs_library_ce_to_mg/inputs_true.dat similarity index 100% rename from tests/test_mgxs_library_ce_to_mg/inputs_true.dat rename to tests/regression_tests/mgxs_library_ce_to_mg/inputs_true.dat diff --git a/tests/test_mgxs_library_ce_to_mg/results_true.dat b/tests/regression_tests/mgxs_library_ce_to_mg/results_true.dat similarity index 100% rename from tests/test_mgxs_library_ce_to_mg/results_true.dat rename to tests/regression_tests/mgxs_library_ce_to_mg/results_true.dat diff --git a/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py b/tests/regression_tests/mgxs_library_ce_to_mg/test.py similarity index 98% rename from tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py rename to tests/regression_tests/mgxs_library_ce_to_mg/test.py index 7ae47636e6..e29cf58313 100644 --- a/tests/test_mgxs_library_ce_to_mg/test_mgxs_library_ce_to_mg.py +++ b/tests/regression_tests/mgxs_library_ce_to_mg/test.py @@ -3,7 +3,7 @@ import os import sys import glob -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc import openmc.mgxs diff --git a/tests/test_mgxs_library_condense/inputs_true.dat b/tests/regression_tests/mgxs_library_condense/inputs_true.dat similarity index 100% rename from tests/test_mgxs_library_condense/inputs_true.dat rename to tests/regression_tests/mgxs_library_condense/inputs_true.dat diff --git a/tests/test_mgxs_library_condense/results_true.dat b/tests/regression_tests/mgxs_library_condense/results_true.dat similarity index 100% rename from tests/test_mgxs_library_condense/results_true.dat rename to tests/regression_tests/mgxs_library_condense/results_true.dat diff --git a/tests/test_mgxs_library_condense/test_mgxs_library_condense.py b/tests/regression_tests/mgxs_library_condense/test.py similarity index 97% rename from tests/test_mgxs_library_condense/test_mgxs_library_condense.py rename to tests/regression_tests/mgxs_library_condense/test.py index 127980da6e..fd144636f9 100644 --- a/tests/test_mgxs_library_condense/test_mgxs_library_condense.py +++ b/tests/regression_tests/mgxs_library_condense/test.py @@ -4,7 +4,7 @@ import os import sys import glob import hashlib -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc import openmc.mgxs diff --git a/tests/test_mgxs_library_distribcell/inputs_true.dat b/tests/regression_tests/mgxs_library_distribcell/inputs_true.dat similarity index 100% rename from tests/test_mgxs_library_distribcell/inputs_true.dat rename to tests/regression_tests/mgxs_library_distribcell/inputs_true.dat diff --git a/tests/test_mgxs_library_distribcell/results_true.dat b/tests/regression_tests/mgxs_library_distribcell/results_true.dat similarity index 100% rename from tests/test_mgxs_library_distribcell/results_true.dat rename to tests/regression_tests/mgxs_library_distribcell/results_true.dat diff --git a/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py b/tests/regression_tests/mgxs_library_distribcell/test.py similarity index 97% rename from tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py rename to tests/regression_tests/mgxs_library_distribcell/test.py index 38f16c5884..e59f4c7578 100644 --- a/tests/test_mgxs_library_distribcell/test_mgxs_library_distribcell.py +++ b/tests/regression_tests/mgxs_library_distribcell/test.py @@ -4,7 +4,7 @@ import os import sys import glob import hashlib -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc import openmc.mgxs diff --git a/tests/test_mgxs_library_hdf5/inputs_true.dat b/tests/regression_tests/mgxs_library_hdf5/inputs_true.dat similarity index 100% rename from tests/test_mgxs_library_hdf5/inputs_true.dat rename to tests/regression_tests/mgxs_library_hdf5/inputs_true.dat diff --git a/tests/test_mgxs_library_hdf5/results_true.dat b/tests/regression_tests/mgxs_library_hdf5/results_true.dat similarity index 100% rename from tests/test_mgxs_library_hdf5/results_true.dat rename to tests/regression_tests/mgxs_library_hdf5/results_true.dat diff --git a/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py b/tests/regression_tests/mgxs_library_hdf5/test.py similarity index 98% rename from tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py rename to tests/regression_tests/mgxs_library_hdf5/test.py index 31a9d96126..8daf828cea 100644 --- a/tests/test_mgxs_library_hdf5/test_mgxs_library_hdf5.py +++ b/tests/regression_tests/mgxs_library_hdf5/test.py @@ -8,7 +8,7 @@ import hashlib import numpy as np import h5py -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc import openmc.mgxs diff --git a/tests/test_mgxs_library_mesh/inputs_true.dat b/tests/regression_tests/mgxs_library_mesh/inputs_true.dat similarity index 100% rename from tests/test_mgxs_library_mesh/inputs_true.dat rename to tests/regression_tests/mgxs_library_mesh/inputs_true.dat diff --git a/tests/test_mgxs_library_mesh/results_true.dat b/tests/regression_tests/mgxs_library_mesh/results_true.dat similarity index 100% rename from tests/test_mgxs_library_mesh/results_true.dat rename to tests/regression_tests/mgxs_library_mesh/results_true.dat diff --git a/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py b/tests/regression_tests/mgxs_library_mesh/test.py similarity index 97% rename from tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py rename to tests/regression_tests/mgxs_library_mesh/test.py index e0a3307bc3..06cb10601b 100644 --- a/tests/test_mgxs_library_mesh/test_mgxs_library_mesh.py +++ b/tests/regression_tests/mgxs_library_mesh/test.py @@ -4,7 +4,7 @@ import os import sys import glob import hashlib -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc import openmc.mgxs diff --git a/tests/test_mgxs_library_no_nuclides/inputs_true.dat b/tests/regression_tests/mgxs_library_no_nuclides/inputs_true.dat similarity index 100% rename from tests/test_mgxs_library_no_nuclides/inputs_true.dat rename to tests/regression_tests/mgxs_library_no_nuclides/inputs_true.dat diff --git a/tests/test_mgxs_library_no_nuclides/results_true.dat b/tests/regression_tests/mgxs_library_no_nuclides/results_true.dat similarity index 100% rename from tests/test_mgxs_library_no_nuclides/results_true.dat rename to tests/regression_tests/mgxs_library_no_nuclides/results_true.dat diff --git a/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py b/tests/regression_tests/mgxs_library_no_nuclides/test.py similarity index 97% rename from tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py rename to tests/regression_tests/mgxs_library_no_nuclides/test.py index 793cfc7146..ede916059c 100644 --- a/tests/test_mgxs_library_no_nuclides/test_mgxs_library_no_nuclides.py +++ b/tests/regression_tests/mgxs_library_no_nuclides/test.py @@ -4,7 +4,7 @@ import os import sys import glob import hashlib -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc import openmc.mgxs diff --git a/tests/test_mgxs_library_nuclides/inputs_true.dat b/tests/regression_tests/mgxs_library_nuclides/inputs_true.dat similarity index 100% rename from tests/test_mgxs_library_nuclides/inputs_true.dat rename to tests/regression_tests/mgxs_library_nuclides/inputs_true.dat diff --git a/tests/test_mgxs_library_nuclides/results_true.dat b/tests/regression_tests/mgxs_library_nuclides/results_true.dat similarity index 100% rename from tests/test_mgxs_library_nuclides/results_true.dat rename to tests/regression_tests/mgxs_library_nuclides/results_true.dat diff --git a/tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py b/tests/regression_tests/mgxs_library_nuclides/test.py similarity index 97% rename from tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py rename to tests/regression_tests/mgxs_library_nuclides/test.py index 9e54e1bb6b..e668ab52cc 100644 --- a/tests/test_mgxs_library_nuclides/test_mgxs_library_nuclides.py +++ b/tests/regression_tests/mgxs_library_nuclides/test.py @@ -4,7 +4,7 @@ import os import sys import glob import hashlib -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc import openmc.mgxs diff --git a/tests/test_multipole/inputs_true.dat b/tests/regression_tests/multipole/inputs_true.dat similarity index 100% rename from tests/test_multipole/inputs_true.dat rename to tests/regression_tests/multipole/inputs_true.dat diff --git a/tests/test_multipole/results_true.dat b/tests/regression_tests/multipole/results_true.dat similarity index 100% rename from tests/test_multipole/results_true.dat rename to tests/regression_tests/multipole/results_true.dat diff --git a/tests/test_multipole/test_multipole.py b/tests/regression_tests/multipole/test.py similarity index 98% rename from tests/test_multipole/test_multipole.py rename to tests/regression_tests/multipole/test.py index 294185312a..20da97f7c0 100644 --- a/tests/test_multipole/test_multipole.py +++ b/tests/regression_tests/multipole/test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness, PyAPITestHarness import openmc import openmc.model diff --git a/tests/test_output/geometry.xml b/tests/regression_tests/output/geometry.xml similarity index 100% rename from tests/test_output/geometry.xml rename to tests/regression_tests/output/geometry.xml diff --git a/tests/test_output/materials.xml b/tests/regression_tests/output/materials.xml similarity index 100% rename from tests/test_output/materials.xml rename to tests/regression_tests/output/materials.xml diff --git a/tests/test_output/results_true.dat b/tests/regression_tests/output/results_true.dat similarity index 100% rename from tests/test_output/results_true.dat rename to tests/regression_tests/output/results_true.dat diff --git a/tests/test_output/settings.xml b/tests/regression_tests/output/settings.xml similarity index 100% rename from tests/test_output/settings.xml rename to tests/regression_tests/output/settings.xml diff --git a/tests/test_output/test_output.py b/tests/regression_tests/output/test.py similarity index 94% rename from tests/test_output/test_output.py rename to tests/regression_tests/output/test.py index 475b3e9f02..0092f54919 100644 --- a/tests/test_output/test_output.py +++ b/tests/regression_tests/output/test.py @@ -3,7 +3,7 @@ import glob import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness diff --git a/tests/test_particle_restart_eigval/geometry.xml b/tests/regression_tests/particle_restart_eigval/geometry.xml similarity index 100% rename from tests/test_particle_restart_eigval/geometry.xml rename to tests/regression_tests/particle_restart_eigval/geometry.xml diff --git a/tests/test_particle_restart_eigval/materials.xml b/tests/regression_tests/particle_restart_eigval/materials.xml similarity index 100% rename from tests/test_particle_restart_eigval/materials.xml rename to tests/regression_tests/particle_restart_eigval/materials.xml diff --git a/tests/test_particle_restart_eigval/results_true.dat b/tests/regression_tests/particle_restart_eigval/results_true.dat similarity index 100% rename from tests/test_particle_restart_eigval/results_true.dat rename to tests/regression_tests/particle_restart_eigval/results_true.dat diff --git a/tests/test_particle_restart_eigval/settings.xml b/tests/regression_tests/particle_restart_eigval/settings.xml similarity index 100% rename from tests/test_particle_restart_eigval/settings.xml rename to tests/regression_tests/particle_restart_eigval/settings.xml diff --git a/tests/test_particle_restart_eigval/test_particle_restart_eigval.py b/tests/regression_tests/particle_restart_eigval/test.py similarity index 79% rename from tests/test_particle_restart_eigval/test_particle_restart_eigval.py rename to tests/regression_tests/particle_restart_eigval/test.py index 1ebbd3ea53..455ff9e927 100644 --- a/tests/test_particle_restart_eigval/test_particle_restart_eigval.py +++ b/tests/regression_tests/particle_restart_eigval/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import ParticleRestartTestHarness diff --git a/tests/test_particle_restart_fixed/geometry.xml b/tests/regression_tests/particle_restart_fixed/geometry.xml similarity index 100% rename from tests/test_particle_restart_fixed/geometry.xml rename to tests/regression_tests/particle_restart_fixed/geometry.xml diff --git a/tests/test_particle_restart_fixed/materials.xml b/tests/regression_tests/particle_restart_fixed/materials.xml similarity index 100% rename from tests/test_particle_restart_fixed/materials.xml rename to tests/regression_tests/particle_restart_fixed/materials.xml diff --git a/tests/test_particle_restart_fixed/results_true.dat b/tests/regression_tests/particle_restart_fixed/results_true.dat similarity index 100% rename from tests/test_particle_restart_fixed/results_true.dat rename to tests/regression_tests/particle_restart_fixed/results_true.dat diff --git a/tests/test_particle_restart_fixed/settings.xml b/tests/regression_tests/particle_restart_fixed/settings.xml similarity index 100% rename from tests/test_particle_restart_fixed/settings.xml rename to tests/regression_tests/particle_restart_fixed/settings.xml diff --git a/tests/test_particle_restart_fixed/test_particle_restart_fixed.py b/tests/regression_tests/particle_restart_fixed/test.py similarity index 79% rename from tests/test_particle_restart_fixed/test_particle_restart_fixed.py rename to tests/regression_tests/particle_restart_fixed/test.py index df0398c6eb..e473fdb59e 100644 --- a/tests/test_particle_restart_fixed/test_particle_restart_fixed.py +++ b/tests/regression_tests/particle_restart_fixed/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import ParticleRestartTestHarness diff --git a/tests/test_periodic/inputs_true.dat b/tests/regression_tests/periodic/inputs_true.dat similarity index 100% rename from tests/test_periodic/inputs_true.dat rename to tests/regression_tests/periodic/inputs_true.dat diff --git a/tests/test_periodic/results_true.dat b/tests/regression_tests/periodic/results_true.dat similarity index 100% rename from tests/test_periodic/results_true.dat rename to tests/regression_tests/periodic/results_true.dat diff --git a/tests/test_periodic/test_periodic.py b/tests/regression_tests/periodic/test.py similarity index 97% rename from tests/test_periodic/test_periodic.py rename to tests/regression_tests/periodic/test.py index 3883654c13..ddd7cd89b8 100644 --- a/tests/test_periodic/test_periodic.py +++ b/tests/regression_tests/periodic/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc diff --git a/tests/test_plot/geometry.xml b/tests/regression_tests/plot/geometry.xml similarity index 100% rename from tests/test_plot/geometry.xml rename to tests/regression_tests/plot/geometry.xml diff --git a/tests/test_plot/materials.xml b/tests/regression_tests/plot/materials.xml similarity index 100% rename from tests/test_plot/materials.xml rename to tests/regression_tests/plot/materials.xml diff --git a/tests/test_plot/plots.xml b/tests/regression_tests/plot/plots.xml similarity index 100% rename from tests/test_plot/plots.xml rename to tests/regression_tests/plot/plots.xml diff --git a/tests/test_plot/results_true.dat b/tests/regression_tests/plot/results_true.dat similarity index 100% rename from tests/test_plot/results_true.dat rename to tests/regression_tests/plot/results_true.dat diff --git a/tests/test_plot/settings.xml b/tests/regression_tests/plot/settings.xml similarity index 100% rename from tests/test_plot/settings.xml rename to tests/regression_tests/plot/settings.xml diff --git a/tests/test_plot/test_plot.py b/tests/regression_tests/plot/test.py similarity index 97% rename from tests/test_plot/test_plot.py rename to tests/regression_tests/plot/test.py index 1a99c24886..d0c362ef2b 100644 --- a/tests/test_plot/test_plot.py +++ b/tests/regression_tests/plot/test.py @@ -4,7 +4,7 @@ import glob import hashlib import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness import h5py diff --git a/tests/test_ptables_off/geometry.xml b/tests/regression_tests/ptables_off/geometry.xml similarity index 100% rename from tests/test_ptables_off/geometry.xml rename to tests/regression_tests/ptables_off/geometry.xml diff --git a/tests/test_ptables_off/materials.xml b/tests/regression_tests/ptables_off/materials.xml similarity index 100% rename from tests/test_ptables_off/materials.xml rename to tests/regression_tests/ptables_off/materials.xml diff --git a/tests/test_ptables_off/results_true.dat b/tests/regression_tests/ptables_off/results_true.dat similarity index 100% rename from tests/test_ptables_off/results_true.dat rename to tests/regression_tests/ptables_off/results_true.dat diff --git a/tests/test_ptables_off/settings.xml b/tests/regression_tests/ptables_off/settings.xml similarity index 100% rename from tests/test_ptables_off/settings.xml rename to tests/regression_tests/ptables_off/settings.xml diff --git a/tests/regression_tests/ptables_off/test.py b/tests/regression_tests/ptables_off/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/ptables_off/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_quadric_surfaces/geometry.xml b/tests/regression_tests/quadric_surfaces/geometry.xml similarity index 100% rename from tests/test_quadric_surfaces/geometry.xml rename to tests/regression_tests/quadric_surfaces/geometry.xml diff --git a/tests/test_quadric_surfaces/materials.xml b/tests/regression_tests/quadric_surfaces/materials.xml similarity index 100% rename from tests/test_quadric_surfaces/materials.xml rename to tests/regression_tests/quadric_surfaces/materials.xml diff --git a/tests/test_quadric_surfaces/results_true.dat b/tests/regression_tests/quadric_surfaces/results_true.dat similarity index 100% rename from tests/test_quadric_surfaces/results_true.dat rename to tests/regression_tests/quadric_surfaces/results_true.dat diff --git a/tests/test_quadric_surfaces/settings.xml b/tests/regression_tests/quadric_surfaces/settings.xml similarity index 100% rename from tests/test_quadric_surfaces/settings.xml rename to tests/regression_tests/quadric_surfaces/settings.xml diff --git a/tests/regression_tests/quadric_surfaces/test.py b/tests/regression_tests/quadric_surfaces/test.py new file mode 100755 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/quadric_surfaces/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_reflective_plane/geometry.xml b/tests/regression_tests/reflective_plane/geometry.xml similarity index 100% rename from tests/test_reflective_plane/geometry.xml rename to tests/regression_tests/reflective_plane/geometry.xml diff --git a/tests/test_reflective_plane/materials.xml b/tests/regression_tests/reflective_plane/materials.xml similarity index 100% rename from tests/test_reflective_plane/materials.xml rename to tests/regression_tests/reflective_plane/materials.xml diff --git a/tests/test_reflective_plane/results_true.dat b/tests/regression_tests/reflective_plane/results_true.dat similarity index 100% rename from tests/test_reflective_plane/results_true.dat rename to tests/regression_tests/reflective_plane/results_true.dat diff --git a/tests/test_reflective_plane/settings.xml b/tests/regression_tests/reflective_plane/settings.xml similarity index 100% rename from tests/test_reflective_plane/settings.xml rename to tests/regression_tests/reflective_plane/settings.xml diff --git a/tests/regression_tests/reflective_plane/test.py b/tests/regression_tests/reflective_plane/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/reflective_plane/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_resonance_scattering/inputs_true.dat b/tests/regression_tests/resonance_scattering/inputs_true.dat similarity index 100% rename from tests/test_resonance_scattering/inputs_true.dat rename to tests/regression_tests/resonance_scattering/inputs_true.dat diff --git a/tests/test_resonance_scattering/results_true.dat b/tests/regression_tests/resonance_scattering/results_true.dat similarity index 100% rename from tests/test_resonance_scattering/results_true.dat rename to tests/regression_tests/resonance_scattering/results_true.dat diff --git a/tests/test_resonance_scattering/test_resonance_scattering.py b/tests/regression_tests/resonance_scattering/test.py similarity index 96% rename from tests/test_resonance_scattering/test_resonance_scattering.py rename to tests/regression_tests/resonance_scattering/test.py index 94c9f5c3de..3ed7fe2272 100644 --- a/tests/test_resonance_scattering/test_resonance_scattering.py +++ b/tests/regression_tests/resonance_scattering/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc diff --git a/tests/test_rotation/geometry.xml b/tests/regression_tests/rotation/geometry.xml similarity index 100% rename from tests/test_rotation/geometry.xml rename to tests/regression_tests/rotation/geometry.xml diff --git a/tests/test_rotation/materials.xml b/tests/regression_tests/rotation/materials.xml similarity index 100% rename from tests/test_rotation/materials.xml rename to tests/regression_tests/rotation/materials.xml diff --git a/tests/test_rotation/results_true.dat b/tests/regression_tests/rotation/results_true.dat similarity index 100% rename from tests/test_rotation/results_true.dat rename to tests/regression_tests/rotation/results_true.dat diff --git a/tests/test_rotation/settings.xml b/tests/regression_tests/rotation/settings.xml similarity index 100% rename from tests/test_rotation/settings.xml rename to tests/regression_tests/rotation/settings.xml diff --git a/tests/regression_tests/rotation/test.py b/tests/regression_tests/rotation/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/rotation/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_salphabeta/inputs_true.dat b/tests/regression_tests/salphabeta/inputs_true.dat similarity index 100% rename from tests/test_salphabeta/inputs_true.dat rename to tests/regression_tests/salphabeta/inputs_true.dat diff --git a/tests/test_salphabeta/results_true.dat b/tests/regression_tests/salphabeta/results_true.dat similarity index 100% rename from tests/test_salphabeta/results_true.dat rename to tests/regression_tests/salphabeta/results_true.dat diff --git a/tests/test_salphabeta/test_salphabeta.py b/tests/regression_tests/salphabeta/test.py similarity index 97% rename from tests/test_salphabeta/test_salphabeta.py rename to tests/regression_tests/salphabeta/test.py index 600c703324..6ced79a8d6 100644 --- a/tests/test_salphabeta/test_salphabeta.py +++ b/tests/regression_tests/salphabeta/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc diff --git a/tests/test_score_current/geometry.xml b/tests/regression_tests/score_current/geometry.xml similarity index 100% rename from tests/test_score_current/geometry.xml rename to tests/regression_tests/score_current/geometry.xml diff --git a/tests/test_score_current/materials.xml b/tests/regression_tests/score_current/materials.xml similarity index 100% rename from tests/test_score_current/materials.xml rename to tests/regression_tests/score_current/materials.xml diff --git a/tests/test_score_current/results_true.dat b/tests/regression_tests/score_current/results_true.dat similarity index 100% rename from tests/test_score_current/results_true.dat rename to tests/regression_tests/score_current/results_true.dat diff --git a/tests/test_score_current/settings.xml b/tests/regression_tests/score_current/settings.xml similarity index 100% rename from tests/test_score_current/settings.xml rename to tests/regression_tests/score_current/settings.xml diff --git a/tests/test_score_current/tallies.xml b/tests/regression_tests/score_current/tallies.xml similarity index 100% rename from tests/test_score_current/tallies.xml rename to tests/regression_tests/score_current/tallies.xml diff --git a/tests/test_score_current/test_score_current.py b/tests/regression_tests/score_current/test.py similarity index 77% rename from tests/test_score_current/test_score_current.py rename to tests/regression_tests/score_current/test.py index ea5886a639..70ddc22198 100644 --- a/tests/test_score_current/test_score_current.py +++ b/tests/regression_tests/score_current/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import HashedTestHarness diff --git a/tests/test_seed/geometry.xml b/tests/regression_tests/seed/geometry.xml similarity index 100% rename from tests/test_seed/geometry.xml rename to tests/regression_tests/seed/geometry.xml diff --git a/tests/test_seed/materials.xml b/tests/regression_tests/seed/materials.xml similarity index 100% rename from tests/test_seed/materials.xml rename to tests/regression_tests/seed/materials.xml diff --git a/tests/test_seed/results_true.dat b/tests/regression_tests/seed/results_true.dat similarity index 100% rename from tests/test_seed/results_true.dat rename to tests/regression_tests/seed/results_true.dat diff --git a/tests/test_seed/settings.xml b/tests/regression_tests/seed/settings.xml similarity index 100% rename from tests/test_seed/settings.xml rename to tests/regression_tests/seed/settings.xml diff --git a/tests/regression_tests/seed/test.py b/tests/regression_tests/seed/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/seed/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_source/inputs_true.dat b/tests/regression_tests/source/inputs_true.dat similarity index 100% rename from tests/test_source/inputs_true.dat rename to tests/regression_tests/source/inputs_true.dat diff --git a/tests/test_source/results_true.dat b/tests/regression_tests/source/results_true.dat similarity index 100% rename from tests/test_source/results_true.dat rename to tests/regression_tests/source/results_true.dat diff --git a/tests/test_source/test_source.py b/tests/regression_tests/source/test.py similarity index 97% rename from tests/test_source/test_source.py rename to tests/regression_tests/source/test.py index a872ab4816..7a3d054d8e 100644 --- a/tests/test_source/test_source.py +++ b/tests/regression_tests/source/test.py @@ -6,7 +6,7 @@ import sys import numpy as np -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc diff --git a/tests/test_source_file/geometry.xml b/tests/regression_tests/source_file/geometry.xml similarity index 100% rename from tests/test_source_file/geometry.xml rename to tests/regression_tests/source_file/geometry.xml diff --git a/tests/test_source_file/materials.xml b/tests/regression_tests/source_file/materials.xml similarity index 100% rename from tests/test_source_file/materials.xml rename to tests/regression_tests/source_file/materials.xml diff --git a/tests/test_source_file/results_true.dat b/tests/regression_tests/source_file/results_true.dat similarity index 100% rename from tests/test_source_file/results_true.dat rename to tests/regression_tests/source_file/results_true.dat diff --git a/tests/test_source_file/settings.xml b/tests/regression_tests/source_file/settings.xml similarity index 100% rename from tests/test_source_file/settings.xml rename to tests/regression_tests/source_file/settings.xml diff --git a/tests/test_source_file/test_source_file.py b/tests/regression_tests/source_file/test.py similarity index 98% rename from tests/test_source_file/test_source_file.py rename to tests/regression_tests/source_file/test.py index 5631814b4c..f04441a208 100644 --- a/tests/test_source_file/test_source_file.py +++ b/tests/regression_tests/source_file/test.py @@ -3,7 +3,7 @@ import glob import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import * diff --git a/tests/test_sourcepoint_batch/geometry.xml b/tests/regression_tests/sourcepoint_batch/geometry.xml similarity index 100% rename from tests/test_sourcepoint_batch/geometry.xml rename to tests/regression_tests/sourcepoint_batch/geometry.xml diff --git a/tests/test_sourcepoint_batch/materials.xml b/tests/regression_tests/sourcepoint_batch/materials.xml similarity index 100% rename from tests/test_sourcepoint_batch/materials.xml rename to tests/regression_tests/sourcepoint_batch/materials.xml diff --git a/tests/test_sourcepoint_batch/results_true.dat b/tests/regression_tests/sourcepoint_batch/results_true.dat similarity index 100% rename from tests/test_sourcepoint_batch/results_true.dat rename to tests/regression_tests/sourcepoint_batch/results_true.dat diff --git a/tests/test_sourcepoint_batch/settings.xml b/tests/regression_tests/sourcepoint_batch/settings.xml similarity index 100% rename from tests/test_sourcepoint_batch/settings.xml rename to tests/regression_tests/sourcepoint_batch/settings.xml diff --git a/tests/test_sourcepoint_batch/test_sourcepoint_batch.py b/tests/regression_tests/sourcepoint_batch/test.py similarity index 95% rename from tests/test_sourcepoint_batch/test_sourcepoint_batch.py rename to tests/regression_tests/sourcepoint_batch/test.py index d5ea0e48b2..1239a00dcd 100644 --- a/tests/test_sourcepoint_batch/test_sourcepoint_batch.py +++ b/tests/regression_tests/sourcepoint_batch/test.py @@ -3,7 +3,7 @@ import glob import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness from openmc import StatePoint diff --git a/tests/test_sourcepoint_latest/geometry.xml b/tests/regression_tests/sourcepoint_latest/geometry.xml similarity index 100% rename from tests/test_sourcepoint_latest/geometry.xml rename to tests/regression_tests/sourcepoint_latest/geometry.xml diff --git a/tests/test_sourcepoint_latest/materials.xml b/tests/regression_tests/sourcepoint_latest/materials.xml similarity index 100% rename from tests/test_sourcepoint_latest/materials.xml rename to tests/regression_tests/sourcepoint_latest/materials.xml diff --git a/tests/test_sourcepoint_latest/results_true.dat b/tests/regression_tests/sourcepoint_latest/results_true.dat similarity index 100% rename from tests/test_sourcepoint_latest/results_true.dat rename to tests/regression_tests/sourcepoint_latest/results_true.dat diff --git a/tests/test_sourcepoint_latest/settings.xml b/tests/regression_tests/sourcepoint_latest/settings.xml similarity index 100% rename from tests/test_sourcepoint_latest/settings.xml rename to tests/regression_tests/sourcepoint_latest/settings.xml diff --git a/tests/test_sourcepoint_latest/test_sourcepoint_latest.py b/tests/regression_tests/sourcepoint_latest/test.py similarity index 91% rename from tests/test_sourcepoint_latest/test_sourcepoint_latest.py rename to tests/regression_tests/sourcepoint_latest/test.py index c64cc20cc7..4af176eecd 100644 --- a/tests/test_sourcepoint_latest/test_sourcepoint_latest.py +++ b/tests/regression_tests/sourcepoint_latest/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness diff --git a/tests/test_sourcepoint_restart/geometry.xml b/tests/regression_tests/sourcepoint_restart/geometry.xml similarity index 100% rename from tests/test_sourcepoint_restart/geometry.xml rename to tests/regression_tests/sourcepoint_restart/geometry.xml diff --git a/tests/test_sourcepoint_restart/materials.xml b/tests/regression_tests/sourcepoint_restart/materials.xml similarity index 100% rename from tests/test_sourcepoint_restart/materials.xml rename to tests/regression_tests/sourcepoint_restart/materials.xml diff --git a/tests/test_sourcepoint_restart/results_true.dat b/tests/regression_tests/sourcepoint_restart/results_true.dat similarity index 100% rename from tests/test_sourcepoint_restart/results_true.dat rename to tests/regression_tests/sourcepoint_restart/results_true.dat diff --git a/tests/test_sourcepoint_restart/settings.xml b/tests/regression_tests/sourcepoint_restart/settings.xml similarity index 100% rename from tests/test_sourcepoint_restart/settings.xml rename to tests/regression_tests/sourcepoint_restart/settings.xml diff --git a/tests/test_sourcepoint_restart/tallies.xml b/tests/regression_tests/sourcepoint_restart/tallies.xml similarity index 100% rename from tests/test_sourcepoint_restart/tallies.xml rename to tests/regression_tests/sourcepoint_restart/tallies.xml diff --git a/tests/regression_tests/sourcepoint_restart/test.py b/tests/regression_tests/sourcepoint_restart/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/sourcepoint_restart/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_statepoint_batch/geometry.xml b/tests/regression_tests/statepoint_batch/geometry.xml similarity index 100% rename from tests/test_statepoint_batch/geometry.xml rename to tests/regression_tests/statepoint_batch/geometry.xml diff --git a/tests/test_statepoint_batch/materials.xml b/tests/regression_tests/statepoint_batch/materials.xml similarity index 100% rename from tests/test_statepoint_batch/materials.xml rename to tests/regression_tests/statepoint_batch/materials.xml diff --git a/tests/test_statepoint_batch/results_true.dat b/tests/regression_tests/statepoint_batch/results_true.dat similarity index 100% rename from tests/test_statepoint_batch/results_true.dat rename to tests/regression_tests/statepoint_batch/results_true.dat diff --git a/tests/test_statepoint_batch/settings.xml b/tests/regression_tests/statepoint_batch/settings.xml similarity index 100% rename from tests/test_statepoint_batch/settings.xml rename to tests/regression_tests/statepoint_batch/settings.xml diff --git a/tests/test_statepoint_batch/test_statepoint_batch.py b/tests/regression_tests/statepoint_batch/test.py similarity index 91% rename from tests/test_statepoint_batch/test_statepoint_batch.py rename to tests/regression_tests/statepoint_batch/test.py index e3e2391ba1..0820aa6f01 100644 --- a/tests/test_statepoint_batch/test_statepoint_batch.py +++ b/tests/regression_tests/statepoint_batch/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness diff --git a/tests/test_statepoint_restart/geometry.xml b/tests/regression_tests/statepoint_restart/geometry.xml similarity index 100% rename from tests/test_statepoint_restart/geometry.xml rename to tests/regression_tests/statepoint_restart/geometry.xml diff --git a/tests/test_statepoint_restart/materials.xml b/tests/regression_tests/statepoint_restart/materials.xml similarity index 100% rename from tests/test_statepoint_restart/materials.xml rename to tests/regression_tests/statepoint_restart/materials.xml diff --git a/tests/test_statepoint_restart/results_true.dat b/tests/regression_tests/statepoint_restart/results_true.dat similarity index 100% rename from tests/test_statepoint_restart/results_true.dat rename to tests/regression_tests/statepoint_restart/results_true.dat diff --git a/tests/test_statepoint_restart/settings.xml b/tests/regression_tests/statepoint_restart/settings.xml similarity index 100% rename from tests/test_statepoint_restart/settings.xml rename to tests/regression_tests/statepoint_restart/settings.xml diff --git a/tests/test_statepoint_restart/tallies.xml b/tests/regression_tests/statepoint_restart/tallies.xml similarity index 100% rename from tests/test_statepoint_restart/tallies.xml rename to tests/regression_tests/statepoint_restart/tallies.xml diff --git a/tests/test_statepoint_restart/test_statepoint_restart.py b/tests/regression_tests/statepoint_restart/test.py similarity index 97% rename from tests/test_statepoint_restart/test_statepoint_restart.py rename to tests/regression_tests/statepoint_restart/test.py index 9c10551dea..f3a52c1cf0 100644 --- a/tests/test_statepoint_restart/test_statepoint_restart.py +++ b/tests/regression_tests/statepoint_restart/test.py @@ -3,7 +3,7 @@ import glob import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness import openmc diff --git a/tests/test_statepoint_sourcesep/geometry.xml b/tests/regression_tests/statepoint_sourcesep/geometry.xml similarity index 100% rename from tests/test_statepoint_sourcesep/geometry.xml rename to tests/regression_tests/statepoint_sourcesep/geometry.xml diff --git a/tests/test_statepoint_sourcesep/materials.xml b/tests/regression_tests/statepoint_sourcesep/materials.xml similarity index 100% rename from tests/test_statepoint_sourcesep/materials.xml rename to tests/regression_tests/statepoint_sourcesep/materials.xml diff --git a/tests/test_statepoint_sourcesep/results_true.dat b/tests/regression_tests/statepoint_sourcesep/results_true.dat similarity index 100% rename from tests/test_statepoint_sourcesep/results_true.dat rename to tests/regression_tests/statepoint_sourcesep/results_true.dat diff --git a/tests/test_statepoint_sourcesep/settings.xml b/tests/regression_tests/statepoint_sourcesep/settings.xml similarity index 100% rename from tests/test_statepoint_sourcesep/settings.xml rename to tests/regression_tests/statepoint_sourcesep/settings.xml diff --git a/tests/test_statepoint_sourcesep/test_statepoint_sourcesep.py b/tests/regression_tests/statepoint_sourcesep/test.py similarity index 94% rename from tests/test_statepoint_sourcesep/test_statepoint_sourcesep.py rename to tests/regression_tests/statepoint_sourcesep/test.py index f4bdcfb7b3..904fa471e8 100644 --- a/tests/test_statepoint_sourcesep/test_statepoint_sourcesep.py +++ b/tests/regression_tests/statepoint_sourcesep/test.py @@ -3,7 +3,7 @@ import glob import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness diff --git a/tests/test_surface_tally/inputs_true.dat b/tests/regression_tests/surface_tally/inputs_true.dat similarity index 100% rename from tests/test_surface_tally/inputs_true.dat rename to tests/regression_tests/surface_tally/inputs_true.dat diff --git a/tests/test_surface_tally/results_true.dat b/tests/regression_tests/surface_tally/results_true.dat similarity index 100% rename from tests/test_surface_tally/results_true.dat rename to tests/regression_tests/surface_tally/results_true.dat diff --git a/tests/test_surface_tally/test_surface_tally.py b/tests/regression_tests/surface_tally/test.py similarity index 99% rename from tests/test_surface_tally/test_surface_tally.py rename to tests/regression_tests/surface_tally/test.py index ae525a6838..9729fdf20d 100644 --- a/tests/test_surface_tally/test_surface_tally.py +++ b/tests/regression_tests/surface_tally/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import numpy as np import openmc diff --git a/tests/test_survival_biasing/geometry.xml b/tests/regression_tests/survival_biasing/geometry.xml similarity index 100% rename from tests/test_survival_biasing/geometry.xml rename to tests/regression_tests/survival_biasing/geometry.xml diff --git a/tests/test_survival_biasing/materials.xml b/tests/regression_tests/survival_biasing/materials.xml similarity index 100% rename from tests/test_survival_biasing/materials.xml rename to tests/regression_tests/survival_biasing/materials.xml diff --git a/tests/test_survival_biasing/results_true.dat b/tests/regression_tests/survival_biasing/results_true.dat similarity index 100% rename from tests/test_survival_biasing/results_true.dat rename to tests/regression_tests/survival_biasing/results_true.dat diff --git a/tests/test_survival_biasing/settings.xml b/tests/regression_tests/survival_biasing/settings.xml similarity index 100% rename from tests/test_survival_biasing/settings.xml rename to tests/regression_tests/survival_biasing/settings.xml diff --git a/tests/test_survival_biasing/tallies.xml b/tests/regression_tests/survival_biasing/tallies.xml similarity index 100% rename from tests/test_survival_biasing/tallies.xml rename to tests/regression_tests/survival_biasing/tallies.xml diff --git a/tests/regression_tests/survival_biasing/test.py b/tests/regression_tests/survival_biasing/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/survival_biasing/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_tallies/inputs_true.dat b/tests/regression_tests/tallies/inputs_true.dat similarity index 100% rename from tests/test_tallies/inputs_true.dat rename to tests/regression_tests/tallies/inputs_true.dat diff --git a/tests/test_tallies/results_true.dat b/tests/regression_tests/tallies/results_true.dat similarity index 100% rename from tests/test_tallies/results_true.dat rename to tests/regression_tests/tallies/results_true.dat diff --git a/tests/test_tallies/test_tallies.py b/tests/regression_tests/tallies/test.py similarity index 99% rename from tests/test_tallies/test_tallies.py rename to tests/regression_tests/tallies/test.py index 577d2babc0..693e941af1 100644 --- a/tests/test_tallies/test_tallies.py +++ b/tests/regression_tests/tallies/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import HashedPyAPITestHarness from openmc.filter import * diff --git a/tests/test_tally_aggregation/inputs_true.dat b/tests/regression_tests/tally_aggregation/inputs_true.dat similarity index 100% rename from tests/test_tally_aggregation/inputs_true.dat rename to tests/regression_tests/tally_aggregation/inputs_true.dat diff --git a/tests/test_tally_aggregation/results_true.dat b/tests/regression_tests/tally_aggregation/results_true.dat similarity index 100% rename from tests/test_tally_aggregation/results_true.dat rename to tests/regression_tests/tally_aggregation/results_true.dat diff --git a/tests/test_tally_aggregation/test_tally_aggregation.py b/tests/regression_tests/tally_aggregation/test.py similarity index 97% rename from tests/test_tally_aggregation/test_tally_aggregation.py rename to tests/regression_tests/tally_aggregation/test.py index cf291e0266..62d3a3f041 100644 --- a/tests/test_tally_aggregation/test_tally_aggregation.py +++ b/tests/regression_tests/tally_aggregation/test.py @@ -4,7 +4,7 @@ import os import sys import glob import hashlib -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc diff --git a/tests/test_tally_arithmetic/inputs_true.dat b/tests/regression_tests/tally_arithmetic/inputs_true.dat similarity index 100% rename from tests/test_tally_arithmetic/inputs_true.dat rename to tests/regression_tests/tally_arithmetic/inputs_true.dat diff --git a/tests/test_tally_arithmetic/results_true.dat b/tests/regression_tests/tally_arithmetic/results_true.dat similarity index 100% rename from tests/test_tally_arithmetic/results_true.dat rename to tests/regression_tests/tally_arithmetic/results_true.dat diff --git a/tests/test_tally_arithmetic/test_tally_arithmetic.py b/tests/regression_tests/tally_arithmetic/test.py similarity index 98% rename from tests/test_tally_arithmetic/test_tally_arithmetic.py rename to tests/regression_tests/tally_arithmetic/test.py index 593a0a2917..fab1b0fb2c 100644 --- a/tests/test_tally_arithmetic/test_tally_arithmetic.py +++ b/tests/regression_tests/tally_arithmetic/test.py @@ -4,7 +4,7 @@ import os import sys import glob import hashlib -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc diff --git a/tests/test_tally_assumesep/geometry.xml b/tests/regression_tests/tally_assumesep/geometry.xml similarity index 100% rename from tests/test_tally_assumesep/geometry.xml rename to tests/regression_tests/tally_assumesep/geometry.xml diff --git a/tests/test_tally_assumesep/materials.xml b/tests/regression_tests/tally_assumesep/materials.xml similarity index 100% rename from tests/test_tally_assumesep/materials.xml rename to tests/regression_tests/tally_assumesep/materials.xml diff --git a/tests/test_tally_assumesep/results_true.dat b/tests/regression_tests/tally_assumesep/results_true.dat similarity index 100% rename from tests/test_tally_assumesep/results_true.dat rename to tests/regression_tests/tally_assumesep/results_true.dat diff --git a/tests/test_tally_assumesep/settings.xml b/tests/regression_tests/tally_assumesep/settings.xml similarity index 100% rename from tests/test_tally_assumesep/settings.xml rename to tests/regression_tests/tally_assumesep/settings.xml diff --git a/tests/test_tally_assumesep/tallies.xml b/tests/regression_tests/tally_assumesep/tallies.xml similarity index 100% rename from tests/test_tally_assumesep/tallies.xml rename to tests/regression_tests/tally_assumesep/tallies.xml diff --git a/tests/regression_tests/tally_assumesep/test.py b/tests/regression_tests/tally_assumesep/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/tally_assumesep/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_tally_nuclides/geometry.xml b/tests/regression_tests/tally_nuclides/geometry.xml similarity index 100% rename from tests/test_tally_nuclides/geometry.xml rename to tests/regression_tests/tally_nuclides/geometry.xml diff --git a/tests/test_tally_nuclides/materials.xml b/tests/regression_tests/tally_nuclides/materials.xml similarity index 100% rename from tests/test_tally_nuclides/materials.xml rename to tests/regression_tests/tally_nuclides/materials.xml diff --git a/tests/test_tally_nuclides/results_true.dat b/tests/regression_tests/tally_nuclides/results_true.dat similarity index 100% rename from tests/test_tally_nuclides/results_true.dat rename to tests/regression_tests/tally_nuclides/results_true.dat diff --git a/tests/test_tally_nuclides/settings.xml b/tests/regression_tests/tally_nuclides/settings.xml similarity index 100% rename from tests/test_tally_nuclides/settings.xml rename to tests/regression_tests/tally_nuclides/settings.xml diff --git a/tests/test_tally_nuclides/tallies.xml b/tests/regression_tests/tally_nuclides/tallies.xml similarity index 100% rename from tests/test_tally_nuclides/tallies.xml rename to tests/regression_tests/tally_nuclides/tallies.xml diff --git a/tests/regression_tests/tally_nuclides/test.py b/tests/regression_tests/tally_nuclides/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/tally_nuclides/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_tally_slice_merge/inputs_true.dat b/tests/regression_tests/tally_slice_merge/inputs_true.dat similarity index 100% rename from tests/test_tally_slice_merge/inputs_true.dat rename to tests/regression_tests/tally_slice_merge/inputs_true.dat diff --git a/tests/test_tally_slice_merge/results_true.dat b/tests/regression_tests/tally_slice_merge/results_true.dat similarity index 100% rename from tests/test_tally_slice_merge/results_true.dat rename to tests/regression_tests/tally_slice_merge/results_true.dat diff --git a/tests/test_tally_slice_merge/test_tally_slice_merge.py b/tests/regression_tests/tally_slice_merge/test.py similarity index 99% rename from tests/test_tally_slice_merge/test_tally_slice_merge.py rename to tests/regression_tests/tally_slice_merge/test.py index d917d2dadb..84908b5cbe 100644 --- a/tests/test_tally_slice_merge/test_tally_slice_merge.py +++ b/tests/regression_tests/tally_slice_merge/test.py @@ -7,7 +7,7 @@ import sys import glob import hashlib import itertools -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc diff --git a/tests/test_trace/geometry.xml b/tests/regression_tests/trace/geometry.xml similarity index 100% rename from tests/test_trace/geometry.xml rename to tests/regression_tests/trace/geometry.xml diff --git a/tests/test_trace/materials.xml b/tests/regression_tests/trace/materials.xml similarity index 100% rename from tests/test_trace/materials.xml rename to tests/regression_tests/trace/materials.xml diff --git a/tests/test_trace/results_true.dat b/tests/regression_tests/trace/results_true.dat similarity index 100% rename from tests/test_trace/results_true.dat rename to tests/regression_tests/trace/results_true.dat diff --git a/tests/test_trace/settings.xml b/tests/regression_tests/trace/settings.xml similarity index 100% rename from tests/test_trace/settings.xml rename to tests/regression_tests/trace/settings.xml diff --git a/tests/regression_tests/trace/test.py b/tests/regression_tests/trace/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/trace/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_track_output/geometry.xml b/tests/regression_tests/track_output/geometry.xml similarity index 100% rename from tests/test_track_output/geometry.xml rename to tests/regression_tests/track_output/geometry.xml diff --git a/tests/test_track_output/materials.xml b/tests/regression_tests/track_output/materials.xml similarity index 100% rename from tests/test_track_output/materials.xml rename to tests/regression_tests/track_output/materials.xml diff --git a/tests/test_track_output/results_true.dat b/tests/regression_tests/track_output/results_true.dat similarity index 100% rename from tests/test_track_output/results_true.dat rename to tests/regression_tests/track_output/results_true.dat diff --git a/tests/test_track_output/settings.xml b/tests/regression_tests/track_output/settings.xml similarity index 100% rename from tests/test_track_output/settings.xml rename to tests/regression_tests/track_output/settings.xml diff --git a/tests/test_track_output/test_track_output.py b/tests/regression_tests/track_output/test.py similarity index 96% rename from tests/test_track_output/test_track_output.py rename to tests/regression_tests/track_output/test.py index 0357aae19e..c7a2df4ebe 100644 --- a/tests/test_track_output/test_track_output.py +++ b/tests/regression_tests/track_output/test.py @@ -5,7 +5,7 @@ import os from subprocess import call import shutil import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness diff --git a/tests/test_translation/geometry.xml b/tests/regression_tests/translation/geometry.xml similarity index 100% rename from tests/test_translation/geometry.xml rename to tests/regression_tests/translation/geometry.xml diff --git a/tests/test_translation/materials.xml b/tests/regression_tests/translation/materials.xml similarity index 100% rename from tests/test_translation/materials.xml rename to tests/regression_tests/translation/materials.xml diff --git a/tests/test_translation/results_true.dat b/tests/regression_tests/translation/results_true.dat similarity index 100% rename from tests/test_translation/results_true.dat rename to tests/regression_tests/translation/results_true.dat diff --git a/tests/test_translation/settings.xml b/tests/regression_tests/translation/settings.xml similarity index 100% rename from tests/test_translation/settings.xml rename to tests/regression_tests/translation/settings.xml diff --git a/tests/regression_tests/translation/test.py b/tests/regression_tests/translation/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/translation/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_trigger_batch_interval/geometry.xml b/tests/regression_tests/trigger_batch_interval/geometry.xml similarity index 100% rename from tests/test_trigger_batch_interval/geometry.xml rename to tests/regression_tests/trigger_batch_interval/geometry.xml diff --git a/tests/test_trigger_batch_interval/materials.xml b/tests/regression_tests/trigger_batch_interval/materials.xml similarity index 100% rename from tests/test_trigger_batch_interval/materials.xml rename to tests/regression_tests/trigger_batch_interval/materials.xml diff --git a/tests/test_trigger_batch_interval/results_true.dat b/tests/regression_tests/trigger_batch_interval/results_true.dat similarity index 100% rename from tests/test_trigger_batch_interval/results_true.dat rename to tests/regression_tests/trigger_batch_interval/results_true.dat diff --git a/tests/test_trigger_batch_interval/settings.xml b/tests/regression_tests/trigger_batch_interval/settings.xml similarity index 100% rename from tests/test_trigger_batch_interval/settings.xml rename to tests/regression_tests/trigger_batch_interval/settings.xml diff --git a/tests/test_trigger_batch_interval/tallies.xml b/tests/regression_tests/trigger_batch_interval/tallies.xml similarity index 100% rename from tests/test_trigger_batch_interval/tallies.xml rename to tests/regression_tests/trigger_batch_interval/tallies.xml diff --git a/tests/test_trigger_batch_interval/test_trigger_batch_interval.py b/tests/regression_tests/trigger_batch_interval/test.py similarity index 76% rename from tests/test_trigger_batch_interval/test_trigger_batch_interval.py rename to tests/regression_tests/trigger_batch_interval/test.py index fb88ada001..542c2ffdeb 100644 --- a/tests/test_trigger_batch_interval/test_trigger_batch_interval.py +++ b/tests/regression_tests/trigger_batch_interval/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness diff --git a/tests/test_trigger_no_batch_interval/geometry.xml b/tests/regression_tests/trigger_no_batch_interval/geometry.xml similarity index 100% rename from tests/test_trigger_no_batch_interval/geometry.xml rename to tests/regression_tests/trigger_no_batch_interval/geometry.xml diff --git a/tests/test_trigger_no_batch_interval/materials.xml b/tests/regression_tests/trigger_no_batch_interval/materials.xml similarity index 100% rename from tests/test_trigger_no_batch_interval/materials.xml rename to tests/regression_tests/trigger_no_batch_interval/materials.xml diff --git a/tests/test_trigger_no_batch_interval/results_true.dat b/tests/regression_tests/trigger_no_batch_interval/results_true.dat similarity index 100% rename from tests/test_trigger_no_batch_interval/results_true.dat rename to tests/regression_tests/trigger_no_batch_interval/results_true.dat diff --git a/tests/test_trigger_no_batch_interval/settings.xml b/tests/regression_tests/trigger_no_batch_interval/settings.xml similarity index 100% rename from tests/test_trigger_no_batch_interval/settings.xml rename to tests/regression_tests/trigger_no_batch_interval/settings.xml diff --git a/tests/test_trigger_no_batch_interval/tallies.xml b/tests/regression_tests/trigger_no_batch_interval/tallies.xml similarity index 100% rename from tests/test_trigger_no_batch_interval/tallies.xml rename to tests/regression_tests/trigger_no_batch_interval/tallies.xml diff --git a/tests/test_trigger_no_batch_interval/test_trigger_no_batch_interval.py b/tests/regression_tests/trigger_no_batch_interval/test.py similarity index 76% rename from tests/test_trigger_no_batch_interval/test_trigger_no_batch_interval.py rename to tests/regression_tests/trigger_no_batch_interval/test.py index fb88ada001..542c2ffdeb 100644 --- a/tests/test_trigger_no_batch_interval/test_trigger_no_batch_interval.py +++ b/tests/regression_tests/trigger_no_batch_interval/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness diff --git a/tests/test_trigger_no_status/geometry.xml b/tests/regression_tests/trigger_no_status/geometry.xml similarity index 100% rename from tests/test_trigger_no_status/geometry.xml rename to tests/regression_tests/trigger_no_status/geometry.xml diff --git a/tests/test_trigger_no_status/materials.xml b/tests/regression_tests/trigger_no_status/materials.xml similarity index 100% rename from tests/test_trigger_no_status/materials.xml rename to tests/regression_tests/trigger_no_status/materials.xml diff --git a/tests/test_trigger_no_status/results_true.dat b/tests/regression_tests/trigger_no_status/results_true.dat similarity index 100% rename from tests/test_trigger_no_status/results_true.dat rename to tests/regression_tests/trigger_no_status/results_true.dat diff --git a/tests/test_trigger_no_status/settings.xml b/tests/regression_tests/trigger_no_status/settings.xml similarity index 100% rename from tests/test_trigger_no_status/settings.xml rename to tests/regression_tests/trigger_no_status/settings.xml diff --git a/tests/test_trigger_no_status/tallies.xml b/tests/regression_tests/trigger_no_status/tallies.xml similarity index 100% rename from tests/test_trigger_no_status/tallies.xml rename to tests/regression_tests/trigger_no_status/tallies.xml diff --git a/tests/regression_tests/trigger_no_status/test.py b/tests/regression_tests/trigger_no_status/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/trigger_no_status/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_trigger_tallies/geometry.xml b/tests/regression_tests/trigger_tallies/geometry.xml similarity index 100% rename from tests/test_trigger_tallies/geometry.xml rename to tests/regression_tests/trigger_tallies/geometry.xml diff --git a/tests/test_trigger_tallies/materials.xml b/tests/regression_tests/trigger_tallies/materials.xml similarity index 100% rename from tests/test_trigger_tallies/materials.xml rename to tests/regression_tests/trigger_tallies/materials.xml diff --git a/tests/test_trigger_tallies/results_true.dat b/tests/regression_tests/trigger_tallies/results_true.dat similarity index 100% rename from tests/test_trigger_tallies/results_true.dat rename to tests/regression_tests/trigger_tallies/results_true.dat diff --git a/tests/test_trigger_tallies/settings.xml b/tests/regression_tests/trigger_tallies/settings.xml similarity index 100% rename from tests/test_trigger_tallies/settings.xml rename to tests/regression_tests/trigger_tallies/settings.xml diff --git a/tests/test_trigger_tallies/tallies.xml b/tests/regression_tests/trigger_tallies/tallies.xml similarity index 100% rename from tests/test_trigger_tallies/tallies.xml rename to tests/regression_tests/trigger_tallies/tallies.xml diff --git a/tests/test_trigger_tallies/test_trigger_tallies.py b/tests/regression_tests/trigger_tallies/test.py similarity index 76% rename from tests/test_trigger_tallies/test_trigger_tallies.py rename to tests/regression_tests/trigger_tallies/test.py index fb88ada001..542c2ffdeb 100644 --- a/tests/test_trigger_tallies/test_trigger_tallies.py +++ b/tests/regression_tests/trigger_tallies/test.py @@ -2,7 +2,7 @@ import os import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import TestHarness diff --git a/tests/test_triso/inputs_true.dat b/tests/regression_tests/triso/inputs_true.dat similarity index 100% rename from tests/test_triso/inputs_true.dat rename to tests/regression_tests/triso/inputs_true.dat diff --git a/tests/test_triso/results_true.dat b/tests/regression_tests/triso/results_true.dat similarity index 100% rename from tests/test_triso/results_true.dat rename to tests/regression_tests/triso/results_true.dat diff --git a/tests/test_triso/test_triso.py b/tests/regression_tests/triso/test.py similarity index 98% rename from tests/test_triso/test_triso.py rename to tests/regression_tests/triso/test.py index e5c823c01f..c92495ace3 100644 --- a/tests/test_triso/test_triso.py +++ b/tests/regression_tests/triso/test.py @@ -8,7 +8,7 @@ from math import sqrt import numpy as np -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc import openmc.model diff --git a/tests/test_uniform_fs/geometry.xml b/tests/regression_tests/uniform_fs/geometry.xml similarity index 100% rename from tests/test_uniform_fs/geometry.xml rename to tests/regression_tests/uniform_fs/geometry.xml diff --git a/tests/test_uniform_fs/materials.xml b/tests/regression_tests/uniform_fs/materials.xml similarity index 100% rename from tests/test_uniform_fs/materials.xml rename to tests/regression_tests/uniform_fs/materials.xml diff --git a/tests/test_uniform_fs/results_true.dat b/tests/regression_tests/uniform_fs/results_true.dat similarity index 100% rename from tests/test_uniform_fs/results_true.dat rename to tests/regression_tests/uniform_fs/results_true.dat diff --git a/tests/test_uniform_fs/settings.xml b/tests/regression_tests/uniform_fs/settings.xml similarity index 100% rename from tests/test_uniform_fs/settings.xml rename to tests/regression_tests/uniform_fs/settings.xml diff --git a/tests/regression_tests/uniform_fs/test.py b/tests/regression_tests/uniform_fs/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/uniform_fs/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_universe/geometry.xml b/tests/regression_tests/universe/geometry.xml similarity index 100% rename from tests/test_universe/geometry.xml rename to tests/regression_tests/universe/geometry.xml diff --git a/tests/test_universe/materials.xml b/tests/regression_tests/universe/materials.xml similarity index 100% rename from tests/test_universe/materials.xml rename to tests/regression_tests/universe/materials.xml diff --git a/tests/test_universe/results_true.dat b/tests/regression_tests/universe/results_true.dat similarity index 100% rename from tests/test_universe/results_true.dat rename to tests/regression_tests/universe/results_true.dat diff --git a/tests/test_universe/settings.xml b/tests/regression_tests/universe/settings.xml similarity index 100% rename from tests/test_universe/settings.xml rename to tests/regression_tests/universe/settings.xml diff --git a/tests/regression_tests/universe/test.py b/tests/regression_tests/universe/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/universe/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_void/geometry.xml b/tests/regression_tests/void/geometry.xml similarity index 100% rename from tests/test_void/geometry.xml rename to tests/regression_tests/void/geometry.xml diff --git a/tests/test_void/materials.xml b/tests/regression_tests/void/materials.xml similarity index 100% rename from tests/test_void/materials.xml rename to tests/regression_tests/void/materials.xml diff --git a/tests/test_void/results_true.dat b/tests/regression_tests/void/results_true.dat similarity index 100% rename from tests/test_void/results_true.dat rename to tests/regression_tests/void/results_true.dat diff --git a/tests/test_void/settings.xml b/tests/regression_tests/void/settings.xml similarity index 100% rename from tests/test_void/settings.xml rename to tests/regression_tests/void/settings.xml diff --git a/tests/regression_tests/void/test.py b/tests/regression_tests/void/test.py new file mode 100644 index 0000000000..43f8e5ff0f --- /dev/null +++ b/tests/regression_tests/void/test.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +import os +import sys +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) +from testing_harness import TestHarness + + +if __name__ == '__main__': + harness = TestHarness('statepoint.10.h5') + harness.main() diff --git a/tests/test_volume_calc/inputs_true.dat b/tests/regression_tests/volume_calc/inputs_true.dat similarity index 100% rename from tests/test_volume_calc/inputs_true.dat rename to tests/regression_tests/volume_calc/inputs_true.dat diff --git a/tests/test_volume_calc/results_true.dat b/tests/regression_tests/volume_calc/results_true.dat similarity index 100% rename from tests/test_volume_calc/results_true.dat rename to tests/regression_tests/volume_calc/results_true.dat diff --git a/tests/test_volume_calc/test_volume_calc.py b/tests/regression_tests/volume_calc/test.py similarity index 98% rename from tests/test_volume_calc/test_volume_calc.py rename to tests/regression_tests/volume_calc/test.py index 003528b0df..47ce27a122 100644 --- a/tests/test_volume_calc/test_volume_calc.py +++ b/tests/regression_tests/volume_calc/test.py @@ -3,7 +3,7 @@ import os import glob import sys -sys.path.insert(0, os.pardir) +sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from testing_harness import PyAPITestHarness import openmc diff --git a/tests/test_complex_cell/test_complex_cell.py b/tests/test_complex_cell/test_complex_cell.py deleted file mode 100755 index 0669165e25..0000000000 --- a/tests/test_complex_cell/test_complex_cell.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python - -import sys -sys.path.insert(0, '..') -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_infinite_cell/test_infinite_cell.py b/tests/test_infinite_cell/test_infinite_cell.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_infinite_cell/test_infinite_cell.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_lattice/test_lattice.py b/tests/test_lattice/test_lattice.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_lattice/test_lattice.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_lattice_hex/test_lattice_hex.py b/tests/test_lattice_hex/test_lattice_hex.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_lattice_hex/test_lattice_hex.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_lattice_mixed/test_lattice_mixed.py b/tests/test_lattice_mixed/test_lattice_mixed.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_lattice_mixed/test_lattice_mixed.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_lattice_multiple/test_lattice_multiple.py b/tests/test_lattice_multiple/test_lattice_multiple.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_lattice_multiple/test_lattice_multiple.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_ptables_off/test_ptables_off.py b/tests/test_ptables_off/test_ptables_off.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_ptables_off/test_ptables_off.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_quadric_surfaces/test_quadric_surfaces.py b/tests/test_quadric_surfaces/test_quadric_surfaces.py deleted file mode 100755 index b04fcc6eba..0000000000 --- a/tests/test_quadric_surfaces/test_quadric_surfaces.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_reflective_plane/test_reflective_plane.py b/tests/test_reflective_plane/test_reflective_plane.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_reflective_plane/test_reflective_plane.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_rotation/test_rotation.py b/tests/test_rotation/test_rotation.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_rotation/test_rotation.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_seed/test_seed.py b/tests/test_seed/test_seed.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_seed/test_seed.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_sourcepoint_restart/test_sourcepoint_restart.py b/tests/test_sourcepoint_restart/test_sourcepoint_restart.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_sourcepoint_restart/test_sourcepoint_restart.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_survival_biasing/test_survival_biasing.py b/tests/test_survival_biasing/test_survival_biasing.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_survival_biasing/test_survival_biasing.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_tally_assumesep/test_tally_assumesep.py b/tests/test_tally_assumesep/test_tally_assumesep.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_tally_assumesep/test_tally_assumesep.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_tally_nuclides/test_tally_nuclides.py b/tests/test_tally_nuclides/test_tally_nuclides.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_tally_nuclides/test_tally_nuclides.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_trace/test_trace.py b/tests/test_trace/test_trace.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_trace/test_trace.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_translation/test_translation.py b/tests/test_translation/test_translation.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_translation/test_translation.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_trigger_no_status/test_trigger_no_status.py b/tests/test_trigger_no_status/test_trigger_no_status.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_trigger_no_status/test_trigger_no_status.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_uniform_fs/test_uniform_fs.py b/tests/test_uniform_fs/test_uniform_fs.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_uniform_fs/test_uniform_fs.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_universe/test_universe.py b/tests/test_universe/test_universe.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_universe/test_universe.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() diff --git a/tests/test_void/test_void.py b/tests/test_void/test_void.py deleted file mode 100644 index b04fcc6eba..0000000000 --- a/tests/test_void/test_void.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.pardir) -from testing_harness import TestHarness - - -if __name__ == '__main__': - harness = TestHarness('statepoint.10.h5') - harness.main() From 920afa123edf490a558099f21e0fe23a904db78c Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sun, 28 Jan 2018 15:57:52 -0600 Subject: [PATCH 33/74] Make tests directory a package (for pytest) --- setup.py | 2 +- tests/__init__.py | 0 tests/regression_tests/__init__.py | 0 tests/regression_tests/asymmetric_lattice/__init__.py | 0 tests/regression_tests/cmfd_feed/__init__.py | 0 tests/regression_tests/cmfd_nofeed/__init__.py | 0 tests/regression_tests/complex_cell/__init__.py | 0 tests/regression_tests/confidence_intervals/__init__.py | 0 tests/regression_tests/create_fission_neutrons/__init__.py | 0 tests/regression_tests/density/__init__.py | 0 tests/regression_tests/diff_tally/__init__.py | 0 tests/regression_tests/distribmat/__init__.py | 0 tests/regression_tests/eigenvalue_genperbatch/__init__.py | 0 tests/regression_tests/eigenvalue_no_inactive/__init__.py | 0 tests/regression_tests/energy_cutoff/__init__.py | 0 tests/regression_tests/energy_grid/__init__.py | 0 tests/regression_tests/energy_laws/__init__.py | 0 tests/regression_tests/enrichment/__init__.py | 0 tests/regression_tests/entropy/__init__.py | 0 tests/regression_tests/filter_distribcell/__init__.py | 0 tests/regression_tests/filter_energyfun/__init__.py | 0 tests/regression_tests/filter_mesh/__init__.py | 0 tests/regression_tests/fixed_source/__init__.py | 0 tests/regression_tests/infinite_cell/__init__.py | 0 tests/regression_tests/iso_in_lab/__init__.py | 0 tests/regression_tests/lattice/__init__.py | 0 tests/regression_tests/lattice_hex/__init__.py | 0 tests/regression_tests/lattice_mixed/__init__.py | 0 tests/regression_tests/lattice_multiple/__init__.py | 0 tests/regression_tests/mg_basic/__init__.py | 0 tests/regression_tests/mg_convert/__init__.py | 0 tests/regression_tests/mg_legendre/__init__.py | 0 tests/regression_tests/mg_max_order/__init__.py | 0 tests/regression_tests/mg_nuclide/__init__.py | 0 tests/regression_tests/mg_survival_biasing/__init__.py | 0 tests/regression_tests/mg_tallies/__init__.py | 0 tests/regression_tests/mgxs_library_ce_to_mg/__init__.py | 0 tests/regression_tests/mgxs_library_condense/__init__.py | 0 tests/regression_tests/mgxs_library_distribcell/__init__.py | 0 tests/regression_tests/mgxs_library_hdf5/__init__.py | 0 tests/regression_tests/mgxs_library_mesh/__init__.py | 0 tests/regression_tests/mgxs_library_no_nuclides/__init__.py | 0 tests/regression_tests/mgxs_library_nuclides/__init__.py | 0 tests/regression_tests/multipole/__init__.py | 0 tests/regression_tests/output/__init__.py | 0 tests/regression_tests/particle_restart_eigval/__init__.py | 0 tests/regression_tests/particle_restart_fixed/__init__.py | 0 tests/regression_tests/periodic/__init__.py | 0 tests/regression_tests/plot/__init__.py | 0 tests/regression_tests/ptables_off/__init__.py | 0 tests/regression_tests/quadric_surfaces/__init__.py | 0 tests/regression_tests/reflective_plane/__init__.py | 0 tests/regression_tests/resonance_scattering/__init__.py | 0 tests/regression_tests/rotation/__init__.py | 0 tests/regression_tests/salphabeta/__init__.py | 0 tests/regression_tests/score_current/__init__.py | 0 tests/regression_tests/seed/__init__.py | 0 tests/regression_tests/source/__init__.py | 0 tests/regression_tests/source_file/__init__.py | 0 tests/regression_tests/sourcepoint_batch/__init__.py | 0 tests/regression_tests/sourcepoint_latest/__init__.py | 0 tests/regression_tests/sourcepoint_restart/__init__.py | 0 tests/regression_tests/statepoint_batch/__init__.py | 0 tests/regression_tests/statepoint_restart/__init__.py | 0 tests/regression_tests/statepoint_sourcesep/__init__.py | 0 tests/regression_tests/surface_tally/__init__.py | 0 tests/regression_tests/survival_biasing/__init__.py | 0 tests/regression_tests/tallies/__init__.py | 0 tests/regression_tests/tally_aggregation/__init__.py | 0 tests/regression_tests/tally_arithmetic/__init__.py | 0 tests/regression_tests/tally_assumesep/__init__.py | 0 tests/regression_tests/tally_nuclides/__init__.py | 0 tests/regression_tests/tally_slice_merge/__init__.py | 0 tests/regression_tests/trace/__init__.py | 0 tests/regression_tests/track_output/__init__.py | 0 tests/regression_tests/translation/__init__.py | 0 tests/regression_tests/trigger_batch_interval/__init__.py | 0 tests/regression_tests/trigger_no_batch_interval/__init__.py | 0 tests/regression_tests/trigger_no_status/__init__.py | 0 tests/regression_tests/trigger_tallies/__init__.py | 0 tests/regression_tests/triso/__init__.py | 0 tests/regression_tests/uniform_fs/__init__.py | 0 tests/regression_tests/universe/__init__.py | 0 tests/regression_tests/void/__init__.py | 0 tests/regression_tests/volume_calc/__init__.py | 0 tests/unit_tests/__init__.py | 0 86 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 tests/__init__.py create mode 100644 tests/regression_tests/__init__.py create mode 100644 tests/regression_tests/asymmetric_lattice/__init__.py create mode 100644 tests/regression_tests/cmfd_feed/__init__.py create mode 100644 tests/regression_tests/cmfd_nofeed/__init__.py create mode 100644 tests/regression_tests/complex_cell/__init__.py create mode 100644 tests/regression_tests/confidence_intervals/__init__.py create mode 100644 tests/regression_tests/create_fission_neutrons/__init__.py create mode 100644 tests/regression_tests/density/__init__.py create mode 100644 tests/regression_tests/diff_tally/__init__.py create mode 100644 tests/regression_tests/distribmat/__init__.py create mode 100644 tests/regression_tests/eigenvalue_genperbatch/__init__.py create mode 100644 tests/regression_tests/eigenvalue_no_inactive/__init__.py create mode 100644 tests/regression_tests/energy_cutoff/__init__.py create mode 100644 tests/regression_tests/energy_grid/__init__.py create mode 100644 tests/regression_tests/energy_laws/__init__.py create mode 100644 tests/regression_tests/enrichment/__init__.py create mode 100644 tests/regression_tests/entropy/__init__.py create mode 100644 tests/regression_tests/filter_distribcell/__init__.py create mode 100644 tests/regression_tests/filter_energyfun/__init__.py create mode 100644 tests/regression_tests/filter_mesh/__init__.py create mode 100644 tests/regression_tests/fixed_source/__init__.py create mode 100644 tests/regression_tests/infinite_cell/__init__.py create mode 100644 tests/regression_tests/iso_in_lab/__init__.py create mode 100644 tests/regression_tests/lattice/__init__.py create mode 100644 tests/regression_tests/lattice_hex/__init__.py create mode 100644 tests/regression_tests/lattice_mixed/__init__.py create mode 100644 tests/regression_tests/lattice_multiple/__init__.py create mode 100644 tests/regression_tests/mg_basic/__init__.py create mode 100644 tests/regression_tests/mg_convert/__init__.py create mode 100644 tests/regression_tests/mg_legendre/__init__.py create mode 100644 tests/regression_tests/mg_max_order/__init__.py create mode 100644 tests/regression_tests/mg_nuclide/__init__.py create mode 100644 tests/regression_tests/mg_survival_biasing/__init__.py create mode 100644 tests/regression_tests/mg_tallies/__init__.py create mode 100644 tests/regression_tests/mgxs_library_ce_to_mg/__init__.py create mode 100644 tests/regression_tests/mgxs_library_condense/__init__.py create mode 100644 tests/regression_tests/mgxs_library_distribcell/__init__.py create mode 100644 tests/regression_tests/mgxs_library_hdf5/__init__.py create mode 100644 tests/regression_tests/mgxs_library_mesh/__init__.py create mode 100644 tests/regression_tests/mgxs_library_no_nuclides/__init__.py create mode 100644 tests/regression_tests/mgxs_library_nuclides/__init__.py create mode 100644 tests/regression_tests/multipole/__init__.py create mode 100644 tests/regression_tests/output/__init__.py create mode 100644 tests/regression_tests/particle_restart_eigval/__init__.py create mode 100644 tests/regression_tests/particle_restart_fixed/__init__.py create mode 100644 tests/regression_tests/periodic/__init__.py create mode 100644 tests/regression_tests/plot/__init__.py create mode 100644 tests/regression_tests/ptables_off/__init__.py create mode 100644 tests/regression_tests/quadric_surfaces/__init__.py create mode 100644 tests/regression_tests/reflective_plane/__init__.py create mode 100644 tests/regression_tests/resonance_scattering/__init__.py create mode 100644 tests/regression_tests/rotation/__init__.py create mode 100644 tests/regression_tests/salphabeta/__init__.py create mode 100644 tests/regression_tests/score_current/__init__.py create mode 100644 tests/regression_tests/seed/__init__.py create mode 100644 tests/regression_tests/source/__init__.py create mode 100644 tests/regression_tests/source_file/__init__.py create mode 100644 tests/regression_tests/sourcepoint_batch/__init__.py create mode 100644 tests/regression_tests/sourcepoint_latest/__init__.py create mode 100644 tests/regression_tests/sourcepoint_restart/__init__.py create mode 100644 tests/regression_tests/statepoint_batch/__init__.py create mode 100644 tests/regression_tests/statepoint_restart/__init__.py create mode 100644 tests/regression_tests/statepoint_sourcesep/__init__.py create mode 100644 tests/regression_tests/surface_tally/__init__.py create mode 100644 tests/regression_tests/survival_biasing/__init__.py create mode 100644 tests/regression_tests/tallies/__init__.py create mode 100644 tests/regression_tests/tally_aggregation/__init__.py create mode 100644 tests/regression_tests/tally_arithmetic/__init__.py create mode 100644 tests/regression_tests/tally_assumesep/__init__.py create mode 100644 tests/regression_tests/tally_nuclides/__init__.py create mode 100644 tests/regression_tests/tally_slice_merge/__init__.py create mode 100644 tests/regression_tests/trace/__init__.py create mode 100644 tests/regression_tests/track_output/__init__.py create mode 100644 tests/regression_tests/translation/__init__.py create mode 100644 tests/regression_tests/trigger_batch_interval/__init__.py create mode 100644 tests/regression_tests/trigger_no_batch_interval/__init__.py create mode 100644 tests/regression_tests/trigger_no_status/__init__.py create mode 100644 tests/regression_tests/trigger_tallies/__init__.py create mode 100644 tests/regression_tests/triso/__init__.py create mode 100644 tests/regression_tests/uniform_fs/__init__.py create mode 100644 tests/regression_tests/universe/__init__.py create mode 100644 tests/regression_tests/void/__init__.py create mode 100644 tests/regression_tests/volume_calc/__init__.py create mode 100644 tests/unit_tests/__init__.py diff --git a/setup.py b/setup.py index 338fe5fec8..7bffc516f0 100755 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ with open('openmc/__init__.py', 'r') as f: kwargs = { 'name': 'openmc', 'version': version, - 'packages': find_packages(), + 'packages': find_packages(exclude=['tests*']), 'scripts': glob.glob('scripts/openmc-*'), # Data files and librarries diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/__init__.py b/tests/regression_tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/asymmetric_lattice/__init__.py b/tests/regression_tests/asymmetric_lattice/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/cmfd_feed/__init__.py b/tests/regression_tests/cmfd_feed/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/cmfd_nofeed/__init__.py b/tests/regression_tests/cmfd_nofeed/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/complex_cell/__init__.py b/tests/regression_tests/complex_cell/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/confidence_intervals/__init__.py b/tests/regression_tests/confidence_intervals/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/create_fission_neutrons/__init__.py b/tests/regression_tests/create_fission_neutrons/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/density/__init__.py b/tests/regression_tests/density/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/diff_tally/__init__.py b/tests/regression_tests/diff_tally/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/distribmat/__init__.py b/tests/regression_tests/distribmat/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/eigenvalue_genperbatch/__init__.py b/tests/regression_tests/eigenvalue_genperbatch/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/eigenvalue_no_inactive/__init__.py b/tests/regression_tests/eigenvalue_no_inactive/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/energy_cutoff/__init__.py b/tests/regression_tests/energy_cutoff/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/energy_grid/__init__.py b/tests/regression_tests/energy_grid/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/energy_laws/__init__.py b/tests/regression_tests/energy_laws/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/enrichment/__init__.py b/tests/regression_tests/enrichment/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/entropy/__init__.py b/tests/regression_tests/entropy/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/filter_distribcell/__init__.py b/tests/regression_tests/filter_distribcell/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/filter_energyfun/__init__.py b/tests/regression_tests/filter_energyfun/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/filter_mesh/__init__.py b/tests/regression_tests/filter_mesh/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/fixed_source/__init__.py b/tests/regression_tests/fixed_source/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/infinite_cell/__init__.py b/tests/regression_tests/infinite_cell/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/iso_in_lab/__init__.py b/tests/regression_tests/iso_in_lab/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/lattice/__init__.py b/tests/regression_tests/lattice/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/lattice_hex/__init__.py b/tests/regression_tests/lattice_hex/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/lattice_mixed/__init__.py b/tests/regression_tests/lattice_mixed/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/lattice_multiple/__init__.py b/tests/regression_tests/lattice_multiple/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/mg_basic/__init__.py b/tests/regression_tests/mg_basic/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/mg_convert/__init__.py b/tests/regression_tests/mg_convert/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/mg_legendre/__init__.py b/tests/regression_tests/mg_legendre/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/mg_max_order/__init__.py b/tests/regression_tests/mg_max_order/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/mg_nuclide/__init__.py b/tests/regression_tests/mg_nuclide/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/mg_survival_biasing/__init__.py b/tests/regression_tests/mg_survival_biasing/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/mg_tallies/__init__.py b/tests/regression_tests/mg_tallies/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/mgxs_library_ce_to_mg/__init__.py b/tests/regression_tests/mgxs_library_ce_to_mg/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/mgxs_library_condense/__init__.py b/tests/regression_tests/mgxs_library_condense/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/mgxs_library_distribcell/__init__.py b/tests/regression_tests/mgxs_library_distribcell/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/mgxs_library_hdf5/__init__.py b/tests/regression_tests/mgxs_library_hdf5/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/mgxs_library_mesh/__init__.py b/tests/regression_tests/mgxs_library_mesh/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/mgxs_library_no_nuclides/__init__.py b/tests/regression_tests/mgxs_library_no_nuclides/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/mgxs_library_nuclides/__init__.py b/tests/regression_tests/mgxs_library_nuclides/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/multipole/__init__.py b/tests/regression_tests/multipole/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/output/__init__.py b/tests/regression_tests/output/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/particle_restart_eigval/__init__.py b/tests/regression_tests/particle_restart_eigval/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/particle_restart_fixed/__init__.py b/tests/regression_tests/particle_restart_fixed/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/periodic/__init__.py b/tests/regression_tests/periodic/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/plot/__init__.py b/tests/regression_tests/plot/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/ptables_off/__init__.py b/tests/regression_tests/ptables_off/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/quadric_surfaces/__init__.py b/tests/regression_tests/quadric_surfaces/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/reflective_plane/__init__.py b/tests/regression_tests/reflective_plane/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/resonance_scattering/__init__.py b/tests/regression_tests/resonance_scattering/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/rotation/__init__.py b/tests/regression_tests/rotation/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/salphabeta/__init__.py b/tests/regression_tests/salphabeta/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/score_current/__init__.py b/tests/regression_tests/score_current/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/seed/__init__.py b/tests/regression_tests/seed/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/source/__init__.py b/tests/regression_tests/source/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/source_file/__init__.py b/tests/regression_tests/source_file/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/sourcepoint_batch/__init__.py b/tests/regression_tests/sourcepoint_batch/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/sourcepoint_latest/__init__.py b/tests/regression_tests/sourcepoint_latest/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/sourcepoint_restart/__init__.py b/tests/regression_tests/sourcepoint_restart/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/statepoint_batch/__init__.py b/tests/regression_tests/statepoint_batch/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/statepoint_restart/__init__.py b/tests/regression_tests/statepoint_restart/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/statepoint_sourcesep/__init__.py b/tests/regression_tests/statepoint_sourcesep/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/surface_tally/__init__.py b/tests/regression_tests/surface_tally/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/survival_biasing/__init__.py b/tests/regression_tests/survival_biasing/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/tallies/__init__.py b/tests/regression_tests/tallies/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/tally_aggregation/__init__.py b/tests/regression_tests/tally_aggregation/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/tally_arithmetic/__init__.py b/tests/regression_tests/tally_arithmetic/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/tally_assumesep/__init__.py b/tests/regression_tests/tally_assumesep/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/tally_nuclides/__init__.py b/tests/regression_tests/tally_nuclides/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/tally_slice_merge/__init__.py b/tests/regression_tests/tally_slice_merge/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/trace/__init__.py b/tests/regression_tests/trace/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/track_output/__init__.py b/tests/regression_tests/track_output/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/translation/__init__.py b/tests/regression_tests/translation/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/trigger_batch_interval/__init__.py b/tests/regression_tests/trigger_batch_interval/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/trigger_no_batch_interval/__init__.py b/tests/regression_tests/trigger_no_batch_interval/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/trigger_no_status/__init__.py b/tests/regression_tests/trigger_no_status/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/trigger_tallies/__init__.py b/tests/regression_tests/trigger_tallies/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/triso/__init__.py b/tests/regression_tests/triso/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/uniform_fs/__init__.py b/tests/regression_tests/uniform_fs/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/universe/__init__.py b/tests/regression_tests/universe/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/void/__init__.py b/tests/regression_tests/void/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/regression_tests/volume_calc/__init__.py b/tests/regression_tests/volume_calc/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/unit_tests/__init__.py b/tests/unit_tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 72aebfccf262d798e0ae574eb9c3989ec15be285 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 29 Jan 2018 10:52:36 -0600 Subject: [PATCH 34/74] Fix subtle bug with next_id not getting reset for autogenerated IDs --- openmc/mixin.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/openmc/mixin.py b/openmc/mixin.py index d724fc32a0..09a63ae4e4 100644 --- a/openmc/mixin.py +++ b/openmc/mixin.py @@ -45,14 +45,24 @@ class IDManagerMixin(object): @id.setter def id(self, uid): - cls = type(self) - name = cls.__name__ + # The first time this is called for a class, we search through the MRO + # to determine which class actually holds next_id and used_ids. Since + # next_id is an integer (immutable), we can't modify it directly through + # the instance without just creating a new attribute + try: + cls = self._id_class + except AttributeError: + for cls in self.__class__.__mro__: + if 'next_id' in cls.__dict__: + break + if uid is None: while cls.next_id in cls.used_ids: cls.next_id += 1 self._id = cls.next_id cls.used_ids.add(cls.next_id) else: + name = cls.__name__ cv.check_type('{} ID'.format(name), uid, Integral) cv.check_greater_than('{} ID'.format(name), uid, 0, equality=True) if uid in cls.used_ids: From 98d5496102b418613665f5caa7b447cd8ecdaeae Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 29 Jan 2018 10:53:46 -0600 Subject: [PATCH 35/74] Ability to run regression tests using pytest --- pytest.ini | 4 +++ .../asymmetric_lattice/test.py | 11 ++++--- tests/regression_tests/cmfd_feed/test.py | 10 ++----- tests/regression_tests/cmfd_nofeed/test.py | 10 ++----- tests/regression_tests/complex_cell/test.py | 10 ++----- .../confidence_intervals/test.py | 10 ++----- .../create_fission_neutrons/test.py | 11 +++---- tests/regression_tests/density/test.py | 10 ++----- tests/regression_tests/diff_tally/test.py | 12 ++++---- tests/regression_tests/distribmat/test.py | 11 +++---- .../eigenvalue_genperbatch/test.py | 10 ++----- .../eigenvalue_no_inactive/test.py | 10 ++----- tests/regression_tests/energy_cutoff/test.py | 11 +++---- tests/regression_tests/energy_grid/test.py | 10 ++----- tests/regression_tests/energy_laws/test.py | 11 ++----- tests/regression_tests/enrichment/test.py | 5 +--- tests/regression_tests/entropy/test.py | 11 ++++--- .../filter_distribcell/test.py | 11 +++---- .../regression_tests/filter_energyfun/test.py | 15 ++++------ tests/regression_tests/filter_mesh/test.py | 11 +++---- tests/regression_tests/fixed_source/test.py | 16 ++++------ tests/regression_tests/infinite_cell/test.py | 10 ++----- tests/regression_tests/iso_in_lab/test.py | 10 ++----- tests/regression_tests/lattice/test.py | 10 ++----- tests/regression_tests/lattice_hex/test.py | 10 ++----- tests/regression_tests/lattice_mixed/test.py | 10 ++----- .../regression_tests/lattice_multiple/test.py | 10 ++----- tests/regression_tests/mg_basic/test.py | 11 +++---- tests/regression_tests/mg_convert/test.py | 11 +++---- tests/regression_tests/mg_legendre/test.py | 12 +++----- tests/regression_tests/mg_max_order/test.py | 12 +++----- tests/regression_tests/mg_nuclide/test.py | 12 +++----- .../mg_survival_biasing/test.py | 11 +++---- tests/regression_tests/mg_tallies/test.py | 11 +++---- .../mgxs_library_ce_to_mg/test.py | 15 ++++------ .../mgxs_library_condense/test.py | 16 ++++------ .../mgxs_library_distribcell/test.py | 16 ++++------ .../mgxs_library_hdf5/test.py | 17 ++++------- .../mgxs_library_mesh/test.py | 16 ++++------ .../mgxs_library_no_nuclides/test.py | 13 +++----- .../mgxs_library_nuclides/test.py | 13 +++----- tests/regression_tests/multipole/test.py | 10 +++---- tests/regression_tests/output/test.py | 20 +++++-------- .../particle_restart_eigval/test.py | 10 ++----- .../particle_restart_fixed/test.py | 10 ++----- tests/regression_tests/periodic/test.py | 11 +++---- tests/regression_tests/plot/test.py | 11 +++---- tests/regression_tests/ptables_off/test.py | 10 ++----- .../regression_tests/quadric_surfaces/test.py | 10 ++----- .../regression_tests/reflective_plane/test.py | 10 ++----- .../resonance_scattering/test.py | 11 +++---- tests/regression_tests/rotation/test.py | 10 ++----- tests/regression_tests/salphabeta/test.py | 12 +++----- tests/regression_tests/score_current/test.py | 10 ++----- tests/regression_tests/seed/test.py | 10 ++----- tests/regression_tests/source/test.py | 12 +++----- tests/regression_tests/source_file/test.py | 8 ++--- .../sourcepoint_batch/test.py | 23 ++++++-------- .../sourcepoint_latest/test.py | 13 ++++---- .../sourcepoint_restart/test.py | 10 ++----- .../regression_tests/statepoint_batch/test.py | 10 ++----- .../statepoint_restart/test.py | 11 ++++--- .../statepoint_sourcesep/test.py | 16 ++++------ tests/regression_tests/surface_tally/test.py | 11 +++---- .../regression_tests/survival_biasing/test.py | 10 ++----- tests/regression_tests/tallies/test.py | 12 +++----- .../tally_aggregation/test.py | 16 ++++------ .../regression_tests/tally_arithmetic/test.py | 16 ++++------ .../regression_tests/tally_assumesep/test.py | 10 ++----- tests/regression_tests/tally_nuclides/test.py | 10 ++----- .../tally_slice_merge/test.py | 16 ++++------ tests/regression_tests/trace/test.py | 10 ++----- tests/regression_tests/track_output/test.py | 19 +++++------- tests/regression_tests/translation/test.py | 10 ++----- .../trigger_batch_interval/test.py | 10 ++----- .../trigger_no_batch_interval/test.py | 10 ++----- .../trigger_no_status/test.py | 10 ++----- .../regression_tests/trigger_tallies/test.py | 10 ++----- tests/regression_tests/triso/test.py | 13 +++----- tests/regression_tests/uniform_fs/test.py | 10 ++----- tests/regression_tests/universe/test.py | 10 ++----- tests/regression_tests/void/test.py | 10 ++----- tests/regression_tests/volume_calc/test.py | 13 ++++---- tests/testing_harness.py | 30 ++++++++++++------- 84 files changed, 351 insertions(+), 639 deletions(-) create mode 100644 pytest.ini diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000000..d960ba8d25 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,4 @@ +[pytest] +python_files = test*.py +python_classes = NoThanks +filterwarnings = ignore::UserWarning diff --git a/tests/regression_tests/asymmetric_lattice/test.py b/tests/regression_tests/asymmetric_lattice/test.py index f7cbf35c62..8bb2384855 100644 --- a/tests/regression_tests/asymmetric_lattice/test.py +++ b/tests/regression_tests/asymmetric_lattice/test.py @@ -1,13 +1,11 @@ -#!/usr/bin/env python - import os -import sys import glob import hashlib -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness + import openmc +from tests.testing_harness import PyAPITestHarness + class AsymmetricLatticeTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): @@ -90,6 +88,7 @@ class AsymmetricLatticeTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_asymmetric_lattice(request): harness = AsymmetricLatticeTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/cmfd_feed/test.py b/tests/regression_tests/cmfd_feed/test.py index 30e61d03f5..677c58c2a0 100644 --- a/tests/regression_tests/cmfd_feed/test.py +++ b/tests/regression_tests/cmfd_feed/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import CMFDTestHarness +from tests.testing_harness import CMFDTestHarness -if __name__ == '__main__': +def test_cmfd_feed(request): harness = CMFDTestHarness('statepoint.20.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/cmfd_nofeed/test.py b/tests/regression_tests/cmfd_nofeed/test.py index 30e61d03f5..113efc051d 100644 --- a/tests/regression_tests/cmfd_nofeed/test.py +++ b/tests/regression_tests/cmfd_nofeed/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import CMFDTestHarness +from tests.testing_harness import CMFDTestHarness -if __name__ == '__main__': +def test_cmfd_nofeed(request): harness = CMFDTestHarness('statepoint.20.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/complex_cell/test.py b/tests/regression_tests/complex_cell/test.py index 43f8e5ff0f..0e12eccf66 100755 --- a/tests/regression_tests/complex_cell/test.py +++ b/tests/regression_tests/complex_cell/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_complex_cell(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/confidence_intervals/test.py b/tests/regression_tests/confidence_intervals/test.py index 43f8e5ff0f..9d87e596be 100755 --- a/tests/regression_tests/confidence_intervals/test.py +++ b/tests/regression_tests/confidence_intervals/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_confidence_intervals(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/create_fission_neutrons/test.py b/tests/regression_tests/create_fission_neutrons/test.py index 080a0ab0d8..86ff9a29f9 100755 --- a/tests/regression_tests/create_fission_neutrons/test.py +++ b/tests/regression_tests/create_fission_neutrons/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness import openmc +from tests.testing_harness import PyAPITestHarness + class CreateFissionNeutronsTestHarness(PyAPITestHarness): def _build_inputs(self): @@ -69,6 +65,7 @@ class CreateFissionNeutronsTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_create_fission_neutrons(request): harness = CreateFissionNeutronsTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/density/test.py b/tests/regression_tests/density/test.py index 43f8e5ff0f..8ce3f5898e 100644 --- a/tests/regression_tests/density/test.py +++ b/tests/regression_tests/density/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_density(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/diff_tally/test.py b/tests/regression_tests/diff_tally/test.py index 5f1da9c30a..87dcd77b8f 100644 --- a/tests/regression_tests/diff_tally/test.py +++ b/tests/regression_tests/diff_tally/test.py @@ -1,15 +1,12 @@ -#!/usr/bin/env python - import glob import os -import sys import pandas as pd - -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness import openmc +from tests.testing_harness import PyAPITestHarness + + class DiffTallyTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): super(DiffTallyTestHarness, self).__init__(*args, **kwargs) @@ -125,6 +122,7 @@ class DiffTallyTestHarness(PyAPITestHarness): return df.to_csv(None, columns=cols, index=False, float_format='%.7e') -if __name__ == '__main__': +def test_diff_tally(request): harness = DiffTallyTestHarness('statepoint.3.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/distribmat/test.py b/tests/regression_tests/distribmat/test.py index d18bb15430..fdb77669ec 100644 --- a/tests/regression_tests/distribmat/test.py +++ b/tests/regression_tests/distribmat/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness, PyAPITestHarness import openmc +from tests.testing_harness import TestHarness, PyAPITestHarness + class DistribmatTestHarness(PyAPITestHarness): def _build_inputs(self): @@ -103,6 +99,7 @@ class DistribmatTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_distribmat(request): harness = DistribmatTestHarness('statepoint.5.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/eigenvalue_genperbatch/test.py b/tests/regression_tests/eigenvalue_genperbatch/test.py index a36c2ae374..1ba8e0d637 100644 --- a/tests/regression_tests/eigenvalue_genperbatch/test.py +++ b/tests/regression_tests/eigenvalue_genperbatch/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_eigenvalue_genperbatch(request): harness = TestHarness('statepoint.7.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/eigenvalue_no_inactive/test.py b/tests/regression_tests/eigenvalue_no_inactive/test.py index 43f8e5ff0f..a7ed17e0d4 100644 --- a/tests/regression_tests/eigenvalue_no_inactive/test.py +++ b/tests/regression_tests/eigenvalue_no_inactive/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_eigenvalue_no_inactive(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/energy_cutoff/test.py b/tests/regression_tests/energy_cutoff/test.py index 74f7b2ab2a..d597b331f2 100755 --- a/tests/regression_tests/energy_cutoff/test.py +++ b/tests/regression_tests/energy_cutoff/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness import openmc +from tests.testing_harness import PyAPITestHarness + class EnergyCutoffTestHarness(PyAPITestHarness): def _build_inputs(self): @@ -73,6 +69,7 @@ class EnergyCutoffTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_energy_cutoff(request): harness = EnergyCutoffTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/energy_grid/test.py b/tests/regression_tests/energy_grid/test.py index 43f8e5ff0f..f03e7de66a 100644 --- a/tests/regression_tests/energy_grid/test.py +++ b/tests/regression_tests/energy_grid/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_energy_grid(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/energy_laws/test.py b/tests/regression_tests/energy_laws/test.py index 5180344dab..02a58f763b 100644 --- a/tests/regression_tests/energy_laws/test.py +++ b/tests/regression_tests/energy_laws/test.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - """The purpose of this test is to provide coverage of energy distributions that are not covered in other tests. It has a single material with the following nuclides: @@ -18,13 +16,10 @@ that use linear-linear interpolation. """ -import glob -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_energy_laws(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/enrichment/test.py b/tests/regression_tests/enrichment/test.py index 395fafdf56..a20838c7cb 100644 --- a/tests/regression_tests/enrichment/test.py +++ b/tests/regression_tests/enrichment/test.py @@ -1,16 +1,13 @@ -#!/usr/bin/env python - import os import sys import numpy as np -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) from openmc import Material from openmc.data import NATURAL_ABUNDANCE, atomic_mass -if __name__ == '__main__': +def test_enrichment(): # This test doesn't require an OpenMC run. We just need to make sure the # element.expand() method expands Uranium to the proper enrichment. diff --git a/tests/regression_tests/entropy/test.py b/tests/regression_tests/entropy/test.py index bbc6c0c7f4..c2ccceffed 100644 --- a/tests/regression_tests/entropy/test.py +++ b/tests/regression_tests/entropy/test.py @@ -1,12 +1,10 @@ -#!/usr/bin/env python - import glob import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness + from openmc import StatePoint +from tests.testing_harness import TestHarness + class EntropyTestHarness(TestHarness): def _get_results(self): @@ -26,6 +24,7 @@ class EntropyTestHarness(TestHarness): return outstr -if __name__ == '__main__': +def test_entropy(request): harness = EntropyTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/filter_distribcell/test.py b/tests/regression_tests/filter_distribcell/test.py index 320a808a5f..a1354f56f9 100644 --- a/tests/regression_tests/filter_distribcell/test.py +++ b/tests/regression_tests/filter_distribcell/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - import glob -import hashlib import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import * + +from tests.testing_harness import * class DistribcellTestHarness(TestHarness): @@ -72,6 +68,7 @@ class DistribcellTestHarness(TestHarness): 'Tally output file does not exist.' -if __name__ == '__main__': +def test_filter_distribcell(request): harness = DistribcellTestHarness() + harness.request = request harness.main() diff --git a/tests/regression_tests/filter_energyfun/test.py b/tests/regression_tests/filter_energyfun/test.py index 1de522f540..c4d0d60f97 100644 --- a/tests/regression_tests/filter_energyfun/test.py +++ b/tests/regression_tests/filter_energyfun/test.py @@ -1,12 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -import glob -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness import openmc +from tests.testing_harness import PyAPITestHarness + class FilterEnergyFunHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): @@ -38,8 +33,7 @@ class FilterEnergyFunHarness(PyAPITestHarness): def _get_results(self): # Read the statepoint file. - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = openmc.StatePoint(statepoint) + sp = openmc.StatePoint(self._sp_name) # Use tally arithmetic to compute the branching ratio. br_tally = sp.tallies[2] / sp.tallies[1] @@ -48,6 +42,7 @@ class FilterEnergyFunHarness(PyAPITestHarness): return br_tally.get_pandas_dataframe().to_string() + '\n' -if __name__ == '__main__': +def test_filter_energyfun(request): harness = FilterEnergyFunHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/filter_mesh/test.py b/tests/regression_tests/filter_mesh/test.py index 4ad5e9005b..e5a0baba1d 100644 --- a/tests/regression_tests/filter_mesh/test.py +++ b/tests/regression_tests/filter_mesh/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import HashedPyAPITestHarness import openmc +from tests.testing_harness import HashedPyAPITestHarness + class FilterMeshTestHarness(HashedPyAPITestHarness): def __init__(self, *args, **kwargs): @@ -67,6 +63,7 @@ class FilterMeshTestHarness(HashedPyAPITestHarness): self._model.tallies.append(tally) -if __name__ == '__main__': +def test_filter_mesh(request): harness = FilterMeshTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/fixed_source/test.py b/tests/regression_tests/fixed_source/test.py index 3e28610fb0..caef20a4cb 100644 --- a/tests/regression_tests/fixed_source/test.py +++ b/tests/regression_tests/fixed_source/test.py @@ -1,22 +1,17 @@ -#!/usr/bin/env python - -import glob -import os -import sys import numpy as np -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness + import openmc import openmc.stats +from tests.testing_harness import PyAPITestHarness + class FixedSourceTestHarness(PyAPITestHarness): def _get_results(self): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] outstr = '' - with openmc.StatePoint(statepoint) as sp: + with openmc.StatePoint(self._sp_name) as sp: # Write out tally data. for i, tally_ind in enumerate(sp.tallies): tally = sp.tallies[tally_ind] @@ -36,7 +31,7 @@ class FixedSourceTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_fixed_source(request): mat = openmc.Material() mat.add_nuclide('O16', 1.0) mat.add_nuclide('U238', 0.0001) @@ -61,4 +56,5 @@ if __name__ == '__main__': model.tallies.append(tally) harness = FixedSourceTestHarness('statepoint.10.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/infinite_cell/test.py b/tests/regression_tests/infinite_cell/test.py index 43f8e5ff0f..0e2d8454db 100644 --- a/tests/regression_tests/infinite_cell/test.py +++ b/tests/regression_tests/infinite_cell/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_infinite_cell(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/iso_in_lab/test.py b/tests/regression_tests/iso_in_lab/test.py index 8cc9c7b7d7..37bf05a069 100644 --- a/tests/regression_tests/iso_in_lab/test.py +++ b/tests/regression_tests/iso_in_lab/test.py @@ -1,13 +1,9 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness +from tests.testing_harness import PyAPITestHarness -if __name__ == '__main__': +def test_iso_in_lab(request): # Force iso-in-lab scattering. harness = PyAPITestHarness('statepoint.10.h5') harness._model.materials.make_isotropic_in_lab() + harness.request = request harness.main() diff --git a/tests/regression_tests/lattice/test.py b/tests/regression_tests/lattice/test.py index 43f8e5ff0f..34c598680b 100644 --- a/tests/regression_tests/lattice/test.py +++ b/tests/regression_tests/lattice/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_lattice(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/lattice_hex/test.py b/tests/regression_tests/lattice_hex/test.py index 43f8e5ff0f..b0028f3c52 100644 --- a/tests/regression_tests/lattice_hex/test.py +++ b/tests/regression_tests/lattice_hex/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_lattice_hex(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/lattice_mixed/test.py b/tests/regression_tests/lattice_mixed/test.py index 43f8e5ff0f..2feb9a1381 100644 --- a/tests/regression_tests/lattice_mixed/test.py +++ b/tests/regression_tests/lattice_mixed/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_lattice_mixed(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/lattice_multiple/test.py b/tests/regression_tests/lattice_multiple/test.py index 43f8e5ff0f..15daf0beac 100644 --- a/tests/regression_tests/lattice_multiple/test.py +++ b/tests/regression_tests/lattice_multiple/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_lattice_multiple(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/mg_basic/test.py b/tests/regression_tests/mg_basic/test.py index 054503f9ab..9fb2681ffd 100644 --- a/tests/regression_tests/mg_basic/test.py +++ b/tests/regression_tests/mg_basic/test.py @@ -1,13 +1,10 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness from openmc.examples import slab_mg +from tests.testing_harness import PyAPITestHarness -if __name__ == '__main__': + +def test_mg_basic(request): model = slab_mg() harness = PyAPITestHarness('statepoint.10.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/mg_convert/test.py b/tests/regression_tests/mg_convert/test.py index 45f701ff11..f51e4e87b9 100755 --- a/tests/regression_tests/mg_convert/test.py +++ b/tests/regression_tests/mg_convert/test.py @@ -1,15 +1,11 @@ -#!/usr/bin/env python - import os -import sys import hashlib -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) import numpy as np - -from testing_harness import PyAPITestHarness import openmc +from tests.testing_harness import PyAPITestHarness + # OpenMC simulation parameters batches = 10 inactive = 5 @@ -202,6 +198,7 @@ class MGXSTestHarness(PyAPITestHarness): self._cleanup() -if __name__ == '__main__': +def test_mg_convert(request): harness = MGXSTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/mg_legendre/test.py b/tests/regression_tests/mg_legendre/test.py index 2e574afb61..a15cd5f94b 100644 --- a/tests/regression_tests/mg_legendre/test.py +++ b/tests/regression_tests/mg_legendre/test.py @@ -1,16 +1,12 @@ -#!/usr/bin/env python - -import os -import sys - -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness from openmc.examples import slab_mg +from tests.testing_harness import PyAPITestHarness -if __name__ == '__main__': + +def test_mg_legendre(request): model = slab_mg(reps=['iso']) model.settings.tabular_legendre = {'enable': False} harness = PyAPITestHarness('statepoint.10.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/mg_max_order/test.py b/tests/regression_tests/mg_max_order/test.py index 21fd2c0b64..c8f1ee7287 100644 --- a/tests/regression_tests/mg_max_order/test.py +++ b/tests/regression_tests/mg_max_order/test.py @@ -1,15 +1,11 @@ -#!/usr/bin/env python - -import os -import sys - -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness from openmc.examples import slab_mg +from tests.testing_harness import PyAPITestHarness -if __name__ == '__main__': + +def test_mg_max_order(request): model = slab_mg(reps=['iso']) model.settings.max_order = 1 harness = PyAPITestHarness('statepoint.10.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/mg_nuclide/test.py b/tests/regression_tests/mg_nuclide/test.py index d1c06cd417..fd298b3680 100644 --- a/tests/regression_tests/mg_nuclide/test.py +++ b/tests/regression_tests/mg_nuclide/test.py @@ -1,14 +1,10 @@ -#!/usr/bin/env python - -import os -import sys - -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness from openmc.examples import slab_mg +from tests.testing_harness import PyAPITestHarness -if __name__ == '__main__': + +def test_mg_nuclide(request): model = slab_mg(as_macro=False) harness = PyAPITestHarness('statepoint.10.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/mg_survival_biasing/test.py b/tests/regression_tests/mg_survival_biasing/test.py index 2669201c0e..a4c6e48097 100644 --- a/tests/regression_tests/mg_survival_biasing/test.py +++ b/tests/regression_tests/mg_survival_biasing/test.py @@ -1,14 +1,11 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness from openmc.examples import slab_mg +from tests.testing_harness import PyAPITestHarness -if __name__ == '__main__': + +def test_mg_survival_biasing(request): model = slab_mg() model.settings.survival_biasing = True harness = PyAPITestHarness('statepoint.10.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/mg_tallies/test.py b/tests/regression_tests/mg_tallies/test.py index ec7081e2ad..2adf34f7a2 100644 --- a/tests/regression_tests/mg_tallies/test.py +++ b/tests/regression_tests/mg_tallies/test.py @@ -1,14 +1,10 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import HashedPyAPITestHarness import openmc from openmc.examples import slab_mg +from tests.testing_harness import HashedPyAPITestHarness -if __name__ == '__main__': + +def test_mg_tallies(request): model = slab_mg(as_macro=False) # Instantiate a tally mesh @@ -92,4 +88,5 @@ if __name__ == '__main__': model.tallies.append(t) harness = HashedPyAPITestHarness('statepoint.10.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/mgxs_library_ce_to_mg/test.py b/tests/regression_tests/mgxs_library_ce_to_mg/test.py index e29cf58313..c8bcef172a 100644 --- a/tests/regression_tests/mgxs_library_ce_to_mg/test.py +++ b/tests/regression_tests/mgxs_library_ce_to_mg/test.py @@ -1,14 +1,9 @@ -#!/usr/bin/env python - -import os -import sys -import glob -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness import openmc import openmc.mgxs from openmc.examples import pwr_pin_cell +from tests.testing_harness import PyAPITestHarness + class MGXSTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): @@ -42,8 +37,7 @@ class MGXSTestHarness(PyAPITestHarness): # Build MG Inputs # Get data needed to execute Library calculations. - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = openmc.StatePoint(statepoint) + sp = openmc.StatePoint(self._sp_name) self.mgxs_lib.load_from_statepoint(sp) self._model.mgxs_file, self._model.materials, \ self._model.geometry = self.mgxs_lib.create_mg_mode() @@ -80,9 +74,10 @@ class MGXSTestHarness(PyAPITestHarness): os.remove(f) -if __name__ == '__main__': +def test_mgxs_library_ce_to_mg(request): # Set the input set to use the pincell model model = pwr_pin_cell() harness = MGXSTestHarness('statepoint.10.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/mgxs_library_condense/test.py b/tests/regression_tests/mgxs_library_condense/test.py index fd144636f9..c88c523417 100644 --- a/tests/regression_tests/mgxs_library_condense/test.py +++ b/tests/regression_tests/mgxs_library_condense/test.py @@ -1,15 +1,11 @@ -#!/usr/bin/env python - -import os -import sys -import glob import hashlib -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness + import openmc import openmc.mgxs from openmc.examples import pwr_pin_cell +from tests.testing_harness import PyAPITestHarness + class MGXSTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): @@ -38,8 +34,7 @@ class MGXSTestHarness(PyAPITestHarness): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = openmc.StatePoint(statepoint) + sp = openmc.StatePoint(self._sp_name) # Load the MGXS library from the statepoint self.mgxs_lib.load_from_statepoint(sp) @@ -65,8 +60,9 @@ class MGXSTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_mgxs_library_condense(request): # Use the pincell model model = pwr_pin_cell() harness = MGXSTestHarness('statepoint.10.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/mgxs_library_distribcell/test.py b/tests/regression_tests/mgxs_library_distribcell/test.py index e59f4c7578..f18ae54b10 100644 --- a/tests/regression_tests/mgxs_library_distribcell/test.py +++ b/tests/regression_tests/mgxs_library_distribcell/test.py @@ -1,15 +1,11 @@ -#!/usr/bin/env python - -import os -import sys -import glob import hashlib -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness + import openmc import openmc.mgxs from openmc.examples import pwr_assembly +from tests.testing_harness import PyAPITestHarness + class MGXSTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): @@ -43,8 +39,7 @@ class MGXSTestHarness(PyAPITestHarness): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = openmc.StatePoint(statepoint) + sp = openmc.StatePoint(self._sp_name) # Load the MGXS library from the statepoint self.mgxs_lib.load_from_statepoint(sp) @@ -69,7 +64,8 @@ class MGXSTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_mgxs_library_distribcell(request): model = pwr_assembly() harness = MGXSTestHarness('statepoint.10.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/mgxs_library_hdf5/test.py b/tests/regression_tests/mgxs_library_hdf5/test.py index 8daf828cea..b070f22e82 100644 --- a/tests/regression_tests/mgxs_library_hdf5/test.py +++ b/tests/regression_tests/mgxs_library_hdf5/test.py @@ -1,19 +1,14 @@ -#!/usr/bin/env python - import os -import sys -import glob import hashlib import numpy as np import h5py - -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness import openmc import openmc.mgxs from openmc.examples import pwr_pin_cell +from tests.testing_harness import PyAPITestHarness + np.set_printoptions(formatter={'float_kind': '{:.8e}'.format}) @@ -46,8 +41,7 @@ class MGXSTestHarness(PyAPITestHarness): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = openmc.StatePoint(statepoint) + sp = openmc.StatePoint(self._sp_name) # Load the MGXS library from the statepoint self.mgxs_lib.load_from_statepoint(sp) @@ -77,12 +71,13 @@ class MGXSTestHarness(PyAPITestHarness): def _cleanup(self): super(MGXSTestHarness, self)._cleanup() - f = os.path.join(os.getcwd(), 'mgxs.h5') + f = 'mgxs.h5' if os.path.exists(f): os.remove(f) -if __name__ == '__main__': +def test_mgxs_library_hdf5(request): model = pwr_pin_cell() harness = MGXSTestHarness('statepoint.10.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/mgxs_library_mesh/test.py b/tests/regression_tests/mgxs_library_mesh/test.py index 06cb10601b..809782467d 100644 --- a/tests/regression_tests/mgxs_library_mesh/test.py +++ b/tests/regression_tests/mgxs_library_mesh/test.py @@ -1,14 +1,10 @@ -#!/usr/bin/env python - -import os -import sys -import glob import hashlib -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness + import openmc import openmc.mgxs +from tests.testing_harness import PyAPITestHarness + class MGXSTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): @@ -47,8 +43,7 @@ class MGXSTestHarness(PyAPITestHarness): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = openmc.StatePoint(statepoint) + sp = openmc.StatePoint(self._sp_name) # Load the MGXS library from the statepoint self.mgxs_lib.load_from_statepoint(sp) @@ -70,6 +65,7 @@ class MGXSTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_mgxs_library_mesh(request): harness = MGXSTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/mgxs_library_no_nuclides/test.py b/tests/regression_tests/mgxs_library_no_nuclides/test.py index ede916059c..743be994fd 100644 --- a/tests/regression_tests/mgxs_library_no_nuclides/test.py +++ b/tests/regression_tests/mgxs_library_no_nuclides/test.py @@ -1,15 +1,11 @@ -#!/usr/bin/env python - -import os -import sys -import glob import hashlib -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness + import openmc import openmc.mgxs from openmc.examples import pwr_pin_cell +from tests.testing_harness import PyAPITestHarness + class MGXSTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): @@ -39,8 +35,7 @@ class MGXSTestHarness(PyAPITestHarness): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = openmc.StatePoint(statepoint) + sp = openmc.StatePoint(self._sp_name) # Load the MGXS library from the statepoint self.mgxs_lib.load_from_statepoint(sp) diff --git a/tests/regression_tests/mgxs_library_nuclides/test.py b/tests/regression_tests/mgxs_library_nuclides/test.py index e668ab52cc..23ebb23297 100644 --- a/tests/regression_tests/mgxs_library_nuclides/test.py +++ b/tests/regression_tests/mgxs_library_nuclides/test.py @@ -1,15 +1,11 @@ -#!/usr/bin/env python - -import os -import sys -import glob import hashlib -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness + import openmc import openmc.mgxs from openmc.examples import pwr_pin_cell +from tests.testing_harness import PyAPITestHarness + class MGXSTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): @@ -35,8 +31,7 @@ class MGXSTestHarness(PyAPITestHarness): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = openmc.StatePoint(statepoint) + sp = openmc.StatePoint(self._sp_name) # Load the MGXS library from the statepoint self.mgxs_lib.load_from_statepoint(sp) diff --git a/tests/regression_tests/multipole/test.py b/tests/regression_tests/multipole/test.py index 20da97f7c0..a91bdae5ee 100644 --- a/tests/regression_tests/multipole/test.py +++ b/tests/regression_tests/multipole/test.py @@ -1,11 +1,10 @@ -#!/usr/bin/env python import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness, PyAPITestHarness + import openmc import openmc.model +from tests.testing_harness import TestHarness, PyAPITestHarness + def make_model(): model = openmc.model.Model() @@ -81,7 +80,8 @@ class MultipoleTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_multipole(request): model = make_model() harness = MultipoleTestHarness('statepoint.5.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/output/test.py b/tests/regression_tests/output/test.py index 0092f54919..30fcc3a80c 100644 --- a/tests/regression_tests/output/test.py +++ b/tests/regression_tests/output/test.py @@ -1,10 +1,7 @@ -#!/usr/bin/env python - -import glob import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +import glob + +from tests.testing_harness import TestHarness class OutputTestHarness(TestHarness): @@ -21,13 +18,12 @@ class OutputTestHarness(TestHarness): def _cleanup(self): TestHarness._cleanup(self) - output = glob.glob(os.path.join(os.getcwd(), 'summary.*')) - output.append(os.path.join(os.getcwd(), 'cross_sections.out')) - for f in output: - if os.path.exists(f): - os.remove(f) + f = 'summary.h5' + if os.path.exists(f): + os.remove(f) -if __name__ == '__main__': +def test_output(request): harness = OutputTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/particle_restart_eigval/test.py b/tests/regression_tests/particle_restart_eigval/test.py index 455ff9e927..6b9d103fdb 100644 --- a/tests/regression_tests/particle_restart_eigval/test.py +++ b/tests/regression_tests/particle_restart_eigval/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import ParticleRestartTestHarness +from tests.testing_harness import ParticleRestartTestHarness -if __name__ == '__main__': +def test_particle_restart_eigval(request): harness = ParticleRestartTestHarness('particle_10_1030.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/particle_restart_fixed/test.py b/tests/regression_tests/particle_restart_fixed/test.py index e473fdb59e..428d9586d9 100644 --- a/tests/regression_tests/particle_restart_fixed/test.py +++ b/tests/regression_tests/particle_restart_fixed/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import ParticleRestartTestHarness +from tests.testing_harness import ParticleRestartTestHarness -if __name__ == '__main__': +def test_particle_restart_fixed(request): harness = ParticleRestartTestHarness('particle_7_144.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/periodic/test.py b/tests/regression_tests/periodic/test.py index ddd7cd89b8..188827a5dc 100644 --- a/tests/regression_tests/periodic/test.py +++ b/tests/regression_tests/periodic/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness import openmc +from tests.testing_harness import PyAPITestHarness + class PeriodicTest(PyAPITestHarness): def _build_inputs(self): @@ -55,6 +51,7 @@ class PeriodicTest(PyAPITestHarness): settings.export_to_xml() -if __name__ == '__main__': +def test_periodic(request): harness = PeriodicTest('statepoint.4.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/plot/test.py b/tests/regression_tests/plot/test.py index d0c362ef2b..1e7773ea6a 100644 --- a/tests/regression_tests/plot/test.py +++ b/tests/regression_tests/plot/test.py @@ -1,16 +1,12 @@ -#!/usr/bin/env python - import glob import hashlib import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness import h5py - import openmc +from tests.testing_harness import TestHarness + class PlotTestHarness(TestHarness): """Specialized TestHarness for running OpenMC plotting tests.""" @@ -60,7 +56,8 @@ class PlotTestHarness(TestHarness): return outstr -if __name__ == '__main__': +def test_plot(request): harness = PlotTestHarness(('plot_1.ppm', 'plot_2.ppm', 'plot_3.ppm', 'plot_4.h5')) + harness.request = request harness.main() diff --git a/tests/regression_tests/ptables_off/test.py b/tests/regression_tests/ptables_off/test.py index 43f8e5ff0f..8d67cf400b 100644 --- a/tests/regression_tests/ptables_off/test.py +++ b/tests/regression_tests/ptables_off/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_ptables_off(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/quadric_surfaces/test.py b/tests/regression_tests/quadric_surfaces/test.py index 43f8e5ff0f..f919f1648c 100755 --- a/tests/regression_tests/quadric_surfaces/test.py +++ b/tests/regression_tests/quadric_surfaces/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_quadric_surfaces(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/reflective_plane/test.py b/tests/regression_tests/reflective_plane/test.py index 43f8e5ff0f..ba693c61aa 100644 --- a/tests/regression_tests/reflective_plane/test.py +++ b/tests/regression_tests/reflective_plane/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_reflective_plane(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/resonance_scattering/test.py b/tests/regression_tests/resonance_scattering/test.py index 3ed7fe2272..98096a0cac 100644 --- a/tests/regression_tests/resonance_scattering/test.py +++ b/tests/regression_tests/resonance_scattering/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness import openmc +from tests.testing_harness import PyAPITestHarness + class ResonanceScatteringTestHarness(PyAPITestHarness): def _build_inputs(self): @@ -46,6 +42,7 @@ class ResonanceScatteringTestHarness(PyAPITestHarness): settings.export_to_xml() -if __name__ == '__main__': +def test_resonance_scattering(request): harness = ResonanceScatteringTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/rotation/test.py b/tests/regression_tests/rotation/test.py index 43f8e5ff0f..b27e7faa4b 100644 --- a/tests/regression_tests/rotation/test.py +++ b/tests/regression_tests/rotation/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_rotation(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/salphabeta/test.py b/tests/regression_tests/salphabeta/test.py index 6ced79a8d6..4ab213fce9 100644 --- a/tests/regression_tests/salphabeta/test.py +++ b/tests/regression_tests/salphabeta/test.py @@ -1,13 +1,8 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) - -from testing_harness import PyAPITestHarness import openmc import openmc.model +from tests.testing_harness import PyAPITestHarness + def make_model(): model = openmc.model.Model() @@ -78,7 +73,8 @@ def make_model(): return model -if __name__ == '__main__': +def test_salphabeta(request): model = make_model() harness = PyAPITestHarness('statepoint.5.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/score_current/test.py b/tests/regression_tests/score_current/test.py index 70ddc22198..1acc7c604f 100644 --- a/tests/regression_tests/score_current/test.py +++ b/tests/regression_tests/score_current/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import HashedTestHarness +from tests.testing_harness import HashedTestHarness -if __name__ == '__main__': +def test_score_current(request): harness = HashedTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/seed/test.py b/tests/regression_tests/seed/test.py index 43f8e5ff0f..4c6bf95dc2 100644 --- a/tests/regression_tests/seed/test.py +++ b/tests/regression_tests/seed/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_seed(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/source/test.py b/tests/regression_tests/source/test.py index 7a3d054d8e..aa17143f0d 100644 --- a/tests/regression_tests/source/test.py +++ b/tests/regression_tests/source/test.py @@ -1,15 +1,10 @@ -#!/usr/bin/env python - from math import pi -import os -import sys import numpy as np - -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness import openmc +from tests.testing_harness import PyAPITestHarness + class SourceTestHarness(PyAPITestHarness): def _build_inputs(self): @@ -63,6 +58,7 @@ class SourceTestHarness(PyAPITestHarness): settings.export_to_xml() -if __name__ == '__main__': +def test_source(request): harness = SourceTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/source_file/test.py b/tests/regression_tests/source_file/test.py index f04441a208..1989de4c90 100644 --- a/tests/regression_tests/source_file/test.py +++ b/tests/regression_tests/source_file/test.py @@ -2,9 +2,8 @@ import glob import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import * + +from tests.testing_harness import * settings1=""" @@ -97,6 +96,7 @@ class SourceFileTestHarness(TestHarness): fh.write(settings1) -if __name__ == '__main__': +def test_source_file(request): harness = SourceFileTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/sourcepoint_batch/test.py b/tests/regression_tests/sourcepoint_batch/test.py index 1239a00dcd..96326d15b8 100644 --- a/tests/regression_tests/sourcepoint_batch/test.py +++ b/tests/regression_tests/sourcepoint_batch/test.py @@ -1,20 +1,15 @@ -#!/usr/bin/env python - import glob -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness + from openmc import StatePoint +from tests.testing_harness import TestHarness + class SourcepointTestHarness(TestHarness): def _test_output_created(self): - """Make sure statepoint.* files have been created.""" - statepoint = glob.glob(os.path.join(os.getcwd(), 'statepoint.*')) - assert len(statepoint) == 5, '5 statepoint files must exist.' - assert statepoint[0].endswith('h5'), \ - 'Statepoint file is not a HDF5 file.' + """Make sure statepoint files have been created.""" + statepoint = glob.glob('statepoint.*.h5') + assert len(statepoint) == 5, 'Five statepoint files must exist.' def _get_results(self): """Digest info in the statepoint and return as a string.""" @@ -22,8 +17,7 @@ class SourcepointTestHarness(TestHarness): outstr = TestHarness._get_results(self) # Read the statepoint file. - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - with StatePoint(statepoint) as sp: + with StatePoint(self._sp_name) as sp: # Add the source information. xyz = sp.source[0]['xyz'] outstr += ' '.join(['{0:12.6E}'.format(x) for x in xyz]) @@ -32,6 +26,7 @@ class SourcepointTestHarness(TestHarness): return outstr -if __name__ == '__main__': +def test_sourcepoint_batch(request): harness = SourcepointTestHarness('statepoint.08.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/sourcepoint_latest/test.py b/tests/regression_tests/sourcepoint_latest/test.py index 4af176eecd..15082e6d82 100644 --- a/tests/regression_tests/sourcepoint_latest/test.py +++ b/tests/regression_tests/sourcepoint_latest/test.py @@ -1,22 +1,19 @@ -#!/usr/bin/env python - import os import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness + +from tests.testing_harness import TestHarness class SourcepointTestHarness(TestHarness): def _test_output_created(self): """Make sure statepoint.* and source* have been created.""" TestHarness._test_output_created(self) - source = glob.glob(os.path.join(os.getcwd(), 'source.*')) + source = glob.glob(os.path.join(os.getcwd(), 'source.*.h5')) assert len(source) == 1, 'Either multiple or no source files ' \ 'exist.' - assert source[0].endswith('h5'), \ - 'Source file is not a HDF5 file.' -if __name__ == '__main__': +def test_sourcepoint_latest(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/sourcepoint_restart/test.py b/tests/regression_tests/sourcepoint_restart/test.py index 43f8e5ff0f..b0d2e9069a 100644 --- a/tests/regression_tests/sourcepoint_restart/test.py +++ b/tests/regression_tests/sourcepoint_restart/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_sourcepoint_restart(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/statepoint_batch/test.py b/tests/regression_tests/statepoint_batch/test.py index 0820aa6f01..aeb91e2a6e 100644 --- a/tests/regression_tests/statepoint_batch/test.py +++ b/tests/regression_tests/statepoint_batch/test.py @@ -1,9 +1,4 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness class StatepointTestHarness(TestHarness): @@ -18,6 +13,7 @@ class StatepointTestHarness(TestHarness): TestHarness._test_output_created(self) -if __name__ == '__main__': +def test_statepoint_batch(request): harness = StatepointTestHarness() + harness.request = request harness.main() diff --git a/tests/regression_tests/statepoint_restart/test.py b/tests/regression_tests/statepoint_restart/test.py index f3a52c1cf0..219a8a7ed8 100644 --- a/tests/regression_tests/statepoint_restart/test.py +++ b/tests/regression_tests/statepoint_restart/test.py @@ -1,12 +1,10 @@ -#!/usr/bin/env python - import glob import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness + import openmc +from tests.testing_harness import TestHarness + class StatepointRestartTestHarness(TestHarness): def __init__(self, final_sp, restart_sp): @@ -56,7 +54,8 @@ class StatepointRestartTestHarness(TestHarness): openmc.run(openmc_exec=self._opts.exe, restart_file=statepoint) -if __name__ == '__main__': +def test_statepoint_restart(request): harness = StatepointRestartTestHarness('statepoint.10.h5', 'statepoint.07.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/statepoint_sourcesep/test.py b/tests/regression_tests/statepoint_sourcesep/test.py index 904fa471e8..44a45d406f 100644 --- a/tests/regression_tests/statepoint_sourcesep/test.py +++ b/tests/regression_tests/statepoint_sourcesep/test.py @@ -1,30 +1,26 @@ -#!/usr/bin/env python - import glob import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness + +from tests.testing_harness import TestHarness class SourcepointTestHarness(TestHarness): def _test_output_created(self): """Make sure statepoint.* and source* have been created.""" TestHarness._test_output_created(self) - source = glob.glob(os.path.join(os.getcwd(), 'source.*')) + source = glob.glob('source.*.h5') assert len(source) == 1, 'Either multiple or no source files ' \ 'exist.' - assert source[0].endswith('h5'), \ - 'Source file is not a HDF5 file.' def _cleanup(self): TestHarness._cleanup(self) - output = glob.glob(os.path.join(os.getcwd(), 'source.*')) + output = glob.glob('source.*.h5') for f in output: if os.path.exists(f): os.remove(f) -if __name__ == '__main__': +def test_statepoint_sourcesep(request): harness = SourcepointTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/surface_tally/test.py b/tests/regression_tests/surface_tally/test.py index 9729fdf20d..2d499cb293 100644 --- a/tests/regression_tests/surface_tally/test.py +++ b/tests/regression_tests/surface_tally/test.py @@ -1,13 +1,9 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness import numpy as np import openmc import pandas as pd +from tests.testing_harness import PyAPITestHarness + class SurfaceTallyTestHarness(PyAPITestHarness): def _build_inputs(self): @@ -178,6 +174,7 @@ class SurfaceTallyTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_surface_tally(request): harness = SurfaceTallyTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/survival_biasing/test.py b/tests/regression_tests/survival_biasing/test.py index 43f8e5ff0f..2dc7c86ab1 100644 --- a/tests/regression_tests/survival_biasing/test.py +++ b/tests/regression_tests/survival_biasing/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_survival_biasing(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/tallies/test.py b/tests/regression_tests/tallies/test.py index 693e941af1..25545dd82a 100644 --- a/tests/regression_tests/tallies/test.py +++ b/tests/regression_tests/tallies/test.py @@ -1,16 +1,12 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) - -from testing_harness import HashedPyAPITestHarness from openmc.filter import * from openmc import Mesh, Tally, Tallies +from tests.testing_harness import HashedPyAPITestHarness -if __name__ == '__main__': + +def test_tallies(request): harness = HashedPyAPITestHarness('statepoint.5.h5') + harness.request = request model = harness._model # Set settings explicitly diff --git a/tests/regression_tests/tally_aggregation/test.py b/tests/regression_tests/tally_aggregation/test.py index 62d3a3f041..dfa0266902 100644 --- a/tests/regression_tests/tally_aggregation/test.py +++ b/tests/regression_tests/tally_aggregation/test.py @@ -1,13 +1,9 @@ -#!/usr/bin/env python - -import os -import sys -import glob import hashlib -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness + import openmc +from tests.testing_harness import PyAPITestHarness + class TallyAggregationTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): @@ -28,8 +24,7 @@ class TallyAggregationTestHarness(PyAPITestHarness): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = openmc.StatePoint(statepoint) + sp = openmc.StatePoint(self._sp_name) # Extract the tally of interest tally = sp.get_tally(name='distribcell tally') @@ -66,6 +61,7 @@ class TallyAggregationTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_tally_aggregation(request): harness = TallyAggregationTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/tally_arithmetic/test.py b/tests/regression_tests/tally_arithmetic/test.py index fab1b0fb2c..c87d0149f4 100644 --- a/tests/regression_tests/tally_arithmetic/test.py +++ b/tests/regression_tests/tally_arithmetic/test.py @@ -1,13 +1,9 @@ -#!/usr/bin/env python - -import os -import sys -import glob import hashlib -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness + import openmc +from tests.testing_harness import PyAPITestHarness + class TallyArithmeticTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): @@ -43,8 +39,7 @@ class TallyArithmeticTestHarness(PyAPITestHarness): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = openmc.StatePoint(statepoint) + sp = openmc.StatePoint(self._sp_name) # Load the tallies tally_1 = sp.get_tally(name='tally 1') @@ -80,6 +75,7 @@ class TallyArithmeticTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_tally_arithmetic(request): harness = TallyArithmeticTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/tally_assumesep/test.py b/tests/regression_tests/tally_assumesep/test.py index 43f8e5ff0f..c4248c10af 100644 --- a/tests/regression_tests/tally_assumesep/test.py +++ b/tests/regression_tests/tally_assumesep/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_tally_assumesep(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/tally_nuclides/test.py b/tests/regression_tests/tally_nuclides/test.py index 43f8e5ff0f..7eec5ef3f1 100644 --- a/tests/regression_tests/tally_nuclides/test.py +++ b/tests/regression_tests/tally_nuclides/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_tally_nuclides(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/tally_slice_merge/test.py b/tests/regression_tests/tally_slice_merge/test.py index 84908b5cbe..4ee99d34a8 100644 --- a/tests/regression_tests/tally_slice_merge/test.py +++ b/tests/regression_tests/tally_slice_merge/test.py @@ -1,16 +1,12 @@ -#!/usr/bin/env python - from __future__ import division -import os -import sys -import glob import hashlib import itertools -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness + import openmc +from tests.testing_harness import PyAPITestHarness + class TallySliceMergeTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): @@ -85,8 +81,7 @@ class TallySliceMergeTestHarness(PyAPITestHarness): """Digest info in the statepoint and return as a string.""" # Read the statepoint file. - statepoint = glob.glob(os.path.join(os.getcwd(), self._sp_name))[0] - sp = openmc.StatePoint(statepoint) + sp = openmc.StatePoint(self._sp_name) # Extract the cell tally tallies = [sp.get_tally(name='cell tally')] @@ -171,6 +166,7 @@ class TallySliceMergeTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_tally_slice_merge(request): harness = TallySliceMergeTestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/trace/test.py b/tests/regression_tests/trace/test.py index 43f8e5ff0f..c037bb23bf 100644 --- a/tests/regression_tests/trace/test.py +++ b/tests/regression_tests/trace/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_trace(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/track_output/test.py b/tests/regression_tests/track_output/test.py index c7a2df4ebe..b0abb7ecc8 100644 --- a/tests/regression_tests/track_output/test.py +++ b/tests/regression_tests/track_output/test.py @@ -1,12 +1,11 @@ -#!/usr/bin/env python - import glob import os from subprocess import call import shutil -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness + +import pytest + +from tests.testing_harness import TestHarness class TrackTestHarness(TestHarness): @@ -39,14 +38,10 @@ class TrackTestHarness(TestHarness): os.remove(f) -if __name__ == '__main__': +def test_track_output(request): # If vtk python module is not available, we can't run track.py so skip this # test. - try: - import vtk - except ImportError: - print('----------------Skipping test-------------') - shutil.copy('results_true.dat', 'results_test.dat') - exit() + vtk = pytest.importerskip('vtk') harness = TrackTestHarness('statepoint.2.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/translation/test.py b/tests/regression_tests/translation/test.py index 43f8e5ff0f..29ef1c0114 100644 --- a/tests/regression_tests/translation/test.py +++ b/tests/regression_tests/translation/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_translation(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/trigger_batch_interval/test.py b/tests/regression_tests/trigger_batch_interval/test.py index 542c2ffdeb..1ac01a08bf 100644 --- a/tests/regression_tests/trigger_batch_interval/test.py +++ b/tests/regression_tests/trigger_batch_interval/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_trigger_batch_interval(request): harness = TestHarness('statepoint.15.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/trigger_no_batch_interval/test.py b/tests/regression_tests/trigger_no_batch_interval/test.py index 542c2ffdeb..d38304feea 100644 --- a/tests/regression_tests/trigger_no_batch_interval/test.py +++ b/tests/regression_tests/trigger_no_batch_interval/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_trigger_no_batch_interval(request): harness = TestHarness('statepoint.15.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/trigger_no_status/test.py b/tests/regression_tests/trigger_no_status/test.py index 43f8e5ff0f..98173f8dda 100644 --- a/tests/regression_tests/trigger_no_status/test.py +++ b/tests/regression_tests/trigger_no_status/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_trigger_no_status(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/trigger_tallies/test.py b/tests/regression_tests/trigger_tallies/test.py index 542c2ffdeb..fde7298ffe 100644 --- a/tests/regression_tests/trigger_tallies/test.py +++ b/tests/regression_tests/trigger_tallies/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_trigger_tallies(request): harness = TestHarness('statepoint.15.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/triso/test.py b/tests/regression_tests/triso/test.py index c92495ace3..2da26d1d38 100644 --- a/tests/regression_tests/triso/test.py +++ b/tests/regression_tests/triso/test.py @@ -1,18 +1,12 @@ -#!/usr/bin/env python - -import os -import sys -import glob import random from math import sqrt import numpy as np - -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness import openmc import openmc.model +from tests.testing_harness import PyAPITestHarness + class TRISOTestHarness(PyAPITestHarness): def _build_inputs(self): @@ -96,6 +90,7 @@ class TRISOTestHarness(PyAPITestHarness): mats.export_to_xml() -if __name__ == '__main__': +def test_triso(request): harness = TRISOTestHarness('statepoint.5.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/uniform_fs/test.py b/tests/regression_tests/uniform_fs/test.py index 43f8e5ff0f..553484e0ab 100644 --- a/tests/regression_tests/uniform_fs/test.py +++ b/tests/regression_tests/uniform_fs/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_uniform_fs(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/universe/test.py b/tests/regression_tests/universe/test.py index 43f8e5ff0f..5da34d90c8 100644 --- a/tests/regression_tests/universe/test.py +++ b/tests/regression_tests/universe/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_universe(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/void/test.py b/tests/regression_tests/void/test.py index 43f8e5ff0f..a08813c45b 100644 --- a/tests/regression_tests/void/test.py +++ b/tests/regression_tests/void/test.py @@ -1,11 +1,7 @@ -#!/usr/bin/env python - -import os -import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import TestHarness +from tests.testing_harness import TestHarness -if __name__ == '__main__': +def test_void(request): harness = TestHarness('statepoint.10.h5') + harness.request = request harness.main() diff --git a/tests/regression_tests/volume_calc/test.py b/tests/regression_tests/volume_calc/test.py index 47ce27a122..da3a66c36f 100644 --- a/tests/regression_tests/volume_calc/test.py +++ b/tests/regression_tests/volume_calc/test.py @@ -1,12 +1,11 @@ -#!/usr/bin/env python - import os import glob import sys -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) -from testing_harness import PyAPITestHarness + import openmc +from tests.testing_harness import PyAPITestHarness + class VolumeTest(PyAPITestHarness): def _build_inputs(self): @@ -57,8 +56,7 @@ class VolumeTest(PyAPITestHarness): def _get_results(self): outstr = '' - for i, filename in enumerate(sorted(glob.glob(os.path.join( - os.getcwd(), 'volume_*.h5')))): + for i, filename in enumerate(sorted(glob.glob('volume_*.h5'))): outstr += 'Volume calculation {}\n'.format(i) # Read volume calculation results @@ -75,6 +73,7 @@ class VolumeTest(PyAPITestHarness): def _test_output_created(self): pass -if __name__ == '__main__': +def test_volume_calc(request): harness = VolumeTest('') + harness.request = request harness.main() diff --git a/tests/testing_harness.py b/tests/testing_harness.py index ad3b8ac1ec..9aee4f741a 100644 --- a/tests/testing_harness.py +++ b/tests/testing_harness.py @@ -11,7 +11,6 @@ import sys import numpy as np -sys.path.insert(0, os.path.join(os.pardir, os.pardir)) import openmc from openmc.examples import pwr_core @@ -33,10 +32,14 @@ class TestHarness(object): def main(self): """Accept commandline arguments and either run or update tests.""" (self._opts, self._args) = self.parser.parse_args() - if self._opts.update: - self.update_results() - else: - self.execute_test() + try: + olddir = self.request.fspath.dirpath().chdir() + if self._opts.update: + self.update_results() + else: + self.execute_test() + finally: + olddir.chdir() def execute_test(self): """Run OpenMC with the appropriate arguments and check the outputs.""" @@ -234,6 +237,7 @@ class PyAPITestHarness(TestHarness): super(PyAPITestHarness, self).__init__(statepoint_name) self.parser.add_option('-b', '--build-inputs', dest='build_only', action='store_true', default=False) + openmc.reset_auto_ids() if model is None: self._model = pwr_core() else: @@ -244,12 +248,16 @@ class PyAPITestHarness(TestHarness): def main(self): """Accept commandline arguments and either run or update tests.""" (self._opts, self._args) = self.parser.parse_args() - if self._opts.build_only: - self._build_inputs() - elif self._opts.update: - self.update_results() - else: - self.execute_test() + try: + olddir = self.request.fspath.dirpath().chdir() + if self._opts.build_only: + self._build_inputs() + elif self._opts.update: + self.update_results() + else: + self.execute_test() + finally: + olddir.chdir() def execute_test(self): """Build input XMLs, run OpenMC, and verify correct results.""" From 73947ad7de5061d094f12a7feebb7e55ca876f31 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 29 Jan 2018 11:39:37 -0600 Subject: [PATCH 36/74] Reset IDs for tests that instantiate models directly --- tests/regression_tests/fixed_source/test.py | 2 +- tests/regression_tests/mg_basic/test.py | 2 +- tests/regression_tests/mg_legendre/test.py | 2 +- tests/regression_tests/mg_max_order/test.py | 2 +- tests/regression_tests/mg_nuclide/test.py | 2 +- .../mg_survival_biasing/test.py | 2 +- tests/regression_tests/mg_tallies/test.py | 2 +- .../mgxs_library_ce_to_mg/test.py | 10 ++++++---- .../mgxs_library_condense/test.py | 2 +- .../mgxs_library_distribcell/test.py | 2 +- .../regression_tests/mgxs_library_hdf5/test.py | 17 +++++++++-------- .../mgxs_library_no_nuclides/test.py | 3 ++- .../mgxs_library_nuclides/test.py | 3 ++- tests/regression_tests/multipole/test.py | 2 +- tests/regression_tests/salphabeta/test.py | 2 +- tests/regression_tests/tallies/test.py | 2 +- tests/regression_tests/track_output/test.py | 2 +- 17 files changed, 32 insertions(+), 27 deletions(-) diff --git a/tests/regression_tests/fixed_source/test.py b/tests/regression_tests/fixed_source/test.py index caef20a4cb..e652ed3f82 100644 --- a/tests/regression_tests/fixed_source/test.py +++ b/tests/regression_tests/fixed_source/test.py @@ -31,7 +31,7 @@ class FixedSourceTestHarness(PyAPITestHarness): return outstr -def test_fixed_source(request): +def test_fixed_source(request, reset_ids): mat = openmc.Material() mat.add_nuclide('O16', 1.0) mat.add_nuclide('U238', 0.0001) diff --git a/tests/regression_tests/mg_basic/test.py b/tests/regression_tests/mg_basic/test.py index 9fb2681ffd..7b4ec247a6 100644 --- a/tests/regression_tests/mg_basic/test.py +++ b/tests/regression_tests/mg_basic/test.py @@ -3,7 +3,7 @@ from openmc.examples import slab_mg from tests.testing_harness import PyAPITestHarness -def test_mg_basic(request): +def test_mg_basic(request, reset_ids): model = slab_mg() harness = PyAPITestHarness('statepoint.10.h5', model) harness.request = request diff --git a/tests/regression_tests/mg_legendre/test.py b/tests/regression_tests/mg_legendre/test.py index a15cd5f94b..58ea4a1dc4 100644 --- a/tests/regression_tests/mg_legendre/test.py +++ b/tests/regression_tests/mg_legendre/test.py @@ -3,7 +3,7 @@ from openmc.examples import slab_mg from tests.testing_harness import PyAPITestHarness -def test_mg_legendre(request): +def test_mg_legendre(request, reset_ids): model = slab_mg(reps=['iso']) model.settings.tabular_legendre = {'enable': False} diff --git a/tests/regression_tests/mg_max_order/test.py b/tests/regression_tests/mg_max_order/test.py index c8f1ee7287..72bca32317 100644 --- a/tests/regression_tests/mg_max_order/test.py +++ b/tests/regression_tests/mg_max_order/test.py @@ -3,7 +3,7 @@ from openmc.examples import slab_mg from tests.testing_harness import PyAPITestHarness -def test_mg_max_order(request): +def test_mg_max_order(request, reset_ids): model = slab_mg(reps=['iso']) model.settings.max_order = 1 harness = PyAPITestHarness('statepoint.10.h5', model) diff --git a/tests/regression_tests/mg_nuclide/test.py b/tests/regression_tests/mg_nuclide/test.py index fd298b3680..53eac5e8d5 100644 --- a/tests/regression_tests/mg_nuclide/test.py +++ b/tests/regression_tests/mg_nuclide/test.py @@ -3,7 +3,7 @@ from openmc.examples import slab_mg from tests.testing_harness import PyAPITestHarness -def test_mg_nuclide(request): +def test_mg_nuclide(request, reset_ids): model = slab_mg(as_macro=False) harness = PyAPITestHarness('statepoint.10.h5', model) harness.request = request diff --git a/tests/regression_tests/mg_survival_biasing/test.py b/tests/regression_tests/mg_survival_biasing/test.py index a4c6e48097..09a210d046 100644 --- a/tests/regression_tests/mg_survival_biasing/test.py +++ b/tests/regression_tests/mg_survival_biasing/test.py @@ -3,7 +3,7 @@ from openmc.examples import slab_mg from tests.testing_harness import PyAPITestHarness -def test_mg_survival_biasing(request): +def test_mg_survival_biasing(request, reset_ids): model = slab_mg() model.settings.survival_biasing = True harness = PyAPITestHarness('statepoint.10.h5', model) diff --git a/tests/regression_tests/mg_tallies/test.py b/tests/regression_tests/mg_tallies/test.py index 2adf34f7a2..3f9bcae79f 100644 --- a/tests/regression_tests/mg_tallies/test.py +++ b/tests/regression_tests/mg_tallies/test.py @@ -4,7 +4,7 @@ from openmc.examples import slab_mg from tests.testing_harness import HashedPyAPITestHarness -def test_mg_tallies(request): +def test_mg_tallies(request, reset_ids): model = slab_mg(as_macro=False) # Instantiate a tally mesh diff --git a/tests/regression_tests/mgxs_library_ce_to_mg/test.py b/tests/regression_tests/mgxs_library_ce_to_mg/test.py index c8bcef172a..9246694ea9 100644 --- a/tests/regression_tests/mgxs_library_ce_to_mg/test.py +++ b/tests/regression_tests/mgxs_library_ce_to_mg/test.py @@ -1,3 +1,5 @@ +import os + import openmc import openmc.mgxs from openmc.examples import pwr_pin_cell @@ -52,8 +54,8 @@ class MGXSTestHarness(PyAPITestHarness): self._model.materials.export_to_xml() self._model.mgxs_file.export_to_hdf5() # Dont need tallies.xml, so remove the file - if os.path.exists('./tallies.xml'): - os.remove('./tallies.xml') + if os.path.exists('tallies.xml'): + os.remove('tallies.xml') # Enforce closing statepoint and summary files so HDF5 # does not throw an error during the next OpenMC execution @@ -69,12 +71,12 @@ class MGXSTestHarness(PyAPITestHarness): def _cleanup(self): super(MGXSTestHarness, self)._cleanup() - f = os.path.join(os.getcwd(), 'mgxs.h5') + f = 'mgxs.h5' if os.path.exists(f): os.remove(f) -def test_mgxs_library_ce_to_mg(request): +def test_mgxs_library_ce_to_mg(request, reset_ids): # Set the input set to use the pincell model model = pwr_pin_cell() diff --git a/tests/regression_tests/mgxs_library_condense/test.py b/tests/regression_tests/mgxs_library_condense/test.py index c88c523417..b7ecf8925c 100644 --- a/tests/regression_tests/mgxs_library_condense/test.py +++ b/tests/regression_tests/mgxs_library_condense/test.py @@ -60,7 +60,7 @@ class MGXSTestHarness(PyAPITestHarness): return outstr -def test_mgxs_library_condense(request): +def test_mgxs_library_condense(request, reset_ids): # Use the pincell model model = pwr_pin_cell() harness = MGXSTestHarness('statepoint.10.h5', model) diff --git a/tests/regression_tests/mgxs_library_distribcell/test.py b/tests/regression_tests/mgxs_library_distribcell/test.py index f18ae54b10..b9f343eafa 100644 --- a/tests/regression_tests/mgxs_library_distribcell/test.py +++ b/tests/regression_tests/mgxs_library_distribcell/test.py @@ -64,7 +64,7 @@ class MGXSTestHarness(PyAPITestHarness): return outstr -def test_mgxs_library_distribcell(request): +def test_mgxs_library_distribcell(request, reset_ids): model = pwr_assembly() harness = MGXSTestHarness('statepoint.10.h5', model) harness.request = request diff --git a/tests/regression_tests/mgxs_library_hdf5/test.py b/tests/regression_tests/mgxs_library_hdf5/test.py index b070f22e82..38dbeef1a5 100644 --- a/tests/regression_tests/mgxs_library_hdf5/test.py +++ b/tests/regression_tests/mgxs_library_hdf5/test.py @@ -10,9 +10,6 @@ from openmc.examples import pwr_pin_cell from tests.testing_harness import PyAPITestHarness -np.set_printoptions(formatter={'float_kind': '{:.8e}'.format}) - - class MGXSTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): # Generate inputs using parent class routine @@ -76,8 +73,12 @@ class MGXSTestHarness(PyAPITestHarness): os.remove(f) -def test_mgxs_library_hdf5(request): - model = pwr_pin_cell() - harness = MGXSTestHarness('statepoint.10.h5', model) - harness.request = request - harness.main() +def test_mgxs_library_hdf5(request, reset_ids): + try: + np.set_printoptions(formatter={'float_kind': '{:.8e}'.format}) + model = pwr_pin_cell() + harness = MGXSTestHarness('statepoint.10.h5', model) + harness.request = request + harness.main() + finally: + np.set_printoptions(formatter=None) diff --git a/tests/regression_tests/mgxs_library_no_nuclides/test.py b/tests/regression_tests/mgxs_library_no_nuclides/test.py index 743be994fd..3e6e236480 100644 --- a/tests/regression_tests/mgxs_library_no_nuclides/test.py +++ b/tests/regression_tests/mgxs_library_no_nuclides/test.py @@ -57,7 +57,8 @@ class MGXSTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_mgxs_library_no_nuclides(request, reset_ids): model = pwr_pin_cell() harness = MGXSTestHarness('statepoint.10.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/mgxs_library_nuclides/test.py b/tests/regression_tests/mgxs_library_nuclides/test.py index 23ebb23297..c670e18e30 100644 --- a/tests/regression_tests/mgxs_library_nuclides/test.py +++ b/tests/regression_tests/mgxs_library_nuclides/test.py @@ -53,7 +53,8 @@ class MGXSTestHarness(PyAPITestHarness): return outstr -if __name__ == '__main__': +def test_mgxs_library_nuclides(request, reset_ids): model = pwr_pin_cell() harness = MGXSTestHarness('statepoint.10.h5', model) + harness.request = request harness.main() diff --git a/tests/regression_tests/multipole/test.py b/tests/regression_tests/multipole/test.py index a91bdae5ee..d7ed3ca7c0 100644 --- a/tests/regression_tests/multipole/test.py +++ b/tests/regression_tests/multipole/test.py @@ -80,7 +80,7 @@ class MultipoleTestHarness(PyAPITestHarness): return outstr -def test_multipole(request): +def test_multipole(request, reset_ids): model = make_model() harness = MultipoleTestHarness('statepoint.5.h5', model) harness.request = request diff --git a/tests/regression_tests/salphabeta/test.py b/tests/regression_tests/salphabeta/test.py index 4ab213fce9..62ccbb2267 100644 --- a/tests/regression_tests/salphabeta/test.py +++ b/tests/regression_tests/salphabeta/test.py @@ -73,7 +73,7 @@ def make_model(): return model -def test_salphabeta(request): +def test_salphabeta(request, reset_ids): model = make_model() harness = PyAPITestHarness('statepoint.5.h5', model) harness.request = request diff --git a/tests/regression_tests/tallies/test.py b/tests/regression_tests/tallies/test.py index 25545dd82a..3f6f7de748 100644 --- a/tests/regression_tests/tallies/test.py +++ b/tests/regression_tests/tallies/test.py @@ -4,7 +4,7 @@ from openmc import Mesh, Tally, Tallies from tests.testing_harness import HashedPyAPITestHarness -def test_tallies(request): +def test_tallies(request, reset_ids): harness = HashedPyAPITestHarness('statepoint.5.h5') harness.request = request model = harness._model diff --git a/tests/regression_tests/track_output/test.py b/tests/regression_tests/track_output/test.py index b0abb7ecc8..f3d665e11e 100644 --- a/tests/regression_tests/track_output/test.py +++ b/tests/regression_tests/track_output/test.py @@ -41,7 +41,7 @@ class TrackTestHarness(TestHarness): def test_track_output(request): # If vtk python module is not available, we can't run track.py so skip this # test. - vtk = pytest.importerskip('vtk') + vtk = pytest.importorskip('vtk') harness = TrackTestHarness('statepoint.2.h5') harness.request = request harness.main() From 740f03fce15760433a90835c2197cb5bc42f5160 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 29 Jan 2018 12:10:24 -0600 Subject: [PATCH 37/74] Use single package-level fixture for regression tests --- .../asymmetric_lattice/test.py | 3 +- tests/regression_tests/cmfd_feed/test.py | 3 +- tests/regression_tests/cmfd_nofeed/test.py | 3 +- tests/regression_tests/complex_cell/test.py | 3 +- .../confidence_intervals/test.py | 3 +- tests/regression_tests/conftest.py | 15 ++++++++++ .../create_fission_neutrons/test.py | 3 +- tests/regression_tests/density/test.py | 3 +- tests/regression_tests/diff_tally/test.py | 3 +- tests/regression_tests/distribmat/test.py | 3 +- .../eigenvalue_genperbatch/test.py | 3 +- .../eigenvalue_no_inactive/test.py | 3 +- tests/regression_tests/energy_cutoff/test.py | 3 +- tests/regression_tests/energy_grid/test.py | 3 +- tests/regression_tests/energy_laws/test.py | 3 +- tests/regression_tests/entropy/test.py | 3 +- .../filter_distribcell/test.py | 3 +- .../regression_tests/filter_energyfun/test.py | 3 +- tests/regression_tests/filter_mesh/test.py | 3 +- tests/regression_tests/fixed_source/test.py | 3 +- tests/regression_tests/infinite_cell/test.py | 3 +- tests/regression_tests/iso_in_lab/test.py | 3 +- tests/regression_tests/lattice/test.py | 3 +- tests/regression_tests/lattice_hex/test.py | 3 +- tests/regression_tests/lattice_mixed/test.py | 3 +- .../regression_tests/lattice_multiple/test.py | 3 +- tests/regression_tests/mg_basic/test.py | 3 +- tests/regression_tests/mg_convert/test.py | 3 +- tests/regression_tests/mg_legendre/test.py | 3 +- tests/regression_tests/mg_max_order/test.py | 3 +- tests/regression_tests/mg_nuclide/test.py | 3 +- .../mg_survival_biasing/test.py | 3 +- tests/regression_tests/mg_tallies/test.py | 3 +- .../mgxs_library_ce_to_mg/test.py | 3 +- .../mgxs_library_condense/test.py | 3 +- .../mgxs_library_distribcell/test.py | 3 +- .../mgxs_library_hdf5/test.py | 3 +- .../mgxs_library_mesh/test.py | 3 +- .../mgxs_library_no_nuclides/test.py | 3 +- .../mgxs_library_nuclides/test.py | 3 +- tests/regression_tests/multipole/test.py | 3 +- tests/regression_tests/output/test.py | 3 +- .../particle_restart_eigval/test.py | 3 +- .../particle_restart_fixed/test.py | 3 +- tests/regression_tests/periodic/test.py | 3 +- tests/regression_tests/plot/test.py | 3 +- tests/regression_tests/ptables_off/test.py | 3 +- .../regression_tests/quadric_surfaces/test.py | 3 +- .../regression_tests/reflective_plane/test.py | 3 +- .../resonance_scattering/test.py | 3 +- tests/regression_tests/rotation/test.py | 3 +- tests/regression_tests/salphabeta/test.py | 3 +- tests/regression_tests/score_current/test.py | 3 +- tests/regression_tests/seed/test.py | 3 +- tests/regression_tests/source/test.py | 3 +- tests/regression_tests/source_file/test.py | 3 +- .../sourcepoint_batch/test.py | 3 +- .../sourcepoint_latest/test.py | 3 +- .../sourcepoint_restart/test.py | 3 +- .../regression_tests/statepoint_batch/test.py | 3 +- .../statepoint_restart/test.py | 3 +- .../statepoint_sourcesep/test.py | 3 +- tests/regression_tests/surface_tally/test.py | 3 +- .../regression_tests/survival_biasing/test.py | 3 +- tests/regression_tests/tallies/test.py | 3 +- .../tally_aggregation/test.py | 3 +- .../regression_tests/tally_arithmetic/test.py | 3 +- .../regression_tests/tally_assumesep/test.py | 3 +- tests/regression_tests/tally_nuclides/test.py | 3 +- .../tally_slice_merge/test.py | 3 +- tests/regression_tests/trace/test.py | 3 +- tests/regression_tests/track_output/test.py | 3 +- tests/regression_tests/translation/test.py | 3 +- .../trigger_batch_interval/test.py | 3 +- .../trigger_no_batch_interval/test.py | 3 +- .../trigger_no_status/test.py | 3 +- .../regression_tests/trigger_tallies/test.py | 3 +- tests/regression_tests/triso/test.py | 3 +- tests/regression_tests/uniform_fs/test.py | 3 +- tests/regression_tests/universe/test.py | 3 +- tests/regression_tests/void/test.py | 3 +- tests/regression_tests/volume_calc/test.py | 3 +- tests/testing_harness.py | 29 +++++++------------ 83 files changed, 106 insertions(+), 181 deletions(-) create mode 100644 tests/regression_tests/conftest.py diff --git a/tests/regression_tests/asymmetric_lattice/test.py b/tests/regression_tests/asymmetric_lattice/test.py index 8bb2384855..0318d7b922 100644 --- a/tests/regression_tests/asymmetric_lattice/test.py +++ b/tests/regression_tests/asymmetric_lattice/test.py @@ -88,7 +88,6 @@ class AsymmetricLatticeTestHarness(PyAPITestHarness): return outstr -def test_asymmetric_lattice(request): +def test_asymmetric_lattice(): harness = AsymmetricLatticeTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/cmfd_feed/test.py b/tests/regression_tests/cmfd_feed/test.py index 677c58c2a0..4fc39d96ad 100644 --- a/tests/regression_tests/cmfd_feed/test.py +++ b/tests/regression_tests/cmfd_feed/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import CMFDTestHarness -def test_cmfd_feed(request): +def test_cmfd_feed(): harness = CMFDTestHarness('statepoint.20.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/cmfd_nofeed/test.py b/tests/regression_tests/cmfd_nofeed/test.py index 113efc051d..a3c7301738 100644 --- a/tests/regression_tests/cmfd_nofeed/test.py +++ b/tests/regression_tests/cmfd_nofeed/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import CMFDTestHarness -def test_cmfd_nofeed(request): +def test_cmfd_nofeed(): harness = CMFDTestHarness('statepoint.20.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/complex_cell/test.py b/tests/regression_tests/complex_cell/test.py index 0e12eccf66..77cbd6cb7d 100755 --- a/tests/regression_tests/complex_cell/test.py +++ b/tests/regression_tests/complex_cell/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_complex_cell(request): +def test_complex_cell(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/confidence_intervals/test.py b/tests/regression_tests/confidence_intervals/test.py index 9d87e596be..3227418280 100755 --- a/tests/regression_tests/confidence_intervals/test.py +++ b/tests/regression_tests/confidence_intervals/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_confidence_intervals(request): +def test_confidence_intervals(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/conftest.py b/tests/regression_tests/conftest.py new file mode 100644 index 0000000000..00ef247dc4 --- /dev/null +++ b/tests/regression_tests/conftest.py @@ -0,0 +1,15 @@ +import openmc +import pytest + + +@pytest.fixture(scope='module', autouse=True) +def setup_regression_test(request): + # Reset autogenerated IDs assigned to OpenMC objects + openmc.reset_auto_ids() + + # Change to test directory + olddir = request.fspath.dirpath().chdir() + try: + yield + finally: + olddir.chdir() diff --git a/tests/regression_tests/create_fission_neutrons/test.py b/tests/regression_tests/create_fission_neutrons/test.py index 86ff9a29f9..f1c1d072cb 100755 --- a/tests/regression_tests/create_fission_neutrons/test.py +++ b/tests/regression_tests/create_fission_neutrons/test.py @@ -65,7 +65,6 @@ class CreateFissionNeutronsTestHarness(PyAPITestHarness): return outstr -def test_create_fission_neutrons(request): +def test_create_fission_neutrons(): harness = CreateFissionNeutronsTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/density/test.py b/tests/regression_tests/density/test.py index 8ce3f5898e..f3ae6b4144 100644 --- a/tests/regression_tests/density/test.py +++ b/tests/regression_tests/density/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_density(request): +def test_density(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/diff_tally/test.py b/tests/regression_tests/diff_tally/test.py index 87dcd77b8f..e383b726e8 100644 --- a/tests/regression_tests/diff_tally/test.py +++ b/tests/regression_tests/diff_tally/test.py @@ -122,7 +122,6 @@ class DiffTallyTestHarness(PyAPITestHarness): return df.to_csv(None, columns=cols, index=False, float_format='%.7e') -def test_diff_tally(request): +def test_diff_tally(): harness = DiffTallyTestHarness('statepoint.3.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/distribmat/test.py b/tests/regression_tests/distribmat/test.py index fdb77669ec..69bb7a67b1 100644 --- a/tests/regression_tests/distribmat/test.py +++ b/tests/regression_tests/distribmat/test.py @@ -99,7 +99,6 @@ class DistribmatTestHarness(PyAPITestHarness): return outstr -def test_distribmat(request): +def test_distribmat(): harness = DistribmatTestHarness('statepoint.5.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/eigenvalue_genperbatch/test.py b/tests/regression_tests/eigenvalue_genperbatch/test.py index 1ba8e0d637..0dfb112428 100644 --- a/tests/regression_tests/eigenvalue_genperbatch/test.py +++ b/tests/regression_tests/eigenvalue_genperbatch/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_eigenvalue_genperbatch(request): +def test_eigenvalue_genperbatch(): harness = TestHarness('statepoint.7.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/eigenvalue_no_inactive/test.py b/tests/regression_tests/eigenvalue_no_inactive/test.py index a7ed17e0d4..5ab4900153 100644 --- a/tests/regression_tests/eigenvalue_no_inactive/test.py +++ b/tests/regression_tests/eigenvalue_no_inactive/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_eigenvalue_no_inactive(request): +def test_eigenvalue_no_inactive(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/energy_cutoff/test.py b/tests/regression_tests/energy_cutoff/test.py index d597b331f2..8b16149947 100755 --- a/tests/regression_tests/energy_cutoff/test.py +++ b/tests/regression_tests/energy_cutoff/test.py @@ -69,7 +69,6 @@ class EnergyCutoffTestHarness(PyAPITestHarness): return outstr -def test_energy_cutoff(request): +def test_energy_cutoff(): harness = EnergyCutoffTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/energy_grid/test.py b/tests/regression_tests/energy_grid/test.py index f03e7de66a..889bdfbc61 100644 --- a/tests/regression_tests/energy_grid/test.py +++ b/tests/regression_tests/energy_grid/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_energy_grid(request): +def test_energy_grid(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/energy_laws/test.py b/tests/regression_tests/energy_laws/test.py index 02a58f763b..8f9bbde356 100644 --- a/tests/regression_tests/energy_laws/test.py +++ b/tests/regression_tests/energy_laws/test.py @@ -19,7 +19,6 @@ that use linear-linear interpolation. from tests.testing_harness import TestHarness -def test_energy_laws(request): +def test_energy_laws(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/entropy/test.py b/tests/regression_tests/entropy/test.py index c2ccceffed..0f1052b6b8 100644 --- a/tests/regression_tests/entropy/test.py +++ b/tests/regression_tests/entropy/test.py @@ -24,7 +24,6 @@ class EntropyTestHarness(TestHarness): return outstr -def test_entropy(request): +def test_entropy(): harness = EntropyTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/filter_distribcell/test.py b/tests/regression_tests/filter_distribcell/test.py index a1354f56f9..bdd134bf57 100644 --- a/tests/regression_tests/filter_distribcell/test.py +++ b/tests/regression_tests/filter_distribcell/test.py @@ -68,7 +68,6 @@ class DistribcellTestHarness(TestHarness): 'Tally output file does not exist.' -def test_filter_distribcell(request): +def test_filter_distribcell(): harness = DistribcellTestHarness() - harness.request = request harness.main() diff --git a/tests/regression_tests/filter_energyfun/test.py b/tests/regression_tests/filter_energyfun/test.py index c4d0d60f97..d9148dd35d 100644 --- a/tests/regression_tests/filter_energyfun/test.py +++ b/tests/regression_tests/filter_energyfun/test.py @@ -42,7 +42,6 @@ class FilterEnergyFunHarness(PyAPITestHarness): return br_tally.get_pandas_dataframe().to_string() + '\n' -def test_filter_energyfun(request): +def test_filter_energyfun(): harness = FilterEnergyFunHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/filter_mesh/test.py b/tests/regression_tests/filter_mesh/test.py index e5a0baba1d..66cd1ac19f 100644 --- a/tests/regression_tests/filter_mesh/test.py +++ b/tests/regression_tests/filter_mesh/test.py @@ -63,7 +63,6 @@ class FilterMeshTestHarness(HashedPyAPITestHarness): self._model.tallies.append(tally) -def test_filter_mesh(request): +def test_filter_mesh(): harness = FilterMeshTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/fixed_source/test.py b/tests/regression_tests/fixed_source/test.py index e652ed3f82..7d98de9fc3 100644 --- a/tests/regression_tests/fixed_source/test.py +++ b/tests/regression_tests/fixed_source/test.py @@ -31,7 +31,7 @@ class FixedSourceTestHarness(PyAPITestHarness): return outstr -def test_fixed_source(request, reset_ids): +def test_fixed_source(): mat = openmc.Material() mat.add_nuclide('O16', 1.0) mat.add_nuclide('U238', 0.0001) @@ -56,5 +56,4 @@ def test_fixed_source(request, reset_ids): model.tallies.append(tally) harness = FixedSourceTestHarness('statepoint.10.h5', model) - harness.request = request harness.main() diff --git a/tests/regression_tests/infinite_cell/test.py b/tests/regression_tests/infinite_cell/test.py index 0e2d8454db..59abec3003 100644 --- a/tests/regression_tests/infinite_cell/test.py +++ b/tests/regression_tests/infinite_cell/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_infinite_cell(request): +def test_infinite_cell(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/iso_in_lab/test.py b/tests/regression_tests/iso_in_lab/test.py index 37bf05a069..0e8edc2186 100644 --- a/tests/regression_tests/iso_in_lab/test.py +++ b/tests/regression_tests/iso_in_lab/test.py @@ -1,9 +1,8 @@ from tests.testing_harness import PyAPITestHarness -def test_iso_in_lab(request): +def test_iso_in_lab(): # Force iso-in-lab scattering. harness = PyAPITestHarness('statepoint.10.h5') harness._model.materials.make_isotropic_in_lab() - harness.request = request harness.main() diff --git a/tests/regression_tests/lattice/test.py b/tests/regression_tests/lattice/test.py index 34c598680b..a32b9a629c 100644 --- a/tests/regression_tests/lattice/test.py +++ b/tests/regression_tests/lattice/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_lattice(request): +def test_lattice(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/lattice_hex/test.py b/tests/regression_tests/lattice_hex/test.py index b0028f3c52..eb63f84df5 100644 --- a/tests/regression_tests/lattice_hex/test.py +++ b/tests/regression_tests/lattice_hex/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_lattice_hex(request): +def test_lattice_hex(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/lattice_mixed/test.py b/tests/regression_tests/lattice_mixed/test.py index 2feb9a1381..3df1d7a4f3 100644 --- a/tests/regression_tests/lattice_mixed/test.py +++ b/tests/regression_tests/lattice_mixed/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_lattice_mixed(request): +def test_lattice_mixed(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/lattice_multiple/test.py b/tests/regression_tests/lattice_multiple/test.py index 15daf0beac..f0672d9a4e 100644 --- a/tests/regression_tests/lattice_multiple/test.py +++ b/tests/regression_tests/lattice_multiple/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_lattice_multiple(request): +def test_lattice_multiple(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/mg_basic/test.py b/tests/regression_tests/mg_basic/test.py index 7b4ec247a6..3c22e60408 100644 --- a/tests/regression_tests/mg_basic/test.py +++ b/tests/regression_tests/mg_basic/test.py @@ -3,8 +3,7 @@ from openmc.examples import slab_mg from tests.testing_harness import PyAPITestHarness -def test_mg_basic(request, reset_ids): +def test_mg_basic(): model = slab_mg() harness = PyAPITestHarness('statepoint.10.h5', model) - harness.request = request harness.main() diff --git a/tests/regression_tests/mg_convert/test.py b/tests/regression_tests/mg_convert/test.py index f51e4e87b9..e6a8690c22 100755 --- a/tests/regression_tests/mg_convert/test.py +++ b/tests/regression_tests/mg_convert/test.py @@ -198,7 +198,6 @@ class MGXSTestHarness(PyAPITestHarness): self._cleanup() -def test_mg_convert(request): +def test_mg_convert(): harness = MGXSTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/mg_legendre/test.py b/tests/regression_tests/mg_legendre/test.py index 58ea4a1dc4..5a57f758e8 100644 --- a/tests/regression_tests/mg_legendre/test.py +++ b/tests/regression_tests/mg_legendre/test.py @@ -3,10 +3,9 @@ from openmc.examples import slab_mg from tests.testing_harness import PyAPITestHarness -def test_mg_legendre(request, reset_ids): +def test_mg_legendre(): model = slab_mg(reps=['iso']) model.settings.tabular_legendre = {'enable': False} harness = PyAPITestHarness('statepoint.10.h5', model) - harness.request = request harness.main() diff --git a/tests/regression_tests/mg_max_order/test.py b/tests/regression_tests/mg_max_order/test.py index 72bca32317..20cc4f805d 100644 --- a/tests/regression_tests/mg_max_order/test.py +++ b/tests/regression_tests/mg_max_order/test.py @@ -3,9 +3,8 @@ from openmc.examples import slab_mg from tests.testing_harness import PyAPITestHarness -def test_mg_max_order(request, reset_ids): +def test_mg_max_order(): model = slab_mg(reps=['iso']) model.settings.max_order = 1 harness = PyAPITestHarness('statepoint.10.h5', model) - harness.request = request harness.main() diff --git a/tests/regression_tests/mg_nuclide/test.py b/tests/regression_tests/mg_nuclide/test.py index 53eac5e8d5..44206ef28f 100644 --- a/tests/regression_tests/mg_nuclide/test.py +++ b/tests/regression_tests/mg_nuclide/test.py @@ -3,8 +3,7 @@ from openmc.examples import slab_mg from tests.testing_harness import PyAPITestHarness -def test_mg_nuclide(request, reset_ids): +def test_mg_nuclide(): model = slab_mg(as_macro=False) harness = PyAPITestHarness('statepoint.10.h5', model) - harness.request = request harness.main() diff --git a/tests/regression_tests/mg_survival_biasing/test.py b/tests/regression_tests/mg_survival_biasing/test.py index 09a210d046..3c6c77a370 100644 --- a/tests/regression_tests/mg_survival_biasing/test.py +++ b/tests/regression_tests/mg_survival_biasing/test.py @@ -3,9 +3,8 @@ from openmc.examples import slab_mg from tests.testing_harness import PyAPITestHarness -def test_mg_survival_biasing(request, reset_ids): +def test_mg_survival_biasing(): model = slab_mg() model.settings.survival_biasing = True harness = PyAPITestHarness('statepoint.10.h5', model) - harness.request = request harness.main() diff --git a/tests/regression_tests/mg_tallies/test.py b/tests/regression_tests/mg_tallies/test.py index 3f9bcae79f..8952cc4ad8 100644 --- a/tests/regression_tests/mg_tallies/test.py +++ b/tests/regression_tests/mg_tallies/test.py @@ -4,7 +4,7 @@ from openmc.examples import slab_mg from tests.testing_harness import HashedPyAPITestHarness -def test_mg_tallies(request, reset_ids): +def test_mg_tallies(): model = slab_mg(as_macro=False) # Instantiate a tally mesh @@ -88,5 +88,4 @@ def test_mg_tallies(request, reset_ids): model.tallies.append(t) harness = HashedPyAPITestHarness('statepoint.10.h5', model) - harness.request = request harness.main() diff --git a/tests/regression_tests/mgxs_library_ce_to_mg/test.py b/tests/regression_tests/mgxs_library_ce_to_mg/test.py index 9246694ea9..9dc640acd1 100644 --- a/tests/regression_tests/mgxs_library_ce_to_mg/test.py +++ b/tests/regression_tests/mgxs_library_ce_to_mg/test.py @@ -76,10 +76,9 @@ class MGXSTestHarness(PyAPITestHarness): os.remove(f) -def test_mgxs_library_ce_to_mg(request, reset_ids): +def test_mgxs_library_ce_to_mg(): # Set the input set to use the pincell model model = pwr_pin_cell() harness = MGXSTestHarness('statepoint.10.h5', model) - harness.request = request harness.main() diff --git a/tests/regression_tests/mgxs_library_condense/test.py b/tests/regression_tests/mgxs_library_condense/test.py index b7ecf8925c..06b4704784 100644 --- a/tests/regression_tests/mgxs_library_condense/test.py +++ b/tests/regression_tests/mgxs_library_condense/test.py @@ -60,9 +60,8 @@ class MGXSTestHarness(PyAPITestHarness): return outstr -def test_mgxs_library_condense(request, reset_ids): +def test_mgxs_library_condense(): # Use the pincell model model = pwr_pin_cell() harness = MGXSTestHarness('statepoint.10.h5', model) - harness.request = request harness.main() diff --git a/tests/regression_tests/mgxs_library_distribcell/test.py b/tests/regression_tests/mgxs_library_distribcell/test.py index b9f343eafa..d7bc84bf57 100644 --- a/tests/regression_tests/mgxs_library_distribcell/test.py +++ b/tests/regression_tests/mgxs_library_distribcell/test.py @@ -64,8 +64,7 @@ class MGXSTestHarness(PyAPITestHarness): return outstr -def test_mgxs_library_distribcell(request, reset_ids): +def test_mgxs_library_distribcell(): model = pwr_assembly() harness = MGXSTestHarness('statepoint.10.h5', model) - harness.request = request harness.main() diff --git a/tests/regression_tests/mgxs_library_hdf5/test.py b/tests/regression_tests/mgxs_library_hdf5/test.py index 38dbeef1a5..8eed0258aa 100644 --- a/tests/regression_tests/mgxs_library_hdf5/test.py +++ b/tests/regression_tests/mgxs_library_hdf5/test.py @@ -73,12 +73,11 @@ class MGXSTestHarness(PyAPITestHarness): os.remove(f) -def test_mgxs_library_hdf5(request, reset_ids): +def test_mgxs_library_hdf5(): try: np.set_printoptions(formatter={'float_kind': '{:.8e}'.format}) model = pwr_pin_cell() harness = MGXSTestHarness('statepoint.10.h5', model) - harness.request = request harness.main() finally: np.set_printoptions(formatter=None) diff --git a/tests/regression_tests/mgxs_library_mesh/test.py b/tests/regression_tests/mgxs_library_mesh/test.py index 809782467d..70bd2113ce 100644 --- a/tests/regression_tests/mgxs_library_mesh/test.py +++ b/tests/regression_tests/mgxs_library_mesh/test.py @@ -65,7 +65,6 @@ class MGXSTestHarness(PyAPITestHarness): return outstr -def test_mgxs_library_mesh(request): +def test_mgxs_library_mesh(): harness = MGXSTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/mgxs_library_no_nuclides/test.py b/tests/regression_tests/mgxs_library_no_nuclides/test.py index 3e6e236480..c59b52189e 100644 --- a/tests/regression_tests/mgxs_library_no_nuclides/test.py +++ b/tests/regression_tests/mgxs_library_no_nuclides/test.py @@ -57,8 +57,7 @@ class MGXSTestHarness(PyAPITestHarness): return outstr -def test_mgxs_library_no_nuclides(request, reset_ids): +def test_mgxs_library_no_nuclides(): model = pwr_pin_cell() harness = MGXSTestHarness('statepoint.10.h5', model) - harness.request = request harness.main() diff --git a/tests/regression_tests/mgxs_library_nuclides/test.py b/tests/regression_tests/mgxs_library_nuclides/test.py index c670e18e30..a65fb9a6d3 100644 --- a/tests/regression_tests/mgxs_library_nuclides/test.py +++ b/tests/regression_tests/mgxs_library_nuclides/test.py @@ -53,8 +53,7 @@ class MGXSTestHarness(PyAPITestHarness): return outstr -def test_mgxs_library_nuclides(request, reset_ids): +def test_mgxs_library_nuclides(): model = pwr_pin_cell() harness = MGXSTestHarness('statepoint.10.h5', model) - harness.request = request harness.main() diff --git a/tests/regression_tests/multipole/test.py b/tests/regression_tests/multipole/test.py index d7ed3ca7c0..43aa9963aa 100644 --- a/tests/regression_tests/multipole/test.py +++ b/tests/regression_tests/multipole/test.py @@ -80,8 +80,7 @@ class MultipoleTestHarness(PyAPITestHarness): return outstr -def test_multipole(request, reset_ids): +def test_multipole(): model = make_model() harness = MultipoleTestHarness('statepoint.5.h5', model) - harness.request = request harness.main() diff --git a/tests/regression_tests/output/test.py b/tests/regression_tests/output/test.py index 30fcc3a80c..d9568ba4b0 100644 --- a/tests/regression_tests/output/test.py +++ b/tests/regression_tests/output/test.py @@ -23,7 +23,6 @@ class OutputTestHarness(TestHarness): os.remove(f) -def test_output(request): +def test_output(): harness = OutputTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/particle_restart_eigval/test.py b/tests/regression_tests/particle_restart_eigval/test.py index 6b9d103fdb..a30eb97870 100644 --- a/tests/regression_tests/particle_restart_eigval/test.py +++ b/tests/regression_tests/particle_restart_eigval/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import ParticleRestartTestHarness -def test_particle_restart_eigval(request): +def test_particle_restart_eigval(): harness = ParticleRestartTestHarness('particle_10_1030.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/particle_restart_fixed/test.py b/tests/regression_tests/particle_restart_fixed/test.py index 428d9586d9..463568ecca 100644 --- a/tests/regression_tests/particle_restart_fixed/test.py +++ b/tests/regression_tests/particle_restart_fixed/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import ParticleRestartTestHarness -def test_particle_restart_fixed(request): +def test_particle_restart_fixed(): harness = ParticleRestartTestHarness('particle_7_144.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/periodic/test.py b/tests/regression_tests/periodic/test.py index 188827a5dc..d746ebdd5f 100644 --- a/tests/regression_tests/periodic/test.py +++ b/tests/regression_tests/periodic/test.py @@ -51,7 +51,6 @@ class PeriodicTest(PyAPITestHarness): settings.export_to_xml() -def test_periodic(request): +def test_periodic(): harness = PeriodicTest('statepoint.4.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/plot/test.py b/tests/regression_tests/plot/test.py index 1e7773ea6a..64f2d4d31a 100644 --- a/tests/regression_tests/plot/test.py +++ b/tests/regression_tests/plot/test.py @@ -56,8 +56,7 @@ class PlotTestHarness(TestHarness): return outstr -def test_plot(request): +def test_plot(): harness = PlotTestHarness(('plot_1.ppm', 'plot_2.ppm', 'plot_3.ppm', 'plot_4.h5')) - harness.request = request harness.main() diff --git a/tests/regression_tests/ptables_off/test.py b/tests/regression_tests/ptables_off/test.py index 8d67cf400b..cc316f8c3e 100644 --- a/tests/regression_tests/ptables_off/test.py +++ b/tests/regression_tests/ptables_off/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_ptables_off(request): +def test_ptables_off(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/quadric_surfaces/test.py b/tests/regression_tests/quadric_surfaces/test.py index f919f1648c..862ee9bf41 100755 --- a/tests/regression_tests/quadric_surfaces/test.py +++ b/tests/regression_tests/quadric_surfaces/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_quadric_surfaces(request): +def test_quadric_surfaces(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/reflective_plane/test.py b/tests/regression_tests/reflective_plane/test.py index ba693c61aa..906174f338 100644 --- a/tests/regression_tests/reflective_plane/test.py +++ b/tests/regression_tests/reflective_plane/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_reflective_plane(request): +def test_reflective_plane(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/resonance_scattering/test.py b/tests/regression_tests/resonance_scattering/test.py index 98096a0cac..15e9d68944 100644 --- a/tests/regression_tests/resonance_scattering/test.py +++ b/tests/regression_tests/resonance_scattering/test.py @@ -42,7 +42,6 @@ class ResonanceScatteringTestHarness(PyAPITestHarness): settings.export_to_xml() -def test_resonance_scattering(request): +def test_resonance_scattering(): harness = ResonanceScatteringTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/rotation/test.py b/tests/regression_tests/rotation/test.py index b27e7faa4b..31c3d8d655 100644 --- a/tests/regression_tests/rotation/test.py +++ b/tests/regression_tests/rotation/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_rotation(request): +def test_rotation(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/salphabeta/test.py b/tests/regression_tests/salphabeta/test.py index 62ccbb2267..e69ada5ba3 100644 --- a/tests/regression_tests/salphabeta/test.py +++ b/tests/regression_tests/salphabeta/test.py @@ -73,8 +73,7 @@ def make_model(): return model -def test_salphabeta(request, reset_ids): +def test_salphabeta(): model = make_model() harness = PyAPITestHarness('statepoint.5.h5', model) - harness.request = request harness.main() diff --git a/tests/regression_tests/score_current/test.py b/tests/regression_tests/score_current/test.py index 1acc7c604f..21c5d08812 100644 --- a/tests/regression_tests/score_current/test.py +++ b/tests/regression_tests/score_current/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import HashedTestHarness -def test_score_current(request): +def test_score_current(): harness = HashedTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/seed/test.py b/tests/regression_tests/seed/test.py index 4c6bf95dc2..8b2f031b3e 100644 --- a/tests/regression_tests/seed/test.py +++ b/tests/regression_tests/seed/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_seed(request): +def test_seed(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/source/test.py b/tests/regression_tests/source/test.py index aa17143f0d..00171a2551 100644 --- a/tests/regression_tests/source/test.py +++ b/tests/regression_tests/source/test.py @@ -58,7 +58,6 @@ class SourceTestHarness(PyAPITestHarness): settings.export_to_xml() -def test_source(request): +def test_source(): harness = SourceTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/source_file/test.py b/tests/regression_tests/source_file/test.py index 1989de4c90..b4d9c4a31d 100644 --- a/tests/regression_tests/source_file/test.py +++ b/tests/regression_tests/source_file/test.py @@ -96,7 +96,6 @@ class SourceFileTestHarness(TestHarness): fh.write(settings1) -def test_source_file(request): +def test_source_file(): harness = SourceFileTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/sourcepoint_batch/test.py b/tests/regression_tests/sourcepoint_batch/test.py index 96326d15b8..3086b5610d 100644 --- a/tests/regression_tests/sourcepoint_batch/test.py +++ b/tests/regression_tests/sourcepoint_batch/test.py @@ -26,7 +26,6 @@ class SourcepointTestHarness(TestHarness): return outstr -def test_sourcepoint_batch(request): +def test_sourcepoint_batch(): harness = SourcepointTestHarness('statepoint.08.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/sourcepoint_latest/test.py b/tests/regression_tests/sourcepoint_latest/test.py index 15082e6d82..d14b566ad8 100644 --- a/tests/regression_tests/sourcepoint_latest/test.py +++ b/tests/regression_tests/sourcepoint_latest/test.py @@ -13,7 +13,6 @@ class SourcepointTestHarness(TestHarness): 'exist.' -def test_sourcepoint_latest(request): +def test_sourcepoint_latest(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/sourcepoint_restart/test.py b/tests/regression_tests/sourcepoint_restart/test.py index b0d2e9069a..32f53ec238 100644 --- a/tests/regression_tests/sourcepoint_restart/test.py +++ b/tests/regression_tests/sourcepoint_restart/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_sourcepoint_restart(request): +def test_sourcepoint_restart(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/statepoint_batch/test.py b/tests/regression_tests/statepoint_batch/test.py index aeb91e2a6e..6c5e4de318 100644 --- a/tests/regression_tests/statepoint_batch/test.py +++ b/tests/regression_tests/statepoint_batch/test.py @@ -13,7 +13,6 @@ class StatepointTestHarness(TestHarness): TestHarness._test_output_created(self) -def test_statepoint_batch(request): +def test_statepoint_batch(): harness = StatepointTestHarness() - harness.request = request harness.main() diff --git a/tests/regression_tests/statepoint_restart/test.py b/tests/regression_tests/statepoint_restart/test.py index 219a8a7ed8..2ee2e7be79 100644 --- a/tests/regression_tests/statepoint_restart/test.py +++ b/tests/regression_tests/statepoint_restart/test.py @@ -54,8 +54,7 @@ class StatepointRestartTestHarness(TestHarness): openmc.run(openmc_exec=self._opts.exe, restart_file=statepoint) -def test_statepoint_restart(request): +def test_statepoint_restart(): harness = StatepointRestartTestHarness('statepoint.10.h5', 'statepoint.07.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/statepoint_sourcesep/test.py b/tests/regression_tests/statepoint_sourcesep/test.py index 44a45d406f..3d63ca8ee5 100644 --- a/tests/regression_tests/statepoint_sourcesep/test.py +++ b/tests/regression_tests/statepoint_sourcesep/test.py @@ -20,7 +20,6 @@ class SourcepointTestHarness(TestHarness): os.remove(f) -def test_statepoint_sourcesep(request): +def test_statepoint_sourcesep(): harness = SourcepointTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/surface_tally/test.py b/tests/regression_tests/surface_tally/test.py index 2d499cb293..6995b7780c 100644 --- a/tests/regression_tests/surface_tally/test.py +++ b/tests/regression_tests/surface_tally/test.py @@ -174,7 +174,6 @@ class SurfaceTallyTestHarness(PyAPITestHarness): return outstr -def test_surface_tally(request): +def test_surface_tally(): harness = SurfaceTallyTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/survival_biasing/test.py b/tests/regression_tests/survival_biasing/test.py index 2dc7c86ab1..39e6faed8e 100644 --- a/tests/regression_tests/survival_biasing/test.py +++ b/tests/regression_tests/survival_biasing/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_survival_biasing(request): +def test_survival_biasing(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/tallies/test.py b/tests/regression_tests/tallies/test.py index 3f6f7de748..e3aebfd986 100644 --- a/tests/regression_tests/tallies/test.py +++ b/tests/regression_tests/tallies/test.py @@ -4,9 +4,8 @@ from openmc import Mesh, Tally, Tallies from tests.testing_harness import HashedPyAPITestHarness -def test_tallies(request, reset_ids): +def test_tallies(): harness = HashedPyAPITestHarness('statepoint.5.h5') - harness.request = request model = harness._model # Set settings explicitly diff --git a/tests/regression_tests/tally_aggregation/test.py b/tests/regression_tests/tally_aggregation/test.py index dfa0266902..f723160737 100644 --- a/tests/regression_tests/tally_aggregation/test.py +++ b/tests/regression_tests/tally_aggregation/test.py @@ -61,7 +61,6 @@ class TallyAggregationTestHarness(PyAPITestHarness): return outstr -def test_tally_aggregation(request): +def test_tally_aggregation(): harness = TallyAggregationTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/tally_arithmetic/test.py b/tests/regression_tests/tally_arithmetic/test.py index c87d0149f4..469ed00de1 100644 --- a/tests/regression_tests/tally_arithmetic/test.py +++ b/tests/regression_tests/tally_arithmetic/test.py @@ -75,7 +75,6 @@ class TallyArithmeticTestHarness(PyAPITestHarness): return outstr -def test_tally_arithmetic(request): +def test_tally_arithmetic(): harness = TallyArithmeticTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/tally_assumesep/test.py b/tests/regression_tests/tally_assumesep/test.py index c4248c10af..64595ced22 100644 --- a/tests/regression_tests/tally_assumesep/test.py +++ b/tests/regression_tests/tally_assumesep/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_tally_assumesep(request): +def test_tally_assumesep(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/tally_nuclides/test.py b/tests/regression_tests/tally_nuclides/test.py index 7eec5ef3f1..ee1f4b600e 100644 --- a/tests/regression_tests/tally_nuclides/test.py +++ b/tests/regression_tests/tally_nuclides/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_tally_nuclides(request): +def test_tally_nuclides(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/tally_slice_merge/test.py b/tests/regression_tests/tally_slice_merge/test.py index 4ee99d34a8..c198411f7d 100644 --- a/tests/regression_tests/tally_slice_merge/test.py +++ b/tests/regression_tests/tally_slice_merge/test.py @@ -166,7 +166,6 @@ class TallySliceMergeTestHarness(PyAPITestHarness): return outstr -def test_tally_slice_merge(request): +def test_tally_slice_merge(): harness = TallySliceMergeTestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/trace/test.py b/tests/regression_tests/trace/test.py index c037bb23bf..79dcaa1060 100644 --- a/tests/regression_tests/trace/test.py +++ b/tests/regression_tests/trace/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_trace(request): +def test_trace(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/track_output/test.py b/tests/regression_tests/track_output/test.py index f3d665e11e..22eac03bfc 100644 --- a/tests/regression_tests/track_output/test.py +++ b/tests/regression_tests/track_output/test.py @@ -38,10 +38,9 @@ class TrackTestHarness(TestHarness): os.remove(f) -def test_track_output(request): +def test_track_output(): # If vtk python module is not available, we can't run track.py so skip this # test. vtk = pytest.importorskip('vtk') harness = TrackTestHarness('statepoint.2.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/translation/test.py b/tests/regression_tests/translation/test.py index 29ef1c0114..876db736b9 100644 --- a/tests/regression_tests/translation/test.py +++ b/tests/regression_tests/translation/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_translation(request): +def test_translation(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/trigger_batch_interval/test.py b/tests/regression_tests/trigger_batch_interval/test.py index 1ac01a08bf..e161745022 100644 --- a/tests/regression_tests/trigger_batch_interval/test.py +++ b/tests/regression_tests/trigger_batch_interval/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_trigger_batch_interval(request): +def test_trigger_batch_interval(): harness = TestHarness('statepoint.15.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/trigger_no_batch_interval/test.py b/tests/regression_tests/trigger_no_batch_interval/test.py index d38304feea..4a40def5aa 100644 --- a/tests/regression_tests/trigger_no_batch_interval/test.py +++ b/tests/regression_tests/trigger_no_batch_interval/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_trigger_no_batch_interval(request): +def test_trigger_no_batch_interval(): harness = TestHarness('statepoint.15.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/trigger_no_status/test.py b/tests/regression_tests/trigger_no_status/test.py index 98173f8dda..75ae9a8cc9 100644 --- a/tests/regression_tests/trigger_no_status/test.py +++ b/tests/regression_tests/trigger_no_status/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_trigger_no_status(request): +def test_trigger_no_status(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/trigger_tallies/test.py b/tests/regression_tests/trigger_tallies/test.py index fde7298ffe..f8493c0c68 100644 --- a/tests/regression_tests/trigger_tallies/test.py +++ b/tests/regression_tests/trigger_tallies/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_trigger_tallies(request): +def test_trigger_tallies(): harness = TestHarness('statepoint.15.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/triso/test.py b/tests/regression_tests/triso/test.py index 2da26d1d38..174bba94fd 100644 --- a/tests/regression_tests/triso/test.py +++ b/tests/regression_tests/triso/test.py @@ -90,7 +90,6 @@ class TRISOTestHarness(PyAPITestHarness): mats.export_to_xml() -def test_triso(request): +def test_triso(): harness = TRISOTestHarness('statepoint.5.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/uniform_fs/test.py b/tests/regression_tests/uniform_fs/test.py index 553484e0ab..64d997909c 100644 --- a/tests/regression_tests/uniform_fs/test.py +++ b/tests/regression_tests/uniform_fs/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_uniform_fs(request): +def test_uniform_fs(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/universe/test.py b/tests/regression_tests/universe/test.py index 5da34d90c8..d5ed9645bd 100644 --- a/tests/regression_tests/universe/test.py +++ b/tests/regression_tests/universe/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_universe(request): +def test_universe(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/void/test.py b/tests/regression_tests/void/test.py index a08813c45b..af16f2ac80 100644 --- a/tests/regression_tests/void/test.py +++ b/tests/regression_tests/void/test.py @@ -1,7 +1,6 @@ from tests.testing_harness import TestHarness -def test_void(request): +def test_void(): harness = TestHarness('statepoint.10.h5') - harness.request = request harness.main() diff --git a/tests/regression_tests/volume_calc/test.py b/tests/regression_tests/volume_calc/test.py index da3a66c36f..a6b62b9be9 100644 --- a/tests/regression_tests/volume_calc/test.py +++ b/tests/regression_tests/volume_calc/test.py @@ -73,7 +73,6 @@ class VolumeTest(PyAPITestHarness): def _test_output_created(self): pass -def test_volume_calc(request): +def test_volume_calc(): harness = VolumeTest('') - harness.request = request harness.main() diff --git a/tests/testing_harness.py b/tests/testing_harness.py index 9aee4f741a..9901dcb718 100644 --- a/tests/testing_harness.py +++ b/tests/testing_harness.py @@ -32,14 +32,10 @@ class TestHarness(object): def main(self): """Accept commandline arguments and either run or update tests.""" (self._opts, self._args) = self.parser.parse_args() - try: - olddir = self.request.fspath.dirpath().chdir() - if self._opts.update: - self.update_results() - else: - self.execute_test() - finally: - olddir.chdir() + if self._opts.update: + self.update_results() + else: + self.execute_test() def execute_test(self): """Run OpenMC with the appropriate arguments and check the outputs.""" @@ -237,7 +233,6 @@ class PyAPITestHarness(TestHarness): super(PyAPITestHarness, self).__init__(statepoint_name) self.parser.add_option('-b', '--build-inputs', dest='build_only', action='store_true', default=False) - openmc.reset_auto_ids() if model is None: self._model = pwr_core() else: @@ -248,16 +243,12 @@ class PyAPITestHarness(TestHarness): def main(self): """Accept commandline arguments and either run or update tests.""" (self._opts, self._args) = self.parser.parse_args() - try: - olddir = self.request.fspath.dirpath().chdir() - if self._opts.build_only: - self._build_inputs() - elif self._opts.update: - self.update_results() - else: - self.execute_test() - finally: - olddir.chdir() + if self._opts.build_only: + self._build_inputs() + elif self._opts.update: + self.update_results() + else: + self.execute_test() def execute_test(self): """Build input XMLs, run OpenMC, and verify correct results.""" From 0d3845c32744b59dc1c99b3bb28111b6ad793a0f Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 29 Jan 2018 13:46:40 -0600 Subject: [PATCH 38/74] Fix command-line arguments for regression tests --- tests/conftest.py | 17 +++++++++ tests/regression_tests/__init__.py | 9 +++++ tests/regression_tests/mg_convert/test.py | 25 ++++++------- .../mgxs_library_ce_to_mg/test.py | 17 ++++----- tests/regression_tests/plot/test.py | 11 +++--- .../statepoint_restart/test.py | 9 ++--- tests/testing_harness.py | 35 +++++++------------ tests/unit_tests/test_capi.py | 1 + tools/ci/travis-script.sh | 14 ++++---- 9 files changed, 75 insertions(+), 63 deletions(-) create mode 100644 tests/conftest.py diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000000..422c036fb3 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,17 @@ +from tests.regression_tests import config as regression_config + + +def pytest_addoption(parser): + parser.addoption('--exe') + parser.addoption('--mpi', action='store_true') + parser.addoption('--mpiexec') + parser.addoption('--mpi-np') + parser.addoption('--update', action='store_true') + parser.addoption('--build-inputs', action='store_true') + + +def pytest_configure(config): + opts = ['exe', 'mpi', 'mpiexec', 'mpi_np', 'update', 'build_inputs'] + for opt in opts: + if config.getoption(opt) is not None: + regression_config[opt] = config.getoption(opt) diff --git a/tests/regression_tests/__init__.py b/tests/regression_tests/__init__.py index e69de29bb2..965a7f94db 100644 --- a/tests/regression_tests/__init__.py +++ b/tests/regression_tests/__init__.py @@ -0,0 +1,9 @@ +# Test configuration options for regression tests +config = { + 'exe': 'openmc', + 'mpi': False, + 'mpiexec': 'mpiexec', + 'mpi_np': '2', + 'update': False, + 'build_inputs': False +} diff --git a/tests/regression_tests/mg_convert/test.py b/tests/regression_tests/mg_convert/test.py index e6a8690c22..4bbbcbeb9a 100755 --- a/tests/regression_tests/mg_convert/test.py +++ b/tests/regression_tests/mg_convert/test.py @@ -5,6 +5,7 @@ import numpy as np import openmc from tests.testing_harness import PyAPITestHarness +from tests.regression_tests import config # OpenMC simulation parameters batches = 10 @@ -133,24 +134,18 @@ class MGXSTestHarness(PyAPITestHarness): for case in cases: build_mgxs_library(case) - if self._opts.mpi_exec is not None: - mpi_args = [self._opts.mpi_exec, '-n', self._opts.mpi_np] - openmc.run(openmc_exec=self._opts.exe, mpi_args=mpi_args) + if config['mpi']: + mpi_args = [config['mpiexec'], '-n', config['mpi_np']] + openmc.run(openmc_exec=config['exe'], mpi_args=mpi_args) else: - openmc.run(openmc_exec=self._opts.exe) + openmc.run(openmc_exec=config['exe']) - sp = openmc.StatePoint('statepoint.' + str(batches) + '.h5') - - # Write out k-combined. - outstr += 'k-combined:\n' - form = '{0:12.6E} {1:12.6E}\n' - outstr += form.format(sp.k_combined[0], sp.k_combined[1]) - - # Enforce closing statepoint and summary files so HDF5 - # does not throw an error during the next OpenMC execution - sp._f.close() - sp._summary._f.close() + with openmc.StatePoint('statepoint.{}.h5'.format(batches)) as sp: + # Write out k-combined. + outstr += 'k-combined:\n' + form = '{0:12.6E} {1:12.6E}\n' + outstr += form.format(sp.k_combined[0], sp.k_combined[1]) return outstr diff --git a/tests/regression_tests/mgxs_library_ce_to_mg/test.py b/tests/regression_tests/mgxs_library_ce_to_mg/test.py index 9dc640acd1..922b2c302c 100644 --- a/tests/regression_tests/mgxs_library_ce_to_mg/test.py +++ b/tests/regression_tests/mgxs_library_ce_to_mg/test.py @@ -5,6 +5,7 @@ import openmc.mgxs from openmc.examples import pwr_pin_cell from tests.testing_harness import PyAPITestHarness +from tests.regression_tests import config class MGXSTestHarness(PyAPITestHarness): @@ -31,11 +32,11 @@ class MGXSTestHarness(PyAPITestHarness): def _run_openmc(self): # Initial run - if self._opts.mpi_exec is not None: - mpi_args = [self._opts.mpi_exec, '-n', self._opts.mpi_np] - openmc.run(openmc_exec=self._opts.exe, mpi_args=mpi_args) + if config['mpi']: + mpi_args = [config['mpiexec'], '-n', config['mpi_np']] + openmc.run(openmc_exec=config['exe'], mpi_args=mpi_args) else: - openmc.run(openmc_exec=self._opts.exe) + openmc.run(openmc_exec=config['exe']) # Build MG Inputs # Get data needed to execute Library calculations. @@ -63,11 +64,11 @@ class MGXSTestHarness(PyAPITestHarness): sp._summary._f.close() # Re-run MG mode. - if self._opts.mpi_exec is not None: - mpi_args = [self._opts.mpi_exec, '-n', self._opts.mpi_np] - openmc.run(openmc_exec=self._opts.exe, mpi_args=mpi_args) + if config['mpi']: + mpi_args = [config['mpiexec'], '-n', config['mpi_np']] + openmc.run(openmc_exec=config['exe'], mpi_args=mpi_args) else: - openmc.run(openmc_exec=self._opts.exe) + openmc.run(openmc_exec=config['exe']) def _cleanup(self): super(MGXSTestHarness, self)._cleanup() diff --git a/tests/regression_tests/plot/test.py b/tests/regression_tests/plot/test.py index 64f2d4d31a..e7115c4dde 100644 --- a/tests/regression_tests/plot/test.py +++ b/tests/regression_tests/plot/test.py @@ -6,6 +6,7 @@ import h5py import openmc from tests.testing_harness import TestHarness +from tests.regression_tests import config class PlotTestHarness(TestHarness): @@ -15,20 +16,18 @@ class PlotTestHarness(TestHarness): self._plot_names = plot_names def _run_openmc(self): - openmc.plot_geometry(openmc_exec=self._opts.exe) + openmc.plot_geometry(openmc_exec=config['exe']) def _test_output_created(self): """Make sure *.ppm has been created.""" for fname in self._plot_names: - assert os.path.exists(os.path.join(os.getcwd(), fname)), \ - 'Plot output file does not exist.' + assert os.path.exists(fname), 'Plot output file does not exist.' def _cleanup(self): super(PlotTestHarness, self)._cleanup() for fname in self._plot_names: - path = os.path.join(os.getcwd(), fname) - if os.path.exists(path): - os.remove(path) + if os.path.exists(fname): + os.remove(fname) def _get_results(self): """Return a string hash of the plot files.""" diff --git a/tests/regression_tests/statepoint_restart/test.py b/tests/regression_tests/statepoint_restart/test.py index 2ee2e7be79..d36ff93950 100644 --- a/tests/regression_tests/statepoint_restart/test.py +++ b/tests/regression_tests/statepoint_restart/test.py @@ -4,6 +4,7 @@ import os import openmc from tests.testing_harness import TestHarness +from tests.regression_tests import config class StatepointRestartTestHarness(TestHarness): @@ -46,12 +47,12 @@ class StatepointRestartTestHarness(TestHarness): statepoint = statepoint[0] # Run OpenMC - if self._opts.mpi_exec is not None: - mpi_args = [self._opts.mpi_exec, '-n', self._opts.mpi_np] - openmc.run(restart_file=statepoint, openmc_exec=self._opts.exe, + if config['mpi']: + mpi_args = [config['mpiexec'], '-n', config['mpi_np']] + openmc.run(restart_file=statepoint, openmc_exec=config['exe'], mpi_args=mpi_args) else: - openmc.run(openmc_exec=self._opts.exe, restart_file=statepoint) + openmc.run(openmc_exec=config['exe'], restart_file=statepoint) def test_statepoint_restart(): diff --git a/tests/testing_harness.py b/tests/testing_harness.py index 9901dcb718..55a5660f1c 100644 --- a/tests/testing_harness.py +++ b/tests/testing_harness.py @@ -10,29 +10,21 @@ import shutil import sys import numpy as np - import openmc from openmc.examples import pwr_core +from tests.regression_tests import config + class TestHarness(object): """General class for running OpenMC regression tests.""" def __init__(self, statepoint_name): self._sp_name = statepoint_name - self.parser = OptionParser() - self.parser.add_option('--exe', dest='exe', default='openmc') - self.parser.add_option('--mpi_exec', dest='mpi_exec', default=None) - self.parser.add_option('--mpi_np', dest='mpi_np', default='2') - self.parser.add_option('--update', dest='update', action='store_true', - default=False) - self._opts = None - self._args = None def main(self): """Accept commandline arguments and either run or update tests.""" - (self._opts, self._args) = self.parser.parse_args() - if self._opts.update: + if config['update']: self.update_results() else: self.execute_test() @@ -60,11 +52,11 @@ class TestHarness(object): self._cleanup() def _run_openmc(self): - if self._opts.mpi_exec is not None: - openmc.run(openmc_exec=self._opts.exe, - mpi_args=[self._opts.mpi_exec, '-n', self._opts.mpi_np]) + if config['mpi']: + mpi_args = [config['mpiexec'], '-n', config['mpi_np']] + openmc.run(openmc_exec=config['exe'], mpi_args=mpi_args) else: - openmc.run(openmc_exec=self._opts.exe) + openmc.run(openmc_exec=config['exe']) def _test_output_created(self): """Make sure statepoint.* and tallies.out have been created.""" @@ -179,9 +171,9 @@ class ParticleRestartTestHarness(TestHarness): def _run_openmc(self): # Set arguments - args = {'openmc_exec': self._opts.exe} - if self._opts.mpi_exec is not None: - args['mpi_args'] = [self._opts.mpi_exec, '-n', self._opts.mpi_np] + args = {'openmc_exec': config['exe']} + if config['mpi']: + args['mpi_args'] = [config['mpiexec'], '-n', config['mpi_np']] # Initial run openmc.run(**args) @@ -231,8 +223,6 @@ class ParticleRestartTestHarness(TestHarness): class PyAPITestHarness(TestHarness): def __init__(self, statepoint_name, model=None): super(PyAPITestHarness, self).__init__(statepoint_name) - self.parser.add_option('-b', '--build-inputs', dest='build_only', - action='store_true', default=False) if model is None: self._model = pwr_core() else: @@ -242,10 +232,9 @@ class PyAPITestHarness(TestHarness): def main(self): """Accept commandline arguments and either run or update tests.""" - (self._opts, self._args) = self.parser.parse_args() - if self._opts.build_only: + if config['build_inputs']: self._build_inputs() - elif self._opts.update: + elif config['update']: self.update_results() else: self.execute_test() diff --git a/tests/unit_tests/test_capi.py b/tests/unit_tests/test_capi.py index ba9ac5c9e0..e1e87e27b3 100644 --- a/tests/unit_tests/test_capi.py +++ b/tests/unit_tests/test_capi.py @@ -12,6 +12,7 @@ import openmc.capi @pytest.fixture(scope='module') def pincell_model(): """Set up a model to test with and delete files when done""" + openmc.reset_auto_ids() pincell = openmc.examples.pwr_pin_cell() # Add a tally diff --git a/tools/ci/travis-script.sh b/tools/ci/travis-script.sh index 2934cb59a0..468cd0cc8a 100755 --- a/tools/ci/travis-script.sh +++ b/tools/ci/travis-script.sh @@ -1,15 +1,15 @@ #!/bin/bash set -ex -# Run regression test suite -cd build -ctest - # Run source check -cd ../tests +cd tests if [[ $TRAVIS_PYTHON_VERSION == "3.4" && $OMP == 'n' && $MPI == 'n' ]]; then ./check_source.py fi -# Run unit tests -pytest --cov=../openmc -v unit_tests/ +# Run regression and unit tests +if [[ $MPI == 'y' ]]; then + pytest --cov=../openmc -v --mpi +else + pytest --cov=../openmc -v +fi From ea15a931042f231500cb2b853825f35d619f162c Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 29 Jan 2018 14:05:48 -0600 Subject: [PATCH 39/74] Remove use of ctest / update_results.py --- CMakeLists.txt | 49 ----------------------------- tests/convert_precision.py | 23 -------------- tests/update_results.py | 60 ------------------------------------ tests/valgrind.supp | 63 -------------------------------------- 4 files changed, 195 deletions(-) delete mode 100755 tests/convert_precision.py delete mode 100755 tests/update_results.py delete mode 100644 tests/valgrind.supp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d0fcb0ab3..78db0ab453 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -522,52 +522,3 @@ if(PYTHONINTERP_FOUND) WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})") endif() endif() - -#=============================================================================== -# Regression tests -#=============================================================================== - -# This allows for dashboard configuration -include(CTest) - -# Get a list of all the tests to run -file(GLOB_RECURSE TESTS ${CMAKE_CURRENT_SOURCE_DIR}/tests/test.py) - -# Loop through all the tests -foreach(test ${TESTS}) - # Remove unit tests - if(test MATCHES ".*unit_tests.*") - continue() - endif() - - # Get test information - get_filename_component(TEST_NAME ${test} NAME) - get_filename_component(TEST_PATH ${test} PATH) - - if (DEFINED ENV{MEM_CHECK}) - # Generate input files if needed - if (NOT EXISTS "${TEST_PATH}/geometry.xml") - execute_process(COMMAND ${PYTHON_EXECUTABLE} ${TEST_NAME} --build-inputs - WORKING_DIRECTORY ${TEST_PATH}) - endif() - - # Add serial test - add_test(NAME ${TEST_PATH} - WORKING_DIRECTORY ${TEST_PATH} - COMMAND $) - else() - # Check serial/parallel - if (${MPI_ENABLED}) - # Preform a parallel test - add_test(NAME ${TEST_PATH} - WORKING_DIRECTORY ${TEST_PATH} - COMMAND ${PYTHON_EXECUTABLE} ${TEST_NAME} --exe $ - --mpi_exec ${MPI_DIR}/mpiexec) - else() - # Perform a serial test - add_test(NAME ${TEST_PATH} - WORKING_DIRECTORY ${TEST_PATH} - COMMAND ${PYTHON_EXECUTABLE} ${TEST_NAME} --exe $) - endif() - endif() -endforeach(test) diff --git a/tests/convert_precision.py b/tests/convert_precision.py deleted file mode 100755 index 625fe49ca9..0000000000 --- a/tests/convert_precision.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python - -import os -import glob - -dirs = glob.glob('test_*') - -for adir in dirs: - - os.chdir(adir) - - files = glob.glob('results.py') - - if len(files) > 0: - - files = files[0] - with open(files, 'r') as fh: - intxt = fh.read() - intxt = intxt.replace('14.8E', '12.6E') - with open(files, 'w') as fh: - fh.write(intxt) - - os.chdir('..') diff --git a/tests/update_results.py b/tests/update_results.py deleted file mode 100755 index 5656003331..0000000000 --- a/tests/update_results.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python - -from __future__ import print_function - -import os -import re -from subprocess import Popen, call, STDOUT, PIPE -from glob import glob -from optparse import OptionParser - -parser = OptionParser() -parser.add_option('-R', '--tests-regex', dest='regex_tests', - help="Run tests matching regular expression. \ - Test names are the directories present in tests folder.\ - This uses standard regex syntax to select tests.") -(opts, args) = parser.parse_args() -cwd = os.getcwd() - -# Terminal color configurations -OKGREEN = '\033[92m' -FAIL = '\033[91m' -ENDC = '\033[0m' -BOLD = '\033[1m' - -# Get a list of all test folders -folders = glob('test_*') - -# Check to see if a subset of tests is specified on command line -if opts.regex_tests is not None: - folders = [item for item in folders if re.search(opts.regex_tests, item)] - -# Loop around directories -for adir in sorted(folders): - - # Go into that directory - os.chdir(adir) - pwd = os.path.abspath(os.path.dirname('settings.xml')) - os.putenv('PWD', pwd) - - # Print status to screen - print(adir, end="") - sz = len(adir) - for i in range(35 - sz): - print('.', end="") - - # Find the test executable - test_exec = glob('test_*.py') - assert len(test_exec) == 1, 'There must be only one test executable per ' \ - 'test directory' - - # Update the test results - proc = Popen(['python', test_exec[0], '--update']) - returncode = proc.wait() - if returncode == 0: - print(BOLD + OKGREEN + "[OK]" + ENDC) - else: - print(BOLD + FAIL + "[FAILED]" + ENDC) - - # Go back a directory - os.chdir('..') diff --git a/tests/valgrind.supp b/tests/valgrind.supp deleted file mode 100644 index ad302c5397..0000000000 --- a/tests/valgrind.supp +++ /dev/null @@ -1,63 +0,0 @@ -{ - Create HDF5 statepoint file - Memcheck:Addr4 - fun:H5_build_extpath - fun:H5F_open - fun:H5Fcreate - fun:h5fcreate_c_ - fun:__h5f_MOD_h5fcreate_f - fun:__hdf5_interface_MOD_hdf5_file_create - fun:__output_interface_MOD_file_create - fun:__state_point_MOD_write_state_point - fun:__eigenvalue_MOD_finalize_batch - fun:__eigenvalue_MOD_run_eigenvalue - fun:MAIN__ - fun:main -} -{ - Open HDF5 statepoint file - Memcheck:Addr4 - fun:H5_build_extpath - fun:H5F_open - fun:H5Fopen - fun:h5fopen_c_ - fun:__h5f_MOD_h5fopen_f - fun:__hdf5_interface_MOD_hdf5_file_open - fun:__output_interface_MOD_file_open - fun:__state_point_MOD_write_source_point - fun:__eigenvalue_MOD_finalize_batch - fun:__eigenvalue_MOD_run_eigenvalue - fun:MAIN__ - fun:main -} -{ - Create HDF5 summary file - Memcheck:Addr4 - fun:H5_build_extpath - fun:H5F_open - fun:H5Fcreate - fun:h5fcreate_c_ - fun:__h5f_MOD_h5fcreate_f - fun:__hdf5_interface_MOD_hdf5_file_create - fun:__output_interface_MOD_file_create - fun:__hdf5_summary_MOD_hdf5_write_summary - fun:__initialize_MOD_initialize_run - fun:MAIN__ - fun:main -} -{ - Create HDF5 track file - Memcheck:Addr4 - fun:H5_build_extpath - fun:H5F_open - fun:H5Fcreate - fun:h5fcreate_c_ - fun:__h5f_MOD_h5fcreate_f - fun:__hdf5_interface_MOD_hdf5_file_create - fun:__output_interface_MOD_file_create - fun:__track_output_MOD_finalize_particle_track - fun:__tracking_MOD_transport - fun:__eigenvalue_MOD_run_eigenvalue - fun:MAIN__ - fun:main -} From dd2415d35065019d3b1be232dd2babe0b1eb44ce Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 29 Jan 2018 15:26:29 -0600 Subject: [PATCH 40/74] Make sure non-PHDF5 builds turn off prefer_parallel --- tools/ci/travis-install.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/ci/travis-install.py b/tools/ci/travis-install.py index 0e4dbdc01b..8fda09b093 100644 --- a/tools/ci/travis-install.py +++ b/tools/ci/travis-install.py @@ -42,13 +42,16 @@ def install(omp=False, mpi=False, phdf5=False): if not mpi: raise ValueError('Parallel HDF5 must be used in ' 'conjunction with MPI.') - cmake_cmd.append('-DHDF5_PREFER_PARALLEL=on') + cmake_cmd.append('-DHDF5_PREFER_PARALLEL=ON') + else: + cmake_cmd.append('-DHDF5_PREFER_PARALLEL=OFF') # Build and install cmake_cmd.append('..') + print(' '.join(cmake_cmd)) subprocess.call(cmake_cmd) subprocess.call(['make', '-j']) - subprocess.call(['make', 'install']) + subprocess.call(['sudo', 'make', 'install']) def main(): From fe353aff401e02a4c3880c49476271ab9cd7150d Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 29 Jan 2018 15:45:03 -0600 Subject: [PATCH 41/74] Update documentation relating to test suite --- docs/source/devguide/index.rst | 3 +- docs/source/devguide/tests.rst | 73 ++++++++++++++++ docs/source/devguide/workflow.rst | 133 ----------------------------- docs/source/usersguide/install.rst | 2 +- docs/source/usersguide/scripts.rst | 4 +- tests/readme.rst | 59 +------------ 6 files changed, 79 insertions(+), 195 deletions(-) create mode 100644 docs/source/devguide/tests.rst diff --git a/docs/source/devguide/index.rst b/docs/source/devguide/index.rst index 1a8252383c..e40e7f6359 100644 --- a/docs/source/devguide/index.rst +++ b/docs/source/devguide/index.rst @@ -10,9 +10,10 @@ as debugging. .. toctree:: :numbered: - :maxdepth: 3 + :maxdepth: 2 styleguide workflow + tests user-input docbuild diff --git a/docs/source/devguide/tests.rst b/docs/source/devguide/tests.rst new file mode 100644 index 0000000000..749737b5cb --- /dev/null +++ b/docs/source/devguide/tests.rst @@ -0,0 +1,73 @@ +.. _devguide_tests: + +========== +Test Suite +========== + +Running Tests +------------- + +The OpenMC test suite consists of two parts, a regression test suite and a unit +test suite. The regression test suite is based on regression or integrated +testing where different types of input files are configured and the full OpenMC +code is executed. Results from simulations are compared with expected +results. The unit tests are primarily intended to test individual +functions/classes in the OpenMC Python API. + +The test suite relies on the third-party `pytest `_ +package. To run either or both the regression and unit test suites, it is +assumed that you have OpenMC fully installed, i.e., the :ref:`scripts_openmc` +executable is available on your :envvar:`PATH` and the :mod:`openmc` Python +module is importable. In development where it would be onerous to continually +install OpenMC every time a small change is made, it is recommended to install +OpenMC in development/editable mode. With setuptools, this is accomplished by +running:: + + python setup.py develop + +or using pip (recommended):: + + pip install -e .[test] + +It is also assumed that you have cross section data available that is pointed to +by the :envvar:`OPENMC_CROSS_SECTIONS` and :envvar:`OPENMC_MULTIPOLE_LIBRARY` +environment variables. Furthermore, to run unit tests for the :mod:`openmc.data` +module, it is necessary to have ENDF/B-VII.1 data available and pointed to by +the :envvar:`OPENMC_ENDF_DATA` environment variable. All data sources can be +obtained using the ``tools/ci/travis-before-script.sh`` script. + +To execute the test suite, go to the ``tests/`` directory and run:: + + pytest + +If you want to collect information about source line coverage in the Python API, +you must have the `pytest-cov `_ plugin +installed and run:: + + pytest --cov=../openmc --cov-report=html + +Adding Tests to the Regression Suite +------------------------------------ + +To add a new test to the regression test suite, create a sub-directory in the +``tests/regression_tests/`` directory. To configure a test you need to add the +following files to your new test directory: + + * OpenMC input XML files, if they are not generated through the Python API + * **test.py** - Python test driver script; please refer to other tests to + see how to construct. Any output files that are generated during testing + must be removed at the end of this script. + * **inputs_true.dat** - ASCII file that contains Python API-generated XML + files concatenated together. When the test is run, inputs that are + generated are compared to this file. + * **results_true.dat** - ASCII file that contains the expected results from + the test. The file *results_test.dat* is compared to this file during the + execution of the python test driver script. When the above files have been + created, generate a *results_test.dat* file and copy it to this name and + commit. It should be noted that this file should be generated with basic + compiler options during openmc configuration and build (e.g., no MPI, no + debug/optimization). + +In addition to this description, please see the various types of tests that are +already included in the test suite to see how to create them. If all is +implemented correctly, the new test will automatically be discovered by pytest. diff --git a/docs/source/devguide/workflow.rst b/docs/source/devguide/workflow.rst index 942cee55be..fd1ae0455e 100644 --- a/docs/source/devguide/workflow.rst +++ b/docs/source/devguide/workflow.rst @@ -89,139 +89,6 @@ features and bug fixes. The general steps for contributing are as follows: 6. After the pull request has been thoroughly vetted, it is merged back into the *develop* branch of mit-crpg/openmc. -.. _test suite: - -OpenMC Test Suite ------------------ - -The purpose of this test suite is to ensure that OpenMC compiles using various -combinations of compiler flags and options, and that all user input options can -be used successfully without breaking the code. The test suite is comprised of -regression tests where different types of input files are configured and the -full OpenMC code is executed. Results from simulations are compared with -expected results. The test suite is comprised of many build configurations -(e.g. debug, mpi, hdf5) and the actual tests which reside in sub-directories -in the tests directory. We recommend to developers to test their branches -before submitting a formal pull request using gfortran and Intel compilers -if available. - -The test suite is designed to integrate with cmake using ctest_. It is -configured to run with cross sections from NNDC_ augmented with 0 K elastic -scattering data for select nuclides as well as multipole data. To download the -proper data, run the following commands: - -.. code-block:: sh - - wget -O nndc_hdf5.tar.xz $(cat /.travis.yml | grep anl.box | awk '{print $2}') - tar xJvf nndc_hdf5.tar.xz - export OPENMC_CROSS_SECTIONS=$(pwd)/nndc_hdf5/cross_sections.xml - - git clone --branch=master git://github.com/smharper/windowed_multipole_library.git wmp_lib - tar xzvf wmp_lib/multipole_lib.tar.gz - export OPENMC_MULTIPOLE_LIBRARY=$(pwd)/multipole_lib - -The test suite can be run on an already existing build using: - -.. code-block:: sh - - cd build - make test - -or - -.. code-block:: sh - - cd build - ctest - -There are numerous ctest_ command line options that can be set to have -more control over which tests are executed. - -Before running the test suite python script, the following environmental -variables should be set if the default paths are incorrect: - - * **FC** - The command for a Fortran compiler (e.g. gfotran, ifort). - - * Default - *gfortran* - - * **CC** - The command for a C compiler (e.g. gcc, icc). - - * Default - *gcc* - - * **CXX** - The command for a C++ compiler (e.g. g++, icpc). - - * Default - *g++* - - * **MPI_DIR** - The path to the MPI directory. - - * Default - */opt/mpich/3.2-gnu* - - * **HDF5_DIR** - The path to the HDF5 directory. - - * Default - */opt/hdf5/1.8.16-gnu* - - * **PHDF5_DIR** - The path to the parallel HDF5 directory. - - * Default - */opt/phdf5/1.8.16-gnu* - -To run the full test suite, the following command can be executed in the -tests directory: - -.. code-block:: sh - - python run_tests.py - -A subset of build configurations and/or tests can be run. To see how to use -the script run: - -.. code-block:: sh - - python run_tests.py --help - -As an example, say we want to run all tests with debug flags only on tests -that have cone and plot in their name. Also, we would like to run this on -4 processors. We can run: - -.. code-block:: sh - - python run_tests.py -j 4 -C debug -R "cone|plot" - -Note that standard regular expression syntax is used for selecting build -configurations and tests. To print out a list of build configurations, we -can run: - -.. code-block:: sh - - python run_tests.py -p - -Adding tests to test suite -++++++++++++++++++++++++++ - -To add a new test to the test suite, create a sub-directory in the tests -directory that conforms to the regular expression *test_*. To configure -a test you need to add the following files to your new test directory, -*test_name* for example: - - * OpenMC input XML files - * **test_name.py** - Python test driver script, please refer to other - tests to see how to construct. Any output files that are generated - during testing must be removed at the end of this script. - * **inputs_true.dat** - ASCII file that contains Python API-generated XML - files concatenated together. When the test is run, inputs that are - generated are compared to this file. - * **results_true.dat** - ASCII file that contains the expected results - from the test. The file *results_test.dat* is compared to this file - during the execution of the python test driver script. When the - above files have been created, generate a *results_test.dat* file and - copy it to this name and commit. It should be noted that this file - should be generated with basic compiler options during openmc - configuration and build (e.g., no MPI/HDF5, no debug/optimization). - -In addition to this description, please see the various types of tests that -are already included in the test suite to see how to create them. If all is -implemented correctly, the new test directory will automatically be added -to the CTest framework. - Private Development ------------------- diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index b595729236..6bb685f480 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -364,7 +364,7 @@ Testing Build To run the test suite, you will first need to download a pre-generated cross section library along with windowed multipole data. Please refer to our -:ref:`test suite` documentation for further details. +:ref:`devguide_tests` documentation for further details. -------------------- Python Prerequisites diff --git a/docs/source/usersguide/scripts.rst b/docs/source/usersguide/scripts.rst index 90ca6886d1..2f199fc256 100644 --- a/docs/source/usersguide/scripts.rst +++ b/docs/source/usersguide/scripts.rst @@ -168,8 +168,8 @@ ENDF/B-VII.1. It has the following optional arguments: This script downloads `ENDF/B-VII.1 ACE data `_ from NNDC and converts it to -an HDF5 library for use with OpenMC. This data is used for OpenMC's regression -test suite. This script has the following optional arguments: +an HDF5 library for use with OpenMC. This script has the following optional +arguments: -b, --batch Suppress standard in diff --git a/tests/readme.rst b/tests/readme.rst index f2e2bb1c12..5e4b0227be 100644 --- a/tests/readme.rst +++ b/tests/readme.rst @@ -1,58 +1 @@ -================= -OpenMC Test Suite -================= - -The purpose of this test suite is to ensure that OpenMC compiles using various -combinations of compiler flags and options and that all user input options can -be used successfully without breaking the code. The test suite is based on -regression or integrated testing where different types of input files are -configured and the full OpenMC code is executed. Results from simulations -are compared with expected results. The test suite is comprised of many -build configurations (e.g. debug, mpi, hdf5) and the actual tests which -reside in sub-directories in the tests directory. - -The test suite is designed to integrate with cmake using ctest_. To run the -full test suite run: - -.. code-block:: sh - - python run_tests.py - -The test suite is configured to run with cross sections from NNDC_. To -download these cross sections please do the following: - -.. code-block:: sh - - cd ../data - python get_nndc.py - export CROSS_SECTIONS=/nndc/cross_sections.xml - -The environmental variable **CROSS_SECTIONS** can be used to quickly switch -between the cross sections set for the test suite and cross section set for -your simulations. - -A subset of build configurations and/or tests can be run. To see how to use -the script run: - -.. code-block:: sh - - python run_tests.py --help - -As an example, say we want to run all tests with debug flags only on tests -that have cone and plot in their name. Also, we would like to run this on -4 processors. We can run: - -.. code-block:: sh - - python run_tests.py -j 4 -C debug -R "cone|plot" - -Note that standard regular expression syntax is used for selecting build -configurations and tests. To print out a list of build configurations, we -can run: - -.. code-block:: sh - - python run_tests.py -p - -.. _ctest: http://www.cmake.org/cmake/help/v2.8.12/ctest.html -.. _NNDC: http://http://www.nndc.bnl.gov/endf/b7.1/acefiles.html +See docs/source/devguide/tests.rst for information on the OpenMC test suite. From 60909945459dfc76faace3306d767dd9be56b857 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 29 Jan 2018 15:49:30 -0600 Subject: [PATCH 42/74] Make sure IPython<6 is used for Python 2.7 --- tools/ci/travis-install.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/ci/travis-install.sh b/tools/ci/travis-install.sh index 6051f03aa9..3ee54af76c 100755 --- a/tools/ci/travis-install.sh +++ b/tools/ci/travis-install.sh @@ -10,6 +10,11 @@ pip install numpy cython # pytest installed by default -- make sure we get latest pip install --upgrade pytest +# IPython stopped supporting Python 2.7 with version 6 +if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then + pip install "ipython<6" +fi + # Pandas stopped supporting Python 3.4 with version 0.21 if [[ "$TRAVIS_PYTHON_VERSION" == "3.4" ]]; then pip install pandas==0.20.3 From 18695c2878a0750814af0e4a7d9ace0da9bdebd8 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 29 Jan 2018 16:30:57 -0600 Subject: [PATCH 43/74] Don't install Python package from CMakeLists.txt --- CMakeLists.txt | 16 ---------------- tools/ci/travis-install.py | 6 +++--- tools/ci/travis-install.sh | 6 +++--- 3 files changed, 6 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78db0ab453..7ab012ef6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -506,19 +506,3 @@ install(TARGETS ${program} libopenmc install(DIRECTORY src/relaxng DESTINATION share/openmc) install(FILES man/man1/openmc.1 DESTINATION share/man/man1) install(FILES LICENSE DESTINATION "share/doc/${program}" RENAME copyright) - -find_package(PythonInterp) -if(PYTHONINTERP_FOUND) - if(debian) - install(CODE "execute_process( - COMMAND ${PYTHON_EXECUTABLE} setup.py install - --root=debian/openmc --install-layout=deb - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})") - else() - install(CODE "set(ENV{PYTHONPATH} \"${CMAKE_INSTALL_PREFIX}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages\")") - install(CODE "execute_process( - COMMAND ${PYTHON_EXECUTABLE} setup.py install - --prefix=${CMAKE_INSTALL_PREFIX} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})") - endif() -endif() diff --git a/tools/ci/travis-install.py b/tools/ci/travis-install.py index 8fda09b093..bd7f886dbc 100644 --- a/tools/ci/travis-install.py +++ b/tools/ci/travis-install.py @@ -49,9 +49,9 @@ def install(omp=False, mpi=False, phdf5=False): # Build and install cmake_cmd.append('..') print(' '.join(cmake_cmd)) - subprocess.call(cmake_cmd) - subprocess.call(['make', '-j']) - subprocess.call(['sudo', 'make', 'install']) + subprocess.check_call(cmake_cmd) + subprocess.check_call(['make', '-j']) + subprocess.check_call(['sudo', 'make', 'install']) def main(): diff --git a/tools/ci/travis-install.sh b/tools/ci/travis-install.sh index 3ee54af76c..3723315a4e 100755 --- a/tools/ci/travis-install.sh +++ b/tools/ci/travis-install.sh @@ -20,8 +20,8 @@ if [[ "$TRAVIS_PYTHON_VERSION" == "3.4" ]]; then pip install pandas==0.20.3 fi -# Build and install +# Build and install OpenMC executable python tools/ci/travis-install.py -# Install OpenMC in editable mode -pip install -e .[test] +# Install Python API +pip install .[test] From d75b715026ef881d5d8b62dc5f5abb41a8d10694 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 29 Jan 2018 17:41:10 -0600 Subject: [PATCH 44/74] Add source tests and fix one failing test --- tests/unit_tests/test_source.py | 30 ++++++++++++++++++++++++++++++ tests/unit_tests/test_stats.py | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/unit_tests/test_source.py diff --git a/tests/unit_tests/test_source.py b/tests/unit_tests/test_source.py new file mode 100644 index 0000000000..3c963d0527 --- /dev/null +++ b/tests/unit_tests/test_source.py @@ -0,0 +1,30 @@ +import openmc +import openmc.stats + + +def test_source(): + space = openmc.stats.Point() + energy = openmc.stats.Discrete([1.0e6], [1.0]) + angle = openmc.stats.Isotropic() + + src = openmc.Source(space=space, angle=angle, energy=energy) + assert src.space == space + assert src.angle == angle + assert src.energy == energy + assert src.strength == 1.0 + + elem = src.to_xml_element() + assert 'strength' in elem.attrib + assert elem.find('space') is not None + assert elem.find('angle') is not None + assert elem.find('energy') is not None + + +def test_source_file(): + filename = 'source.h5' + src = openmc.Source(filename=filename) + assert src.file == filename + + elem = src.to_xml_element() + assert 'strength' in elem.attrib + assert 'file' in elem.attrib diff --git a/tests/unit_tests/test_stats.py b/tests/unit_tests/test_stats.py index 3a91ecd8fd..388408bb22 100644 --- a/tests/unit_tests/test_stats.py +++ b/tests/unit_tests/test_stats.py @@ -23,7 +23,7 @@ def test_discrete(): def test_uniform(): - a, b = 10, 20 + a, b = 10.0, 20.0 d = openmc.stats.Uniform(a, b) assert d.a == a assert d.b == b From 54cd34f33e7b9c3e1876ab06e4011482439c4313 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 29 Jan 2018 18:02:03 -0600 Subject: [PATCH 45/74] Install Python package in editable mode once again --- tools/ci/travis-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ci/travis-install.sh b/tools/ci/travis-install.sh index 3723315a4e..cef34a2e0e 100755 --- a/tools/ci/travis-install.sh +++ b/tools/ci/travis-install.sh @@ -23,5 +23,5 @@ fi # Build and install OpenMC executable python tools/ci/travis-install.py -# Install Python API -pip install .[test] +# Install Python API in editable mode +pip install -e .[test] From 4ad4feecc688f311d1e4ae3555dff3f48c011690 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 29 Jan 2018 22:31:44 -0600 Subject: [PATCH 46/74] Update minimum CMake version to 3.0 --- CMakeLists.txt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ab012ef6d..fc8b252954 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) +cmake_minimum_required(VERSION 3.0 FATAL_ERROR) project(openmc Fortran C CXX) # Setup output directories @@ -21,11 +21,6 @@ if (${UNIX}) add_definitions(-DUNIX) endif() -# Set MACOSX_RPATH -if(POLICY CMP0042) - cmake_policy(SET CMP0042 NEW) -endif() - #=============================================================================== # Command line options #=============================================================================== From f6fc24c808215694b7880a1c4f69c6e59861b5ca Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 29 Jan 2018 23:23:48 -0600 Subject: [PATCH 47/74] Add unit tests for plots --- tests/unit_tests/conftest.py | 10 ++++ tests/unit_tests/test_material.py | 9 ---- tests/unit_tests/test_plots.py | 90 +++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 9 deletions(-) create mode 100644 tests/unit_tests/conftest.py create mode 100644 tests/unit_tests/test_plots.py diff --git a/tests/unit_tests/conftest.py b/tests/unit_tests/conftest.py new file mode 100644 index 0000000000..aad0ac0581 --- /dev/null +++ b/tests/unit_tests/conftest.py @@ -0,0 +1,10 @@ +import pytest + + +@pytest.fixture +def run_in_tmpdir(tmpdir): + orig = tmpdir.chdir() + try: + yield + finally: + orig.chdir() diff --git a/tests/unit_tests/test_material.py b/tests/unit_tests/test_material.py index 84627ba8c4..b96cbfb4c0 100644 --- a/tests/unit_tests/test_material.py +++ b/tests/unit_tests/test_material.py @@ -40,15 +40,6 @@ def sphere_model(): return model -@pytest.fixture -def run_in_tmpdir(tmpdir): - orig = tmpdir.chdir() - try: - yield - finally: - orig.chdir() - - def test_attributes(uo2): assert uo2.name == 'UO2' assert uo2.id == 100 diff --git a/tests/unit_tests/test_plots.py b/tests/unit_tests/test_plots.py new file mode 100644 index 0000000000..d48b609c1e --- /dev/null +++ b/tests/unit_tests/test_plots.py @@ -0,0 +1,90 @@ +import openmc +import openmc.examples +import pytest + + +@pytest.fixture(scope='module') +def myplot(): + plot = openmc.Plot(name='myplot') + plot.width = (100., 100.) + plot.origin = (2., 3., -10.) + plot.pixels = (500, 500) + plot.filename = 'myplot' + plot.type = 'slice' + plot.basis = 'yz' + plot.background = (0, 0, 0) + plot.background = 'black' + + plot.color_by = 'material' + m1, m2 = openmc.Material(), openmc.Material() + plot.colors = {m1: (0, 255, 0), m2: (0, 0, 255)} + plot.colors = {m1: 'green', m2: 'blue'} + + plot.mask_components = [openmc.Material()] + plot.mask_background = (255, 255, 255) + plot.mask_background = 'white' + + plot.level = 1 + plot.meshlines = { + 'type': 'tally', + 'id': 1, + 'linewidth': 2, + 'color': (40, 30, 20) + } + return plot + + +def test_attributes(myplot): + assert myplot.name == 'myplot' + + +def test_repr(myplot): + r = repr(myplot) + assert isinstance(r, str) + + +def test_from_geometry(): + width = 25. + s = openmc.Sphere(R=width/2, boundary_type='vacuum') + c = openmc.Cell(region=-s) + univ = openmc.Universe(cells=[c]) + geom = openmc.Geometry(univ) + + for basis in ('xy', 'yz', 'xz'): + plot = openmc.Plot.from_geometry(geom, basis) + assert plot.origin == pytest.approx((0., 0., 0.)) + assert plot.width == pytest.approx((width, width)) + + +def test_highlight_domains(): + plot = openmc.Plot() + plot.color_by = 'material' + plots = openmc.Plots([plot]) + + model = openmc.examples.pwr_pin_cell() + mats = {m for m in model.materials if 'UO2' in m.name} + plots.highlight_domains(model.geometry, mats) + + +def test_to_xml_element(myplot): + elem = myplot.to_xml_element() + assert 'id' in elem.attrib + assert 'color_by' in elem.attrib + assert 'type' in elem.attrib + assert elem.find('origin') is not None + assert elem.find('width') is not None + assert elem.find('pixels') is not None + assert elem.find('background').text == '0 0 0' + + +def test_plots(run_in_tmpdir): + p1 = openmc.Plot(name='plot1') + p2 = openmc.Plot(name='plot2') + plots = openmc.Plots([p1, p2]) + assert len(plots) == 2 + + p3 = openmc.Plot(name='plot3') + plots.append(p3) + assert len(plots) == 3 + + plots.export_to_xml() From ebd4f72b4075f17ed7f33f2b18e4f6a8318346df Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 31 Jan 2018 13:13:15 -0600 Subject: [PATCH 48/74] Update installation instructions for Python API --- docs/source/devguide/workflow.rst | 22 ++++++++ docs/source/quickinstall.rst | 24 +++++---- docs/source/usersguide/install.rst | 85 ++++++++++++++++++++++-------- 3 files changed, 101 insertions(+), 30 deletions(-) diff --git a/docs/source/devguide/workflow.rst b/docs/source/devguide/workflow.rst index fd1ae0455e..9b27fd655f 100644 --- a/docs/source/devguide/workflow.rst +++ b/docs/source/devguide/workflow.rst @@ -103,6 +103,27 @@ changes you've made in your private repository back to mit-crpg/openmc repository, simply follow the steps above with an extra step of pulling a branch from your private repository into a public fork. +.. _devguide_editable: + +Working in "Development" Mode +----------------------------- + +If you are making changes to the Python API during development, it is highly +suggested to install the Python API in development/editable mode using +pip_. From the root directory of the OpenMC repository, run: + +.. code-block:: sh + + pip install -e .[test] + +This installs the OpenMC Python package in `"editable" mode +`_ so +that 1) it can be imported from a Python interpreter and 2) any changes made are +immediately reflected in the installed version (that is, you don't need to keep +reinstalling it). While the same effect can be achieved using the +:envvar:`PYTHONPATH` environment variable, this is generally discouraged as it +can interfere with virtual environments. + .. _git: http://git-scm.com/ .. _GitHub: https://github.com/ .. _git flow: http://nvie.com/git-model @@ -114,3 +135,4 @@ from your private repository into a public fork. .. _Bitbucket: https://bitbucket.org .. _ctest: http://www.cmake.org/cmake/help/v2.8.12/ctest.html .. _NNDC: http://www.nndc.bnl.gov/endf/b7.1/acefiles.html +.. _pip: https://pip.pypa.io/en/stable/ diff --git a/docs/source/quickinstall.rst b/docs/source/quickinstall.rst index 97980037c5..7176b67be0 100644 --- a/docs/source/quickinstall.rst +++ b/docs/source/quickinstall.rst @@ -57,7 +57,6 @@ are no longer supported. .. _Personal Package Archive: https://launchpad.net/~paulromano/+archive/staging .. _APT package manager: https://help.ubuntu.com/community/AptGet/Howto -.. _HDF5: http://www.hdfgroup.org/HDF5/ --------------------------------------- Installing from Source on Ubuntu 15.04+ @@ -83,9 +82,12 @@ building and installing OpenMC from source. Installing from Source on Linux or Mac OS X ------------------------------------------- -All OpenMC source code is hosted on GitHub_. If you have git_, the gfortran_ -compiler, CMake_, and HDF5_ installed, you can download and install OpenMC be -entering the following commands in a terminal: +All OpenMC source code is hosted on `GitHub +`_. If you have `git +`_, the `gcc `_ compiler suite, +`CMake `_, and `HDF5 `_ +installed, you can download and install OpenMC be entering the following +commands in a terminal: .. code-block:: sh @@ -104,11 +106,15 @@ should specify an installation directory where you have write access, e.g. cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local .. +The :mod:`openmc` Python package must be installed separately. The easiest way +to install it is using `pip `_, which is +included by default in Python 2.7 and Python 3.4+. From the root directory of +the OpenMC distribution/repository, run: + +.. code-block:: sh + + pip install . + If you want to build a parallel version of OpenMC (using OpenMP or MPI), directions can be found in the :ref:`detailed installation instructions `. - -.. _GitHub: https://github.com/mit-crpg/openmc -.. _git: http://git-scm.com -.. _gfortran: http://gcc.gnu.org/wiki/GFortran -.. _CMake: http://www.cmake.org diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index 6bb685f480..48188928cf 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -6,17 +6,18 @@ Installation and Configuration .. currentmodule:: openmc +.. _install_conda: + ---------------------------------------- Installing on Linux/Mac with conda-forge ---------------------------------------- -`Conda `_ is an open source package management -system and environment management system for installing multiple versions of -software packages and their dependencies and switching easily between -them. `conda-forge `_ is a community-led conda -channel of installable packages. For instructions on installing conda, please -consult their `documentation -`_. +Conda_ is an open source package management system and environment management +system for installing multiple versions of software packages and their +dependencies and switching easily between them. `conda-forge +`_ is a community-led conda channel of +installable packages. For instructions on installing conda, please consult their +`documentation `_. Once you have `conda` installed on your system, add the `conda-forge` channel to your configuration with: @@ -38,6 +39,8 @@ It is possible to list all of the versions of OpenMC available on your platform conda search openmc --channel conda-forge +.. _install_ppa: + ----------------------------- Installing on Ubuntu with PPA ----------------------------- @@ -68,9 +71,11 @@ are no longer supported. .. _Personal Package Archive: https://launchpad.net/~paulromano/+archive/staging .. _APT package manager: https://help.ubuntu.com/community/AptGet/Howto --------------------- -Building from Source --------------------- +.. _install_source: + +---------------------- +Installing from Source +---------------------- .. _prerequisites: @@ -191,8 +196,8 @@ switch to the source of the latest stable release, run the following commands:: git checkout master .. _GitHub: https://github.com/mit-crpg/openmc -.. _git: http://git-scm.com -.. _ssh: http://en.wikipedia.org/wiki/Secure_Shell +.. _git: https://git-scm.com +.. _ssh: https://en.wikipedia.org/wiki/Secure_Shell .. _usersguide_build: @@ -366,16 +371,52 @@ To run the test suite, you will first need to download a pre-generated cross section library along with windowed multipole data. Please refer to our :ref:`devguide_tests` documentation for further details. --------------------- -Python Prerequisites --------------------- +--------------------- +Installing Python API +--------------------- -OpenMC's :ref:`Python API ` works with either Python 2.7 or Python -3.2+. In addition to Python itself, the API relies on a number of third-party -packages. All prerequisites can be installed using `conda -`_ (recommended), `pip -`_, or through the package manager in most Linux -distributions. +If you installed OpenMC using :ref:`Conda ` or :ref:`PPA +`, no further steps are necessary in order to use OpenMC's +:ref:`Python API `. However, if you are :ref:`installing from source +`, the Python API is not installed by default when ``make +install`` is run because in many situations it doesn't make sense to install a +Python package in the same location as the ``openmc`` executable (for example, +if you are installing the package into a `virtual environment +`_). The easiest way to install +the :mod:`openmc` Python package is to use pip_, which is included by default in +Python 2.7 and Python 3.4+. From the root directory of the OpenMC +distribution/repository, run: + +.. code-block:: sh + + pip install . + +pip will first check that all :ref:`required third-party packages +` have been installed, and if they are not present, +they will be installed by downloading the appropriate packages from the Python +Package Index (`PyPI `_). However, do note that since pip +runs the ``setup.py`` script which requires NumPy, you will have to first +install NumPy: + +.. code-block:: sh + + pip install numpy + +Installing in "Development" Mode +-------------------------------- + +If you are primarily doing development with OpenMC, it is strongly recommended +to install the Python package in :ref:`"editable" mode `. + +.. _usersguide_python_prereqs: + +Prerequisites +------------- + +The Python API works with either Python 2.7 or Python 3.2+. In addition to +Python itself, the API relies on a number of third-party packages. All +prerequisites can be installed using Conda_ (recommended), pip_, or through the +package manager in most Linux distributions. .. admonition:: Required :class: error @@ -457,3 +498,5 @@ schemas.xml file in your own OpenMC source directory. .. _RELAX NG: http://relaxng.org/ .. _NNDC: http://www.nndc.bnl.gov/endf/b7.1/acefiles.html .. _ctest: http://www.cmake.org/cmake/help/v2.8.12/ctest.html +.. _Conda: https://conda.io/docs/ +.. _pip: https://pip.pypa.io/en/stable/ From bf8c556b5afea43be0973ec1af6514e1d4b24d87 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 31 Jan 2018 16:17:42 -0600 Subject: [PATCH 49/74] Unit tests for openmc.Cell --- openmc/cell.py | 9 +- tests/unit_tests/__init__.py | 9 ++ tests/unit_tests/conftest.py | 31 +++++ tests/unit_tests/test_cell.py | 204 ++++++++++++++++++++++++++++++ tests/unit_tests/test_material.py | 40 +----- tests/unit_tests/test_region.py | 8 +- 6 files changed, 252 insertions(+), 49 deletions(-) create mode 100644 tests/unit_tests/test_cell.py diff --git a/openmc/cell.py b/openmc/cell.py index 5975d7f70b..074fadc06d 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -211,14 +211,7 @@ class Cell(IDManagerMixin): @fill.setter def fill(self, fill): if fill is not None: - if isinstance(fill, string_types): - if fill.strip().lower() != 'void': - msg = 'Unable to set Cell ID="{0}" to use a non-Material ' \ - 'or Universe fill "{1}"'.format(self._id, fill) - raise ValueError(msg) - fill = None - - elif isinstance(fill, Iterable): + if isinstance(fill, Iterable): for i, f in enumerate(fill): if f is not None: cv.check_type('cell.fill[i]', f, openmc.Material) diff --git a/tests/unit_tests/__init__.py b/tests/unit_tests/__init__.py index e69de29bb2..59a520c12a 100644 --- a/tests/unit_tests/__init__.py +++ b/tests/unit_tests/__init__.py @@ -0,0 +1,9 @@ +import numpy as np +import pytest + + +def assert_unbounded(obj): + """Assert that a region/cell is unbounded.""" + ll, ur = obj.bounding_box + assert ll == pytest.approx((-np.inf, -np.inf, -np.inf)) + assert ur == pytest.approx((np.inf, np.inf, np.inf)) diff --git a/tests/unit_tests/conftest.py b/tests/unit_tests/conftest.py index aad0ac0581..334bb5fb95 100644 --- a/tests/unit_tests/conftest.py +++ b/tests/unit_tests/conftest.py @@ -1,3 +1,4 @@ +import openmc import pytest @@ -8,3 +9,33 @@ def run_in_tmpdir(tmpdir): yield finally: orig.chdir() + + +@pytest.fixture(scope='module') +def uo2(): + m = openmc.Material(material_id=100, name='UO2') + m.add_nuclide('U235', 1.0) + m.add_nuclide('O16', 2.0) + m.set_density('g/cm3', 10.0) + m.depletable = True + return m + + +@pytest.fixture(scope='module') +def sphere_model(): + model = openmc.model.Model() + + m = openmc.Material() + m.add_nuclide('U235', 1.0) + m.set_density('g/cm3', 1.0) + model.materials.append(m) + + sph = openmc.Sphere(boundary_type='vacuum') + c = openmc.Cell(fill=m, region=-sph) + model.geometry.root_universe = openmc.Universe(cells=[c]) + + model.settings.particles = 100 + model.settings.batches = 10 + model.settings.run_mode = 'fixed source' + model.settings.source = openmc.Source(space=openmc.stats.Point()) + return model diff --git a/tests/unit_tests/test_cell.py b/tests/unit_tests/test_cell.py new file mode 100644 index 0000000000..6e6483a28e --- /dev/null +++ b/tests/unit_tests/test_cell.py @@ -0,0 +1,204 @@ +import xml.etree. ElementTree as ET + +import numpy as np +import openmc +import pytest + +from tests.unit_tests import assert_unbounded + + +@pytest.fixture +def cell_with_lattice(): + m_inside = [openmc.Material(), openmc.Material(), None, openmc.Material()] + m_outside = openmc.Material() + + cyl = openmc.ZCylinder(R=1.0) + inside_cyl = openmc.Cell(fill=m_inside, region=-cyl) + outside_cyl = openmc.Cell(fill=m_outside, region=+cyl) + univ = openmc.Universe(cells=[inside_cyl, outside_cyl]) + + lattice = openmc.RectLattice() + lattice.lower_left = (-4.0, -4.0) + lattice.pitch = (4.0, 4.0) + lattice.dimension = (2, 2) + lattice.universes = [[univ, univ], [univ, univ]] + main_cell = openmc.Cell(fill=lattice) + + return ([inside_cyl, outside_cyl, main_cell], + [m_inside[0], m_inside[1], m_inside[3], m_outside], + univ, lattice) + + +def test_contains(): + # Cell with specified region + s = openmc.XPlane() + c = openmc.Cell(region=+s) + assert (1.0, 0.0, 0.0) in c + assert (-1.0, 0.0, 0.0) not in c + + # Cell with no region + c = openmc.Cell() + assert (10.0, -4., 2.0) in c + + +def test_repr(cell_with_lattice): + cells, mats, univ, lattice = cell_with_lattice + repr(cells[0]) # cell with distributed materials + repr(cells[1]) # cell with material + repr(cells[2]) # cell with lattice + + # Empty cell + c = openmc.Cell() + repr(c) + + +def test_bounding_box(): + zcyl = openmc.ZCylinder() + c = openmc.Cell(region=-zcyl) + ll, ur = c.bounding_box + assert ll == pytest.approx((-1., -1., -np.inf)) + assert ur == pytest.approx((1., 1., np.inf)) + + # Cell with no region specified + c = openmc.Cell() + assert_unbounded(c) + + +def test_clone(): + m = openmc.Material() + cyl = openmc.ZCylinder() + c = openmc.Cell(fill=m, region=-cyl) + c.temperature = 650. + + c2 = c.clone() + assert c2.id != c.id + assert c2.fill != c.fill + assert c2.region != c.region + assert c2.temperature == c.temperature + + +def test_temperature(cell_with_lattice): + # Make sure temperature propagates through universes + m = openmc.Material() + s = openmc.XPlane() + c1 = openmc.Cell(fill=m, region=+s) + c2 = openmc.Cell(fill=m, region=-s) + u1 = openmc.Universe(cells=[c1, c2]) + c = openmc.Cell(fill=u1) + + c.temperature = 400.0 + assert c1.temperature == 400.0 + assert c2.temperature == 400.0 + with pytest.raises(ValueError): + c.temperature = -100. + + # distributed temperature + cells, _, _, _ = cell_with_lattice + c = cells[0] + c.temperature = (300., 600., 900.) + + +def test_rotation(): + u = openmc.Universe() + c = openmc.Cell(fill=u) + c.rotation = (180.0, 0.0, 0.0) + assert np.allclose(c.rotation_matrix, [ + [1., 0., 0.], + [0., -1., 0.], + [0., 0., -1.] + ]) + + c.rotation = (0.0, 90.0, 0.0) + assert np.allclose(c.rotation_matrix, [ + [0., 0., -1.], + [0., 1., 0.], + [1., 0., 0.] + ]) + + +def test_volume(run_in_tmpdir, sphere_model): + """Test adding volume information from a volume calculation.""" + ll, ur = sphere_model.geometry.bounding_box + cells = list(sphere_model.geometry.root_universe.cells.values()) + sphere_model.settings.volume_calculations = [ + openmc.VolumeCalculation(domains=cells, samples=1000, + lower_left=ll, upper_right=ur) + ] + sphere_model.export_to_xml() + openmc.calculate_volumes() + volume_calc = openmc.VolumeCalculation.from_hdf5('volume_1.h5') + cells[0].add_volume_information(volume_calc) + + +def test_get_nuclides(uo2): + c = openmc.Cell(fill=uo2) + nucs = c.get_nuclides() + assert nucs == ['U235', 'O16'] + + +def test_nuclide_densities(uo2): + c = openmc.Cell(fill=uo2) + expected_nucs = ['U235', 'O16'] + expected_density = [1.0, 2.0] + tuples = list(c.get_nuclide_densities().values()) + for nuc, density, t in zip(expected_nucs, expected_density, tuples): + assert nuc == t[0] + assert density == t[1] + + # Empty cell + c = openmc.Cell() + assert not c.get_nuclide_densities() + + +def test_get_all_universes(cell_with_lattice): + # Cell with nested universes + c1 = openmc.Cell() + u1 = openmc.Universe(cells=[c1]) + c2 = openmc.Cell(fill=u1) + u2 = openmc.Universe(cells=[c2]) + c3 = openmc.Cell(fill=u2) + univs = set(c3.get_all_universes().values()) + assert not (univs ^ {u1, u2}) + + # Cell with lattice + cells, mats, univ, lattice = cell_with_lattice + univs = set(cells[-1].get_all_universes().values()) + assert not (univs ^ {univ}) + + +def test_get_all_materials(cell_with_lattice): + # Normal cell + m = openmc.Material() + c = openmc.Cell(fill=m) + test_mats = set(c.get_all_materials().values()) + assert not(test_mats ^ {m}) + + # Cell filled with distributed materials + cells, mats, univ, lattice = cell_with_lattice + c = cells[0] + test_mats = set(c.get_all_materials().values()) + assert not (test_mats ^ set(m for m in c.fill if m is not None)) + + # Cell filled with universe + c = cells[-1] + test_mats = set(c.get_all_materials().values()) + assert not (test_mats ^ set(mats)) + + +def test_to_xml_element(cell_with_lattice): + cells, mats, univ, lattice = cell_with_lattice + + c = cells[-1] + root = ET.Element('geometry') + elem = c.create_xml_subelement(root) + assert elem.tag == 'cell' + assert elem.get('id') == str(c.id) + assert elem.get('region') is None + surf_elem = root.find('surface') + assert surf_elem.get('id') == str(cells[0].region.surface.id) + + c = cells[0] + c.temperature = 900.0 + elem = c.create_xml_subelement(root) + assert elem.get('region') == str(c.region) + assert elem.get('temperature') == str(c.temperature) diff --git a/tests/unit_tests/test_material.py b/tests/unit_tests/test_material.py index b96cbfb4c0..ed2f7698a2 100644 --- a/tests/unit_tests/test_material.py +++ b/tests/unit_tests/test_material.py @@ -5,41 +5,6 @@ import openmc.examples import pytest -@pytest.fixture(scope='module') -def uo2(): - m = openmc.Material(material_id=100, name='UO2') - m.add_nuclide('U235', 1.0) - m.add_nuclide('O16', 2.0) - m.set_density('g/cm3', 10.0) - m.depletable = True - return m - - -@pytest.fixture(scope='module') -def sphere_model(): - model = openmc.model.Model() - - m = openmc.Material() - m.add_nuclide('U235', 1.0) - m.set_density('g/cm3', 1.0) - model.materials.append(m) - - sph = openmc.Sphere(boundary_type='vacuum') - c = openmc.Cell(fill=m, region=-sph) - model.geometry.root_universe = openmc.Universe(cells=[c]) - - model.settings.particles = 100 - model.settings.batches = 10 - model.settings.run_mode = 'fixed source' - model.settings.source = openmc.Source(space=openmc.stats.Point()) - ll, ur = c.region.bounding_box - model.settings.volume_calculations = [ - openmc.VolumeCalculation(domains=[m], samples=1000, - lower_left=ll, upper_right=ur) - ] - return model - - def test_attributes(uo2): assert uo2.name == 'UO2' assert uo2.id == 100 @@ -143,6 +108,11 @@ def test_isotropic(): def test_volume(run_in_tmpdir, sphere_model): """Test adding volume information from a volume calculation.""" + ll, ur = sphere_model.geometry.bounding_box + sphere_model.settings.volume_calculations = [ + openmc.VolumeCalculation(domains=sphere_model.materials, samples=1000, + lower_left=ll, upper_right=ur) + ] sphere_model.export_to_xml() openmc.calculate_volumes() volume_calc = openmc.VolumeCalculation.from_hdf5('volume_1.h5') diff --git a/tests/unit_tests/test_region.py b/tests/unit_tests/test_region.py index 346ec7d95e..c4f4065bf3 100644 --- a/tests/unit_tests/test_region.py +++ b/tests/unit_tests/test_region.py @@ -2,18 +2,14 @@ import numpy as np import pytest import openmc +from tests.unit_tests import assert_unbounded + @pytest.fixture def reset(): openmc.reset_auto_ids() -def assert_unbounded(region): - ll, ur = region.bounding_box - assert ll == pytest.approx((-np.inf, -np.inf, -np.inf)) - assert ur == pytest.approx((np.inf, np.inf, np.inf)) - - def test_union(reset): s1 = openmc.XPlane(surface_id=1, x0=5) s2 = openmc.XPlane(surface_id=2, x0=-5) From b573ad50cf26450a7070d606127e74db7d84ba11 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 31 Jan 2018 21:50:29 -0600 Subject: [PATCH 50/74] Add test for Region.from_expression --- tests/unit_tests/test_region.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/unit_tests/test_region.py b/tests/unit_tests/test_region.py index c4f4065bf3..377c8fbd58 100644 --- a/tests/unit_tests/test_region.py +++ b/tests/unit_tests/test_region.py @@ -128,3 +128,35 @@ def test_extend_clone(): r5 = ~r1 r6 = r5.clone() + + +def test_from_expression(reset): + # Create surface dictionary + s1 = openmc.ZCylinder(surface_id=1) + s2 = openmc.ZPlane(surface_id=2, z0=-10.) + s3 = openmc.ZPlane(surface_id=3, z0=10.) + surfs = {1: s1, 2: s2, 3: s3} + + r = openmc.Region.from_expression('-1 2 -3', surfs) + assert isinstance(r, openmc.Intersection) + assert r[:] == [-s1, +s2, -s3] + + r = openmc.Region.from_expression('+1 | -2 | +3', surfs) + assert isinstance(r, openmc.Union) + assert r[:] == [+s1, -s2, +s3] + + r = openmc.Region.from_expression('~(-1)', surfs) + assert r == +s1 + + # Since & has higher precendence than |, the resulting region should be an + # instance of Union + r = openmc.Region.from_expression('1 -2 | 3', surfs) + assert isinstance(r, openmc.Union) + assert isinstance(r[0], openmc.Intersection) + assert r[0][:] == [+s1, -s2] + + # ...but not if we use parentheses + r = openmc.Region.from_expression('1 (-2 | 3)', surfs) + assert isinstance(r, openmc.Intersection) + assert isinstance(r[1], openmc.Union) + assert r[1][:] == [-s2, +s3] From 1a93883b670421e37ac226849df8dfc98abed0fb Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 1 Feb 2018 07:17:34 -0600 Subject: [PATCH 51/74] Add tests for openmc.Universe --- openmc/universe.py | 8 +- tests/unit_tests/conftest.py | 22 ++++ tests/unit_tests/test_cell.py | 22 ---- tests/unit_tests/test_geometry.py | 17 ++++ tests/unit_tests/test_universe.py | 160 ++++++++++++++++++++++++++++++ 5 files changed, 203 insertions(+), 26 deletions(-) create mode 100644 tests/unit_tests/test_geometry.py create mode 100644 tests/unit_tests/test_universe.py diff --git a/openmc/universe.py b/openmc/universe.py index 92b152ca09..4a0a1a9aac 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -92,7 +92,7 @@ class Universe(IDManagerMixin): return openmc.Union(regions).bounding_box else: # Infinite bounding box - return openmc.Intersection().bounding_box + return openmc.Intersection([]).bounding_box @name.setter def name(self, name): @@ -322,7 +322,7 @@ class Universe(IDManagerMixin): if not isinstance(cell, openmc.Cell): msg = 'Unable to add a Cell to Universe ID="{0}" since "{1}" is not ' \ 'a Cell'.format(self._id, cell) - raise ValueError(msg) + raise TypeError(msg) cell_id = cell.id @@ -342,7 +342,7 @@ class Universe(IDManagerMixin): if not isinstance(cells, Iterable): msg = 'Unable to add Cells to Universe ID="{0}" since "{1}" is not ' \ 'iterable'.format(self._id, cells) - raise ValueError(msg) + raise TypeError(msg) for cell in cells: self.add_cell(cell) @@ -360,7 +360,7 @@ class Universe(IDManagerMixin): if not isinstance(cell, openmc.Cell): msg = 'Unable to remove a Cell from Universe ID="{0}" since "{1}" is ' \ 'not a Cell'.format(self._id, cell) - raise ValueError(msg) + raise TypeError(msg) # If the Cell is in the Universe's list of Cells, delete it if cell.id in self._cells: diff --git a/tests/unit_tests/conftest.py b/tests/unit_tests/conftest.py index 334bb5fb95..6210064719 100644 --- a/tests/unit_tests/conftest.py +++ b/tests/unit_tests/conftest.py @@ -39,3 +39,25 @@ def sphere_model(): model.settings.run_mode = 'fixed source' model.settings.source = openmc.Source(space=openmc.stats.Point()) return model + + +@pytest.fixture +def cell_with_lattice(): + m_inside = [openmc.Material(), openmc.Material(), None, openmc.Material()] + m_outside = openmc.Material() + + cyl = openmc.ZCylinder(R=1.0) + inside_cyl = openmc.Cell(fill=m_inside, region=-cyl) + outside_cyl = openmc.Cell(fill=m_outside, region=+cyl) + univ = openmc.Universe(cells=[inside_cyl, outside_cyl]) + + lattice = openmc.RectLattice() + lattice.lower_left = (-4.0, -4.0) + lattice.pitch = (4.0, 4.0) + lattice.dimension = (2, 2) + lattice.universes = [[univ, univ], [univ, univ]] + main_cell = openmc.Cell(fill=lattice) + + return ([inside_cyl, outside_cyl, main_cell], + [m_inside[0], m_inside[1], m_inside[3], m_outside], + univ, lattice) diff --git a/tests/unit_tests/test_cell.py b/tests/unit_tests/test_cell.py index 6e6483a28e..b9470a3a6f 100644 --- a/tests/unit_tests/test_cell.py +++ b/tests/unit_tests/test_cell.py @@ -7,28 +7,6 @@ import pytest from tests.unit_tests import assert_unbounded -@pytest.fixture -def cell_with_lattice(): - m_inside = [openmc.Material(), openmc.Material(), None, openmc.Material()] - m_outside = openmc.Material() - - cyl = openmc.ZCylinder(R=1.0) - inside_cyl = openmc.Cell(fill=m_inside, region=-cyl) - outside_cyl = openmc.Cell(fill=m_outside, region=+cyl) - univ = openmc.Universe(cells=[inside_cyl, outside_cyl]) - - lattice = openmc.RectLattice() - lattice.lower_left = (-4.0, -4.0) - lattice.pitch = (4.0, 4.0) - lattice.dimension = (2, 2) - lattice.universes = [[univ, univ], [univ, univ]] - main_cell = openmc.Cell(fill=lattice) - - return ([inside_cyl, outside_cyl, main_cell], - [m_inside[0], m_inside[1], m_inside[3], m_outside], - univ, lattice) - - def test_contains(): # Cell with specified region s = openmc.XPlane() diff --git a/tests/unit_tests/test_geometry.py b/tests/unit_tests/test_geometry.py new file mode 100644 index 0000000000..fc681c8d8c --- /dev/null +++ b/tests/unit_tests/test_geometry.py @@ -0,0 +1,17 @@ +import xml.etree.ElementTree as ET + +import openmc +import pytest + + +def test_determine_paths(cell_with_lattice): + cells, mats, univ, lattice = cell_with_lattice + u = openmc.Universe(cells=[cells[-1]]) + geom = openmc.Geometry(u) + + geom.determine_paths() + assert len(cells[0].paths) == 4 + assert len(cells[1].paths) == 4 + assert len(cells[2].paths) == 1 + assert len(mats[0].paths) == 1 + assert len(mats[-1].paths) == 4 diff --git a/tests/unit_tests/test_universe.py b/tests/unit_tests/test_universe.py new file mode 100644 index 0000000000..656b419cf0 --- /dev/null +++ b/tests/unit_tests/test_universe.py @@ -0,0 +1,160 @@ +import xml.etree.ElementTree as ET + +import numpy as np +import openmc +import pytest + +from tests.unit_tests import assert_unbounded + + +def test_basic(): + c1 = openmc.Cell() + c2 = openmc.Cell() + c3 = openmc.Cell() + u = openmc.Universe(name='cool', cells=(c1, c2, c3)) + assert u.name == 'cool' + + cells = set(u.cells.values()) + assert not (cells ^ {c1, c2, c3}) + + # Test __repr__ + repr(u) + + with pytest.raises(TypeError): + u.add_cell(openmc.Material()) + with pytest.raises(TypeError): + u.add_cells(c1) + + u.remove_cell(c3) + cells = set(u.cells.values()) + assert not (cells ^ {c1, c2}) + + u.clear_cells() + assert not set(u.cells) + + +def test_bounding_box(): + cyl1 = openmc.ZCylinder(R=1.0) + cyl2 = openmc.ZCylinder(R=2.0) + c1 = openmc.Cell(region=-cyl1) + c2 = openmc.Cell(region=+cyl1 & -cyl2) + + u = openmc.Universe(cells=[c1, c2]) + ll, ur = u.bounding_box + assert ll == pytest.approx((-2., -2., -np.inf)) + assert ur == pytest.approx((2., 2., np.inf)) + + u = openmc.Universe() + assert_unbounded(u) + + +def test_find(uo2): + xp = openmc.XPlane() + c1 = openmc.Cell(fill=uo2, region=+xp) + c2 = openmc.Cell(region=-xp) + u1 = openmc.Universe(cells=(c1, c2)) + + cyl = openmc.ZCylinder() + c3 = openmc.Cell(fill=u1, region=-cyl) + c4 = openmc.Cell(region=+cyl) + u = openmc.Universe(cells=(c3, c4)) + + seq = u.find((0.5, 0., 0.)) + assert seq[-1] == c1 + seq = u.find((-0.5, 0., 0.)) + assert seq[-1] == c2 + seq = u.find((-1.5, 0., 0.)) + assert seq[-1] == c4 + + +def test_volume(run_in_tmpdir, sphere_model): + """Test adding volume information from a volume calculation.""" + univ = sphere_model.geometry.root_universe + ll, ur = univ.bounding_box + sphere_model.settings.volume_calculations = [ + openmc.VolumeCalculation(domains=[univ], samples=1000, + lower_left=ll, upper_right=ur) + ] + sphere_model.export_to_xml() + openmc.calculate_volumes() + volume_calc = openmc.VolumeCalculation.from_hdf5('volume_1.h5') + univ.add_volume_information(volume_calc) + + # get_nuclide_densities relies on volume information + nucs = set(univ.get_nuclide_densities()) + assert not (nucs ^ {'U235'}) + + +def test_plot(run_in_tmpdir, sphere_model): + m = sphere_model.materials[0] + univ = sphere_model.geometry.root_universe + + colors = {m: 'limegreen'} + for basis in ('xy', 'yz', 'xz'): + univ.plot( + basis=basis, + pixels=(10, 10), + color_by='material', + colors=colors, + filename='test.png' + ) + + +def test_get_nuclides(uo2): + c = openmc.Cell(fill=uo2) + univ = openmc.Universe(cells=[c]) + nucs = univ.get_nuclides() + assert nucs == ['U235', 'O16'] + + +def test_cells(): + cells = [openmc.Cell() for i in range(5)] + cells2 = [openmc.Cell() for i in range(3)] + cells[0].fill = openmc.Universe(cells=cells2) + u = openmc.Universe(cells=cells) + assert not (set(u.cells.values()) ^ set(cells)) + + all_cells = set(u.get_all_cells().values()) + assert not (all_cells ^ set(cells + cells2)) + + +def test_get_all_materials(cell_with_lattice): + cells, mats, univ, lattice = cell_with_lattice + test_mats = set(univ.get_all_materials().values()) + assert not (test_mats ^ set(mats)) + + +def test_get_all_universes(): + c1 = openmc.Cell() + u1 = openmc.Universe(cells=[c1]) + c2 = openmc.Cell() + u2 = openmc.Universe(cells=[c2]) + c3 = openmc.Cell(fill=u1) + c4 = openmc.Cell(fill=u2) + u3 = openmc.Universe(cells=[c3, c4]) + + univs = set(u3.get_all_universes().values()) + assert not (univs ^ {u1, u2}) + + +def test_clone(): + c1 = openmc.Cell() + c2 = openmc.Cell() + u = openmc.Universe(cells=[c1, c2]) + + u_clone = u.clone() + assert u_clone.id != u.id + assert not (set(u.cells) & set(u_clone.cells)) + + +def test_create_xml(cell_with_lattice): + cells = [openmc.Cell() for i in range(5)] + u = openmc.Universe(cells=cells) + + geom = ET.Element('geom') + u.create_xml_subelement(geom) + cell_elems = geom.findall('cell') + assert len(cell_elems) == len(cells) + assert all(c.get('universe') == str(u.id) for c in cell_elems) + assert not (set(c.get('id') for c in cell_elems) ^ + set(str(c.id) for c in cells)) From 347243876f5c6d50a13acaa13a136dc57eb3f536 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 1 Feb 2018 10:00:50 -0600 Subject: [PATCH 52/74] Combine volume calculations into a single unit test --- tests/unit_tests/test_cell.py | 14 ----- tests/unit_tests/test_geometry.py | 98 +++++++++++++++++++++++++++++++ tests/unit_tests/test_material.py | 13 ---- tests/unit_tests/test_universe.py | 18 ------ 4 files changed, 98 insertions(+), 45 deletions(-) diff --git a/tests/unit_tests/test_cell.py b/tests/unit_tests/test_cell.py index b9470a3a6f..d01d94a324 100644 --- a/tests/unit_tests/test_cell.py +++ b/tests/unit_tests/test_cell.py @@ -94,20 +94,6 @@ def test_rotation(): ]) -def test_volume(run_in_tmpdir, sphere_model): - """Test adding volume information from a volume calculation.""" - ll, ur = sphere_model.geometry.bounding_box - cells = list(sphere_model.geometry.root_universe.cells.values()) - sphere_model.settings.volume_calculations = [ - openmc.VolumeCalculation(domains=cells, samples=1000, - lower_left=ll, upper_right=ur) - ] - sphere_model.export_to_xml() - openmc.calculate_volumes() - volume_calc = openmc.VolumeCalculation.from_hdf5('volume_1.h5') - cells[0].add_volume_information(volume_calc) - - def test_get_nuclides(uo2): c = openmc.Cell(fill=uo2) nucs = c.get_nuclides() diff --git a/tests/unit_tests/test_geometry.py b/tests/unit_tests/test_geometry.py index fc681c8d8c..8394537873 100644 --- a/tests/unit_tests/test_geometry.py +++ b/tests/unit_tests/test_geometry.py @@ -4,6 +4,104 @@ import openmc import pytest +def test_volume(uo2): + """Test adding volume information from a volume calculation.""" + # Create model with nested spheres + model = openmc.model.Model() + model.materials.append(uo2) + inner = openmc.Sphere(R=1.) + outer = openmc.Sphere(R=2., boundary_type='vacuum') + c1 = openmc.Cell(fill=uo2, region=-inner) + c2 = openmc.Cell(region=+inner & -outer) + u = openmc.Universe(cells=[c1, c2]) + model.geometry.root_universe = u + model.settings.particles = 100 + model.settings.batches = 10 + model.settings.run_mode = 'fixed source' + model.settings.source = openmc.Source(space=openmc.stats.Point()) + + ll, ur = model.geometry.bounding_box + assert ll == pytest.approx((-outer.r, -outer.r, -outer.r)) + assert ur == pytest.approx((outer.r, outer.r, outer.r)) + model.settings.volume_calculations + + for domain in (c1, uo2, u): + # Run stochastic volume calculation + volume_calc = openmc.VolumeCalculation( + domains=[domain], samples=1000, lower_left=ll, upper_right=ur) + model.settings.volume_calculations = [volume_calc] + model.export_to_xml() + openmc.calculate_volumes() + + # Load results and add volume information + volume_calc.load_results('volume_1.h5') + model.geometry.add_volume_information(volume_calc) + + # get_nuclide_densities relies on volume information + nucs = set(domain.get_nuclide_densities()) + assert not (nucs ^ {'U235', 'O16'}) + + +def test_export_xml(): + pass + + +def test_find(): + pass + + +def test_get_instances(): + pass + + +def test_get_all_universes(): + pass + + +def test_get_all_materials(): + pass + + +def test_get_all_material_cells(): + pass + + +def test_get_all_material_universes(): + pass + + +def test_get_all_lattices(): + pass + + +def test_get_all_surfaces(): + pass + + +def test_get_materials_by_name(): + pass + + +def test_get_cells_by_name(): + pass + + +def test_get_cells_by_fill_name(): + pass + + +def test_get_universes_by_name(): + pass + + +def test_get_lattices_by_name(): + pass + + +def test_clone(): + pass + + def test_determine_paths(cell_with_lattice): cells, mats, univ, lattice = cell_with_lattice u = openmc.Universe(cells=[cells[-1]]) diff --git a/tests/unit_tests/test_material.py b/tests/unit_tests/test_material.py index ed2f7698a2..e92a2ac088 100644 --- a/tests/unit_tests/test_material.py +++ b/tests/unit_tests/test_material.py @@ -106,19 +106,6 @@ def test_isotropic(): assert m2.isotropic == ['H1'] -def test_volume(run_in_tmpdir, sphere_model): - """Test adding volume information from a volume calculation.""" - ll, ur = sphere_model.geometry.bounding_box - sphere_model.settings.volume_calculations = [ - openmc.VolumeCalculation(domains=sphere_model.materials, samples=1000, - lower_left=ll, upper_right=ur) - ] - sphere_model.export_to_xml() - openmc.calculate_volumes() - volume_calc = openmc.VolumeCalculation.from_hdf5('volume_1.h5') - sphere_model.materials[0].add_volume_information(volume_calc) - - def test_get_nuclide_densities(uo2): nucs = uo2.get_nuclide_densities() for nuc, density, density_type in nucs.values(): diff --git a/tests/unit_tests/test_universe.py b/tests/unit_tests/test_universe.py index 656b419cf0..ac384e9e46 100644 --- a/tests/unit_tests/test_universe.py +++ b/tests/unit_tests/test_universe.py @@ -67,24 +67,6 @@ def test_find(uo2): assert seq[-1] == c4 -def test_volume(run_in_tmpdir, sphere_model): - """Test adding volume information from a volume calculation.""" - univ = sphere_model.geometry.root_universe - ll, ur = univ.bounding_box - sphere_model.settings.volume_calculations = [ - openmc.VolumeCalculation(domains=[univ], samples=1000, - lower_left=ll, upper_right=ur) - ] - sphere_model.export_to_xml() - openmc.calculate_volumes() - volume_calc = openmc.VolumeCalculation.from_hdf5('volume_1.h5') - univ.add_volume_information(volume_calc) - - # get_nuclide_densities relies on volume information - nucs = set(univ.get_nuclide_densities()) - assert not (nucs ^ {'U235'}) - - def test_plot(run_in_tmpdir, sphere_model): m = sphere_model.materials[0] univ = sphere_model.geometry.root_universe From b9ae59620003f66018c45e7c6566ddf5d4549662 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 1 Feb 2018 11:23:17 -0600 Subject: [PATCH 53/74] Add tests for openmc.Geometry and remove __eq__ on openmc.Lattice --- openmc/geometry.py | 39 +++--- openmc/lattice.py | 19 --- tests/unit_tests/conftest.py | 2 +- tests/unit_tests/test_geometry.py | 199 +++++++++++++++++++++++++----- tests/unit_tests/test_universe.py | 29 ----- 5 files changed, 184 insertions(+), 104 deletions(-) diff --git a/openmc/geometry.py b/openmc/geometry.py index 0738ae615a..ac068e2b04 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -14,8 +14,9 @@ class Geometry(object): Parameters ---------- - root_universe : openmc.Universe, optional - Root universe which contains all others + root : openmc.Universe or Iterable of openmc.Cell, optional + Root universe which contains all others, or an iterable of cells that + should be used to create a root universe. Attributes ---------- @@ -27,11 +28,17 @@ class Geometry(object): """ - def __init__(self, root_universe=None): + def __init__(self, root=None): self._root_universe = None self._offsets = {} - if root_universe is not None: - self.root_universe = root_universe + if root is not None: + if isinstance(root, openmc.Universe): + self.root_universe = root + else: + univ = openmc.Universe() + for cell in root: + univ.add_cell(cell) + self._root_universe = univ @property def root_universe(self): @@ -249,7 +256,7 @@ class Geometry(object): for cell in self.get_all_cells().values(): if cell.fill_type == 'lattice': - if cell.fill not in lattices: + if cell.fill.id not in lattices: lattices[cell.fill.id] = cell.fill return lattices @@ -306,9 +313,7 @@ class Geometry(object): elif not matching and name in material_name: materials.add(material) - materials = list(materials) - materials.sort(key=lambda x: x.id) - return materials + return sorted(materials, key=lambda x: x.id) def get_cells_by_name(self, name, case_sensitive=False, matching=False): """Return a list of cells with matching names. @@ -346,9 +351,7 @@ class Geometry(object): elif not matching and name in cell_name: cells.add(cell) - cells = list(cells) - cells.sort(key=lambda x: x.id) - return cells + return sorted(cells, key=lambda x: x.id) def get_cells_by_fill_name(self, name, case_sensitive=False, matching=False): """Return a list of cells with fills with matching names. @@ -393,9 +396,7 @@ class Geometry(object): elif not matching and name in fill_name: cells.add(cell) - cells = list(cells) - cells.sort(key=lambda x: x.id) - return cells + return sorted(cells, key=lambda x: x.id) def get_universes_by_name(self, name, case_sensitive=False, matching=False): """Return a list of universes with matching names. @@ -433,9 +434,7 @@ class Geometry(object): elif not matching and name in universe_name: universes.add(universe) - universes = list(universes) - universes.sort(key=lambda x: x.id) - return universes + return sorted(universes, key=lambda x: x.id) def get_lattices_by_name(self, name, case_sensitive=False, matching=False): """Return a list of lattices with matching names. @@ -473,9 +472,7 @@ class Geometry(object): elif not matching and name in lattice_name: lattices.add(lattice) - lattices = list(lattices) - lattices.sort(key=lambda x: x.id) - return lattices + return sorted(lattices, key=lambda x: x.id) def determine_paths(self, instances_only=False): """Determine paths through CSG tree for cells and materials. diff --git a/openmc/lattice.py b/openmc/lattice.py index 79f0d43f3b..933f51af34 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -54,25 +54,6 @@ class Lattice(IDManagerMixin): self._outer = None self._universes = None - def __eq__(self, other): - if not isinstance(other, Lattice): - return False - elif self.id != other.id: - return False - elif self.name != other.name: - return False - elif np.any(self.pitch != other.pitch): - return False - elif self.outer != other.outer: - return False - elif np.any(self.universes != other.universes): - return False - else: - return True - - def __ne__(self, other): - return not self == other - @property def name(self): return self._name diff --git a/tests/unit_tests/conftest.py b/tests/unit_tests/conftest.py index 6210064719..af534afe35 100644 --- a/tests/unit_tests/conftest.py +++ b/tests/unit_tests/conftest.py @@ -51,7 +51,7 @@ def cell_with_lattice(): outside_cyl = openmc.Cell(fill=m_outside, region=+cyl) univ = openmc.Universe(cells=[inside_cyl, outside_cyl]) - lattice = openmc.RectLattice() + lattice = openmc.RectLattice(name='My Lattice') lattice.lower_left = (-4.0, -4.0) lattice.pitch = (4.0, 4.0) lattice.dimension = (2, 2) diff --git a/tests/unit_tests/test_geometry.py b/tests/unit_tests/test_geometry.py index 8394537873..93d2fa6341 100644 --- a/tests/unit_tests/test_geometry.py +++ b/tests/unit_tests/test_geometry.py @@ -1,10 +1,11 @@ import xml.etree.ElementTree as ET +import numpy as np import openmc import pytest -def test_volume(uo2): +def test_volume(run_in_tmpdir, uo2): """Test adding volume information from a volume calculation.""" # Create model with nested spheres model = openmc.model.Model() @@ -39,67 +40,192 @@ def test_volume(uo2): # get_nuclide_densities relies on volume information nucs = set(domain.get_nuclide_densities()) - assert not (nucs ^ {'U235', 'O16'}) + assert not nucs ^ {'U235', 'O16'} -def test_export_xml(): - pass +def test_export_xml(run_in_tmpdir, uo2): + s1 = openmc.Sphere(R=1.) + s2 = openmc.Sphere(R=2., boundary_type='reflective') + c1 = openmc.Cell(fill=uo2, region=-s1) + c2 = openmc.Cell(fill=uo2, region=+s1 & -s2) + geom = openmc.Geometry([c1, c2]) + geom.export_to_xml() + + doc = ET.parse('geometry.xml') + root = doc.getroot() + assert root.tag == 'geometry' + cells = root.findall('cell') + assert [int(c.get('id')) for c in cells] == [c1.id, c2.id] + surfs = root.findall('surface') + assert [int(s.get('id')) for s in surfs] == [s1.id, s2.id] -def test_find(): - pass +def test_find(uo2): + xp = openmc.XPlane() + c1 = openmc.Cell(fill=uo2, region=+xp) + c2 = openmc.Cell(region=-xp) + u1 = openmc.Universe(cells=(c1, c2)) + + cyl = openmc.ZCylinder() + c3 = openmc.Cell(fill=u1, region=-cyl) + c4 = openmc.Cell(region=+cyl) + geom = openmc.Geometry((c3, c4)) + + seq = geom.find((0.5, 0., 0.)) + assert seq[-1] == c1 + seq = geom.find((-0.5, 0., 0.)) + assert seq[-1] == c2 + seq = geom.find((-1.5, 0., 0.)) + assert seq[-1] == c4 -def test_get_instances(): - pass +def test_get_all_cells(): + cells = [openmc.Cell() for i in range(5)] + cells2 = [openmc.Cell() for i in range(3)] + cells[0].fill = openmc.Universe(cells=cells2) + geom = openmc.Geometry(cells) - -def test_get_all_universes(): - pass + all_cells = set(geom.get_all_cells().values()) + assert not all_cells ^ set(cells + cells2) def test_get_all_materials(): - pass + m1 = openmc.Material() + m2 = openmc.Material() + c1 = openmc.Cell(fill=m1) + u1 = openmc.Universe(cells=[c1]) + + s = openmc.Sphere() + c2 = openmc.Cell(fill=u1, region=-s) + c3 = openmc.Cell(fill=m2, region=+s) + geom = openmc.Geometry([c2, c3]) + + all_mats = set(geom.get_all_materials().values()) + assert not all_mats ^ {m1, m2} def test_get_all_material_cells(): - pass + m1 = openmc.Material() + m2 = openmc.Material() + c1 = openmc.Cell(fill=m1) + u1 = openmc.Universe(cells=[c1]) + + s = openmc.Sphere() + c2 = openmc.Cell(fill=u1, region=-s) + c3 = openmc.Cell(fill=m2, region=+s) + geom = openmc.Geometry([c2, c3]) + + all_cells = set(geom.get_all_material_cells().values()) + assert not all_cells ^ {c1, c3} def test_get_all_material_universes(): - pass + m1 = openmc.Material() + m2 = openmc.Material() + c1 = openmc.Cell(fill=m1) + u1 = openmc.Universe(cells=[c1]) + + s = openmc.Sphere() + c2 = openmc.Cell(fill=u1, region=-s) + c3 = openmc.Cell(fill=m2, region=+s) + geom = openmc.Geometry([c2, c3]) + + all_univs = set(geom.get_all_material_universes().values()) + assert not all_univs ^ {u1, geom.root_universe} -def test_get_all_lattices(): - pass +def test_get_all_lattices(cell_with_lattice): + cells, mats, univ, lattice = cell_with_lattice + geom = openmc.Geometry([cells[-1]]) + + lats = list(geom.get_all_lattices().values()) + assert lats == [lattice] -def test_get_all_surfaces(): - pass +def test_get_all_surfaces(uo2): + planes = [openmc.ZPlane(z0=z) for z in np.linspace(-100., 100.)] + slabs = [] + for region in openmc.model.subdivide(planes): + slabs.append(openmc.Cell(fill=uo2, region=region)) + geom = openmc.Geometry(slabs) + + surfs = set(geom.get_all_surfaces().values()) + assert not surfs ^ set(planes) -def test_get_materials_by_name(): - pass +def test_get_by_name(): + m1 = openmc.Material(name='zircaloy') + m1.add_element('Zr', 1.0) + m2 = openmc.Material(name='Zirconium') + m2.add_element('Zr', 1.0) + + c1 = openmc.Cell(fill=m1, name='cell1') + u1 = openmc.Universe(name='Zircaloy universe', cells=[c1]) + + cyl = openmc.ZCylinder() + c2 = openmc.Cell(fill=u1, region=-cyl, name='cell2') + c3 = openmc.Cell(fill=m2, region=+cyl, name='Cell3') + root = openmc.Universe(name='root Universe', cells=[c2, c3]) + geom = openmc.Geometry(root) + + mats = set(geom.get_materials_by_name('zirc')) + assert not mats ^ {m1, m2} + mats = set(geom.get_materials_by_name('zirc', True)) + assert not mats ^ {m1} + mats = set(geom.get_materials_by_name('zirconium', False, True)) + assert not mats ^ {m2} + mats = geom.get_materials_by_name('zirconium', True, True) + assert not mats + + cells = set(geom.get_cells_by_name('cell')) + assert not cells ^ {c1, c2, c3} + cells = set(geom.get_cells_by_name('cell', True)) + assert not cells ^ {c1, c2} + cells = set(geom.get_cells_by_name('cell3', False, True)) + assert not cells ^ {c3} + cells = geom.get_cells_by_name('cell3', True, True) + assert not cells + + cells = set(geom.get_cells_by_fill_name('Zircaloy')) + assert not cells ^ {c1, c2} + cells = set(geom.get_cells_by_fill_name('Zircaloy', True)) + assert not cells ^ {c2} + cells = set(geom.get_cells_by_fill_name('Zircaloy', False, True)) + assert not cells ^ {c1} + cells = geom.get_cells_by_fill_name('Zircaloy', True, True) + assert not cells + + univs = set(geom.get_universes_by_name('universe')) + assert not univs ^ {u1, root} + univs = set(geom.get_universes_by_name('universe', True)) + assert not univs ^ {u1} + univs = set(geom.get_universes_by_name('universe', True, True)) + assert not univs -def test_get_cells_by_name(): - pass +def test_get_lattice_by_name(cell_with_lattice): + cells, _, _, lattice = cell_with_lattice + geom = openmc.Geometry([cells[-1]]) - -def test_get_cells_by_fill_name(): - pass - - -def test_get_universes_by_name(): - pass - - -def test_get_lattices_by_name(): - pass + f = geom.get_lattices_by_name + assert f('lattice') == [lattice] + assert f('lattice', True) == [] + assert f('Lattice', True) == [lattice] + assert f('my lattice', False, True) == [lattice] + assert f('my lattice', True, True) == [] def test_clone(): - pass + c1 = openmc.Cell() + c2 = openmc.Cell() + root = openmc.Universe(cells=[c1, c2]) + geom = openmc.Geometry(root) + + clone = geom.clone() + root_clone = clone.root_universe + + assert root.id != root_clone.id + assert not (set(root.cells) & set(root_clone.cells)) def test_determine_paths(cell_with_lattice): @@ -113,3 +239,8 @@ def test_determine_paths(cell_with_lattice): assert len(cells[2].paths) == 1 assert len(mats[0].paths) == 1 assert len(mats[-1].paths) == 4 + + # Test get_instances + for i in range(4): + assert geom.get_instances(cells[0].paths[i]) == i + assert geom.get_instances(mats[-1].paths[i]) == i diff --git a/tests/unit_tests/test_universe.py b/tests/unit_tests/test_universe.py index ac384e9e46..59e34e2017 100644 --- a/tests/unit_tests/test_universe.py +++ b/tests/unit_tests/test_universe.py @@ -48,25 +48,6 @@ def test_bounding_box(): assert_unbounded(u) -def test_find(uo2): - xp = openmc.XPlane() - c1 = openmc.Cell(fill=uo2, region=+xp) - c2 = openmc.Cell(region=-xp) - u1 = openmc.Universe(cells=(c1, c2)) - - cyl = openmc.ZCylinder() - c3 = openmc.Cell(fill=u1, region=-cyl) - c4 = openmc.Cell(region=+cyl) - u = openmc.Universe(cells=(c3, c4)) - - seq = u.find((0.5, 0., 0.)) - assert seq[-1] == c1 - seq = u.find((-0.5, 0., 0.)) - assert seq[-1] == c2 - seq = u.find((-1.5, 0., 0.)) - assert seq[-1] == c4 - - def test_plot(run_in_tmpdir, sphere_model): m = sphere_model.materials[0] univ = sphere_model.geometry.root_universe @@ -119,16 +100,6 @@ def test_get_all_universes(): assert not (univs ^ {u1, u2}) -def test_clone(): - c1 = openmc.Cell() - c2 = openmc.Cell() - u = openmc.Universe(cells=[c1, c2]) - - u_clone = u.clone() - assert u_clone.id != u.id - assert not (set(u.cells) & set(u_clone.cells)) - - def test_create_xml(cell_with_lattice): cells = [openmc.Cell() for i in range(5)] u = openmc.Universe(cells=cells) From ef16a6cb575e9f907a2c2babc091aca5d9c7d86d Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 1 Feb 2018 12:35:29 -0600 Subject: [PATCH 54/74] Fix bug in stochastic volume calculation with void cell --- src/volume_calc.F90 | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/volume_calc.F90 b/src/volume_calc.F90 index 15c0497699..e374f21064 100644 --- a/src/volume_calc.F90 +++ b/src/volume_calc.F90 @@ -193,11 +193,13 @@ contains if (this % domain_type == FILTER_MATERIAL) then i_material = p % material - do i_domain = 1, size(this % domain_id) - if (materials(i_material) % id == this % domain_id(i_domain)) then - call check_hit(i_domain, i_material, indices, hits, n_mat) - end if - end do + if (i_material /= MATERIAL_VOID) then + do i_domain = 1, size(this % domain_id) + if (materials(i_material) % id == this % domain_id(i_domain)) then + call check_hit(i_domain, i_material, indices, hits, n_mat) + end if + end do + end if elseif (this % domain_type == FILTER_CELL) THEN do level = 1, p % n_coord From 07d853dd1d1275eea957095d2fd8a8d7d8148561 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 1 Feb 2018 12:40:54 -0600 Subject: [PATCH 55/74] Allow tests that require GUI (matplotlib) --- .travis.yml | 1 + tools/ci/travis-before-script.sh | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 14e2484110..9094637c80 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,7 @@ env: - OPENMC_ENDF_DATA=$HOME/endf-b-vii.1 - OPENMC_MULTIPOLE_LIBRARY=$HOME/multipole_lib - PATH=$PATH:$HOME/NJOY2016/build + - DISPLAY=:99.0 matrix: - OMP=n MPI=n PHDF5=n - OMP=y MPI=n PHDF5=n diff --git a/tools/ci/travis-before-script.sh b/tools/ci/travis-before-script.sh index bbf4980b0f..d0df06f2fd 100755 --- a/tools/ci/travis-before-script.sh +++ b/tools/ci/travis-before-script.sh @@ -1,6 +1,10 @@ #!/bin/bash set -ex +# Allow tests that require GUI as described at: +# https://docs.travis-ci.com/user/gui-and-headless-browsers/#Using-xvfb-to-Run-Tests-That-Require-a-GUI +sh -e /etc/init.d/xvfb start + # Download NNDC HDF5 data if [[ ! -e $HOME/nndc_hdf5/cross_sections.xml ]]; then wget https://anl.box.com/shared/static/a6sw2cep34wlz6b9i9jwiotaqoayxcxt.xz -O - | tar -C $HOME -xvJ From 2027920fdd4e692405c939be5bf0932c54f982d9 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Thu, 1 Feb 2018 14:52:53 -0600 Subject: [PATCH 56/74] Add unit tests for openmc.RectLattice and openmc.HexLattice --- openmc/lattice.py | 6 +- tests/unit_tests/conftest.py | 12 +- tests/unit_tests/test_data_neutron.py | 1 + tests/unit_tests/test_lattice.py | 344 ++++++++++++++++++++++++++ 4 files changed, 360 insertions(+), 3 deletions(-) create mode 100644 tests/unit_tests/test_lattice.py diff --git a/openmc/lattice.py b/openmc/lattice.py index 933f51af34..730d7dc4a9 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -560,7 +560,11 @@ class RectLattice(Lattice): @property def ndim(self): - return len(self.pitch) + if self.pitch is not None: + return len(self.pitch) + else: + raise ValueError('Number of dimensions cannot be determined until ' + 'the lattice pitch has been set.') @property def shape(self): diff --git a/tests/unit_tests/conftest.py b/tests/unit_tests/conftest.py index af534afe35..d618b85def 100644 --- a/tests/unit_tests/conftest.py +++ b/tests/unit_tests/conftest.py @@ -21,10 +21,19 @@ def uo2(): return m +@pytest.fixture(scope='module') +def water(): + m = openmc.Material(name='light water') + m.add_nuclide('H1', 2.0) + m.add_nuclide('O16', 1.0) + m.set_density('g/cm3', 1.0) + m.add_s_alpha_beta('c_H_in_H2O') + return m + + @pytest.fixture(scope='module') def sphere_model(): model = openmc.model.Model() - m = openmc.Material() m.add_nuclide('U235', 1.0) m.set_density('g/cm3', 1.0) @@ -54,7 +63,6 @@ def cell_with_lattice(): lattice = openmc.RectLattice(name='My Lattice') lattice.lower_left = (-4.0, -4.0) lattice.pitch = (4.0, 4.0) - lattice.dimension = (2, 2) lattice.universes = [[univ, univ], [univ, univ]] main_cell = openmc.Cell(fill=lattice) diff --git a/tests/unit_tests/test_data_neutron.py b/tests/unit_tests/test_data_neutron.py index e314d32a42..5713bfbc57 100644 --- a/tests/unit_tests/test_data_neutron.py +++ b/tests/unit_tests/test_data_neutron.py @@ -213,6 +213,7 @@ def test_export_to_hdf5(tmpdir, pu239, gd154): with pytest.raises(NotImplementedError): gd154.export_to_hdf5('gd154.h5') + def test_slbw(xe135): res = xe135.resonances assert isinstance(res, openmc.data.Resonances) diff --git a/tests/unit_tests/test_lattice.py b/tests/unit_tests/test_lattice.py new file mode 100644 index 0000000000..47dc1c029e --- /dev/null +++ b/tests/unit_tests/test_lattice.py @@ -0,0 +1,344 @@ +from math import sqrt +import xml.etree.ElementTree as ET + +import openmc +import pytest + + +@pytest.fixture(scope='module') +def pincell1(uo2, water): + cyl = openmc.ZCylinder(R=0.35) + fuel = openmc.Cell(fill=uo2, region=-cyl) + moderator = openmc.Cell(fill=water, region=+cyl) + + univ = openmc.Universe(cells=[fuel, moderator]) + univ.fuel = fuel + univ.moderator = moderator + return univ + + +@pytest.fixture(scope='module') +def pincell2(uo2, water): + cyl = openmc.ZCylinder(R=0.4) + fuel = openmc.Cell(fill=uo2, region=-cyl) + moderator = openmc.Cell(fill=water, region=+cyl) + + univ = openmc.Universe(cells=[fuel, moderator]) + univ.fuel = fuel + univ.moderator = moderator + return univ + + +@pytest.fixture(scope='module') +def zr(): + zr = openmc.Material() + zr.add_element('Zr', 1.0) + zr.set_density('g/cm3', 1.0) + return zr + + +@pytest.fixture(scope='module') +def rlat2(pincell1, pincell2, uo2, water, zr): + """2D Rectangular lattice for testing.""" + all_zr = openmc.Cell(fill=zr) + pitch = 1.2 + n = 3 + u1, u2 = pincell1, pincell2 + lattice = openmc.RectLattice() + lattice.lower_left = (-pitch*n/2, -pitch*n/2) + lattice.pitch = (pitch, pitch) + lattice.outer = openmc.Universe(cells=[all_zr]) + lattice.universes = [ + [u1, u2, u1], + [u2, u1, u2], + [u2, u1, u1] + ] + + # Add extra attributes for comparison purpose + lattice.cells = [u1.fuel, u1.moderator, u2.fuel, u2.moderator, all_zr] + lattice.mats = [uo2, water, zr] + lattice.univs = [u1, u2, lattice.outer] + return lattice + + +@pytest.fixture(scope='module') +def rlat3(pincell1, pincell2, uo2, water, zr): + """3D Rectangular lattice for testing.""" + + # Create another universe for top layer + hydrogen = openmc.Material() + hydrogen.add_element('H', 1.0) + hydrogen.set_density('g/cm3', 0.09) + h_cell = openmc.Cell(fill=hydrogen) + u3 = openmc.Universe(cells=[h_cell]) + + all_zr = openmc.Cell(fill=zr) + pitch = 1.2 + n = 3 + u1, u2 = pincell1, pincell2 + lattice = openmc.RectLattice() + lattice.lower_left = (-pitch*n/2, -pitch*n/2, -10.0) + lattice.pitch = (pitch, pitch, 10.0) + lattice.outer = openmc.Universe(cells=[all_zr]) + lattice.universes = [ + [[u1, u2, u1], + [u2, u1, u2], + [u2, u1, u1]], + [[u3, u1, u2], + [u1, u3, u2], + [u2, u1, u1]] + ] + + # Add extra attributes for comparison purpose + lattice.cells = [u1.fuel, u1.moderator, u2.fuel, u2.moderator, + h_cell, all_zr] + lattice.mats = [uo2, water, zr, hydrogen] + lattice.univs = [u1, u2, u3, lattice.outer] + return lattice + + +@pytest.fixture(scope='module') +def hlat2(pincell1, pincell2, uo2, water, zr): + """2D Hexagonal lattice for testing.""" + all_zr = openmc.Cell(fill=zr) + pitch = 1.2 + u1, u2 = pincell1, pincell2 + lattice = openmc.HexLattice() + lattice.center = (0., 0.) + lattice.pitch = (pitch,) + lattice.outer = openmc.Universe(cells=[all_zr]) + lattice.universes = [ + [u2, u1, u1, u1, u1, u1, u1, u1, u1, u1, u1, u1], + [u2, u1, u1, u1, u1, u1], + [u2] + ] + + # Add extra attributes for comparison purpose + lattice.cells = [u1.fuel, u1.moderator, u2.fuel, u2.moderator, all_zr] + lattice.mats = [uo2, water, zr] + lattice.univs = [u1, u2, lattice.outer] + return lattice + + +@pytest.fixture(scope='module') +def hlat3(pincell1, pincell2, uo2, water, zr): + """3D Hexagonal lattice for testing.""" + + # Create another universe for top layer + hydrogen = openmc.Material() + hydrogen.add_element('H', 1.0) + hydrogen.set_density('g/cm3', 0.09) + h_cell = openmc.Cell(fill=hydrogen) + u3 = openmc.Universe(cells=[h_cell]) + + all_zr = openmc.Cell(fill=zr) + pitch = 1.2 + u1, u2 = pincell1, pincell2 + lattice = openmc.HexLattice() + lattice.center = (0., 0., 0.) + lattice.pitch = (pitch, 10.0) + lattice.outer = openmc.Universe(cells=[all_zr]) + lattice.universes = [ + [[u2, u1, u1, u1, u1, u1, u1, u1, u1, u1, u1, u1], + [u2, u1, u1, u1, u1, u1], + [u2]], + [[u1, u1, u1, u1, u1, u1, u3, u1, u1, u1, u1, u1], + [u1, u1, u1, u3, u1, u1], + [u3]] + ] + + # Add extra attributes for comparison purpose + lattice.cells = [u1.fuel, u1.moderator, u2.fuel, u2.moderator, + h_cell, all_zr] + lattice.mats = [uo2, water, zr, hydrogen] + lattice.univs = [u1, u2, u3, lattice.outer] + return lattice + + +def test_get_nuclides(rlat2, rlat3, hlat2, hlat3): + for lat in (rlat2, hlat2): + nucs = rlat2.get_nuclides() + assert sorted(nucs) == ['H1', 'O16', 'U235', + 'Zr90', 'Zr91', 'Zr92', 'Zr94', 'Zr96'] + for lat in (rlat3, hlat3): + nucs = rlat3.get_nuclides() + assert sorted(nucs) == ['H1', 'H2', 'O16', 'U235', + 'Zr90', 'Zr91', 'Zr92', 'Zr94', 'Zr96'] + + +def test_get_all_cells(rlat2, rlat3, hlat2, hlat3): + for lat in (rlat2, rlat3, hlat2, hlat3): + cells = set(lat.get_all_cells().values()) + assert not cells ^ set(lat.cells) + + +def test_get_all_materials(rlat2, rlat3, hlat2, hlat3): + for lat in (rlat2, rlat3, hlat2, hlat3): + mats = set(lat.get_all_materials().values()) + assert not mats ^ set(lat.mats) + + +def test_get_all_universes(rlat2, rlat3, hlat2, hlat3): + for lat in (rlat2, rlat3, hlat2, hlat3): + univs = set(lat.get_all_universes().values()) + assert not univs ^ set(lat.univs) + + +def test_get_universe(rlat2, rlat3, hlat2, hlat3): + u1, u2, outer = rlat2.univs + assert rlat2.get_universe((0, 0)) == u2 + assert rlat2.get_universe((1, 0)) == u1 + assert rlat2.get_universe((0, 1)) == u2 + + u1, u2, u3, outer = rlat3.univs + assert rlat3.get_universe((0, 0, 0)) == u2 + assert rlat3.get_universe((2, 2, 0)) == u1 + assert rlat3.get_universe((0, 2, 1)) == u3 + assert rlat3.get_universe((2, 1, 1)) == u2 + + u1, u2, outer = hlat2.univs + assert hlat2.get_universe((0, 0)) == u2 + assert hlat2.get_universe((0, 2)) == u2 + assert hlat2.get_universe((1, 0)) == u1 + assert hlat2.get_universe((-2, 2)) == u1 + + u1, u2, u3, outer = hlat3.univs + assert hlat3.get_universe((0, 0, 0)) == u2 + assert hlat3.get_universe((0, 0, 1)) == u3 + assert hlat3.get_universe((0, 2, 0)) == u2 + assert hlat3.get_universe((0, 2, 1)) == u1 + assert hlat3.get_universe((0, -2, 0)) == u1 + assert hlat3.get_universe((0, -2, 1)) == u3 + + +def test_find(rlat2, rlat3, hlat2, hlat3): + pitch = rlat2.pitch[0] + seq = rlat2.find((0., 0., 0.)) + assert seq[-1] == rlat2.cells[0] + seq = rlat2.find((pitch, 0., 0.)) + assert seq[-1] == rlat2.cells[2] + seq = rlat2.find((0., -pitch, 0.)) + assert seq[-1] == rlat2.cells[0] + seq = rlat2.find((pitch*100, 0., 0.)) + assert seq[-1] == rlat2.cells[-1] + seq = rlat3.find((-pitch, pitch, 5.0)) + assert seq[-1] == rlat3.cells[-2] + + pitch = hlat2.pitch[0] + seq = hlat2.find((0., 0., 0.)) + assert seq[-1] == hlat2.cells[2] + seq = hlat2.find((0.5, 0., 0.)) + assert seq[-1] == hlat2.cells[3] + seq = hlat2.find((sqrt(3)*pitch, 0., 0.)) + assert seq[-1] == hlat2.cells[0] + seq = hlat2.find((0., pitch, 0.)) + assert seq[-1] == hlat2.cells[2] + + # bottom of 3D lattice + seq = hlat3.find((0., 0., -5.)) + assert seq[-1] == hlat3.cells[2] + seq = hlat3.find((0., pitch, -5.)) + assert seq[-1] == hlat3.cells[2] + seq = hlat3.find((0., -pitch, -5.)) + assert seq[-1] == hlat3.cells[0] + seq = hlat3.find((sqrt(3)*pitch, 0., -5.)) + assert seq[-1] == hlat3.cells[0] + + # top of 3D lattice + seq = hlat3.find((0., 0., 5.)) + assert seq[-1] == hlat3.cells[-2] + seq = hlat3.find((0., pitch, 5.)) + assert seq[-1] == hlat3.cells[0] + seq = hlat3.find((0., -pitch, 5.)) + assert seq[-1] == hlat3.cells[-2] + seq = hlat3.find((sqrt(3)*pitch, 0., 5.)) + assert seq[-1] == hlat3.cells[0] + + +def test_clone(rlat2, hlat2, hlat3): + rlat_clone = rlat2.clone() + assert rlat_clone.id != rlat2.id + assert rlat_clone.lower_left == rlat2.lower_left + assert rlat_clone.pitch == rlat2.pitch + + hlat_clone = hlat2.clone() + assert hlat_clone.id != hlat2.id + assert hlat_clone.center == hlat2.center + assert hlat_clone.pitch == hlat2.pitch + + hlat_clone = hlat3.clone() + assert hlat_clone.id != hlat3.id + assert hlat_clone.center == hlat3.center + assert hlat_clone.pitch == hlat3.pitch + + +def test_repr(rlat2, rlat3, hlat2, hlat3): + repr(rlat2) + repr(rlat3) + repr(hlat2) + repr(hlat3) + + +def test_indices_rect(rlat2, rlat3): + # (y, x) indices + assert rlat2.indices == [(0, 0), (0, 1), (0, 2), + (1, 0), (1, 1), (1, 2), + (2, 0), (2, 1), (2, 2)] + # (z, y, x) indices + assert rlat3.indices == [ + (0, 0, 0), (0, 0, 1), (0, 0, 2), + (0, 1, 0), (0, 1, 1), (0, 1, 2), + (0, 2, 0), (0, 2, 1), (0, 2, 2), + (1, 0, 0), (1, 0, 1), (1, 0, 2), + (1, 1, 0), (1, 1, 1), (1, 1, 2), + (1, 2, 0), (1, 2, 1), (1, 2, 2) + ] + + +def test_indices_hex(hlat2, hlat3): + # (r, i) indices + assert hlat2.indices == ( + [(0, i) for i in range(12)] + + [(1, i) for i in range(6)] + + [(2, 0)] + ) + + # (z, r, i) indices + assert hlat3.indices == ( + [(0, 0, i) for i in range(12)] + + [(0, 1, i) for i in range(6)] + + [(0, 2, 0)] + + [(1, 0, i) for i in range(12)] + + [(1, 1, i) for i in range(6)] + + [(1, 2, 0)] + ) + + +def test_xml_rect(rlat2, rlat3): + for lat in (rlat2, rlat3): + geom = ET.Element('geometry') + lat.create_xml_subelement(geom) + elem = geom.find('lattice') + assert elem.tag == 'lattice' + assert elem.get('id') == str(lat.id) + assert len(elem.find('pitch').text.split()) == lat.ndim + assert len(elem.find('lower_left').text.split()) == lat.ndim + assert len(elem.find('universes').text.split()) == len(lat.indices) + + +def test_xml_hex(hlat2, hlat3): + for lat in (hlat2, hlat3): + geom = ET.Element('geometry') + lat.create_xml_subelement(geom) + elem = geom.find('hex_lattice') + assert elem.tag == 'hex_lattice' + assert elem.get('id') == str(lat.id) + assert len(elem.find('center').text.split()) == lat.ndim + assert len(elem.find('pitch').text.split()) == lat.ndim - 1 + assert len(elem.find('universes').text.split()) == len(lat.indices) + + +def test_show_indices(): + for i in range(1, 11): + lines = openmc.HexLattice.show_indices(i).split('\n') + assert len(lines) == 4*i - 3 From 68a01b8fc15e130c842bf7188f94ba946da38bf2 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 2 Feb 2018 06:22:18 -0600 Subject: [PATCH 57/74] Explicitly use int(floor(...)) for Python 2 compatibility --- docs/source/conf.py | 5 +++-- openmc/lattice.py | 12 ++++++------ openmc/mgxs/mgxs.py | 6 +----- openmc/model/triso.py | 12 ++---------- openmc/tallies.py | 2 -- 5 files changed, 12 insertions(+), 25 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 9330315903..b97ff782d9 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -27,8 +27,9 @@ except ImportError: MOCK_MODULES = ['numpy', 'numpy.polynomial', 'numpy.polynomial.polynomial', 'numpy.ctypeslib', 'scipy', 'scipy.sparse', 'scipy.interpolate', 'scipy.integrate', 'scipy.optimize', 'scipy.special', - 'scipy.stats', 'h5py', 'pandas', 'uncertainties', 'matplotlib', - 'matplotlib.pyplot','openmoc', 'openmc.data.reconstruct'] + 'scipy.stats', 'scipy.spatial', 'h5py', 'pandas', 'uncertainties', + 'matplotlib', 'matplotlib.pyplot','openmoc', + 'openmc.data.reconstruct'] sys.modules.update((mod_name, MagicMock()) for mod_name in MOCK_MODULES) import numpy as np diff --git a/openmc/lattice.py b/openmc/lattice.py index 730d7dc4a9..89cfcfe52c 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -607,12 +607,12 @@ class RectLattice(Lattice): element coordinate system """ - ix = floor((point[0] - self.lower_left[0])/self.pitch[0]) - iy = floor((point[1] - self.lower_left[1])/self.pitch[1]) + ix = int(floor((point[0] - self.lower_left[0])/self.pitch[0])) + iy = int(floor((point[1] - self.lower_left[1])/self.pitch[1])) if self.ndim == 2: idx = (ix, iy) else: - iz = floor((point[2] - self.lower_left[2])/self.pitch[2]) + iz = int(floor((point[2] - self.lower_left[2])/self.pitch[2])) idx = (ix, iy, iz) return idx, self.get_local_coordinates(point, idx) @@ -1019,10 +1019,10 @@ class HexLattice(Lattice): iz = 1 else: z = point[2] - self.center[2] - iz = floor(z/self.pitch[1] + 0.5*self.num_axial) + iz = int(floor(z/self.pitch[1] + 0.5*self.num_axial)) alpha = y - x/sqrt(3.) - ix = floor(x/(sqrt(0.75) * self.pitch[0])) - ia = floor(alpha/self.pitch[0]) + ix = int(floor(x/(sqrt(0.75) * self.pitch[0]))) + ia = int(floor(alpha/self.pitch[0])) # Check four lattice elements to see which one is closest based on local # coordinates diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index a557e51cc1..0c0b15ad9d 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -10,6 +10,7 @@ import itertools from six import add_metaclass, string_types import numpy as np +import h5py import openmc import openmc.checkvalue as cv @@ -1682,13 +1683,8 @@ class MGXS(object): ValueError When this method is called before the multi-group cross section is computed from tally data. - ImportError - When h5py is not installed. """ - - import h5py - # Make directory if it does not exist if not os.path.exists(directory): os.makedirs(directory) diff --git a/openmc/model/triso.py b/openmc/model/triso.py index 67bf3bc442..7258a86f21 100644 --- a/openmc/model/triso.py +++ b/openmc/model/triso.py @@ -12,11 +12,7 @@ from abc import ABCMeta, abstractproperty, abstractmethod from six import add_metaclass import numpy as np -try: - import scipy.spatial - _SCIPY_AVAILABLE = True -except ImportError: - _SCIPY_AVAILABLE = False +import scipy.spatial import openmc import openmc.checkvalue as cv @@ -742,7 +738,7 @@ def _close_random_pack(domain, particles, contraction_rate): outer_pf = (4/3 * pi * (outer_diameter[0]/2)**3 * n_particles / domain.volume) - j = floor(-log10(outer_pf - inner_pf)) + j = int(floor(-log10(outer_pf - inner_pf))) outer_diameter[0] = (outer_diameter[0] - 0.5**j * contraction_rate * initial_outer_diameter / n_particles) @@ -837,10 +833,6 @@ def _close_random_pack(domain, particles, contraction_rate): if rods: inner_diameter[0] = rods[0][0] - if not _SCIPY_AVAILABLE: - raise ImportError('SciPy must be installed to perform ' - 'close random packing.') - n_particles = len(particles) diameter = 2*domain.particle_radius diff --git a/openmc/tallies.py b/openmc/tallies.py index 235ad2472e..b685dcae39 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -1508,8 +1508,6 @@ class Tally(IDManagerMixin): ------ KeyError When this method is called before the Tally is populated with data - ImportError - When Pandas can not be found on the caller's system """ From d45856157626ef8c21957991baafbcec933e5827 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 2 Feb 2018 07:09:51 -0600 Subject: [PATCH 58/74] Upload test coverage results to coveralls --- .travis.yml | 6 ++---- tools/ci/travis-install.sh | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9094637c80..8a745c5d69 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,17 +30,15 @@ env: - OMP=y MPI=n PHDF5=n - OMP=n MPI=y PHDF5=n - OMP=n MPI=y PHDF5=y - before_install: - sudo add-apt-repository ppa:nschloe/hdf5-backports -y - sudo apt-get update -q - sudo apt-get install libhdf5-serial-dev libhdf5-mpich-dev -y - install: - ./tools/ci/travis-install.sh - before_script: - ./tools/ci/travis-before-script.sh - script: - ./tools/ci/travis-script.sh +after_success: + - coveralls -d tests/.coverage diff --git a/tools/ci/travis-install.sh b/tools/ci/travis-install.sh index cef34a2e0e..58bcfb789d 100755 --- a/tools/ci/travis-install.sh +++ b/tools/ci/travis-install.sh @@ -25,3 +25,6 @@ python tools/ci/travis-install.py # Install Python API in editable mode pip install -e .[test] + +# For uploading to coveralls +pip install python-coveralls From 6044edc24a5dd39e3b71d1a7e67a30762c2619e0 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 2 Feb 2018 09:24:41 -0600 Subject: [PATCH 59/74] Add simple test for openmc.Settings --- .gitignore | 2 ++ readme.rst | 6 +++- tests/unit_tests/test_settings.py | 54 +++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 tests/unit_tests/test_settings.py diff --git a/.gitignore b/.gitignore index 35f45e747b..8c7cc3e366 100644 --- a/.gitignore +++ b/.gitignore @@ -101,3 +101,5 @@ examples/jupyter/plots .cache/ .tox/ .python-version +.coverage +htmlcov \ No newline at end of file diff --git a/readme.rst b/readme.rst index b7366fe3e1..32cbb34e14 100644 --- a/readme.rst +++ b/readme.rst @@ -2,7 +2,7 @@ OpenMC Monte Carlo Particle Transport Code ========================================== -|licensebadge| |travisbadge| +|licensebadge| |travisbadge| |coverallsbadge| The OpenMC project aims to provide a fully-featured Monte Carlo particle transport code based on modern methods. It is a constructive solid geometry, @@ -74,3 +74,7 @@ OpenMC is distributed under the MIT/X license_. .. |travisbadge| image:: https://travis-ci.org/mit-crpg/openmc.svg?branch=develop :target: https://travis-ci.org/mit-crpg/openmc :alt: Travis CI build status (Linux) + +.. |coverallsbadge| image:: https://coveralls.io/repos/github/mit-crpg/openmc/badge.svg?branch=develop + :target: https://coveralls.io/github/mit-crpg/openmc?branch=develop + :alt: Code Coverage diff --git a/tests/unit_tests/test_settings.py b/tests/unit_tests/test_settings.py new file mode 100644 index 0000000000..f72840be27 --- /dev/null +++ b/tests/unit_tests/test_settings.py @@ -0,0 +1,54 @@ +import openmc +import openmc.stats + + +def test_export_to_xml(run_in_tmpdir): + s = openmc.Settings() + s.run_mode = 'fixed source' + s.batches = 1000 + s.generations_per_batch = 10 + s.inactive = 100 + s.particles = 1000000 + s.keff_trigger = {'type': 'std_dev', 'threshold': 0.001} + s.energy_mode = 'continuous-energy' + s.max_order = 5 + s.source = openmc.Source(space=openmc.stats.Point()) + s.output = {'summary': True, 'tallies': False, 'path': 'here'} + s.verbosity = 7 + s.sourcepoint = {'batches': [50, 150, 500, 1000], 'separate': True, + 'write': True, 'overwrite': True} + s.statepoint = {'batches': [50, 150, 500, 1000]} + s.confidence_intervals = True + s.cross_sections = '/path/to/cross_sections.xml' + s.multipole_library = '/path/to/wmp/' + s.ptables = True + s.run_cmfd = False + s.seed = 17 + s.survival_biasing = True + s.cutoff = {'weight': 0.25, 'weight_avg': 0.5, 'energy': 1.0e-5} + mesh = openmc.Mesh() + mesh.lower_left = (-10., -10., -10.) + mesh.upper_right = (10., 10., 10.) + mesh.dimension = (5, 5, 5) + s.entropy_mesh = mesh + s.trigger_active = True + s.trigger_max_batches = 10000 + s.trigger_batch_interval = 50 + s.no_reduce = False + s.tabular_legendre = {'enable': True, 'num_points': 50} + s.temperature = {'default': 293.6, 'method': 'interpolation', + 'multipole': True, 'range': (200., 1000.)} + s.threads = 8 + s.trace = (10, 1, 20) + s.track = [1, 1, 1, 2, 1, 1] + s.ufs_mesh = mesh + s.resonance_scattering = {'enable': True, 'method': 'ares', + 'energy_min': 1.0, 'energy_max': 1000.0, + 'nuclides': ['U235', 'U238', 'Pu239']} + s.volume_calculations = openmc.VolumeCalculation( + domains=[openmc.Cell()], samples=1000, lower_left=(-10., -10., -10.), + upper_right = (10., 10., 10.)) + s.create_fission_neutrons = True + + # Make sure exporting XML works + s.export_to_xml() From bc4c7d9372c3c4cc33f6606c972423ed0aaddb4f Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 2 Feb 2018 09:30:49 -0600 Subject: [PATCH 60/74] Add option in openmc.Settings for log_grid_bins (and remove DD) --- openmc/settings.py | 158 ++++-------------------------- tests/unit_tests/test_settings.py | 1 + 2 files changed, 20 insertions(+), 139 deletions(-) diff --git a/openmc/settings.py b/openmc/settings.py index 9ead82ec61..3c46d0c2c5 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -60,6 +60,8 @@ class Settings(object): type are 'variance', 'std_dev', and 'rel_err'. The threshold value should be a float indicating the variance, standard deviation, or relative error used. + log_grid_bins : int + Number of bins for logarithmic energy grid search max_order : None or int Maximum scattering order to apply globally when in multi-group mode. multipole_library : str @@ -220,19 +222,12 @@ class Settings(object): # Uniform fission source subelement self._ufs_mesh = None - # Domain decomposition subelement - self._dd_mesh_dimension = None - self._dd_mesh_lower_left = None - self._dd_mesh_upper_right = None - self._dd_nodemap = None - self._dd_allow_leakage = False - self._dd_count_interactions = False - self._resonance_scattering = {} self._volume_calculations = cv.CheckedList( VolumeCalculation, 'volume calculations') self._create_fission_neutrons = None + self._log_grid_bins = None @property def run_mode(self): @@ -362,30 +357,6 @@ class Settings(object): def ufs_mesh(self): return self._ufs_mesh - @property - def dd_mesh_dimension(self): - return self._dd_mesh_dimension - - @property - def dd_mesh_lower_left(self): - return self._dd_mesh_lower_left - - @property - def dd_mesh_upper_right(self): - return self._dd_mesh_upper_right - - @property - def dd_nodemap(self): - return self._dd_nodemap - - @property - def dd_allow_leakage(self): - return self._dd_allow_leakage - - @property - def dd_count_interactions(self): - return self._dd_count_interactions - @property def resonance_scattering(self): return self._resonance_scattering @@ -398,6 +369,10 @@ class Settings(object): def create_fission_neutrons(self): return self._create_fission_neutrons + @property + def log_grid_bins(self): + return self._log_grid_bins + @run_mode.setter def run_mode(self, run_mode): cv.check_value('run mode', run_mode, _RUN_MODES) @@ -696,85 +671,6 @@ class Settings(object): cv.check_length('UFS mesh upper-right corner', ufs_mesh.upper_right, 3) self._ufs_mesh = ufs_mesh - @dd_mesh_dimension.setter - def dd_mesh_dimension(self, dimension): - # TODO: remove this when domain decomposition is merged - warnings.warn('This feature is not yet implemented in a release ' - 'version of openmc') - - cv.check_type('DD mesh dimension', dimension, Iterable, Integral) - cv.check_length('DD mesh dimension', dimension, 3) - - self._dd_mesh_dimension = dimension - - @dd_mesh_lower_left.setter - def dd_mesh_lower_left(self, lower_left): - # TODO: remove this when domain decomposition is merged - warnings.warn('This feature is not yet implemented in a release ' - 'version of openmc') - - cv.check_type('DD mesh lower left corner', lower_left, Iterable, Real) - cv.check_length('DD mesh lower left corner', lower_left, 3) - - self._dd_mesh_lower_left = lower_left - - @dd_mesh_upper_right.setter - def dd_mesh_upper_right(self, upper_right): - # TODO: remove this when domain decomposition is merged - warnings.warn('This feature is not yet implemented in a release ' - 'version of openmc') - - cv.check_type('DD mesh upper right corner', upper_right, Iterable, Real) - cv.check_length('DD mesh upper right corner', upper_right, 3) - - self._dd_mesh_upper_right = upper_right - - @dd_nodemap.setter - def dd_nodemap(self, nodemap): - # TODO: remove this when domain decomposition is merged - warnings.warn('This feature is not yet implemented in a release ' - 'version of openmc') - - cv.check_type('DD nodemap', nodemap, Iterable) - - nodemap = np.array(nodemap).flatten() - - if self._dd_mesh_dimension is None: - msg = 'Must set DD mesh dimension before setting the nodemap' - raise ValueError(msg) - else: - len_nodemap = np.prod(self._dd_mesh_dimension) - - if len(nodemap) < len_nodemap or len(nodemap) > len_nodemap: - msg = 'Unable to set DD nodemap with length "{0}" which ' \ - 'does not have the same dimensionality as the domain ' \ - 'mesh'.format(len(nodemap)) - raise ValueError(msg) - - self._dd_nodemap = nodemap - - @dd_allow_leakage.setter - def dd_allow_leakage(self, allow): - - # TODO: remove this when domain decomposition is merged - warnings.warn('This feature is not yet implemented in a release ' - 'version of openmc') - - cv.check_type('DD allow leakage', allow, bool) - - self._dd_allow_leakage = allow - - @dd_count_interactions.setter - def dd_count_interactions(self, interactions): - - # TODO: remove this when domain decomposition is merged - warnings.warn('This feature is not yet implemented in a release ' - 'version of openmc') - - cv.check_type('DD count interactions', interactions, bool) - - self._dd_count_interactions = interactions - @resonance_scattering.setter def resonance_scattering(self, res): cv.check_type('resonance scattering settings', res, Mapping) @@ -812,6 +708,12 @@ class Settings(object): create_fission_neutrons, bool) self._create_fission_neutrons = create_fission_neutrons + @log_grid_bins.setter + def log_grid_bins(self, log_grid_bins): + cv.check_type('log grid bins', log_grid_bins, Real) + cv.check_greater_than('log grid bins', log_grid_bins, 0) + self._log_grid_bins = log_grid_bins + def _create_run_mode_subelement(self, root): elem = ET.SubElement(root, "run_mode") elem.text = self._run_mode @@ -1033,33 +935,6 @@ class Settings(object): subelement = ET.SubElement(root, "ufs_mesh") subelement.text = str(self.ufs_mesh.id) - def _create_dd_subelement(self, root): - if self._dd_mesh_lower_left is not None and \ - self._dd_mesh_upper_right is not None and \ - self._dd_mesh_dimension is not None: - - element = ET.SubElement(root, "domain_decomposition") - - subelement = ET.SubElement(element, "mesh") - subsubelement = ET.SubElement(subelement, "dimension") - subsubelement.text = ' '.join(map(str, self._dd_mesh_dimension)) - - subsubelement = ET.SubElement(subelement, "lower_left") - subsubelement.text = ' '.join(map(str, self._dd_mesh_lower_left)) - - subsubelement = ET.SubElement(subelement, "upper_right") - subsubelement.text = ' '.join(map(str, self._dd_mesh_upper_right)) - - if self._dd_nodemap is not None: - subelement = ET.SubElement(element, "nodemap") - subelement.text = ' '.join(map(str, self._dd_nodemap)) - - subelement = ET.SubElement(element, "allow_leakage") - subelement.text = str(self._dd_allow_leakage).lower() - - subelement = ET.SubElement(element, "count_interactions") - subelement.text = str(self._dd_count_interactions).lower() - def _create_resonance_scattering_subelement(self, root): res = self.resonance_scattering if res: @@ -1085,6 +960,11 @@ class Settings(object): elem = ET.SubElement(root, "create_fission_neutrons") elem.text = str(self._create_fission_neutrons).lower() + def _create_log_grid_bins_subelement(self, root): + if self._log_grid_bins is not None: + elem = ET.SubElement(root, "log_grid_bins") + elem.text = str(self._log_grid_bins) + def export_to_xml(self, path='settings.xml'): """Export simulation settings to an XML file. @@ -1128,10 +1008,10 @@ class Settings(object): self._create_trace_subelement(root_element) self._create_track_subelement(root_element) self._create_ufs_mesh_subelement(root_element) - self._create_dd_subelement(root_element) self._create_resonance_scattering_subelement(root_element) self._create_volume_calcs_subelement(root_element) self._create_create_fission_neutrons_subelement(root_element) + self._create_log_grid_bins_subelement(root_element) # Clean the indentation in the file to be user-readable clean_xml_indentation(root_element) diff --git a/tests/unit_tests/test_settings.py b/tests/unit_tests/test_settings.py index f72840be27..e3bfc697eb 100644 --- a/tests/unit_tests/test_settings.py +++ b/tests/unit_tests/test_settings.py @@ -49,6 +49,7 @@ def test_export_to_xml(run_in_tmpdir): domains=[openmc.Cell()], samples=1000, lower_left=(-10., -10., -10.), upper_right = (10., 10., 10.)) s.create_fission_neutrons = True + s.log_grid_bins = 2000 # Make sure exporting XML works s.export_to_xml() From c710184fba7b2eb1aa8063f082013b04dc7cd6f7 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 2 Feb 2018 09:46:16 -0600 Subject: [PATCH 61/74] Run tests from root directory --- .travis.yml | 2 +- tools/ci/travis-script.sh | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8a745c5d69..05e239025e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,4 +41,4 @@ before_script: script: - ./tools/ci/travis-script.sh after_success: - - coveralls -d tests/.coverage + - coveralls diff --git a/tools/ci/travis-script.sh b/tools/ci/travis-script.sh index 468cd0cc8a..ee445b517f 100755 --- a/tools/ci/travis-script.sh +++ b/tools/ci/travis-script.sh @@ -2,14 +2,13 @@ set -ex # Run source check -cd tests if [[ $TRAVIS_PYTHON_VERSION == "3.4" && $OMP == 'n' && $MPI == 'n' ]]; then - ./check_source.py + pushd tests && python check_source.py && popd fi # Run regression and unit tests if [[ $MPI == 'y' ]]; then - pytest --cov=../openmc -v --mpi + pytest --cov=openmc -v --mpi tests else - pytest --cov=../openmc -v + pytest --cov=openmc -v tests fi From 36244692fd0e4d40b0d55a7cb90f6e6e68514e22 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Mon, 5 Feb 2018 08:09:47 -0600 Subject: [PATCH 62/74] Use mpicc and mpicxx for MPI configurations --- docs/source/usersguide/install.rst | 13 +++++++------ tools/ci/travis-install.py | 4 +++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index 48188928cf..638d425014 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -263,14 +263,15 @@ should be used: Compiling with MPI ++++++++++++++++++ -To compile with MPI, set the :envvar:`FC` and :envvar:`CC` environment variables -to the path to the MPI Fortran and C wrappers, respectively. For example, in a -bash shell: +To compile with MPI, set the :envvar:`FC`, :envvar:`CC`, and :envvar:`CXX` +environment variables to the path to the MPI Fortran, C, and C++ wrappers, +respectively. For example, in a bash shell: .. code-block:: sh - export FC=mpif90 + export FC=mpifort export CC=mpicc + export CXX=mpicxx cmake /path/to/openmc Note that in many shells, environment variables can be set for a single command, @@ -278,7 +279,7 @@ i.e. .. code-block:: sh - FC=mpif90 CC=mpicc cmake /path/to/openmc + FC=mpifort CC=mpicc CXX=mpicxx cmake /path/to/openmc Selecting HDF5 Installation +++++++++++++++++++++++++++ @@ -354,7 +355,7 @@ follows: .. code-block:: sh mkdir build && cd build - FC=ifort CC=icc FFLAGS=-mmic cmake -Dopenmp=on .. + FC=ifort CC=icc CXX=icpc FFLAGS=-mmic cmake -Dopenmp=on .. make Note that unless an HDF5 build for the Intel Xeon Phi (Knights Corner) is diff --git a/tools/ci/travis-install.py b/tools/ci/travis-install.py index bd7f886dbc..15e4d576b7 100644 --- a/tools/ci/travis-install.py +++ b/tools/ci/travis-install.py @@ -33,9 +33,11 @@ def install(omp=False, mpi=False, phdf5=False): if not omp: cmake_cmd.append('-Dopenmp=off') - # For MPI, we just need to change the Fortran compiler + # Use MPI wrappers when building in parallel if mpi: os.environ['FC'] = 'mpifort' if which('mpifort') else 'mpif90' + os.environ['CC'] = 'mpicc' + os.environ['CXX'] = 'mpicxx' # Tell CMake to prefer parallel HDF5 if specified if phdf5: From c428cee667fcc7341c3cb3eca5798b03d50d13f4 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sun, 24 Dec 2017 16:06:05 +0700 Subject: [PATCH 63/74] Remove __future__ and six imports --- openmc/arithmetic.py | 22 +++++----- openmc/cell.py | 3 +- openmc/cmfd.py | 4 +- openmc/data/ace.py | 4 +- openmc/data/angle_energy.py | 5 +-- openmc/data/decay.py | 5 +-- openmc/data/endf.py | 5 +-- openmc/data/energy_distribution.py | 4 +- openmc/data/function.py | 4 +- openmc/data/library.py | 3 +- openmc/data/multipole.py | 3 +- openmc/data/neutron.py | 6 +-- openmc/data/njoy.py | 1 - openmc/data/product.py | 3 +- openmc/data/reaction.py | 4 +- openmc/element.py | 4 +- openmc/executor.py | 5 +-- openmc/filter.py | 5 +-- openmc/geometry.py | 4 +- openmc/lattice.py | 8 +--- openmc/macroscopic.py | 4 +- openmc/material.py | 23 +++++------ openmc/mesh.py | 5 +-- openmc/mgxs/library.py | 23 +++++------ openmc/mgxs/mdgxs.py | 49 ++++++++++------------ openmc/mgxs/mgxs.py | 65 ++++++++++++++---------------- openmc/mgxs_library.py | 5 +-- openmc/model/funcs.py | 1 - openmc/model/triso.py | 5 +-- openmc/nuclide.py | 2 - openmc/plots.py | 21 +++++----- openmc/plotter.py | 7 ++-- openmc/region.py | 4 +- openmc/settings.py | 9 ++--- openmc/source.py | 4 +- openmc/stats/multivariate.py | 7 +--- openmc/stats/univariate.py | 4 +- openmc/surface.py | 12 ++---- openmc/tallies.py | 22 +++++----- openmc/tally_derivative.py | 8 +--- openmc/trigger.py | 4 +- openmc/universe.py | 6 +-- scripts/openmc-ace-to-hdf5 | 2 +- scripts/openmc-convert-mcnp70-data | 3 +- scripts/openmc-convert-mcnp71-data | 3 +- scripts/openmc-get-jeff-data | 7 +--- scripts/openmc-get-multipole-data | 7 +--- scripts/openmc-get-nndc-data | 5 +-- scripts/openmc-plot-mesh-tally | 12 +++--- scripts/openmc-track-to-vtk | 2 +- scripts/openmc-update-inputs | 4 +- scripts/openmc-update-mgxs | 3 +- scripts/openmc-validate-xml | 4 +- scripts/openmc-voxel-to-silovtk | 3 +- setup.py | 6 +-- 55 files changed, 171 insertions(+), 282 deletions(-) diff --git a/openmc/arithmetic.py b/openmc/arithmetic.py index fe002f1e31..4a5e7486a8 100644 --- a/openmc/arithmetic.py +++ b/openmc/arithmetic.py @@ -2,7 +2,6 @@ import sys import copy from collections import Iterable -from six import string_types import numpy as np import pandas as pd @@ -86,18 +85,18 @@ class CrossScore(object): @left_score.setter def left_score(self, left_score): cv.check_type('left_score', left_score, - string_types + (CrossScore, AggregateScore)) + (str, CrossScore, AggregateScore)) self._left_score = left_score @right_score.setter def right_score(self, right_score): cv.check_type('right_score', right_score, - string_types + (CrossScore, AggregateScore)) + (str, CrossScore, AggregateScore)) self._right_score = right_score @binary_op.setter def binary_op(self, binary_op): - cv.check_type('binary_op', binary_op, string_types) + cv.check_type('binary_op', binary_op, str) cv.check_value('binary_op', binary_op, _TALLY_ARITHMETIC_OPS) self._binary_op = binary_op @@ -202,7 +201,7 @@ class CrossNuclide(object): @binary_op.setter def binary_op(self, binary_op): - cv.check_type('binary_op', binary_op, string_types) + cv.check_type('binary_op', binary_op, str) cv.check_value('binary_op', binary_op, _TALLY_ARITHMETIC_OPS) self._binary_op = binary_op @@ -335,7 +334,7 @@ class CrossFilter(object): @binary_op.setter def binary_op(self, binary_op): - cv.check_type('binary_op', binary_op, string_types) + cv.check_type('binary_op', binary_op, str) cv.check_value('binary_op', binary_op, _TALLY_ARITHMETIC_OPS) self._binary_op = binary_op @@ -482,12 +481,12 @@ class AggregateScore(object): @scores.setter def scores(self, scores): - cv.check_iterable_type('scores', scores, string_types) + cv.check_iterable_type('scores', scores, str) self._scores = scores @aggregate_op.setter def aggregate_op(self, aggregate_op): - cv.check_type('aggregate_op', aggregate_op, string_types +(CrossScore,)) + cv.check_type('aggregate_op', aggregate_op, (str, CrossScore)) cv.check_value('aggregate_op', aggregate_op, _TALLY_AGGREGATE_OPS) self._aggregate_op = aggregate_op @@ -561,13 +560,12 @@ class AggregateNuclide(object): @nuclides.setter def nuclides(self, nuclides): - cv.check_iterable_type('nuclides', nuclides, - string_types + (openmc.Nuclide, CrossNuclide)) + cv.check_iterable_type('nuclides', nuclides, (str, CrossNuclide)) self._nuclides = nuclides @aggregate_op.setter def aggregate_op(self, aggregate_op): - cv.check_type('aggregate_op', aggregate_op, string_types) + cv.check_type('aggregate_op', aggregate_op, str) cv.check_value('aggregate_op', aggregate_op, _TALLY_AGGREGATE_OPS) self._aggregate_op = aggregate_op @@ -690,7 +688,7 @@ class AggregateFilter(object): @aggregate_op.setter def aggregate_op(self, aggregate_op): - cv.check_type('aggregate_op', aggregate_op, string_types) + cv.check_type('aggregate_op', aggregate_op, str) cv.check_value('aggregate_op', aggregate_op, _TALLY_AGGREGATE_OPS) self._aggregate_op = aggregate_op diff --git a/openmc/cell.py b/openmc/cell.py index 074fadc06d..087f2816d4 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -6,7 +6,6 @@ from xml.etree import ElementTree as ET import sys import warnings -from six import string_types import numpy as np import openmc @@ -203,7 +202,7 @@ class Cell(IDManagerMixin): @name.setter def name(self, name): if name is not None: - cv.check_type('cell name', name, string_types) + cv.check_type('cell name', name, str) self._name = name else: self._name = '' diff --git a/openmc/cmfd.py b/openmc/cmfd.py index c3df3f1047..236491923d 100644 --- a/openmc/cmfd.py +++ b/openmc/cmfd.py @@ -15,8 +15,6 @@ from numbers import Real, Integral from xml.etree import ElementTree as ET import sys -from six import string_types - from openmc.clean_xml import clean_xml_indentation from openmc.checkvalue import (check_type, check_length, check_value, check_greater_than, check_less_than) @@ -338,7 +336,7 @@ class CMFD(object): @display.setter def display(self, display): - check_type('CMFD display', display, string_types) + check_type('CMFD display', display, str) check_value('CMFD display', display, ['balance', 'dominance', 'entropy', 'source']) self._display = display diff --git a/openmc/data/ace.py b/openmc/data/ace.py index 9827df5b9d..385408bd48 100644 --- a/openmc/data/ace.py +++ b/openmc/data/ace.py @@ -15,12 +15,10 @@ generates ACE-format cross sections. """ -from __future__ import division, unicode_literals from os import SEEK_CUR import struct import sys -from six import string_types import numpy as np from openmc.mixin import EqualityMixin @@ -153,7 +151,7 @@ class Library(EqualityMixin): """ def __init__(self, filename, table_names=None, verbose=False): - if isinstance(table_names, string_types): + if isinstance(table_names, str): table_names = [table_names] if table_names is not None: table_names = set(table_names) diff --git a/openmc/data/angle_energy.py b/openmc/data/angle_energy.py index 8bf95152a9..d67cc6b266 100644 --- a/openmc/data/angle_energy.py +++ b/openmc/data/angle_energy.py @@ -1,14 +1,11 @@ from abc import ABCMeta, abstractmethod from io import StringIO -from six import add_metaclass - import openmc.data from openmc.mixin import EqualityMixin -@add_metaclass(ABCMeta) -class AngleEnergy(EqualityMixin): +class AngleEnergy(EqualityMixin, metaclass=ABCMeta): """Distribution in angle and energy of a secondary particle.""" @abstractmethod def to_hdf5(self, group): diff --git a/openmc/data/decay.py b/openmc/data/decay.py index 4327b2fc35..3d365b6c70 100644 --- a/openmc/data/decay.py +++ b/openmc/data/decay.py @@ -5,7 +5,6 @@ from numbers import Real import re from warnings import warn -from six import string_types import numpy as np try: from uncertainties import ufloat, unumpy, UFloat @@ -278,12 +277,12 @@ class DecayMode(EqualityMixin): @modes.setter def modes(self, modes): - cv.check_type('decay modes', modes, Iterable, string_types) + cv.check_type('decay modes', modes, Iterable, str) self._modes = modes @parent.setter def parent(self, parent): - cv.check_type('parent nuclide', parent, string_types) + cv.check_type('parent nuclide', parent, str) self._parent = parent diff --git a/openmc/data/endf.py b/openmc/data/endf.py index 0fa75ded89..882874b590 100644 --- a/openmc/data/endf.py +++ b/openmc/data/endf.py @@ -6,15 +6,12 @@ Data File ENDF-6". The latest version from June 2009 can be found at http://www-nds.iaea.org/ndspub/documents/endf/endf102/endf102.pdf """ -from __future__ import print_function, division, unicode_literals - import io import re import os from math import pi from collections import OrderedDict, Iterable -from six import string_types import numpy as np from numpy.polynomial.polynomial import Polynomial @@ -301,7 +298,7 @@ class Evaluation(object): """ def __init__(self, filename_or_obj): - if isinstance(filename_or_obj, string_types): + if isinstance(filename_or_obj, str): fh = open(filename_or_obj, 'r') else: fh = filename_or_obj diff --git a/openmc/data/energy_distribution.py b/openmc/data/energy_distribution.py index c3740beaf0..e8c92801cf 100644 --- a/openmc/data/energy_distribution.py +++ b/openmc/data/energy_distribution.py @@ -3,7 +3,6 @@ from collections import Iterable from numbers import Integral, Real from warnings import warn -from six import add_metaclass import numpy as np from .function import Tabulated1D, INTERPOLATION_SCHEME @@ -14,8 +13,7 @@ from .data import EV_PER_MEV from .endf import get_tab1_record, get_tab2_record -@add_metaclass(ABCMeta) -class EnergyDistribution(EqualityMixin): +class EnergyDistribution(EqualityMixin, metaclass=ABCMeta): """Abstract superclass for all energy distributions.""" def __init__(self): pass diff --git a/openmc/data/function.py b/openmc/data/function.py index 0515a57c0c..2d3a8ce9c1 100644 --- a/openmc/data/function.py +++ b/openmc/data/function.py @@ -2,7 +2,6 @@ from abc import ABCMeta, abstractmethod from collections import Iterable, Callable from numbers import Real, Integral -from six import add_metaclass import numpy as np import openmc.data @@ -14,8 +13,7 @@ INTERPOLATION_SCHEME = {1: 'histogram', 2: 'linear-linear', 3: 'linear-log', 4: 'log-linear', 5: 'log-log'} -@add_metaclass(ABCMeta) -class Function1D(EqualityMixin): +class Function1D(EqualityMixin, metaclass=ABCMeta): """A function of one independent variable with HDF5 support.""" @abstractmethod def __call__(self): pass diff --git a/openmc/data/library.py b/openmc/data/library.py index c179f78f8c..34cd380a55 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -1,6 +1,5 @@ import os import xml.etree.ElementTree as ET -from six import string_types import h5py @@ -125,7 +124,7 @@ class DataLibrary(EqualityMixin): raise ValueError("Either path or OPENMC_CROSS_SECTIONS " "environmental variable must be set") - check_type('path', path, string_types) + check_type('path', path, str) tree = ET.parse(path) root = tree.getroot() diff --git a/openmc/data/multipole.py b/openmc/data/multipole.py index 4e77e16ea9..33078f5046 100644 --- a/openmc/data/multipole.py +++ b/openmc/data/multipole.py @@ -3,7 +3,6 @@ from math import exp, erf, pi, sqrt import h5py import numpy as np -from six import string_types from . import WMP_VERSION from .data import K_BOLTZMANN @@ -300,7 +299,7 @@ class WindowedMultipole(EqualityMixin): @formalism.setter def formalism(self, formalism): if formalism is not None: - cv.check_type('formalism', formalism, string_types) + cv.check_type('formalism', formalism, str) cv.check_value('formalism', formalism, ('MLBW', 'RM')) self._formalism = formalism diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index 7dcac5d6e6..8d59316892 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -1,4 +1,3 @@ -from __future__ import division, unicode_literals import sys from collections import OrderedDict, Iterable, Mapping, MutableMapping from io import StringIO @@ -10,7 +9,6 @@ import shutil import tempfile from warnings import warn -from six import string_types import numpy as np import h5py @@ -245,7 +243,7 @@ class IncidentNeutron(EqualityMixin): @name.setter def name(self, name): - cv.check_type('name', name, string_types) + cv.check_type('name', name, str) self._name = name @property @@ -301,7 +299,7 @@ class IncidentNeutron(EqualityMixin): def urr(self, urr): cv.check_type('probability table dictionary', urr, MutableMapping) for key, value in urr: - cv.check_type('probability table temperature', key, string_types) + cv.check_type('probability table temperature', key, str) cv.check_type('probability tables', value, ProbabilityTables) self._urr = urr diff --git a/openmc/data/njoy.py b/openmc/data/njoy.py index b08b3bdfb3..be16d96f81 100644 --- a/openmc/data/njoy.py +++ b/openmc/data/njoy.py @@ -1,4 +1,3 @@ -from __future__ import print_function import argparse from collections import namedtuple from io import StringIO diff --git a/openmc/data/product.py b/openmc/data/product.py index bcffec0daf..b7d89ba0ea 100644 --- a/openmc/data/product.py +++ b/openmc/data/product.py @@ -3,7 +3,6 @@ from io import StringIO from numbers import Real import sys -from six import string_types import numpy as np import openmc.checkvalue as cv @@ -113,7 +112,7 @@ class Product(EqualityMixin): @particle.setter def particle(self, particle): - cv.check_type('product particle type', particle, string_types) + cv.check_type('product particle type', particle, str) self._particle = particle @yield_.setter diff --git a/openmc/data/reaction.py b/openmc/data/reaction.py index ac3a049ab1..737885f357 100644 --- a/openmc/data/reaction.py +++ b/openmc/data/reaction.py @@ -1,11 +1,9 @@ -from __future__ import division, unicode_literals from collections import Iterable, Callable, MutableMapping from copy import deepcopy from numbers import Real, Integral from warnings import warn from io import StringIO -from six import string_types import numpy as np import openmc.checkvalue as cv @@ -863,7 +861,7 @@ class Reaction(EqualityMixin): def xs(self, xs): cv.check_type('reaction cross section dictionary', xs, MutableMapping) for key, value in xs.items(): - cv.check_type('reaction cross section temperature', key, string_types) + cv.check_type('reaction cross section temperature', key, str) cv.check_type('reaction cross section', value, Callable) self._xs = xs diff --git a/openmc/element.py b/openmc/element.py index 5ba19c63c4..25cb97538c 100644 --- a/openmc/element.py +++ b/openmc/element.py @@ -1,8 +1,6 @@ from collections import OrderedDict import re import os - -from six import string_types from xml.etree import ElementTree as ET import openmc @@ -29,7 +27,7 @@ class Element(str): """ def __new__(cls, name): - cv.check_type('element name', name, string_types) + cv.check_type('element name', name, str) cv.check_length('element name', name, 1, 2) return super(Element, cls).__new__(cls, name) diff --git a/openmc/executor.py b/openmc/executor.py index ada662a12f..e3768f4c61 100644 --- a/openmc/executor.py +++ b/openmc/executor.py @@ -1,10 +1,7 @@ -from __future__ import print_function from collections import Iterable import subprocess from numbers import Integral -from six import string_types - import openmc from openmc import VolumeCalculation @@ -203,7 +200,7 @@ def run(particles=None, threads=None, geometry_debug=False, if geometry_debug: args.append('-g') - if isinstance(restart_file, string_types): + if isinstance(restart_file, str): args += ['-r', restart_file] if tracks: diff --git a/openmc/filter.py b/openmc/filter.py index 21bb64f8d5..8f57a80906 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -1,4 +1,3 @@ -from __future__ import division from abc import ABCMeta from collections import Iterable, OrderedDict import copy @@ -8,7 +7,6 @@ from numbers import Real, Integral import operator from xml.etree import ElementTree as ET -from six import add_metaclass import numpy as np import pandas as pd @@ -70,8 +68,7 @@ class FilterMeta(ABCMeta): **kwargs) -@add_metaclass(FilterMeta) -class Filter(IDManagerMixin): +class Filter(IDManagerMixin, metaclass=FilterMeta): """Tally modifier that describes phase-space and other characteristics. Parameters diff --git a/openmc/geometry.py b/openmc/geometry.py index ac068e2b04..7e14272698 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -2,8 +2,6 @@ from collections import OrderedDict, Iterable from copy import deepcopy from xml.etree import ElementTree as ET -from six import string_types - import openmc from openmc.clean_xml import clean_xml_indentation from openmc.checkvalue import check_type @@ -139,7 +137,7 @@ class Geometry(object): """ # Make sure we are working with an iterable return_list = (isinstance(paths, Iterable) and - not isinstance(paths, string_types)) + not isinstance(paths, str)) path_list = paths if return_list else [paths] indices = [] diff --git a/openmc/lattice.py b/openmc/lattice.py index 89cfcfe52c..1bb82f6284 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -1,5 +1,3 @@ -from __future__ import division - from abc import ABCMeta from collections import OrderedDict, Iterable from copy import deepcopy @@ -7,7 +5,6 @@ from math import sqrt, floor from numbers import Real, Integral from xml.etree import ElementTree as ET -from six import add_metaclass, string_types import numpy as np import openmc.checkvalue as cv @@ -15,8 +12,7 @@ import openmc from openmc.mixin import IDManagerMixin -@add_metaclass(ABCMeta) -class Lattice(IDManagerMixin): +class Lattice(IDManagerMixin, metaclass=ABCMeta): """A repeating structure wherein each element is a universe. Parameters @@ -73,7 +69,7 @@ class Lattice(IDManagerMixin): @name.setter def name(self, name): if name is not None: - cv.check_type('lattice name', name, string_types) + cv.check_type('lattice name', name, str) self._name = name else: self._name = '' diff --git a/openmc/macroscopic.py b/openmc/macroscopic.py index cdb5cbb395..f5bd90f3a4 100644 --- a/openmc/macroscopic.py +++ b/openmc/macroscopic.py @@ -1,5 +1,3 @@ -from six import string_types - from openmc.checkvalue import check_type @@ -19,7 +17,7 @@ class Macroscopic(str): """ def __new__(cls, name): - check_type('name', name, string_types) + check_type('name', name, str) return super(Macroscopic, cls).__new__(cls, name) @property diff --git a/openmc/material.py b/openmc/material.py index a59fdaa285..cb3024447b 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -4,7 +4,6 @@ from numbers import Real, Integral import warnings from xml.etree import ElementTree as ET -from six import string_types import numpy as np import openmc @@ -217,7 +216,7 @@ class Material(IDManagerMixin): def name(self, name): if name is not None: cv.check_type('name for Material ID="{}"'.format(self._id), - name, string_types) + name, str) self._name = name else: self._name = '' @@ -243,7 +242,7 @@ class Material(IDManagerMixin): @isotropic.setter def isotropic(self, isotropic): cv.check_iterable_type('Isotropic scattering nuclides', isotropic, - string_types) + str) self._isotropic = list(isotropic) @classmethod @@ -345,7 +344,7 @@ class Material(IDManagerMixin): warnings.warn('This feature is not yet implemented in a release ' 'version of openmc') - if not isinstance(filename, string_types) and filename is not None: + if not isinstance(filename, str) and filename is not None: msg = 'Unable to add OTF material file to Material ID="{}" with a ' \ 'non-string name "{}"'.format(self._id, filename) raise ValueError(msg) @@ -379,7 +378,7 @@ class Material(IDManagerMixin): 'macroscopic data-set has already been added'.format(self._id) raise ValueError(msg) - if not isinstance(nuclide, string_types): + if not isinstance(nuclide, str): msg = 'Unable to add a Nuclide to Material ID="{}" with a ' \ 'non-string value "{}"'.format(self._id, nuclide) raise ValueError(msg) @@ -405,7 +404,7 @@ class Material(IDManagerMixin): Nuclide to remove """ - cv.check_type('nuclide', nuclide, string_types) + cv.check_type('nuclide', nuclide, str) # If the Material contains the Nuclide, delete it for nuc in self._nuclides: @@ -434,7 +433,7 @@ class Material(IDManagerMixin): 'has already been added'.format(self._id, macroscopic) raise ValueError(msg) - if not isinstance(macroscopic, string_types): + if not isinstance(macroscopic, str): msg = 'Unable to add a Macroscopic to Material ID="{}" with a ' \ 'non-string value "{}"'.format(self._id, macroscopic) raise ValueError(msg) @@ -465,7 +464,7 @@ class Material(IDManagerMixin): """ - if not isinstance(macroscopic, string_types): + if not isinstance(macroscopic, str): msg = 'Unable to remove a Macroscopic "{}" in Material ID="{}" ' \ 'since it is not a string'.format(self._id, macroscopic) raise ValueError(msg) @@ -498,7 +497,7 @@ class Material(IDManagerMixin): 'macroscopic data-set has already been added'.format(self._id) raise ValueError(msg) - if not isinstance(element, string_types): + if not isinstance(element, str): msg = 'Unable to add an Element to Material ID="{}" with a ' \ 'non-string value "{}"'.format(self._id, element) raise ValueError(msg) @@ -563,7 +562,7 @@ class Material(IDManagerMixin): 'macroscopic data-set has already been added'.format(self._id) raise ValueError(msg) - if not isinstance(name, string_types): + if not isinstance(name, str): msg = 'Unable to add an S(a,b) table to Material ID="{}" with a ' \ 'non-string table name "{}"'.format(self._id, name) raise ValueError(msg) @@ -903,12 +902,12 @@ class Materials(cv.CheckedList): @cross_sections.setter def cross_sections(self, cross_sections): - cv.check_type('cross sections', cross_sections, string_types) + cv.check_type('cross sections', cross_sections, str) self._cross_sections = cross_sections @multipole_library.setter def multipole_library(self, multipole_library): - cv.check_type('cross sections', multipole_library, string_types) + cv.check_type('cross sections', multipole_library, str) self._multipole_library = multipole_library def add_material(self, material): diff --git a/openmc/mesh.py b/openmc/mesh.py index b315b2628b..d937e25ce9 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -3,7 +3,6 @@ from numbers import Real, Integral from xml.etree import ElementTree as ET import sys -from six import string_types import numpy as np import openmc.checkvalue as cv @@ -87,7 +86,7 @@ class Mesh(IDManagerMixin): def name(self, name): if name is not None: cv.check_type('name for mesh ID="{0}"'.format(self._id), - name, string_types) + name, str) self._name = name else: self._name = '' @@ -95,7 +94,7 @@ class Mesh(IDManagerMixin): @type.setter def type(self, meshtype): cv.check_type('type for mesh ID="{0}"'.format(self._id), - meshtype, string_types) + meshtype, str) cv.check_value('type for mesh ID="{0}"'.format(self._id), meshtype, ['regular']) self._type = meshtype diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index b83305783f..c8b151e024 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -6,7 +6,6 @@ from numbers import Integral from collections import OrderedDict, Iterable from warnings import warn -from six import string_types import numpy as np import openmc @@ -271,7 +270,7 @@ class Library(object): @name.setter def name(self, name): - cv.check_type('name', name, string_types) + cv.check_type('name', name, str) self._name = name @mgxs_types.setter @@ -280,7 +279,7 @@ class Library(object): if mgxs_types == 'all': self._mgxs_types = all_mgxs_types else: - cv.check_iterable_type('mgxs_types', mgxs_types, string_types) + cv.check_iterable_type('mgxs_types', mgxs_types, str) for mgxs_type in mgxs_types: cv.check_value('mgxs_type', mgxs_type, all_mgxs_types) self._mgxs_types = mgxs_types @@ -814,8 +813,8 @@ class Library(object): 'since a statepoint has not yet been loaded' raise ValueError(msg) - cv.check_type('filename', filename, string_types) - cv.check_type('directory', directory, string_types) + cv.check_type('filename', filename, str) + cv.check_type('directory', directory, str) import h5py @@ -857,8 +856,8 @@ class Library(object): """ - cv.check_type('filename', filename, string_types) - cv.check_type('directory', directory, string_types) + cv.check_type('filename', filename, str) + cv.check_type('directory', directory, str) # Make directory if it does not exist if not os.path.exists(directory): @@ -892,8 +891,8 @@ class Library(object): """ - cv.check_type('filename', filename, string_types) - cv.check_type('directory', directory, string_types) + cv.check_type('filename', filename, str) + cv.check_type('directory', directory, str) # Make directory if it does not exist if not os.path.exists(directory): @@ -953,8 +952,8 @@ class Library(object): cv.check_type('domain', domain, (openmc.Material, openmc.Cell, openmc.Universe, openmc.Mesh)) - cv.check_type('xsdata_name', xsdata_name, string_types) - cv.check_type('nuclide', nuclide, string_types) + cv.check_type('xsdata_name', xsdata_name, str) + cv.check_type('nuclide', nuclide, str) cv.check_value('xs_type', xs_type, ['macro', 'micro']) if subdomain is not None: cv.check_iterable_type('subdomain', subdomain, Integral, @@ -1213,7 +1212,7 @@ class Library(object): cv.check_value('xs_type', xs_type, ['macro', 'micro']) if xsdata_names is not None: - cv.check_iterable_type('xsdata_names', xsdata_names, string_types) + cv.check_iterable_type('xsdata_names', xsdata_names, str) # If gathering material-specific data, set the xs_type to macro if not self.by_nuclide: diff --git a/openmc/mgxs/mdgxs.py b/openmc/mgxs/mdgxs.py index d3f1a0646b..7799183ff7 100644 --- a/openmc/mgxs/mdgxs.py +++ b/openmc/mgxs/mdgxs.py @@ -1,5 +1,3 @@ -from __future__ import division - from collections import Iterable, OrderedDict import itertools from numbers import Integral @@ -9,7 +7,6 @@ import sys import copy from abc import ABCMeta -from six import add_metaclass, string_types import numpy as np import openmc @@ -29,7 +26,6 @@ MDGXS_TYPES = ['delayed-nu-fission', MAX_DELAYED_GROUPS = 8 -@add_metaclass(ABCMeta) class MDGXS(MGXS): """An abstract multi-delayed-group cross section for some energy and delayed group structures within some spatial domain. @@ -355,7 +351,7 @@ class MDGXS(MGXS): filter_bins = [] # Construct a collection of the domain filter bins - if not isinstance(subdomains, string_types): + if not isinstance(subdomains, str): cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3) for subdomain in subdomains: @@ -363,7 +359,7 @@ class MDGXS(MGXS): filter_bins.append((subdomain,)) # Construct list of energy group bounds tuples for all requested groups - if not isinstance(groups, string_types): + if not isinstance(groups, str): cv.check_iterable_type('groups', groups, Integral) for group in groups: filters.append(openmc.EnergyFilter) @@ -371,7 +367,7 @@ class MDGXS(MGXS): (self.energy_groups.get_group_bounds(group),)) # Construct list of delayed group tuples for all requested groups - if not isinstance(delayed_groups, string_types): + if not isinstance(delayed_groups, str): cv.check_type('delayed groups', delayed_groups, list, int) for delayed_group in delayed_groups: filters.append(openmc.DelayedGroupFilter) @@ -475,7 +471,7 @@ class MDGXS(MGXS): """ - cv.check_iterable_type('nuclides', nuclides, string_types) + cv.check_iterable_type('nuclides', nuclides, str) cv.check_iterable_type('energy_groups', groups, Integral) cv.check_type('delayed groups', delayed_groups, list, int) @@ -585,7 +581,7 @@ class MDGXS(MGXS): return # Construct a collection of the subdomains to report - if not isinstance(subdomains, string_types): + if not isinstance(subdomains, str): cv.check_iterable_type('subdomains', subdomains, Integral) elif self.domain_type == 'distribcell': subdomains = np.arange(self.num_subdomains, dtype=np.int) @@ -602,7 +598,7 @@ class MDGXS(MGXS): elif nuclides == 'sum': nuclides = ['sum'] else: - cv.check_iterable_type('nuclides', nuclides, string_types) + cv.check_iterable_type('nuclides', nuclides, str) else: nuclides = ['sum'] @@ -725,8 +721,8 @@ class MDGXS(MGXS): """ - cv.check_type('filename', filename, string_types) - cv.check_type('directory', directory, string_types) + cv.check_type('filename', filename, str) + cv.check_type('directory', directory, str) cv.check_value('format', format, ['csv', 'excel', 'pickle', 'latex']) cv.check_value('xs_type', xs_type, ['macro', 'micro']) @@ -816,11 +812,11 @@ class MDGXS(MGXS): """ - if not isinstance(groups, string_types): + if not isinstance(groups, str): cv.check_iterable_type('groups', groups, Integral) if nuclides != 'all' and nuclides != 'sum': - cv.check_iterable_type('nuclides', nuclides, string_types) - if not isinstance(delayed_groups, string_types): + cv.check_iterable_type('nuclides', nuclides, str) + if not isinstance(delayed_groups, str): cv.check_type('delayed groups', delayed_groups, list, int) cv.check_value('xs_type', xs_type, ['macro', 'micro']) @@ -858,7 +854,7 @@ class MDGXS(MGXS): columns = self._df_convert_columns_to_bins(df) # Select out those groups the user requested - if not isinstance(groups, string_types): + if not isinstance(groups, str): if 'group in' in df: df = df[df['group in'].isin(groups)] if 'group out' in df: @@ -1288,7 +1284,7 @@ class ChiDelayed(MDGXS): filter_bins = [] # Construct a collection of the domain filter bins - if not isinstance(subdomains, string_types): + if not isinstance(subdomains, str): cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3) for subdomain in subdomains: @@ -1296,7 +1292,7 @@ class ChiDelayed(MDGXS): filter_bins.append((subdomain,)) # Construct list of energy group bounds tuples for all requested groups - if not isinstance(groups, string_types): + if not isinstance(groups, str): cv.check_iterable_type('groups', groups, Integral) for group in groups: filters.append(openmc.EnergyoutFilter) @@ -1304,7 +1300,7 @@ class ChiDelayed(MDGXS): (self.energy_groups.get_group_bounds(group),)) # Construct list of delayed group tuples for all requested groups - if not isinstance(delayed_groups, string_types): + if not isinstance(delayed_groups, str): cv.check_type('delayed groups', delayed_groups, list, int) for delayed_group in delayed_groups: filters.append(openmc.DelayedGroupFilter) @@ -1352,7 +1348,7 @@ class ChiDelayed(MDGXS): # Get chi delayed for user-specified nuclides in the domain else: - cv.check_iterable_type('nuclides', nuclides, string_types) + cv.check_iterable_type('nuclides', nuclides, str) xs = self.xs_tally.get_values(filters=filters, filter_bins=filter_bins, nuclides=nuclides, value=value) @@ -1914,7 +1910,6 @@ class DecayRate(MDGXS): return self._get_homogenized_mgxs(other_mgxs, 'delayed-nu-fission') -@add_metaclass(ABCMeta) class MatrixMDGXS(MDGXS): """An abstract multi-delayed-group cross section for some energy group and delayed group structure within some spatial domain. This class is @@ -2117,7 +2112,7 @@ class MatrixMDGXS(MDGXS): filter_bins = [] # Construct a collection of the domain filter bins - if not isinstance(subdomains, string_types): + if not isinstance(subdomains, str): cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3) for subdomain in subdomains: @@ -2125,7 +2120,7 @@ class MatrixMDGXS(MDGXS): filter_bins.append((subdomain,)) # Construct list of energy group bounds tuples for all requested groups - if not isinstance(in_groups, string_types): + if not isinstance(in_groups, str): cv.check_iterable_type('groups', in_groups, Integral) for group in in_groups: filters.append(openmc.EnergyFilter) @@ -2133,7 +2128,7 @@ class MatrixMDGXS(MDGXS): self.energy_groups.get_group_bounds(group),)) # Construct list of energy group bounds tuples for all requested groups - if not isinstance(out_groups, string_types): + if not isinstance(out_groups, str): cv.check_iterable_type('groups', out_groups, Integral) for group in out_groups: filters.append(openmc.EnergyoutFilter) @@ -2141,7 +2136,7 @@ class MatrixMDGXS(MDGXS): self.energy_groups.get_group_bounds(group),)) # Construct list of delayed group tuples for all requested groups - if not isinstance(delayed_groups, string_types): + if not isinstance(delayed_groups, str): cv.check_type('delayed groups', delayed_groups, list, int) for delayed_group in delayed_groups: filters.append(openmc.DelayedGroupFilter) @@ -2312,7 +2307,7 @@ class MatrixMDGXS(MDGXS): """ # Construct a collection of the subdomains to report - if not isinstance(subdomains, string_types): + if not isinstance(subdomains, str): cv.check_iterable_type('subdomains', subdomains, Integral) elif self.domain_type == 'distribcell': subdomains = np.arange(self.num_subdomains, dtype=np.int) @@ -2329,7 +2324,7 @@ class MatrixMDGXS(MDGXS): if nuclides == 'sum': nuclides = ['sum'] else: - cv.check_iterable_type('nuclides', nuclides, string_types) + cv.check_iterable_type('nuclides', nuclides, str) else: nuclides = ['sum'] diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 0c0b15ad9d..949f0fba00 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -1,5 +1,3 @@ -from __future__ import division - from collections import OrderedDict from numbers import Integral import warnings @@ -8,7 +6,6 @@ import copy from abc import ABCMeta import itertools -from six import add_metaclass, string_types import numpy as np import h5py @@ -116,8 +113,7 @@ def _df_column_convert_to_bin(df, current_name, new_name, values_to_bin, df.rename(columns={current_name: new_name}, inplace=True) -@add_metaclass(ABCMeta) -class MGXS(object): +class MGXS(metaclass=ABCMeta): """An abstract multi-group cross section for some energy group structure within some spatial domain. @@ -580,7 +576,7 @@ class MGXS(object): @name.setter def name(self, name): - cv.check_type('name', name, string_types) + cv.check_type('name', name, str) self._name = name @by_nuclide.setter @@ -590,7 +586,7 @@ class MGXS(object): @nuclides.setter def nuclides(self, nuclides): - cv.check_iterable_type('nuclides', nuclides, string_types) + cv.check_iterable_type('nuclides', nuclides, str) self._nuclides = nuclides @estimator.setter @@ -806,7 +802,7 @@ class MGXS(object): """ - cv.check_type('nuclide', nuclide, string_types) + cv.check_type('nuclide', nuclide, str) # Get list of all nuclides in the spatial domain nuclides = self.domain.get_nuclide_densities() @@ -1033,7 +1029,7 @@ class MGXS(object): filter_bins = [] # Construct a collection of the domain filter bins - if not isinstance(subdomains, string_types): + if not isinstance(subdomains, str): cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3) @@ -1044,7 +1040,7 @@ class MGXS(object): filter_bins.append(tuple(subdomain_bins)) # Construct list of energy group bounds tuples for all requested groups - if not isinstance(groups, string_types): + if not isinstance(groups, str): cv.check_iterable_type('groups', groups, Integral) filters.append(openmc.EnergyFilter) energy_bins = [] @@ -1219,7 +1215,7 @@ class MGXS(object): """ # Construct a collection of the subdomain filter bins to average across - if not isinstance(subdomains, string_types): + if not isinstance(subdomains, str): cv.check_iterable_type('subdomains', subdomains, Integral) subdomains = [(subdomain,) for subdomain in subdomains] subdomains = [tuple(subdomains)] @@ -1376,7 +1372,7 @@ class MGXS(object): """ - cv.check_iterable_type('nuclides', nuclides, string_types) + cv.check_iterable_type('nuclides', nuclides, str) cv.check_iterable_type('energy_groups', groups, Integral) # Build lists of filters and filter bins to slice @@ -1530,7 +1526,7 @@ class MGXS(object): """ # Construct a collection of the subdomains to report - if not isinstance(subdomains, string_types): + if not isinstance(subdomains, str): cv.check_iterable_type('subdomains', subdomains, Integral) elif self.domain_type == 'distribcell': subdomains = np.arange(self.num_subdomains, dtype=np.int) @@ -1547,7 +1543,7 @@ class MGXS(object): elif nuclides == 'sum': nuclides = ['sum'] else: - cv.check_iterable_type('nuclides', nuclides, string_types) + cv.check_iterable_type('nuclides', nuclides, str) else: nuclides = ['sum'] @@ -1698,7 +1694,7 @@ class MGXS(object): xs_results = h5py.File(filename, 'w', libver=libver) # Construct a collection of the subdomains to report - if not isinstance(subdomains, string_types): + if not isinstance(subdomains, str): cv.check_iterable_type('subdomains', subdomains, Integral) elif self.domain_type == 'distribcell': subdomains = np.arange(self.num_subdomains, dtype=np.int) @@ -1719,7 +1715,7 @@ class MGXS(object): elif nuclides == 'sum': nuclides = ['sum'] else: - cv.check_iterable_type('nuclides', nuclides, string_types) + cv.check_iterable_type('nuclides', nuclides, str) else: nuclides = ['sum'] @@ -1797,8 +1793,8 @@ class MGXS(object): """ - cv.check_type('filename', filename, string_types) - cv.check_type('directory', directory, string_types) + cv.check_type('filename', filename, str) + cv.check_type('directory', directory, str) cv.check_value('format', format, ['csv', 'excel', 'pickle', 'latex']) cv.check_value('xs_type', xs_type, ['macro', 'micro']) @@ -1884,10 +1880,10 @@ class MGXS(object): """ - if not isinstance(groups, string_types): + if not isinstance(groups, str): cv.check_iterable_type('groups', groups, Integral) if nuclides != 'all' and nuclides != 'sum': - cv.check_iterable_type('nuclides', nuclides, string_types) + cv.check_iterable_type('nuclides', nuclides, str) cv.check_value('xs_type', xs_type, ['macro', 'micro']) # Get a Pandas DataFrame from the derived xs tally @@ -1923,7 +1919,7 @@ class MGXS(object): columns = self._df_convert_columns_to_bins(df) # Select out those groups the user requested - if not isinstance(groups, string_types): + if not isinstance(groups, str): if 'group in' in df: df = df[df['group in'].isin(groups)] if 'group out' in df: @@ -1976,7 +1972,6 @@ class MGXS(object): return 'cm^-1' if xs_type == 'macro' else 'barns' -@add_metaclass(ABCMeta) class MatrixMGXS(MGXS): """An abstract multi-group cross section for some energy group structure within some spatial domain. This class is specifically intended for @@ -2164,7 +2159,7 @@ class MatrixMGXS(MGXS): filter_bins = [] # Construct a collection of the domain filter bins - if not isinstance(subdomains, string_types): + if not isinstance(subdomains, str): cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3) filters.append(_DOMAIN_TO_FILTER[self.domain_type]) @@ -2174,7 +2169,7 @@ class MatrixMGXS(MGXS): filter_bins.append(tuple(subdomain_bins)) # Construct list of energy group bounds tuples for all requested groups - if not isinstance(in_groups, string_types): + if not isinstance(in_groups, str): cv.check_iterable_type('groups', in_groups, Integral) filters.append(openmc.EnergyFilter) for group in in_groups: @@ -2182,7 +2177,7 @@ class MatrixMGXS(MGXS): filter_bins.append(tuple(energy_bins)) # Construct list of energy group bounds tuples for all requested groups - if not isinstance(out_groups, string_types): + if not isinstance(out_groups, str): cv.check_iterable_type('groups', out_groups, Integral) for group in out_groups: filters.append(openmc.EnergyoutFilter) @@ -2342,7 +2337,7 @@ class MatrixMGXS(MGXS): """ # Construct a collection of the subdomains to report - if not isinstance(subdomains, string_types): + if not isinstance(subdomains, str): cv.check_iterable_type('subdomains', subdomains, Integral) elif self.domain_type == 'distribcell': subdomains = np.arange(self.num_subdomains, dtype=np.int) @@ -2359,7 +2354,7 @@ class MatrixMGXS(MGXS): if nuclides == 'sum': nuclides = ['sum'] else: - cv.check_iterable_type('nuclides', nuclides, string_types) + cv.check_iterable_type('nuclides', nuclides, str) else: nuclides = ['sum'] @@ -4307,7 +4302,7 @@ class ScatterMatrixXS(MatrixMGXS): filter_bins = [] # Construct a collection of the domain filter bins - if not isinstance(subdomains, string_types): + if not isinstance(subdomains, str): cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3) filters.append(_DOMAIN_TO_FILTER[self.domain_type]) subdomain_bins = [] @@ -4316,7 +4311,7 @@ class ScatterMatrixXS(MatrixMGXS): filter_bins.append(tuple(subdomain_bins)) # Construct list of energy group bounds tuples for all requested groups - if not isinstance(in_groups, string_types): + if not isinstance(in_groups, str): cv.check_iterable_type('groups', in_groups, Integral) filters.append(openmc.EnergyFilter) energy_bins = [] @@ -4326,7 +4321,7 @@ class ScatterMatrixXS(MatrixMGXS): filter_bins.append(tuple(energy_bins)) # Construct list of energy group bounds tuples for all requested groups - if not isinstance(out_groups, string_types): + if not isinstance(out_groups, str): cv.check_iterable_type('groups', out_groups, Integral) for group in out_groups: filters.append(openmc.EnergyoutFilter) @@ -4539,7 +4534,7 @@ class ScatterMatrixXS(MatrixMGXS): """ # Construct a collection of the subdomains to report - if not isinstance(subdomains, string_types): + if not isinstance(subdomains, str): cv.check_iterable_type('subdomains', subdomains, Integral) elif self.domain_type == 'distribcell': subdomains = np.arange(self.num_subdomains, dtype=np.int) @@ -4556,7 +4551,7 @@ class ScatterMatrixXS(MatrixMGXS): if nuclides == 'sum': nuclides = ['sum'] else: - cv.check_iterable_type('nuclides', nuclides, string_types) + cv.check_iterable_type('nuclides', nuclides, str) else: nuclides = ['sum'] @@ -5582,7 +5577,7 @@ class Chi(MGXS): filter_bins = [] # Construct a collection of the domain filter bins - if not isinstance(subdomains, string_types): + if not isinstance(subdomains, str): cv.check_iterable_type('subdomains', subdomains, Integral, max_depth=3) filters.append(_DOMAIN_TO_FILTER[self.domain_type]) @@ -5592,7 +5587,7 @@ class Chi(MGXS): filter_bins.append(tuple(subdomain_bins)) # Construct list of energy group bounds tuples for all requested groups - if not isinstance(groups, string_types): + if not isinstance(groups, str): cv.check_iterable_type('groups', groups, Integral) filters.append(openmc.EnergyoutFilter) energy_bins = [] @@ -5640,7 +5635,7 @@ class Chi(MGXS): # Get chi for user-specified nuclides in the domain else: - cv.check_iterable_type('nuclides', nuclides, string_types) + cv.check_iterable_type('nuclides', nuclides, str) xs = self.xs_tally.get_values(filters=filters, filter_bins=filter_bins, nuclides=nuclides, value=value) diff --git a/openmc/mgxs_library.py b/openmc/mgxs_library.py index ebfae2fb0d..e315f33140 100644 --- a/openmc/mgxs_library.py +++ b/openmc/mgxs_library.py @@ -2,7 +2,6 @@ import copy from numbers import Real, Integral import os -from six import string_types import numpy as np import h5py from scipy.interpolate import interp1d @@ -381,7 +380,7 @@ class XSdata(object): @name.setter def name(self, name): - check_type('name for XSdata', name, string_types) + check_type('name for XSdata', name, str) self._name = name @energy_groups.setter @@ -2517,7 +2516,7 @@ class MGXSLibrary(object): """ - check_type('filename', filename, string_types) + check_type('filename', filename, str) # Create and write to the HDF5 file file = h5py.File(filename, "w", libver=libver) diff --git a/openmc/model/funcs.py b/openmc/model/funcs.py index 589765d2c8..b5afdf08d1 100644 --- a/openmc/model/funcs.py +++ b/openmc/model/funcs.py @@ -1,4 +1,3 @@ -from __future__ import division from collections import Iterable, OrderedDict from math import sqrt from numbers import Real diff --git a/openmc/model/triso.py b/openmc/model/triso.py index 7258a86f21..0fe138bd70 100644 --- a/openmc/model/triso.py +++ b/openmc/model/triso.py @@ -1,4 +1,3 @@ -from __future__ import division import copy import warnings import itertools @@ -10,7 +9,6 @@ from heapq import heappush, heappop from math import pi, sin, cos, floor, log10, sqrt from abc import ABCMeta, abstractproperty, abstractmethod -from six import add_metaclass import numpy as np import scipy.spatial @@ -92,8 +90,7 @@ class TRISO(openmc.Cell): k_min:k_max+1, j_min:j_max+1, i_min:i_max+1])) -@add_metaclass(ABCMeta) -class _Domain(object): +class _Domain(metaclass=ABCMeta): """Container in which to pack particles. Parameters diff --git a/openmc/nuclide.py b/openmc/nuclide.py index 2e5a8e1193..73247e1aa2 100644 --- a/openmc/nuclide.py +++ b/openmc/nuclide.py @@ -1,7 +1,5 @@ import warnings -from six import string_types - import openmc.checkvalue as cv diff --git a/openmc/plots.py b/openmc/plots.py index a60b2a3094..bfff2d7e90 100644 --- a/openmc/plots.py +++ b/openmc/plots.py @@ -4,7 +4,6 @@ from xml.etree import ElementTree as ET import sys import warnings -from six import string_types import numpy as np import openmc @@ -297,7 +296,7 @@ class Plot(IDManagerMixin): @name.setter def name(self, name): - cv.check_type('plot name', name, string_types) + cv.check_type('plot name', name, str) self._name = name @width.setter @@ -322,7 +321,7 @@ class Plot(IDManagerMixin): @filename.setter def filename(self, filename): - cv.check_type('filename', filename, string_types) + cv.check_type('filename', filename, str) self._filename = filename @color_by.setter @@ -343,7 +342,7 @@ class Plot(IDManagerMixin): @background.setter def background(self, background): cv.check_type('plot background', background, Iterable) - if isinstance(background, string_types): + if isinstance(background, str): if background.lower() not in _SVG_COLORS: raise ValueError("'{}' is not a valid color.".format(background)) else: @@ -359,7 +358,7 @@ class Plot(IDManagerMixin): for key, value in colors.items(): cv.check_type('plot color key', key, (openmc.Cell, openmc.Material)) cv.check_type('plot color value', value, Iterable) - if isinstance(value, string_types): + if isinstance(value, str): if value.lower() not in _SVG_COLORS: raise ValueError("'{}' is not a valid color.".format(value)) else: @@ -380,7 +379,7 @@ class Plot(IDManagerMixin): @mask_background.setter def mask_background(self, mask_background): cv.check_type('plot mask background', mask_background, Iterable) - if isinstance(mask_background, string_types): + if isinstance(mask_background, str): if mask_background.lower() not in _SVG_COLORS: raise ValueError("'{}' is not a valid color.".format(mask_background)) else: @@ -558,7 +557,7 @@ class Plot(IDManagerMixin): cv.check_type('background', background, Iterable) # Get a background (R,G,B) tuple to apply in alpha compositing - if isinstance(background, string_types): + if isinstance(background, str): if background.lower() not in _SVG_COLORS: raise ValueError("'{}' is not a valid color.".format(background)) background = _SVG_COLORS[background.lower()] @@ -570,7 +569,7 @@ class Plot(IDManagerMixin): # other than those the user wishes to highlight for domain, color in self.colors.items(): if domain not in domains: - if isinstance(color, string_types): + if isinstance(color, str): color = _SVG_COLORS[color.lower()] r, g, b = color r = int(((1-alpha) * background[0]) + (alpha * r)) @@ -610,7 +609,7 @@ class Plot(IDManagerMixin): if self._background is not None: subelement = ET.SubElement(element, "background") color = self._background - if isinstance(color, string_types): + if isinstance(color, str): color = _SVG_COLORS[color.lower()] subelement.text = ' '.join(str(x) for x in color) @@ -619,7 +618,7 @@ class Plot(IDManagerMixin): key=lambda x: x[0].id): subelement = ET.SubElement(element, "color") subelement.set("id", str(domain.id)) - if isinstance(color, string_types): + if isinstance(color, str): color = _SVG_COLORS[color.lower()] subelement.set("rgb", ' '.join(str(x) for x in color)) @@ -629,7 +628,7 @@ class Plot(IDManagerMixin): str(d.id) for d in self._mask_components)) color = self._mask_background if color is not None: - if isinstance(color, string_types): + if isinstance(color, str): color = _SVG_COLORS[color.lower()] subelement.set("background", ' '.join( str(x) for x in color)) diff --git a/openmc/plotter.py b/openmc/plotter.py index 810ee5d27c..1bf6fe46fd 100644 --- a/openmc/plotter.py +++ b/openmc/plotter.py @@ -2,7 +2,6 @@ from numbers import Integral, Real from itertools import chain import string -from six import string_types import matplotlib.pyplot as plt import numpy as np @@ -137,7 +136,7 @@ def plot_xs(this, types, divisor_types=None, temperature=294., data_type=None, data_type = 'material' elif isinstance(this, openmc.Macroscopic): data_type = 'macroscopic' - elif isinstance(this, string_types): + elif isinstance(this, str): if this[-1] in string.digits: data_type = 'nuclide' else: @@ -275,7 +274,7 @@ def calculate_cexs(this, data_type, types, temperature=294., sab_name=None, # Check types cv.check_type('temperature', temperature, Real) if sab_name: - cv.check_type('sab_name', sab_name, string_types) + cv.check_type('sab_name', sab_name, str) if enrichment: cv.check_type('enrichment', enrichment, Real) @@ -648,7 +647,7 @@ def calculate_mgxs(this, data_type, types, orders=None, temperature=294., cv.check_type('temperature', temperature, Real) if enrichment: cv.check_type('enrichment', enrichment, Real) - cv.check_iterable_type('types', types, string_types) + cv.check_iterable_type('types', types, str) cv.check_type("cross_sections", cross_sections, str) library = openmc.MGXSLibrary.from_hdf5(cross_sections) diff --git a/openmc/region.py b/openmc/region.py index 54797f5688..c9bd3b5fc0 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -2,14 +2,12 @@ from abc import ABCMeta, abstractmethod from collections import Iterable, OrderedDict, MutableSequence from copy import deepcopy -from six import add_metaclass import numpy as np from openmc.checkvalue import check_type -@add_metaclass(ABCMeta) -class Region(object): +class Region(metaclass=ABCMeta): """Region of space that can be assigned to a cell. Region is an abstract base class that is inherited by diff --git a/openmc/settings.py b/openmc/settings.py index 3c46d0c2c5..1bbc7a4ec3 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -4,7 +4,6 @@ import warnings from xml.etree import ElementTree as ET import sys -from six import string_types import numpy as np from openmc.clean_xml import clean_xml_indentation @@ -459,7 +458,7 @@ class Settings(object): if key in ('summary', 'tallies'): cv.check_type("output['{}']".format(key), value, bool) else: - cv.check_type("output['path']", value, string_types) + cv.check_type("output['path']", value, str) self._output = output @verbosity.setter @@ -511,7 +510,7 @@ class Settings(object): warnings.warn('Settings.cross_sections has been deprecated and will be ' 'removed in a future version. Materials.cross_sections ' 'should defined instead.', DeprecationWarning) - cv.check_type('cross sections', cross_sections, string_types) + cv.check_type('cross sections', cross_sections, str) self._cross_sections = cross_sections @multipole_library.setter @@ -520,7 +519,7 @@ class Settings(object): 'be removed in a future version. ' 'Materials.multipole_library should defined instead.', DeprecationWarning) - cv.check_type('multipole library', multipole_library, string_types) + cv.check_type('multipole library', multipole_library, str) self._multipole_library = multipole_library @ptables.setter @@ -692,7 +691,7 @@ class Settings(object): cv.check_greater_than(name, value, 0) elif key == 'nuclides': cv.check_type('resonance scattering nuclides', value, - Iterable, string_types) + Iterable, str) self._resonance_scattering = res @volume_calculations.setter diff --git a/openmc/source.py b/openmc/source.py index 1aee435147..932062278c 100644 --- a/openmc/source.py +++ b/openmc/source.py @@ -2,8 +2,6 @@ from numbers import Real import sys from xml.etree import ElementTree as ET -from six import string_types - from openmc.stats.univariate import Univariate from openmc.stats.multivariate import UnitSphere, Spatial import openmc.checkvalue as cv @@ -78,7 +76,7 @@ class Source(object): @file.setter def file(self, filename): - cv.check_type('source file', filename, string_types) + cv.check_type('source file', filename, str) self._file = filename @space.setter diff --git a/openmc/stats/multivariate.py b/openmc/stats/multivariate.py index 0ab11b7c54..ba2debaeaf 100644 --- a/openmc/stats/multivariate.py +++ b/openmc/stats/multivariate.py @@ -5,15 +5,13 @@ from numbers import Real import sys from xml.etree import ElementTree as ET -from six import add_metaclass import numpy as np import openmc.checkvalue as cv from openmc.stats.univariate import Univariate, Uniform -@add_metaclass(ABCMeta) -class UnitSphere(object): +class UnitSphere(metaclass=ABCMeta): """Distribution of points on the unit sphere. This abstract class is used for angular distributions, since a direction is @@ -181,8 +179,7 @@ class Monodirectional(UnitSphere): return element -@add_metaclass(ABCMeta) -class Spatial(object): +class Spatial(metaclass=ABCMeta): """Distribution of locations in three-dimensional Euclidean space. Classes derived from this abstract class can be used for spatial diff --git a/openmc/stats/univariate.py b/openmc/stats/univariate.py index 38683e6927..47a281d213 100644 --- a/openmc/stats/univariate.py +++ b/openmc/stats/univariate.py @@ -4,7 +4,6 @@ from numbers import Real import sys from xml.etree import ElementTree as ET -from six import add_metaclass import numpy as np import openmc.checkvalue as cv @@ -15,8 +14,7 @@ _INTERPOLATION_SCHEMES = ['histogram', 'linear-linear', 'linear-log', 'log-linear', 'log-log'] -@add_metaclass(ABCMeta) -class Univariate(EqualityMixin): +class Univariate(EqualityMixin, metaclass=ABCMeta): """Probability distribution of a single random variable. The Univariate class is an abstract class that can be derived to implement a diff --git a/openmc/surface.py b/openmc/surface.py index eb44a4fe8d..694e9fd221 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -1,4 +1,3 @@ -from __future__ import division from abc import ABCMeta from collections import OrderedDict from copy import deepcopy @@ -6,7 +5,6 @@ from functools import partial from numbers import Real, Integral from xml.etree import ElementTree as ET -from six import add_metaclass, string_types import numpy as np from openmc.checkvalue import check_type, check_value @@ -115,14 +113,14 @@ class Surface(IDManagerMixin): @name.setter def name(self, name): if name is not None: - check_type('surface name', name, string_types) + check_type('surface name', name, str) self._name = name else: self._name = '' @boundary_type.setter def boundary_type(self, boundary_type): - check_type('boundary type', boundary_type, string_types) + check_type('boundary type', boundary_type, str) check_value('boundary type', boundary_type, _BOUNDARY_TYPES) self._boundary_type = boundary_type @@ -738,8 +736,7 @@ class ZPlane(Plane): return point[2] - self.z0 -@add_metaclass(ABCMeta) -class Cylinder(Surface): +class Cylinder(Surface, metaclass=ABCMeta): """A cylinder whose length is parallel to the x-, y-, or z-axis. Parameters @@ -1305,8 +1302,7 @@ class Sphere(Surface): return x**2 + y**2 + z**2 - self.r**2 -@add_metaclass(ABCMeta) -class Cone(Surface): +class Cone(Surface, metaclass=ABCMeta): """A conical surface parallel to the x-, y-, or z-axis. Parameters diff --git a/openmc/tallies.py b/openmc/tallies.py index b685dcae39..17c298a8db 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -1,5 +1,3 @@ -from __future__ import division - from collections import Iterable, MutableSequence import copy import re @@ -10,7 +8,6 @@ import operator import warnings from xml.etree import ElementTree as ET -from six import string_types import numpy as np import pandas as pd import scipy.sparse as sps @@ -31,9 +28,8 @@ _PRODUCT_TYPES = ['tensor', 'entrywise'] # The following indicate acceptable types when setting Tally.scores, # Tally.nuclides, and Tally.filters -_SCORE_CLASSES = string_types + (openmc.CrossScore, openmc.AggregateScore) -_NUCLIDE_CLASSES = string_types + (openmc.Nuclide, openmc.CrossNuclide, - openmc.AggregateNuclide) +_SCORE_CLASSES = (str, openmc.CrossScore, openmc.AggregateScore) +_NUCLIDE_CLASSES = (str, openmc.CrossNuclide, openmc.AggregateNuclide) _FILTER_CLASSES = (openmc.Filter, openmc.CrossFilter, openmc.AggregateFilter) # Valid types of estimators @@ -359,7 +355,7 @@ class Tally(IDManagerMixin): @name.setter def name(self, name): if name is not None: - cv.check_type('tally name', name, string_types) + cv.check_type('tally name', name, str) self._name = name else: self._name = '' @@ -412,7 +408,7 @@ class Tally(IDManagerMixin): raise ValueError(msg) # If score is a string, strip whitespace - if isinstance(score, string_types): + if isinstance(score, str): scores[i] = score.strip() self._scores = cv.CheckedList(_SCORE_CLASSES, 'tally scores', scores) @@ -1327,7 +1323,7 @@ class Tally(IDManagerMixin): """ - cv.check_iterable_type('nuclides', nuclides, string_types) + cv.check_iterable_type('nuclides', nuclides, str) # Determine the score indices from any of the requested scores if nuclides: @@ -1362,7 +1358,7 @@ class Tally(IDManagerMixin): """ for score in scores: - if not isinstance(score, string_types + (openmc.CrossScore,)): + if not isinstance(score, (str, openmc.CrossScore)): msg = 'Unable to get score indices for score "{0}" in Tally ' \ 'ID="{1}" since it is not a string or CrossScore'\ .format(score, self.id) @@ -1555,7 +1551,7 @@ class Tally(IDManagerMixin): column_name = 'score' for score in self.scores: - if isinstance(score, string_types + (openmc.CrossScore,)): + if isinstance(score, (str, openmc.CrossScore)): scores.append(str(score)) elif isinstance(score, openmc.AggregateScore): scores.append(score.name) @@ -2192,11 +2188,11 @@ class Tally(IDManagerMixin): raise ValueError(msg) # Check that the scores are valid - if not isinstance(score1, string_types + (openmc.CrossScore,)): + if not isinstance(score1, (str, openmc.CrossScore)): msg = 'Unable to swap score1 "{0}" in Tally ID="{1}" since it is ' \ 'not a string or CrossScore'.format(score1, self.id) raise ValueError(msg) - elif not isinstance(score2, string_types + (openmc.CrossScore,)): + elif not isinstance(score2, (str, openmc.CrossScore)): msg = 'Unable to swap score2 "{0}" in Tally ID="{1}" since it is ' \ 'not a string or CrossScore'.format(score2, self.id) raise ValueError(msg) diff --git a/openmc/tally_derivative.py b/openmc/tally_derivative.py index facc56f447..9be748b2cb 100644 --- a/openmc/tally_derivative.py +++ b/openmc/tally_derivative.py @@ -1,11 +1,7 @@ -from __future__ import division - import sys from numbers import Integral from xml.etree import ElementTree as ET -from six import string_types - import openmc.checkvalue as cv from openmc.mixin import EqualityMixin, IDManagerMixin @@ -81,7 +77,7 @@ class TallyDerivative(EqualityMixin, IDManagerMixin): @variable.setter def variable(self, var): if var is not None: - cv.check_type('derivative variable', var, string_types) + cv.check_type('derivative variable', var, str) cv.check_value('derivative variable', var, ('density', 'nuclide_density', 'temperature')) self._variable = var @@ -95,7 +91,7 @@ class TallyDerivative(EqualityMixin, IDManagerMixin): @nuclide.setter def nuclide(self, nuc): if nuc is not None: - cv.check_type('derivative nuclide', nuc, string_types) + cv.check_type('derivative nuclide', nuc, str) self._nuclide = nuc def to_xml_element(self): diff --git a/openmc/trigger.py b/openmc/trigger.py index 69ec8c6200..a5ac1d1e83 100644 --- a/openmc/trigger.py +++ b/openmc/trigger.py @@ -4,8 +4,6 @@ import sys import warnings from collections import Iterable -from six import string_types - import openmc.checkvalue as cv @@ -76,7 +74,7 @@ class Trigger(object): @scores.setter def scores(self, scores): - cv.check_type('trigger scores', scores, Iterable, string_types) + cv.check_type('trigger scores', scores, Iterable, str) # Set scores making sure not to have duplicates self._scores = [] diff --git a/openmc/universe.py b/openmc/universe.py index 4a0a1a9aac..55f574c536 100644 --- a/openmc/universe.py +++ b/openmc/universe.py @@ -1,11 +1,9 @@ -from __future__ import division from collections import OrderedDict, Iterable from copy import copy, deepcopy from numbers import Integral, Real import random import sys -from six import string_types import matplotlib.pyplot as plt import numpy as np @@ -97,7 +95,7 @@ class Universe(IDManagerMixin): @name.setter def name(self, name): if name is not None: - cv.check_type('universe name', name, string_types) + cv.check_type('universe name', name, str) self._name = name else: self._name = '' @@ -237,7 +235,7 @@ class Universe(IDManagerMixin): # Convert to RGBA if necessary colors = copy(colors) for obj, color in colors.items(): - if isinstance(color, string_types): + if isinstance(color, str): if color.lower() not in _SVG_COLORS: raise ValueError("'{}' is not a valid color." .format(color)) diff --git a/scripts/openmc-ace-to-hdf5 b/scripts/openmc-ace-to-hdf5 index 3235a2da63..29c987e07c 100755 --- a/scripts/openmc-ace-to-hdf5 +++ b/scripts/openmc-ace-to-hdf5 @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import argparse import os diff --git a/scripts/openmc-convert-mcnp70-data b/scripts/openmc-convert-mcnp70-data index 0489b25de4..75b3b0a5a8 100755 --- a/scripts/openmc-convert-mcnp70-data +++ b/scripts/openmc-convert-mcnp70-data @@ -1,6 +1,5 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -from __future__ import print_function import argparse from collections import defaultdict import glob diff --git a/scripts/openmc-convert-mcnp71-data b/scripts/openmc-convert-mcnp71-data index 061f8f46f0..ce8c427d60 100755 --- a/scripts/openmc-convert-mcnp71-data +++ b/scripts/openmc-convert-mcnp71-data @@ -1,6 +1,5 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -from __future__ import print_function import argparse from collections import defaultdict import glob diff --git a/scripts/openmc-get-jeff-data b/scripts/openmc-get-jeff-data index 6d9e086a91..9f426a4930 100755 --- a/scripts/openmc-get-jeff-data +++ b/scripts/openmc-get-jeff-data @@ -1,6 +1,5 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -from __future__ import print_function import os from collections import defaultdict import sys @@ -9,9 +8,7 @@ import zipfile import glob import argparse from string import digits - -from six.moves import input -from six.moves.urllib.request import urlopen +from urllib.request import urlopen import openmc.data diff --git a/scripts/openmc-get-multipole-data b/scripts/openmc-get-multipole-data index bf0add2840..ea25396488 100755 --- a/scripts/openmc-get-multipole-data +++ b/scripts/openmc-get-multipole-data @@ -1,6 +1,5 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -from __future__ import print_function import os import shutil import subprocess @@ -9,9 +8,7 @@ import tarfile import glob import hashlib import argparse - -from six.moves import input -from six.moves.urllib.request import urlopen +from urllib.request import urlopen description = """ diff --git a/scripts/openmc-get-nndc-data b/scripts/openmc-get-nndc-data index e2c1e7ce3a..a04eed6cd6 100755 --- a/scripts/openmc-get-nndc-data +++ b/scripts/openmc-get-nndc-data @@ -1,6 +1,5 @@ #!/usr/bin/env python -from __future__ import print_function import os import shutil import subprocess @@ -9,9 +8,7 @@ import tarfile import glob import hashlib import argparse - -from six.moves import input -from six.moves.urllib.request import urlopen +from urllib.request import urlopen import openmc.data diff --git a/scripts/openmc-plot-mesh-tally b/scripts/openmc-plot-mesh-tally index c273a6d592..0dfb29b9b3 100755 --- a/scripts/openmc-plot-mesh-tally +++ b/scripts/openmc-plot-mesh-tally @@ -1,16 +1,16 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """Python script to plot tally data generated by OpenMC.""" import os import sys import argparse +import tkinter as tk +import tkinter.filedialog as filedialog +import tkinter.font as font +import tkinter.messagebox as messagebox +import tkinter.ttk as ttk -import six.moves.tkinter as tk -import six.moves.tkinter_filedialog as filedialog -import six.moves.tkinter_font as font -import six.moves.tkinter_messagebox as messagebox -import six.moves.tkinter_ttk as ttk from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.backends.backend_tkagg import NavigationToolbar2TkAgg from matplotlib.figure import Figure diff --git a/scripts/openmc-track-to-vtk b/scripts/openmc-track-to-vtk index 1dd632f9dd..fa154a2a7f 100755 --- a/scripts/openmc-track-to-vtk +++ b/scripts/openmc-track-to-vtk @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """Convert HDF5 particle track to VTK poly data. diff --git a/scripts/openmc-update-inputs b/scripts/openmc-update-inputs index 3eb850207e..ef7cdf47bb 100755 --- a/scripts/openmc-update-inputs +++ b/scripts/openmc-update-inputs @@ -1,10 +1,8 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """Update OpenMC's input XML files to the latest format. """ -from __future__ import print_function - import argparse from difflib import get_close_matches from itertools import chain diff --git a/scripts/openmc-update-mgxs b/scripts/openmc-update-mgxs index f33adfc005..8559affb95 100755 --- a/scripts/openmc-update-mgxs +++ b/scripts/openmc-update-mgxs @@ -1,10 +1,9 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """Update OpenMC's deprecated multi-group cross section XML files to the latest HDF5-based format. """ -from __future__ import print_function import os import warnings import xml.etree.ElementTree as ET diff --git a/scripts/openmc-validate-xml b/scripts/openmc-validate-xml index e5a45f4691..f36ba2b5d3 100755 --- a/scripts/openmc-validate-xml +++ b/scripts/openmc-validate-xml @@ -1,6 +1,4 @@ -#!/usr/bin/env python - -from __future__ import print_function +#!/usr/bin/env python3 import os import sys diff --git a/scripts/openmc-voxel-to-silovtk b/scripts/openmc-voxel-to-silovtk index 9748cc3bba..e0cfc0a5ba 100755 --- a/scripts/openmc-voxel-to-silovtk +++ b/scripts/openmc-voxel-to-silovtk @@ -1,6 +1,5 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -from __future__ import division, print_function import struct import sys from argparse import ArgumentParser diff --git a/setup.py b/setup.py index 7bffc516f0..2a42dd65dd 100755 --- a/setup.py +++ b/setup.py @@ -48,11 +48,7 @@ kwargs = { 'License :: OSI Approved :: MIT License', 'Natural Language :: English', 'Topic :: Scientific/Engineering' - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.2', - 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', @@ -60,7 +56,7 @@ kwargs = { # Required dependencies 'install_requires': [ - 'six', 'numpy>=1.9', 'h5py', 'scipy', 'ipython', 'matplotlib', + 'numpy>=1.9', 'h5py', 'scipy', 'ipython', 'matplotlib', 'pandas', 'lxml', 'uncertainties' ], From 1ccf6c3e5e3656cc6a1425425f8dbb30b89eec8e Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sun, 24 Dec 2017 16:18:22 +0700 Subject: [PATCH 64/74] Use tempfile.TemporaryDirectory() --- openmc/data/neutron.py | 9 +-------- openmc/data/njoy.py | 7 +------ openmc/data/thermal.py | 8 +------- 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index 8d59316892..4f02af1a48 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -840,10 +840,7 @@ class IncidentNeutron(EqualityMixin): Incident neutron continuous-energy data """ - # Create temporary directory -- it would be preferable to use - # TemporaryDirectory(), but it is only available in Python 3.2 - tmpdir = tempfile.mkdtemp() - try: + with tempfile.TemporaryDirectory() as tmpdir: # Run NJOY to create an ACE library ace_file = os.path.join(tmpdir, 'ace') xsdir_file = os.path.join(tmpdir, 'xsdir') @@ -871,8 +868,4 @@ class IncidentNeutron(EqualityMixin): data.energy['0K'] = xs.x data[2].xs['0K'] = xs - finally: - # Get rid of temporary files - shutil.rmtree(tmpdir) - return data diff --git a/openmc/data/njoy.py b/openmc/data/njoy.py index be16d96f81..b2894b3d1c 100644 --- a/openmc/data/njoy.py +++ b/openmc/data/njoy.py @@ -149,10 +149,7 @@ def run(commands, tapein, tapeout, input_filename=None, stdout=False, with open(input_filename, 'w') as f: f.write(commands) - # Create temporary directory -- it would be preferable to use - # TemporaryDirectory(), but it is only available in Python 3.2 - tmpdir = tempfile.mkdtemp() - try: + with tempfile.TemporaryDirectory() as tmpdir: # Copy evaluations to appropriates 'tapes' for tape_num, filename in tapein.items(): tmpfilename = os.path.join(tmpdir, 'tape{}'.format(tape_num)) @@ -186,8 +183,6 @@ def run(commands, tapein, tapeout, input_filename=None, stdout=False, tmpfilename = os.path.join(tmpdir, 'tape{}'.format(tape_num)) if os.path.isfile(tmpfilename): shutil.move(tmpfilename, filename) - finally: - shutil.rmtree(tmpdir) def make_pendf(filename, pendf='pendf', error=0.001, stdout=False): diff --git a/openmc/data/thermal.py b/openmc/data/thermal.py index 68192de039..4f89d8e834 100644 --- a/openmc/data/thermal.py +++ b/openmc/data/thermal.py @@ -623,10 +623,7 @@ class ThermalScattering(EqualityMixin): Thermal scattering data """ - # Create temporary directory -- it would be preferable to use - # TemporaryDirectory(), but it is only available in Python 3.2 - tmpdir = tempfile.mkdtemp() - try: + with tempfile.TemporaryDirectory() as tmpdir: # Run NJOY to create an ACE library ace_file = os.path.join(tmpdir, 'ace') xsdir_file = os.path.join(tmpdir, 'xsdir') @@ -638,8 +635,5 @@ class ThermalScattering(EqualityMixin): data = cls.from_ace(lib.tables[0]) for table in lib.tables[1:]: data.add_temperature_from_ace(table) - finally: - # Get rid of temporary files - shutil.rmtree(tmpdir) return data From deab4b3d337ee91b4411089562e6b8824a25ce90 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sun, 24 Dec 2017 16:34:25 +0700 Subject: [PATCH 65/74] Use empty-argument form of super() --- .travis.yml | 3 +- openmc/capi/cell.py | 2 +- openmc/capi/filter.py | 6 +- openmc/capi/nuclide.py | 2 +- openmc/capi/tally.py | 2 +- openmc/checkvalue.py | 6 +- openmc/data/angle_distribution.py | 2 +- openmc/data/correlated.py | 2 +- openmc/data/energy_distribution.py | 18 +++--- openmc/data/kalbach_mann.py | 2 +- openmc/data/laboratory.py | 2 +- openmc/data/resonance.py | 18 +++--- openmc/element.py | 2 +- openmc/filter.py | 9 ++- openmc/lattice.py | 4 +- openmc/macroscopic.py | 2 +- openmc/material.py | 6 +- openmc/mgxs/mdgxs.py | 49 ++++++--------- openmc/mgxs/mgxs.py | 96 +++++++++++++----------------- openmc/model/triso.py | 8 +-- openmc/nuclide.py | 2 +- openmc/plots.py | 6 +- openmc/stats/multivariate.py | 12 ++-- openmc/stats/univariate.py | 12 ++-- openmc/surface.py | 30 +++++----- openmc/tallies.py | 8 +-- 26 files changed, 142 insertions(+), 169 deletions(-) diff --git a/.travis.yml b/.travis.yml index 05e239025e..de83325e03 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,9 @@ sudo: required dist: trusty language: python python: - - "2.7" - "3.4" + - "3.5" + - "3.6" addons: apt: packages: diff --git a/openmc/capi/cell.py b/openmc/capi/cell.py index 0c4b72c749..0cadfd6af4 100644 --- a/openmc/capi/cell.py +++ b/openmc/capi/cell.py @@ -81,7 +81,7 @@ class Cell(_FortranObjectWithID): index = mapping[uid]._index if index not in cls.__instances: - instance = super(Cell, cls).__new__(cls) + instance = super().__new__(cls) instance._index = index if uid is not None: instance.id = uid diff --git a/openmc/capi/filter.py b/openmc/capi/filter.py index 1b52af6db9..74c6828d60 100644 --- a/openmc/capi/filter.py +++ b/openmc/capi/filter.py @@ -87,7 +87,7 @@ class Filter(_FortranObjectWithID): index = mapping[uid]._index if index not in cls.__instances: - instance = super(Filter, cls).__new__(cls) + instance = super().__new__(cls) instance._index = index if uid is not None: instance.id = uid @@ -110,7 +110,7 @@ class EnergyFilter(Filter): filter_type = 'energy' def __init__(self, bins=None, uid=None, new=True, index=None): - super(EnergyFilter, self).__init__(uid, new, index) + super().__init__(uid, new, index) if bins is not None: self.bins = bins @@ -167,7 +167,7 @@ class MaterialFilter(Filter): filter_type = 'material' def __init__(self, bins=None, uid=None, new=True, index=None): - super(MaterialFilter, self).__init__(uid, new, index) + super().__init__(uid, new, index) if bins is not None: self.bins = bins diff --git a/openmc/capi/nuclide.py b/openmc/capi/nuclide.py index e07872e583..54d131498f 100644 --- a/openmc/capi/nuclide.py +++ b/openmc/capi/nuclide.py @@ -58,7 +58,7 @@ class Nuclide(_FortranObject): def __new__(cls, *args): if args not in cls.__instances: - instance = super(Nuclide, cls).__new__(cls) + instance = super().__new__(cls) cls.__instances[args] = instance return cls.__instances[args] diff --git a/openmc/capi/tally.py b/openmc/capi/tally.py index 751f0e6031..aaf709e612 100644 --- a/openmc/capi/tally.py +++ b/openmc/capi/tally.py @@ -172,7 +172,7 @@ class Tally(_FortranObjectWithID): index = mapping[uid]._index if index not in cls.__instances: - instance = super(Tally, cls).__new__(cls) + instance = super().__new__(cls) instance._index = index if uid is not None: instance.id = uid diff --git a/openmc/checkvalue.py b/openmc/checkvalue.py index aa4dc067f9..643ea4820f 100644 --- a/openmc/checkvalue.py +++ b/openmc/checkvalue.py @@ -288,7 +288,7 @@ class CheckedList(list): """ def __init__(self, expected_type, name, items=[]): - super(CheckedList, self).__init__() + super().__init__() self.expected_type = expected_type self.name = name for item in items: @@ -319,7 +319,7 @@ class CheckedList(list): """ check_type(self.name, item, self.expected_type) - super(CheckedList, self).append(item) + super().append(item) def insert(self, index, item): """Insert item before index @@ -333,4 +333,4 @@ class CheckedList(list): """ check_type(self.name, item, self.expected_type) - super(CheckedList, self).insert(index, item) + super().insert(index, item) diff --git a/openmc/data/angle_distribution.py b/openmc/data/angle_distribution.py index ad3ba89193..71e3d2f309 100644 --- a/openmc/data/angle_distribution.py +++ b/openmc/data/angle_distribution.py @@ -34,7 +34,7 @@ class AngleDistribution(EqualityMixin): """ def __init__(self, energy, mu): - super(AngleDistribution, self).__init__() + super().__init__() self.energy = energy self.mu = mu diff --git a/openmc/data/correlated.py b/openmc/data/correlated.py index 49d116efd0..ba69e6aa6c 100644 --- a/openmc/data/correlated.py +++ b/openmc/data/correlated.py @@ -45,7 +45,7 @@ class CorrelatedAngleEnergy(AngleEnergy): """ def __init__(self, breakpoints, interpolation, energy, energy_out, mu): - super(CorrelatedAngleEnergy, self).__init__() + super().__init__() self.breakpoints = breakpoints self.interpolation = interpolation self.energy = energy diff --git a/openmc/data/energy_distribution.py b/openmc/data/energy_distribution.py index e8c92801cf..55588bd648 100644 --- a/openmc/data/energy_distribution.py +++ b/openmc/data/energy_distribution.py @@ -114,7 +114,7 @@ class ArbitraryTabulated(EnergyDistribution): """ def __init__(self, energy, pdf): - super(ArbitraryTabulated, self).__init__() + super().__init__() self.energy = energy self.pdf = pdf @@ -182,7 +182,7 @@ class GeneralEvaporation(EnergyDistribution): """ def __init__(self, theta, g, u): - super(GeneralEvaporation, self).__init__() + super().__init__() self.theta = theta self.g = g self.u = u @@ -245,7 +245,7 @@ class MaxwellEnergy(EnergyDistribution): """ def __init__(self, theta, u): - super(MaxwellEnergy, self).__init__() + super().__init__() self.theta = theta self.u = u @@ -378,7 +378,7 @@ class Evaporation(EnergyDistribution): """ def __init__(self, theta, u): - super(Evaporation, self).__init__() + super().__init__() self.theta = theta self.u = u @@ -514,7 +514,7 @@ class WattEnergy(EnergyDistribution): """ def __init__(self, a, b, u): - super(WattEnergy, self).__init__() + super().__init__() self.a = a self.b = b self.u = u @@ -682,7 +682,7 @@ class MadlandNix(EnergyDistribution): """ def __init__(self, efl, efh, tm): - super(MadlandNix, self).__init__() + super().__init__() self.efl = efl self.efh = efh self.tm = tm @@ -805,7 +805,7 @@ class DiscretePhoton(EnergyDistribution): """ def __init__(self, primary_flag, energy, atomic_weight_ratio): - super(DiscretePhoton, self).__init__() + super().__init__() self.primary_flag = primary_flag self.energy = energy self.atomic_weight_ratio = atomic_weight_ratio @@ -914,7 +914,7 @@ class LevelInelastic(EnergyDistribution): """ def __init__(self, threshold, mass_ratio): - super(LevelInelastic, self).__init__() + super().__init__() self.threshold = threshold self.mass_ratio = mass_ratio @@ -1019,7 +1019,7 @@ class ContinuousTabular(EnergyDistribution): """ def __init__(self, breakpoints, interpolation, energy, energy_out): - super(ContinuousTabular, self).__init__() + super().__init__() self.breakpoints = breakpoints self.interpolation = interpolation self.energy = energy diff --git a/openmc/data/kalbach_mann.py b/openmc/data/kalbach_mann.py index de9809df3a..30a1c01cdc 100644 --- a/openmc/data/kalbach_mann.py +++ b/openmc/data/kalbach_mann.py @@ -53,7 +53,7 @@ class KalbachMann(AngleEnergy): def __init__(self, breakpoints, interpolation, energy, energy_out, precompound, slope): - super(KalbachMann, self).__init__() + super().__init__() self.breakpoints = breakpoints self.interpolation = interpolation self.energy = energy diff --git a/openmc/data/laboratory.py b/openmc/data/laboratory.py index 3c240b88d1..18516d9b87 100644 --- a/openmc/data/laboratory.py +++ b/openmc/data/laboratory.py @@ -44,7 +44,7 @@ class LaboratoryAngleEnergy(AngleEnergy): """ def __init__(self, breakpoints, interpolation, energy, mu, energy_out): - super(LaboratoryAngleEnergy, self).__init__() + super().__init__() self.breakpoints = breakpoints self.interpolation = interpolation self.energy = energy diff --git a/openmc/data/resonance.py b/openmc/data/resonance.py index 8feda92df4..5e7e0c44d7 100644 --- a/openmc/data/resonance.py +++ b/openmc/data/resonance.py @@ -288,8 +288,8 @@ class MultiLevelBreitWigner(ResonanceRange): """ def __init__(self, target_spin, energy_min, energy_max, channel, scattering): - super(MultiLevelBreitWigner, self).__init__( - target_spin, energy_min, energy_max, channel, scattering) + super().__init__(target_spin, energy_min, energy_max, channel, + scattering) self.parameters = None self.q_value = {} self.atomic_weight_ratio = None @@ -490,8 +490,8 @@ class SingleLevelBreitWigner(MultiLevelBreitWigner): """ def __init__(self, target_spin, energy_min, energy_max, channel, scattering): - super(SingleLevelBreitWigner, self).__init__( - target_spin, energy_min, energy_max, channel, scattering) + super().__init__(target_spin, energy_min, energy_max, channel, + scattering) # Set resonance reconstruction function if _reconstruct: @@ -549,8 +549,8 @@ class ReichMoore(ResonanceRange): """ def __init__(self, target_spin, energy_min, energy_max, channel, scattering): - super(ReichMoore, self).__init__( - target_spin, energy_min, energy_max, channel, scattering) + super().__init__(target_spin, energy_min, energy_max, channel, + scattering) self.parameters = None self.angle_distribution = False self.num_l_convergence = 0 @@ -724,8 +724,7 @@ class RMatrixLimited(ResonanceRange): """ def __init__(self, energy_min, energy_max, particle_pairs, spin_groups): - super(RMatrixLimited, self).__init__(0.0, energy_min, energy_max, - None, None) + super().__init__(0.0, energy_min, energy_max, None, None) self.reduced_width = False self.formalism = 3 self.particle_pairs = particle_pairs @@ -931,8 +930,7 @@ class Unresolved(ResonanceRange): """ def __init__(self, target_spin, energy_min, energy_max, scatter): - super(Unresolved, self).__init__( - target_spin, energy_min, energy_max, None, scatter) + super().__init__(target_spin, energy_min, energy_max, None, scatter) self.energies = None self.parameters = None self.add_to_background = False diff --git a/openmc/element.py b/openmc/element.py index 25cb97538c..336d1f028b 100644 --- a/openmc/element.py +++ b/openmc/element.py @@ -29,7 +29,7 @@ class Element(str): def __new__(cls, name): cv.check_type('element name', name, str) cv.check_length('element name', name, 1, 2) - return super(Element, cls).__new__(cls, name) + return super().__new__(cls, name) @property def name(self): diff --git a/openmc/filter.py b/openmc/filter.py index 8f57a80906..8763515f4e 100644 --- a/openmc/filter.py +++ b/openmc/filter.py @@ -64,8 +64,7 @@ class FilterMeta(ABCMeta): namespace[func_name].__doc__ = old_doc # Make the class. - return super(FilterMeta, cls).__new__(cls, name, bases, namespace, - **kwargs) + return super().__new__(cls, name, bases, namespace, **kwargs) class Filter(IDManagerMixin, metaclass=FilterMeta): @@ -672,7 +671,7 @@ class MeshFilter(Filter): def __init__(self, mesh, filter_id=None): self.mesh = mesh - super(MeshFilter, self).__init__(mesh.id, filter_id) + super().__init__(mesh.id, filter_id) @classmethod def from_hdf5(cls, group, **kwargs): @@ -869,7 +868,7 @@ class RealFilter(Filter): # This logic is used when merging tallies with real filters return self.bins[0] >= other.bins[-1] else: - return super(RealFilter, self).__gt__(other) + return super().__gt__(other) @property def num_bins(self): @@ -1127,7 +1126,7 @@ class DistribcellFilter(Filter): def __init__(self, cell, filter_id=None): self._paths = None - super(DistribcellFilter, self).__init__(cell, filter_id) + super().__init__(cell, filter_id) @classmethod def from_hdf5(cls, group, **kwargs): diff --git a/openmc/lattice.py b/openmc/lattice.py index 1bb82f6284..0819a85917 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -489,7 +489,7 @@ class RectLattice(Lattice): """ def __init__(self, lattice_id=None, name=''): - super(RectLattice, self).__init__(lattice_id, name) + super().__init__(lattice_id, name) # Initialize Lattice class attributes self._lower_left = None @@ -820,7 +820,7 @@ class HexLattice(Lattice): """ def __init__(self, lattice_id=None, name=''): - super(HexLattice, self).__init__(lattice_id, name) + super().__init__(lattice_id, name) # Initialize Lattice class attributes self._num_rings = None diff --git a/openmc/macroscopic.py b/openmc/macroscopic.py index f5bd90f3a4..2a5a22752a 100644 --- a/openmc/macroscopic.py +++ b/openmc/macroscopic.py @@ -18,7 +18,7 @@ class Macroscopic(str): def __new__(cls, name): check_type('name', name, str) - return super(Macroscopic, cls).__new__(cls, name) + return super().__new__(cls, name) @property def name(self): diff --git a/openmc/material.py b/openmc/material.py index cb3024447b..a3fa854533 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -885,7 +885,7 @@ class Materials(cv.CheckedList): """ def __init__(self, materials=None): - super(Materials, self).__init__(Material, 'materials collection') + super().__init__(Material, 'materials collection') self._cross_sections = None self._multipole_library = None @@ -954,7 +954,7 @@ class Materials(cv.CheckedList): Material to append """ - super(Materials, self).append(material) + super().append(material) def insert(self, index, material): """Insert material before index @@ -967,7 +967,7 @@ class Materials(cv.CheckedList): Material to insert """ - super(Materials, self).insert(index, material) + super().insert(index, material) def remove_material(self, material): """Remove a material from the file diff --git a/openmc/mgxs/mdgxs.py b/openmc/mgxs/mdgxs.py index 7799183ff7..dfd0d192d9 100644 --- a/openmc/mgxs/mdgxs.py +++ b/openmc/mgxs/mdgxs.py @@ -129,8 +129,8 @@ class MDGXS(MGXS): def __init__(self, domain=None, domain_type=None, energy_groups=None, delayed_groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(MDGXS, self).__init__(domain, domain_type, energy_groups, - by_nuclide, name, num_polar, num_azimuthal) + super().__init__(domain, domain_type, energy_groups, by_nuclide, name, + num_polar, num_azimuthal) self._delayed_groups = None @@ -547,7 +547,7 @@ class MDGXS(MGXS): """ - merged_mdgxs = super(MDGXS, self).merge(other) + merged_mdgxs = super().merge(other) # Merge delayed groups if self.delayed_groups != other.delayed_groups: @@ -577,7 +577,7 @@ class MDGXS(MGXS): """ if self.delayed_groups is None: - super(MDGXS, self).print_xs(subdomains, nuclides, xs_type) + super().print_xs(subdomains, nuclides, xs_type) return # Construct a collection of the subdomains to report @@ -1007,9 +1007,8 @@ class ChiDelayed(MDGXS): def __init__(self, domain=None, domain_type=None, energy_groups=None, delayed_groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(ChiDelayed, self).__init__(domain, domain_type, energy_groups, - delayed_groups, by_nuclide, name, - num_polar, num_azimuthal) + super().__init__(domain, domain_type, energy_groups, delayed_groups, + by_nuclide, name, num_polar, num_azimuthal) self._rxn_type = 'chi-delayed' self._estimator = 'analog' @@ -1055,7 +1054,7 @@ class ChiDelayed(MDGXS): # Compute chi self._xs_tally = self.rxn_rate_tally / delayed_nu_fission_in - super(ChiDelayed, self)._compute_xs() + super()._compute_xs() # Add the coarse energy filter back to the nu-fission tally delayed_nu_fission_in.filters.append(energy_filter) @@ -1127,8 +1126,7 @@ class ChiDelayed(MDGXS): delayed_nu_fission_in.remove_filter(energy_filter) # Call super class method and null out derived tallies - slice_xs = super(ChiDelayed, self).get_slice(nuclides, groups, - delayed_groups) + slice_xs = super().get_slice(nuclides, groups, delayed_groups) slice_xs._rxn_rate_tally = None slice_xs._xs_tally = None @@ -1521,10 +1519,8 @@ class DelayedNuFissionXS(MDGXS): def __init__(self, domain=None, domain_type=None, energy_groups=None, delayed_groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(DelayedNuFissionXS, self).__init__(domain, domain_type, - energy_groups, delayed_groups, - by_nuclide, name, num_polar, - num_azimuthal) + super().__init__(domain, domain_type, energy_groups, delayed_groups, + by_nuclide, name, num_polar, num_azimuthal) self._rxn_type = 'delayed-nu-fission' @@ -1657,9 +1653,8 @@ class Beta(MDGXS): def __init__(self, domain=None, domain_type=None, energy_groups=None, delayed_groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(Beta, self).__init__(domain, domain_type, energy_groups, - delayed_groups, by_nuclide, name, num_polar, - num_azimuthal) + super().__init__(domain, domain_type, energy_groups, delayed_groups, + by_nuclide, name, num_polar, num_azimuthal) self._rxn_type = 'beta' @property @@ -1685,7 +1680,7 @@ class Beta(MDGXS): # Compute beta self._xs_tally = self.rxn_rate_tally / nu_fission - super(Beta, self)._compute_xs() + super()._compute_xs() return self._xs_tally @@ -1841,9 +1836,8 @@ class DecayRate(MDGXS): def __init__(self, domain=None, domain_type=None, energy_groups=None, delayed_groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(DecayRate, self).__init__(domain, domain_type, energy_groups, - delayed_groups, by_nuclide, name, - num_polar, num_azimuthal) + super().__init__(domain, domain_type, energy_groups, delayed_groups, + by_nuclide, name, num_polar, num_azimuthal) self._rxn_type = 'decay-rate' @property @@ -1878,7 +1872,7 @@ class DecayRate(MDGXS): # Compute the decay rate self._xs_tally = self.rxn_rate_tally / delayed_nu_fission - super(DecayRate, self)._compute_xs() + super()._compute_xs() return self._xs_tally @@ -2261,8 +2255,7 @@ class MatrixMDGXS(MDGXS): """ # Call super class method and null out derived tallies - slice_xs = super(MatrixMDGXS, self).get_slice(nuclides, in_groups, - delayed_groups) + slice_xs = super().get_slice(nuclides, in_groups, delayed_groups) slice_xs._rxn_rate_tally = None slice_xs._xs_tally = None @@ -2609,12 +2602,8 @@ class DelayedNuFissionMatrixXS(MatrixMDGXS): def __init__(self, domain=None, domain_type=None, energy_groups=None, delayed_groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(DelayedNuFissionMatrixXS, self).__init__(domain, domain_type, - energy_groups, - delayed_groups, - by_nuclide, name, - num_polar, - num_azimuthal) + super().__init__(domain, domain_type, energy_groups, delayed_groups, + by_nuclide, name, num_polar, num_azimuthal) self._rxn_type = 'delayed-nu-fission' self._hdf5_key = 'delayed-nu-fission matrix' self._estimator = 'analog' diff --git a/openmc/mgxs/mgxs.py b/openmc/mgxs/mgxs.py index 949f0fba00..ecedc8e63a 100644 --- a/openmc/mgxs/mgxs.py +++ b/openmc/mgxs/mgxs.py @@ -2292,7 +2292,7 @@ class MatrixMGXS(MGXS): """ # Call super class method and null out derived tallies - slice_xs = super(MatrixMGXS, self).get_slice(nuclides, in_groups) + slice_xs = super().get_slice(nuclides, in_groups) slice_xs._rxn_rate_tally = None slice_xs._xs_tally = None @@ -2567,9 +2567,8 @@ class TotalXS(MGXS): def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(TotalXS, self).__init__(domain, domain_type, - groups, by_nuclide, name, num_polar, - num_azimuthal) + super().__init__(domain, domain_type, groups, by_nuclide, name, + num_polar, num_azimuthal) self._rxn_type = 'total' @@ -2704,9 +2703,8 @@ class TransportXS(MGXS): def __init__(self, domain=None, domain_type=None, groups=None, nu=False, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(TransportXS, self).__init__(domain, domain_type, - groups, by_nuclide, name, num_polar, - num_azimuthal) + super().__init__(domain, domain_type, groups, by_nuclide, name, + num_polar, num_azimuthal) # Use tracklength estimators for the total MGXS term, and # analog estimators for the transport correction term @@ -2715,7 +2713,7 @@ class TransportXS(MGXS): self.nu = nu def __deepcopy__(self, memo): - clone = super(TransportXS, self).__deepcopy__(memo) + clone = super().__deepcopy__(memo) clone._nu = self.nu return clone @@ -2912,9 +2910,8 @@ class AbsorptionXS(MGXS): def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(AbsorptionXS, self).__init__(domain, domain_type, - groups, by_nuclide, name, num_polar, - num_azimuthal) + super().__init__(domain, domain_type, groups, by_nuclide, name, + num_polar, num_azimuthal) self._rxn_type = 'absorption' @@ -3039,9 +3036,8 @@ class CaptureXS(MGXS): def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(CaptureXS, self).__init__(domain, domain_type, - groups, by_nuclide, name, num_polar, - num_azimuthal) + super().__init__(domain, domain_type, groups, by_nuclide, name, + num_polar, num_azimuthal) self._rxn_type = 'capture' @property @@ -3194,16 +3190,15 @@ class FissionXS(MGXS): def __init__(self, domain=None, domain_type=None, groups=None, nu=False, prompt=False, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(FissionXS, self).__init__(domain, domain_type, - groups, by_nuclide, name, num_polar, - num_azimuthal) + super().__init__(domain, domain_type, groups, by_nuclide, name, + num_polar, num_azimuthal) self._nu = False self._prompt = False self.nu = nu self.prompt = prompt def __deepcopy__(self, memo): - clone = super(FissionXS, self).__deepcopy__(memo) + clone = super().__deepcopy__(memo) clone._nu = self.nu clone._prompt = self.prompt return clone @@ -3362,9 +3357,8 @@ class KappaFissionXS(MGXS): def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(KappaFissionXS, self).__init__(domain, domain_type, - groups, by_nuclide, name, - num_polar, num_azimuthal) + super().__init__(domain, domain_type, groups, by_nuclide, name, + num_polar, num_azimuthal) self._rxn_type = 'kappa-fission' @@ -3495,13 +3489,12 @@ class ScatterXS(MGXS): def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1, nu=False): - super(ScatterXS, self).__init__(domain, domain_type, - groups, by_nuclide, name, - num_polar, num_azimuthal) + super().__init__(domain, domain_type, groups, by_nuclide, name, + num_polar, num_azimuthal) self.nu = nu def __deepcopy__(self, memo): - clone = super(ScatterXS, self).__deepcopy__(memo) + clone = super().__deepcopy__(memo) clone._nu = self.nu return clone @@ -3712,9 +3705,8 @@ class ScatterMatrixXS(MatrixMGXS): def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1, nu=False): - super(ScatterMatrixXS, self).__init__(domain, domain_type, - groups, by_nuclide, name, - num_polar, num_azimuthal) + super().__init__(domain, domain_type, groups, by_nuclide, name, + num_polar, num_azimuthal) self._formulation = 'simple' self._correction = 'P0' self._scatter_format = 'legendre' @@ -3725,7 +3717,7 @@ class ScatterMatrixXS(MatrixMGXS): self.nu = nu def __deepcopy__(self, memo): - clone = super(ScatterMatrixXS, self).__deepcopy__(memo) + clone = super().__deepcopy__(memo) clone._formulation = self.formulation clone._correction = self.correction clone._scatter_format = self.scatter_format @@ -3816,7 +3808,7 @@ class ScatterMatrixXS(MatrixMGXS): @property def tally_keys(self): if self.formulation == 'simple': - return super(ScatterMatrixXS, self).tally_keys + return super().tally_keys else: # Add keys for groupwise scattering cross section tally_keys = ['flux (tracklength)', 'scatter'] @@ -4146,7 +4138,7 @@ class ScatterMatrixXS(MatrixMGXS): [score_prefix + '{}'.format(i) for i in range(self.legendre_order + 1)] - super(ScatterMatrixXS, self).load_from_statepoint(statepoint) + super().load_from_statepoint(statepoint) def get_slice(self, nuclides=[], in_groups=[], out_groups=[], legendre_order='same'): @@ -4186,7 +4178,7 @@ class ScatterMatrixXS(MatrixMGXS): """ # Call super class method and null out derived tallies - slice_xs = super(ScatterMatrixXS, self).get_slice(nuclides, in_groups) + slice_xs = super().get_slice(nuclides, in_groups) slice_xs._rxn_rate_tally = None slice_xs._xs_tally = None @@ -4477,8 +4469,7 @@ class ScatterMatrixXS(MatrixMGXS): """ - df = super(ScatterMatrixXS, self).get_pandas_dataframe( - groups, nuclides, xs_type, paths) + df = super().get_pandas_dataframe(groups, nuclides, xs_type, paths) if self.scatter_format == 'legendre': # Add a moment column to dataframe @@ -4802,9 +4793,8 @@ class MultiplicityMatrixXS(MatrixMGXS): def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(MultiplicityMatrixXS, self).__init__(domain, domain_type, groups, - by_nuclide, name, num_polar, - num_azimuthal) + super().__init__(domain, domain_type, groups, by_nuclide, name, + num_polar, num_azimuthal) self._rxn_type = 'multiplicity matrix' self._estimator = 'analog' self._valid_estimators = ['analog'] @@ -4839,7 +4829,7 @@ class MultiplicityMatrixXS(MatrixMGXS): # Compute the multiplicity self._xs_tally = self.rxn_rate_tally / scatter - super(MultiplicityMatrixXS, self)._compute_xs() + super()._compute_xs() return self._xs_tally @@ -4968,9 +4958,8 @@ class ScatterProbabilityMatrix(MatrixMGXS): def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(ScatterProbabilityMatrix, self).__init__( - domain, domain_type, groups, by_nuclide, - name, num_polar, num_azimuthal) + super().__init__(domain, domain_type, groups, by_nuclide, + name, num_polar, num_azimuthal) self._rxn_type = 'scatter' self._hdf5_key = 'scatter probability matrix' @@ -5012,7 +5001,7 @@ class ScatterProbabilityMatrix(MatrixMGXS): # Compute the group-to-group probabilities self._xs_tally = self.tallies[self.rxn_type] / norm - super(ScatterProbabilityMatrix, self)._compute_xs() + super()._compute_xs() return self._xs_tally @@ -5142,9 +5131,8 @@ class NuFissionMatrixXS(MatrixMGXS): def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1, prompt=False): - super(NuFissionMatrixXS, self).__init__(domain, domain_type, - groups, by_nuclide, name, - num_polar, num_azimuthal) + super().__init__(domain, domain_type, groups, by_nuclide, name, + num_polar, num_azimuthal) if not prompt: self._rxn_type = 'nu-fission' self._hdf5_key = 'nu-fission matrix' @@ -5165,7 +5153,7 @@ class NuFissionMatrixXS(MatrixMGXS): self._prompt = prompt def __deepcopy__(self, memo): - clone = super(NuFissionMatrixXS, self).__deepcopy__(memo) + clone = super().__deepcopy__(memo) clone._prompt = self.prompt return clone @@ -5299,8 +5287,8 @@ class Chi(MGXS): def __init__(self, domain=None, domain_type=None, groups=None, prompt=False, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(Chi, self).__init__(domain, domain_type, groups, by_nuclide, - name, num_polar, num_azimuthal) + super().__init__(domain, domain_type, groups, by_nuclide, name, + num_polar, num_azimuthal) if not prompt: self._rxn_type = 'chi' else: @@ -5310,7 +5298,7 @@ class Chi(MGXS): self.prompt = prompt def __deepcopy__(self, memo): - clone = super(Chi, self).__deepcopy__(memo) + clone = super().__deepcopy__(memo) clone._prompt = self.prompt return clone @@ -5440,7 +5428,7 @@ class Chi(MGXS): nu_fission_in.remove_filter(energy_filter) # Call super class method and null out derived tallies - slice_xs = super(Chi, self).get_slice(nuclides, groups) + slice_xs = super().get_slice(nuclides, groups) slice_xs._rxn_rate_tally = None slice_xs._xs_tally = None @@ -5718,8 +5706,7 @@ class Chi(MGXS): """ # Build the dataframe using the parent class method - df = super(Chi, self).get_pandas_dataframe( - groups, nuclides, xs_type, paths=paths) + df = super().get_pandas_dataframe(groups, nuclides, xs_type, paths=paths) # If user requested micro cross sections, multiply by the atom # densities to cancel out division made by the parent class method @@ -5877,9 +5864,8 @@ class InverseVelocity(MGXS): def __init__(self, domain=None, domain_type=None, groups=None, by_nuclide=False, name='', num_polar=1, num_azimuthal=1): - super(InverseVelocity, self).__init__(domain, domain_type, - groups, by_nuclide, name, - num_polar, num_azimuthal) + super().__init__(domain, domain_type, groups, by_nuclide, name, + num_polar, num_azimuthal) self._rxn_type = 'inverse-velocity' def get_units(self, xs_type='macro'): diff --git a/openmc/model/triso.py b/openmc/model/triso.py index 0fe138bd70..fab2f54cc1 100644 --- a/openmc/model/triso.py +++ b/openmc/model/triso.py @@ -45,7 +45,7 @@ class TRISO(openmc.Cell): def __init__(self, outer_radius, fill, center=(0., 0., 0.)): self._surface = openmc.Sphere(R=outer_radius) - super(TRISO, self).__init__(fill=fill, region=-self._surface) + super().__init__(fill=fill, region=-self._surface) self.center = np.asarray(center) @property @@ -245,7 +245,7 @@ class _CubicDomain(_Domain): """ def __init__(self, length, particle_radius, center=[0., 0., 0.]): - super(_CubicDomain, self).__init__(particle_radius, center) + super().__init__(particle_radius, center) self.length = length @property @@ -324,7 +324,7 @@ class _CylindricalDomain(_Domain): """ def __init__(self, length, radius, particle_radius, center=[0., 0., 0.]): - super(_CylindricalDomain, self).__init__(particle_radius, center) + super().__init__(particle_radius, center) self.length = length self.radius = radius @@ -414,7 +414,7 @@ class _SphericalDomain(_Domain): """ def __init__(self, radius, particle_radius, center=[0., 0., 0.]): - super(_SphericalDomain, self).__init__(particle_radius, center) + super().__init__(particle_radius, center) self.radius = radius @property diff --git a/openmc/nuclide.py b/openmc/nuclide.py index 73247e1aa2..f7c725040f 100644 --- a/openmc/nuclide.py +++ b/openmc/nuclide.py @@ -32,7 +32,7 @@ class Nuclide(str): '"{}" is being renamed as "{}".'.format(orig_name, name) warnings.warn(msg) - return super(Nuclide, cls).__new__(cls, name) + return super().__new__(cls, name) @property def name(self): diff --git a/openmc/plots.py b/openmc/plots.py index bfff2d7e90..44d68d72f2 100644 --- a/openmc/plots.py +++ b/openmc/plots.py @@ -673,7 +673,7 @@ class Plots(cv.CheckedList): """ def __init__(self, plots=None): - super(Plots, self).__init__(Plot, 'plots collection') + super().__init__(Plot, 'plots collection') self._plots_file = ET.Element("plots") if plots is not None: self += plots @@ -704,7 +704,7 @@ class Plots(cv.CheckedList): Plot to append """ - super(Plots, self).append(plot) + super().append(plot) def insert(self, index, plot): """Insert plot before index @@ -717,7 +717,7 @@ class Plots(cv.CheckedList): Plot to insert """ - super(Plots, self).insert(index, plot) + super().insert(index, plot) def remove_plot(self, plot): """Remove a plot from the file. diff --git a/openmc/stats/multivariate.py b/openmc/stats/multivariate.py index ba2debaeaf..1fe883866f 100644 --- a/openmc/stats/multivariate.py +++ b/openmc/stats/multivariate.py @@ -75,7 +75,7 @@ class PolarAzimuthal(UnitSphere): """ def __init__(self, mu=None, phi=None, reference_uvw=[0., 0., 1.]): - super(PolarAzimuthal, self).__init__(reference_uvw) + super().__init__(reference_uvw) if mu is not None: self.mu = mu else: @@ -128,7 +128,7 @@ class Isotropic(UnitSphere): """ def __init__(self): - super(Isotropic, self).__init__() + super().__init__() def to_xml_element(self): """Return XML representation of the isotropic distribution @@ -161,7 +161,7 @@ class Monodirectional(UnitSphere): def __init__(self, reference_uvw=[1., 0., 0.]): - super(Monodirectional, self).__init__(reference_uvw) + super().__init__(reference_uvw) def to_xml_element(self): """Return XML representation of the monodirectional distribution @@ -222,7 +222,7 @@ class CartesianIndependent(Spatial): def __init__(self, x, y, z): - super(CartesianIndependent, self).__init__() + super().__init__() self.x = x self.y = y self.z = z @@ -298,7 +298,7 @@ class Box(Spatial): def __init__(self, lower_left, upper_right, only_fissionable=False): - super(Box, self).__init__() + super().__init__() self.lower_left = lower_left self.upper_right = upper_right self.only_fissionable = only_fissionable @@ -371,7 +371,7 @@ class Point(Spatial): """ def __init__(self, xyz=(0., 0., 0.)): - super(Point, self).__init__() + super().__init__() self.xyz = xyz @property diff --git a/openmc/stats/univariate.py b/openmc/stats/univariate.py index 47a281d213..6996970af1 100644 --- a/openmc/stats/univariate.py +++ b/openmc/stats/univariate.py @@ -57,7 +57,7 @@ class Discrete(Univariate): """ def __init__(self, x, p): - super(Discrete, self).__init__() + super().__init__() self.x = x self.p = p @@ -131,7 +131,7 @@ class Uniform(Univariate): """ def __init__(self, a=0.0, b=1.0): - super(Uniform, self).__init__() + super().__init__() self.a = a self.b = b @@ -202,7 +202,7 @@ class Maxwell(Univariate): """ def __init__(self, theta): - super(Maxwell, self).__init__() + super().__init__() self.theta = theta def __len__(self): @@ -262,7 +262,7 @@ class Watt(Univariate): """ def __init__(self, a=0.988e6, b=2.249e-6): - super(Watt, self).__init__() + super().__init__() self.a = a self.b = b @@ -342,7 +342,7 @@ class Tabular(Univariate): def __init__(self, x, p, interpolation='linear-linear', ignore_negative=False): - super(Tabular, self).__init__() + super().__init__() self._ignore_negative = ignore_negative self.x = x self.p = p @@ -470,7 +470,7 @@ class Mixture(Univariate): """ def __init__(self, probability, distribution): - super(Mixture, self).__init__() + super().__init__() self.probability = probability self.distribution = distribution diff --git a/openmc/surface.py b/openmc/surface.py index 694e9fd221..ad5053e370 100644 --- a/openmc/surface.py +++ b/openmc/surface.py @@ -326,7 +326,7 @@ class Plane(Surface): def __init__(self, surface_id=None, boundary_type='transmission', A=1., B=0., C=0., D=0., name=''): - super(Plane, self).__init__(surface_id, boundary_type, name=name) + super().__init__(surface_id, boundary_type, name=name) self._type = 'plane' self._coeff_keys = ['A', 'B', 'C', 'D'] @@ -410,7 +410,7 @@ class Plane(Surface): XML element containing source data """ - element = super(Plane, self).to_xml_element() + element = super().to_xml_element() # Add periodic surface pair information if self.boundary_type == 'periodic': @@ -460,7 +460,7 @@ class XPlane(Plane): def __init__(self, surface_id=None, boundary_type='transmission', x0=0., name=''): - super(XPlane, self).__init__(surface_id, boundary_type, name=name) + super().__init__(surface_id, boundary_type, name=name) self._type = 'x-plane' self._coeff_keys = ['x0'] @@ -566,7 +566,7 @@ class YPlane(Plane): def __init__(self, surface_id=None, boundary_type='transmission', y0=0., name=''): # Initialize YPlane class attributes - super(YPlane, self).__init__(surface_id, boundary_type, name=name) + super().__init__(surface_id, boundary_type, name=name) self._type = 'y-plane' self._coeff_keys = ['y0'] @@ -672,7 +672,7 @@ class ZPlane(Plane): def __init__(self, surface_id=None, boundary_type='transmission', z0=0., name=''): # Initialize ZPlane class attributes - super(ZPlane, self).__init__(surface_id, boundary_type, name=name) + super().__init__(surface_id, boundary_type, name=name) self._type = 'z-plane' self._coeff_keys = ['z0'] @@ -773,7 +773,7 @@ class Cylinder(Surface, metaclass=ABCMeta): """ def __init__(self, surface_id=None, boundary_type='transmission', R=1., name=''): - super(Cylinder, self).__init__(surface_id, boundary_type, name=name) + super().__init__(surface_id, boundary_type, name=name) self._coeff_keys = ['R'] self.r = R @@ -833,7 +833,7 @@ class XCylinder(Cylinder): def __init__(self, surface_id=None, boundary_type='transmission', y0=0., z0=0., R=1., name=''): - super(XCylinder, self).__init__(surface_id, boundary_type, R, name=name) + super().__init__(surface_id, boundary_type, R, name=name) self._type = 'x-cylinder' self._coeff_keys = ['y0', 'z0', 'R'] @@ -955,7 +955,7 @@ class YCylinder(Cylinder): def __init__(self, surface_id=None, boundary_type='transmission', x0=0., z0=0., R=1., name=''): - super(YCylinder, self).__init__(surface_id, boundary_type, R, name=name) + super().__init__(surface_id, boundary_type, R, name=name) self._type = 'y-cylinder' self._coeff_keys = ['x0', 'z0', 'R'] @@ -1077,7 +1077,7 @@ class ZCylinder(Cylinder): def __init__(self, surface_id=None, boundary_type='transmission', x0=0., y0=0., R=1., name=''): - super(ZCylinder, self).__init__(surface_id, boundary_type, R, name=name) + super().__init__(surface_id, boundary_type, R, name=name) self._type = 'z-cylinder' self._coeff_keys = ['x0', 'y0', 'R'] @@ -1203,7 +1203,7 @@ class Sphere(Surface): def __init__(self, surface_id=None, boundary_type='transmission', x0=0., y0=0., z0=0., R=1., name=''): - super(Sphere, self).__init__(surface_id, boundary_type, name=name) + super().__init__(surface_id, boundary_type, name=name) self._type = 'sphere' self._coeff_keys = ['x0', 'y0', 'z0', 'R'] @@ -1350,7 +1350,7 @@ class Cone(Surface, metaclass=ABCMeta): """ def __init__(self, surface_id=None, boundary_type='transmission', x0=0., y0=0., z0=0., R2=1., name=''): - super(Cone, self).__init__(surface_id, boundary_type, name=name) + super().__init__(surface_id, boundary_type, name=name) self._coeff_keys = ['x0', 'y0', 'z0', 'R2'] self.x0 = x0 @@ -1445,7 +1445,7 @@ class XCone(Cone): def __init__(self, surface_id=None, boundary_type='transmission', x0=0., y0=0., z0=0., R2=1., name=''): - super(XCone, self).__init__(surface_id, boundary_type, x0, y0, + super().__init__(surface_id, boundary_type, x0, y0, z0, R2, name=name) self._type = 'x-cone' @@ -1521,7 +1521,7 @@ class YCone(Cone): def __init__(self, surface_id=None, boundary_type='transmission', x0=0., y0=0., z0=0., R2=1., name=''): - super(YCone, self).__init__(surface_id, boundary_type, x0, y0, z0, + super().__init__(surface_id, boundary_type, x0, y0, z0, R2, name=name) self._type = 'y-cone' @@ -1597,7 +1597,7 @@ class ZCone(Cone): def __init__(self, surface_id=None, boundary_type='transmission', x0=0., y0=0., z0=0., R2=1., name=''): - super(ZCone, self).__init__(surface_id, boundary_type, x0, y0, z0, + super().__init__(surface_id, boundary_type, x0, y0, z0, R2, name=name) self._type = 'z-cone' @@ -1662,7 +1662,7 @@ class Quadric(Surface): def __init__(self, surface_id=None, boundary_type='transmission', a=0., b=0., c=0., d=0., e=0., f=0., g=0., h=0., j=0., k=0., name=''): - super(Quadric, self).__init__(surface_id, boundary_type, name=name) + super().__init__(surface_id, boundary_type, name=name) self._type = 'quadric' self._coeff_keys = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k'] diff --git a/openmc/tallies.py b/openmc/tallies.py index 17c298a8db..e838de6655 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -3242,7 +3242,7 @@ class Tallies(cv.CheckedList): """ def __init__(self, tallies=None): - super(Tallies, self).__init__(Tally, 'tallies collection') + super().__init__(Tally, 'tallies collection') if tallies is not None: self += tallies @@ -3299,10 +3299,10 @@ class Tallies(cv.CheckedList): # If no mergeable tally was found, simply add this tally if not merged: - super(Tallies, self).append(tally) + super().append(tally) else: - super(Tallies, self).append(tally) + super().append(tally) def insert(self, index, item): """Insert tally before index @@ -3315,7 +3315,7 @@ class Tallies(cv.CheckedList): Tally to insert """ - super(Tallies, self).insert(index, item) + super().insert(index, item) def remove_tally(self, tally): """Remove a tally from the collection From 7263d80c2c231ac35325ebb7bae35569589c10a1 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Sun, 24 Dec 2017 16:36:59 +0700 Subject: [PATCH 66/74] Update installation instructions --- docs/source/usersguide/install.rst | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/docs/source/usersguide/install.rst b/docs/source/usersguide/install.rst index 638d425014..9b11d1dce4 100644 --- a/docs/source/usersguide/install.rst +++ b/docs/source/usersguide/install.rst @@ -385,8 +385,7 @@ Python package in the same location as the ``openmc`` executable (for example, if you are installing the package into a `virtual environment `_). The easiest way to install the :mod:`openmc` Python package is to use pip_, which is included by default in -Python 2.7 and Python 3.4+. From the root directory of the OpenMC -distribution/repository, run: +Python 3.4+. From the root directory of the OpenMC distribution/repository, run: .. code-block:: sh @@ -414,18 +413,14 @@ to install the Python package in :ref:`"editable" mode `. Prerequisites ------------- -The Python API works with either Python 2.7 or Python 3.2+. In addition to -Python itself, the API relies on a number of third-party packages. All -prerequisites can be installed using Conda_ (recommended), pip_, or through the -package manager in most Linux distributions. +The Python API works with Python 3.4+. In addition to Python itself, the API +relies on a number of third-party packages. All prerequisites can be installed +using Conda_ (recommended), pip_, or through the package manager in most Linux +distributions. .. admonition:: Required :class: error - `six `_ - The Python API works with both Python 2.7+ and 3.2+. To do so, the six - compatibility library is used. - `NumPy `_ NumPy is used extensively within the Python API for its powerful N-dimensional array. From 0aee52c5ab8ad077e20542a832a6aaccf34f48e1 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 29 Dec 2017 14:03:11 -0600 Subject: [PATCH 67/74] Remove deprecated methods --- openmc/cell.py | 44 ------ openmc/material.py | 52 ------- openmc/plots.py | 34 ----- openmc/settings.py | 49 ------- openmc/tallies.py | 167 ---------------------- openmc/trigger.py | 17 --- tests/regression_tests/diff_tally/test.py | 36 ++--- 7 files changed, 13 insertions(+), 386 deletions(-) diff --git a/openmc/cell.py b/openmc/cell.py index 087f2816d4..838d419b62 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -283,50 +283,6 @@ class Cell(IDManagerMixin): cv.check_type('cell volume', volume, Real) self._volume = volume - def add_surface(self, surface, halfspace): - """Add a half-space to the list of half-spaces whose intersection defines the - cell. - - .. deprecated:: 0.7.1 - Use the :attr:`Cell.region` property to directly specify a Region - expression. - - Parameters - ---------- - surface : openmc.Surface - Quadric surface dividing space - halfspace : {-1, 1} - Indicate whether the negative or positive half-space is to be used - - """ - - warnings.warn("Cell.add_surface(...) has been deprecated and may be " - "removed in a future version. The region for a Cell " - "should be defined using the region property directly.", - DeprecationWarning) - - if not isinstance(surface, openmc.Surface): - msg = 'Unable to add Surface "{0}" to Cell ID="{1}" since it is ' \ - 'not a Surface object'.format(surface, self._id) - raise ValueError(msg) - - if halfspace not in [-1, +1]: - msg = 'Unable to add Surface "{0}" to Cell ID="{1}" with halfspace ' \ - '"{2}" since it is not +/-1'.format(surface, self._id, halfspace) - raise ValueError(msg) - - # If no region has been assigned, simply use the half-space. Otherwise, - # take the intersection of the current region and the half-space - # specified - region = +surface if halfspace == 1 else -surface - if self.region is None: - self.region = region - else: - if isinstance(self.region, Intersection): - self.region &= region - else: - self.region = Intersection(self.region, region) - def add_volume_information(self, volume_calc): """Add volume information to a cell. diff --git a/openmc/material.py b/openmc/material.py index a3fa854533..e409d6536c 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -910,41 +910,6 @@ class Materials(cv.CheckedList): cv.check_type('cross sections', multipole_library, str) self._multipole_library = multipole_library - def add_material(self, material): - """Append material to collection - - .. deprecated:: 0.8 - Use :meth:`Materials.append` instead. - - Parameters - ---------- - material : openmc.Material - Material to add - - """ - warnings.warn("Materials.add_material(...) has been deprecated and may be " - "removed in a future version. Use Material.append(...) " - "instead.", DeprecationWarning) - self.append(material) - - def add_materials(self, materials): - """Add multiple materials to the collection - - .. deprecated:: 0.8 - Use compound assignment instead. - - Parameters - ---------- - materials : Iterable of openmc.Material - Materials to add - - """ - warnings.warn("Materials.add_materials(...) has been deprecated and may be " - "removed in a future version. Use compound assignment " - "instead.", DeprecationWarning) - for material in materials: - self.append(material) - def append(self, material): """Append material to collection @@ -969,23 +934,6 @@ class Materials(cv.CheckedList): """ super().insert(index, material) - def remove_material(self, material): - """Remove a material from the file - - .. deprecated:: 0.8 - Use :meth:`Materials.remove` instead. - - Parameters - ---------- - material : openmc.Material - Material to remove - - """ - warnings.warn("Materials.remove_material(...) has been deprecated and " - "may be removed in a future version. Use " - "Materials.remove(...) instead.", DeprecationWarning) - self.remove(material) - def make_isotropic_in_lab(self): for material in self: material.make_isotropic_in_lab() diff --git a/openmc/plots.py b/openmc/plots.py index 44d68d72f2..159e920780 100644 --- a/openmc/plots.py +++ b/openmc/plots.py @@ -678,23 +678,6 @@ class Plots(cv.CheckedList): if plots is not None: self += plots - def add_plot(self, plot): - """Add a plot to the file. - - .. deprecated:: 0.8 - Use :meth:`Plots.append` instead. - - Parameters - ---------- - plot : openmc.Plot - Plot to add - - """ - warnings.warn("Plots.add_plot(...) has been deprecated and may be " - "removed in a future version. Use Plots.append(...) " - "instead.", DeprecationWarning) - self.append(plot) - def append(self, plot): """Append plot to collection @@ -719,23 +702,6 @@ class Plots(cv.CheckedList): """ super().insert(index, plot) - def remove_plot(self, plot): - """Remove a plot from the file. - - .. deprecated:: 0.8 - Use :meth:`Plots.remove` instead. - - Parameters - ---------- - plot : openmc.Plot - Plot to remove - - """ - warnings.warn("Plots.remove_plot(...) has been deprecated and may be " - "removed in a future version. Use Plots.remove(...) " - "instead.", DeprecationWarning) - self.remove(plot) - def colorize(self, geometry, seed=1): """Generate a consistent color scheme for each domain in each plot. diff --git a/openmc/settings.py b/openmc/settings.py index 1bbc7a4ec3..b9562b7ddc 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -28,13 +28,6 @@ class Settings(object): deviation. create_fission_neutrons : bool Indicate whether fission neutrons should be created or not. - cross_sections : str - Indicates the path to an XML cross section listing file (usually named - cross_sections.xml). If it is not set, the - :envvar:`OPENMC_CROSS_SECTIONS` environment variable will be used for - continuous-energy calculations and - :envvar:`OPENMC_MG_CROSS_SECTIONS` will be used for multi-group - calculations to find the path to the XML cross section file. cutoff : dict Dictionary defining weight cutoff and energy cutoff. The dictionary may have three keys, 'weight', 'weight_avg' and 'energy'. Value for 'weight' @@ -63,11 +56,6 @@ class Settings(object): Number of bins for logarithmic energy grid search max_order : None or int Maximum scattering order to apply globally when in multi-group mode. - multipole_library : str - Indicates the path to a directory containing a windowed multipole - cross section library. If it is not set, the - :envvar:`OPENMC_MULTIPOLE_LIBRARY` environment variable will be used. A - multipole library is optional. no_reduce : bool Indicate that all user-defined and global tallies should not be reduced across processes in a parallel calculation. @@ -268,14 +256,6 @@ class Settings(object): def confidence_intervals(self): return self._confidence_intervals - @property - def cross_sections(self): - return self._cross_sections - - @property - def multipole_library(self): - return self._multipole_library - @property def ptables(self): return self._ptables @@ -505,23 +485,6 @@ class Settings(object): cv.check_type('confidence interval', confidence_intervals, bool) self._confidence_intervals = confidence_intervals - @cross_sections.setter - def cross_sections(self, cross_sections): - warnings.warn('Settings.cross_sections has been deprecated and will be ' - 'removed in a future version. Materials.cross_sections ' - 'should defined instead.', DeprecationWarning) - cv.check_type('cross sections', cross_sections, str) - self._cross_sections = cross_sections - - @multipole_library.setter - def multipole_library(self, multipole_library): - warnings.warn('Settings.multipole_library has been deprecated and will ' - 'be removed in a future version. ' - 'Materials.multipole_library should defined instead.', - DeprecationWarning) - cv.check_type('multipole library', multipole_library, str) - self._multipole_library = multipole_library - @ptables.setter def ptables(self, ptables): cv.check_type('probability tables', ptables, bool) @@ -814,16 +777,6 @@ class Settings(object): element = ET.SubElement(root, "confidence_intervals") element.text = str(self._confidence_intervals).lower() - def _create_cross_sections_subelement(self, root): - if self._cross_sections is not None: - element = ET.SubElement(root, "cross_sections") - element.text = str(self._cross_sections) - - def _create_multipole_library_subelement(self, root): - if self._multipole_library is not None: - element = ET.SubElement(root, "multipole_library") - element.text = str(self._multipole_library) - def _create_ptables_subelement(self, root): if self._ptables is not None: element = ET.SubElement(root, "ptables") @@ -988,8 +941,6 @@ class Settings(object): self._create_statepoint_subelement(root_element) self._create_sourcepoint_subelement(root_element) self._create_confidence_intervals(root_element) - self._create_cross_sections_subelement(root_element) - self._create_multipole_library_subelement(root_element) self._create_energy_mode_subelement(root_element) self._create_max_order_subelement(root_element) self._create_ptables_subelement(root_element) diff --git a/openmc/tallies.py b/openmc/tallies.py index e838de6655..61be38fb2a 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -332,26 +332,6 @@ class Tally(IDManagerMixin): self._triggers = cv.CheckedList(openmc.Trigger, 'tally triggers', triggers) - def add_trigger(self, trigger): - """Add a tally trigger to the tally - - .. deprecated:: 0.8 - Use the Tally.triggers property directly, i.e., - Tally.triggers.append(...) - - Parameters - ---------- - trigger : openmc.Trigger - Trigger to add - - """ - - warnings.warn('Tally.add_trigger(...) has been deprecated and may be ' - 'removed in a future version. Tally triggers should be ' - 'defined using the triggers property directly.', - DeprecationWarning) - self.triggers.append(trigger) - @name.setter def name(self, name): if name is not None: @@ -413,80 +393,6 @@ class Tally(IDManagerMixin): self._scores = cv.CheckedList(_SCORE_CLASSES, 'tally scores', scores) - def add_filter(self, new_filter): - """Add a filter to the tally - - .. deprecated:: 0.8 - Use the Tally.filters property directly, i.e., - Tally.filters.append(...) - - Parameters - ---------- - new_filter : Filter, CrossFilter or AggregateFilter - A filter to specify a discretization of the tally across some - dimension (e.g., 'energy', 'cell'). The filter should be a Filter - object when a user is adding filters to a Tally for input file - generation or when the Tally is created from a StatePoint. The - filter may be a CrossFilter or AggregateFilter for derived tallies - created by tally arithmetic. - - """ - - warnings.warn('Tally.add_filter(...) has been deprecated and may be ' - 'removed in a future version. Tally filters should be ' - 'defined using the filters property directly.', - DeprecationWarning) - self.filters.append(new_filter) - - def add_nuclide(self, nuclide): - """Specify that scores for a particular nuclide should be accumulated - - .. deprecated:: 0.8 - Use the Tally.nuclides property directly, i.e., - Tally.nuclides.append(...) - - Parameters - ---------- - nuclide : str, openmc.Nuclide, CrossNuclide or AggregateNuclide - Nuclide to add to the tally. The nuclide should be a Nuclide object - when a user is adding nuclides to a Tally for input file generation. - The nuclide is a str when a Tally is created from a StatePoint file - (e.g., 'H1', 'U235') unless a Summary has been linked with the - StatePoint. The nuclide may be a CrossNuclide or AggregateNuclide - for derived tallies created by tally arithmetic. - - """ - - warnings.warn('Tally.add_nuclide(...) has been deprecated and may be ' - 'removed in a future version. Tally nuclides should be ' - 'defined using the nuclides property directly.', - DeprecationWarning) - self.nuclides.append(nuclide) - - def add_score(self, score): - """Specify a quantity to be scored - - .. deprecated:: 0.8 - Use the Tally.scores property directly, i.e., - Tally.scores.append(...) - - Parameters - ---------- - score : str, CrossScore or AggregateScore - A score to be accumulated (e.g., 'flux', 'nu-fission'). The score - should be a str when a user is adding scores to a Tally for input - file generation or when the Tally is created from a StatePoint. The - score may be a CrossScore or AggregateScore for derived tallies - created by tally arithmetic. - - """ - - warnings.warn('Tally.add_score(...) has been deprecated and may be ' - 'removed in a future version. Tally scores should be ' - 'defined using the scores property directly.', - DeprecationWarning) - self.scores.append(score) - @num_realizations.setter def num_realizations(self, num_realizations): cv.check_type('number of realizations', num_realizations, Integral) @@ -3246,26 +3152,6 @@ class Tallies(cv.CheckedList): if tallies is not None: self += tallies - def add_tally(self, tally, merge=False): - """Append tally to collection - - .. deprecated:: 0.8 - Use :meth:`Tallies.append` instead. - - Parameters - ---------- - tally : openmc.Tally - Tally to add - merge : bool - Indicate whether the tally should be merged with an existing tally, - if possible. Defaults to False. - - """ - warnings.warn("Tallies.add_tally(...) has been deprecated and may be " - "removed in a future version. Use Tallies.append(...) " - "instead.", DeprecationWarning) - self.append(tally, merge) - def append(self, tally, merge=False): """Append tally to collection @@ -3317,24 +3203,6 @@ class Tallies(cv.CheckedList): """ super().insert(index, item) - def remove_tally(self, tally): - """Remove a tally from the collection - - .. deprecated:: 0.8 - Use :meth:`Tallies.remove` instead. - - Parameters - ---------- - tally : openmc.Tally - Tally to remove - - """ - warnings.warn("Tallies.remove_tally(...) has been deprecated and may " - "be removed in a future version. Use Tallies.remove(...) " - "instead.", DeprecationWarning) - - self.remove(tally) - def merge_tallies(self): """Merge any mergeable tallies together. Note that n-way merges are possible. @@ -3359,41 +3227,6 @@ class Tallies(cv.CheckedList): # Continue iterating from the first loop break - def add_mesh(self, mesh): - """Add a mesh to the file - - .. deprecated:: 0.8 - Meshes that appear in a tally are automatically added to the - collection. - - Parameters - ---------- - mesh : openmc.Mesh - Mesh to add to the file - - """ - - warnings.warn("Tallies.add_mesh(...) has been deprecated and may be " - "removed in a future version. Meshes that appear in a " - "tally are automatically added to the collection.", - DeprecationWarning) - - def remove_mesh(self, mesh): - """Remove a mesh from the file - - .. deprecated:: 0.8 - Meshes do not need to be managed explicitly. - - Parameters - ---------- - mesh : openmc.Mesh - Mesh to remove from the file - - """ - warnings.warn("Tallies.remove_mesh(...) has been deprecated and may be " - "removed in a future version. Meshes do not need to be " - "managed explicitly.", DeprecationWarning) - def _create_tally_subelements(self, root_element): for tally in self: root_element.append(tally.to_xml_element()) diff --git a/openmc/trigger.py b/openmc/trigger.py index a5ac1d1e83..c6a0c0b25d 100644 --- a/openmc/trigger.py +++ b/openmc/trigger.py @@ -82,23 +82,6 @@ class Trigger(object): if score not in self._scores: self._scores.append(score) - - def add_score(self, score): - """Add a score to the list of scores to be checked against the trigger. - - Parameters - ---------- - score : str - Score to append - - """ - - warnings.warn('Trigger.add_score(...) has been deprecated and may be ' - 'removed in a future version. Tally trigger scores should ' - 'be defined using the scores property directly.', - DeprecationWarning) - self.scores.append(score) - def get_trigger_xml(self, element): """Return XML representation of the trigger diff --git a/tests/regression_tests/diff_tally/test.py b/tests/regression_tests/diff_tally/test.py index e383b726e8..c106e810fc 100644 --- a/tests/regression_tests/diff_tally/test.py +++ b/tests/regression_tests/diff_tally/test.py @@ -55,30 +55,25 @@ class DiffTallyTestHarness(PyAPITestHarness): # Cover the flux score. for i in range(5): t = openmc.Tally() - t.add_score('flux') - t.add_filter(filt_mats) + t.scores = ['flux'] + t.filters = [filt_mats] t.derivative = derivs[i] self._model.tallies.append(t) # Cover supported scores with a collision estimator. for i in range(5): t = openmc.Tally() - t.add_score('total') - t.add_score('absorption') - t.add_score('scatter') - t.add_score('fission') - t.add_score('nu-fission') - t.add_filter(filt_mats) - t.add_nuclide('total') - t.add_nuclide('U235') + t.scores = ['total', 'absorption', 'scatter', 'fission', 'nu-fission'] + t.filters = [filt_mats] + t.nuclides = ['total', 'U235'] t.derivative = derivs[i] self._model.tallies.append(t) # Cover an analog estimator. for i in range(5): t = openmc.Tally() - t.add_score('absorption') - t.add_filter(filt_mats) + t.scores = ['absorption'] + t.filters = [filt_mats] t.estimator = 'analog' t.derivative = derivs[i] self._model.tallies.append(t) @@ -86,23 +81,18 @@ class DiffTallyTestHarness(PyAPITestHarness): # Energyout filter and total nuclide for the density derivatives. for i in range(2): t = openmc.Tally() - t.add_score('nu-fission') - t.add_score('scatter') - t.add_filter(filt_mats) - t.add_filter(filt_eout) - t.add_nuclide('total') - t.add_nuclide('U235') + t.scores = ['nu-fission', 'scatter'] + t.filters = [filt_mats, filt_eout] + t.nuclides = ['total', 'U235'] t.derivative = derivs[i] self._model.tallies.append(t) # Energyout filter without total nuclide for other derivatives. for i in range(2, 5): t = openmc.Tally() - t.add_score('nu-fission') - t.add_score('scatter') - t.add_filter(filt_mats) - t.add_filter(filt_eout) - t.add_nuclide('U235') + t.scores = ['nu-fission', 'scatter'] + t.filters = [filt_mats, filt_eout] + t.nuclides = ['U235'] t.derivative = derivs[i] self._model.tallies.append(t) From d3d6dc87dcb0323290a835877c91af795652f954 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Fri, 2 Feb 2018 10:06:45 -0600 Subject: [PATCH 68/74] Remove a few more __future__ imports. Use collections.abc --- openmc/capi/cell.py | 2 +- openmc/capi/filter.py | 2 +- openmc/capi/material.py | 2 +- openmc/capi/nuclide.py | 2 +- openmc/capi/tally.py | 2 +- openmc/cell.py | 3 ++- openmc/checkvalue.py | 2 +- openmc/cmfd.py | 2 +- openmc/data/angle_distribution.py | 2 +- openmc/data/correlated.py | 2 +- openmc/data/decay.py | 3 ++- openmc/data/endf.py | 3 ++- openmc/data/energy_distribution.py | 2 +- openmc/data/fission_energy.py | 2 +- openmc/data/function.py | 2 +- openmc/data/kalbach_mann.py | 2 +- openmc/data/laboratory.py | 2 +- openmc/data/neutron.py | 3 ++- openmc/data/product.py | 2 +- openmc/data/reaction.py | 2 +- openmc/data/resonance.py | 3 ++- openmc/data/thermal.py | 2 +- openmc/data/urr.py | 2 +- openmc/executor.py | 2 +- openmc/geometry.py | 3 ++- openmc/lattice.py | 3 ++- openmc/mgxs/library.py | 3 ++- openmc/mgxs/mdgxs.py | 3 ++- openmc/model/funcs.py | 3 ++- openmc/model/model.py | 2 +- openmc/model/triso.py | 3 ++- openmc/plots.py | 2 +- openmc/region.py | 3 ++- openmc/search.py | 2 +- openmc/settings.py | 2 +- openmc/stats/multivariate.py | 2 +- openmc/stats/univariate.py | 2 +- openmc/summary.py | 2 +- openmc/tallies.py | 2 +- openmc/trigger.py | 2 +- openmc/volume.py | 3 ++- tests/check_source.py | 4 +--- tests/regression_tests/tally_slice_merge/test.py | 2 -- tests/testing_harness.py | 2 -- 44 files changed, 55 insertions(+), 48 deletions(-) diff --git a/openmc/capi/cell.py b/openmc/capi/cell.py index 0cadfd6af4..3c14aae528 100644 --- a/openmc/capi/cell.py +++ b/openmc/capi/cell.py @@ -1,4 +1,4 @@ -from collections import Mapping, Iterable +from collections.abc import Mapping, Iterable from ctypes import c_int, c_int32, c_double, c_char_p, POINTER from weakref import WeakValueDictionary diff --git a/openmc/capi/filter.py b/openmc/capi/filter.py index 74c6828d60..ac78c0a341 100644 --- a/openmc/capi/filter.py +++ b/openmc/capi/filter.py @@ -1,4 +1,4 @@ -from collections import Mapping +from collections.abc import Mapping from ctypes import c_int, c_int32, c_double, c_char_p, POINTER, \ create_string_buffer from weakref import WeakValueDictionary diff --git a/openmc/capi/material.py b/openmc/capi/material.py index af0e9893e4..8a55c27173 100644 --- a/openmc/capi/material.py +++ b/openmc/capi/material.py @@ -1,4 +1,4 @@ -from collections import Mapping +from collections.abc import Mapping from ctypes import c_int, c_int32, c_double, c_char_p, POINTER from weakref import WeakValueDictionary diff --git a/openmc/capi/nuclide.py b/openmc/capi/nuclide.py index 54d131498f..f66212c971 100644 --- a/openmc/capi/nuclide.py +++ b/openmc/capi/nuclide.py @@ -1,4 +1,4 @@ -from collections import Mapping +from collections.abc import Mapping from ctypes import c_int, c_char_p, POINTER from weakref import WeakValueDictionary diff --git a/openmc/capi/tally.py b/openmc/capi/tally.py index aaf709e612..f50a19001d 100644 --- a/openmc/capi/tally.py +++ b/openmc/capi/tally.py @@ -1,4 +1,4 @@ -from collections import Mapping +from collections.abc import Mapping from ctypes import c_int, c_int32, c_double, c_char_p, POINTER from weakref import WeakValueDictionary diff --git a/openmc/cell.py b/openmc/cell.py index 838d419b62..c7587e136a 100644 --- a/openmc/cell.py +++ b/openmc/cell.py @@ -1,4 +1,5 @@ -from collections import OrderedDict, Iterable +from collections import OrderedDict +from collections.abc import Iterable from copy import deepcopy from math import cos, sin, pi from numbers import Real, Integral diff --git a/openmc/checkvalue.py b/openmc/checkvalue.py index 643ea4820f..dd32aa566c 100644 --- a/openmc/checkvalue.py +++ b/openmc/checkvalue.py @@ -1,5 +1,5 @@ import copy -from collections import Iterable +from collections.abc import Iterable import numpy as np diff --git a/openmc/cmfd.py b/openmc/cmfd.py index 236491923d..5444334b20 100644 --- a/openmc/cmfd.py +++ b/openmc/cmfd.py @@ -10,7 +10,7 @@ References """ -from collections import Iterable +from collections.abc import Iterable from numbers import Real, Integral from xml.etree import ElementTree as ET import sys diff --git a/openmc/data/angle_distribution.py b/openmc/data/angle_distribution.py index 71e3d2f309..a1f498ba61 100644 --- a/openmc/data/angle_distribution.py +++ b/openmc/data/angle_distribution.py @@ -1,4 +1,4 @@ -from collections import Iterable +from collections.abc import Iterable from io import StringIO from numbers import Real from warnings import warn diff --git a/openmc/data/correlated.py b/openmc/data/correlated.py index ba69e6aa6c..8cc4509cea 100644 --- a/openmc/data/correlated.py +++ b/openmc/data/correlated.py @@ -1,4 +1,4 @@ -from collections import Iterable +from collections.abc import Iterable from numbers import Real, Integral from warnings import warn diff --git a/openmc/data/decay.py b/openmc/data/decay.py index 3d365b6c70..d83338d028 100644 --- a/openmc/data/decay.py +++ b/openmc/data/decay.py @@ -1,4 +1,5 @@ -from collections import Iterable, namedtuple +from collections import namedtuple +from collections.abc import Iterable from io import StringIO from math import log from numbers import Real diff --git a/openmc/data/endf.py b/openmc/data/endf.py index 882874b590..160ab61513 100644 --- a/openmc/data/endf.py +++ b/openmc/data/endf.py @@ -10,7 +10,8 @@ import io import re import os from math import pi -from collections import OrderedDict, Iterable +from collections import OrderedDict +from collections.abc import Iterable import numpy as np from numpy.polynomial.polynomial import Polynomial diff --git a/openmc/data/energy_distribution.py b/openmc/data/energy_distribution.py index 55588bd648..9e01a4b302 100644 --- a/openmc/data/energy_distribution.py +++ b/openmc/data/energy_distribution.py @@ -1,5 +1,5 @@ from abc import ABCMeta, abstractmethod -from collections import Iterable +from collections.abc import Iterable from numbers import Integral, Real from warnings import warn diff --git a/openmc/data/fission_energy.py b/openmc/data/fission_energy.py index a7cf3dfed3..c602ba2c6f 100644 --- a/openmc/data/fission_energy.py +++ b/openmc/data/fission_energy.py @@ -1,4 +1,4 @@ -from collections import Callable +from collections.abc import Callable from copy import deepcopy from io import StringIO import sys diff --git a/openmc/data/function.py b/openmc/data/function.py index 2d3a8ce9c1..3d09e44fc8 100644 --- a/openmc/data/function.py +++ b/openmc/data/function.py @@ -1,5 +1,5 @@ from abc import ABCMeta, abstractmethod -from collections import Iterable, Callable +from collections.abc import Iterable, Callable from numbers import Real, Integral import numpy as np diff --git a/openmc/data/kalbach_mann.py b/openmc/data/kalbach_mann.py index 30a1c01cdc..4be0c15d52 100644 --- a/openmc/data/kalbach_mann.py +++ b/openmc/data/kalbach_mann.py @@ -1,4 +1,4 @@ -from collections import Iterable +from collections.abc import Iterable from numbers import Real, Integral from warnings import warn diff --git a/openmc/data/laboratory.py b/openmc/data/laboratory.py index 18516d9b87..cfedb292b1 100644 --- a/openmc/data/laboratory.py +++ b/openmc/data/laboratory.py @@ -1,4 +1,4 @@ -from collections import Iterable +from collections.abc import Iterable from numbers import Real, Integral import numpy as np diff --git a/openmc/data/neutron.py b/openmc/data/neutron.py index 4f02af1a48..0aa1fe7d83 100644 --- a/openmc/data/neutron.py +++ b/openmc/data/neutron.py @@ -1,5 +1,6 @@ import sys -from collections import OrderedDict, Iterable, Mapping, MutableMapping +from collections import OrderedDict +from collections.abc import Iterable, Mapping, MutableMapping from io import StringIO from itertools import chain from math import log10 diff --git a/openmc/data/product.py b/openmc/data/product.py index b7d89ba0ea..5b8652d771 100644 --- a/openmc/data/product.py +++ b/openmc/data/product.py @@ -1,4 +1,4 @@ -from collections import Iterable +from collections.abc import Iterable from io import StringIO from numbers import Real import sys diff --git a/openmc/data/reaction.py b/openmc/data/reaction.py index 737885f357..d3df038f55 100644 --- a/openmc/data/reaction.py +++ b/openmc/data/reaction.py @@ -1,4 +1,4 @@ -from collections import Iterable, Callable, MutableMapping +from collections.abc import Iterable, Callable, MutableMapping from copy import deepcopy from numbers import Real, Integral from warnings import warn diff --git a/openmc/data/resonance.py b/openmc/data/resonance.py index 5e7e0c44d7..d58f706eb9 100644 --- a/openmc/data/resonance.py +++ b/openmc/data/resonance.py @@ -1,4 +1,5 @@ -from collections import defaultdict, MutableSequence, Iterable +from collections import defaultdict +from collections.abc import MutableSequence, Iterable import io import numpy as np diff --git a/openmc/data/thermal.py b/openmc/data/thermal.py index 4f89d8e834..a036a2680c 100644 --- a/openmc/data/thermal.py +++ b/openmc/data/thermal.py @@ -1,4 +1,4 @@ -from collections import Iterable +from collections.abc import Iterable from difflib import get_close_matches from numbers import Real import itertools diff --git a/openmc/data/urr.py b/openmc/data/urr.py index 1f915974b1..0edccf6f06 100644 --- a/openmc/data/urr.py +++ b/openmc/data/urr.py @@ -1,4 +1,4 @@ -from collections import Iterable +from collections.abc import Iterable from numbers import Integral, Real import numpy as np diff --git a/openmc/executor.py b/openmc/executor.py index e3768f4c61..8ad2bd8960 100644 --- a/openmc/executor.py +++ b/openmc/executor.py @@ -1,4 +1,4 @@ -from collections import Iterable +from collections.abc import Iterable import subprocess from numbers import Integral diff --git a/openmc/geometry.py b/openmc/geometry.py index 7e14272698..1ee93dfd6d 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -1,4 +1,5 @@ -from collections import OrderedDict, Iterable +from collections import OrderedDict +from collections.abc import Iterable from copy import deepcopy from xml.etree import ElementTree as ET diff --git a/openmc/lattice.py b/openmc/lattice.py index 0819a85917..2f7fcf56df 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -1,5 +1,6 @@ from abc import ABCMeta -from collections import OrderedDict, Iterable +from collections import OrderedDict +from collections.abc import Iterable from copy import deepcopy from math import sqrt, floor from numbers import Real, Integral diff --git a/openmc/mgxs/library.py b/openmc/mgxs/library.py index c8b151e024..9add7004bb 100644 --- a/openmc/mgxs/library.py +++ b/openmc/mgxs/library.py @@ -3,7 +3,8 @@ import os import copy import pickle from numbers import Integral -from collections import OrderedDict, Iterable +from collections import OrderedDict +from collections.abc import Iterable from warnings import warn import numpy as np diff --git a/openmc/mgxs/mdgxs.py b/openmc/mgxs/mdgxs.py index dfd0d192d9..2d278d62d7 100644 --- a/openmc/mgxs/mdgxs.py +++ b/openmc/mgxs/mdgxs.py @@ -1,4 +1,5 @@ -from collections import Iterable, OrderedDict +from collections import OrderedDict +from collections.abc import Iterable import itertools from numbers import Integral import warnings diff --git a/openmc/model/funcs.py b/openmc/model/funcs.py index b5afdf08d1..6013f6caee 100644 --- a/openmc/model/funcs.py +++ b/openmc/model/funcs.py @@ -1,4 +1,5 @@ -from collections import Iterable, OrderedDict +from collections import OrderedDict +from collections.abc import Iterable from math import sqrt from numbers import Real diff --git a/openmc/model/model.py b/openmc/model/model.py index 17de6fc2e6..89fa84e604 100644 --- a/openmc/model/model.py +++ b/openmc/model/model.py @@ -1,4 +1,4 @@ -from collections import Iterable +from collections.abc import Iterable import openmc from openmc.checkvalue import check_type diff --git a/openmc/model/triso.py b/openmc/model/triso.py index fab2f54cc1..2786216f77 100644 --- a/openmc/model/triso.py +++ b/openmc/model/triso.py @@ -2,7 +2,8 @@ import copy import warnings import itertools import random -from collections import Iterable, defaultdict +from collections import defaultdict +from collections.abc import Iterable from numbers import Real from random import uniform, gauss from heapq import heappush, heappop diff --git a/openmc/plots.py b/openmc/plots.py index 159e920780..4414a39e13 100644 --- a/openmc/plots.py +++ b/openmc/plots.py @@ -1,4 +1,4 @@ -from collections import Iterable, Mapping +from collections.abc import Iterable, Mapping from numbers import Real, Integral from xml.etree import ElementTree as ET import sys diff --git a/openmc/region.py b/openmc/region.py index c9bd3b5fc0..f82db8553b 100644 --- a/openmc/region.py +++ b/openmc/region.py @@ -1,5 +1,6 @@ from abc import ABCMeta, abstractmethod -from collections import Iterable, OrderedDict, MutableSequence +from collections import OrderedDict +from collections.abc import Iterable, MutableSequence from copy import deepcopy import numpy as np diff --git a/openmc/search.py b/openmc/search.py index 7f91438fd7..75935097e4 100644 --- a/openmc/search.py +++ b/openmc/search.py @@ -1,4 +1,4 @@ -from collections import Callable +from collections.abc import Callable from numbers import Real import scipy.optimize as sopt diff --git a/openmc/settings.py b/openmc/settings.py index b9562b7ddc..62cfc27aaa 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -1,4 +1,4 @@ -from collections import Iterable, MutableSequence, Mapping +from collections.abc import Iterable, MutableSequence, Mapping from numbers import Real, Integral import warnings from xml.etree import ElementTree as ET diff --git a/openmc/stats/multivariate.py b/openmc/stats/multivariate.py index 1fe883866f..ac788c3443 100644 --- a/openmc/stats/multivariate.py +++ b/openmc/stats/multivariate.py @@ -1,5 +1,5 @@ from abc import ABCMeta, abstractmethod -from collections import Iterable +from collections.abc import Iterable from math import pi from numbers import Real import sys diff --git a/openmc/stats/univariate.py b/openmc/stats/univariate.py index 6996970af1..16a9dbb9e7 100644 --- a/openmc/stats/univariate.py +++ b/openmc/stats/univariate.py @@ -1,5 +1,5 @@ from abc import ABCMeta, abstractmethod -from collections import Iterable +from collections.abc import Iterable from numbers import Real import sys from xml.etree import ElementTree as ET diff --git a/openmc/summary.py b/openmc/summary.py index 34743757b4..aa98025c08 100644 --- a/openmc/summary.py +++ b/openmc/summary.py @@ -1,4 +1,4 @@ -from collections import Iterable +from collections.abc import Iterable import re import warnings diff --git a/openmc/tallies.py b/openmc/tallies.py index 61be38fb2a..d22cfdcb46 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -1,4 +1,4 @@ -from collections import Iterable, MutableSequence +from collections.abc import Iterable, MutableSequence import copy import re from functools import partial, reduce diff --git a/openmc/trigger.py b/openmc/trigger.py index c6a0c0b25d..71f9c0b92b 100644 --- a/openmc/trigger.py +++ b/openmc/trigger.py @@ -2,7 +2,7 @@ from numbers import Real from xml.etree import ElementTree as ET import sys import warnings -from collections import Iterable +from collections.abc import Iterable import openmc.checkvalue as cv diff --git a/openmc/volume.py b/openmc/volume.py index cccb3c6a27..d61093a178 100644 --- a/openmc/volume.py +++ b/openmc/volume.py @@ -1,4 +1,5 @@ -from collections import Iterable, Mapping, OrderedDict +from collections import OrderedDict +from collections.abc import Iterable, Mapping from numbers import Real, Integral from xml.etree import ElementTree as ET import warnings diff --git a/tests/check_source.py b/tests/check_source.py index 3a79d44c28..78cef2a0cd 100755 --- a/tests/check_source.py +++ b/tests/check_source.py @@ -1,6 +1,4 @@ -#!/usr/bin/env python - -from __future__ import print_function +#!/usr/bin/env python3 import glob from string import whitespace diff --git a/tests/regression_tests/tally_slice_merge/test.py b/tests/regression_tests/tally_slice_merge/test.py index c198411f7d..ff35c177f5 100644 --- a/tests/regression_tests/tally_slice_merge/test.py +++ b/tests/regression_tests/tally_slice_merge/test.py @@ -1,5 +1,3 @@ -from __future__ import division - import hashlib import itertools diff --git a/tests/testing_harness.py b/tests/testing_harness.py index 55a5660f1c..6c9e25b457 100644 --- a/tests/testing_harness.py +++ b/tests/testing_harness.py @@ -1,5 +1,3 @@ -from __future__ import print_function - from difflib import unified_diff import filecmp import glob From 19ddb532bc3ae5a801e4a689010799b762539fcc Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 6 Feb 2018 06:53:43 -0500 Subject: [PATCH 69/74] Remove check for Python 2.7 in travis-install --- tools/ci/travis-install.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tools/ci/travis-install.sh b/tools/ci/travis-install.sh index 58bcfb789d..3efadd6f36 100755 --- a/tools/ci/travis-install.sh +++ b/tools/ci/travis-install.sh @@ -10,11 +10,6 @@ pip install numpy cython # pytest installed by default -- make sure we get latest pip install --upgrade pytest -# IPython stopped supporting Python 2.7 with version 6 -if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then - pip install "ipython<6" -fi - # Pandas stopped supporting Python 3.4 with version 0.21 if [[ "$TRAVIS_PYTHON_VERSION" == "3.4" ]]; then pip install pandas==0.20.3 From b053e054156cfbd314e515db2b1bdab53263575c Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 6 Feb 2018 07:25:21 -0500 Subject: [PATCH 70/74] Remove try/except for importing unittest.mock --- docs/source/conf.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index b97ff782d9..db44e34f4d 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -18,10 +18,7 @@ on_rtd = os.environ.get('READTHEDOCS', None) == 'True' # On Read the Docs, we need to mock a few third-party modules so we don't get # ImportErrors when building documentation -try: - from unittest.mock import MagicMock -except ImportError: - from mock import Mock as MagicMock +from unittest.mock import MagicMock MOCK_MODULES = ['numpy', 'numpy.polynomial', 'numpy.polynomial.polynomial', @@ -254,6 +251,6 @@ napoleon_use_ivar = True intersphinx_mapping = { 'python': ('https://docs.python.org/3', None), 'numpy': ('https://docs.scipy.org/doc/numpy/', None), - 'pandas': ('http://pandas.pydata.org/pandas-docs/stable/', None), + 'pandas': ('https://pandas.pydata.org/pandas-docs/stable/', None), 'matplotlib': ('https://matplotlib.org/', None) } From cba083103c27df2924efc5a9c70073b0963d1d0d Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 6 Feb 2018 07:29:39 -0500 Subject: [PATCH 71/74] Use default argument of max() in capi bindings --- openmc/capi/cell.py | 5 +---- openmc/capi/filter.py | 5 +---- openmc/capi/material.py | 5 +---- openmc/capi/tally.py | 5 +---- 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/openmc/capi/cell.py b/openmc/capi/cell.py index 3c14aae528..0ab3f2583e 100644 --- a/openmc/capi/cell.py +++ b/openmc/capi/cell.py @@ -65,10 +65,7 @@ class Cell(_FortranObjectWithID): if new: # Determine ID to assign if uid is None: - try: - uid = max(mapping) + 1 - except ValueError: - uid = 1 + uid = max(mapping, default=0) + 1 else: if uid in mapping: raise AllocationError('A cell with ID={} has already ' diff --git a/openmc/capi/filter.py b/openmc/capi/filter.py index ac78c0a341..79c19a6248 100644 --- a/openmc/capi/filter.py +++ b/openmc/capi/filter.py @@ -66,10 +66,7 @@ class Filter(_FortranObjectWithID): if new: # Determine ID to assign if uid is None: - try: - uid = max(mapping) + 1 - except ValueError: - uid = 1 + uid = max(mapping, default=0) + 1 else: if uid in mapping: raise AllocationError('A filter with ID={} has already ' diff --git a/openmc/capi/material.py b/openmc/capi/material.py index 8a55c27173..62d6df012a 100644 --- a/openmc/capi/material.py +++ b/openmc/capi/material.py @@ -78,10 +78,7 @@ class Material(_FortranObjectWithID): if new: # Determine ID to assign if uid is None: - try: - uid = max(mapping) + 1 - except ValueError: - uid = 1 + uid = max(mapping, default=0) + 1 else: if uid in mapping: raise AllocationError('A material with ID={} has already ' diff --git a/openmc/capi/tally.py b/openmc/capi/tally.py index f50a19001d..a78347177d 100644 --- a/openmc/capi/tally.py +++ b/openmc/capi/tally.py @@ -155,10 +155,7 @@ class Tally(_FortranObjectWithID): if new: # Determine ID to assign if uid is None: - try: - uid = max(mapping) + 1 - except ValueError: - uid = 1 + uid = max(mapping, default=0) + 1 else: if uid in mapping: raise AllocationError('A tally with ID={} has already ' From 59861c9507142d0d2f2120c96cbcec19f82b9cf8 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 6 Feb 2018 07:35:45 -0500 Subject: [PATCH 72/74] No need to call int(floor(...)) in Python 3 --- openmc/lattice.py | 12 ++++++------ openmc/model/triso.py | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/openmc/lattice.py b/openmc/lattice.py index 2f7fcf56df..86cfd5c41b 100644 --- a/openmc/lattice.py +++ b/openmc/lattice.py @@ -604,12 +604,12 @@ class RectLattice(Lattice): element coordinate system """ - ix = int(floor((point[0] - self.lower_left[0])/self.pitch[0])) - iy = int(floor((point[1] - self.lower_left[1])/self.pitch[1])) + ix = floor((point[0] - self.lower_left[0])/self.pitch[0]) + iy = floor((point[1] - self.lower_left[1])/self.pitch[1]) if self.ndim == 2: idx = (ix, iy) else: - iz = int(floor((point[2] - self.lower_left[2])/self.pitch[2])) + iz = floor((point[2] - self.lower_left[2])/self.pitch[2]) idx = (ix, iy, iz) return idx, self.get_local_coordinates(point, idx) @@ -1016,10 +1016,10 @@ class HexLattice(Lattice): iz = 1 else: z = point[2] - self.center[2] - iz = int(floor(z/self.pitch[1] + 0.5*self.num_axial)) + iz = floor(z/self.pitch[1] + 0.5*self.num_axial) alpha = y - x/sqrt(3.) - ix = int(floor(x/(sqrt(0.75) * self.pitch[0]))) - ia = int(floor(alpha/self.pitch[0])) + ix = floor(x/(sqrt(0.75) * self.pitch[0])) + ia = floor(alpha/self.pitch[0]) # Check four lattice elements to see which one is closest based on local # coordinates diff --git a/openmc/model/triso.py b/openmc/model/triso.py index 2786216f77..5fe51b6644 100644 --- a/openmc/model/triso.py +++ b/openmc/model/triso.py @@ -736,7 +736,7 @@ def _close_random_pack(domain, particles, contraction_rate): outer_pf = (4/3 * pi * (outer_diameter[0]/2)**3 * n_particles / domain.volume) - j = int(floor(-log10(outer_pf - inner_pf))) + j = floor(-log10(outer_pf - inner_pf)) outer_diameter[0] = (outer_diameter[0] - 0.5**j * contraction_rate * initial_outer_diameter / n_particles) From b7c63be018c765092377a463b3fd25cc559d8d92 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 6 Feb 2018 13:14:17 -0500 Subject: [PATCH 73/74] Use super() in Python classes in tests package --- tests/regression_tests/asymmetric_lattice/test.py | 2 +- tests/regression_tests/diff_tally/test.py | 2 +- tests/regression_tests/distribmat/test.py | 2 +- tests/regression_tests/filter_distribcell/test.py | 2 +- tests/regression_tests/filter_energyfun/test.py | 2 +- tests/regression_tests/filter_mesh/test.py | 2 +- tests/regression_tests/mg_convert/test.py | 2 +- tests/regression_tests/mgxs_library_ce_to_mg/test.py | 4 ++-- tests/regression_tests/mgxs_library_condense/test.py | 2 +- .../regression_tests/mgxs_library_distribcell/test.py | 2 +- tests/regression_tests/mgxs_library_hdf5/test.py | 4 ++-- tests/regression_tests/mgxs_library_mesh/test.py | 2 +- .../regression_tests/mgxs_library_no_nuclides/test.py | 2 +- tests/regression_tests/mgxs_library_nuclides/test.py | 2 +- tests/regression_tests/multipole/test.py | 4 ++-- tests/regression_tests/plot/test.py | 4 ++-- tests/regression_tests/statepoint_batch/test.py | 2 +- tests/regression_tests/statepoint_restart/test.py | 2 +- tests/regression_tests/tally_aggregation/test.py | 2 +- tests/regression_tests/tally_arithmetic/test.py | 2 +- tests/regression_tests/tally_slice_merge/test.py | 2 +- tests/testing_harness.py | 10 +++++----- 22 files changed, 30 insertions(+), 30 deletions(-) diff --git a/tests/regression_tests/asymmetric_lattice/test.py b/tests/regression_tests/asymmetric_lattice/test.py index 0318d7b922..d6a0ab9b73 100644 --- a/tests/regression_tests/asymmetric_lattice/test.py +++ b/tests/regression_tests/asymmetric_lattice/test.py @@ -9,7 +9,7 @@ from tests.testing_harness import PyAPITestHarness class AsymmetricLatticeTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): - super(AsymmetricLatticeTestHarness, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Extract universes encapsulating fuel and water assemblies geometry = self._model.geometry diff --git a/tests/regression_tests/diff_tally/test.py b/tests/regression_tests/diff_tally/test.py index c106e810fc..bd6792414b 100644 --- a/tests/regression_tests/diff_tally/test.py +++ b/tests/regression_tests/diff_tally/test.py @@ -9,7 +9,7 @@ from tests.testing_harness import PyAPITestHarness class DiffTallyTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): - super(DiffTallyTestHarness, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Set settings explicitly self._model.settings.batches = 3 diff --git a/tests/regression_tests/distribmat/test.py b/tests/regression_tests/distribmat/test.py index 69bb7a67b1..de1b778772 100644 --- a/tests/regression_tests/distribmat/test.py +++ b/tests/regression_tests/distribmat/test.py @@ -93,7 +93,7 @@ class DistribmatTestHarness(PyAPITestHarness): plots.export_to_xml() def _get_results(self): - outstr = super(DistribmatTestHarness, self)._get_results() + outstr = super()._get_results() su = openmc.Summary('summary.h5') outstr += str(su.geometry.get_all_cells()[11]) return outstr diff --git a/tests/regression_tests/filter_distribcell/test.py b/tests/regression_tests/filter_distribcell/test.py index bdd134bf57..028c6a7790 100644 --- a/tests/regression_tests/filter_distribcell/test.py +++ b/tests/regression_tests/filter_distribcell/test.py @@ -6,7 +6,7 @@ from tests.testing_harness import * class DistribcellTestHarness(TestHarness): def __init__(self): - super(DistribcellTestHarness, self).__init__(None) + super().__init__(None) def execute_test(self): """Run OpenMC with the appropriate arguments and check the outputs.""" diff --git a/tests/regression_tests/filter_energyfun/test.py b/tests/regression_tests/filter_energyfun/test.py index d9148dd35d..7c5645b651 100644 --- a/tests/regression_tests/filter_energyfun/test.py +++ b/tests/regression_tests/filter_energyfun/test.py @@ -5,7 +5,7 @@ from tests.testing_harness import PyAPITestHarness class FilterEnergyFunHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): - super(FilterEnergyFunHarness, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Add Am241 to the fuel. self._model.materials[1].add_nuclide('Am241', 1e-7) diff --git a/tests/regression_tests/filter_mesh/test.py b/tests/regression_tests/filter_mesh/test.py index 66cd1ac19f..e0c6dd0f2f 100644 --- a/tests/regression_tests/filter_mesh/test.py +++ b/tests/regression_tests/filter_mesh/test.py @@ -5,7 +5,7 @@ from tests.testing_harness import HashedPyAPITestHarness class FilterMeshTestHarness(HashedPyAPITestHarness): def __init__(self, *args, **kwargs): - super(FilterMeshTestHarness, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Initialize Meshes mesh_1d = openmc.Mesh(mesh_id=1) diff --git a/tests/regression_tests/mg_convert/test.py b/tests/regression_tests/mg_convert/test.py index 4bbbcbeb9a..5b816a1cd0 100755 --- a/tests/regression_tests/mg_convert/test.py +++ b/tests/regression_tests/mg_convert/test.py @@ -159,7 +159,7 @@ class MGXSTestHarness(PyAPITestHarness): return outstr def _cleanup(self): - super(MGXSTestHarness, self)._cleanup() + super()._cleanup() f = os.path.join(os.getcwd(), 'mgxs.h5') if os.path.exists(f): os.remove(f) diff --git a/tests/regression_tests/mgxs_library_ce_to_mg/test.py b/tests/regression_tests/mgxs_library_ce_to_mg/test.py index 922b2c302c..72f052e68e 100644 --- a/tests/regression_tests/mgxs_library_ce_to_mg/test.py +++ b/tests/regression_tests/mgxs_library_ce_to_mg/test.py @@ -11,7 +11,7 @@ from tests.regression_tests import config class MGXSTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): # Generate inputs using parent class routine - super(MGXSTestHarness, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Initialize a two-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625, 20.e6]) @@ -71,7 +71,7 @@ class MGXSTestHarness(PyAPITestHarness): openmc.run(openmc_exec=config['exe']) def _cleanup(self): - super(MGXSTestHarness, self)._cleanup() + super()._cleanup() f = 'mgxs.h5' if os.path.exists(f): os.remove(f) diff --git a/tests/regression_tests/mgxs_library_condense/test.py b/tests/regression_tests/mgxs_library_condense/test.py index 06b4704784..167772e2fd 100644 --- a/tests/regression_tests/mgxs_library_condense/test.py +++ b/tests/regression_tests/mgxs_library_condense/test.py @@ -9,7 +9,7 @@ from tests.testing_harness import PyAPITestHarness class MGXSTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): - super(MGXSTestHarness, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Initialize a two-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625, 20.e6]) diff --git a/tests/regression_tests/mgxs_library_distribcell/test.py b/tests/regression_tests/mgxs_library_distribcell/test.py index d7bc84bf57..5290d313bb 100644 --- a/tests/regression_tests/mgxs_library_distribcell/test.py +++ b/tests/regression_tests/mgxs_library_distribcell/test.py @@ -10,7 +10,7 @@ from tests.testing_harness import PyAPITestHarness class MGXSTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): # Generate inputs using parent class routine - super(MGXSTestHarness, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Initialize a one-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 20.e6]) diff --git a/tests/regression_tests/mgxs_library_hdf5/test.py b/tests/regression_tests/mgxs_library_hdf5/test.py index 8eed0258aa..9811ab2155 100644 --- a/tests/regression_tests/mgxs_library_hdf5/test.py +++ b/tests/regression_tests/mgxs_library_hdf5/test.py @@ -13,7 +13,7 @@ from tests.testing_harness import PyAPITestHarness class MGXSTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): # Generate inputs using parent class routine - super(MGXSTestHarness, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Initialize a two-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625, 20.e6]) @@ -67,7 +67,7 @@ class MGXSTestHarness(PyAPITestHarness): return outstr def _cleanup(self): - super(MGXSTestHarness, self)._cleanup() + super()._cleanup() f = 'mgxs.h5' if os.path.exists(f): os.remove(f) diff --git a/tests/regression_tests/mgxs_library_mesh/test.py b/tests/regression_tests/mgxs_library_mesh/test.py index 70bd2113ce..a9d24da934 100644 --- a/tests/regression_tests/mgxs_library_mesh/test.py +++ b/tests/regression_tests/mgxs_library_mesh/test.py @@ -8,7 +8,7 @@ from tests.testing_harness import PyAPITestHarness class MGXSTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): - super(MGXSTestHarness, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Initialize a one-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 20.e6]) diff --git a/tests/regression_tests/mgxs_library_no_nuclides/test.py b/tests/regression_tests/mgxs_library_no_nuclides/test.py index c59b52189e..506ac238fc 100644 --- a/tests/regression_tests/mgxs_library_no_nuclides/test.py +++ b/tests/regression_tests/mgxs_library_no_nuclides/test.py @@ -10,7 +10,7 @@ from tests.testing_harness import PyAPITestHarness class MGXSTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): # Generate inputs using parent class routine - super(MGXSTestHarness, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Initialize a two-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625, 20.e6]) diff --git a/tests/regression_tests/mgxs_library_nuclides/test.py b/tests/regression_tests/mgxs_library_nuclides/test.py index a65fb9a6d3..c64c277098 100644 --- a/tests/regression_tests/mgxs_library_nuclides/test.py +++ b/tests/regression_tests/mgxs_library_nuclides/test.py @@ -9,7 +9,7 @@ from tests.testing_harness import PyAPITestHarness class MGXSTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): - super(MGXSTestHarness, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Initialize a two-group structure energy_groups = openmc.mgxs.EnergyGroups(group_edges=[0, 0.625, 20.e6]) diff --git a/tests/regression_tests/multipole/test.py b/tests/regression_tests/multipole/test.py index 43aa9963aa..82e6bb4cd7 100644 --- a/tests/regression_tests/multipole/test.py +++ b/tests/regression_tests/multipole/test.py @@ -71,10 +71,10 @@ class MultipoleTestHarness(PyAPITestHarness): raise RuntimeError("The 'OPENMC_MULTIPOLE_LIBRARY' environment " "variable must be specified for this test.") else: - super(MultipoleTestHarness, self).execute_test() + super().execute_test() def _get_results(self): - outstr = super(MultipoleTestHarness, self)._get_results() + outstr = super()._get_results() su = openmc.Summary('summary.h5') outstr += str(su.geometry.get_all_cells()[11]) return outstr diff --git a/tests/regression_tests/plot/test.py b/tests/regression_tests/plot/test.py index e7115c4dde..bfaef019c1 100644 --- a/tests/regression_tests/plot/test.py +++ b/tests/regression_tests/plot/test.py @@ -12,7 +12,7 @@ from tests.regression_tests import config class PlotTestHarness(TestHarness): """Specialized TestHarness for running OpenMC plotting tests.""" def __init__(self, plot_names): - super(PlotTestHarness, self).__init__(None) + super().__init__(None) self._plot_names = plot_names def _run_openmc(self): @@ -24,7 +24,7 @@ class PlotTestHarness(TestHarness): assert os.path.exists(fname), 'Plot output file does not exist.' def _cleanup(self): - super(PlotTestHarness, self)._cleanup() + super()._cleanup() for fname in self._plot_names: if os.path.exists(fname): os.remove(fname) diff --git a/tests/regression_tests/statepoint_batch/test.py b/tests/regression_tests/statepoint_batch/test.py index 6c5e4de318..323b28fc65 100644 --- a/tests/regression_tests/statepoint_batch/test.py +++ b/tests/regression_tests/statepoint_batch/test.py @@ -3,7 +3,7 @@ from tests.testing_harness import TestHarness class StatepointTestHarness(TestHarness): def __init__(self): - super(StatepointTestHarness, self).__init__(None) + super().__init__(None) def _test_output_created(self): """Make sure statepoint files have been created.""" diff --git a/tests/regression_tests/statepoint_restart/test.py b/tests/regression_tests/statepoint_restart/test.py index d36ff93950..4575607f7d 100644 --- a/tests/regression_tests/statepoint_restart/test.py +++ b/tests/regression_tests/statepoint_restart/test.py @@ -9,7 +9,7 @@ from tests.regression_tests import config class StatepointRestartTestHarness(TestHarness): def __init__(self, final_sp, restart_sp): - super(StatepointRestartTestHarness, self).__init__(final_sp) + super().__init__(final_sp) self._restart_sp = restart_sp def execute_test(self): diff --git a/tests/regression_tests/tally_aggregation/test.py b/tests/regression_tests/tally_aggregation/test.py index f723160737..f7df543ded 100644 --- a/tests/regression_tests/tally_aggregation/test.py +++ b/tests/regression_tests/tally_aggregation/test.py @@ -7,7 +7,7 @@ from tests.testing_harness import PyAPITestHarness class TallyAggregationTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): - super(TallyAggregationTestHarness, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Initialize the filters energy_filter = openmc.EnergyFilter([0.0, 0.253, 1.0e3, 1.0e6, 20.0e6]) diff --git a/tests/regression_tests/tally_arithmetic/test.py b/tests/regression_tests/tally_arithmetic/test.py index 469ed00de1..3adf0c5bef 100644 --- a/tests/regression_tests/tally_arithmetic/test.py +++ b/tests/regression_tests/tally_arithmetic/test.py @@ -7,7 +7,7 @@ from tests.testing_harness import PyAPITestHarness class TallyArithmeticTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): - super(TallyArithmeticTestHarness, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Initialize Mesh mesh = openmc.Mesh(mesh_id=1) diff --git a/tests/regression_tests/tally_slice_merge/test.py b/tests/regression_tests/tally_slice_merge/test.py index ff35c177f5..f79c8b2685 100644 --- a/tests/regression_tests/tally_slice_merge/test.py +++ b/tests/regression_tests/tally_slice_merge/test.py @@ -8,7 +8,7 @@ from tests.testing_harness import PyAPITestHarness class TallySliceMergeTestHarness(PyAPITestHarness): def __init__(self, *args, **kwargs): - super(TallySliceMergeTestHarness, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # Define nuclides and scores to add to both tallies self.nuclides = ['U235', 'U238'] diff --git a/tests/testing_harness.py b/tests/testing_harness.py index 6c9e25b457..92d477e238 100644 --- a/tests/testing_harness.py +++ b/tests/testing_harness.py @@ -127,7 +127,7 @@ class HashedTestHarness(TestHarness): def _get_results(self): """Digest info in the statepoint and return as a string.""" - return super(HashedTestHarness, self)._get_results(True) + return super()._get_results(True) class CMFDTestHarness(TestHarness): @@ -137,7 +137,7 @@ class CMFDTestHarness(TestHarness): """Digest info in the statepoint and return as a string.""" # Write out the eigenvalue and tallies. - outstr = super(CMFDTestHarness, self)._get_results() + outstr = super()._get_results() # Read the statepoint file. statepoint = glob.glob(self._sp_name)[0] @@ -220,7 +220,7 @@ class ParticleRestartTestHarness(TestHarness): class PyAPITestHarness(TestHarness): def __init__(self, statepoint_name, model=None): - super(PyAPITestHarness, self).__init__(statepoint_name) + super().__init__(statepoint_name) if model is None: self._model = pwr_core() else: @@ -300,7 +300,7 @@ class PyAPITestHarness(TestHarness): def _cleanup(self): """Delete XMLs, statepoints, tally, and test files.""" - super(PyAPITestHarness, self)._cleanup() + super()._cleanup() output = ['materials.xml', 'geometry.xml', 'settings.xml', 'tallies.xml', 'plots.xml', 'inputs_test.dat'] for f in output: @@ -311,4 +311,4 @@ class PyAPITestHarness(TestHarness): class HashedPyAPITestHarness(PyAPITestHarness): def _get_results(self): """Digest info in the statepoint and return as a string.""" - return super(HashedPyAPITestHarness, self)._get_results(True) + return super()._get_results(True) From 848305b8d38ceb490655f049a7b49f618484a666 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Tue, 6 Feb 2018 13:27:01 -0500 Subject: [PATCH 74/74] Skip multipole-related tests if OPENMC_MULTIPOLE_LIBRARY is not set --- pytest.ini | 1 + tests/regression_tests/diff_tally/test.py | 4 ++++ tests/regression_tests/multipole/test.py | 11 ++++------- tests/unit_tests/test_data_multipole.py | 7 +++++-- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/pytest.ini b/pytest.ini index d960ba8d25..cdd367ea9d 100644 --- a/pytest.ini +++ b/pytest.ini @@ -2,3 +2,4 @@ python_files = test*.py python_classes = NoThanks filterwarnings = ignore::UserWarning +addopts = -rs diff --git a/tests/regression_tests/diff_tally/test.py b/tests/regression_tests/diff_tally/test.py index bd6792414b..de5423fd9f 100644 --- a/tests/regression_tests/diff_tally/test.py +++ b/tests/regression_tests/diff_tally/test.py @@ -3,6 +3,7 @@ import os import pandas as pd import openmc +import pytest from tests.testing_harness import PyAPITestHarness @@ -112,6 +113,9 @@ class DiffTallyTestHarness(PyAPITestHarness): return df.to_csv(None, columns=cols, index=False, float_format='%.7e') +@pytest.mark.skipif('OPENMC_MULTIPOLE_LIBRARY' not in os.environ, + reason='OPENMC_MULTIPOLE_LIBRARY environment variable ' + 'must be set') def test_diff_tally(): harness = DiffTallyTestHarness('statepoint.3.h5') harness.main() diff --git a/tests/regression_tests/multipole/test.py b/tests/regression_tests/multipole/test.py index 82e6bb4cd7..5c79d4d6b6 100644 --- a/tests/regression_tests/multipole/test.py +++ b/tests/regression_tests/multipole/test.py @@ -2,6 +2,7 @@ import os import openmc import openmc.model +import pytest from tests.testing_harness import TestHarness, PyAPITestHarness @@ -66,13 +67,6 @@ def make_model(): class MultipoleTestHarness(PyAPITestHarness): - def execute_test(self): - if not 'OPENMC_MULTIPOLE_LIBRARY' in os.environ: - raise RuntimeError("The 'OPENMC_MULTIPOLE_LIBRARY' environment " - "variable must be specified for this test.") - else: - super().execute_test() - def _get_results(self): outstr = super()._get_results() su = openmc.Summary('summary.h5') @@ -80,6 +74,9 @@ class MultipoleTestHarness(PyAPITestHarness): return outstr +@pytest.mark.skipif('OPENMC_MULTIPOLE_LIBRARY' not in os.environ, + reason='OPENMC_MULTIPOLE_LIBRARY environment variable ' + 'must be set') def test_multipole(): model = make_model() harness = MultipoleTestHarness('statepoint.5.h5', model) diff --git a/tests/unit_tests/test_data_multipole.py b/tests/unit_tests/test_data_multipole.py index dc30677e80..4a4a9f0d21 100644 --- a/tests/unit_tests/test_data_multipole.py +++ b/tests/unit_tests/test_data_multipole.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - import os import numpy as np @@ -7,6 +5,11 @@ import pytest import openmc.data +pytestmark = pytest.mark.skipif( + 'OPENMC_MULTIPOLE_LIBRARY' not in os.environ, + reason='OPENMC_MULTIPOLE_LIBRARY environment variable must be set') + + @pytest.fixture(scope='module') def u235(): directory = os.environ['OPENMC_MULTIPOLE_LIBRARY']