Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
TrialBase.h
Go to the documentation of this file.
1/* This file is part of MoDELib, the Mechanics Of Defects Evolution Library.
2 *
3 *
4 * MoDELib is distributed without any warranty under the
5 * GNU General Public License (GPL) v2 <http://www.gnu.org/licenses/>.
6 */
7
8#ifndef model_TrialBase_H_
9#define model_TrialBase_H_
10
11#include <iostream>
12
13#include <type_traits>
14#include <map>
15#include <cfloat>
16#include <Eigen/Dense>
17#include <TypeTraits.h>
18#include <TerminalColors.h>
19
20namespace model
21{
22
23 template<typename _TrialFunctionType>
25 {
26
27 public:
28 typedef double Scalar;
30 typedef typename FiniteElementType::MeshType MeshType;
33
35 typedef _TrialFunctionType TrialFunctionType;
36 static constexpr int dim=ElementType::dim;
37 static constexpr int nodesPerElement=ElementType::nodesPerElement;
40
41 typedef std::map<size_t,std::array<bool,TypeTraits<TrialFunctionType>::dofPerNode>> DirichletNodeMapType;
42 typedef std::map<size_t,double> DirichletConditionContainerType;
43
44 private:
45 struct State
46 {
47 std::shared_ptr<FiniteElementType> owner;
48 FiniteElementType* space;
49 std::weak_ptr<const int> lifetime;
50 Eigen::VectorXd dofvector;
51 Eigen::VectorXd periodicNodalOffset;
54 Eigen::Matrix<double,dofPerNode,dim> periodicGradient=Eigen::Matrix<double,dofPerNode,dim>::Zero();
55 explicit State(FiniteElementType& fe):
56 owner(fe.weak_from_this().lock()), space(&fe), lifetime(fe.lifetimeToken()),
57 dofvector(Eigen::VectorXd::Zero(fe.nodeSize()*dofPerNode)) {}
58 };
59 std::shared_ptr<State> state;
60 public:
61 explicit TrialBase(FiniteElementType& fe): state(std::make_shared<State>(fe)) {}
62 // Each field owns independent state; only shared pointers alias the field.
63 TrialBase(const TrialBase&)=delete;
65 const TrialBase& field() const
66 {
67 return *this;
68 }
69 std::shared_ptr<const void> ownership() const
70 {
71 return state;
72 }
73 bool sameField(const TrialBase& other) const
74 {
75 return state==other.state;
76 }
78 {
79 if(state->lifetime.expired())
80 {
81 throw std::runtime_error("FEM field outlived its borrowed space. Use a shared FEM space for retained expressions.");
82 }
83 state->space->validateMeshLifetime();
84 return *state->space;
85 }
86 size_t gSize() const
87 {
88 return nodeSize()*dofPerNode;
89 }
90
91 Eigen::Matrix<double,Eigen::Dynamic,1>& dofVector() const
92 {
93 return state->dofvector;
94 }
95
96 // Affine jump across a periodic translation p: x(X+p)-x(X)=gradient*p.
97 void setPeriodicGradient(const Eigen::Matrix<double,dofPerNode,dim>& gradient) const
98 {
99 if(!gradient.allFinite())
100 {
101 throw std::invalid_argument("Nonfinite FEM periodic gradient.");
102 }
103 state->periodicGradient=gradient;
104 }
105
106 const Eigen::Matrix<double,dofPerNode,dim>& periodicGradient() const
107 {
108 return state->periodicGradient;
109 }
110
111 // Optional known field whose differences supplement affine periodic jumps.
112 void setPeriodicNodalOffset(const Eigen::VectorXd& values) const
113 {
114 if((values.size()!=0 && values.size()!=Eigen::Index(gSize())) || !values.allFinite())
115 {
116 throw std::invalid_argument("Invalid FEM periodic nodal offset.");
117 }
118 state->periodicNodalOffset=values;
119 }
120 const Eigen::VectorXd& periodicNodalOffset() const
121 {
122 return state->periodicNodalOffset;
123 }
124
125 void setFullDofVector(const Eigen::VectorXd& values) const
126 {
127 if(values.size()!=Eigen::Index(gSize()) || !values.allFinite())
128 {
129 throw std::invalid_argument("Invalid full FEM DOF vector.");
130 }
131 state->dofvector=values;
132 }
133
134 Eigen::Matrix<double,dofPerNode,1> dofs(const NodeType& node) const
135 {
136 return state->dofvector.template segment<dofPerNode>(node.gID*dofPerNode);
137 }
138
139 Eigen::Matrix<double,dofPerNode,1> dofs(const size_t& gID) const
140 {
141 return state->dofvector.template segment<dofPerNode>(gID*dofPerNode);
142 }
143
144 Eigen::Matrix<double,dofPerElement,1> dofs(const ElementType& ele) const
145 {
146 Eigen::Matrix<double,dofPerElement,1> temp;
147 for(int n=0;n<nodesPerElement;++n)
148 {
149 temp.template segment<dofPerNode>(n*dofPerNode)=dofs(ele.node(n));
150 }
151 return temp;
152 }
153
154 const ElementType& element(const size_t& n) const
155 {
156 return fe().element(n);
157 }
158
159 const MeshType& mesh() const
160 {
161 return fe().mesh;
162 }
163
164 size_t elementSize() const
165 {
166 return fe().elementSize();
167 }
168
169 size_t nodeSize() const
170 {
171 return fe().nodeSize();
172 }
173
174 const NodeType& node(const size_t& n) const
175 {
176 return fe().node(n);
177 }
178
180 {
181 state->nodes.clear();
182 state->conditions.clear();
183 }
184
186 {
187 return state->nodes;
188 }
189
191 {
192 return state->conditions;
193 }
194
195 template<typename Condition>
196 void addDirichletCondition(const size_t& nodeListID,
197 const Condition& cond,
198 const std::array<bool,dofPerNode>& constrainDof) const
199 {
200
201 bool isConstrained(false);
202 for(int dof=0;dof<dofPerNode;++dof)
203 {
204 isConstrained+=constrainDof[dof];
205 }
206
207 if(isConstrained)
208 {
209
210 for(const auto& pNode : TrialBase<TrialFunctionType>::fe().nodeList(nodeListID))
211 {
212
213 Eigen::Matrix<double,dofPerNode,1> value(Eigen::Matrix<double,dofPerNode,1>::Zero());
214 cond(*pNode,value);
215
216 for(int dof=0;dof<dofPerNode;++dof)
217 {
218 state->nodes[pNode->gID][dof]+=constrainDof[dof];
219
220 if(constrainDof[dof])
221 {
222 const auto temp=state->conditions.emplace(dofPerNode*(pNode->gID)+dof,value(dof));
223
224 if(!(temp.second || std::abs(temp.first->second-value(dof))<FLT_EPSILON ))
225 {
226 std::cout<<"FEM node "<<pNode->gID<<", dof "<<dof<<std::endl;
227 std::cout<<"exising dirichlet-condition= "<<temp.first->second<<std::endl;
228 std::cout<<" new dirichlet-condition= "<<value(dof)<<std::endl;
229 throw std::runtime_error("Conflicting FEM Dirichlet conditions.");
230 }
231 }
232 }
233 }
234 }
235
236 }
237
238 };
239
240}
241#endif
size_t gSize() const
Definition TrialBase.h:86
TrialBase(TrialBase &&)=delete
Eigen::Matrix< double, Eigen::Dynamic, 1 > & dofVector() const
Definition TrialBase.h:91
TypeTraits< TrialFunctionType >::ElementType ElementType
Definition TrialBase.h:31
const NodeType & node(const size_t &n) const
Definition TrialBase.h:174
const Eigen::VectorXd & periodicNodalOffset() const
Definition TrialBase.h:120
DirichletConditionContainerType & dirichletConditions() const
Definition TrialBase.h:190
void addDirichletCondition(const size_t &nodeListID, const Condition &cond, const std::array< bool, dofPerNode > &constrainDof) const
Definition TrialBase.h:196
Eigen::Matrix< double, dofPerElement, 1 > dofs(const ElementType &ele) const
Definition TrialBase.h:144
void setFullDofVector(const Eigen::VectorXd &values) const
Definition TrialBase.h:125
static constexpr int dofPerElement
Definition TrialBase.h:39
static constexpr int nodesPerElement
Definition TrialBase.h:37
TypeTraits< TrialFunctionType >::FiniteElementType FiniteElementType
Definition TrialBase.h:29
TypeTraits< TrialFunctionType >::BaryType BaryType
Definition TrialBase.h:32
const Eigen::Matrix< double, dofPerNode, dim > & periodicGradient() const
Definition TrialBase.h:106
TrialBase(const TrialBase &)=delete
std::shared_ptr< const void > ownership() const
Definition TrialBase.h:69
TrialBase(FiniteElementType &fe)
Definition TrialBase.h:61
void clearDirichletConditions() const
Definition TrialBase.h:179
void setPeriodicGradient(const Eigen::Matrix< double, dofPerNode, dim > &gradient) const
Definition TrialBase.h:97
std::map< size_t, double > DirichletConditionContainerType
Definition TrialBase.h:42
TypeTraits< TrialFunctionType >::NodeType NodeType
Definition TrialBase.h:34
static constexpr int dofPerNode
Definition TrialBase.h:38
size_t nodeSize() const
Definition TrialBase.h:169
Eigen::Matrix< double, dofPerNode, 1 > dofs(const size_t &gID) const
Definition TrialBase.h:139
DirichletNodeMapType & dirichletNodeMap() const
Definition TrialBase.h:185
const TrialBase & field() const
Definition TrialBase.h:65
std::map< size_t, std::array< bool, TypeTraits< TrialFunctionType >::dofPerNode > > DirichletNodeMapType
Definition TrialBase.h:41
FiniteElementType::MeshType MeshType
Definition TrialBase.h:30
size_t elementSize() const
Definition TrialBase.h:164
Eigen::Matrix< double, dofPerNode, 1 > dofs(const NodeType &node) const
Definition TrialBase.h:134
const MeshType & mesh() const
Definition TrialBase.h:159
bool sameField(const TrialBase &other) const
Definition TrialBase.h:73
void setPeriodicNodalOffset(const Eigen::VectorXd &values) const
Definition TrialBase.h:112
FiniteElementType & fe() const
Definition TrialBase.h:77
const ElementType & element(const size_t &n) const
Definition TrialBase.h:154
void lifetime(const std::filesystem::path &root)
vertex temp