ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
Interpolated.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef CORE_EXTERNAL_FIELD_FIELDS_INTERPOLATED_HPP
20#define CORE_EXTERNAL_FIELD_FIELDS_INTERPOLATED_HPP
21
25
26#include "jacobian_type.hpp"
27#include <utils/Vector.hpp>
28
29/* Turn off range checks if release build. */
30#if defined(NDEBUG) && !defined(BOOST_DISABLE_ASSERTS)
31#define BOOST_DISABLE_ASSERTS
32#endif
33#include <boost/multi_array.hpp>
34
35#include <array>
36#include <cstddef>
37#include <vector>
38
39namespace FieldCoupling {
40namespace Fields {
41namespace detail {
42template <typename T>
43void deep_copy(boost::multi_array<T, 3> &dst,
44 const boost::multi_array<T, 3> &src) {
45 auto *s = src.shape();
46 dst.resize(boost::extents[s[0]][s[1]][s[2]]);
47 dst = src;
48
49 auto *b = src.index_bases();
50 dst.reindex(std::array<typename boost::multi_array<T, 3>::index, 3>{
51 {b[0], b[1], b[2]}});
52}
53} // namespace detail
54
55/**
56 * @brief A vector or scalar field interpolated from a regular grid.
57 *
58 * This is an interpolation wrapper around a boost::multi_array,
59 * which can be evaluated on any point in space by spline interpolation.
60 *
61 * @tparam T Underlying type of the field values, see @ref value_type
62 * @tparam codim Dimension of the field: 3 for a vector field,
63 * 1 for a scalar field.
64 */
65template <typename T, std::size_t codim> class Interpolated {
66public:
67 /** Type of the values, usually @ref Utils::Vector<T, 3> for vector fields
68 * and @p T for scalar fields
69 */
70 using value_type =
72 using jacobian_type = detail::jacobian_type<T, codim>;
73 using storage_type = boost::multi_array<value_type, 3>;
74
75private:
76 storage_type m_global_field;
77 Utils::Vector3d m_grid_spacing;
78 Utils::Vector3d m_origin;
79
80public:
81 Interpolated(const boost::const_multi_array_ref<value_type, 3> &global_field,
84 : m_global_field(global_field), m_grid_spacing(grid_spacing),
85 m_origin(origin) {}
86
87private:
88 void copy(const Interpolated &rhs) {
89 detail::deep_copy(m_global_field, rhs.m_global_field);
90
91 m_grid_spacing = rhs.m_grid_spacing;
92 m_origin = rhs.m_origin;
93 }
94
95public:
96 Interpolated(const Interpolated &rhs) { copy(rhs); }
98 copy(rhs);
99 return *this;
100 }
101
102 Utils::Vector3d grid_spacing() const { return m_grid_spacing; }
103 storage_type const &field_data() const { return m_global_field; }
104 Utils::Vector3d origin() const { return m_origin; }
106 return {m_global_field.shape(), m_global_field.shape() + 3};
107 }
108
109 /** Serialize field */
110 std::vector<T> field_data_flat() const {
111 auto const *data = reinterpret_cast<T const *>(m_global_field.data());
112 return std::vector<T>(data, data + codim * m_global_field.num_elements());
113 }
114
115 /*
116 * @brief Evaluate f at pos with the field value as argument.
117 */
118 value_type operator()(const Utils::Vector3d &pos, double = {}) const {
120 return bspline_3d_accumulate<2>(
121 pos,
122 [this](const std::array<int, 3> &ind) { return m_global_field(ind); },
123 m_grid_spacing, m_origin, value_type{});
124 }
125
126 /*
127 * @brief Evaluate f at pos with the jacobian field value as argument.
128 */
129 jacobian_type jacobian(const Utils::Vector3d &pos, double = {}) const {
131 return bspline_3d_gradient_accumulate<2>(
132 pos,
133 [this](const std::array<int, 3> &ind) { return m_global_field(ind); },
134 m_grid_spacing, m_origin, jacobian_type{});
135 }
136
137 bool fits_in_box(const Utils::Vector3d &box) const {
138 auto const box_shape = shape();
139 auto const grid_size = Utils::hadamard_product(m_grid_spacing, box_shape);
140 return (m_origin < Utils::Vector3d::broadcast(0.)) &&
141 ((m_origin + grid_size) >= box);
142 }
143};
144} // namespace Fields
145} // namespace FieldCoupling
146
147#endif
Vector implementation and trait types for boost qvm interoperability.
A vector or scalar field interpolated from a regular grid.
typename Utils::decay_to_scalar< Utils::Vector< T, codim > >::type value_type
Type of the values, usually Utils::Vector<T, 3> for vector fields and T for scalar fields.
bool fits_in_box(const Utils::Vector3d &box) const
Interpolated & operator=(const Interpolated &rhs)
value_type operator()(const Utils::Vector3d &pos, double={}) const
Interpolated(const Interpolated &rhs)
std::vector< T > field_data_flat() const
Serialize field.
Interpolated(const boost::const_multi_array_ref< value_type, 3 > &global_field, const Utils::Vector3d &grid_spacing, const Utils::Vector3d &origin)
storage_type const & field_data() const
jacobian_type jacobian(const Utils::Vector3d &pos, double={}) const
detail::jacobian_type< T, codim > jacobian_type
boost::multi_array< value_type, 3 > storage_type
Utils::Vector3d grid_spacing() const
static DEVICE_QUALIFIER constexpr Vector< T, N > broadcast(typename Base::value_type const &value)
Create a vector that has all entries set to the same value.
Definition Vector.hpp:110
T bspline_3d_accumulate(Vector3d const &pos, Kernel const &kernel, Vector3d const &grid_spacing, Vector3d const &offset, T const &init)
cardinal B-spline weighted sum.
T bspline_3d_gradient_accumulate(Vector3d const &pos, Kernel const &kernel, Vector3d const &grid_spacing, Vector3d const &offset, T const &init)
cardinal B-spline weighted sum.
auto hadamard_product(Vector< T, N > const &a, Vector< U, N > const &b)
Definition Vector.hpp:379
Meta function to turns a Vector<1, T> into T.
Definition Vector.hpp:478