v0.16.0
Loading...
Searching...
No Matches
KspCtx.cpp
Go to the documentation of this file.
1/**
2 * @brief Context for PETSc KSP, i.e. linear solver
3 * @author Anonymous contributor under MIT license
4 *
5 */
6
7namespace MoFEM {
8
9struct KspCtx::KspCtx::KspCtxImpl {
10
11 KspCtxImpl(MoFEM::Interface &m_field, std::string problem_name);
12
13 virtual ~KspCtxImpl() = default;
14
15 /**
16 * @return return reference to vector with FEMethod to calculate matrix
17 */
19
20 /**
21 * @return return vector to vector with FEMethod to vector
22 */
24
25 /**
26 * The sequence of BasicMethod is executed before residual is calculated. It
27 * can be used to setup data structures, e.g. zero global variable which is
28 * integrated in domain, e.g. for calculation of strain energy.
29 *
30 * @return reference to BasicMethod for preprocessing
31 */
33
34 /**
35 * The sequence of BasicMethod is executed after residual is calculated. It
36 * can be used to setup data structures, e.g. aggregate data from processors
37 * or to apply essential boundary conditions.
38 *
39 * @return reference to BasicMethod for postprocessing
40 */
42
43 /**
44 * @return reference to BasicMethod for preprocessing
45 */
47
48 /**
49 * The sequence of BasicMethod is executed after tangent matrix is calculated.
50 * It can be used to setup data structures, e.g. aggregate data from
51 * processors or to apply essential boundary conditions.
52 *
53 * @return reference to BasicMethod for postprocessing
54 */
58
59 friend PetscErrorCode KspRhs(KSP ksp, Vec f, void *ctx);
60 friend PetscErrorCode KspMat(KSP ksp, Mat A, Mat B, void *ctx);
61
62 /**
63 * @brief Clear loops
64 *
65 * @return MoFEMErrorCode
66 */
67 MoFEMErrorCode clearLoops();
68
69protected:
70 PetscLogEvent MOFEM_EVENT_KspRhs;
71 PetscLogEvent MOFEM_EVENT_KspMat;
72
73 boost::movelib::unique_ptr<bool> vecAssembleSwitch;
74 boost::movelib::unique_ptr<bool> matAssembleSwitch;
75
77 moab::Interface &moab;
78
79 std::string problemName; ///< Problem name
80 MoFEMTypes bH; ///< If set to MF_EXIST check if element exist
81
82 FEMethodsSequence loopsOperator; ///< Sequence of finite elements instances
83 ///< assembling tangent matrix
84 FEMethodsSequence loopsRhs; ///< Sequence of finite elements
85 ///< instances assembling residual vector
86 BasicMethodsSequence preProcessOperator; ///< Sequence of methods run before
87 ///< tangent matrix is assembled
88 BasicMethodsSequence postProcessOperator; ///< Sequence of methods run after
89 ///< tangent matrix is assembled
90 BasicMethodsSequence preProcessRhs; ///< Sequence of methods run before
91 ///< residual is assembled
92 BasicMethodsSequence postProcessRhs; ///< Sequence of methods run after
93 ///< residual is assembled
94};
95
96KspCtx::KspCtx(MoFEM::Interface &m_field, std::string problem_name)
97 : kspCtxImpl(boost::movelib::make_unique<KspCtx::KspCtxImpl>(
98 m_field, problem_name)) {}
99
100KspCtx::~KspCtx() = default;
101
103 return kspCtxImpl->getSetOperators();
104}
105
107 return kspCtxImpl->getComputeRhs();
108}
109
111 return kspCtxImpl->getPreProcComputeRhs();
112}
113
115 return kspCtxImpl->getPostProcComputeRhs();
116}
117
119 return kspCtxImpl->getPreProcSetOperators();
120}
121
123 return kspCtxImpl->getPostProcSetOperators();
124}
125
127
128KspCtx::KspCtxImpl::KspCtxImpl(MoFEM::Interface &m_field,
129 std::string problem_name)
130 : mField(m_field), moab(m_field.get_moab()), problemName(problem_name),
131 bH(MF_EXIST) {
132 PetscLogEventRegister("LoopKSPRhs", 0, &MOFEM_EVENT_KspRhs);
133 PetscLogEventRegister("LoopKSPMat", 0, &MOFEM_EVENT_KspMat);
134}
135
136MoFEMErrorCode KspCtx::KspCtxImpl::clearLoops() {
138 loopsOperator.clear();
139 loopsRhs.clear();
140 preProcessOperator.clear();
141 postProcessOperator.clear();
142 preProcessRhs.clear();
143 postProcessRhs.clear();
145}
146
147PetscErrorCode KspRhs(KSP ksp, Vec f, void *ctx) {
149 KspCtx::KspCtxImpl *ksp_ctx = static_cast<KspCtx *>(ctx)->kspCtxImpl.get();
150 PetscLogEventBegin(ksp_ctx->MOFEM_EVENT_KspRhs, 0, 0, 0, 0);
151
152 ksp_ctx->vecAssembleSwitch = boost::movelib::make_unique<bool>(true);
153
154 auto cache_ptr = boost::make_shared<CacheTuple>();
155 CHKERR ksp_ctx->mField.cache_problem_entities(ksp_ctx->problemName,
156 cache_ptr);
157
158 auto set = [&](auto &fe) {
159 fe.ksp = ksp;
160 fe.ksp_ctx = KspMethod::CTX_SETFUNCTION;
161 fe.data_ctx = PetscData::CtxSetF;
162 fe.ksp_f = f;
163 fe.cacheWeakPtr = cache_ptr;
164 };
165
166 auto unset = [&](auto &fe) {
167 fe.ksp_ctx = KspMethod::CTX_KSPNONE;
168 fe.data_ctx = PetscData::CtxSetNone;
169 };
170
171 // pre-process
172 for (auto &bit : ksp_ctx->preProcessRhs) {
173 bit->vecAssembleSwitch = boost::move(ksp_ctx->vecAssembleSwitch);
174 set(*bit);
175 CHKERR ksp_ctx->mField.problem_basic_method_preProcess(ksp_ctx->problemName,
176 *bit);
177 unset(*bit);
178 ksp_ctx->vecAssembleSwitch = boost::move(bit->vecAssembleSwitch);
179 }
180
181 // operators
182 for (auto &lit : ksp_ctx->loopsRhs) {
183 lit.second->vecAssembleSwitch = boost::move(ksp_ctx->vecAssembleSwitch);
184 set(*lit.second);
185 CHKERR ksp_ctx->mField.loop_finite_elements(ksp_ctx->problemName, lit.first,
186 *(lit.second), nullptr,
187 ksp_ctx->bH, cache_ptr);
188 unset(*lit.second);
189 ksp_ctx->vecAssembleSwitch = boost::move(lit.second->vecAssembleSwitch);
190 }
191
192 // post-process
193 for (auto &bit : ksp_ctx->postProcessRhs) {
194 bit->vecAssembleSwitch = boost::move(ksp_ctx->vecAssembleSwitch);
195 set(*bit);
196 CHKERR ksp_ctx->mField.problem_basic_method_postProcess(
197 ksp_ctx->problemName, *bit);
198 unset(*bit);
199 ksp_ctx->vecAssembleSwitch = boost::move(bit->vecAssembleSwitch);
200 }
201
202 if (*ksp_ctx->vecAssembleSwitch) {
203 CHKERR VecGhostUpdateBegin(f, ADD_VALUES, SCATTER_REVERSE);
204 CHKERR VecGhostUpdateEnd(f, ADD_VALUES, SCATTER_REVERSE);
205 CHKERR VecAssemblyBegin(f);
206 CHKERR VecAssemblyEnd(f);
207 }
208 PetscLogEventEnd(ksp_ctx->MOFEM_EVENT_KspRhs, 0, 0, 0, 0);
210}
211PetscErrorCode KspMat(KSP ksp, Mat A, Mat B, void *ctx) {
212 // PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
214 KspCtx::KspCtxImpl *ksp_ctx = static_cast<KspCtx *>(ctx)->kspCtxImpl.get();
215 PetscLogEventBegin(ksp_ctx->MOFEM_EVENT_KspMat, 0, 0, 0, 0);
216
217 ksp_ctx->matAssembleSwitch = boost::movelib::make_unique<bool>(true);
218 auto cache_ptr = boost::make_shared<CacheTuple>();
219 CHKERR ksp_ctx->mField.cache_problem_entities(ksp_ctx->problemName,
220 cache_ptr);
221
222 auto set = [&](auto &fe) {
223 fe.ksp = ksp;
224 fe.ksp_A = A;
225 fe.ksp_B = B;
226 fe.ksp_ctx = KspMethod::CTX_OPERATORS;
228 fe.cacheWeakPtr = cache_ptr;
229 };
230
231 auto unset = [&](auto &fe) {
232 fe.ksp_ctx = KspMethod::CTX_KSPNONE;
233 fe.data_ctx = PetscData::CtxSetNone;
234 };
235
236 auto ent_data_cache = boost::make_shared<std::vector<EntityCacheDofs>>();
237 auto ent_row_cache =
238 boost::make_shared<std::vector<EntityCacheNumeredDofs>>();
239 auto ent_col_cache =
240 boost::make_shared<std::vector<EntityCacheNumeredDofs>>();
241
242 // pre-procsess
243 for (auto &bit : ksp_ctx->preProcessOperator) {
244 bit->matAssembleSwitch = boost::move(ksp_ctx->matAssembleSwitch);
245 set(*bit);
246 CHKERR ksp_ctx->mField.problem_basic_method_preProcess(ksp_ctx->problemName,
247 *bit);
248 unset(*bit);
249 ksp_ctx->matAssembleSwitch = boost::move(bit->matAssembleSwitch);
250 }
251
252 // operators
253 for (auto &lit : ksp_ctx->loopsOperator) {
254 lit.second->matAssembleSwitch = boost::move(ksp_ctx->matAssembleSwitch);
255 set(*lit.second);
256 CHKERR ksp_ctx->mField.loop_finite_elements(ksp_ctx->problemName, lit.first,
257 *(lit.second), nullptr,
258 ksp_ctx->bH, cache_ptr);
259 unset(*lit.second);
260 ksp_ctx->matAssembleSwitch = boost::move(lit.second->matAssembleSwitch);
261 }
262
263 // post-process
264 for (auto &bit : ksp_ctx->postProcessOperator) {
265 bit->matAssembleSwitch = boost::move(ksp_ctx->matAssembleSwitch);
266 set(*bit);
267 CHKERR ksp_ctx->mField.problem_basic_method_postProcess(
268 ksp_ctx->problemName, *bit);
269 unset(*bit);
270 ksp_ctx->matAssembleSwitch = boost::move(bit->matAssembleSwitch);
271 }
272
273 if (ksp_ctx->matAssembleSwitch) {
274 CHKERR MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY);
275 CHKERR MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY);
276 }
277 PetscLogEventEnd(ksp_ctx->MOFEM_EVENT_KspMat, 0, 0, 0, 0);
279}
280
281} // namespace MoFEM
MoFEMTypes
Those types control how functions respond on arguments, f.e. error handling.
@ MF_EXIST
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
auto bit
set bit
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
std::deque< BasicMethodPtr > BasicMethodsSequence
Definition AuxPETSc.hpp:58
std::deque< PairNameFEMethodPtr > FEMethodsSequence
Definition AuxPETSc.hpp:57
constexpr AssemblyType A
Deprecated interface functions.
MoFEM::Interface & mField
Definition KspCtx.cpp:76
BasicMethodsSequence preProcessOperator
Definition KspCtx.cpp:86
boost::movelib::unique_ptr< bool > matAssembleSwitch
Definition KspCtx.cpp:74
BasicMethodsSequence & getPreProcSetOperators()
Definition KspCtx.cpp:46
BasicMethodsSequence postProcessOperator
Definition KspCtx.cpp:88
std::string problemName
Problem name.
Definition KspCtx.cpp:79
FEMethodsSequence & getSetOperators()
Definition KspCtx.cpp:18
MoFEMTypes bH
If set to MF_EXIST check if element exist.
Definition KspCtx.cpp:80
FEMethodsSequence loopsOperator
Definition KspCtx.cpp:82
BasicMethodsSequence & getPostProcComputeRhs()
Definition KspCtx.cpp:41
FEMethodsSequence & getComputeRhs()
Definition KspCtx.cpp:23
BasicMethodsSequence postProcessRhs
Definition KspCtx.cpp:92
boost::movelib::unique_ptr< bool > vecAssembleSwitch
Definition KspCtx.cpp:73
BasicMethodsSequence & getPostProcSetOperators()
Definition KspCtx.cpp:55
BasicMethodsSequence preProcessRhs
Definition KspCtx.cpp:90
BasicMethodsSequence & getPreProcComputeRhs()
Definition KspCtx.cpp:32
Interface for linear (KSP) solver.
Definition KspCtx.hpp:14
boost::movelib::unique_ptr< KspCtxImpl > kspCtxImpl
Definition KspCtx.hpp:74
BasicMethodsSequence & getPostProcComputeRhs()
Definition KspCtx.cpp:114
BasicMethodsSequence & getPreProcComputeRhs()
Definition KspCtx.cpp:110
BasicMethodsSequence & getPreProcSetOperators()
Definition KspCtx.cpp:118
FEMethodsSequence & getSetOperators()
Definition KspCtx.cpp:102
friend PetscErrorCode KspRhs(KSP ksp, Vec f, void *ctx)
Run over elements in the lists.
Definition KspCtx.cpp:147
FEMethodsSequence & getComputeRhs()
Definition KspCtx.cpp:106
MoFEMErrorCode clearLoops()
Clear loops.
Definition KspCtx.cpp:126
virtual ~KspCtx()
friend PetscErrorCode KspMat(KSP ksp, Mat A, Mat B, void *ctx)
Run over elements in the list.
Definition KspCtx.cpp:211
BasicMethodsSequence & getPostProcSetOperators()
Definition KspCtx.cpp:122
@ CTX_KSPNONE
No specific KSP context.
@ CTX_SETFUNCTION
Setting up the linear system function.
@ CTX_OPERATORS
Setting up linear operators.
static constexpr Switches CtxSetA
Jacobian matrix switch.
static constexpr Switches CtxSetNone
No data switch.
static constexpr Switches CtxSetF
Residual vector switch.
static constexpr Switches CtxSetB
Preconditioner matrix switch.