Skip to content

Commit

Permalink
Add small utilities for rasterization work (#1185)
Browse files Browse the repository at this point in the history
* Generalize array "soft unit" and move to independent file

* Add CELER_DEFAULT_MOVE_DELETE_COPY macro

* Add CELER_JSON_PAIR helper
  • Loading branch information
sethrj committed Apr 16, 2024
1 parent bbd64da commit 55dbb28
Show file tree
Hide file tree
Showing 11 changed files with 190 additions and 101 deletions.
7 changes: 1 addition & 6 deletions src/celeritas/ext/GeantSetup.hh
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,8 @@ class GeantSetup
// Terminate run on destruction
~GeantSetup();

//!@{
//! Prevent copying but allow moving
GeantSetup(GeantSetup const&) = delete;
GeantSetup& operator=(GeantSetup const&) = delete;
GeantSetup(GeantSetup&&) = default;
GeantSetup& operator=(GeantSetup&&) = default;
//!@}
CELER_DEFAULT_MOVE_DELETE_COPY(GeantSetup);

// Get the world detector volume
inline G4VPhysicalVolume const* world() const;
Expand Down
28 changes: 14 additions & 14 deletions src/celeritas/field/FieldDriverOptionsIO.json.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <string>
#include <nlohmann/json.hpp>

#include "corecel/io/JsonUtils.json.hh"

#include "FieldDriverOptions.hh"

namespace celeritas
Expand Down Expand Up @@ -49,22 +51,20 @@ void from_json(nlohmann::json const& j, FieldDriverOptions& opts)
*/
void to_json(nlohmann::json& j, FieldDriverOptions const& opts)
{
#define FDO_PAIR(FIELD) {#FIELD, opts.FIELD}
j = nlohmann::json{
FDO_PAIR(minimum_step),
FDO_PAIR(delta_chord),
FDO_PAIR(delta_intersection),
FDO_PAIR(epsilon_step),
FDO_PAIR(epsilon_rel_max),
FDO_PAIR(errcon),
FDO_PAIR(pgrow),
FDO_PAIR(pshrink),
FDO_PAIR(safety),
FDO_PAIR(max_stepping_increase),
FDO_PAIR(max_stepping_decrease),
FDO_PAIR(max_nsteps),
CELER_JSON_PAIR(opts, minimum_step),
CELER_JSON_PAIR(opts, delta_chord),
CELER_JSON_PAIR(opts, delta_intersection),
CELER_JSON_PAIR(opts, epsilon_step),
CELER_JSON_PAIR(opts, epsilon_rel_max),
CELER_JSON_PAIR(opts, errcon),
CELER_JSON_PAIR(opts, pgrow),
CELER_JSON_PAIR(opts, pshrink),
CELER_JSON_PAIR(opts, safety),
CELER_JSON_PAIR(opts, max_stepping_increase),
CELER_JSON_PAIR(opts, max_stepping_decrease),
CELER_JSON_PAIR(opts, max_nsteps),
};
#undef FDO_PAIR
}

//---------------------------------------------------------------------------//
Expand Down
21 changes: 10 additions & 11 deletions src/celeritas/field/RZMapFieldInputIO.json.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <vector>

#include "corecel/cont/Range.hh"
#include "corecel/io/JsonUtils.json.hh"
#include "corecel/io/Logger.hh"
#include "celeritas/Quantities.hh"

Expand Down Expand Up @@ -142,20 +143,18 @@ void from_json(nlohmann::json const& j, RZMapFieldInput& inp)
*/
void to_json(nlohmann::json& j, RZMapFieldInput const& inp)
{
#define RZFI_KEY_VALUE(NAME) {#NAME, inp.NAME}
j = {
{"_units", units::NativeTraits::label()},
RZFI_KEY_VALUE(num_grid_z),
RZFI_KEY_VALUE(num_grid_r),
RZFI_KEY_VALUE(min_z),
RZFI_KEY_VALUE(min_r),
RZFI_KEY_VALUE(max_z),
RZFI_KEY_VALUE(max_r),
RZFI_KEY_VALUE(field_z),
RZFI_KEY_VALUE(field_r),
RZFI_KEY_VALUE(driver_options),
CELER_JSON_PAIR(inp, num_grid_z),
CELER_JSON_PAIR(inp, num_grid_r),
CELER_JSON_PAIR(inp, min_z),
CELER_JSON_PAIR(inp, min_r),
CELER_JSON_PAIR(inp, max_z),
CELER_JSON_PAIR(inp, max_r),
CELER_JSON_PAIR(inp, field_z),
CELER_JSON_PAIR(inp, field_r),
CELER_JSON_PAIR(inp, driver_options),
};
#undef RZFI_KEY_VALUE
}

//---------------------------------------------------------------------------//
Expand Down
12 changes: 12 additions & 0 deletions src/corecel/Macros.hh
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,18 @@
CLS(CLS&&) = delete; \
CLS& operator=(CLS&&) = delete

/*!
* \def CELER_DEFAULT_MOVE_DELETE_COPY
*
* Explicitly declare defaulted copy and move constructors and assignment
* operators. Use this if the destructor is declared explicitly.
*/
#define CELER_DEFAULT_MOVE_DELETE_COPY(CLS) \
CLS(CLS const&) = delete; \
CLS& operator=(CLS const&) = delete; \
CLS(CLS&&) = default; \
CLS& operator=(CLS&&) = default

/*!
* \def CELER_DISCARD
*
Expand Down
9 changes: 2 additions & 7 deletions src/corecel/data/CollectionStateStore.hh
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,8 @@ class CollectionStateStore
template<Ownership W2, MemSpace M2>
inline CollectionStateStore& operator=(S<W2, M2> const& other);

//!@{
//! Default copy/move construction/assignment
CollectionStateStore(CollectionStateStore const&) = default;
CollectionStateStore& operator=(CollectionStateStore const&) = default;
CollectionStateStore(CollectionStateStore&&) = default;
CollectionStateStore& operator=(CollectionStateStore&&) = default;
//!@}
//! Default move, delete copy (since ref "points to" val)
CELER_DEFAULT_MOVE_DELETE_COPY(CollectionStateStore);

//! Whether any data is being stored
explicit operator bool() const { return static_cast<bool>(val_); }
Expand Down
9 changes: 9 additions & 0 deletions src/corecel/io/JsonUtils.json.hh
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@
OBJ[#NAME] = nullptr; \
} \
} while (0)

/*!
* Construct a key/value pair for a JSON object.
*/
#define CELER_JSON_PAIR(STRUCT, NAME) \
{ \
#NAME, STRUCT.NAME \
}

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

namespace celeritas
Expand Down
7 changes: 1 addition & 6 deletions src/corecel/io/detail/LoggerMessage.hh
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,8 @@ class LoggerMessage
// Flush message on destruction
inline ~LoggerMessage();

//!@{
//! Prevent copying but allow moving
LoggerMessage(LoggerMessage const&) = delete;
LoggerMessage& operator=(LoggerMessage const&) = delete;
LoggerMessage(LoggerMessage&&) = default;
LoggerMessage& operator=(LoggerMessage&&) = default;
//!@}
CELER_DEFAULT_MOVE_DELETE_COPY(LoggerMessage);

// Write the object to the stream if applicable
template<class T>
Expand Down
133 changes: 133 additions & 0 deletions src/corecel/math/ArraySoftUnit.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
//----------------------------------*-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 corecel/math/ArraySoftUnit.hh
//---------------------------------------------------------------------------//
#pragma once

#include <cmath>

#include "corecel/Types.hh"
#include "corecel/cont/Array.hh"

#include "detail/SoftEqualTraits.hh"

namespace celeritas
{
//---------------------------------------------------------------------------//
/*!
* Test for being approximately a unit vector.
*
* Consider a unit vector \em v with a small perturbation along a unit vector
* \em e : \f[
\vec v + \epsilon \vec e
\f]
* The magnitude squared is
* \f[
m^2 = (v + \epsilon e) \cdot (v + \epsilon e)
= v \cdot v + 2 \epsilon v \cdot e + \epsilon^2 e \cdot e
= 1 + 2 \epsilon v \cdot e + \epsilon^2
\f]
*
* Since \f[ |v \cdot e| <= |v||e| = 1 \f] by the triangle inequality,
* then the magnitude squared of a perturbed unit vector is bounded
* \f[
m^2 = 1 \pm 2 \epsilon + \epsilon^2
\f]
*
* Instead of calculating the square of the tolerance we loosely bound with
* another epsilon.
*/
template<class T = ::celeritas::real_type>
class ArraySoftUnit
{
public:
//!@{
//! \name Type aliases
using value_type = T;
//!@}

public:
// Construct with explicit tolerance
CELER_FUNCTION inline ArraySoftUnit(value_type tol);

// Construct with default tolerance
CELER_CONSTEXPR_FUNCTION ArraySoftUnit();

// Calculate whether the array is nearly a unit vector
template<::celeritas::size_type N>
CELER_CONSTEXPR_FUNCTION bool operator()(Array<T, N> const& arr) const;

private:
value_type tol_;
};

//---------------------------------------------------------------------------//
// TEMPLATE DEDUCTION GUIDES
//---------------------------------------------------------------------------//
template<class T>
CELER_FUNCTION ArraySoftUnit(T) -> ArraySoftUnit<T>;

//---------------------------------------------------------------------------//
// FREE FUNCTIONS
//---------------------------------------------------------------------------//
// Test for being approximately a unit vector
template<class T, size_type N>
CELER_CONSTEXPR_FUNCTION bool is_soft_unit_vector(Array<T, N> const& v);

//---------------------------------------------------------------------------//
// INLINE DEFINITIONS
//---------------------------------------------------------------------------//
/*!
* Construct with explicit tolereance.
*/
template<class T>
CELER_FUNCTION ArraySoftUnit<T>::ArraySoftUnit(T tol) : tol_{3 * tol}
{
CELER_EXPECT(tol_ > 0);
}

//---------------------------------------------------------------------------//
/*!
* Construct with default tolereance.
*/
template<class T>
CELER_CONSTEXPR_FUNCTION ArraySoftUnit<T>::ArraySoftUnit()
: tol_{3 * detail::SoftEqualTraits<T>::rel_prec()}
{
}

//---------------------------------------------------------------------------//
/*!
* Calculate whether the array is nearly a unit vector.
*
* The calculation below is equivalent to
* \code
* return SoftEqual{tol, tol}(1, dot_product(arr, arr));
* \endcode.
*/
template<class T>
template<::celeritas::size_type N>
CELER_CONSTEXPR_FUNCTION bool
ArraySoftUnit<T>::operator()(Array<T, N> const& arr) const
{
T length_sq{};
for (size_type i = 0; i != N; ++i)
{
length_sq = std::fma(arr[i], arr[i], length_sq);
}
return std::fabs(length_sq - 1) < tol_ * std::fmax(real_type(1), length_sq);
}

//---------------------------------------------------------------------------//
//! Test with default tolerance for being a unit vector
template<class T, size_type N>
CELER_CONSTEXPR_FUNCTION bool is_soft_unit_vector(Array<T, N> const& v)
{
return ArraySoftUnit<T>{}(v);
}

//---------------------------------------------------------------------------//
} // namespace celeritas
44 changes: 2 additions & 42 deletions src/corecel/math/ArrayUtils.hh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
#include "corecel/cont/Array.hh"

#include "Algorithms.hh"
#include "ArraySoftUnit.hh"
#include "SoftEqual.hh"

#include "detail/ArrayUtilsImpl.hh"

namespace celeritas
Expand Down Expand Up @@ -66,11 +68,6 @@ template<class T>
[[nodiscard]] inline CELER_FUNCTION Array<T, 3>
rotate(Array<T, 3> const& dir, Array<T, 3> const& rot);

//---------------------------------------------------------------------------//
// Test for being approximately a unit vector
template<class T, size_type N>
inline CELER_FUNCTION bool is_soft_unit_vector(Array<T, N> const& v);

//---------------------------------------------------------------------------//
// INLINE DEFINITIONS
//---------------------------------------------------------------------------//
Expand Down Expand Up @@ -264,42 +261,5 @@ rotate(Array<T, 3> const& dir, Array<T, 3> const& rot)
return make_unit_vector(result);
}

