v0.16.0
Loading...
Searching...
No Matches
approximation.cpp
Go to the documentation of this file.
1/**
2 * \file approximation.cpp
3 * \example mofem/tutorials/scl-0_least_squares/approximation.cpp
4 *
5 * Using Simple interface and PipelineManager to solve least squares approximation problem.
6 */
7
8#include <MoFEM.hpp>
9
10using namespace MoFEM;
11
12static char help[] = "...\n\n";
13
14#include <MoFEM.hpp>
15
16constexpr char FIELD_NAME[] = "U";
17constexpr int FIELD_DIM = 1;
18constexpr int SPACE_DIM = 2;
19
20template <int DIM> struct ElementsAndOps {};
21
22template <> struct ElementsAndOps<2> {
24};
25
26template <> struct ElementsAndOps<3> {
28};
29
31using DomainEleOp = DomainEle::UserDataOperator;
33
35
36template <int FIELD_DIM> struct ApproxFieldFunction;
37
38template <> struct ApproxFieldFunction<1> {
39 double operator()(const double x, const double y, const double z) {
40 return sin(x * 10.) * cos(y * 10.);
41 }
42};
43
48
49struct Example {
50
51 Example(MoFEM::Interface &m_field) : mField(m_field) {}
52
54
55private:
58
60
70
71 struct CommonData {
72 boost::shared_ptr<VectorDouble> approxVals;
75 };
76 boost::shared_ptr<CommonData> commonDataPtr;
77
78 template <int FIELD_DIM> struct OpError;
79};
80
83
84//! [OpError def]
85template <> struct Example::OpError<1> : public DomainEleOp {
86 boost::shared_ptr<CommonData> commonDataPtr;
87 OpError(boost::shared_ptr<CommonData> &common_data_ptr)
88 : DomainEleOp(FIELD_NAME, OPROW), commonDataPtr(common_data_ptr) {}
89 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
91
92 if (const size_t nb_dofs = data.getIndices().size()) {
93
94 const int nb_integration_pts = getGaussPts().size2();
95 auto t_w = getFTensor0IntegrationWeight();
96 auto t_val = getFTensor0FromVec(*(commonDataPtr->approxVals));
97 auto t_coords = getFTensor1CoordsAtGaussPts();
98
99 VectorDouble nf(nb_dofs, false);
100 nf.clear();
101
102 FTensor::Index<'i', 3> i;
103 const double volume = getMeasure();
104
105 auto t_row_base = data.getFTensor0N();
106 double error = 0;
107 for (int gg = 0; gg != nb_integration_pts; ++gg) {
108
109 const double alpha = t_w * volume;
110 double diff = t_val - Example::approxFunction(t_coords(0), t_coords(1),
111 t_coords(2));
112 error += alpha * pow(diff, 2);
113
114 for (size_t r = 0; r != nb_dofs; ++r) {
115 nf[r] += alpha * t_row_base * diff;
116 ++t_row_base;
117 }
118
119 ++t_w;
120 ++t_val;
121 ++t_coords;
122 }
123
124 const int index = 0;
125 CHKERR VecSetValue(commonDataPtr->L2Vec, index, error, ADD_VALUES);
126 CHKERR VecSetValues(commonDataPtr->resVec, data, &nf[0], ADD_VALUES);
127 }
128
130 }
131};
132//! [OpError def]
133
134//! [Run programme]
147}
148//! [Run programme]
149
150//! [Read mesh]
153
157
159}
160//! [Read mesh]
161
162//! [Set up problem]
165 // Add field
168 constexpr int order = 4;
172}
173//! [Set up problem]
174
175//! [Set integration rule]
178
179 auto rule = [](int, int, int p) -> int { return 2 * p; };
180
182 CHKERR pipeline_mng->setDomainLhsIntegrationRule(rule);
183 CHKERR pipeline_mng->setDomainRhsIntegrationRule(rule);
184
186}
187//! [Set integration rule]
188
189//! [Create common data]
192 commonDataPtr = boost::make_shared<CommonData>();
194 commonDataPtr->L2Vec =
196 commonDataPtr->approxVals = boost::make_shared<VectorDouble>();
198}
199//! [Create common data]
200
201//! [Boundary condition]
203//! [Boundary condition]
204
205//! [Push operators to pipeline]
209 auto beta = [](const double, const double, const double) { return 1; };
210 pipeline_mng->getOpDomainLhsPipeline().push_back(
212 pipeline_mng->getOpDomainRhsPipeline().push_back(
215}
216//! [Push operators to pipeline]
217
218//! [Solve]
222 auto solver = pipeline_mng->createKSP();
223 CHKERR KSPSetFromOptions(solver);
224 CHKERR KSPSetUp(solver);
225
226 auto dm = simpleInterface->getDM();
227 auto D = createDMVector(dm);
228 auto F = vectorDuplicate(D);
229
230 CHKERR KSPSolve(solver, F, D);
231 CHKERR VecGhostUpdateBegin(D, INSERT_VALUES, SCATTER_FORWARD);
232 CHKERR VecGhostUpdateEnd(D, INSERT_VALUES, SCATTER_FORWARD);
233 CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_REVERSE);
235}
236
237//! [Solve]
241 auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
242
243 auto u_ptr = boost::make_shared<VectorDouble>();
244 post_proc_fe->getOpPtrVector().push_back(
246
248
249 post_proc_fe->getOpPtrVector().push_back(
250
251 new OpPPMap(
252
253 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
254
255 {{FIELD_NAME, u_ptr}},
256
257 {},
258
259 {},
260
261 {})
262
263 );
264
265 pipeline_mng->getDomainPostProcFE() = post_proc_fe;
266 CHKERR pipeline_mng->loopFiniteElementsPostProc();
267 CHKERR post_proc_fe->writeFile("out_approx.h5m");
269}
270//! [Postprocess results]
271
272//! [Check results]
276 pipeline_mng->getOpDomainPostProcPipeline().clear();
277 pipeline_mng->getOpDomainPostProcPipeline().push_back(
279 pipeline_mng->getOpDomainPostProcPipeline().push_back(
281 CHKERR pipeline_mng->loopFiniteElementsPostProc();
282 CHKERR VecAssemblyBegin(commonDataPtr->L2Vec);
283 CHKERR VecAssemblyEnd(commonDataPtr->L2Vec);
284 CHKERR VecAssemblyBegin(commonDataPtr->resVec);
285 CHKERR VecAssemblyEnd(commonDataPtr->resVec);
286 double nrm2;
287 CHKERR VecNorm(commonDataPtr->resVec, NORM_2, &nrm2);
288 const double *array;
289 CHKERR VecGetArrayRead(commonDataPtr->L2Vec, &array);
290 if (mField.get_comm_rank() == 0)
291 PetscPrintf(PETSC_COMM_SELF, "Error %6.4e Vec norm %6.4e\n",
292 std::sqrt(array[0]), nrm2);
293 CHKERR VecRestoreArrayRead(commonDataPtr->L2Vec, &array);
294 constexpr double eps = 1e-8;
295 if (nrm2 > eps)
296 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
297 "Not converged solution");
299}
300//! [Check results]
301
302int main(int argc, char *argv[]) {
303
304 // Initialisation of MoFEM/PETSc and MOAB data structures
305 const char param_file[] = "param_file.petsc";
306 MoFEM::Core::Initialize(&argc, &argv, param_file, help);
307
308 try {
309
310 //! [Register MoFEM discrete manager in PETSc]
311 DMType dm_name = "DMMOFEM";
312 CHKERR DMRegister_MoFEM(dm_name);
313 //! [Register MoFEM discrete manager in PETSc
314
315 //! [Create MoAB]
316 moab::Core mb_instance; ///< mesh database
317 moab::Interface &moab = mb_instance; ///< mesh database interface
318 //! [Create MoAB]
319
320 //! [Create MoFEM]
321 MoFEM::Core core(moab); ///< finite element database
322 MoFEM::Interface &m_field = core; ///< finite element database insterface
323 //! [Create MoFEM]
324
325 //! [Example]
326 Example ex(m_field);
327 CHKERR ex.runProblem();
328 //! [Example]
329 }
331
333}
std::string type
int main()
static char help[]
constexpr char FIELD_NAME[]
constexpr int SPACE_DIM
constexpr int FIELD_DIM
constexpr char FIELD_NAME[]
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpSource< 1, FIELD_DIM > OpDomainSource
constexpr int FIELD_DIM
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, FIELD_DIM > OpDomainMass
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ H1
continuous field
Definition definitions.h:85
#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.
constexpr int order
@ F
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:514
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1237
boost::ptr_deque< UserDataOperator > & getOpDomainLhsPipeline()
Get the Op Domain Lhs Pipeline object.
SmartPetscObj< KSP > createKSP(SmartPetscObj< DM > dm=nullptr)
Create KSP (linear) solver.
boost::ptr_deque< UserDataOperator > & getOpDomainPostProcPipeline()
Get the Op Domain PostProc Pipeline object.
MoFEMErrorCode loopFiniteElementsPostProc(SmartPetscObj< DM > dm=nullptr)
Iterate postprocessing finite elements.
boost::ptr_deque< UserDataOperator > & getOpDomainRhsPipeline()
Get the Op Domain Rhs Pipeline object.
@ PETSC
Standard PETSc assembly.
FTensor::Index< 'i', SPACE_DIM > i
double D
const double eps
Definition HenckyOps.hpp:13
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
static auto getFTensor0FromVec(V &data)
Get tensor rank 0 (scalar) form data vector.
MoFEMErrorCode VecSetValues(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Assemble PETSc vector.
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
double operator()(const double x, const double y, const double z)
[Operators_definition]
boost::shared_ptr< VectorDouble > approxVals
SmartPetscObj< Vec > resVec
OpError(boost::shared_ptr< CommonData > &common_data_ptr)
boost::shared_ptr< CommonData > commonDataPtr
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
boost::shared_ptr< CommonData > commonDataPtr
[Example]
Definition plastic.cpp:217
MoFEMErrorCode boundaryCondition()
MoFEMErrorCode assembleSystem()
MoFEMErrorCode readMesh()
MoFEMErrorCode setIntegrationRules()
static ApproxFieldFunction< FIELD_DIM > approxFunction
boost::shared_ptr< CommonData > commonDataPtr
MoFEMErrorCode checkResults()
MoFEMErrorCode solveSystem()
MoFEMErrorCode createCommonData()
Example(MoFEM::Interface &m_field)
MoFEMErrorCode runProblem()
MoFEM::Interface & mField
Reference to MoFEM interface.
Definition plastic.cpp:227
MoFEMErrorCode setupProblem()
MoFEMErrorCode outputResults()
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Core (interface) class.
Definition Core.hpp:83
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition Core.cpp:68
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition Core.cpp:123
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
const VectorInt & getIndices() const
Get global indices of degrees of freedom on entity.
Specialization for double precision scalar field values calculation.
Post post-proc data at points from hash maps.
PipelineManager interface.
MoFEM::FaceElementForcesAndSourcesCore FaceEle
boost::shared_ptr< FEMethod > & getDomainPostProcFE()
Get domain postprocessing finite element.
MoFEMErrorCode setDomainRhsIntegrationRule(RuleHookFun rule)
Set integration rule for domain right-hand side finite element.
MoFEMErrorCode setDomainLhsIntegrationRule(RuleHookFun rule)
Set integration rule for domain left-hand side finite element.
Simple interface for fast problem set-up.
Definition Simple.hpp:27
MoFEMErrorCode addDomainField(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_ZERO, int verb=-1)
Add field on domain.
Definition Simple.cpp:261
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
Definition Simple.cpp:191
MoFEMErrorCode getOptions()
get options
Definition Simple.cpp:180
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:799
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
Definition Simple.cpp:575
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
Definition Simple.cpp:735
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.