Skip to content

Commit

Permalink
Add optical generator data and update pre-generators (celeritas-proje…
Browse files Browse the repository at this point in the history
…ct#1182)

* Add optical generator data and update pre-generators

* Address @stognini's feedback

* Address @sethrj feedback
  • Loading branch information
amandalund committed Apr 11, 2024
1 parent fda9820 commit bb6fc2a
Show file tree
Hide file tree
Showing 8 changed files with 394 additions and 254 deletions.
5 changes: 2 additions & 3 deletions src/celeritas/optical/CerenkovDndxCalculator.hh
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ CerenkovDndxCalculator::CerenkovDndxCalculator(
{
CELER_EXPECT(properties_);
CELER_EXPECT(shared_);
CELER_EXPECT(material_ < shared_.angle_integral.size());
CELER_EXPECT(charge != zero_quantity());
}

//---------------------------------------------------------------------------//
Expand Down Expand Up @@ -128,9 +130,6 @@ CerenkovDndxCalculator::operator()(units::LightSpeed beta)
}
else
{
// TODO: Check that refractive index is monotonically increasing when
// grids are imported

// Find the energy where the refractive index is equal to 1 / beta.
// Both energy and refractive index are monotonically increasing, so
// the grid and values can be swapped and the energy can be calculated
Expand Down
102 changes: 39 additions & 63 deletions src/celeritas/optical/CerenkovPreGenerator.hh
Original file line number Diff line number Diff line change
Expand Up @@ -16,69 +16,42 @@
#include "CerenkovData.hh"
#include "CerenkovDndxCalculator.hh"
#include "OpticalDistributionData.hh"
#include "OpticalGenData.hh"
#include "OpticalPropertyData.hh"

namespace celeritas
{
//---------------------------------------------------------------------------//
/*!
* Sample the number of Cerenkov photons to be generated by
* \c CerenkovGenerator and populate \c OpticalDistributionData values using
* Param and State data.
* \code
CerenkovPreGenerator::OpticalPreGenStepData step_data;
// Populate step_data
CerenkovPreGenerator pre_generate(particle_view,
sim_view,
material,
properties->host_ref(),
params->host_ref(),
step_data);
auto optical_dist_data = pre_generate(rng);
if (optical_dist_data)
{
CerenkovGenerator cerenkov_generate(... , optical_dist_data, ...);
cerenkov_generate(rng);
}
* \endcode
* Sample the number of Cerenkov photons to be generated.
*
* This populates the \c OpticalDistributionData used by the \c
* CerenkovGenerator to generate optical photons using post-step and cached
* pre-step data.
*/
class CerenkovPreGenerator
{
public:
// Placeholder for data that is not available through Views
// TODO: Merge Cerenkov and Scintillation pre-gen data into one struct
struct OpticalPreGenStepData
{
real_type time{}; //!< Pre-step time
EnumArray<StepPoint, OpticalStepData> points; //!< Pre- and post-steps

//! Check whether the data are assigned
explicit CELER_FUNCTION operator bool() const
{
return points[StepPoint::pre].speed > zero_quantity();
}
};

// Construct with optical properties, Cerenkov, and step data
inline CELER_FUNCTION
CerenkovPreGenerator(ParticleTrackView const& particle_view,
SimTrackView const& sim_view,
OpticalMaterialId mat_id,
CerenkovPreGenerator(ParticleTrackView const& particle,
SimTrackView const& sim,
Real3 const& pos,
OpticalMaterialId optmat_id,
NativeCRef<OpticalPropertyData> const& properties,
NativeCRef<CerenkovData> const& shared,
OpticalPreGenStepData const& step_data);
OpticalPreStepData const& step_data);

// Return a populated optical distribution data for the Cerenkov Generator
template<class Generator>
inline CELER_FUNCTION OpticalDistributionData operator()(Generator& rng);

private:
units::ElementaryCharge charge_;
real_type step_len_;
OpticalMaterialId mat_id_;
OpticalPreGenStepData step_data_;
real_type step_length_;
OpticalMaterialId optmat_id_;
OpticalPreStepData pre_step_;
OpticalStepData post_step_;
real_type num_photons_per_len_;
};

Expand All @@ -91,28 +64,29 @@ class CerenkovPreGenerator
* Construct with optical properties, Cerenkov, and step information.
*/
CELER_FUNCTION CerenkovPreGenerator::CerenkovPreGenerator(
ParticleTrackView const& particle_view,
SimTrackView const& sim_view,
OpticalMaterialId mat_id,
ParticleTrackView const& particle,
SimTrackView const& sim,
Real3 const& pos,
OpticalMaterialId optmat_id,
NativeCRef<OpticalPropertyData> const& properties,
NativeCRef<CerenkovData> const& shared,
OpticalPreGenStepData const& step_data)
: charge_(particle_view.charge())
, step_len_(sim_view.step_length())
, mat_id_(mat_id)
, step_data_(step_data)
OpticalPreStepData const& step_data)
: charge_(particle.charge())
, step_length_(sim.step_length())
, optmat_id_(optmat_id)
, pre_step_(step_data)
, post_step_({particle.speed(), pos})
{
CELER_EXPECT(charge_ != zero_quantity());
CELER_EXPECT(step_len_ > 0);
CELER_EXPECT(mat_id_);
CELER_EXPECT(step_data_);
CELER_EXPECT(step_length_ > 0);
CELER_EXPECT(optmat_id_);
CELER_EXPECT(pre_step_);

auto const& pre = step_data_.points[StepPoint::pre];
auto const& post = step_data_.points[StepPoint::post];
units::LightSpeed beta(real_type{0.5}
* (pre.speed.value() + post.speed.value()));
units::LightSpeed beta(
real_type{0.5} * (pre_step_.speed.value() + post_step_.speed.value()));

CerenkovDndxCalculator calculate_dndx(properties, shared, mat_id_, charge_);
CerenkovDndxCalculator calculate_dndx(
properties, shared, optmat_id_, charge_);
num_photons_per_len_ = calculate_dndx(beta);
}

Expand All @@ -138,14 +112,16 @@ CerenkovPreGenerator::operator()(Generator& rng)

OpticalDistributionData data;
data.num_photons = PoissonDistribution<real_type>(num_photons_per_len_
* step_len_)(rng);
* step_length_)(rng);
if (data.num_photons > 0)
{
data.time = step_data_.time;
data.step_length = step_len_;
data.time = pre_step_.time;
data.step_length = step_length_;
data.charge = charge_;
data.material = mat_id_;
data.points = step_data_.points;
data.material = optmat_id_;
data.points[StepPoint::pre].speed = pre_step_.speed;
data.points[StepPoint::pre].pos = pre_step_.pos;
data.points[StepPoint::post] = post_step_;
}
return data;
}
Expand Down
157 changes: 157 additions & 0 deletions src/celeritas/optical/OpticalGenData.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
//----------------------------------*-C++-*----------------------------------//
// Copyright 2024 UT-Battelle, LLC, and other Celeritas developers.
// See the top-level COPYRIGHT file for details.
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
//---------------------------------------------------------------------------//
//! \file celeritas/optical/OpticalGenData.hh
//---------------------------------------------------------------------------//
#pragma once

