Loading [MathJax]/extensions/TeX/AMSmath.js
ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
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) noexcept
Create a vector that has all entries set to the same value.
Definition Vector.hpp:111
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:380
Meta function to turns a Vector<1, T> into T.
Definition Vector.hpp:479