v0.14.0
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 
19 namespace MoFEM {
20 
21 constexpr const char MoFEM_BLOCK_MAT[] = "mofem_block_mat";
22 
23 /**
24  * @brief Structure to register events for Schur block assembly and solver
25  */
26 struct SchurEvents {
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_zeroRowsAndCols;
33  SchurEvents();
34 };
35 
36 struct SchurElemMats;
37 struct SchurElemMatsBlock;
39 
41 
42  OpSchurAssembleBase() = delete;
43 
44 private:
46 };
47 
49 
50 /**
51  * @brief Construct a new Op Schur Assemble End object
52  *
53  * @param fields_name list of fields
54  * @param field_ents list of entities on which schur complement is applied
55  * (can be empty)
56  * @param sequence_of_aos list of maps from base problem to Schur complement
57  * matrix
58  * @param sequence_of_mats list of Schur complement matrices
59  * @param sym_schur true if Schur complement is symmetric
60  * @param symm_op true if block diagonal is symmetric
61  */
63  std::vector<std::string> fields_name,
64  std::vector<boost::shared_ptr<Range>> field_ents,
65  std::vector<SmartPetscObj<AO>> sequence_of_aos,
66  std::vector<SmartPetscObj<Mat>> sequence_of_mats,
67  std::vector<bool> sym_schur, bool symm_op,
68  boost::shared_ptr<BlockStructure> diag_blocks = nullptr);
69 
70 /**
71  * @brief Construct a new Op Schur Assemble End object
72  *
73  * @param fields_name list of fields
74  * @param field_ents list of entities on which schur complement is applied
75  * (can be empty)
76  * @param sequence_of_aos list of maps from base problem to Schur complement
77  * matrix
78  * @param sequence_of_mats list of Schur complement matrices
79  * @param sym_schur true if Schur complement is symmetric
80  * @param diag_eps add epsilon on diagonal of inverted matrix
81  * @param symm_op true if block diagonal is symmetric
82  */
84  std::vector<std::string> fields_name,
85  std::vector<boost::shared_ptr<Range>> field_ents,
86  std::vector<SmartPetscObj<AO>> sequence_of_aos,
87  std::vector<SmartPetscObj<Mat>> sequence_of_mats,
88  std::vector<bool> sym_schur, std::vector<double> diag_eps, bool symm_op,
89  boost::shared_ptr<BlockStructure> diag_blocks = nullptr);
90 
91 using SchurFieldPair = std::pair<std::string, std::string>;
92 
93 using SchurFEOpsFEandFields = std::vector<
94 
95  std::pair<std::string, std::vector<SchurFieldPair>>
96 
97  >;
98 
99 /**
100  * @brief Create a Mat Diag Blocks object
101  *
102  * @return Mat
103  */
104 boost::shared_ptr<BlockStructure> createBlockMatStructure(
105 
106  DM dm, //< dm
107  SchurFEOpsFEandFields schur_fe_op_vec //< block elements
108 
109 );
110 
111 using SchurShellMatData =
112  std::pair<SmartPetscObj<Mat>, boost::shared_ptr<BlockStructure>>;
113 
114 /**
115  * @brief Create a Schur Mat object
116  *
117  * @param dm
118  * @param data
119  * @return std::pair<SmartPetscObj<Mat>, boost::shared_ptr<BlockStructure>>
120  */
121 SchurShellMatData createBlockMat(DM dm, boost::shared_ptr<BlockStructure> data);
122 
123 using NestSchurData = std::tuple<
124 
125  std::array<SmartPetscObj<Mat>, 4>,
126  std::array<boost::shared_ptr<BlockStructure>, 4>,
127  boost::shared_ptr<BlockStructure>,
128  std::pair<SmartPetscObj<IS>, SmartPetscObj<IS>>
129 
130  >;
131 
132 /**
133  * @brief Get the Schur Nest Mat Array object
134  *
135  * @param dms schur dm, and block dm
136  * @param block mat A data
137  * @param fields_name list of fields
138  * @param field_ents list of entities on which schur complement is applied
139  * @param add_preconditioner_block add block for preconditioner
140  * @return boost::shared_ptr<NestSchurData>
141  */
142 boost::shared_ptr<NestSchurData>
144  boost::shared_ptr<BlockStructure> block_mat_data,
145 
146  std::vector<std::string> fields_name, //< a00 fields
147  std::vector<boost::shared_ptr<Range>> field_ents, //< a00 ents
148  bool add_preconditioner_block = false
149 
150 );
151 
152 /**
153  * @brief Switch preconditioner
154  *
155  * @param block_mat_data
156  * @return MoFEMErrorCode
157  */
159 schurSwitchPreconditioner(boost::shared_ptr<BlockStructure> block_mat_data);
160 
161 /**
162  * @brief Save block matrix as a mesh
163  *
164  * @param block_mat_data
165  * @param filename
166  * @return MoFEMErrorCode
167  */
169 schurSaveBlockMesh(boost::shared_ptr<BlockStructure> block_mat_data,
170  std::string filename);
171 
172 /**
173  * @brief Create a Mat Diag Blocks object
174  *
175  * \code {.cpp}
176  *
177  * auto [nested_mat, nested_data_ptr] = createSchurNestedMatrix(
178  *
179  * getNestSchurData(
180  *
181  * {schur_dm, block_dm}, shell_data,
182  *
183  * {"TENSOR"}, {nullptr}
184  *
185  * )
186  *
187  * );
188  *
189  * \endcode
190  *
191  * @return Mat
192  */
193 std::pair<SmartPetscObj<Mat>, boost::shared_ptr<NestSchurData>>
194 createSchurNestedMatrix(boost::shared_ptr<NestSchurData> schur_net_data_ptr);
195 
196 template <>
197 MoFEMErrorCode DMMoFEMSetNestSchurData(DM dm, boost::shared_ptr<NestSchurData>);
198 
199 /**
200  * @brief Set PC for A00 block
201  *
202  * @param pc
203  * @return MoFEMErrorCode
204  */
206 
208 
210  SchurBackendMatSetValuesPtr() = delete;
211  using MatSetValuesPtr = boost::function<MoFEMErrorCode(
212  Mat M, const EntitiesFieldData::EntData &row_data,
213  const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat,
214  InsertMode iora)>;
215  static MatSetValuesPtr matSetValuesPtr; ///< backend assembly function
216  static MatSetValuesPtr
217  matSetValuesBlockPtr; ///< backend assembly block mat function
218  static MatSetValuesPtr
219  matSetValuesPreconditionedBlockPtr; ///< backend assembly block
220  ///< preconditioner mat function
221 };
222 
223 template <>
226  const EntitiesFieldData::EntData &col_data,
227  const MatrixDouble &mat, InsertMode iora);
228 
229 template <>
230 inline MoFEMErrorCode
232  const VectorDouble &nf, InsertMode iora) {
233  return VecSetValues<EssentialBcStorage>(V, data, nf, iora);
234 }
235 
236 template <>
237 MoFEMErrorCode MatSetValues<AssemblyTypeSelector<SCHUR>>(
238  Mat M, const EntitiesFieldData::EntData &row_data,
239  const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat,
240  InsertMode iora);
241 
242 template <>
243 inline MoFEMErrorCode VecSetValues<AssemblyTypeSelector<SCHUR>>(
244  Vec V, const EntitiesFieldData::EntData &data, const VectorDouble &nf,
245  InsertMode iora) {
246  return VecSetValues<SchurElemMats>(V, data, nf, iora);
247 }
248 
249 /***
250  * @brief Specialization of MatSetValues for BlockStructure
251  */
252 template <>
255  const EntitiesFieldData::EntData &col_data,
256  const MatrixDouble &mat, InsertMode iora);
257 
258 /***
259  * @brief Specialisation of MatSetValues for AssemblyTypeSelector<BLOCK_MAT>
260  */
261 template <>
262 inline MoFEMErrorCode MatSetValues<AssemblyTypeSelector<BLOCK_MAT>>(
263  Mat M, const EntitiesFieldData::EntData &row_data,
264  const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat,
265  InsertMode iora) {
266  return MatSetValues<BlockStructure>(M, row_data, col_data, mat, iora);
267 }
268 
269 /***
270  * @brief Specialisation of VecSetValues for AssemblyTypeSelector<BLOCK_MAT>
271  */
272 template <>
273 inline MoFEMErrorCode VecSetValues<AssemblyTypeSelector<BLOCK_MAT>>(
274  Vec V, const EntitiesFieldData::EntData &data, const VectorDouble &nf,
275  InsertMode iora) {
276  return VecSetValues<EssentialBcStorage>(V, data, nf, iora);
277 }
278 
279 /***
280  * @brief Specialization of MatSetValues for SchurElemMatsBlock
281  */
282 template <>
285  const EntitiesFieldData::EntData &row_data,
286  const EntitiesFieldData::EntData &col_data,
287  const MatrixDouble &mat, InsertMode iora);
288 
289 /***
290  * @brief Specialization of VecSetValues for SchurElemMatsBlock
291  */
292 template <>
293 inline MoFEMErrorCode
295  const VectorDouble &nf, InsertMode iora) {
296  return VecSetValues<EssentialBcStorage>(V, data, nf, iora);
297 }
298 
299 /***
300  * @brief Specialisation of MatSetValues for AssemblyTypeSelector<BLOCK_SCHUR>
301  */
302 template <>
303 inline MoFEMErrorCode MatSetValues<AssemblyTypeSelector<BLOCK_SCHUR>>(
304  Mat M, const EntitiesFieldData::EntData &row_data,
305  const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat,
306  InsertMode iora) {
307  return MatSetValues<SchurElemMatsBlock>(M, row_data, col_data, mat, iora);
308 }
309 
310 /***
311  * @brief Specialisation of VecSetValues for AssemblyTypeSelector<BLOCK_SCHUR>
312  */
313 template <>
314 inline MoFEMErrorCode VecSetValues<AssemblyTypeSelector<BLOCK_SCHUR>>(
315  Vec V, const EntitiesFieldData::EntData &data, const VectorDouble &nf,
316  InsertMode iora) {
317  return VecSetValues<EssentialBcStorage>(V, data, nf, iora);
318 }
319 
320 /***
321  * @brief Specialization of MatSetValues for SchurElemMatsPreconditionedBlock
322  */
323 template <>
325  Mat M, const EntitiesFieldData::EntData &row_data,
326  const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat,
327  InsertMode iora);
328 
329 /***
330  * @brief Specialisation of MatSetValues for
331  * AssemblyTypeSelector<BLOCK_PRECONDITIONER_SCHUR>
332  */
333 template <>
334 inline MoFEMErrorCode
335 MatSetValues<AssemblyTypeSelector<BLOCK_PRECONDITIONER_SCHUR>>(
336  Mat M, const EntitiesFieldData::EntData &row_data,
337  const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat,
338  InsertMode iora) {
339  return MatSetValues<SchurElemMatsPreconditionedBlock>(M, row_data, col_data,
340  mat, iora);
341 }
342 
343 /***
344  * @brief Specialisation of VecSetValues for AssemblyTypeSelector<BLOCK_SCHUR>
345  */
346 template <>
347 inline MoFEMErrorCode
348 VecSetValues<AssemblyTypeSelector<BLOCK_PRECONDITIONER_SCHUR>>(
349  Vec V, const EntitiesFieldData::EntData &data, const VectorDouble &nf,
350  InsertMode iora) {
351  return ::VecSetValues(V, data.getIndices().size(),
352  &*data.getIndices().begin(), &*nf.begin(), iora);
353 }
354 
355 } // namespace MoFEM
356 
357 #endif //__SCHUR_HPP__
UBlasMatrix< double >
MoFEM::EntitiesFieldData::EntData
Data on single entity (This is passed as argument to DataOperator::doWork)
Definition: EntitiesFieldData.hpp:128
DEPRECATED
#define DEPRECATED
Definition: definitions.h:17
MoFEM::MatSetValues< BlockStructure >
MoFEMErrorCode MatSetValues< BlockStructure >(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat, InsertMode iora)
Definition: Schur.cpp:2875
MoFEM::MoFEM_BLOCK_MAT
constexpr const char MoFEM_BLOCK_MAT[]
Definition: Schur.hpp:21
MoFEM::SchurFieldPair
std::pair< std::string, std::string > SchurFieldPair
Definition: Schur.hpp:91
MoFEM::OpSchurAssembleBase::OpSchurAssembleBase
OpSchurAssembleBase()=delete
MoFEM::Exceptions::MoFEMErrorCode
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
MoFEM::Types::MatrixDouble
UBlasMatrix< double > MatrixDouble
Definition: Types.hpp:77
MoFEM::SchurBackendMatSetValuesPtr::MatSetValuesPtr
boost::function< MoFEMErrorCode(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat, InsertMode iora)> MatSetValuesPtr
Definition: Schur.hpp:214
MoFEM::SchurEvents::SchurEvents
SchurEvents()
Definition: Schur.cpp:355
MoFEM::SchurEvents::MOFEM_EVENT_BlockStructureMult
static PetscLogEvent MOFEM_EVENT_BlockStructureMult
Definition: Schur.hpp:30
MoFEM::SchurEvents::MOFEM_EVENT_schurMatSetValues
static PetscLogEvent MOFEM_EVENT_schurMatSetValues
Definition: Schur.hpp:27
MoFEM::VecSetValues
MoFEMErrorCode VecSetValues(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Assemble PETSc vector.
Definition: EntitiesFieldData.hpp:1579
PlasticOps::M
FTensor::Index< 'M', 3 > M
Definition: PlasticOps.hpp:117
MoFEM::VecSetValues< SchurElemMatsBlock >
MoFEMErrorCode VecSetValues< SchurElemMatsBlock >(Vec V, const EntitiesFieldData::EntData &data, const VectorDouble &nf, InsertMode iora)
Definition: Schur.hpp:294
MoFEM::createOpSchurAssembleEnd
OpSchurAssembleBase * createOpSchurAssembleEnd(std::vector< std::string > fields_name, std::vector< boost::shared_ptr< Range >> field_ents, std::vector< SmartPetscObj< AO >> sequence_of_aos, std::vector< SmartPetscObj< Mat >> sequence_of_mats, std::vector< bool > sym_schur, bool symm_op, boost::shared_ptr< BlockStructure > diag_blocks)
Construct a new Op Schur Assemble End object.
Definition: Schur.cpp:2771
MoFEM::createBlockMat
SchurShellMatData createBlockMat(DM dm, boost::shared_ptr< BlockStructure > data)
Create a Schur Mat object.
Definition: Schur.cpp:1503
MoFEM
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
MoFEM::SchurEvents::MOFEM_EVENT_BlockStructureSolve
static PetscLogEvent MOFEM_EVENT_BlockStructureSolve
Definition: Schur.hpp:31
MoFEM::schurSwitchPreconditioner
MoFEMErrorCode schurSwitchPreconditioner(boost::shared_ptr< BlockStructure > block_mat_data)
Switch preconditioner.
Definition: Schur.cpp:2947
MoFEM::ForcesAndSourcesCore::UserDataOperator
Definition: ForcesAndSourcesCore.hpp:549
MoFEM::SchurBackendMatSetValuesPtr::SchurBackendMatSetValuesPtr
SchurBackendMatSetValuesPtr()=delete
MoFEM::createOpSchurAssembleBegin
OpSchurAssembleBase * createOpSchurAssembleBegin()
Definition: Schur.cpp:2766
MoFEM::SchurEvents::MOFEM_EVENT_opSchurAssembleEnd
static PetscLogEvent MOFEM_EVENT_opSchurAssembleEnd
Definition: Schur.hpp:28
MoFEM::SchurElemMatsBlock
Definition: Schur.cpp:2881
MoFEM::createSchurNestedMatrix
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:2738
MoFEM::MatSetValues< SchurElemMatsPreconditionedBlock >
MoFEMErrorCode MatSetValues< SchurElemMatsPreconditionedBlock >(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat, InsertMode iora)
Definition: Schur.cpp:2938
MoFEM::SchurBackendMatSetValuesPtr::matSetValuesPtr
static MatSetValuesPtr matSetValuesPtr
backend assembly function
Definition: Schur.hpp:215
MoFEM::SchurElemMatsPreconditionedBlock
Definition: Schur.cpp:2914
MoFEM::SchurBackendMatSetValuesPtr
Definition: Schur.hpp:209
EntData
EntitiesFieldData::EntData EntData
Definition: child_and_parent.cpp:37
MoFEM::OpSchurAssembleBase
Definition: Schur.hpp:40
MoFEM::setSchurMatSolvePC
MoFEMErrorCode setSchurMatSolvePC(SmartPetscObj< PC > pc)
Definition: Schur.cpp:2823
MoFEM::SchurElemMats
Schur complement data storage.
Definition: Schur.cpp:173
MoFEM::setSchurA00MatSolvePC
MoFEMErrorCode setSchurA00MatSolvePC(SmartPetscObj< PC > pc)
Set PC for A00 block.
Definition: Schur.cpp:2805
MoFEM::SchurBackendMatSetValuesPtr::matSetValuesPreconditionedBlockPtr
static MatSetValuesPtr matSetValuesPreconditionedBlockPtr
Definition: Schur.hpp:219
MoFEM::MatSetValues< SchurElemMats >
MoFEMErrorCode MatSetValues< SchurElemMats >(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat, InsertMode iora)
Definition: Schur.cpp:2831
EigenMatrix::Vec
const FTensor::Tensor2< T, Dim, Dim > Vec
Definition: MatrixFunction.hpp:66
MoFEM::SchurEvents
Structure to register events for Schur block assembly and solver.
Definition: Schur.hpp:26
MoFEM::SchurShellMatData
std::pair< SmartPetscObj< Mat >, boost::shared_ptr< BlockStructure > > SchurShellMatData
Definition: Schur.hpp:112
MoFEM::Types::VectorDouble
UBlasVector< double > VectorDouble
Definition: Types.hpp:68
MoFEM::DMMoFEMSetNestSchurData
MoFEMErrorCode DMMoFEMSetNestSchurData(DM dm, boost::shared_ptr< NestSchurData >)
Definition: DMMoFEM.cpp:1562
MoFEM::VecSetValues< SchurElemMats >
MoFEMErrorCode VecSetValues< SchurElemMats >(Vec V, const EntitiesFieldData::EntData &data, const VectorDouble &nf, InsertMode iora)
Definition: Schur.hpp:231
MoFEM::createBlockMatStructure
boost::shared_ptr< BlockStructure > createBlockMatStructure(DM dm, SchurFEOpsFEandFields schur_fe_op_vec)
Create a Mat Diag Blocks object.
Definition: Schur.cpp:1196
MoFEM::SchurBackendMatSetValuesPtr::matSetValuesBlockPtr
static MatSetValuesPtr matSetValuesBlockPtr
backend assembly block mat function
Definition: Schur.hpp:217
MoFEM::SmartPetscObj< AO >
MoFEM::MatSetValues< SchurElemMatsBlock >
MoFEMErrorCode MatSetValues< SchurElemMatsBlock >(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat, InsertMode iora)
Definition: Schur.cpp:2907
MoFEM::NestSchurData
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:130
MoFEM::SchurEvents::MOFEM_EVENT_zeroRowsAndCols
static PetscLogEvent MOFEM_EVENT_zeroRowsAndCols
Definition: Schur.hpp:32
MoFEM::schurSaveBlockMesh
MoFEMErrorCode schurSaveBlockMesh(boost::shared_ptr< BlockStructure > block_mat_data, std::string filename)
Save block matrix as a mesh.
Definition: Schur.cpp:2962
MoFEM::SchurEvents::MOFEM_EVENT_BlockStructureSetValues
static PetscLogEvent MOFEM_EVENT_BlockStructureSetValues
Definition: Schur.hpp:29
MoFEM::SchurFEOpsFEandFields
std::vector< std::pair< std::string, std::vector< SchurFieldPair > > > SchurFEOpsFEandFields
Definition: Schur.hpp:97
MoFEM::VecSetValues< EssentialBcStorage >
MoFEMErrorCode VecSetValues< EssentialBcStorage >(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Set values to vector in operator.
Definition: FormsIntegrators.cpp:76
MoFEM::getNestSchurData
boost::shared_ptr< NestSchurData > getNestSchurData(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)
Get the Schur Nest Mat Array object.
Definition: Schur.cpp:2249
MoFEM::ForcesAndSourcesCore::UserDataOperator::UserDataOperator
UserDataOperator(const FieldSpace space, const char type=OPSPACE, const bool symm=true)
Definition: ForcesAndSourcesCore.cpp:1974