14 using namespace boost::numeric;
15 using namespace MoFEM;
19 int main(
int argc,
char *argv[]) {
35 PetscBool flg = PETSC_TRUE;
37 PetscBool test_jacobian = PETSC_FALSE;
63 Range triangle_springs;
65 if (it->getName().compare(0, 9,
"SPRING_BC") == 0) {
67 triangle_springs,
true);
73 "MESH_NODE_POSITIONS");
75 m_field,
"SPATIAL_POSITION",
"MESH_NODE_POSITIONS", triangle_springs);
85 PetscRandomCreate(PETSC_COMM_WORLD, &rctx);
87 auto set_coord = [&](
VectorAdaptor &&field_data,
double *x,
double *y,
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;
104 set_coord,
"MESH_NODE_POSITIONS");
106 PetscRandomDestroy(&rctx);
108 boost::shared_ptr<NeumannForcesSurface> surfacePressure(
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()));
125 boost::shared_ptr<NeumannForcesSurface> surfaceForce(
128 boost::shared_ptr<NeumannForcesSurface::MyTriangleFE>
129 fe_rhs_surface_force_ptr(surfaceForce, &(surfaceForce->getLoopFe()));
130 boost::shared_ptr<NeumannForcesSurface::MyTriangleFE>
131 fe_lhs_surface_force_ptr(surfaceForce, &(surfaceForce->getLoopFeLhs()));
132 boost::shared_ptr<NeumannForcesSurface::MyTriangleFE>
133 fe_mat_rhs_surface_force_ptr(surfaceForce,
134 &(surfaceForce->getLoopFeMatRhs()));
135 boost::shared_ptr<NeumannForcesSurface::MyTriangleFE>
136 fe_mat_lhs_surface_force_ptr(surfaceForce,
137 &(surfaceForce->getLoopFeMatLhs()));
149 CHKERR moab.get_entities_by_type(0, MBVERTEX, nodes,
false);
154 boost::shared_ptr<NeumannForcesSurface::DataAtIntegrationPts> dataAtPts =
155 boost::make_shared<NeumannForcesSurface::DataAtIntegrationPts>();
157 dataAtPts->forcesOnlyOnEntitiesRow = nodes;
160 if (
bit->getName().compare(0, 8,
"PRESSURE") == 0) {
161 CHKERR surfacePressure->addPressure(
"SPATIAL_POSITION", PETSC_NULL,
162 bit->getMeshsetId(),
true,
true);
163 CHKERR surfacePressure->addPressureAle(
164 "SPATIAL_POSITION",
"MESH_NODE_POSITIONS", dataAtPts,
170 const string block_set_force_name(
"FORCE");
174 CHKERR surfaceForce->addForce(
"SPATIAL_POSITION", PETSC_NULL,
175 (
bit->getMeshsetId()),
true,
false);
176 CHKERR surfaceForce->addForceAle(
177 "SPATIAL_POSITION",
"MESH_NODE_POSITIONS", dataAtPts,
183 if (it->getName().compare(0, block_set_force_name.length(),
184 block_set_force_name) == 0) {
185 CHKERR surfaceForce->addForce(
"SPATIAL_POSITION", PETSC_NULL,
186 (it->getMeshsetId()),
true,
true);
187 CHKERR surfaceForce->addForceAle(
188 "SPATIAL_POSITION",
"MESH_NODE_POSITIONS", dataAtPts,
196 boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_lhs_ptr(
198 boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_rhs_ptr(
201 m_field, fe_spring_lhs_ptr, fe_spring_rhs_ptr,
"SPATIAL_POSITION",
202 "MESH_NODE_POSITIONS");
204 boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_lhs_ale_ptr_dx(
206 boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_lhs_ale_ptr_dX(
209 boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_rhs_ale_ptr(
212 boost::shared_ptr<MetaSpringBC::DataAtIntegrationPtsSprings>
214 boost::make_shared<MetaSpringBC::DataAtIntegrationPtsSprings>(
217 Range spring_ale_nodes;
218 CHKERR moab.get_connectivity(triangle_springs, spring_ale_nodes,
true);
220 data_at_spring_gp->forcesOnlyOnEntitiesRow = spring_ale_nodes;
223 m_field, fe_spring_lhs_ale_ptr_dx, fe_spring_lhs_ale_ptr_dX,
224 fe_spring_rhs_ale_ptr, data_at_spring_gp,
"SPATIAL_POSITION",
233 PETSC_NULL, PETSC_NULL);
235 PETSC_NULL, PETSC_NULL);
237 PETSC_NULL, PETSC_NULL);
251 fe_lhs_surface_force_ptr,
nullptr,
nullptr);
253 fe_rhs_surface_force_ptr,
nullptr,
nullptr);
256 fe_mat_lhs_surface_force_ptr,
nullptr,
259 fe_mat_rhs_surface_force_ptr,
nullptr,
263 CHKERR DMCreateGlobalVector(dm, &x);
265 CHKERR VecSetOption(
f, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE);
270 CHKERR MatDuplicate(
A, MAT_DO_NOT_COPY_VALUES, &fdA);
272 if (test_jacobian == PETSC_TRUE) {
273 char testing_options[] =
274 "-snes_test_jacobian -snes_test_jacobian_display "
275 "-snes_no_convergence_test -snes_atol 0 -snes_rtol 0 -snes_max_it 1 ";
277 CHKERR PetscOptionsInsertString(NULL, testing_options);
279 char testing_options[] =
"-snes_no_convergence_test -snes_atol 0 "
283 CHKERR PetscOptionsInsertString(NULL, testing_options);
287 CHKERR SNESCreate(PETSC_COMM_WORLD, &snes);
292 CHKERR SNESSetFromOptions(snes);
294 CHKERR SNESSolve(snes, NULL, x);
296 if (test_jacobian == PETSC_FALSE) {
298 CHKERR MatNorm(
A, NORM_INFINITY, &nrm_A0);
300 char testing_options_fd[] =
"-snes_fd";
301 CHKERR PetscOptionsInsertString(NULL, testing_options_fd);
305 CHKERR SNESSetFromOptions(snes);
307 CHKERR SNESSolve(snes, NULL, x);
308 CHKERR MatAXPY(
A, -1, fdA, SUBSET_NONZERO_PATTERN);
311 CHKERR MatNorm(
A, NORM_INFINITY, &nrm_A);
312 PetscPrintf(PETSC_COMM_WORLD,
"Matrix norms %3.4e %3.4e\n", nrm_A,
316 const double tol = 1e-7;
319 "Difference between hand-calculated tangent matrix and finite "
320 "difference matrix is too big");
328 CHKERR SNESDestroy(&snes);