Skip to content

Commit

Permalink
Add generic grid inserter (#1229)
Browse files Browse the repository at this point in the history
  • Loading branch information
hhollenb committed May 15, 2024
1 parent d6b41af commit 124e0db
Show file tree
Hide file tree
Showing 5 changed files with 389 additions and 8 deletions.
136 changes: 136 additions & 0 deletions src/celeritas/grid/GenericGridInserter.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
//----------------------------------*-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/grid/GenericGridInserter.hh
//---------------------------------------------------------------------------//
#pragma once

#include <utility>
#include <vector>

#include "corecel/Types.hh"
#include "corecel/cont/Span.hh"
#include "corecel/data/Collection.hh"
#include "corecel/data/CollectionBuilder.hh"
#include "celeritas/Types.hh"
#include "celeritas/io/ImportPhysicsVector.hh"

#include "GenericGridBuilder.hh"
#include "GenericGridData.hh"

namespace celeritas
{
//---------------------------------------------------------------------------//
/*!
* Construct a generic grid using mutable host data and add it to
* the specified grid collection.
*
* \code
GenericGridInserter insert(&data->reals, &data->generic_grids);
std::vector<GenericGridIndex> grid_ids;
for (material : range(MaterialId{mats->size()}))
grid_ids.push_back(insert(physics_vector[material.get()]));
\endcode
*/
template<class Index>
class GenericGridInserter
{
public:
//!@{
//! \name Type aliases
using SpanConstFlt = Span<float const>;
using SpanConstDbl = Span<double const>;
using RealCollection
= Collection<real_type, Ownership::value, MemSpace::host>;
using GenericGridCollection
= Collection<GenericGridData, Ownership::value, MemSpace::host, Index>;
//!@}

public:
// Construct with a reference to mutable host data
GenericGridInserter(RealCollection* real_data, GenericGridCollection* grid);

// Add a grid of generic data with linear interpolation
Index operator()(SpanConstFlt grid, SpanConstFlt values);

// Add a grid of generic data with linear interpolation
Index operator()(SpanConstDbl grid, SpanConstDbl values);

// Add an imported physics vector as a grid
Index operator()(ImportPhysicsVector const& vec);

// Add an empty grid (no data present)
Index operator()();

private:
GenericGridBuilder grid_builder_;
CollectionBuilder<GenericGridData, MemSpace::host, Index> grids_;
};

//---------------------------------------------------------------------------//
/*!
* Construct with a reference to mutable host data.
*/
template<class Index>
GenericGridInserter<Index>::GenericGridInserter(RealCollection* real_data,
GenericGridCollection* grid)
: grid_builder_(real_data), grids_(grid)
{
CELER_EXPECT(real_data && grid);
}

//---------------------------------------------------------------------------//
/*!
* Add an imported physics vector as a generic grid to the collection.
*
* Returns the id of the inserted grid, or an empty id if the vector is
* empty.
*/
template<class Index>
auto GenericGridInserter<Index>::operator()(ImportPhysicsVector const& vec)
-> Index
{
CELER_EXPECT(!vec.x.empty());
return grids_.push_back(grid_builder_(vec));
}

//---------------------------------------------------------------------------//
/*!
* Add a grid of generic data with linear interpolation to the collection.
*/
template<class Index>
auto GenericGridInserter<Index>::operator()(SpanConstFlt grid,
SpanConstFlt values) -> Index
{
CELER_EXPECT(!grid.empty());
return grids_.push_back(grid_builder_(grid, values));
}

//---------------------------------------------------------------------------//
/*!
* Add a grid of generic data with linear interpolation to the collection.
*/
template<class Index>
auto GenericGridInserter<Index>::operator()(SpanConstDbl grid,
SpanConstDbl values) -> Index
{
CELER_EXPECT(!grid.empty());
return grids_.push_back(grid_builder_(grid, values));
}

//---------------------------------------------------------------------------//
/*!
* Add an empty grid.
*
* Useful for when there's no imported grid present for a given material.
*/
template<class Index>
auto GenericGridInserter<Index>::operator()() -> Index
{
return grids_.push_back({});
}

//---------------------------------------------------------------------------//
} // namespace celeritas
16 changes: 8 additions & 8 deletions src/celeritas/optical/CerenkovParams.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
#include "corecel/math/Algorithms.hh"
#include "celeritas/Quantities.hh"
#include "celeritas/Types.hh"
#include "celeritas/grid/GenericGridBuilder.hh"
#include "celeritas/grid/GenericGridData.hh"
#include "celeritas/grid/GenericGridInserter.hh"

#include "OpticalPropertyParams.hh"

Expand All @@ -33,8 +32,8 @@ CerenkovParams::CerenkovParams(SPConstProperties properties)
auto const& host_ref = properties->host_ref();

HostVal<CerenkovData> data;
GenericGridBuilder build_angle_integral(&data.reals);
CollectionBuilder angle_integral(&data.angle_integral);
GenericGridInserter insert_angle_integral(&data.reals,
&data.angle_integral);

for (auto mat_id :
range(OpticalMaterialId(host_ref.refractive_index.size())))
Expand All @@ -43,7 +42,7 @@ CerenkovParams::CerenkovParams(SPConstProperties properties)
if (!ri_grid)
{
// No refractive index data stored for this material
angle_integral.push_back({});
insert_angle_integral();
continue;
}

Expand All @@ -58,10 +57,11 @@ CerenkovParams::CerenkovParams(SPConstProperties properties)
* (1 / ipow<2>(refractive_index[i - 1])
+ 1 / ipow<2>(refractive_index[i]));
}
angle_integral.push_back(
build_angle_integral(make_span(energy), make_span(integral)));

