8#ifndef model_TrialBase_H_
9#define model_TrialBase_H_
23 template<
typename _TrialFunctionType>
30 typedef typename FiniteElementType::MeshType
MeshType;
36 static constexpr int dim=ElementType::dim;
47 std::shared_ptr<FiniteElementType> owner;
50 Eigen::VectorXd dofvector;
54 Eigen::Matrix<double,dofPerNode,dim>
periodicGradient=Eigen::Matrix<double,dofPerNode,dim>::Zero();
56 owner(
fe.weak_from_this().lock()), space(&
fe),
lifetime(
fe.lifetimeToken()),
57 dofvector(Eigen::VectorXd::Zero(
fe.nodeSize()*
dofPerNode)) {}
59 std::shared_ptr<State> state;
75 return state==other.state;
79 if(state->lifetime.expired())
81 throw std::runtime_error(
"FEM field outlived its borrowed space. Use a shared FEM space for retained expressions.");
83 state->space->validateMeshLifetime();
91 Eigen::Matrix<double,Eigen::Dynamic,1>&
dofVector()
const
93 return state->dofvector;
99 if(!gradient.allFinite())
101 throw std::invalid_argument(
"Nonfinite FEM periodic gradient.");
103 state->periodicGradient=gradient;
108 return state->periodicGradient;
114 if((values.size()!=0 && values.size()!=Eigen::Index(
gSize())) || !values.allFinite())
116 throw std::invalid_argument(
"Invalid FEM periodic nodal offset.");
118 state->periodicNodalOffset=values;
122 return state->periodicNodalOffset;
127 if(values.size()!=Eigen::Index(
gSize()) || !values.allFinite())
129 throw std::invalid_argument(
"Invalid full FEM DOF vector.");
131 state->dofvector=values;
136 return state->dofvector.template segment<dofPerNode>(
node.gID*
dofPerNode);
139 Eigen::Matrix<double,dofPerNode,1>
dofs(
const size_t& gID)
const
141 return state->dofvector.template segment<dofPerNode>(gID*
dofPerNode);
146 Eigen::Matrix<double,dofPerElement,1>
temp;
156 return fe().element(n);
166 return fe().elementSize();
171 return fe().nodeSize();
181 state->nodes.clear();
182 state->conditions.clear();
192 return state->conditions;
195 template<
typename Condition>
197 const Condition& cond,
198 const std::array<bool,dofPerNode>& constrainDof)
const
201 bool isConstrained(
false);
204 isConstrained+=constrainDof[dof];
213 Eigen::Matrix<double,dofPerNode,1> value(Eigen::Matrix<double,dofPerNode,1>::Zero());
218 state->nodes[pNode->gID][dof]+=constrainDof[dof];
220 if(constrainDof[dof])
222 const auto temp=state->conditions.emplace(
dofPerNode*(pNode->gID)+dof,value(dof));
224 if(!(
temp.second || std::abs(
temp.first->second-value(dof))<FLT_EPSILON ))
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.");
TrialBase(TrialBase &&)=delete
Eigen::Matrix< double, Eigen::Dynamic, 1 > & dofVector() const
TypeTraits< TrialFunctionType >::ElementType ElementType
const NodeType & node(const size_t &n) const
const Eigen::VectorXd & periodicNodalOffset() const
DirichletConditionContainerType & dirichletConditions() const
void addDirichletCondition(const size_t &nodeListID, const Condition &cond, const std::array< bool, dofPerNode > &constrainDof) const
Eigen::Matrix< double, dofPerElement, 1 > dofs(const ElementType &ele) const
void setFullDofVector(const Eigen::VectorXd &values) const
static constexpr int dofPerElement
TrialFunctionType TrialFunctionType
static constexpr int nodesPerElement
TypeTraits< TrialFunctionType >::FiniteElementType FiniteElementType
TypeTraits< TrialFunctionType >::BaryType BaryType
const Eigen::Matrix< double, dofPerNode, dim > & periodicGradient() const
TrialBase(const TrialBase &)=delete
std::shared_ptr< const void > ownership() const
TrialBase(FiniteElementType &fe)
void clearDirichletConditions() const
void setPeriodicGradient(const Eigen::Matrix< double, dofPerNode, dim > &gradient) const
std::map< size_t, double > DirichletConditionContainerType
TypeTraits< TrialFunctionType >::NodeType NodeType
static constexpr int dofPerNode
Eigen::Matrix< double, dofPerNode, 1 > dofs(const size_t &gID) const
DirichletNodeMapType & dirichletNodeMap() const
const TrialBase & field() const
std::map< size_t, std::array< bool, TypeTraits< TrialFunctionType >::dofPerNode > > DirichletNodeMapType
FiniteElementType::MeshType MeshType
size_t elementSize() const
Eigen::Matrix< double, dofPerNode, 1 > dofs(const NodeType &node) const
const MeshType & mesh() const
bool sameField(const TrialBase &other) const
void setPeriodicNodalOffset(const Eigen::VectorXd &values) const
FiniteElementType & fe() const
const ElementType & element(const size_t &n) const
void lifetime(const std::filesystem::path &root)