67 auto snes = pipeline_mng->createSNES();
68 ExampleTimeScale::snesPtr = snes;
70 PetscBool post_proc_vol;
71 PetscBool post_proc_skin;
74 post_proc_vol = PETSC_TRUE;
75 post_proc_skin = PETSC_FALSE;
77 post_proc_vol = PETSC_FALSE;
78 post_proc_skin = PETSC_TRUE;
80 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_vol",
81 &post_proc_vol, PETSC_NULLPTR);
82 CHKERR PetscOptionsGetBool(PETSC_NULLPTR,
"",
"-post_proc_skin",
83 &post_proc_skin, PETSC_NULLPTR);
86 auto create_post_proc_fe = [dm,
this,
simple, post_proc_vol,
88 auto post_proc_ele_domain = [dm,
this](
auto &pip_domain) {
91 auto common_ptr = commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
92 mField, pip_domain,
"U",
"MAT_ELASTIC", Sev::inform);
96 auto post_proc_map = [
this](
auto &pip,
auto u_ptr,
auto common_ptr) {
99 using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
101 auto X_ptr = boost::make_shared<MatrixDouble>();
103 pip->getOpPtrVector().push_back(
104 new OpCalculateVectorFieldValues<SPACE_DIM>(
"GEOMETRY", X_ptr));
106 pip->getOpPtrVector().push_back(
108 new OpPPMap(pip->getPostProcMesh(), pip->getMapGaussPts(), {},
109 {{
"U", u_ptr}, {
"GEOMETRY", X_ptr}},
110 {{
"GRAD", common_ptr->matGradPtr},
111 {
"FIRST_PIOLA", common_ptr->getMatFirstPiolaStress()}},
116 auto push_post_proc_bdy = [dm,
this,
simple, post_proc_skin,
117 &post_proc_ele_domain,
118 &post_proc_map](
auto &pip_bdy) {
119 if (post_proc_skin == PETSC_FALSE)
120 return boost::shared_ptr<PostProcEleBdy>();
122 auto u_ptr = boost::make_shared<MatrixDouble>();
123 pip_bdy->getOpPtrVector().push_back(
124 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
127 auto common_ptr = post_proc_ele_domain(op_loop_side->getOpPtrVector());
128 pip_bdy->getOpPtrVector().push_back(op_loop_side);
130 CHKERR post_proc_map(pip_bdy, u_ptr, common_ptr);
135 auto push_post_proc_domain = [dm,
this,
simple, post_proc_vol,
136 &post_proc_ele_domain,
137 &post_proc_map](
auto &pip_domain) {
138 if (post_proc_vol == PETSC_FALSE)
139 return boost::shared_ptr<PostProcEleDomain>();
141 auto u_ptr = boost::make_shared<MatrixDouble>();
142 pip_domain->getOpPtrVector().push_back(
143 new OpCalculateVectorFieldValues<SPACE_DIM>(
"U", u_ptr));
144 auto common_ptr = post_proc_ele_domain(pip_domain->getOpPtrVector());
146 CHKERR post_proc_map(pip_domain, u_ptr, common_ptr);
151 auto post_proc_fe_domain = boost::make_shared<PostProcEleDomain>(
mField);
152 auto post_proc_fe_bdy = boost::make_shared<PostProcEleBdy>(
mField);
154 return std::make_pair(push_post_proc_domain(post_proc_fe_domain),
155 push_post_proc_bdy(post_proc_fe_bdy));
158 auto add_arc_length_load_tangent_operator = [&](
auto snes) {
160 auto bdy_pipeline = boost::make_shared<BoundaryEle>(mField);
161 auto domain_pipeline = boost::make_shared<DomainEle>(mField);
170 double getScale(
const double)
override {
return -1.; }
172 auto time_one = boost::make_shared<TimeOne>();
179 CHKERR BoundaryNaturalBC::AddFluxToPipeline<OpForce>::add(
180 bdy_pipeline->getOpPtrVector(), mField,
"U", {time_one},
"FORCE",
181 "PRESSURE", Sev::inform);
183 CHKERR DomainNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
184 domain_pipeline->getOpPtrVector(), mField,
"U", {time_one},
185 "BODY_FORCE", Sev::inform);
188 snes_ctx_ptr->getLoadTangent().push_back(
189 {
simple->getBoundaryFEName(), bdy_pipeline});
190 snes_ctx_ptr->getLoadTangent().push_back(
191 {
simple->getDomainFEName(), domain_pipeline});
193 auto time_scale = boost::make_shared<ExampleTimeScale>();
195 auto pre_proc_ptr = boost::make_shared<FEMethod>();
196 auto get_bc_hook_rhs = [
this, pre_proc_ptr, time_scale]() {
198 CHKERR EssentialPreProc<DisplacementCubitBcData>(mField, pre_proc_ptr,
199 {time_scale},
false)();
202 pre_proc_ptr->preProcessHook = get_bc_hook_rhs;
203 snes_ctx_ptr->getPreProcLoadTangent().push_back(pre_proc_ptr);
204 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
205 auto get_post_proc_hook_rhs = [
this, post_proc_rhs_ptr]() {
207 CHKERR EssentialPostProcRhs<DisplacementCubitBcData>(
208 mField, post_proc_rhs_ptr, 0.)();
211 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
212 snes_ctx_ptr->getPostProcLoadTangent().push_back(post_proc_rhs_ptr);
214 CHKERR SNESNewtonALSetFunction(snes, SnesLoadTangent, snes_ctx_ptr.get());
219 auto add_extra_finite_elements_to_solver_pipelines = [&]() {
222 auto pre_proc_ptr = boost::make_shared<FEMethod>();
223 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
224 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
226 auto time_scale = boost::make_shared<ExampleTimeScale>();
228 auto get_bc_hook_rhs = [
this, pre_proc_ptr, time_scale]() {
230 CHKERR EssentialPreProc<DisplacementCubitBcData>(mField, pre_proc_ptr,
231 {time_scale},
false)();
235 pre_proc_ptr->preProcessHook = get_bc_hook_rhs;
237 auto get_post_proc_hook_rhs = [
this, post_proc_rhs_ptr]() {
239 CHKERR EssentialPreProcReaction<DisplacementCubitBcData>(
240 mField, post_proc_rhs_ptr,
nullptr, Sev::verbose)();
241 CHKERR EssentialPostProcRhs<DisplacementCubitBcData>(
242 mField, post_proc_rhs_ptr, 1.)();
245 auto get_post_proc_hook_lhs = [
this, post_proc_lhs_ptr]() {
247 CHKERR EssentialPostProcLhs<DisplacementCubitBcData>(
248 mField, post_proc_lhs_ptr, 1.)();
251 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
252 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs;
256 snes_ctx_ptr->getPreProcComputeRhs().push_front(pre_proc_ptr);
257 snes_ctx_ptr->getPreProcSetOperators().push_front(pre_proc_ptr);
258 snes_ctx_ptr->getPostProcComputeRhs().push_back(post_proc_rhs_ptr);
259 snes_ctx_ptr->getPostProcSetOperators().push_back(post_proc_lhs_ptr);
263 auto set_log_and_post_hook = [
this](
auto post_proc_fe,
auto post_proc_bdy) {
266 auto make_vtk = [
this, post_proc_fe, post_proc_bdy](
auto iter,
269 auto simple = mField.getInterface<Simple>();
270 auto dm =
simple->getDM();
273 CHKERR post_proc_fe->writeFile(
274 "out_step_" + boost::lexical_cast<std::string>(iter) +
".h5m");
278 CHKERR post_proc_bdy->writeFile(
279 "out_skin_" + boost::lexical_cast<std::string>(iter) +
".h5m");
284 auto hook = [
this, make_vtk](SNES snes,
Vec x,
Vec F,
285 boost::shared_ptr<CacheTuple> cache_ptr,
286 void *ctx) -> MoFEMErrorCode {
289 double atol, rtol, stol;
291 CHKERR SNESGetTolerances(snes, &atol, &rtol, &stol, &maxit, &maxf);
297 CHKERR VecNorm(
F, NORM_2, &nrm);
300 CHKERR SNESGetIterationNumber(snes, &iter);
301 SNESConvergedReason reason;
302 CHKERR SNESGetConvergedReason(snes, &reason);
304 "SNES iteration %d, reason %d nrm2 %g lambda %g", iter,
307 CHKERR make_vtk(iter, cache_ptr);
312 auto simple = mField.getInterface<Simple>();
314 snes_ctx_ptr->getRhsHook() = hook;
321 CHKERR SNESSetType(snes, SNESNEWTONLS);
322 CHKERR SNESSetFromOptions(snes);
325 CHKERR SNESSetJacobian(snes,
B,
B, PETSC_NULLPTR, PETSC_NULLPTR);
328 CHKERR add_extra_finite_elements_to_solver_pipelines();
329 CHKERR add_arc_length_load_tangent_operator(snes);
331 auto [post_proc_fe, post_proc_bdy] = create_post_proc_fe();
332 CHKERR set_log_and_post_hook(post_proc_fe, post_proc_bdy);
334 CHKERR SNESSolve(snes, PETSC_NULLPTR,
D);