Skip to content

Commit

Permalink
Delete larger volumes instead of forcing scalars
Browse files Browse the repository at this point in the history
  • Loading branch information
sethrj committed Sep 27, 2024
1 parent 7bde023 commit 253e52a
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 48 deletions.
41 changes: 0 additions & 41 deletions src/orange/OrangeParams.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
//---------------------------------------------------------------------------//
#include "OrangeParams.hh"

#include <charconv>
#include <fstream>
#include <initializer_list>
#include <limits>
#include <numeric>
#include <regex>
#include <utility>
#include <vector>
#include <nlohmann/json.hpp>
Expand Down Expand Up @@ -104,43 +102,6 @@ OrangeInput input_from_file(std::string filename)
return input_from_json(std::move(filename));
}

//---------------------------------------------------------------------------//
/*!
* Update faces/intersections if we know the "automatic" value is wrong.
*
* See https://github.com/celeritas-project/celeritas/issues/1334 .
*/
void apply_face_intersect_hack(std::string const& var,
OrangeParamsScalars* scalars)
{
std::string mfi = celeritas::getenv(var);
if (mfi.empty())
{
return;
}
CELER_LOG(warning)
<< "Using a temporary, unsupported, and dangerous hack to "
"override maximum faces and intersections in ORANGE: "
<< var << "='" << mfi << "'";

static std::regex const mfi_regex{R"re(^(\d+),(\d+)$)re"};
std::smatch mfi_match;
CELER_VALIDATE(std::regex_match(mfi, mfi_match, mfi_regex),
<< "invalid pattern for " << var);
auto update = [](char const* type, auto const& submatch, size_type* dest) {
auto&& s = submatch.str();
int updated{-1};
std::from_chars(s.data(), s.data() + s.length(), updated);
CELER_VALIDATE(updated > 0,
<< "invalid maximum " << type << ": " << updated);
CELER_LOG(warning) << "Forcing maximum " << type << " from " << *dest
<< " to " << updated;
*dest = static_cast<size_type>(updated);
};
update("faces", mfi_match[0], &scalars->max_faces);
update("intersections", mfi_match[1], &scalars->max_intersections);
}

//---------------------------------------------------------------------------//
} // namespace

Expand Down Expand Up @@ -237,8 +198,6 @@ OrangeParams::OrangeParams(OrangeInput&& input)
"stack is limited to a depth of "
<< detail::LogicStack::max_stack_depth());

apply_face_intersect_hack("ORANGE_MAX_FACE_INTERSECT", &host_data.scalars);

// Construct device values and device/host references
CELER_ASSERT(host_data);
data_ = CollectionMirror<OrangeParamsData>{std::move(host_data)};
Expand Down
89 changes: 82 additions & 7 deletions src/orange/detail/UnitInserter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
#include "UnitInserter.hh"

#include <algorithm>
#include <charconv>
#include <iostream>
#include <regex>
#include <set>
#include <vector>

Expand All @@ -19,7 +21,9 @@
#include "corecel/cont/Span.hh"
#include "corecel/data/Collection.hh"
#include "corecel/data/Ref.hh"
#include "corecel/io/Logger.hh"
#include "corecel/math/Algorithms.hh"
#include "corecel/sys/Environment.hh"

#include "UniverseInserter.hh"
#include "../OrangeInput.hh"
Expand Down Expand Up @@ -159,12 +163,14 @@ std::vector<Label> make_volume_labels(UnitInput& inp)
}

//---------------------------------------------------------------------------//
//! Create a bounding box bumper for a given tolerance.
//
// This bumper will convert *to* fast real type *from* regular
// real type. It conservatively expand to twice the potential bump distance
// from a boundary so that the bbox will enclose the point even after a
// potential bump.
/*!
* Create a bounding box bumper for a given tolerance.
*
* This bumper will convert *to* fast real type *from* regular
* real type. It conservatively expand to twice the potential bump distance
* from a boundary so that the bbox will enclose the point even after a
* potential bump.
*/
BoundingBoxBumper<fast_real_type, real_type> make_bumper(Tolerance<> const& tol)
{
Tolerance<real_type> bbox_tol;
Expand All @@ -174,6 +180,58 @@ BoundingBoxBumper<fast_real_type, real_type> make_bumper(Tolerance<> const& tol)
return BoundingBoxBumper<fast_real_type, real_type>(std::move(bbox_tol));
}

