OGS
AnchorTerm.cpp
Go to the documentation of this file.
1
11#include "AnchorTerm.h"
12
13#include <Eigen/Core>
14#include <cassert>
15
18
19namespace ProcessLib
20{
21template <int GlobalDim>
23 std::unique_ptr<NumLib::LocalToGlobalIndexMap> source_term_dof_table,
24 std::size_t const source_term_mesh_id,
25 MeshLib::Mesh const& st_mesh,
26 const int variable_id,
27 ParameterLib::Parameter<double> const& parameter)
28 : SourceTerm(std::move(source_term_dof_table)),
29 source_term_mesh_id_(source_term_mesh_id),
30 st_mesh_(st_mesh),
31 variable_id_(variable_id),
32 parameter_(parameter)
33{
34 DBUG("Create AnchorTerm.");
35}
36
37template <int GlobalDim>
38void AnchorTerm<GlobalDim>::integrate(const double t, GlobalVector const& x,
39 GlobalVector& b, GlobalMatrix* jac) const
40{
41 DBUG("Assemble AnchorTerm.");
42
43 using GlobalDimVector = Eigen::Vector<double, GlobalDim>;
44 using GlobalDimMatrix = Eigen::Matrix<double, GlobalDim, GlobalDim>;
45
46 for (MeshLib::Element const* const element : st_mesh_.getElements())
47 {
48 auto const element_id = element->getID();
49
51 pos.setElementID(element_id);
52
53 std::vector<GlobalIndexType> const global_indices =
54 NumLib::getIndices(element_id, *_source_term_dof_table);
55 assert(global_indices.size() == 2 * GlobalDim);
56
57 Eigen::Vector<double, 2 * GlobalDim> const local_x =
58 MathLib::toVector(x.get(global_indices));
59
60 Eigen::Vector<double, 2 * GlobalDim> local_rhs =
61 Eigen::Vector<double, 2 * GlobalDim>::Zero();
62 Eigen::Matrix<double, 2 * GlobalDim, 2 * GlobalDim> local_Jac =
63 Eigen::Matrix<double, 2 * GlobalDim, 2 * GlobalDim>::Zero();
64
65 // The local indices are, due to the nature of the DOF table, all even
66 // for the first node and odd for the second node.
67 auto node_local_indices = [](int const i)
68 { return Eigen::seqN(i, Eigen::fix<GlobalDim>, Eigen::fix<2>); };
69
70 auto node_coords = [element](int const i)
71 { return element->getNode(i)->asEigenVector3d(); };
72 GlobalDimVector const l_original =
73 (node_coords(1) - node_coords(0)).template head<GlobalDim>();
74 double const l_original_norm = l_original.norm();
75
76 // Displacement in the two nodes.
77 auto u = [&local_x, &node_local_indices](int const i)
78 { return local_x(node_local_indices(i)); };
79 GlobalDimVector const l = l_original + u(1) - u(0);
80
81 double const K = parameter_(t, pos)[0];
82 GlobalDimVector const f = l_original / l_original_norm * K *
83 (l.norm() - l_original_norm) /
84 l_original_norm;
85
86 GlobalDimMatrix const Df = l_original / l_original_norm * K *
87 l.transpose() / l.norm() / l_original_norm;
88
89 // Signs for the two nodes alternate.
90 constexpr auto even_odd_sign = [](int const n)
91 { return (n % 2 == 0) ? 1.0 : -1.0; };
92
93 // There are two blocks in the rhs vector for the two nodes of the
94 // element and four blocks in the local Jacobian formed by the four
95 // combinations of the two nodes.
96 for (int i = 0; i < 2; ++i)
97 {
98 local_rhs(node_local_indices(i)).noalias() += even_odd_sign(i) * f;
99
100 for (int j = 0; j < 2; ++j)
101 {
102 local_Jac(node_local_indices(i), node_local_indices(j))
103 .noalias() += even_odd_sign(i) * even_odd_sign(j) * Df;
104 }
105 }
106
107 b.add(global_indices, local_rhs);
108 if (jac)
109 {
110 jac->add({global_indices, global_indices}, local_Jac);
111 }
112 }
113}
114
115template class AnchorTerm<2>;
116template class AnchorTerm<3>;
117
118} // namespace ProcessLib
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:30
int add(IndexType row, IndexType col, double val)
Definition EigenMatrix.h:87
Global vector based on Eigen vector.
Definition EigenVector.h:25
void add(IndexType rowId, double v)
add entry
Definition EigenVector.h:76
double get(IndexType rowId) const
get entry
Definition EigenVector.h:58
void setElementID(std::size_t element_id)
void integrate(const double t, GlobalVector const &x, GlobalVector &b, GlobalMatrix *jac) const override
AnchorTerm(std::unique_ptr< NumLib::LocalToGlobalIndexMap > source_term_dof_table, std::size_t const source_term_mesh_id, MeshLib::Mesh const &st_mesh, const int variable_id, ParameterLib::Parameter< double > const &parameter)
Eigen::Map< const Vector > toVector(std::vector< double > const &data, Eigen::VectorXd::Index size)
Creates an Eigen mapped vector from the given data vector.
std::vector< GlobalIndexType > getIndices(std::size_t const mesh_item_id, NumLib::LocalToGlobalIndexMap const &dof_table)