19 {
20
21
23
24
25 moab::Core mb_instance;
26 moab::Interface &moab = mb_instance;
27
28 try {
29
32
33 PetscInt order_x = 2;
34 PetscInt order_X = 2;
35 PetscBool flg = PETSC_TRUE;
36
37 PetscBool test_jacobian = PETSC_FALSE;
39 PETSC_NULLPTR);
41 &flg);
43 &flg);
44
46
48
52 3);
54 3);
56
62
63 Range triangle_springs;
65 if (it->getName().compare(0, 9, "SPRING_BC") == 0) {
67 triangle_springs, true);
68 }
69 }
70
71
73 "MESH_NODE_POSITIONS");
75 m_field, "SPATIAL_POSITION", "MESH_NODE_POSITIONS", triangle_springs);
79
80
81 DM dm;
83
84 PetscRandom rctx;
85 PetscRandomCreate(PETSC_COMM_WORLD, &rctx);
86
87 auto set_coord = [&](
VectorAdaptor &&field_data,
double *x,
double *y,
88 double *z) {
90 double value;
92 PetscRandomGetValue(rctx, &value);
93 field_data[0] = (*x) + (value - 0.5) *
scale;
94 PetscRandomGetValue(rctx, &value);
95 field_data[1] = (*y) + (value - 0.5) *
scale;
96 PetscRandomGetValue(rctx, &value);
97 field_data[2] = (*z) + (value - 0.5) *
scale;
99 };
100
102 "SPATIAL_POSITION");
104 set_coord, "MESH_NODE_POSITIONS");
105
106 PetscRandomDestroy(&rctx);
107
108 boost::shared_ptr<NeumannForcesSurface> surfacePressure(
110
111 boost::shared_ptr<NeumannForcesSurface::MyTriangleFE> fe_rhs_ptr(
112 surfacePressure, &(surfacePressure->getLoopFe()));
113 boost::shared_ptr<NeumannForcesSurface::MyTriangleFE> fe_lhs_ptr(
114 surfacePressure, &(surfacePressure->getLoopFeLhs()));
115 boost::shared_ptr<NeumannForcesSurface::MyTriangleFE> fe_mat_rhs_ptr(
116 surfacePressure, &(surfacePressure->getLoopFeMatRhs()));
117 boost::shared_ptr<NeumannForcesSurface::MyTriangleFE> fe_mat_lhs_ptr(
118 surfacePressure, &(surfacePressure->getLoopFeMatLhs()));
119
121 "MESH_NODE_POSITIONS");
123 "MESH_NODE_POSITIONS");
125 "MESH_NODE_POSITIONS");
127 "MESH_NODE_POSITIONS");
128
129 boost::shared_ptr<NeumannForcesSurface> surfaceForce(
131
132 boost::shared_ptr<NeumannForcesSurface::MyTriangleFE>
133 fe_rhs_surface_force_ptr(surfaceForce, &(surfaceForce->getLoopFe()));
134 boost::shared_ptr<NeumannForcesSurface::MyTriangleFE>
135 fe_lhs_surface_force_ptr(surfaceForce, &(surfaceForce->getLoopFeLhs()));
136 boost::shared_ptr<NeumannForcesSurface::MyTriangleFE>
137 fe_mat_rhs_surface_force_ptr(surfaceForce,
138 &(surfaceForce->getLoopFeMatRhs()));
139 boost::shared_ptr<NeumannForcesSurface::MyTriangleFE>
140 fe_mat_lhs_surface_force_ptr(surfaceForce,
141 &(surfaceForce->getLoopFeMatLhs()));
142
144 fe_rhs_surface_force_ptr->getOpPtrVector(), {},
145 "MESH_NODE_POSITIONS");
147 fe_lhs_surface_force_ptr->getOpPtrVector(), {},
148 "MESH_NODE_POSITIONS");
150 fe_mat_rhs_surface_force_ptr->getOpPtrVector(), {},
151 "MESH_NODE_POSITIONS");
153 fe_mat_lhs_surface_force_ptr->getOpPtrVector(), {},
154 "MESH_NODE_POSITIONS");
155
157 CHKERR moab.get_entities_by_type(0, MBVERTEX, nodes,
false);
158
159 nodes.pop_front();
160 nodes.pop_back();
161
162 boost::shared_ptr<NeumannForcesSurface::DataAtIntegrationPts> dataAtPts =
163 boost::make_shared<NeumannForcesSurface::DataAtIntegrationPts>();
164
165 dataAtPts->forcesOnlyOnEntitiesRow = nodes;
166
168 if (
bit->getName().compare(0, 8,
"PRESSURE") == 0) {
169 CHKERR surfacePressure->addPressure(
"SPATIAL_POSITION", PETSC_NULLPTR,
170 bit->getMeshsetId(),
true,
true);
171 CHKERR surfacePressure->addPressureAle(
172 "SPATIAL_POSITION", "MESH_NODE_POSITIONS", dataAtPts,
174 true, true);
175 }
176 }
177
178 const string block_set_force_name("FORCE");
179
182 CHKERR surfaceForce->addForce(
"SPATIAL_POSITION", PETSC_NULLPTR,
183 (
bit->getMeshsetId()),
true,
false);
184 CHKERR surfaceForce->addForceAle(
185 "SPATIAL_POSITION", "MESH_NODE_POSITIONS", dataAtPts,
187 true, false, false);
188 }
189
191 if (it->getName().compare(0, block_set_force_name.length(),
192 block_set_force_name) == 0) {
193 CHKERR surfaceForce->addForce(
"SPATIAL_POSITION", PETSC_NULLPTR,
194 (it->getMeshsetId()), true, true);
195 CHKERR surfaceForce->addForceAle(
196 "SPATIAL_POSITION", "MESH_NODE_POSITIONS", dataAtPts,
197 si->
getDomainFEName(), PETSC_NULLPTR, PETSC_NULLPTR, it->getMeshsetId(),
198 true, true, false);
199 }
200 }
201
202
203
204 boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_lhs_ptr(
206 boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_rhs_ptr(
209 m_field, fe_spring_lhs_ptr, fe_spring_rhs_ptr, "SPATIAL_POSITION",
210 "MESH_NODE_POSITIONS");
211
212 boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_lhs_ale_ptr_dx(
214 boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_lhs_ale_ptr_dX(
216
217 boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_rhs_ale_ptr(
219
220 boost::shared_ptr<MetaSpringBC::DataAtIntegrationPtsSprings>
221 data_at_spring_gp =
222 boost::make_shared<MetaSpringBC::DataAtIntegrationPtsSprings>(
223 m_field);
224
225 Range spring_ale_nodes;
226 CHKERR moab.get_connectivity(triangle_springs, spring_ale_nodes,
true);
227
228 data_at_spring_gp->forcesOnlyOnEntitiesRow = spring_ale_nodes;
229
231 m_field, fe_spring_lhs_ale_ptr_dx, fe_spring_lhs_ale_ptr_dX,
232 fe_spring_rhs_ale_ptr, data_at_spring_gp, "SPATIAL_POSITION",
234
236 PETSC_NULLPTR);
238 PETSC_NULLPTR);
239
241 PETSC_NULLPTR, PETSC_NULLPTR);
243 PETSC_NULLPTR, PETSC_NULLPTR);
245 PETSC_NULLPTR, PETSC_NULLPTR);
246
248 nullptr, nullptr);
250 nullptr, nullptr);
251
253 nullptr, nullptr);
255 nullptr, nullptr);
256
257
259 fe_lhs_surface_force_ptr, nullptr, nullptr);
261 fe_rhs_surface_force_ptr, nullptr, nullptr);
262
264 fe_mat_lhs_surface_force_ptr, nullptr,
265 nullptr);
267 fe_mat_rhs_surface_force_ptr, nullptr,
268 nullptr);
269
271 CHKERR DMCreateGlobalVector(dm, &x);
272 CHKERR VecDuplicate(x, &f);
273 CHKERR VecSetOption(f, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE);
275
277 CHKERR DMCreateMatrix(dm, &A);
278 CHKERR MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, &fdA);
279
280 if (test_jacobian == PETSC_TRUE) {
281 char testing_options[] =
282 "-snes_test_jacobian -snes_test_jacobian_display "
283 "-snes_no_convergence_test -snes_atol 0 -snes_rtol 0 -snes_max_it 1 ";
284
285 CHKERR PetscOptionsInsertString(NULL, testing_options);
286 } else {
287 char testing_options[] = "-snes_no_convergence_test -snes_atol 0 "
288 "-snes_rtol 0 "
289 "-snes_max_it 1 ";
290
291 CHKERR PetscOptionsInsertString(NULL, testing_options);
292 }
293
294 SNES snes;
295 CHKERR SNESCreate(PETSC_COMM_WORLD, &snes);
300 CHKERR SNESSetFromOptions(snes);
301
302 CHKERR SNESSolve(snes, NULL, x);
303
304 if (test_jacobian == PETSC_FALSE) {
305 double nrm_A0;
306 CHKERR MatNorm(A, NORM_INFINITY, &nrm_A0);
307
308 char testing_options_fd[] = "-snes_fd";
309 CHKERR PetscOptionsInsertString(NULL, testing_options_fd);
310
313 CHKERR SNESSetFromOptions(snes);
314
315 CHKERR SNESSolve(snes, NULL, x);
316 CHKERR MatAXPY(A, -1, fdA, SUBSET_NONZERO_PATTERN);
317
318 double nrm_A;
319 CHKERR MatNorm(A, NORM_INFINITY, &nrm_A);
320 PetscPrintf(PETSC_COMM_WORLD, "Matrix norms %3.4e %3.4e\n", nrm_A,
321 nrm_A / nrm_A0);
322 nrm_A /= nrm_A0;
323
324 const double tol = 1e-7;
327 "Difference between hand-calculated tangent matrix and finite "
328 "difference matrix is too big");
329 }
330 }
331
336 CHKERR SNESDestroy(&snes);
337
338
340 }
342
343
345
346 return 0;
347}
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_ATOM_TEST_INVALID
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
PetscErrorCode DMMoFEMSNESSetFunction(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set SNES residual evaluation function
PetscErrorCode DMMoFEMSNESSetJacobian(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set SNES Jacobian evaluation function
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
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
PetscErrorCode DMMoFEMGetSnesCtx(DM dm, MoFEM::SnesCtx **snes_ctx)
get MoFEM::SnesCtx data structure
#define _IT_CUBITMESHSETS_BY_BCDATA_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet in a moFEM field.
#define _IT_CUBITMESHSETS_BY_SET_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet having a particular BC meshset in a moFEM field.
const FTensor::Tensor2< T, Dim, Dim > Vec
VectorShallowArrayAdaptor< double > VectorAdaptor
PetscErrorCode SnesMat(SNES snes, Vec x, Mat A, Mat B, void *ctx)
This is MoFEM implementation for the left hand side (tangent matrix) evaluation in SNES solver.
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
PetscErrorCode SnesRhs(SNES snes, Vec x, Vec f, void *ctx)
This is MoFEM implementation for the right hand side (residual vector) evaluation in SNES solver.
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
Add operators pushing bases from local to physical configuration.
virtual moab::Interface & get_moab()=0
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Deprecated interface functions.
Simple interface for fast problem set-up.
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.
const std::string getBoundaryFEName() const
Get the Boundary FE Name.
MoFEMErrorCode loadFile(const std::string options, const std::string mesh_file_name, LoadFileFunc loadFunc=defaultLoadFileFunc)
Load mesh file.
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.
std::vector< std::string > & getOtherFiniteElements()
Get the Other Finite Elements.
MoFEMErrorCode getOptions()
get options
MoFEMErrorCode getDM(DM *dm)
Get DM.
MoFEMErrorCode setFieldOrder(const std::string field_name, const int order, const Range *ents=NULL)
Set field order.
MoFEMErrorCode setUp(const PetscBool is_partitioned=PETSC_TRUE)
Setup problem.
const std::string getDomainFEName() const
Get the Domain FE Name.
Interface for nonlinear (SNES) solver.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Finite element and operators to apply force/pressures applied to surfaces.