Medusa  1.1
Coordinate Free Mehless Method implementation
ExplicitVectorOperators.hpp
Go to the documentation of this file.
1 #ifndef MEDUSA_BITS_OPERATORS_EXPLICITVECTOROPERATORS_HPP_
2 #define MEDUSA_BITS_OPERATORS_EXPLICITVECTOROPERATORS_HPP_
3 
11 #include <Eigen/Core>
12 #include "ShapeStorage_fwd.hpp"
13 
14 namespace mm {
15 
21 #define NODE_ASSERTS(node) \
22  assert_msg(0 <= (node) && (node) < ss->size(), "Node index %d must be in range " \
23  "[0, num_nodes = %d).", ss->size());
24 
26 template <class shape_storage_type>
27 template <class vector_field_t>
32 ExplicitVectorOperators<shape_storage_type>::grad(const vector_field_t& u, int node) const {
33  NODE_ASSERTS(node);
34  constexpr int vector_dim = vector_type<vector_field_t>::type::dim;
35  constexpr int domain_dim = ExplicitVectorOperators<shape_storage_type>::dim;
37  for (int d = 0; d < vector_dim; ++d) {
38  for (int var = 0; var < domain_dim; ++var) {
39  ret(d, var) = ss->d1(var, node, 0) * u[ss->support(node, 0)][d];
40  for (int i = 1; i < ss->supportSize(node); ++i) {
41  ret(d, var) += ss->d1(var, node, i) * u[ss->support(node, i)][d];
42  }
43  }
44  }
45  return ret;
46 }
47 
48 template <class shape_storage_type>
49 template <typename op_family_t, typename vector_field_t>
51 ExplicitVectorOperators<shape_storage_type>::apply(const vector_field_t& u, int node,
52  typename op_family_t::operator_t o) const {
53  constexpr int u_dim = vector_type<vector_field_t>::type::dim;
55  res.setZero();
56  int idx = op_family_t::index(o);
57  for (int i = 0; i < ss->supportSize(node); ++i) {
58  for (int d = 0; d < u_dim; ++d) {
59  res[d] += ss->template get<op_family_t>(idx, node, i) * u[ss->support(node, i)][d];
60  }
61  }
62  return res;
63 }
64 
65 template <class shape_storage_type>
66 template <class vector_field_t>
68 ExplicitVectorOperators<shape_storage_type>::div(const vector_field_t& u, int node) const {
69  NODE_ASSERTS(node);
70  static_assert(static_cast<int>(dim) == static_cast<int>(vector_type<vector_field_t>::type::dim),
71  "Domain and filed dimensions must match.");
73  ss->d1(0, node, 0) * u[ss->support(node, 0)][0];
74  for (int i = 1; i < ss->supportSize(node); ++i)
75  ret += ss->d1(0, node, i) * u[ss->support(node, i)][0];
76  for (int var = 1; var < dim; ++var)
77  for (int i = 0; i < ss->supportSize(node); ++i)
78  ret += ss->d1(var, node, i) * u[ss->support(node, i)][var];
79  return ret;
80 }
81 
82 template <class shape_storage_type>
83 template <class vector_field_t>
85 ExplicitVectorOperators<shape_storage_type>::curl(const vector_field_t& u, int node) const {
86  NODE_ASSERTS(node);
87  static_assert(static_cast<int>(vector_type<vector_field_t>::type::dim) == 3,
88  "The field must be three dimensional.");
90  ret.setZero();
91  for (int i = 0; i < ss->supportSize(node); ++i) {
92  ret[0] += ss->d1(1, node, i) * u[ss->support(node, i)][2]
93  - ss->d1(2, node, i) * u[ss->support(node, i)][1];
94  ret[1] += ss->d1(2, node, i) * u[ss->support(node, i)][0]
95  - ss->d1(0, node, i) * u[ss->support(node, i)][2];
96  ret[2] += ss->d1(0, node, i) * u[ss->support(node, i)][1]
97  - ss->d1(1, node, i) * u[ss->support(node, i)][0];
98  }
99  return ret;
100 }
101 
102 template <class shape_storage_type>
103 template <class vector_field_t>
105 ExplicitVectorOperators<shape_storage_type>::graddiv(const vector_field_t& u, int node) const {
106  NODE_ASSERTS(node);
107  static_assert(static_cast<int>(dim) == static_cast<int>(vector_type<vector_field_t>::type::dim),
108  "Domain and filed dimensions must match.");
110  ret.setZero();
111  for (int d1 = 0; d1 < dim; ++d1) {
112  for (int d2 = 0; d2 < dim; ++d2) { // loop over dimensions
113  int dmin = std::min(d1, d2);
114  int dmax = std::max(d1, d2);
115  for (int i = 0; i < ss->supportSize(node); ++i) {
116  ret[d1] += ss->d2(dmin, dmax, node, i) * u[ss->support(node, i)][d2];
117  }
118  }
119  }
120  return ret;
121 }
122 
123 template <class shape_storage_type>
124 template <class vector_field_t>
127  const vector_field_t& u, int node, const vector_t& normal,
128  typename vector_type<vector_field_t>::type val) const {
129  NODE_ASSERTS(node);
130  static_assert(static_cast<int>(dim) == static_cast<int>(vector_type<vector_field_t>::type::dim),
131  "Domain and filed dimensions must match.");
132  assert_msg(ss->support(node, 0) == node, "First support node should be the node itself.");
133  scalar_t denominator = 0;
134  for (int d = 0; d < dim; ++d) {
135  for (int i = 1; i < ss->supportSize(node); ++i) {
136  val -= normal[d] * ss->d1(d, node, i) * u[ss->support(node, i)];
137  }
138  // i = 0
139  denominator += normal[d] * ss->d1(d, node, 0);
140  }
141  assert_msg(std::abs(denominator) >= 1e-14,
142  "Node %d has no effect on the flux in direction %s. The cause of this might be wrong"
143  " normal direction, bad neighbourhood choice or bad nodal positions.", node, normal);
144  return val / denominator;
145 }
146 
148 
150 template <typename S>
151 std::ostream& operator<<(std::ostream& os, const ExplicitVectorOperators<S>& op) {
152  if (!op.hasShapes()) {
153  return os << "Explicit vector operators without any linked storage.";
154  }
155  return os << "Explicit vector operators over storage: " << *op.ss;
156 }
157 
158 template <typename Derived, typename vec_t, typename OpFamilies>
159 ExplicitVectorOperators<Derived>
161  return ExplicitVectorOperators<Derived>(*static_cast<const Derived*>(this));
162 }
163 
164 } // namespace mm
165 
166 #endif // MEDUSA_BITS_OPERATORS_EXPLICITVECTOROPERATORS_HPP_
mm::sh::d1
static const shape_flags d1
Indicates to calculate d1 shapes.
Definition: shape_flags.hpp:23
mm::ExplicitVectorOperators::ss
const shape_storage_t * ss
Pointer to shape storage, but name is shortened for readability.
Definition: ExplicitVectorOperators_fwd.hpp:48
mm
Root namespace for the whole library.
Definition: Gaussian.hpp:14
scalar_t
Scalar scalar_t
Type of the elements, alias of Scalar.
Definition: MatrixBaseAddons.hpp:16
mm::vector_type::type
void type
By default invalid underlying vector type. Must be specified for each type separately.
Definition: traits.hpp:31
ShapeStorage_fwd.hpp
mm::ExplicitVectorOperators::graddiv
vector_type< vector_field_t >::type graddiv(const vector_field_t &u, int node) const
Returns gradient of divergence of a vector field u in in node with index node.
dim
@ dim
Number of elements of this matrix.
Definition: MatrixBaseAddons.hpp:14
mm::operator<<
std::ostream & operator<<(std::ostream &os, const Gaussian< S > &b)
Output basic information about given Gaussian RBF.
Definition: Gaussian.hpp:37
assert_msg
#define assert_msg(cond,...)
Assert with better error reporting.
Definition: assert.hpp:75
mm::ExplicitVectorOperators
A class for evaluating typical operators needed in spatial discretization.
Definition: ExplicitVectorOperators_fwd.hpp:38
mm::sh::d2
static const shape_flags d2
Indicates to calculate d2 shapes.
Definition: shape_flags.hpp:25
NODE_ASSERTS
#define NODE_ASSERTS(node)
Performs all asserts for a given node: asserts that node index is valid and that shape functions were...
Definition: ExplicitVectorOperators.hpp:21
mm::ExplicitVectorOperators::dim
@ dim
Dimensionality of the function domain.
Definition: ExplicitVectorOperators_fwd.hpp:44
ExplicitVectorOperators_fwd.hpp
mm::ShapeStorage::explicitVectorOperators
ExplicitVectorOperators< Derived > explicitVectorOperators() const
Construct explicit vector operators over this storage.
Definition: ExplicitVectorOperators.hpp:160
assert.hpp
mm::ExplicitVectorOperators::curl
vector_type< vector_field_t >::type curl(const vector_field_t &u, int node) const
Returns curl of a vector field u in node with index node.
mm::ExplicitVectorOperators::neumann
vector_type< vector_field_t >::type neumann(const vector_field_t &u, int node, const vector_t &normal, typename vector_type< vector_field_t >::type val) const
This is a vectorised version of ExplicitOperators::neumann.
mm::ExplicitVectorOperators::hasShapes
bool hasShapes() const
Returns true if operators have a non-null pointer to storage and false otherwise.
Definition: ExplicitVectorOperators_fwd.hpp:72
mm::ExplicitVectorOperators::grad
Eigen::Matrix< typename vector_type< vector_field_t >::type::scalar_t, vector_type< vector_field_t >::type::dim, dim > grad(const vector_field_t &u, int node) const
Returns gradient of vector field u in node with index node.
mm::ExplicitVectorOperators::div
vector_type< vector_field_t >::type::scalar_t div(const vector_field_t &u, int node) const
Returns divergence of a vector field u in in node with index node.
Matrix
Matrix(const Scalar &s)
Construct matrix from scalar. Enabled only for fixed size matrices.
Definition: MatrixAddons.hpp:21
mm::ExplicitVectorOperators::apply
vector_type< vector_field_t >::type apply(const vector_field_t &u, int node, typename op_family_t::operator_t o) const
Returns an approximation of applying the requested operator to each component of field u at node node...