v0.10.0
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 namespace MoFEM {
16 
17 PetscErrorCode SnesRhs(SNES snes, Vec x, Vec f, void *ctx) {
18  SnesCtx *snes_ctx = (SnesCtx *)ctx;
19  // PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21  PetscLogEventBegin(snes_ctx->MOFEM_EVENT_SnesRhs, 0, 0, 0, 0);
22  CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
23  CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
24  if (snes_ctx->vErify) {
25  // Verify finite elements, check for not a number
26  CHKERR VecAssemblyBegin(f);
27  CHKERR VecAssemblyEnd(f);
28  MPI_Comm comm = PetscObjectComm((PetscObject)f);
29  PetscSynchronizedPrintf(comm, "SNES Verify x\n");
30  const Problem *prb_ptr;
31  CHKERR snes_ctx->mField.get_problem(snes_ctx->problemName, &prb_ptr);
32  CHKERR snes_ctx->mField.getInterface<Tools>()->checkVectorForNotANumber(
33  prb_ptr, COL, x);
34  }
35  CHKERR snes_ctx->mField.getInterface<VecManager>()->setLocalGhostVector(
36  snes_ctx->problemName, COL, x, INSERT_VALUES, SCATTER_REVERSE);
37 
38  auto zero_ghost_vec = [](Vec g) {
40  Vec l;
41  CHKERR VecGhostGetLocalForm(g, &l);
42  double *a;
43  CHKERR VecGetArray(l, &a);
44  int s;
45  CHKERR VecGetLocalSize(l, &s);
46  for (int i = 0; i != s; ++i)
47  a[i] = 0;
48  CHKERR VecRestoreArray(l, &a);
49  CHKERR VecGhostRestoreLocalForm(g, &l);
51  };
52  CHKERR zero_ghost_vec(f);
53 
54  snes_ctx->vecAssembleSwitch = boost::movelib::make_unique<bool>(true);
55 
56  auto set = [&](auto &fe) {
57  fe.snes = snes;
58  fe.snes_x = x;
59  fe.snes_f = f;
60  fe.snes_ctx = SnesMethod::CTX_SNESSETFUNCTION;
61  fe.ksp_ctx = KspMethod::CTX_SETFUNCTION;
62  fe.data_ctx = PetscData::CtxSetF | PetscData::CtxSetX;
63  };
64 
65  auto unset = [&](auto &fe) {
66  fe.snes_ctx = SnesMethod::CTX_SNESNONE;
67  fe.ksp_ctx = KspMethod::CTX_KSPNONE;
68  fe.data_ctx = PetscData::CtxSetNone;
69  };
70 
71  auto cache_ptr = boost::make_shared<CacheTuple>();
72  CHKERR snes_ctx->mField.cache_problem_entities(snes_ctx->problemName,
73  cache_ptr);
74 
75  for (auto &bit : snes_ctx->preProcess_Rhs) {
76  bit->vecAssembleSwitch = boost::move(snes_ctx->vecAssembleSwitch);
77  set(*bit);
79  snes_ctx->problemName, *bit);
80  unset(*bit);
81  snes_ctx->vecAssembleSwitch = boost::move(bit->vecAssembleSwitch);
82  }
83 
84  for (auto &lit : snes_ctx->loops_to_do_Rhs) {
85  lit.second->vecAssembleSwitch = boost::move(snes_ctx->vecAssembleSwitch);
86  set(*lit.second);
88  snes_ctx->problemName, lit.first, *lit.second, nullptr, snes_ctx->bH,
89  cache_ptr);
90  unset(*lit.second);
91  if (snes_ctx->vErify) {
92  // Verify finite elements, check for not a number
93  CHKERR VecAssemblyBegin(f);
94  CHKERR VecAssemblyEnd(f);
95  MPI_Comm comm = PetscObjectComm((PetscObject)f);
96  PetscSynchronizedPrintf(comm, "SNES Verify f FE < %s >\n",
97  lit.first.c_str());
98  const Problem *prb_ptr;
99  CHKERR snes_ctx->mField.get_problem(snes_ctx->problemName, &prb_ptr);
100  CHKERR snes_ctx->mField.getInterface<Tools>()->checkVectorForNotANumber(
101  prb_ptr, ROW, f);
102  }
103 
104  snes_ctx->vecAssembleSwitch = boost::move(lit.second->vecAssembleSwitch);
105  }
106 
107  for (auto &bit : snes_ctx->postProcess_Rhs) {
108  bit->vecAssembleSwitch = boost::move(snes_ctx->vecAssembleSwitch);
109  set(*bit);
111  snes_ctx->problemName, *bit);
112  unset(*bit);
113  snes_ctx->vecAssembleSwitch = boost::move(bit->vecAssembleSwitch);
114  }
115 
116  if (snes_ctx->vecAssembleSwitch) {
117  CHKERR VecGhostUpdateBegin(f, ADD_VALUES, SCATTER_REVERSE);
118  CHKERR VecGhostUpdateEnd(f, ADD_VALUES, SCATTER_REVERSE);
119  CHKERR VecAssemblyBegin(f);
120  CHKERR VecAssemblyEnd(f);
121  }
122  PetscLogEventEnd(snes_ctx->MOFEM_EVENT_SnesRhs, 0, 0, 0, 0);
124 }
125 
126 PetscErrorCode SnesMat(SNES snes, Vec x, Mat A, Mat B, void *ctx) {
127  SnesCtx *snes_ctx = (SnesCtx *)ctx;
128  // PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
130  PetscLogEventBegin(snes_ctx->MOFEM_EVENT_SnesMat, 0, 0, 0, 0);
131  if (snes_ctx->zeroPreCondMatrixB)
132  CHKERR MatZeroEntries(B);
133 
134  snes_ctx->matAssembleSwitch = boost::movelib::make_unique<bool>(true);
135 
136  auto set = [&](auto &fe) {
137  fe.snes = snes;
138  fe.snes_x = x;
139  fe.snes_A = A;
140  fe.snes_B = B;
141  fe.snes_ctx = SnesMethod::CTX_SNESSETJACOBIAN;
142  fe.ksp_ctx = KspMethod::CTX_OPERATORS;
144  };
145 
146  auto unset = [&](auto &fe) {
147  fe.snes_ctx = SnesMethod::CTX_SNESNONE;
148  fe.ksp_ctx = KspMethod::CTX_KSPNONE;
149  fe.data_ctx = PetscData::CtxSetNone;
150  };
151 
152  auto cache_ptr = boost::make_shared<CacheTuple>();
153  CHKERR snes_ctx->mField.cache_problem_entities(snes_ctx->problemName,
154  cache_ptr);
155 
156  CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
157  CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
158  CHKERR snes_ctx->mField.getInterface<VecManager>()->setLocalGhostVector(
159  snes_ctx->problemName, COL, x, INSERT_VALUES, SCATTER_REVERSE);
160  for (auto &bit : snes_ctx->preProcess_Mat) {
161  bit->matAssembleSwitch = boost::move(snes_ctx->matAssembleSwitch);
162  set(*bit);
164  snes_ctx->problemName, *bit);
165  unset(*bit);
166  snes_ctx->matAssembleSwitch = boost::move(bit->matAssembleSwitch);
167  }
168 
169  for (auto &lit : snes_ctx->loops_to_do_Mat) {
170  lit.second->matAssembleSwitch = boost::move(snes_ctx->matAssembleSwitch);
171  set(*lit.second);
173  snes_ctx->problemName, lit.first, *(lit.second), nullptr, snes_ctx->bH,
174  cache_ptr);
175  unset(*lit.second);
176  snes_ctx->matAssembleSwitch = boost::move(lit.second->matAssembleSwitch);
177  }
178 
179  for (auto &bit : snes_ctx->postProcess_Mat) {
180  bit->matAssembleSwitch = boost::move(snes_ctx->matAssembleSwitch);
181  set(*bit);
183  snes_ctx->problemName, *bit);
184  unset(*bit);
185  snes_ctx->matAssembleSwitch = boost::move(bit->matAssembleSwitch);
186  }
187 
188  if (*snes_ctx->matAssembleSwitch) {
189  CHKERR MatAssemblyBegin(B, snes_ctx->typeOfAssembly);
190  CHKERR MatAssemblyEnd(B, snes_ctx->typeOfAssembly);
191  }
192  PetscLogEventEnd(snes_ctx->MOFEM_EVENT_SnesMat, 0, 0, 0, 0);
194 }
195 
196 MoFEMErrorCode SnesMoFEMSetAssemblyType(SNES snes, MatAssemblyType type) {
197  SnesCtx *snes_ctx;
198  // PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
200  CHKERR SNESGetApplicationContext(snes, &snes_ctx);
201  snes_ctx->typeOfAssembly = type;
203 }
204 
206  SnesCtx *snes_ctx;
208  CHKERR SNESGetApplicationContext(snes, &snes_ctx);
209  snes_ctx->bH = bh;
211 }
212 
213 } // 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:149
PetscLogEvent MOFEM_EVENT_SnesRhs
Log events to assemble residual.
Definition: SnesCtx.hpp:148
virtual MoFEMErrorCode cache_problem_entities(const std::string prb_name, CacheTupleWeakPtr cache_ptr)=0
Cache variables.
static constexpr Switches CtxSetB
Definition: LoopMethods.hpp:64
boost::movelib::unique_ptr< bool > matAssembleSwitch
Definition: SnesCtx.hpp:147
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:126
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:485
Auxiliary tools.
Definition: Tools.hpp:30
static Index< 'l', 3 > l
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:196
BasicMethodsSequence postProcess_Rhs
Sequence of methods run after residual is assembled.
Definition: SnesCtx.hpp:55
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
static Index< 'i', 3 > i
FEMethodsSequence loops_to_do_Rhs
Definition: SnesCtx.hpp:46
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:67
FEMethodsSequence loops_to_do_Mat
Definition: SnesCtx.hpp:44
Interface for nonlinear (SNES) solver.
Definition: SnesCtx.hpp:27
static constexpr Switches CtxSetF
Definition: LoopMethods.hpp:62
BasicMethodsSequence postProcess_Mat
Definition: SnesCtx.hpp:50
Vector manager is used to create vectors \mofem_vectors.
Definition: VecManager.hpp:36
boost::movelib::unique_ptr< bool > vecAssembleSwitch
Definition: SnesCtx.hpp:146
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:604
BasicMethodsSequence preProcess_Rhs
Sequence of methods run before residual is assembled.
Definition: SnesCtx.hpp:53
static constexpr Switches CtxSetA
Definition: LoopMethods.hpp:63
virtual const Problem * get_problem(const std::string &problem_name) const =0
Get the problem object.
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:415
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:17
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 ...
static constexpr Switches CtxSetX
Definition: LoopMethods.hpp:65
MoFEMErrorCode SnesMoFEMSetBehavior(SNES snes, MoFEMTypes bh)
Set behavior if finite element in sequence does not exist.
Definition: SnesCtx.cpp:205
MoFEMTypes
Those types control how functions respond on arguments, f.e. error handling.
Definition: definitions.h:189
BasicMethodsSequence preProcess_Mat
Definition: SnesCtx.hpp:48
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)
static constexpr Switches CtxSetNone
Definition: LoopMethods.hpp:61