v0.16.0
Loading...
Searching...
No Matches
AnalyticalDirichlet.hpp
Go to the documentation of this file.
1/** \file AnalyticalDirichlet.hpp
2
3 Enforce Dirichlet boundary condition for given analytical function,
4
5*/
6
7
8
9#ifndef __ANALYTICALDIRICHLETBC_HPP__
10#define __ANALYTICALDIRICHLETBC_HPP__
11
12using namespace boost::numeric;
13using namespace MoFEM;
14
15/** \brief Analytical Dirichlet boundary conditions
16 \ingroup user_modules
17 */
19
20 /** \brief finite element to approximate analytical solution on surface
21 */
22 struct ApproxField {
23
25
26 int addToRule; ///< this is add to integration rule if 2nd order geometry
27 ///< approximation
30 int getRule(int order) { return 2 * order + addToRule; };
31 };
32
33 ApproxField(MoFEM::Interface &m_field) : feApprox(m_field) {}
34 virtual ~ApproxField() = default;
35
38
39 /** \brief Lhs operator used to build matrix
40 */
41 struct OpLhs
43
44 OpLhs(const std::string field_name);
45
47 MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type,
48 EntityType col_type,
51 };
52
53 /** \brief Rhs operator used to build matrix
54 */
55 template <typename FUNEVAL>
56 struct OpRhs
58
59 // Range tRis;
60 boost::shared_ptr<FUNEVAL> functionEvaluator;
62
63 OpRhs(const std::string field_name,
64 boost::shared_ptr<FUNEVAL> function_evaluator, int field_number)
67 functionEvaluator(function_evaluator), fieldNumber(field_number) {}
68
71
72 MoFEMErrorCode doWork(int side, EntityType type,
75
76 unsigned int nb_row = data.getIndices().size();
77 if (nb_row == 0)
79
80 const auto &dof_ptr = data.getFieldDofs()[0];
81 unsigned int rank = dof_ptr->getNbOfCoeffs();
82
83 const auto &gauss_pts = getGaussPts();
84 const auto &coords_at_gauss_pts = getCoordsAtGaussPts();
85
86 NTf.resize(nb_row / rank);
87 iNdices.resize(nb_row / rank);
88
89 for (unsigned int gg = 0; gg < data.getN().size1(); gg++) {
90
91 const double area = norm_2(getNormalsAtGaussPts(gg)) * 0.5;
92 const double val = gauss_pts(2, gg) * area;
93 const double x = coords_at_gauss_pts(gg, 0);
94 const double y = coords_at_gauss_pts(gg, 1);
95 const double z = coords_at_gauss_pts(gg, 2);
96
97 VectorDouble a = (*functionEvaluator)(x, y, z)[fieldNumber];
98
99 if (a.size() != rank) {
100 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
101 "data inconsistency");
102 }
103
104 for (unsigned int rr = 0; rr < rank; rr++) {
105
106 ublas::noalias(iNdices) = ublas::vector_slice<VectorInt>(
107 data.getIndices(),
108 ublas::slice(rr, rank, data.getIndices().size() / rank));
109
110 noalias(NTf) = data.getN(gg, nb_row / rank) * a[rr] * val;
111 CHKERR VecSetValues(getFEMethod()->snes_f, iNdices.size(),
112 &iNdices[0], &*NTf.data().begin(), ADD_VALUES);
113 }
114 }
115
117 }
118 };
119 };
120
121 /**
122 * \brief Structure used to enforce analytical boundary conditions
123 */
125
126 DirichletBC(MoFEM::Interface &m_field, const std::string &field, Mat A,
127 Vec X, Vec F);
128
129 DirichletBC(MoFEM::Interface &m_field, const std::string &field);
130
131 boost::shared_ptr<Range> trisPtr;
132
135 };
136
139
140 /**
141 * \brief Set operators used to calculate the rhs vector and the lhs matrix
142
143 * To enforce analytical function on boundary, first function has to be
144 approximated
145 * by finite element base functions. This is done by solving system of linear
146 * equations, Following function set finite element operators to calculate
147 * the left hand side matrix and the left hand side matrix.
148
149 * @param m_field interface
150 * @param field_name field name
151 * @param function_evaluator analytical function to evaluate
152 * @param field_number field index
153 * @param nodals_positions name of the field for ho-geometry description
154 * @return error code
155 */
156 template <typename FUNEVAL>
158 setApproxOps(MoFEM::Interface &m_field, const std::string field_name,
159 boost::shared_ptr<FUNEVAL> function_evaluator,
160 const int field_number = 0,
161 const string nodals_positions = "MESH_NODE_POSITIONS") {
164 if (m_field.check_field(nodals_positions))
167 nodals_positions);
170 }
172 new ApproxField::OpRhs<FUNEVAL>(field_name, function_evaluator,
173 field_number));
175 }
176
177 // /**
178 // * \deprecated no need to use function with argument of triangle range
179 // */
180 // template<typename FUNEVAL> DEPRECATED MoFEMErrorCode setApproxOps(
181 // MoFEM::Interface &m_field,
182 // string field_name,
183 // Range& tris,
184 // boost::shared_ptr<FUNEVAL> function_evaluator,
185 // int field_number = 0,
186 // string nodals_positions = "MESH_NODE_POSITIONS"
187 // ) {
188 // return setApproxOps(
189 // m_field,field_name,tris,function_evaluator,field_number,nodals_positions
190 // );
191 // }
192
193 /**
194 * \brief set finite element
195 * @param m_field mofem interface
196 * @param fe finite element name
197 * @param field field name
198 * @param tris faces where analytical boundary is given
199 * @param nodals_positions field having higher order geometry description
200 * @return error code
201 */
203 setFiniteElement(MoFEM::Interface &m_field, string fe, string field,
204 Range &tris,
205 string nodals_positions = "MESH_NODE_POSITIONS");
206
207 // /**
208 // \deprecated use setFiniteElement instead
209 // */
210 // DEPRECATED MoFEMErrorCode initializeProblem(
211 // MoFEM::Interface &m_field,
212 // string fe,
213 // string field,
214 // Range& tris,
215 // string nodals_positions = "MESH_NODE_POSITIONS"
216 // ) {
217 // return setFiniteElement(m_field,fe,field,tris,nodals_positions);
218 // }
219
220 Mat A;
221 Vec D, F;
223
224 /**
225 * \brief set problem solver and create matrices and vectors
226 * @param m_field mofem interface
227 * @param problem problem name
228 * @return error code
229 */
230 MoFEMErrorCode setUpProblem(MoFEM::Interface &m_field, string problem);
231
232 // /**
233 // * \deprecated use setUpProblem instead
234 // */
235 // DEPRECATED MoFEMErrorCode setProblem(
236 // MoFEM::Interface &m_field,string problem
237 // ) {
238 // return setUpProblem(m_field,problem);
239 // }
240
241 /**
242 * \brief solve boundary problem
243 *
244
245 * This functions solve for DOFs on boundary where analytical solution is
246 * given. i.e. finding values of DOFs which approximate analytical solution.
247
248 * @param m_field mofem interface
249 * @param problem problem name
250 * @param fe finite element name
251 * @param bc Driblet boundary structure used to apply boundary
252 conditions
253 * @param tris triangles on boundary
254 * @return error code
255 */
256 MoFEMErrorCode solveProblem(MoFEM::Interface &m_field, string problem,
257 string fe, DirichletBC &bc, Range &tris);
258
259 /**
260 * \brief solve boundary problem
261 *
262
263 * This functions solve for DOFs on boundary where analytical solution is
264 * given.
265
266 * @param m_field mofem interface
267 * @param problem problem name
268 * @param fe finite element name
269 * @param bc Driblet boundary structure used to apply boundary
270 conditions
271 * @return [description]
272 */
273 MoFEMErrorCode solveProblem(MoFEM::Interface &m_field, string problem,
274 string fe, DirichletBC &bc);
275
276 /**
277 * \brief Destroy problem
278 *
279 * Destroy matrices and vectors used to solve boundary problem, i.e. finding
280 * values of DOFs which approximate analytical solution.
281 *
282 * @return error code
283 */
285};
286
287#endif //__ANALYTICALDIRICHLETBC_HPP__
std::string type
constexpr double a
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
constexpr int order
virtual bool check_field(const std::string &name) const =0
check if field is in database
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasVector< int > VectorInt
Definition Types.hpp:67
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
MoFEMErrorCode VecSetValues(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Assemble PETSc vector.
constexpr auto field_name
Lhs operator used to build matrix.
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
Operator for bi-linear form, usually to calculate values on left hand side.
Rhs operator used to build matrix.
OpRhs(const std::string field_name, boost::shared_ptr< FUNEVAL > function_evaluator, int field_number)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
finite element to approximate analytical solution on surface
ApproxField(MoFEM::Interface &m_field)
Structure used to enforce analytical boundary conditions.
Analytical Dirichlet boundary conditions.
MoFEMErrorCode destroyProblem()
Destroy problem.
MoFEMErrorCode setUpProblem(MoFEM::Interface &m_field, string problem)
set problem solver and create matrices and vectors
MoFEMErrorCode setApproxOps(MoFEM::Interface &m_field, const std::string field_name, boost::shared_ptr< FUNEVAL > function_evaluator, const int field_number=0, const string nodals_positions="MESH_NODE_POSITIONS")
Set operators used to calculate the rhs vector and the lhs matrix.
MoFEMErrorCode setFiniteElement(MoFEM::Interface &m_field, string fe, string field, Range &tris, string nodals_positions="MESH_NODE_POSITIONS")
set finite element
MoFEMErrorCode solveProblem(MoFEM::Interface &m_field, string problem, string fe, DirichletBC &bc, Range &tris)
solve boundary problem
Set Dirichlet boundary conditions on displacements.
Add operators pushing bases from local to physical configuration.
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
const VectorDofs & getFieldDofs() const
Get DOF data structures (const version)
const VectorInt & getIndices() const
Get global indices of degrees of freedom on entity.
MatrixDouble & getNormalsAtGaussPts()
if higher order geometry return normals at Gauss pts.
MatrixDouble & getCoordsAtGaussPts()
Gauss points and weight, matrix (nb. of points x 3)
@ OPROW
operator doWork function is executed on FE rows
const FEMethod * getFEMethod() const
Return raw pointer to Finite Element Method object.
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
structure to get information from mofem into EntitiesFieldData
boost::ptr_deque< UserDataOperator > & getOpPtrVector()
Use to push back operator for row operator.