v0.16.3
Loading...
Searching...
No Matches
Schur.hpp
Go to the documentation of this file.
1/**
2 * @file Schur.hpp
3 * @brief Assemble Schur complement
4 * @date 2023-02-02
5 *
6 * @copyright Copyright (c) 2023
7 *
8 * To create nested system of Schur complements, you push sequence of operator,
9 * to set up data on entities, and then assemble complements.
10 *
11 * \note Try separate floating points operations from book keeping. Also, align
12 * memory that blocks follow floating point operations.
13 *
14 */
15
16#ifndef __SCHUR_HPP__
17#define __SCHUR_HPP__
18
19namespace MoFEM {
20
21constexpr const char MoFEM_BLOCK_MAT[] = "mofem_block_mat";
22
23/**
24 * @brief Structure to register events for Schur block assembly and solver
25 */
27 static PetscLogEvent MOFEM_EVENT_schurMatSetValues;
28 static PetscLogEvent MOFEM_EVENT_opSchurAssembleEnd;
30 static PetscLogEvent MOFEM_EVENT_BlockStructureMult;
31 static PetscLogEvent MOFEM_EVENT_BlockStructureSolve;
32 static PetscLogEvent MOFEM_EVENT_AssembleSchurMat;
33 static PetscLogEvent MOFEM_EVENT_zeroRowsAndCols;
35};
36
37struct SchurElemMats;
40
48
50
51/**
52 * @brief Construct a new Op Schur Assemble End object
53 *
54 * @param fields_name list of fields (can be empty)
55 * @param field_ents list of entities on which schur complement is applied
56 * @param schur_aos maps dofs indices from main problem to schur complement
57 * @param schur_mat schur matrix
58 * @param sym_schur true if schur (matrix) complement is symmetric
59 * @param symm_op true if block diagonal is symmetric
60 */
62createOpSchurAssembleEnd(std::vector<std::string> fields_name,
63 std::vector<boost::shared_ptr<Range>> field_ents,
66 bool sym_schur = false, bool symm_op = false);
67
68/**
69 * @brief Create a Op Schur Zero Rows And Cols object
70 *
71 * @param marker_ptr
72 * @return OpSchurAssembleBase*
73 */
75 boost::shared_ptr<std::vector<unsigned char>> marker_ptr, double diag_val);
76
77using SchurFieldPair = std::pair<std::string, std::string>;
78
79using SchurFEOpsFEandFields = std::vector<
80
81 std::pair<std::string, std::vector<SchurFieldPair>>
82
83 >;
84
85/**
86 * @brief Create block matrix structure
87 *
88 * For each listed element and each listed pair of fields, one dense block is
89 * allocated per pair of (row entity, column entity). Blocks are stored
90 * row-major, values are shared by block matrix and by nested Schur matrices
91 * created with createSchurNestedMatrixStruture. Block values are allocated on
92 * first use.
93 *
94 * @param dm problem DM
95 * @param schur_fe_op_vec list of elements with pairs of (row, column) fields
96 * @return boost::shared_ptr<BlockStructure>
97 */
98boost::shared_ptr<BlockStructure> createBlockMatStructure(
99
100 DM dm, //< dm
101 SchurFEOpsFEandFields schur_fe_op_vec //< block elements
102
103);
104
106 std::pair<SmartPetscObj<Mat>, boost::shared_ptr<BlockStructure>>;
107
108/**
109 * @brief Create a Schur Mat object
110 *
111 * @param dm
112 * @param data
113 * @return std::pair<SmartPetscObj<Mat>, boost::shared_ptr<BlockStructure>>
114 */
115SchurShellMatData createBlockMat(DM dm, boost::shared_ptr<BlockStructure> data);
116
117using NestSchurData = std::tuple<
118
119 std::array<SmartPetscObj<Mat>, 4>,
120 std::array<boost::shared_ptr<BlockStructure>, 4>,
121 boost::shared_ptr<BlockStructure>,
122 std::pair<SmartPetscObj<IS>, SmartPetscObj<IS>>
123
124 >;
125
126/**
127 * @brief Create structure of nested matrix [A11 A10; A01 A00]
128 *
129 * Storage contract:
130 *
131 * - Blocks of A00 (both entities in block DM) of one finite element are
132 * stored in a buffer of that element. Eliminated fields have to be element
133 * local (L2, broken spaces, interior DOFs); an entity shared by two elements
134 * is an error. Elements with the same block pattern (entities, numbers of
135 * DOFs, listed pairs) share the layout of their buffers.
136 * - Buffers start with listed blocks only. At the first factorisation each
137 * pattern is analysed on a probe element: entities whose diagonal block is
138 * an admissible pivot are eliminated block by block (block LU in place, fill
139 * only where the pattern creates it), the remaining entities form a dense
140 * core factorised with partial pivoting. Buffers are then relaid in place.
141 * The analysis uses values only, it does not depend on the application.
142 * - Block factors of every element are accepted only if the backward error of
143 * a solve with them is small; otherwise the element is factorised dense in
144 * a separate buffer.
145 * - Factors are computed by assembleBlockMatSchur or by first MatSolve on the
146 * A00 matrix, and are reused by MatMult, MatSolve and assembleBlockMatSchur
147 * until MatZeroEntries is called. Assembly or MatZeroRowsColumns on
148 * factorised matrix is an error, i.e. each assembly has to start with
149 * MatZeroEntries.
150 * - If add_preconditioner_block is true, preconditioner buffers are allocated
151 * only for A00 elements, and factors of (A00 + preconditioner) are stored in
152 * place of preconditioner blocks, A00 blocks are kept intact.
153 * Preconditioner can be assembled only to A00 blocks.
154 * - MatSolve is implemented only for the A00 matrix (last matrix in the
155 * array). Processes without A00 elements perform empty solve.
156 * - Element matrices not assembled on this process (copies of elements owned
157 * by other processes) are zero and are skipped.
158 * - Layout of shared storage is fixed by this function, it can be called only
159 * once for given block structure.
160 *
161 * Options:
162 * - -schur_a00_dense: dense element matrices, no block elimination
163 * - -schur_a00_rcond_min (1e-12): smallest reciprocal condition number of
164 * diagonal block admissible as pivot
165 * - -schur_a00_pivot_threshold (0, off): block threshold pivoting, smallest
166 * singular value of pivot block relative to its couplings
167 * - -schur_a00_backward_error (1e-12): accepted backward error of solve with
168 * block factors (or 100 times the dense backward error on probe)
169 *
170 * See doc/development/schur.md.
171 *
172 * @param dms schur dm, and block dm
173 * @param block mat A data
174 * @param fields_name list of fields
175 * @param field_ents list of entities on which schur complement is applied
176 * @param add_preconditioner_block add block for preconditioner
177 * @return boost::shared_ptr<NestSchurData>
178 */
179boost::shared_ptr<NestSchurData> createSchurNestedMatrixStruture(
180 std::pair<SmartPetscObj<DM>, SmartPetscObj<DM>> dms,
181 boost::shared_ptr<BlockStructure> block_mat_data,
182
183 std::vector<std::string> fields_name, //< a00 fields
184 std::vector<boost::shared_ptr<Range>> field_ents, //< a00 ents
185 bool add_preconditioner_block = false
186
187);
188
189/**
190 * @brief Assemble Schur complement S = A11 - A10 A00^{-1} A01 from block
191 * matrix
192 *
193 * A00 is eliminated element by element. If fields_name and field_ents
194 * coincide with A00 of nested matrix (see createSchurNestedMatrixStruture),
195 * A00 element matrices are factorised in place and factors are reused by
196 * MatSolve. Otherwise element matrices are factorised in scratch memory, and
197 * it is an error if A00 is already factorised in place.
198 *
199 * @param m_field
200 * @param B block matrix
201 * @param S Schur complement matrix (PETSc matrix)
202 * @param fields_name eliminated fields
203 * @param field_ents entities of eliminated fields (can be null)
204 * @param ao mapping from block matrix indices to S indices
205 * @return MoFEMErrorCode
206 */
208assembleBlockMatSchur(MoFEM::Interface &m_field, Mat B, Mat S,
209 std::vector<std::string> fields_name,
210 std::vector<boost::shared_ptr<Range>> field_ents,
212
213/**
214 * @brief Get block values storage
215 *
216 * @note After createSchurNestedMatrixStruture it holds blocks outside A00
217 * only, A00 blocks are stored in element buffers. Direct access bypasses
218 * factorisation guard.
219 *
220 * @return boost::shared_ptr<std::vector<double>>
221 */
222boost::shared_ptr<std::vector<double>> getBlockMatStorageMat(Mat B);
223
224/**
225 * @brief Get preconditioner blocks storage
226 *
227 * @deprecated Preconditioner blocks are stored in buffers of A00 elements,
228 * this function returns an empty vector.
229 *
230 * @return boost::shared_ptr<std::vector<double>>
231 */
232boost::shared_ptr<std::vector<double>>
234
235/**
236 * @brief Switch preconditioner
237 *
238 * @param block_mat_data
239 * @return MoFEMErrorCode
240 */
242schurSwitchPreconditioner(boost::shared_ptr<BlockStructure> block_mat_data);
243
244/**
245 * @brief Save block matrix as a mesh
246 *
247 * @param block_mat_data
248 * @param filename
249 * @return MoFEMErrorCode
250 */
252schurSaveBlockMesh(boost::shared_ptr<BlockStructure> block_mat_data,
253 std::string filename);
254
255/**
256 * @brief Create a Mat Diag Blocks object
257 *
258 * \code {.cpp}
259 *
260 * auto [nested_mat, nested_data_ptr] = createSchurNestedMatrix(
261 *
262 * createSchurNestedMatrixStruture(
263 *
264 * {schur_dm, block_dm}, shell_data,
265 *
266 * {"TENSOR"}, {nullptr}
267 *
268 * )
269 *
270 * );
271 *
272 * \endcode
273 *
274 * @return Mat
275 */
276std::pair<SmartPetscObj<Mat>, boost::shared_ptr<NestSchurData>>
277createSchurNestedMatrix(boost::shared_ptr<NestSchurData> schur_net_data_ptr);
278
279template <>
280MoFEMErrorCode DMMoFEMSetNestSchurData(DM dm, boost::shared_ptr<NestSchurData>);
281
282/**
283 * @brief Set PC for A00 block
284 *
285 * @param pc
286 * @return MoFEMErrorCode
287 */
289
292 using MatSetValuesPtr = boost::function<MoFEMErrorCode(
293 Mat M, const EntitiesFieldData::EntData &row_data,
294 const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat,
295 InsertMode iora)>;
296 static MatSetValuesPtr matSetValuesPtr; ///< backend assembly function
297 static MatSetValuesPtr
298 matSetValuesBlockPtr; ///< backend assembly block mat function
299 static MatSetValuesPtr
300 matSetValuesPreconditionedBlockPtr; ///< backend assembly block
301 ///< preconditioner mat function
302};
303
304template <>
307 const EntitiesFieldData::EntData &col_data,
308 const MatrixDouble &mat, InsertMode iora);
309
310template <>
313 const VectorDouble &nf, InsertMode iora) {
314 return VecSetValues<EssentialBcStorage>(V, data, nf, iora);
315}
316
317template <>
318MoFEMErrorCode MatSetValues<AssemblyTypeSelector<SCHUR>>(
319 Mat M, const EntitiesFieldData::EntData &row_data,
320 const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat,
321 InsertMode iora);
322
323template <>
324inline MoFEMErrorCode VecSetValues<AssemblyTypeSelector<SCHUR>>(
325 Vec V, const EntitiesFieldData::EntData &data, const VectorDouble &nf,
326 InsertMode iora) {
327 return VecSetValues<SchurElemMats>(V, data, nf, iora);
328}
329
330/***
331 * @brief Specialization of MatSetValues for BlockStructure
332 */
333template <>
335MatSetValues<BlockStructure>(Mat M, const EntitiesFieldData::EntData &row_data,
336 const EntitiesFieldData::EntData &col_data,
337 const MatrixDouble &mat, InsertMode iora);
338
339/***
340 * @brief Specialisation of MatSetValues for AssemblyTypeSelector<BLOCK_MAT>
341 */
342template <>
343inline MoFEMErrorCode MatSetValues<AssemblyTypeSelector<BLOCK_MAT>>(
344 Mat M, const EntitiesFieldData::EntData &row_data,
345 const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat,
346 InsertMode iora) {
347 return MatSetValues<BlockStructure>(M, row_data, col_data, mat, iora);
348}
349
350/***
351 * @brief Specialisation of VecSetValues for AssemblyTypeSelector<BLOCK_MAT>
352 */
353template <>
354inline MoFEMErrorCode VecSetValues<AssemblyTypeSelector<BLOCK_MAT>>(
355 Vec V, const EntitiesFieldData::EntData &data, const VectorDouble &nf,
356 InsertMode iora) {
357 return VecSetValues<EssentialBcStorage>(V, data, nf, iora);
358}
359
360/***
361 * @brief Specialization of MatSetValues for SchurElemMatsBlock
362 */
363template <>
366 const EntitiesFieldData::EntData &row_data,
367 const EntitiesFieldData::EntData &col_data,
368 const MatrixDouble &mat, InsertMode iora);
369
370/***
371 * @brief Specialization of VecSetValues for SchurElemMatsBlock
372 */
373template <>
376 const VectorDouble &nf, InsertMode iora) {
377 return VecSetValues<EssentialBcStorage>(V, data, nf, iora);
378}
379
380/***
381 * @brief Specialisation of MatSetValues for AssemblyTypeSelector<BLOCK_SCHUR>
382 */
383template <>
384inline MoFEMErrorCode MatSetValues<AssemblyTypeSelector<BLOCK_SCHUR>>(
385 Mat M, const EntitiesFieldData::EntData &row_data,
386 const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat,
387 InsertMode iora) {
388 return MatSetValues<SchurElemMatsBlock>(M, row_data, col_data, mat, iora);
389}
390
391/***
392 * @brief Specialisation of VecSetValues for AssemblyTypeSelector<BLOCK_SCHUR>
393 */
394template <>
395inline MoFEMErrorCode VecSetValues<AssemblyTypeSelector<BLOCK_SCHUR>>(
396 Vec V, const EntitiesFieldData::EntData &data, const VectorDouble &nf,
397 InsertMode iora) {
398 return VecSetValues<EssentialBcStorage>(V, data, nf, iora);
399}
400
401/***
402 * @brief Specialization of MatSetValues for SchurElemMatsPreconditionedBlock
403 */
404template <>
406 Mat M, const EntitiesFieldData::EntData &row_data,
407 const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat,
408 InsertMode iora);
409
410/***
411 * @brief Specialisation of MatSetValues for
412 * AssemblyTypeSelector<BLOCK_PRECONDITIONER_SCHUR>
413 */
414template <>
416MatSetValues<AssemblyTypeSelector<BLOCK_PRECONDITIONER_SCHUR>>(
417 Mat M, const EntitiesFieldData::EntData &row_data,
418 const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat,
419 InsertMode iora) {
420 return MatSetValues<SchurElemMatsPreconditionedBlock>(M, row_data, col_data,
421 mat, iora);
422}
423
424/***
425 * @brief Specialisation of VecSetValues for AssemblyTypeSelector<BLOCK_SCHUR>
426 */
427template <>
429VecSetValues<AssemblyTypeSelector<BLOCK_PRECONDITIONER_SCHUR>>(
430 Vec V, const EntitiesFieldData::EntData &data, const VectorDouble &nf,
431 InsertMode iora) {
432 return ::VecSetValues(V, data.getIndices().size(),
433 &*data.getIndices().begin(), &*nf.begin(), iora);
434}
435
436/**
437 * @deprecated do not use
438 */
439DEPRECATED OpSchurAssembleBase *createOpSchurAssembleEnd(
440 std::vector<std::string> fields_name,
441 std::vector<boost::shared_ptr<Range>> field_ents,
442 std::vector<SmartPetscObj<AO>> sequence_of_aos,
443 std::vector<SmartPetscObj<Mat>> sequence_of_mats,
444 std::vector<bool> sym_schur, bool symm_op,
445 boost::shared_ptr<BlockStructure> diag_blocks = nullptr);
446
447/**
448 * @deprecated do not use
449 */
450DEPRECATED OpSchurAssembleBase *createOpSchurAssembleEnd(
451 std::vector<std::string> fields_name,
452 std::vector<boost::shared_ptr<Range>> field_ents,
453 std::vector<SmartPetscObj<AO>> sequence_of_aos,
454 std::vector<SmartPetscObj<Mat>> sequence_of_mats,
455 std::vector<bool> sym_schur, std::vector<double> diag_eps, bool symm_op,
456 boost::shared_ptr<BlockStructure> diag_blocks = nullptr);
457
458/** @deprecated do not use, use createSchurNestedMatrixStruture instead */
459DEPRECATED inline boost::shared_ptr<NestSchurData>
461 boost::shared_ptr<BlockStructure> block_mat_data,
462
463 std::vector<std::string> fields_name, //< a00 fields
464 std::vector<boost::shared_ptr<Range>> field_ents, //< a00 ents
465 bool add_preconditioner_block = false
466
467) {
468 return createSchurNestedMatrixStruture(dms, block_mat_data, fields_name,
469 field_ents, add_preconditioner_block);
470}
471
472} // namespace MoFEM
473
474#endif //__SCHUR_HPP__
#define DEPRECATED
Definition definitions.h:17
MoFEMErrorCode VecSetValues< EssentialBcStorage >(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Set values to vector in operator.
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
Definition Types.hpp:77
UBlasVector< double > VectorDouble
Definition Types.hpp:68
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
MoFEMErrorCode MatSetValues< SchurElemMats >(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat, InsertMode iora)
Definition Schur.cpp:4269
OpSchurAssembleBase * createOpSchurAssembleEnd(std::vector< std::string > fields_name, std::vector< boost::shared_ptr< Range > > field_ents, SmartPetscObj< AO > ao, SmartPetscObj< Mat > schur, bool sym_schur, bool symm_op)
Construct a new Op Schur Assemble End object.
Definition Schur.cpp:4196
MoFEMErrorCode MatSetValues< SchurElemMatsBlock >(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat, InsertMode iora)
Definition Schur.cpp:4345
MoFEMErrorCode schurSwitchPreconditioner(boost::shared_ptr< BlockStructure > block_mat_data)
Switch preconditioner.
Definition Schur.cpp:4385
MoFEMErrorCode setSchurA00MatSolvePC(SmartPetscObj< PC > pc)
Set PC for A00 block.
Definition Schur.cpp:4238
MoFEMErrorCode MatSetValues< SchurElemMatsPreconditionedBlock >(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat, InsertMode iora)
Definition Schur.cpp:4376
std::pair< SmartPetscObj< Mat >, boost::shared_ptr< BlockStructure > > SchurShellMatData
Definition Schur.hpp:106
std::pair< SmartPetscObj< Mat >, boost::shared_ptr< NestSchurData > > createSchurNestedMatrix(boost::shared_ptr< NestSchurData > schur_net_data_ptr)
Create a Mat Diag Blocks object.
Definition Schur.cpp:4163
MoFEMErrorCode MatSetValues< BlockStructure >(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat, InsertMode iora)
Definition Schur.cpp:4313
std::tuple< std::array< SmartPetscObj< Mat >, 4 >, std::array< boost::shared_ptr< BlockStructure >, 4 >, boost::shared_ptr< BlockStructure >, std::pair< SmartPetscObj< IS >, SmartPetscObj< IS > > > NestSchurData
Definition Schur.hpp:124
std::pair< std::string, std::string > SchurFieldPair
Definition Schur.hpp:77
boost::shared_ptr< std::vector< double > > getBlockMatPrconditionerStorageMat(Mat B)
Get preconditioner blocks storage.
Definition Schur.cpp:3461
DEPRECATED boost::shared_ptr< NestSchurData > getNestSchurData(std::pair< SmartPetscObj< DM >, SmartPetscObj< DM > > dms, boost::shared_ptr< BlockStructure > block_mat_data, std::vector< std::string > fields_name, std::vector< boost::shared_ptr< Range > > field_ents, bool add_preconditioner_block=false)
Definition Schur.hpp:460
boost::shared_ptr< BlockStructure > createBlockMatStructure(DM dm, SchurFEOpsFEandFields schur_fe_op_vec)
Create block matrix structure.
Definition Schur.cpp:2415
boost::shared_ptr< NestSchurData > createSchurNestedMatrixStruture(std::pair< SmartPetscObj< DM >, SmartPetscObj< DM > > dms, boost::shared_ptr< BlockStructure > block_mat_data_ptr, std::vector< std::string > fields_names, std::vector< boost::shared_ptr< Range > > field_ents, bool add_preconditioner_block)
Create structure of nested matrix [A11 A10; A01 A00].
Definition Schur.cpp:3667
OpSchurAssembleBase * createOpSchurZeroRowsAndCols(boost::shared_ptr< std::vector< unsigned char > > marker_ptr, double diag_val)
Create a Op Schur Zero Rows And Cols object.
Definition Schur.cpp:4208
MoFEMErrorCode schurSaveBlockMesh(boost::shared_ptr< BlockStructure > block_mat_data, std::string filename)
Save block matrix as a mesh.
Definition Schur.cpp:4400
constexpr const char MoFEM_BLOCK_MAT[]
Definition Schur.hpp:21
MoFEMErrorCode VecSetValues< SchurElemMatsBlock >(Vec V, const EntitiesFieldData::EntData &data, const VectorDouble &nf, InsertMode iora)
Definition Schur.hpp:375
MoFEMErrorCode DMMoFEMSetNestSchurData(DM dm, boost::shared_ptr< NestSchurData >)
Definition DMMoFEM.cpp:1584
std::vector< std::pair< std::string, std::vector< SchurFieldPair > > > SchurFEOpsFEandFields
Definition Schur.hpp:83
MoFEMErrorCode VecSetValues< SchurElemMats >(Vec V, const EntitiesFieldData::EntData &data, const VectorDouble &nf, InsertMode iora)
Definition Schur.hpp:312
SchurShellMatData createBlockMat(DM dm, boost::shared_ptr< BlockStructure > data)
Create a Schur Mat object.
Definition Schur.cpp:3072
MoFEMErrorCode assembleBlockMatSchur(MoFEM::Interface &m_field, Mat B, Mat S, std::vector< std::string > fields_name, std::vector< boost::shared_ptr< Range > > field_ents, SmartPetscObj< AO > ao)
Assemble Schur complement S = A11 - A10 A00^{-1} A01 from block matrix.
Definition Schur.cpp:3107
OpSchurAssembleBase * createOpSchurAssembleBegin()
Definition Schur.cpp:4191
boost::shared_ptr< std::vector< double > > getBlockMatStorageMat(Mat B)
Get block values storage.
Definition Schur.cpp:3452
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
UserDataOperator(const FieldSpace space, const char type=OPSPACE, const bool symm=true)
Constructor for operators working on finite element spaces.
static MatSetValuesPtr matSetValuesPreconditionedBlockPtr
Definition Schur.hpp:300
static MatSetValuesPtr matSetValuesPtr
backend assembly function
Definition Schur.hpp:296
static MatSetValuesPtr matSetValuesBlockPtr
backend assembly block mat function
Definition Schur.hpp:298
boost::function< MoFEMErrorCode(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat, InsertMode iora)> MatSetValuesPtr
Definition Schur.hpp:295
Schur complement data storage.
Definition Schur.cpp:161
Structure to register events for Schur block assembly and solver.
Definition Schur.hpp:26
static PetscLogEvent MOFEM_EVENT_BlockStructureSetValues
Definition Schur.hpp:29
static PetscLogEvent MOFEM_EVENT_BlockStructureMult
Definition Schur.hpp:30
static PetscLogEvent MOFEM_EVENT_zeroRowsAndCols
Definition Schur.hpp:33
static PetscLogEvent MOFEM_EVENT_opSchurAssembleEnd
Definition Schur.hpp:28
static PetscLogEvent MOFEM_EVENT_BlockStructureSolve
Definition Schur.hpp:31
static PetscLogEvent MOFEM_EVENT_schurMatSetValues
Definition Schur.hpp:27
static PetscLogEvent MOFEM_EVENT_AssembleSchurMat
Definition Schur.hpp:32
intrusive_ptr for managing petsc objects