v0.14.0
Loading...
Searching...
No Matches
simple_interface.cpp
Go to the documentation of this file.
1/**
2 * \file simple_interface.cpp
3 * \ingroup mofem_simple_interface
4 * \example simple_interface.cpp
5 *
6 * Calculate volume by integrating volume elements and using divergence theorem
7 * by integrating surface elements.
8 *
9 */
10
11
12
13#include <MoFEM.hpp>
14using namespace MoFEM;
15
16static char help[] = "...\n\n";
17
18struct OpVolume : public VolumeElementForcesAndSourcesCore::UserDataOperator {
19 Vec vOl;
20 OpVolume(const std::string &field_name, Vec vol)
22 vOl(vol) {}
23 MoFEMErrorCode doWork(int side, EntityType type,
25
27 if (type != MBVERTEX)
29 const int nb_int_pts = getGaussPts().size2();
30 // cerr << nb_int_pts << endl;
31 auto t_w = getFTensor0IntegrationWeight();
32 double v = getMeasure();
33 double vol = 0;
34 for (int gg = 0; gg != nb_int_pts; gg++) {
35 vol += t_w * v;
36 ++t_w;
37 }
38 CHKERR VecSetValue(vOl, 0, vol, ADD_VALUES);
40 }
41 MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type,
42 EntityType col_type,
46 // PetscPrintf(PETSC_COMM_WORLD,"domain: calculate matrix\n");
48 }
49};
50
51struct OpFace : public FaceElementForcesAndSourcesCore::UserDataOperator {
52 Vec vOl;
53 OpFace(const std::string &field_name, Vec vol)
55 vOl(vol) {}
56 MoFEMErrorCode doWork(int side, EntityType type,
58
60 if (type != MBVERTEX)
62 const int nb_int_pts = getGaussPts().size2();
63 auto t_normal = getFTensor1NormalsAtGaussPts();
65 auto t_coords = getFTensor1CoordsAtGaussPts();
66 FTensor::Index<'i', 3> i;
67 double vol = 0;
68 for (int gg = 0; gg != nb_int_pts; gg++) {
69 vol += (t_coords(i) * t_normal(i)) * t_w;
70 ++t_normal;
71 ++t_w;
72 ++t_coords;
73 }
74 vol /= 6;
75 CHKERR VecSetValue(vOl, 0, vol, ADD_VALUES);
77 }
78 MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type,
79 EntityType col_type,
83 // PetscPrintf(PETSC_COMM_WORLD,"boundary: calculate matrix\n");
85 }
86};
87
88struct VolRule {
89 int operator()(int, int, int) const { return 2; }
90};
91struct FaceRule {
92 int operator()(int, int, int) const { return 4; }
93};
94
95int main(int argc, char *argv[]) {
96
97 // initialize petsc
98 MoFEM::Core::Initialize(&argc, &argv, (char *)0, help);
99
100 auto core_log = logging::core::get();
101 core_log->add_sink(
103 LogManager::setLog("TEST");
104 MOFEM_LOG_TAG("TEST", "atom_test");
105 core_log->add_sink(
107 LogManager::setLog("TESTSYNC");
108 MOFEM_LOG_TAG("TESTSYNC", "atom_test");
109
110 try {
111
112 // Create MoAB database
113 moab::Core moab_core;
114 moab::Interface &moab = moab_core;
115
116 // Create MoFEM database and link it to MoAB
117 MoFEM::Core mofem_core(moab);
118 MoFEM::Interface &m_field = mofem_core;
119
120 // Register DM Manager
121 DMType dm_name = "DMMOFEM";
122 CHKERR DMRegister_MoFEM(dm_name);
123
124 // Simple interface
125 Simple *simple_interface;
126 CHKERR m_field.getInterface(simple_interface);
127 {
128 // get options from command line
129 CHKERR simple_interface->getOptions();
130 // load mesh file
131 CHKERR simple_interface->loadFile();
132 // add fields
133 CHKERR simple_interface->addDomainField("MESH_NODE_POSITIONS", H1,
135 CHKERR simple_interface->addBoundaryField("MESH_NODE_POSITIONS", H1,
137 CHKERR simple_interface->addSkeletonField("MESH_NODE_POSITIONS", H1,
139
140 CHKERR simple_interface->addMeshsetField("GLOBAL", NOFIELD, NOBASE, 3);
141 CHKERR simple_interface->addMeshsetField("MESH_NODE_POSITIONS", H1,
143
144 // Note:: two "meshset" elements are created, one with GOLOBAL field and
145 // vertices with "MESH_NODE_POSITIONS" field, and other with "GLOABL"
146 // field and edges with "MESH_NODE_POSITIONS" field.
147 // That us only to test API, and data structures, potential application is
148 // here not known.
149 Range verts;
150 CHKERR m_field.get_moab().get_entities_by_type(0, MBVERTEX, verts);
151 simple_interface->getMeshsetFiniteElementEntities().push_back(verts);
152 Range edge;
153 CHKERR m_field.get_moab().get_entities_by_type(0, MBEDGE, edge);
154 simple_interface->getMeshsetFiniteElementEntities().push_back(edge);
155
156 // set fields order
157 CHKERR simple_interface->setFieldOrder("MESH_NODE_POSITIONS", 1);
158 // setup problem
159 CHKERR simple_interface->setUp();
160 // Project mesh coordinate on mesh
161 Projection10NodeCoordsOnField ent_method(m_field, "MESH_NODE_POSITIONS");
162 CHKERR m_field.loop_dofs("MESH_NODE_POSITIONS", ent_method);
163 // get dm
164 auto dm = simple_interface->getDM();
165 // create elements
166 auto domain_fe =
167 boost::make_shared<VolumeElementForcesAndSourcesCore>(m_field);
168 auto boundary_fe =
169 boost::make_shared<FaceElementForcesAndSourcesCore>(m_field);
170
171 // set integration rule
172 domain_fe->getRuleHook = VolRule();
173 boundary_fe->getRuleHook = FaceRule();
174 // create distributed vector to accumulate values from processors.
175 int ghosts[] = {0};
176
177 auto vol = createGhostVector(
178 PETSC_COMM_WORLD, m_field.get_comm_rank() == 0 ? 1 : 0, 1,
179 m_field.get_comm_rank() == 0 ? 0 : 1, ghosts);
180 auto surf_vol = vectorDuplicate(vol);
181
182 // set operator to the volume element
183 auto material_grad_mat = boost::make_shared<MatrixDouble>();
184 auto material_det_vec = boost::make_shared<VectorDouble>();
185
186 domain_fe->getOpPtrVector().push_back(
187 new OpCalculateVectorFieldGradient<3, 3>("MESH_NODE_POSITIONS",
188 material_grad_mat));
189 domain_fe->getOpPtrVector().push_back(
190 new OpInvertMatrix<3>(material_grad_mat, material_det_vec, nullptr));
191 domain_fe->getOpPtrVector().push_back(
192 new OpSetHOWeights(material_det_vec));
193 domain_fe->getOpPtrVector().push_back(
194 new OpCalculateHOCoords("MESH_NODE_POSITIONS"));
195 domain_fe->getOpPtrVector().push_back(
196 new OpVolume("MESH_NODE_POSITIONS", vol));
197 // set operator to the face element
198 boundary_fe->getOpPtrVector().push_back(
199 new OpCalculateHOCoords("MESH_NODE_POSITIONS"));
200 boundary_fe->getOpPtrVector().push_back(
201 new OpFace("MESH_NODE_POSITIONS", surf_vol));
202 // make integration in volume (here real calculations starts)
203 CHKERR DMoFEMLoopFiniteElements(dm, simple_interface->getDomainFEName(),
204 domain_fe);
205 // make integration on boundary
206 CHKERR DMoFEMLoopFiniteElements(dm, simple_interface->getBoundaryFEName(),
207 boundary_fe);
208
209 auto skeleton_fe = boost::make_shared<FEMethod>();
210 auto A = createDMMatrix(dm);
211 auto B = createDMMatrix(dm);
212 auto f = createDMVector(dm);
213 auto x = createDMVector(dm);
214 auto x_t = createDMVector(dm);
215 auto x_tt = createDMVector(dm);
216 skeleton_fe->f = f;
217 skeleton_fe->A = A;
218 skeleton_fe->B = B;
219 skeleton_fe->x = x;
220 skeleton_fe->x_t = x_t;
221 skeleton_fe->x_tt = x_tt;
222
223 skeleton_fe->preProcessHook = [&]() {
225 if (f != skeleton_fe->ts_F)
226 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Wrong ptr");
227 if (A != skeleton_fe->ts_A)
228 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Wrong ptr");
229 if (B != skeleton_fe->ts_B)
230 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Wrong ptr");
231 if (x != skeleton_fe->ts_u)
232 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Wrong ptr");
233 if (x_t != skeleton_fe->ts_u_t)
234 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Wrong ptr");
235 if (x_tt != skeleton_fe->ts_u_tt)
236 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY, "Wrong ptr");
238 };
239
240 skeleton_fe->postProcessHook = []() { return 0; };
241 skeleton_fe->operatorHook = []() { return 0; };
242
243 CHKERR DMoFEMLoopFiniteElements(dm, simple_interface->getSkeletonFEName(),
244 skeleton_fe);
245
246 // assemble volumes from processors and accumulate on processor of rank 0
247 CHKERR VecAssemblyBegin(vol);
248 CHKERR VecAssemblyEnd(vol);
249 CHKERR VecGhostUpdateBegin(vol, ADD_VALUES, SCATTER_REVERSE);
250 CHKERR VecGhostUpdateEnd(vol, ADD_VALUES, SCATTER_REVERSE);
251 CHKERR VecAssemblyBegin(surf_vol);
252 CHKERR VecAssemblyEnd(surf_vol);
253 CHKERR VecGhostUpdateBegin(surf_vol, ADD_VALUES, SCATTER_REVERSE);
254 CHKERR VecGhostUpdateEnd(surf_vol, ADD_VALUES, SCATTER_REVERSE);
255 if (m_field.get_comm_rank() == 0) {
256 double *a_vol;
257 CHKERR VecGetArray(vol, &a_vol);
258 double *a_surf_vol;
259 CHKERR VecGetArray(surf_vol, &a_surf_vol);
260 MOFEM_LOG("TEST", Sev::inform) << "Volume = " << a_vol[0];
261 MOFEM_LOG("TEST", Sev::inform) << "Surf Volume = " << a_surf_vol[0];
262 if (fabs(a_vol[0] - a_surf_vol[0]) > 1e-12) {
263 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID, "Should be zero");
264 }
265 CHKERR VecRestoreArray(vol, &a_vol);
266 CHKERR VecRestoreArray(vol, &a_surf_vol);
267 }
268
269 struct MeshsetFE : public ForcesAndSourcesCore {
270 using ForcesAndSourcesCore::ForcesAndSourcesCore;
273 const auto type = numeredEntFiniteElementPtr->getEntType();
274 if (type != MBENTITYSET) {
275 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
276 "Expected entity set as a finite element");
277 }
280 }
281 MoFEMErrorCode preProcess() { return 0; }
282 MoFEMErrorCode postProcess() { return 0; }
283 };
284
285 auto fe_ptr = boost::make_shared<MeshsetFE>(m_field);
286
287 struct OpMeshset : ForcesAndSourcesCore::UserDataOperator {
288 using OP = ForcesAndSourcesCore::UserDataOperator;
289 using OP::OP;
290
291 MoFEMErrorCode doWork(int side, EntityType type,
294 MOFEM_LOG("TESTSYNC", Sev::inform) << data.getIndices();
296 }
297
298 MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type,
299 EntityType col_type,
301 EntitiesFieldData::EntData &col_data) {
303 MOFEM_LOG("TESTSYNC", Sev::inform)
304 << row_data.getIndices() << " " << col_data.getIndices() << endl;
306 }
307 };
308
309 fe_ptr->getOpPtrVector().push_back(
310 new OpMeshset("GLOBAL", OpMeshset::OPROW));
311 fe_ptr->getOpPtrVector().push_back(
312 new OpMeshset("GLOBAL", "GLOBAL", OpMeshset::OPROWCOL));
313
315 dm, simple_interface->getMeshsetFEName(), fe_ptr, 0,
316 m_field.get_comm_size());
317 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::inform);
318 }
319 }
321
322 // finish work cleaning memory, getting statistics, etc.
324
325 return 0;
326}
ForcesAndSourcesCore::UserDataOperator UserDataOperator
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
int main()
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base nme:nme847.
Definition definitions.h:60
@ NOBASE
Definition definitions.h:59
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ NOFIELD
scalar or vector of scalars describe (no true field)
Definition definitions.h:84
@ 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_ATOM_TEST_INVALID
Definition definitions.h:40
@ 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 ...
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
Definition DMMoFEM.cpp:43
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:586
auto createDMVector(DM dm)
Get smart vector from DM.
Definition DMMoFEM.hpp:1099
auto createDMMatrix(DM dm)
Get smart matrix from DM.
Definition DMMoFEM.hpp:1056
PetscErrorCode DMoFEMLoopFiniteElementsUpAndLowRank(DM dm, const char fe_name[], MoFEM::FEMethod *method, int low_rank, int up_rank, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:567
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
FTensor::Index< 'i', SPACE_DIM > i
const double v
phase velocity of light in medium (cm/ns)
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 createGhostVector(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt nghost, const PetscInt ghosts[])
Create smart ghost vector.
constexpr AssemblyType A
constexpr auto field_name
static char help[]
Set integration rule to boundary elements.
int operator()(int, int, int) const
virtual int get_comm_size() const =0
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Core (interface) class.
Definition Core.hpp:82
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition Core.cpp:72
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition Core.cpp:112
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
const VectorInt & getIndices() const
Get global indices of dofs on entity.
auto getFTensor1CoordsAtGaussPts()
Get coordinates at integration points assuming linear geometry.
auto getFTensor0IntegrationWeight()
Get integration weights.
@ OPROW
operator doWork function is executed on FE rows
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
structure to get information form mofem into EntitiesFieldData
MoFEMErrorCode loopOverOperators()
Iterate user data operators.
virtual MoFEMErrorCode operator()()
function is run for every finite element
virtual MoFEMErrorCode preProcess()
function is run at the beginning of loop
virtual MoFEMErrorCode postProcess()
function is run at the end of loop
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
static boost::shared_ptr< std::ostream > getStrmSync()
Get the strm sync object.
Calculate HO coordinates at gauss points.
Get field gradients at integration pts for scalar filed rank 0, i.e. vector field.
Set inverse jacobian to base functions.
Projection of edge entities with one mid-node on hierarchical basis.
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:264
const std::string getBoundaryFEName() const
Get the Boundary FE Name.
Definition Simple.hpp:394
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
Definition Simple.cpp:194
MoFEMErrorCode addMeshsetField(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 meshset field.
Definition Simple.cpp:414
const std::string getSkeletonFEName() const
Get the Skeleton FE Name.
Definition Simple.hpp:401
MoFEMErrorCode addBoundaryField(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 boundary.
Definition Simple.cpp:358
MoFEMErrorCode getOptions()
get options
Definition Simple.cpp:180
MoFEMErrorCode getDM(DM *dm)
Get DM.
Definition Simple.cpp:829
std::string & getMeshsetFEName()
Get the Skeleton FE Name.
Definition Simple.hpp:436
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
Definition Simple.cpp:599
auto & getMeshsetFiniteElementEntities()
Get the Domain Fields.
Definition Simple.hpp:443
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
Definition Simple.cpp:765
const std::string getDomainFEName() const
Get the Domain FE Name.
Definition Simple.hpp:387
MoFEMErrorCode addSkeletonField(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 skeleton.
Definition Simple.cpp:376
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
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.
OpFace(const std::string &field_name, Vec vol)
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
OpVolume(const std::string &field_name, Vec vol)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Set integration rule to volume elements.
int operator()(int, int, int) const