insert_angle_integral(make_span(energy), make_span(integral));
}
CELER_ASSERT(angle_integral.size() == host_ref.refractive_index.size());
CELER_ASSERT(data.angle_integral.size()
== host_ref.refractive_index.size());

data_ = CollectionMirror<CerenkovData>{std::move(data)};
CELER_ENSURE(data_ || host_ref.refractive_index.empty());
Expand Down
2 changes: 2 additions & 0 deletions test/celeritas/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ celeritas_add_test(global/Stepper.test.cc
# Grid
set(CELERITASTEST_PREFIX celeritas/grid)
celeritas_add_test(grid/GenericCalculator.test.cc)
celeritas_add_test(grid/GenericGridBuilder.test.cc)
celeritas_add_test(grid/GenericGridInserter.test.cc)
celeritas_add_test(grid/GridIdFinder.test.cc)
celeritas_add_test(grid/InverseRangeCalculator.test.cc)
celeritas_add_test(grid/PolyEvaluator.test.cc)
Expand Down
83 changes: 83 additions & 0 deletions test/celeritas/grid/GenericGridBuilder.test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//----------------------------------*-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/grid/GenericGridBuilder.test.cc
//---------------------------------------------------------------------------//
#include "celeritas/grid/GenericGridBuilder.hh"

#include <iostream>
#include <vector>

#include "celeritas/io/ImportPhysicsVector.hh"

#include "celeritas_test.hh"

namespace celeritas
{
namespace test
{
//---------------------------------------------------------------------------//

//---------------------------------------------------------------------------//
// TEST HARNESS
//---------------------------------------------------------------------------//

class GenericGridBuilderTest : public ::celeritas::test::Test
{
protected:
GenericGridBuilder make_builder() { return GenericGridBuilder(&scalars_); }

static Span<real_type const> span_grid() { return make_span(grid_); }

static Span<real_type const> span_values() { return make_span(values_); }

Collection<real_type, Ownership::value, MemSpace::host> scalars_;

constexpr static real_type grid_[] = {0.0, 0.4, 0.9, 1.3};
constexpr static real_type values_[] = {-31.0, 12.1, 15.5, 92.0};
};

//---------------------------------------------------------------------------//
// TESTS
//---------------------------------------------------------------------------//

TEST_F(GenericGridBuilderTest, build_span)
{
auto builder = make_builder();

GenericGridData grid_data = builder(span_grid(), span_values());

ASSERT_TRUE(grid_data);
ASSERT_EQ(8, scalars_.size());
ASSERT_EQ(4, grid_data.grid.size());
ASSERT_EQ(4, grid_data.value.size());

EXPECT_VEC_SOFT_EQ(grid_, scalars_[grid_data.grid]);
EXPECT_VEC_SOFT_EQ(values_, scalars_[grid_data.value]);
}

TEST_F(GenericGridBuilderTest, TEST_IF_CELERITAS_DOUBLE(build_vec))
{
ImportPhysicsVector vect;
vect.vector_type = ImportPhysicsVectorType::free;
vect.x = std::vector<double>(span_grid().begin(), span_grid().end());
vect.y = std::vector<double>(span_values().begin(), span_values().end());

auto builder = make_builder();

GenericGridData grid_data = builder(vect);

ASSERT_TRUE(grid_data);
ASSERT_EQ(8, scalars_.size());
ASSERT_EQ(4, grid_data.grid.size());
ASSERT_EQ(4, grid_data.value.size());

EXPECT_VEC_SOFT_EQ(grid_, scalars_[grid_data.grid]);
EXPECT_VEC_SOFT_EQ(values_, scalars_[grid_data.value]);
}

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

0 comments on commit 124e0db

Please sign in to comment.