1 #ifndef MEDUSA_BITS_OPERATORS_EXPLICITVECTOROPERATORS_HPP_
2 #define MEDUSA_BITS_OPERATORS_EXPLICITVECTOROPERATORS_HPP_
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());
26 template <
class shape_storage_type>
27 template <
class vector_field_t>
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];
48 template <
class shape_storage_type>
49 template <
typename op_family_t,
typename vector_field_t>
52 typename op_family_t::operator_t o)
const {
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];
65 template <
class shape_storage_type>
66 template <
class vector_field_t>
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];
82 template <
class shape_storage_type>
83 template <
class vector_field_t>
88 "The field must be three dimensional.");
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];
102 template <
class shape_storage_type>
103 template <
class vector_field_t>
108 "Domain and filed dimensions must match.");
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];
123 template <
class shape_storage_type>
124 template <
class vector_field_t>
127 const vector_field_t& u,
int node,
const vector_t& normal,
131 "Domain and filed dimensions must match.");
132 assert_msg(ss->support(node, 0) == node,
"First support node should be the node itself.");
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)];
139 denominator += normal[d] * ss->d1(d, node, 0);
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;
150 template <
typename S>
153 return os <<
"Explicit vector operators without any linked storage.";
155 return os <<
"Explicit vector operators over storage: " << *op.
ss;
158 template <
typename Derived,
typename vec_t,
typename OpFamilies>
159 ExplicitVectorOperators<Derived>
166 #endif // MEDUSA_BITS_OPERATORS_EXPLICITVECTOROPERATORS_HPP_