struct ForceMax
{
size_type faces = std::numeric_limits<size_type>::max();
size_type intersections = std::numeric_limits<size_type>::max();
};

static char const mfi_hack_envname[] = "ORANGE_MAX_FACE_INTERSECT";

//---------------------------------------------------------------------------//
/*!
* Force maximum faces/intersections.
*
* This is if we know the "automatic" value is wrong, specifically if all
* complicated/background cells are unreachable.
*
* See https://github.com/celeritas-project/celeritas/issues/1334 .
*/
ForceMax const& forced_scalar_max()
{
static ForceMax const result = [] {
std::string mfi = celeritas::getenv(mfi_hack_envname);
if (mfi.empty())
{
return ForceMax{};
}
CELER_LOG(warning)
<< "Using a temporary, unsupported, and dangerous hack to "
"override maximum faces and intersections in ORANGE: "
<< mfi_hack_envname << "='" << mfi << "'";

ForceMax result;
static std::regex const mfi_regex{R"re(^(\d+),(\d+)$)re"};
std::smatch mfi_match;
CELER_VALIDATE(std::regex_match(mfi, mfi_match, mfi_regex),
<< "invalid pattern for " << mfi_hack_envname);
auto get = [](char const* type, auto const& submatch) {
auto&& s = submatch.str();
int updated{-1};
std::from_chars(s.data(), s.data() + s.length(), updated);
CELER_VALIDATE(updated > 0,
<< "invalid maximum " << type << ": " << updated);
CELER_LOG(warning)
<< "Forcing maximum " << type << " to " << updated;
return static_cast<size_type>(updated);
};
result.faces = get("faces", mfi_match[0]);
result.intersections = get("intersections", mfi_match[1]);
return result;
}();
return result;
}

//---------------------------------------------------------------------------//
} // namespace

Expand Down Expand Up @@ -340,12 +398,13 @@ VolumeRecord UnitInserter::insert_volume(SurfacesRecord const& surf_record,
max_intersections += visit_surface(NumIntersectionGetter{}, sid);
}

static logic_int const nowhere_logic[] = {logic::ltrue, logic::lnot};

auto input_logic = make_span(v.logic);
if (v.zorder == ZOrder::background)
{
// "Background" volumes should not be explicitly reachable by logic or
// BIH
static logic_int const nowhere_logic[] = {logic::ltrue, logic::lnot};
CELER_EXPECT(std::equal(input_logic.begin(),
input_logic.end(),
std::begin(nowhere_logic),
Expand All @@ -369,6 +428,22 @@ VolumeRecord UnitInserter::insert_volume(SurfacesRecord const& surf_record,
output.flags |= VolumeRecord::Flags::simple_safety;
}

if (output.max_intersections > forced_scalar_max().intersections
|| output.faces.size() > forced_scalar_max().faces)
{
CELER_LOG(warning) << "Max intersections (" << output.max_intersections
<< ") and/or faces (" << output.faces.size()
<< ") exceed limits of '" << mfi_hack_envname
<< " in volume '" << v.label
<< "': replacing with unreachable volume";

output.faces = {};
output.logic = logic_ints_.insert_back(std::begin(nowhere_logic),
std::end(nowhere_logic));
output.max_intersections = 0;
output.flags = VolumeRecord::implicit_vol;
}

// Calculate the maximum stack depth of the volume definition
int max_depth = calc_max_depth(input_logic);
CELER_VALIDATE(max_depth > 0,
Expand Down

0 comments on commit 253e52a

Please sign in to comment.