v0.14.0
Loading...
Searching...
No Matches
Schur.cpp
Go to the documentation of this file.
1/**
2 * @file Schur.cpp
3 * @brief Implementation of Schur Complement
4 * @date 2023-02-03
5 *
6 * @copyright Copyright (c) 2023
7 *
8 */
9
10namespace MoFEM {
11
13boost::ptr_vector<MatrixDouble> SchurL2Mats::locMats;
14boost::ptr_vector<VectorInt> SchurL2Mats::rowIndices;
15boost::ptr_vector<VectorInt> SchurL2Mats::colIndices;
16
17SchurL2Mats::SchurL2Mats(const size_t idx, const UId uid_row, const UId uid_col)
18 : iDX(idx), uidRow(uid_row), uidCol(uid_col) {}
19
22
25 const EntitiesFieldData::EntData &col_data,
26 const MatrixDouble &mat, InsertMode iora) {
27 return MatSetValues<AssemblyTypeSelector<PETSC>>(M, row_data, col_data, mat,
28 iora);
29}
30
33
36 const EntitiesFieldData::EntData &col_data,
37 const MatrixDouble &mat, InsertMode iora) {
39
40 CHKERR matSetValuesPtr(M, row_data, col_data, mat, iora);
41
42 auto get_row_indices = [&]() -> const VectorInt & {
43 if (auto e_ptr = row_data.getFieldEntities()[0]) {
44 if (auto stored_data_ptr =
45 e_ptr->getSharedStoragePtr<EssentialBcStorage>()) {
46 return stored_data_ptr->entityIndices;
47 }
48 }
49 return row_data.getIndices();
50 };
51
52 const auto &row_ind = get_row_indices();
53 const auto &col_ind = col_data.getIndices();
54
55 const auto nb_rows = row_ind.size();
56 const auto nb_cols = col_ind.size();
57
58#ifndef NDEBUG
59 if (mat.size1() != nb_rows) {
60 SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
61 "Wrong mat size %d != %d", mat.size1(), nb_rows);
62 }
63 if (mat.size2() != nb_cols) {
64 SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
65 "Wrong mat size %d != %d", mat.size2(), nb_cols);
66 }
67#endif // NDEBUG
68
69 const auto idx = SchurL2Mats::schurL2Storage.size();
70 const auto size = SchurL2Mats::locMats.size();
71
72 if (idx >= size) {
73 SchurL2Mats::locMats.push_back(new MatrixDouble());
74 SchurL2Mats::rowIndices.push_back(new VectorInt());
75 SchurL2Mats::colIndices.push_back(new VectorInt());
76 }
77
78 // insert index
79 auto get_uid = [](auto &data) {
80 if (data.getFieldEntities().size() == 1) {
81
82 return data.getFieldEntities()[0]->getLocalUniqueId();
83
84 } else {
85
86 // Is assumed that sum of entities ids gives unique id, that is not true,
87 // but corner case is improbable.
88
89 // @todo: debug version should have test
90
91 auto &uid0 = data.getFieldEntities()[0]->getLocalUniqueId();
92 auto field_id0 = FieldEntity::getFieldBitNumberFromUniqueId(uid0);
93 auto ent0 = FieldEntity::getHandleFromUniqueId(uid0);
94 auto type0 = type_from_handle(ent0);
95 auto id = id_from_handle(ent0);
96
97 for (auto i = 1; i < data.getFieldEntities().size(); ++i) {
98
99 // get entity id from ent
100 id += id_from_handle(
101
102 // get entity handle from unique uid
104 data.getFieldEntities()[i]->getLocalUniqueId())
105
106 );
107
108 }
109
111 field_id0,
112
113 ent_form_type_and_id(type0, id)
114
115 );
116
117 }
118 };
119
120 auto uid_row = get_uid(row_data);
121 auto uid_col = get_uid(col_data);
122 auto p = SchurL2Mats::schurL2Storage.emplace(idx, uid_row, uid_col);
123
124 auto get_storage = [&p]() { return const_cast<SchurL2Mats &>(*p.first); };
125
126 if (p.second) {
127
128 auto asmb = [&](auto &sm) {
129 sm.resize(nb_rows, nb_cols, false);
130 noalias(sm) = mat;
131 };
132
133 asmb(get_storage().getMat());
134
135 auto add_indices = [](auto &storage, auto &ind) {
136 storage.resize(ind.size(), false);
137 noalias(storage) = ind;
138 };
139
140 add_indices(get_storage().getRowInd(), row_ind);
141 add_indices(get_storage().getColInd(), col_ind);
142
143 } else {
144
145 auto asmb = [&](auto &sm) {
147
148#ifndef NDEBUG
149 if (sm.size1() != nb_rows) {
150 SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
151 "Wrong mat or storage size %d != %d", sm.size1(), nb_rows);
152 }
153 if (sm.size2() != nb_cols) {
154 SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
155 "Wrong mat or storage size %d != %d", sm.size2(), nb_cols);
156 }
157#endif // NDEBUG
158
159 switch (iora) {
160 case ADD_VALUES:
161 sm += mat;
162 break;
163 case INSERT_VALUES:
164 noalias(sm) = mat;
165 break;
166 default:
167 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
168 "Assembly type not implemented");
169 }
171 };
172
173 CHKERR asmb(get_storage().getMat());
174
175 }
176
178}
179
183#ifndef NDEBUG
184 MOFEM_LOG("SELF", Sev::noisy) << "Schur assemble begin";
185#endif
187
188 auto zero_mats = [&](auto &mats) {
189 for (auto &m : mats) {
190 m.resize(0, 0, false);
191 }
192 };
193
194 zero_mats(SchurL2Mats::locMats);
195
197}
198
200 std::vector<std::string> fields_name,
201 std::vector<boost::shared_ptr<Range>> field_ents,
202 std::vector<SmartPetscObj<AO>> sequence_of_aos,
203 std::vector<SmartPetscObj<Mat>> sequence_of_mats,
204 std::vector<bool> sym_schur, std::vector<double> diag_eps, bool symm_op)
205 : ForcesAndSourcesCore::UserDataOperator(NOSPACE, OPSPACE, symm_op),
206 fieldsName(fields_name), fieldEnts(field_ents),
207 sequenceOfAOs(sequence_of_aos), sequenceOfMats(sequence_of_mats),
208 symSchur(sym_schur), diagEps(diag_eps) {}
209
211 std::vector<std::string> fields_name,
212 std::vector<boost::shared_ptr<Range>> field_ents,
213 std::vector<SmartPetscObj<AO>> sequence_of_aos,
214 std::vector<SmartPetscObj<Mat>> sequence_of_mats,
215 std::vector<bool> sym_schur, bool symm_op)
216 : ForcesAndSourcesCore::UserDataOperator(NOSPACE, OPSPACE, symm_op),
217 fieldsName(fields_name), fieldEnts(field_ents),
218 sequenceOfAOs(sequence_of_aos), sequenceOfMats(sequence_of_mats),
219 symSchur(sym_schur), diagEps(fields_name.size(), 0) {}
220
221template <typename I>
225
227#ifndef NDEBUG
228 MOFEM_LOG("SELF", Sev::noisy) << "Schur assemble begin -> end";
229#endif
230
231 auto assemble = [&](SmartPetscObj<Mat> M, MatSetValuesRaw mat_set_values,
232 auto &storage) {
234 if (M) {
235 for (auto &s : storage) {
236 auto &m = s.getMat();
237 if (m.size1()) {
238 auto &row_ind = s.getRowInd();
239 auto &col_ind = s.getColInd();
240
241 if (mat_set_values(M, row_ind.size(), &*row_ind.begin(),
242 col_ind.size(), &*col_ind.begin(),
243 &*m.data().begin(), ADD_VALUES)) {
244 auto field_ents = getPtrFE()->mField.get_field_ents();
245 auto row_ent_it = field_ents->find(s.uidRow);
246 auto col_ent_it = field_ents->find(s.uidCol);
247 MOFEM_LOG_CHANNEL("SELF");
248 if (row_ent_it != field_ents->end())
249 MOFEM_LOG("SELF", Sev::error)
250 << "Assemble row entity: " << (*row_ent_it)->getName() << " "
251 << (*col_ent_it)->getEntTypeName() << " side "
252 << (*row_ent_it)->getSideNumber();
253 if (col_ent_it != field_ents->end())
254 MOFEM_LOG("SELF", Sev::error)
255 << "Assemble col entity: " << (*col_ent_it)->getName() << " "
256 << (*col_ent_it)->getEntTypeName() << " side "
257 << (*col_ent_it)->getSideNumber();
258 CHK_THROW_MESSAGE(ierr, "MatSetValues");
259 }
260 }
261 }
262 }
264 };
265
266 auto apply_schur = [&](auto &storage,
267
268 const auto ss,
269
270 auto lo_uid, auto hi_uid, double eps) {
272
273 auto add_off_mat = [&](auto row_uid, auto col_uid, auto &row_ind,
274 auto &col_ind, auto &offMatInvDiagOffMat) {
276 auto it = storage.template get<SchurL2Mats::uid_mi_tag>().find(
277 boost::make_tuple(row_uid, col_uid));
278 if (it == storage.template get<SchurL2Mats::uid_mi_tag>().end()) {
279 const auto idx = SchurL2Mats::schurL2Storage.size();
280 const auto size = SchurL2Mats::locMats.size();
281 const auto nb_rows = offMatInvDiagOffMat.size1();
282 const auto nb_cols = offMatInvDiagOffMat.size2();
283 if (idx >= size) {
284 SchurL2Mats::locMats.push_back(new MatrixDouble(nb_rows, nb_cols));
285 SchurL2Mats::rowIndices.push_back(new VectorInt(nb_rows));
286 SchurL2Mats::colIndices.push_back(new VectorInt(nb_cols));
287 } else {
288 SchurL2Mats::locMats[idx].resize(nb_rows, nb_cols, false);
289 SchurL2Mats::rowIndices[idx].resize(nb_rows, false);
290 SchurL2Mats::colIndices[idx].resize(nb_cols, false);
291 }
292 auto p = SchurL2Mats::schurL2Storage.emplace(idx, row_uid, col_uid);
293 auto &mat = p.first->getMat();
294 auto &set_row_ind = p.first->getRowInd();
295 auto &set_col_ind = p.first->getColInd();
296#ifndef NDEBUG
297 if (mat.size1() != set_row_ind.size()) {
298 SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
299 "Wrong size %d != %d", mat.size1(), set_row_ind.size());
300 }
301 if (mat.size2() != set_col_ind.size()) {
302 SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
303 "Wrong size %d != %d", mat.size2(), set_col_ind.size());
304 }
305#endif // NDEBUG
306 noalias(mat) = offMatInvDiagOffMat;
307 noalias(set_row_ind) = row_ind;
308 noalias(set_col_ind) = col_ind;
309 } else {
310 auto &mat = it->getMat();
311#ifndef NDEBUG
312 if (mat.size1() != offMatInvDiagOffMat.size1()) {
313 SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
314 "Wrong size %d != %d", mat.size1(),
315 offMatInvDiagOffMat.size1());
316 }
317 if (mat.size2() != offMatInvDiagOffMat.size2()) {
318 SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
319 "Wrong size %d != %d", mat.size2(),
320 offMatInvDiagOffMat.size2());
321 }
322#endif // NDEBUG
323 mat += offMatInvDiagOffMat;
324 }
326 };
327
328 auto get_row_view = [&]() {
329 auto row_it =
330 storage.template get<SchurL2Mats::row_mi_tag>().lower_bound(lo_uid);
331 auto hi_row_it =
332 storage.template get<SchurL2Mats::row_mi_tag>().upper_bound(hi_uid);
333 std::vector<const SchurL2Mats *> schur_row_ptr_view;
334 schur_row_ptr_view.reserve(std::distance(row_it, hi_row_it));
335 for (; row_it != hi_row_it; ++row_it) {
336 schur_row_ptr_view.push_back(&*row_it);
337 }
338 return schur_row_ptr_view;
339 };
340
341 auto get_col_view = [&]() {
342 auto col_it =
343 storage.template get<SchurL2Mats::col_mi_tag>().lower_bound(lo_uid);
344 auto hi_col_it =
345 storage.template get<SchurL2Mats::col_mi_tag>().upper_bound(hi_uid);
346 std::vector<const SchurL2Mats *> schur_col_ptr_view;
347 schur_col_ptr_view.reserve(std::distance(col_it, hi_col_it));
348 for (; col_it != hi_col_it; ++col_it) {
349 schur_col_ptr_view.push_back(&*col_it);
350 }
351 return schur_col_ptr_view;
352 };
353
354 auto schur_row_ptr_view = get_row_view();
355 auto schur_col_ptr_view = get_col_view();
356
357 for (auto row_it : schur_row_ptr_view) {
358 if (row_it->uidRow == row_it->uidCol) {
359
360 CHKERR I::invertMat(row_it->getMat(), invMat, eps);
361
362 for (auto c_lo : schur_col_ptr_view) {
363
364 auto &row_uid = c_lo->uidRow;
365 if (row_uid == row_it->uidRow)
366 continue;
367
368 auto &cc_off_mat = c_lo->getMat();
369 invDiagOffMat.resize(cc_off_mat.size1(), invMat.size2(), false);
370#ifndef NDEBUG
371 if (invMat.size1() != cc_off_mat.size2()) {
372 SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
373 "Wrong size %d != %d", invMat.size1(), cc_off_mat.size2());
374 }
375#endif // NDEBUG
376 noalias(invDiagOffMat) = prod(cc_off_mat, invMat);
377
378 for (auto r_lo : schur_row_ptr_view) {
379 auto &col_uid = r_lo->uidCol;
380
381 // Skip diagonal
382 if (col_uid == row_it->uidRow)
383 continue;
384
385 // If symmetry only run upper off diagonal terms
386 if (symSchur[ss] && row_uid > col_uid)
387 continue;
388
389 auto &rr_off_mat = r_lo->getMat();
390 offMatInvDiagOffMat.resize(invDiagOffMat.size1(),
391 rr_off_mat.size2(), false);
392#ifndef NDEBUG
393 if (rr_off_mat.size1() != invDiagOffMat.size2()) {
394 SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
395 "Wrong size %d != %d", rr_off_mat.size1(),
396 invDiagOffMat.size2());
397 }
398#endif // NDEBUG
399 noalias(offMatInvDiagOffMat) = prod(invDiagOffMat, rr_off_mat);
400
401 CHKERR add_off_mat(row_uid, col_uid, c_lo->getRowInd(),
402 r_lo->getColInd(), offMatInvDiagOffMat);
403
404 if (symSchur[ss] && row_uid != col_uid) {
406 offMatInvDiagOffMat.size1(),
407 false);
409 CHKERR add_off_mat(col_uid, row_uid, r_lo->getColInd(),
410 c_lo->getRowInd(), transOffMatInvDiagOffMat);
411 }
412 }
413 }
414 }
415 }
416
418 };
419
420 auto erase_factored = [&](auto &storage,
421
422 const auto ss, auto lo_uid, auto hi_uid) {
424
425 auto r_lo =
426 storage.template get<SchurL2Mats::row_mi_tag>().lower_bound(lo_uid);
427 auto r_hi =
428 storage.template get<SchurL2Mats::row_mi_tag>().upper_bound(hi_uid);
429 storage.template get<SchurL2Mats::row_mi_tag>().erase(r_lo, r_hi);
430
431 auto c_lo =
432 storage.template get<SchurL2Mats::col_mi_tag>().lower_bound(lo_uid);
433 auto c_hi =
434 storage.template get<SchurL2Mats::col_mi_tag>().upper_bound(hi_uid);
435 storage.template get<SchurL2Mats::col_mi_tag>().erase(c_lo, c_hi);
436
438 };
439
440 auto assemble_off_diagonal = [&](auto &storage, const auto ss) {
442
443 // apply AO
444 for (auto &m : storage) {
445 if (auto ao = sequenceOfAOs[ss]) {
446 auto &ind_row = m.getRowInd();
447 CHKERR AOApplicationToPetsc(ao, ind_row.size(), &*ind_row.begin());
448 auto &ind_col = m.getColInd();
449 CHKERR AOApplicationToPetsc(ao, ind_col.size(), &*ind_col.begin());
450 }
451 }
452
453 // assemble Schur
454 if (sequenceOfMats[ss]) {
455 CHKERR assemble(sequenceOfMats[ss], matSetValuesSchurRaw, storage);
456 }
457
459 };
460
461 auto &storage = SchurL2Mats::schurL2Storage;
462 // Assemble to global matrix
463
464 // Assemble Schur complements
465 // Iterate complements
466 for (auto ss = 0; ss != fieldsName.size(); ++ss) {
467
468 auto assemble = [&](auto &storage, auto ss, auto lo_uid, auto hi_uid) {
470
471 CHKERR apply_schur(storage, ss, lo_uid, hi_uid, diagEps[ss]);
472 CHKERR erase_factored(storage, ss, lo_uid, hi_uid);
473 CHKERR assemble_off_diagonal(storage, ss);
475 };
476
477 auto field_bit = getPtrFE()->mField.get_field_bit_number(fieldsName[ss]);
478 auto row_ents = fieldEnts[ss];
479
480 if (row_ents) {
481 for (auto p = row_ents->pair_begin(); p != row_ents->pair_end(); ++p) {
482 auto lo_uid =
483 FieldEntity::getLoLocalEntityBitNumber(field_bit, p->first);
484 auto hi_uid =
485 FieldEntity::getHiLocalEntityBitNumber(field_bit, p->second);
486 CHKERR assemble(storage, ss, lo_uid, hi_uid);
487 }
488 } else {
489 // Iterate all entities (typically L2)
491 field_bit, get_id_for_min_type<MBVERTEX>());
493 field_bit, get_id_for_max_type<MBENTITYSET>());
494 CHKERR assemble(storage, ss, lo_uid, hi_uid);
495 }
496 }
497
498#ifndef NDEBUG
499 MOFEM_LOG("SELF", Sev::noisy) << "Schur assemble done";
500#endif
501
503}
504
506 static auto invertMat(MatrixDouble &m, MatrixDouble &inv, double eps) {
508 VectorInt ipiv;
509 VectorDouble lapack_work;
510 const int nb = m.size1();
511
512 if (eps) {
513 for (int cc = 0; cc != nb; ++cc) {
514 m(cc, cc) += eps;
515 }
516 }
517
518 inv.resize(nb, nb, false);
519 inv.clear();
520 for (int cc = 0; cc != nb; ++cc)
521 inv(cc, cc) = -1;
522 ipiv.resize(nb, false);
523 lapack_work.resize(nb * nb, false);
524 const auto info =
525 lapack_dsysv('L', nb, nb, &*m.data().begin(), nb, &*ipiv.begin(),
526 &*inv.data().begin(), nb, &*lapack_work.begin(), nb * nb);
527 if (info != 0)
528 SETERRQ1(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
529 "Can not invert matrix info = %d", info);
531 };
532};
533
535 static auto invertMat(MatrixDouble &m, MatrixDouble &inv, double eps) {
537 VectorInt ipiv;
538 const auto nb = m.size1();
539#ifndef NDEBUG
540 if (nb != m.size2()) {
541 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
542 "It should be square matrix");
543 }
544#endif
545
546 if (eps) {
547 for (int cc = 0; cc != nb; ++cc) {
548 m(cc, cc) += eps;
549 }
550 }
551
552 inv.resize(nb, nb, false);
553 inv.clear();
554 for (int c = 0; c != nb; ++c)
555 inv(c, c) = -1;
556 ipiv.resize(nb, false);
557 const auto info = lapack_dgesv(nb, nb, &*m.data().begin(), nb,
558 &*ipiv.begin(), &*inv.data().begin(), nb);
559 if (info != 0)
560 SETERRQ1(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
561 "Can not invert matrix info = %d", info);
563 };
564};
565
569 return doWorkImpl<SCHUR_DSYSV>(side, type, data);
570}
571
575 return doWorkImpl<SCHUR_DGESV>(side, type, data);
576}
577
578} // namespace MoFEM
static Index< 'M', 3 > M
static Index< 'p', 3 > p
ForcesAndSourcesCore::UserDataOperator UserDataOperator
static const double eps
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
Definition: definitions.h:595
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:447
@ NOSPACE
Definition: definitions.h:83
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:346
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition: definitions.h:34
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition: definitions.h:32
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:416
#define CHKERR
Inline error check.
Definition: definitions.h:535
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:440
FTensor::Index< 'm', SPACE_DIM > m
virtual const FieldEntity_multiIndex * get_field_ents() const =0
Get the field ents object.
#define MOFEM_LOG(channel, severity)
Log.
Definition: LogManager.hpp:308
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
Definition: LogManager.hpp:284
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
static __CLPK_integer lapack_dgesv(__CLPK_integer n, __CLPK_integer nrhs, __CLPK_doublereal *a, __CLPK_integer lda, __CLPK_integer *ipiv, __CLPK_doublereal *b, __CLPK_integer ldb)
Definition: lapack_wrap.h:176
static __CLPK_integer lapack_dsysv(char uplo, __CLPK_integer n, __CLPK_integer nrhs, __CLPK_doublereal *a, __CLPK_integer lda, __CLPK_integer *ipiv, __CLPK_doublereal *b, __CLPK_integer ldb, __CLPK_doublereal *work, __CLPK_integer lwork)
Definition: lapack_wrap.h:220
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
Definition: Exceptions.hpp:76
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
uint128_t UId
Unique Id.
Definition: Types.hpp:31
UBlasMatrix< double > MatrixDouble
Definition: Types.hpp:77
UBlasVector< int > VectorInt
Definition: Types.hpp:67
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
auto type_from_handle(const EntityHandle h)
get type from entity handle
Definition: Templates.hpp:1779
MoFEMErrorCode schur_mat_set_values_wrap(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat, InsertMode iora)
Definition: Schur.cpp:24
auto id_from_handle(const EntityHandle h)
Definition: Templates.hpp:1771
MoFEMErrorCode MatSetValues(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const double *ptr, InsertMode iora)
Assemble PETSc matrix.
auto ent_form_type_and_id(const EntityType type, const EntityID id)
get entity handle from type and id
Definition: Templates.hpp:1787
virtual FieldBitNumber get_field_bit_number(const std::string name) const =0
get field bit number
Data on single entity (This is passed as argument to DataOperator::doWork)
const VectorFieldEntities & getFieldEntities() const
get field entities
const VectorInt & getIndices() const
Get global indices of dofs on entity.
[Storage and set boundary conditions]
static auto getHandleFromUniqueId(const UId uid)
Get the Handle From Unique Id.
static auto getFieldBitNumberFromUniqueId(const UId uid)
Get the Field Bit Number From Unique Id.
UId getLocalUniqueIdCalculate()
Get the Local Unique Id Calculate object.
static UId getLoLocalEntityBitNumber(const char bit_number, const EntityHandle ent)
static UId getHiLocalEntityBitNumber(const char bit_number, const EntityHandle ent)
structure to get information form mofem into EntitiesFieldData
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
Definition: Schur.cpp:180
Assemble Schur complement.
Definition: Schur.hpp:104
MatrixDouble offMatInvDiagOffMat
Definition: Schur.hpp:92
std::vector< boost::shared_ptr< Range > > fieldEnts
Definition: Schur.hpp:84
boost::function< MoFEMErrorCode(Mat mat, PetscInt m, const PetscInt idxm[], PetscInt n, const PetscInt idxn[], const PetscScalar v[], InsertMode addv)> MatSetValuesRaw
Definition: Schur.hpp:39
static MatSetValuesRaw matSetValuesSchurRaw
Definition: Schur.hpp:41
MoFEMErrorCode doWorkImpl(int side, EntityType type, EntitiesFieldData::EntData &data)
Definition: Schur.cpp:223
OpSchurAssembleEndImpl(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=true)
Construct a new Op Schur Assemble End object.
Definition: Schur.cpp:210
std::vector< bool > symSchur
Definition: Schur.hpp:87
std::vector< std::string > fieldsName
Definition: Schur.hpp:83
MatrixDouble invDiagOffMat
Definition: Schur.hpp:91
std::vector< SmartPetscObj< Mat > > sequenceOfMats
Definition: Schur.hpp:86
std::vector< SmartPetscObj< AO > > sequenceOfAOs
Definition: Schur.hpp:85
MatrixDouble transOffMatInvDiagOffMat
Definition: Schur.hpp:93
std::vector< double > diagEps
Definition: Schur.hpp:88
static auto invertMat(MatrixDouble &m, MatrixDouble &inv, double eps)
Definition: Schur.cpp:535
static auto invertMat(MatrixDouble &m, MatrixDouble &inv, double eps)
Definition: Schur.cpp:506
SchurL2Mats(const size_t idx, const UId uid_row, const UId uid_col)
Definition: Schur.cpp:17
static MatSetValuesPtr matSetValuesPtr
backend assembly function
Definition: Schur.hpp:141
static boost::ptr_vector< VectorInt > rowIndices
Definition: Schur.hpp:182
static SchurL2Storage schurL2Storage
Definition: Schur.hpp:184
multi_index_container< SchurL2Mats, indexed_by< ordered_unique< tag< uid_mi_tag >, composite_key< SchurL2Mats, member< SchurL2Mats, const UId, &SchurL2Mats::uidRow >, member< SchurL2Mats, const UId, &SchurL2Mats::uidCol > > >, ordered_non_unique< tag< row_mi_tag >, member< SchurL2Mats, const UId, &SchurL2Mats::uidRow > >, ordered_non_unique< tag< col_mi_tag >, member< SchurL2Mats, const UId, &SchurL2Mats::uidCol > > > > SchurL2Storage
Definition: Schur.hpp:179
static boost::ptr_vector< VectorInt > colIndices
Definition: Schur.hpp:183
boost::function< MoFEMErrorCode(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat, InsertMode iora)> MatSetValuesPtr
Definition: Schur.hpp:139
auto & getMat() const
Definition: Schur.hpp:132
static MoFEMErrorCode MatSetValues(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const MatrixDouble &mat, InsertMode iora)
Definition: Schur.cpp:35
static boost::ptr_vector< MatrixDouble > locMats
Definition: Schur.hpp:181
auto & getRowInd() const
Definition: Schur.hpp:133
auto & getColInd() const
Definition: Schur.hpp:134
intrusive_ptr for managing petsc objects