v0.8.23
SnesCtx.cpp
Go to the documentation of this file.
1 /* This file is part of MoFEM.
2  * MoFEM is free software: you can redistribute it and/or modify it under
3  * the terms of the GNU Lesser General Public License as published by the
4  * Free Software Foundation, either version 3 of the License, or (at your
5  * option) any later version.
6  *
7  * MoFEM is distributed in the hope that it will be useful, but WITHOUT
8  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  * License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with MoFEM. If not, see <http://www.gnu.org/licenses/>. */
14 
15 // #if PETSC_VERSION_GE(3,6,0)
16 // #include <petsc/private/snesimpl.h>
17 // #else
18 // #include <petsc-private/snesimpl.h>
19 // #endif
20 
21 namespace MoFEM {
22 
23 PetscErrorCode SnesRhs(SNES snes, Vec x, Vec f, void *ctx) {
24  SnesCtx *snes_ctx = (SnesCtx *)ctx;
25  // PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
27  PetscLogEventBegin(snes_ctx->MOFEM_EVENT_SnesRhs, 0, 0, 0, 0);
28  CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
29  CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
30  if (snes_ctx->vErify) {
31  // Verify finite elements, check for not a number
32  CHKERR VecAssemblyBegin(f);
33  CHKERR VecAssemblyEnd(f);
34  MPI_Comm comm = PetscObjectComm((PetscObject)f);
35  PetscSynchronizedPrintf(comm, "SNES Verify x\n");
36  const Problem *prb_ptr;
37  CHKERR snes_ctx->mField.get_problem(snes_ctx->problemName, &prb_ptr);
38  CHKERR snes_ctx->mField.getInterface<Tools>()->checkVectorForNotANumber(
39  prb_ptr, COL, x);
40  }
41  CHKERR snes_ctx->mField.getInterface<VecManager>()->setLocalGhostVector(
42  snes_ctx->problemName, COL, x, INSERT_VALUES, SCATTER_REVERSE);
43 
44  auto zero_ghost_vec = [](Vec g) {
46  Vec l;
47  CHKERR VecGhostGetLocalForm(g, &l);
48  double *a;
49  CHKERR VecGetArray(l, &a);
50  int s;
51  CHKERR VecGetLocalSize(l, &s);
52  for (int i = 0; i != s; ++i)
53  a[i] = 0;
54  CHKERR VecRestoreArray(l, &a);
55  CHKERR VecGhostRestoreLocalForm(g, &l);
57  };
58  CHKERR zero_ghost_vec(f);
59 
60  snes_ctx->vecAssembleSwitch =
61  boost::movelib::make_unique<bool>(true);
62 
63  for (auto &bit : snes_ctx->preProcess_Rhs) {
64  bit->vecAssembleSwitch = boost::move(snes_ctx->vecAssembleSwitch);
65  CHKERR bit->setSnes(snes);
66  bit->snes_x = x;
67  bit->snes_f = f;
68  CHKERR bit->setSnesCtx(SnesMethod::CTX_SNESSETFUNCTION);
70  snes_ctx->problemName, *bit);
71  CHKERR bit->setSnesCtx(SnesMethod::CTX_SNESNONE);
72  snes_ctx->vecAssembleSwitch = boost::move(bit->vecAssembleSwitch);
73  }
74 
75  for (auto &lit : snes_ctx->loops_to_do_Rhs) {
76  lit.second->vecAssembleSwitch = boost::move(snes_ctx->vecAssembleSwitch);
77  CHKERR lit.second->setSnesCtx(SnesMethod::CTX_SNESSETFUNCTION);
78  CHKERR lit.second->setSnes(snes);
79  lit.second->snes_x = x;
80  lit.second->snes_f = f;
82  snes_ctx->problemName, lit.first, *lit.second, nullptr, snes_ctx->bH);
83  CHKERR lit.second->setSnesCtx(SnesMethod::CTX_SNESNONE);
84  if (snes_ctx->vErify) {
85  // Verify finite elements, check for not a number
86  CHKERR VecAssemblyBegin(f);
87  CHKERR VecAssemblyEnd(f);
88  MPI_Comm comm = PetscObjectComm((PetscObject)f);
89  PetscSynchronizedPrintf(comm, "SNES Verify f FE < %s >\n",
90  lit.first.c_str());
91  const Problem *prb_ptr;
92  CHKERR snes_ctx->mField.get_problem(snes_ctx->problemName, &prb_ptr);
93  CHKERR snes_ctx->mField.getInterface<Tools>()->checkVectorForNotANumber(
94  prb_ptr, ROW, f);
95  }
96  snes_ctx->vecAssembleSwitch = boost::move(lit.second->vecAssembleSwitch);
97  }
98 
99  for (auto &bit : snes_ctx->postProcess_Rhs) {
100  bit->vecAssembleSwitch = boost::move(snes_ctx->vecAssembleSwitch);
101  CHKERR bit->setSnes(snes);
102  bit->snes_x = x;
103  bit->snes_f = f;
104  CHKERR bit->setSnesCtx(SnesMethod::CTX_SNESSETFUNCTION);
106  snes_ctx->problemName, *bit);
107  CHKERR bit->setSnesCtx(SnesMethod::CTX_SNESNONE);
108  snes_ctx->vecAssembleSwitch = boost::move(bit->vecAssembleSwitch);
109  }
110 
111  if (snes_ctx->vecAssembleSwitch) {
112  CHKERR VecGhostUpdateBegin(f, ADD_VALUES, SCATTER_REVERSE);
113  CHKERR VecGhostUpdateEnd(f, ADD_VALUES, SCATTER_REVERSE);
114  CHKERR VecAssemblyBegin(f);
115  CHKERR VecAssemblyEnd(f);
116  }
117  PetscLogEventEnd(snes_ctx->MOFEM_EVENT_SnesRhs, 0, 0, 0, 0);
119 }
120 
121 PetscErrorCode SnesMat(SNES snes, Vec x, Mat A, Mat B, void *ctx) {
122  SnesCtx *snes_ctx = (SnesCtx *)ctx;
123  // PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
125  PetscLogEventBegin(snes_ctx->MOFEM_EVENT_SnesMat, 0, 0, 0, 0);
126  if (snes_ctx->zeroPreCondMatrixB)
127  CHKERR MatZeroEntries(B);
128 
129  snes_ctx->matAssembleSwitch = boost::movelib::make_unique<bool>(true);
130 
131  CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
132  CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
133  CHKERR snes_ctx->mField.getInterface<VecManager>()->setLocalGhostVector(
134  snes_ctx->problemName, COL, x, INSERT_VALUES, SCATTER_REVERSE);
135  for (auto &bit : snes_ctx->preProcess_Mat) {
136  bit->matAssembleSwitch = boost::move(snes_ctx->matAssembleSwitch);
137  CHKERR bit->setSnes(snes);
138  bit->snes_x = x;
139  bit->snes_A = A;
140  bit->snes_B = B;
141  CHKERR bit->setSnesCtx(SnesMethod::CTX_SNESSETJACOBIAN);
143  snes_ctx->problemName, *bit);
144  CHKERR bit->setSnesCtx(SnesMethod::CTX_SNESNONE);
145  snes_ctx->matAssembleSwitch = boost::move(bit->matAssembleSwitch);
146  }
147  for (auto &lit : snes_ctx->loops_to_do_Mat) {
148  lit.second->matAssembleSwitch = boost::move(snes_ctx->matAssembleSwitch);
149  CHKERR lit.second->setSnesCtx(SnesMethod::CTX_SNESSETJACOBIAN);
150  CHKERR lit.second->setSnes(snes);
151  lit.second->snes_x = x;
152  lit.second->snes_A = A;
153  lit.second->snes_B = B;
155  snes_ctx->problemName, lit.first, *(lit.second), nullptr, snes_ctx->bH);
156  CHKERR lit.second->setSnesCtx(SnesMethod::CTX_SNESNONE);
157  snes_ctx->matAssembleSwitch = boost::move(lit.second->matAssembleSwitch);
158  }
159  for (auto &bit : snes_ctx->postProcess_Mat) {
160  bit->matAssembleSwitch = boost::move(snes_ctx->matAssembleSwitch);
161  CHKERR bit->setSnes(snes);
162  bit->snes_x = x;
163  bit->snes_A = A;
164  bit->snes_B = B;
165  CHKERR bit->setSnesCtx(SnesMethod::CTX_SNESSETJACOBIAN);
167  snes_ctx->problemName, *bit);
168  CHKERR bit->setSnesCtx(SnesMethod::CTX_SNESNONE);
169  snes_ctx->matAssembleSwitch = boost::move(bit->matAssembleSwitch);
170  }
171  if (*snes_ctx->matAssembleSwitch) {
172  CHKERR MatAssemblyBegin(B, snes_ctx->typeOfAssembly);
173  CHKERR MatAssemblyEnd(B, snes_ctx->typeOfAssembly);
174  }
175  PetscLogEventEnd(snes_ctx->MOFEM_EVENT_SnesMat, 0, 0, 0, 0);
177 }
178 
179 MoFEMErrorCode SnesMoFEMSetAssemblyType(SNES snes, MatAssemblyType type) {
180  SnesCtx *snes_ctx;
181  // PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
183  CHKERR SNESGetApplicationContext(snes, &snes_ctx);
184  snes_ctx->typeOfAssembly = type;
186 }
187 
189  SnesCtx *snes_ctx;
191  CHKERR SNESGetApplicationContext(snes, &snes_ctx);
192  snes_ctx->bH = bh;
194 }
195 
196 } // namespace MoFEM
MatAssemblyType typeOfAssembly
type of assembly at the end
Definition: SnesCtx.hpp:37
bool zeroPreCondMatrixB
Definition: SnesCtx.hpp:35
PetscLogEvent MOFEM_EVENT_SnesMat
Log events to assemble tangent matrix.
Definition: SnesCtx.hpp:158
PetscLogEvent MOFEM_EVENT_SnesRhs
Log events to assemble residual.
Definition: SnesCtx.hpp:157
boost::movelib::unique_ptr< bool > matAssembleSwitch
Definition: SnesCtx.hpp:156
MoFEM::Interface & mField
database Interface
Definition: SnesCtx.hpp:29
std::string problemName
problem name
Definition: SnesCtx.hpp:32
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.
Definition: SnesCtx.cpp:121
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:476
Auxiliary tools.
Definition: Tools.hpp:30
keeps basic data about problemThis is low level structure with information about problem,...
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:21
MoFEMErrorCode SnesMoFEMSetAssemblyType(SNES snes, MatAssemblyType type)
Set assembly type at the end of SnesMat.
Definition: SnesCtx.cpp:179
BasicMethodsSequence postProcess_Rhs
Sequence of methods run after residual is assembled.
Definition: SnesCtx.hpp:64
MoFEMErrorCode getInterface(const MOFEMuuid &uuid, IFACE *&iface) const
Get interface by uuid and return reference to pointer of interface.
bool vErify
If true verify vector.
Definition: SnesCtx.hpp:38
FEMethodsSequence loops_to_do_Rhs
Definition: SnesCtx.hpp:55
virtual MoFEMErrorCode get_problem(const std::string &problem_name, const Problem **problem_ptr) const =0
Get problem database (data structure)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:66
FEMethodsSequence loops_to_do_Mat
Definition: SnesCtx.hpp:53
Interface for nonlinear (SNES) solver.
Definition: SnesCtx.hpp:27
BasicMethodsSequence postProcess_Mat
Definition: SnesCtx.hpp:59
Vector manager is used to create vectors \mofem_vectors.
Definition: VecManager.hpp:36
boost::movelib::unique_ptr< bool > vecAssembleSwitch
Definition: SnesCtx.hpp:155
virtual MoFEMErrorCode problem_basic_method_preProcess(const Problem *problem_ptr, BasicMethod &method, int verb=DEFAULT_VERBOSITY)=0
Set data for BasicMethod.
#define CHKERR
Inline error check.
Definition: definitions.h:595
BasicMethodsSequence preProcess_Rhs
Sequence of methods run before residual is assembled.
Definition: SnesCtx.hpp:62
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:406
MoFEMTypes bH
If set to MF_EXIST check if element exist, default MF_EXIST.
Definition: SnesCtx.hpp:34
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.
Definition: SnesCtx.cpp:23
virtual MoFEMErrorCode problem_basic_method_postProcess(const Problem *problem_ptr, BasicMethod &method, int verb=DEFAULT_VERBOSITY)=0
Set data for BasicMethodThis function set data about problem, adjacencies and other multi-indices in ...
MoFEMErrorCode SnesMoFEMSetBehavior(SNES snes, MoFEMTypes bh)
Set behavior if finite element in sequence does not exist.
Definition: SnesCtx.cpp:188
MoFEMTypes
Those types control how functions respond on arguments, f.e. error handling.
Definition: definitions.h:182
BasicMethodsSequence preProcess_Mat
Definition: SnesCtx.hpp:57
DEPRECATED MoFEMErrorCode loop_finite_elements(const Problem *problem_ptr, const std::string &fe_name, FEMethod &method, int lower_rank, int upper_rank, MoFEMTypes bh, int verb=DEFAULT_VERBOSITY)