#include "corecel/Macros.hh"
#include "corecel/Types.hh"
#include "corecel/data/Collection.hh"
#include "celeritas/Quantities.hh"
#include "celeritas/Types.hh"
#include "celeritas/optical/CerenkovData.hh"
#include "celeritas/optical/OpticalDistributionData.hh"
#include "celeritas/optical/OpticalPropertyData.hh"
#include "celeritas/optical/ScintillationData.hh"

namespace celeritas
{
//---------------------------------------------------------------------------//
/*!
* Current sizes of the buffers of distribution data.
*
* These sizes are updated by value on the host at each step.
*/
struct OpticalBufferSize
{
size_type cerenkov{0};
size_type scintillation{0};
};

//---------------------------------------------------------------------------//
/*!
* Immutable problem data for generating optical photon distributions.
*/
template<Ownership W, MemSpace M>
struct OpticalGenParamsData
{
//// DATA ////

bool cerenkov{false}; //!< Whether Cerenkov is enabled
bool scintillation{false}; //!< Whether scintillation is enabled
real_type capacity{0}; //!< Distribution data buffer capacity

//// METHODS ////

//! True if all params are assigned
explicit CELER_FUNCTION operator bool() const
{
return (cerenkov || scintillation) && capacity > 0;
}

//! Assign from another set of data
template<Ownership W2, MemSpace M2>
OpticalGenParamsData& operator=(OpticalGenParamsData<W2, M2> const& other)
{
CELER_EXPECT(other);
cerenkov = other.cerenkov;
scintillation = other.scintillation;
capacity = other.capacity;
return *this;
}
};

//---------------------------------------------------------------------------//
/*!
* Pre-step data needed to generate optical photon distributions.
*/
struct OpticalPreStepData
{
units::LightSpeed speed;
Real3 pos{};
real_type time{};

//! Check whether the data are assigned
explicit CELER_FUNCTION operator bool() const
{
return speed > zero_quantity();
}
};

//---------------------------------------------------------------------------//
/*!
* Optical photon distribution data.
*/
template<Ownership W, MemSpace M>
struct OpticalGenStateData
{
//// TYPES ////

template<class T>
using StateItems = StateCollection<T, W, M>;
template<class T>
using Items = Collection<T, W, M>;

//// DATA ////

// Pre-step data for generating optical photon distributions
StateItems<OpticalPreStepData> step;

// Buffers of distribution data for generating optical primaries
Items<OpticalDistributionData> cerenkov;
Items<OpticalDistributionData> scintillation;

//// METHODS ////

//! Number of states
CELER_FUNCTION size_type size() const { return step.size(); }

//! Whether all data are assigned and valid
explicit CELER_FUNCTION operator bool() const
{
return !step.empty() && !(cerenkov.empty() && scintillation.empty());
}

//! Assign from another set of data
template<Ownership W2, MemSpace M2>
OpticalGenStateData& operator=(OpticalGenStateData<W2, M2>& other)
{
CELER_EXPECT(other);
step = other.step;
cerenkov = other.cerenkov;
scintillation = other.scintillation;
return *this;
}
};

//---------------------------------------------------------------------------//
/*!
* Resize optical states.
*/
template<MemSpace M>
void resize(OpticalGenStateData<Ownership::value, M>* state,
HostCRef<OpticalGenParamsData> const& params,
StreamId,
size_type size)
{
CELER_EXPECT(params);
CELER_EXPECT(size > 0);

resize(&state->step, size);
if (params.cerenkov)
{
resize(&state->cerenkov, params.capacity);
}
if (params.scintillation)
{
resize(&state->scintillation, params.capacity);
}

CELER_ENSURE(*state);
}

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

0 comments on commit bb6fc2a

Please sign in to comment.