//---------------------------------------------------------------------------//
/*!
* Test for being approximately a unit vector.
*
* Consider a unit vector \em v with a small perturbation along a unit vector
* \em e : \f[
\vec v + \epsilon \vec e
\f]
* The magnitude squared is
* \f[
m^2 = (v + \epsilon e) \cdot (v + \epsilon e)
= v \cdot v + 2 \epsilon v \cdot e + \epsilon^2 e \cdot e
= 1 + 2 \epsilon v \cdot e + \epsilon^2
\f]
*
* Since \f[ |v \cdot e| <= |v||e| = 1 \f] by the triangle inequality,
* then the magnitude squared of a perturbed unit vector is bounded
* \f[
m^2 = 1 \pm 2 \epsilon + \epsilon^2
\f]
*
* Instead of calculating the square of the tolerance we loosely bound with
* another epsilon.
*
* Example:
* \code
CELER_EXPECT(is_soft_unit_vector(v));
* \endcode
*/
template<class T, size_type N>
CELER_FUNCTION bool is_soft_unit_vector(Array<T, N> const& v)
{
constexpr SoftEqual<T> default_soft_eq;
SoftEqual cmp{3 * default_soft_eq.rel(), 3 * default_soft_eq.abs()};
return cmp(T{1}, dot_product(v, v));
}

//---------------------------------------------------------------------------//
} // namespace celeritas
9 changes: 2 additions & 7 deletions src/corecel/sys/ScopedMem.hh
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,8 @@ class ScopedMem
// Register data on destruction
~ScopedMem();

//!@{
//! Default move assign and construct; no copying
ScopedMem(ScopedMem&&) = default;
ScopedMem(ScopedMem const&) = delete;
ScopedMem& operator=(ScopedMem&&) = default;
ScopedMem& operator=(ScopedMem const&) = delete;
//!@}
//! Prevent copying but allow moving
CELER_DEFAULT_MOVE_DELETE_COPY(ScopedMem);

private:
using value_type = KibiBytes::value_type;
Expand Down

0 comments on commit 55dbb28

Please sign in to comment.