Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 23 additions & 17 deletions src/celeritas/ext/detail/GeantPhysicsLoader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -326,34 +326,40 @@ size_type GeantPhysicsLoader::op_rayleigh(G4VProcess const&)
// as a grid
for (auto opt_mat_id : range(OptMatId{optical_ids_.num_optical()}))
{
if (model.materials.count(opt_mat_id))
{
continue;
}
bool has_mfp = model.materials.count(opt_mat_id);

auto get_property = this->property_getter(opt_mat_id);
inp::OpticalModelMaterial<ImportOpticalRayleigh> model_mat;
bool any_found = false;
any_found = get_property(model_mat.scale_factor,
"RS_SCALE_FACTOR",
ImportUnits::unitless)
|| any_found;
any_found = get_property(model_mat.compressibility,
"ISOTHERMAL_COMPRESSIBILITY",
ImportUnits::len_time_sq_per_mass)
|| any_found;
if (!any_found)

// Check for optional scale factor
bool has_scale = get_property(
model_mat.scale_factor, "RS_SCALE_FACTOR", ImportUnits::unitless);
bool has_compr = get_property(model_mat.compressibility,
"ISOTHERMAL_COMPRESSIBILITY",
ImportUnits::len_time_sq_per_mass);
if (!has_mfp && !has_compr)
{
// Check for G4 special case for water if no other data given
auto& g4mat = *optical_g4mat_[opt_mat_id.get()];
if (g4mat.GetName() == "Water")
{
load_rayleigh_water(model_mat, g4mat);
any_found = true;
has_compr = true;
}
}
if (any_found)

if (has_mfp && (has_scale || has_compr))
{
constexpr auto to_given_str
= [](bool v) { return v ? "provided" : "missing"; };
CELER_LOG(warning)
<< "Inconsistent Rayleigh input data: compressibility ("
<< to_given_str(has_compr) << ") with optional scale ("
<< to_given_str(has_scale)
<< ") is ignored in favor of MFP grid";
}
if (!has_mfp && has_compr)
{
CELER_VALIDATE(model_mat, << "inconsistent Rayleigh input data");
// Add non-grid rayleigh
model.materials.emplace(opt_mat_id, std::move(model_mat));
}
Expand Down
6 changes: 5 additions & 1 deletion src/celeritas/optical/gen/detail/MatScintSpecInserter.hh
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@ MatScintSpecInserter::MatScintSpecInserter(Data* data)
*/
auto MatScintSpecInserter::operator()(ImportMaterialScintSpectrum const& mat)
{
CELER_EXPECT(mat);
if (!mat)
{
CELER_LOG(warning) << "Missing scintillation data";
return materials_.push_back({});
Comment thread
sethrj marked this conversation as resolved.
}

CELER_VALIDATE(mat.yield_per_energy > 0,
<< "invalid yield=" << mat.yield_per_energy
Expand Down
2 changes: 1 addition & 1 deletion src/geocel/GeantGdmlLoader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ auto GeantGdmlLoader::operator()(std::string const& filename) const -> Result

Result result;
result.world = gdml_parser.GetWorldVolume();
CELER_VALIDATE(result.world, << "failed to load GDML");

if (opts_.detectors)
{
Expand Down Expand Up @@ -133,7 +134,6 @@ auto GeantGdmlLoader::operator()(std::string const& filename) const -> Result
remove_pointers(*G4LogicalVolumeStore::GetInstance());
}

CELER_ENSURE(result.world);
return result;
}

Expand Down
23 changes: 14 additions & 9 deletions test/celeritas/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,15 @@ endif()
#-----------------------------------------------------------------------------#
# External
set(_import_filter
"DuneCryostat.*"
"FourSteelSlabs*"
"TestEm3*"
"OneSteelSphere.*"
"OneSteelSphereGG.*"
"LarSphere.*"
"LarSphereExtramat.*"
"MucfBox.*"
"OneSteelSphere.*"
"OneSteelSphereGG.*"
"Solids.*"
"TestEm3*"
)
if(Geant4_VERSION VERSION_LESS 11.0)
list(REMOVE_ITEM _import_filter
Expand Down Expand Up @@ -428,15 +430,17 @@ function(celeritas_standalone_add_tests basename suite test backend)
set(_env ${CELER_G4ENV})
set(_labels "unit")

if("${backend}" STREQUAL "cpu")
if(backend STREQUAL "cpu")
if(CELERITAS_USE_CUDA OR CELERITAS_USE_HIP)
list(APPEND _env "CELER_DISABLE_DEVICE=1")
endif()
elseif("${backend}" STREQUAL "gpu")
if(CELERITAS_USE_CUDA OR CELERITAS_USE_HIP)
list(APPEND _test_props RESOURCE_LOCK gpu)
list(APPEND _labels gpu)
else()
elseif(backend STREQUAL "gpu")
# Set option to disable GPU environment
celeritas_get_disable_device(CELER_DISABLE_DEVICE)

list(APPEND _test_props RESOURCE_LOCK gpu)
list(APPEND _labels gpu)
if(CELER_DISABLE_DEVICE)
list(APPEND _test_props DISABLED TRUE)
endif()
else()
Expand All @@ -460,6 +464,7 @@ endfunction()
celeritas_add_standalone_tests(optical/Generator LArSphereGeneratorTest primary)
celeritas_add_standalone_tests(optical/Generator LArSphereGeneratorTest direct)
celeritas_add_standalone_tests(optical/Generator LArSphereGeneratorTest offload)
celeritas_add_standalone_tests(optical/Generator DuneGeneratorTest offload)
celeritas_add_standalone_tests(optical/Detector DetectorTest simple)
celeritas_add_standalone_tests(optical/Detector DetectorTest stress)

Expand Down
68 changes: 64 additions & 4 deletions test/celeritas/ext/GeantImporter.test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,19 @@
#include "corecel/ScopedLogStorer.hh"
#include "corecel/io/Logger.hh"
#include "corecel/io/Repr.hh"
#include "corecel/math/Quantity.hh"
#include "corecel/sys/Version.hh"
#include "geocel/UnitUtils.hh"
#include "celeritas/GeantTestBase.hh"
#include "celeritas/Types.hh"
#include "celeritas/UnitTypes.hh"
#include "celeritas/ext/GeantPhysicsOptions.hh"
#include "celeritas/ext/GeantPhysicsOptionsIO.json.hh"
#include "celeritas/io/ImportData.hh"
#include "celeritas/phys/AtomicNumber.hh"
#include "celeritas/phys/PDGNumber.hh"

#include "TestMacros.hh"
#include "celeritas_test.hh"

namespace celeritas
Expand Down Expand Up @@ -270,6 +273,24 @@ class FourSteelSlabsEmStandard : public GeantImporterTest
}
};

//---------------------------------------------------------------------------//
class DuneCryostat : public GeantImporterTest
{
protected:
std::string_view gdml_basename() const override
{
return "dune-cryostat"sv;
}

GeantPhysicsOptions build_geant_options() const override
{
GeantPhysicsOptions gpo = GeantPhysicsOptions::deactivated();
gpo.optical.emplace();
gpo.ionization = true;
return gpo;
}
};

//---------------------------------------------------------------------------//
class TestEm3 : public GeantImporterTest
{
Expand Down Expand Up @@ -414,6 +435,24 @@ class Solids : public GeantImporterTest
// TESTS
//---------------------------------------------------------------------------//

TEST_F(DuneCryostat, optical)
{
selection_.particles = GeantImportDataSelection::optical;
selection_.processes = GeantImportDataSelection::optical;
ScopedLogStorer scoped_log_{&celeritas::world_logger(), LogLevel::warning};
auto&& imported = this->imported_data();
CELER_DISCARD(imported);

static char const* const expected_log_messages[] = {
"Loaded no model data from process G4OpMieHG(\"OpMieHG\")",
"Loaded no model data from process G4OpWLS(\"OpWLS\")",
"Loaded no model data from process G4OpWLS2(\"OpWLS2\")",
};
EXPECT_VEC_EQ(expected_log_messages, scoped_log_.messages());
}

//---------------------------------------------------------------------------//

TEST_F(FourSteelSlabsEmStandard, em_particles)
{
selection_.particles = DataSelection::em;
Expand Down Expand Up @@ -1179,9 +1218,9 @@ TEST_F(FourSteelSlabsEmStandard, mu_pair_production_data)
//---------------------------------------------------------------------------//
TEST_F(FourSteelSlabsEmStandard, livermore_pe_data)
{
ScopedLogStorer scoped_log{&celeritas::world_logger(), LogLevel::warning};
ScopedLogStorer scoped_log_{&celeritas::world_logger(), LogLevel::warning};
auto&& import_data = this->imported_data();
EXPECT_TRUE(scoped_log.empty()) << scoped_log;
EXPECT_TRUE(scoped_log_.empty()) << scoped_log_;

auto const& lpe_map = import_data.livermore_photo.atomic_xs;
EXPECT_EQ(4, lpe_map.size());
Expand Down Expand Up @@ -1635,8 +1674,17 @@ TEST_F(OneSteelSphereGG, physics)

TEST_F(LarSphere, optical)
{
ScopedLogStorer scoped_log{&celeritas::world_logger(), LogLevel::info};
ScopedLogStorer scoped_log_{&celeritas::world_logger(), LogLevel::warning};
auto&& imported = this->imported_data();

static char const* const expected_log_messages[] = {
R"(Inconsistent Rayleigh input data: compressibility (provided) with optional scale (missing) is ignored in favor of MFP grid)",
"Loaded no model data from process G4OpMieHG(\"OpMieHG\")",
};
EXPECT_VEC_EQ(expected_log_messages, scoped_log_.messages());
static char const* const expected_log_levels[] = {"warning", "warning"};
EXPECT_VEC_EQ(expected_log_levels, scoped_log_.levels());

ASSERT_EQ(1, imported.optical_materials.size());
ASSERT_EQ(3, imported.geo_materials.size());
ASSERT_EQ(2, imported.phys_materials.size());
Expand Down Expand Up @@ -1840,7 +1888,19 @@ TEST_F(LarSphere, optical)

TEST_F(LarSphereExtramat, optical)
{
ScopedLogStorer scoped_log_{&celeritas::world_logger(), LogLevel::warning};
auto&& imported = this->imported_data();

static char const* const expected_log_messages[] = {
"Loaded no model data from process G4OpMieHG(\"OpMieHG\")",
"Loaded no model data from process G4OpWLS(\"OpWLS\")",
"Loaded no model data from process G4OpWLS2(\"OpWLS2\")",
};
EXPECT_VEC_EQ(expected_log_messages, scoped_log_.messages());
static char const* const expected_log_levels[]
= {"warning", "warning", "warning"};
EXPECT_VEC_EQ(expected_log_levels, scoped_log_.levels());

ASSERT_EQ(1, imported.optical_materials.size());
ASSERT_EQ(3, imported.geo_materials.size());
ASSERT_EQ(2, imported.phys_materials.size());
Expand Down Expand Up @@ -2115,7 +2175,7 @@ TEST_F(MucfBox, static_data)
EXPECT_EQ(expected_muon_energy_cdf_size, mucf.muon_energy_cdf.x.size());
EXPECT_EQ(expected_muon_energy_cdf_size, mucf.muon_energy_cdf.y.size());
EXPECT_SOFT_EQ(0.55157437567861023, average(mucf.muon_energy_cdf.x));
EXPECT_SOFT_EQ(11.250286274435437, average(mucf.muon_energy_cdf.y));
EXPECT_SOFT_EQ(0.011250286274435, average(mucf.muon_energy_cdf.y));

//! \todo Add real cycle rate data test

Expand Down
61 changes: 55 additions & 6 deletions test/celeritas/optical/Generator.test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#include "corecel/Types.hh"
#include "corecel/random/distribution/PoissonDistribution.hh"
#include "geocel/UnitUtils.hh"
#include "celeritas/Quantities.hh"
#include "celeritas/Types.hh"
#include "celeritas/Units.hh"
#include "celeritas/inp/StandaloneInput.hh"
#include "celeritas/optical/Runner.hh"
#include "celeritas/optical/gen/GeneratorData.hh"
Expand All @@ -34,17 +37,20 @@ constexpr bool reference_configuration
// TEST FIXTURES
//---------------------------------------------------------------------------//

class LArSphereGeneratorTest : public Test
class GeneratorTestBase : public Test
{
public:
using VecDistribution = std::vector<optical::GeneratorDistributionData>;

public:
//! Get an identifying key for the geometry (basename, description, etc)
virtual std::string gdml_basename() const = 0;

void SetUp() override
{
// Set geometry filename
osi_.problem.model.geometry
= Test::test_data_path("geocel", "lar-sphere.gdml");
= Test::test_data_path("geocel", this->gdml_basename() + ".gdml");

// Set per-process state sizes
osi_.problem.capacity = [] {
Expand Down Expand Up @@ -72,6 +78,15 @@ class LArSphereGeneratorTest : public Test
}();
}

protected:
inp::OpticalStandaloneInput osi_;
};

class LArSphereGeneratorTest : public GeneratorTestBase
{
public:
std::string gdml_basename() const final { return "lar-sphere"; }

//! Buffer host distribution data for Cherenkov and scintillation
VecDistribution make_distributions(size_type count)
{
Expand Down Expand Up @@ -101,9 +116,12 @@ class LArSphereGeneratorTest : public Test
}
return result;
}
};

protected:
inp::OpticalStandaloneInput osi_;
class DuneGeneratorTest : public GeneratorTestBase
{
public:
std::string gdml_basename() const final { return "dune-cryostat"; }
};

//---------------------------------------------------------------------------//
Expand Down Expand Up @@ -180,8 +198,6 @@ TEST_F(LArSphereGeneratorTest, offload)
{
// Generate Cherenkov and scintillation photons
osi_.problem.generator = inp::OpticalOffloadGenerator{};

// Enable Cherenkov and scintillation
osi_.geant_setup.cherenkov = CherenkovPhysicsOptions{};
osi_.geant_setup.scintillation = ScintillationPhysicsOptions{};

Expand Down Expand Up @@ -235,6 +251,39 @@ TEST_F(LArSphereGeneratorTest, offload)
EXPECT_VEC_EQ(expected_labels, labels);
}

TEST_F(DuneGeneratorTest, offload)
{
// Generate Cherenkov and scintillation photons
osi_.problem.generator = inp::OpticalOffloadGenerator{};
osi_.geant_setup.scintillation.emplace();

// Enable action times
osi_.problem.timers.action = true;

// Create host distributions and copy to generator
optical::GeneratorDistributionData gdd;
gdd.type = GeneratorType::scintillation;
gdd.num_photons = 4096;
gdd.primary = PrimaryId{123};
gdd.step_length = 2.0 * units::centimeter;
gdd.charge = units::ElementaryCharge{-1};
gdd.material = OptMatId{1}; // Should be LAr
gdd.continuous_edep_fraction = 1.0;
gdd.points[StepPoint::pre] = {units::LightSpeed(0.7),
1e-9 * units::nanosecond,
from_cm(Real3{-1, -98, 0})};
gdd.points[StepPoint::post] = {units::LightSpeed(0.6),
3e-9 * units::nanosecond,
from_cm(Real3{1, -98, 0})};
CELER_ASSERT(gdd);

// Construct the runner and transport the single distribution
auto result = optical::Runner(std::move(osi_))({&gdd, 1});

EXPECT_EQ(1, result.counters.flushes);
ASSERT_EQ(1, result.counters.generators.size());
}

//---------------------------------------------------------------------------//
} // namespace test
} // namespace celeritas
Loading
Loading