7static auto save_range(moab::Interface &moab,
const std::string name,
11 CHKERR moab.create_meshset(MESHSET_SET, out_meshset);
12 CHKERR moab.add_entities(out_meshset, r);
13 CHKERR moab.write_file(name.c_str(),
"VTK",
"", &out_meshset, 1);
14 CHKERR moab.delete_entities(&out_meshset, 1);
26 : cOre(const_cast<
MoFEM::
Core &>(core)), dEbug(false) {
28 auto core_log = logging::core::get();
46 MOFEM_LOG(
"VECWORLD", Sev::noisy) <<
"Vector manager created";
55 DofIdx nb_local_dofs, nb_ghost_dofs;
68 CHKERR ::VecCreateSeq(PETSC_COMM_SELF, nb_local_dofs + nb_ghost_dofs, V);
69 CHKERR ::VecSetOption(
70 *V, VEC_IGNORE_NEGATIVE_INDICES,
81 DofIdx nb_dofs, nb_local_dofs, nb_ghost_dofs;
102 auto miit = dofs->lower_bound(nb_local_dofs);
103 auto hi_miit = dofs->upper_bound(nb_local_dofs + nb_ghost_dofs);
104 int count = std::distance(miit, hi_miit);
105 if (count != nb_ghost_dofs) {
108 std::vector<DofIdx> ghost_idx;
109 ghost_idx.reserve(count);
110 for (; miit != hi_miit; ++miit) {
111 if ((*miit)->getActive()) {
112 ghost_idx.emplace_back((*miit)->petscGloablDofIdx);
114 if (PetscUnlikely(ghost_idx.back() > nb_dofs || ghost_idx.back() < 0)) {
117 auto save_no_global_id_entities = [&]() {
121 for (
auto &it : (*dofs)) {
122 int global_idx = it->getPetscGlobalDofIdx();
123 if (global_idx > nb_dofs || global_idx < 0) {
124 ghost_range.insert(it->getEnt());
128 "error_ghost_dofs_range_" + std::to_string(part) +
134 CHKERR save_no_global_id_entities();
140 MOFEM_LOG(
"VECSELF", Sev::error) <<
"Problem with DOF " << **miit;
145 CHKERR ::VecCreateGhost(m_field.
get_comm(), nb_local_dofs, nb_dofs,
146 ghost_idx.size(), &*ghost_idx.begin(), V);
147 CHKERR ::VecSetOption(
148 *V, VEC_IGNORE_NEGATIVE_INDICES,
158 v_ptr.reset(vec,
false);
163 Vec xin,
const std::string x_problem,
const std::string x_field_name,
164 RowColData x_rc, Vec yin,
const std::string y_problem,
165 const std::string y_field_name,
RowColData y_rc, VecScatter *newctx)
const {
168 std::vector<int> idx(0), idy(0);
170 ->isCreateFromProblemFieldToOtherProblemField(
171 x_problem, x_field_name, x_rc, y_problem, y_field_name, y_rc, idx,
174 CHKERR ISCreateGeneral(PETSC_COMM_WORLD, idx.size(), &idx[0],
175 PETSC_USE_POINTER, &ix);
176 CHKERR ISCreateGeneral(PETSC_COMM_WORLD, idy.size(), &idy[0],
177 PETSC_USE_POINTER, &iy);
178 CHKERR ::VecScatterCreate(xin, ix, yin, iy, newctx);
185 Vec xin,
const std::string x_problem,
RowColData x_rc, Vec yin,
186 const std::string y_problem,
RowColData y_rc, VecScatter *newctx)
const {
189 std::vector<int> idx(0), idy(0);
191 x_problem, x_rc, y_problem, y_rc, idx, idy);
193 CHKERR ISCreateGeneral(PETSC_COMM_WORLD, idx.size(), &idx[0],
194 PETSC_USE_POINTER, &ix);
195 CHKERR ISCreateGeneral(PETSC_COMM_WORLD, idy.size(), &idy[0],
196 PETSC_USE_POINTER, &iy);
198 ISView(ix, PETSC_VIEWER_STDOUT_WORLD);
199 ISView(iy, PETSC_VIEWER_STDOUT_WORLD);
201 CHKERR ::VecScatterCreate(xin, ix, yin, iy, newctx);
209 const std::string x_field_name,
RowColData x_rc,
210 Vec yin,
const std::string y_problem,
211 const std::string y_field_name,
RowColData y_rc,
216 y_field_name, y_rc, &newctx);
236 ScatterMode scatter_mode)
const {
239 DofIdx nb_local_dofs, nb_ghost_dofs;
257 CHKERR VecGhostGetLocalForm(V, &Vlocal);
259 CHKERR VecGetLocalSize(V, &size);
260 if (size != nb_local_dofs) {
262 "data inconsistency: check ghost vector, problem <%s> with nb. of "
263 "local nodes %d != %d",
264 problem_ptr->
getName().c_str(), size, nb_local_dofs);
266 CHKERR VecGetLocalSize(Vlocal, &size);
267 if (size != nb_local_dofs + nb_ghost_dofs) {
269 "data inconsistency: check ghost vector, problem with nb. of "
270 "ghost nodes %d != %d ",
271 size, nb_local_dofs + nb_ghost_dofs);
273 auto miit = dofs->lower_bound(0);
274 auto hi_miit = dofs->upper_bound(nb_local_dofs + nb_ghost_dofs);
276 switch (scatter_mode) {
277 case SCATTER_FORWARD: {
279 CHKERR VecGetArray(Vlocal, &array);
282 for (; miit != hi_miit; ++miit, ++ii)
283 array[ii] = (*miit)->getFieldData();
286 for (; miit != hi_miit; ++miit, ++ii)
287 array[ii] += (*miit)->getFieldData();
292 CHKERR VecRestoreArray(Vlocal, &array);
294 case SCATTER_REVERSE: {
295 const PetscScalar *array;
296 CHKERR VecGetArrayRead(Vlocal, &array);
299 for (; miit != hi_miit; ++miit, ++ii) {
300 (*miit)->getFieldData() = array[ii];
304 for (; miit != hi_miit; ++miit, ++ii)
305 (*miit)->getFieldData() += array[ii];
310 CHKERR VecRestoreArrayRead(Vlocal, &array);
315 CHKERR VecGhostRestoreLocalForm(V, &Vlocal);
322 ScatterMode scatter_mode)
const {
333 Vec V, InsertMode mode,
334 ScatterMode scatter_mode)
const {
336 typedef NumeredDofEntity_multiIndex::index<PetscGlobalIdx_mi_tag>::type
338 DofsByGlobalIdx *dofs;
343 dofs =
const_cast<DofsByGlobalIdx *
>(
348 dofs =
const_cast<DofsByGlobalIdx *
>(
353 "Function works only for ROWs and COLs");
355 DofsByGlobalIdx::iterator miit = dofs->lower_bound(0);
356 DofsByGlobalIdx::iterator hi_miit = dofs->upper_bound(nb_dofs);
357 auto comm = PetscObjectComm((PetscObject)V);
358 switch (scatter_mode) {
359 case SCATTER_REVERSE: {
362 CHKERR VecScatterCreateToAll(V, &ctx, &V_glob);
363 CHKERR VecScatterBegin(ctx, V, V_glob, INSERT_VALUES, SCATTER_FORWARD);
364 CHKERR VecScatterEnd(ctx, V, V_glob, INSERT_VALUES, SCATTER_FORWARD);
366 CHKERR VecGetSize(V_glob, &size);
367 if (size != nb_dofs) {
369 "Size of vector is inconsistent with size of problem. You could "
370 "use wrong vector with wrong problem, or you created vector "
371 "before you remove DOFs from problem.");
374 CHKERR VecGetArray(V_glob, &array);
377 for (; miit != hi_miit; miit++)
378 (*miit)->getFieldData() = array[(*miit)->getPetscGlobalDofIdx()];
381 for (; miit != hi_miit; miit++)
382 (*miit)->getFieldData() += array[(*miit)->getPetscGlobalDofIdx()];
387 CHKERR VecRestoreArray(V_glob, &array);
388 CHKERR VecScatterDestroy(&ctx);
389 CHKERR VecDestroy(&V_glob);
401 ScatterMode scatter_mode)
const {
411 template <
typename A0,
typename A1,
typename A2,
typename A3,
typename A4>
414 const std::string cpy_field_name) {
416 for (; miit != hi_miit; miit++) {
417 if (miit->get()->getHasLocalIndex()) {
420 cpy_bit_number, (*miit)->getEnt()));
421 auto diiiit = dofs_ptr->template get<Unique_mi_tag>().find(uid);
422 if (diiiit == dofs_ptr->template get<Unique_mi_tag>().end()) {
427 <<
"Problem finding DOFs in the copy field";
428 MOFEM_LOG(
"VECSELF", Sev::error) <<
"Field DOF: " << (**miit);
430 <<
"Copy field name: " << cpy_field_name;
432 "Automatic creation of entity and dof not implemented");
434 if constexpr (MODE == INSERT_VALUES)
435 (*diiiit)->getFieldData() = array[(*miit)->getPetscLocalDofIdx()];
436 else if constexpr (MODE == ADD_VALUES)
437 (*diiiit)->getFieldData() += array[(*miit)->getPetscLocalDofIdx()];
446 const std::string cpy_field_name,
RowColData rc, Vec V, InsertMode mode,
447 ScatterMode scatter_mode)
const {
452 using DofsByUId = NumeredDofEntity_multiIndex::index<Unique_mi_tag>::type;
457 dofs =
const_cast<DofsByUId *
>(
461 dofs =
const_cast<DofsByUId *
>(
471 "cpy field < %s > not found, (top tip: check spelling)",
472 cpy_field_name.c_str());
473 const auto cpy_bit_number = (*cpy_fit)->getBitNumber();
475 auto miit = dofs->lower_bound(
477 if (miit == dofs->end()) {
479 "cpy field < %s > not found, (top tip: check spelling)",
482 auto hi_miit = dofs->upper_bound(
485 if ((*miit)->getSpace() != (*cpy_fit)->getSpace()) {
487 "fields have to have same space (%s) %s != (%s) %s",
491 if ((*miit)->getNbOfCoeffs() != (*cpy_fit)->getNbOfCoeffs()) {
493 "fields have to have same rank");
496 switch (scatter_mode) {
497 case SCATTER_REVERSE: {
500 CHKERR VecGetArray(V, &array);
501 if (mode == INSERT_VALUES)
503 dofs_ptr, array, miit, hi_miit, cpy_bit_number, cpy_field_name);
504 else if (mode == ADD_VALUES)
506 dofs_ptr, array, miit, hi_miit, cpy_bit_number, cpy_field_name);
509 "Operation mode not implemented");
510 CHKERR VecRestoreArray(V, &array);
512 case SCATTER_FORWARD: {
513 for (; miit != hi_miit; miit++) {
514 if (!miit->get()->getHasLocalIndex())
518 cpy_bit_number, (*miit)->getEnt()));
522 "no data to fill the vector (top tip: you want scatter forward "
523 "or scatter reverse?)");
525 CHKERR VecSetValue(V, (*miit)->getPetscGlobalDofIdx(),
526 (*diiiit)->getFieldData(), mode);
528 CHKERR VecAssemblyBegin(V);
538 const std::string name,
const std::string
field_name,
539 const std::string cpy_field_name,
RowColData rc, Vec V, InsertMode mode,
540 ScatterMode scatter_mode)
const {
546 V, mode, scatter_mode);
551 template <
typename A0,
typename A1,
typename A2,
typename A3,
typename A4>
553 A4 &cpy_bit_number) {
555 for (; miit != hi_miit; miit++) {
558 cpy_bit_number, (*miit)->getEnt()));
559 auto diiiit = dofs_ptr->template get<Unique_mi_tag>().find(uid);
561 if (diiiit == dofs_ptr->template get<Unique_mi_tag>().end()) {
563 "Automatic creation of entity and dof not implemented");
566 if constexpr (MODE == INSERT_VALUES)
567 (*diiiit)->getFieldData() = array[(*miit)->getPetscGlobalDofIdx()];
568 else if constexpr (MODE == ADD_VALUES)
569 (*diiiit)->getFieldData() += array[(*miit)->getPetscGlobalDofIdx()];
577 const std::string cpy_field_name,
RowColData rc, Vec V, InsertMode mode,
578 ScatterMode scatter_mode)
const {
602 "cpy field < %s > not found, (top tip: check spelling)",
603 cpy_field_name.c_str());
605 const auto cpy_bit_number = (*cpy_fit)->getBitNumber();
607 auto miit = dofs->lower_bound(
609 if (miit == dofs->end()) {
611 "problem field < %s > not found, (top tip: check spelling)",
614 auto hi_miit = dofs->upper_bound(
616 if ((*miit)->getSpace() != (*cpy_fit)->getSpace()) {
618 "fields have to have same space");
620 if ((*miit)->getNbOfCoeffs() != (*cpy_fit)->getNbOfCoeffs()) {
622 "fields have to have same rank");
624 switch (scatter_mode) {
625 case SCATTER_REVERSE: {
628 CHKERR VecScatterCreateToAll(V, &ctx, &V_glob);
629 CHKERR VecScatterBegin(ctx, V, V_glob, INSERT_VALUES, SCATTER_FORWARD);
630 CHKERR VecScatterEnd(ctx, V, V_glob, INSERT_VALUES, SCATTER_FORWARD);
632 CHKERR VecGetSize(V_glob, &size);
636 "data inconsistency: nb. of dofs and declared nb. dofs in database");
638 CHKERR VecGetArray(V_glob, &array);
640 if (mode == INSERT_VALUES)
642 dofs_ptr, array, miit, hi_miit, cpy_bit_number);
643 else if (mode == ADD_VALUES)
645 hi_miit, cpy_bit_number);
648 "Operation mode not implemented");
650 CHKERR VecRestoreArray(V_glob, &array);
651 CHKERR VecDestroy(&V_glob);
652 CHKERR VecScatterDestroy(&ctx);
654 case SCATTER_FORWARD: {
655 for (; miit != hi_miit; miit++) {
658 cpy_bit_number, (*miit)->getEnt()));
662 "No data to fill the vector (top tip: you want scatter forward "
663 "or scatter reverse?)");
665 CHKERR VecSetValue(V, (*miit)->getPetscGlobalDofIdx(),
666 (*diiiit)->getFieldData(), mode);
668 CHKERR VecAssemblyBegin(V);
678 const std::string name,
const std::string
field_name,
679 const std::string cpy_field_name,
RowColData rc, Vec V, InsertMode mode,
680 ScatterMode scatter_mode)
const {
686 V, mode, scatter_mode);
static const char *const FieldSpaceNames[]
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
NumeredDofEntity_multiIndex::index< Unique_mi_tag >::type NumeredDofEntityByUId
Numbered DoF multi-index by UId.
NumeredDofEntity_multiIndex::index< PetscLocalIdx_mi_tag >::type NumeredDofEntityByLocalIdx
Numbered DoF multi-index by local index.
virtual const Problem * get_problem(const std::string problem_name) const =0
Get the problem object.
virtual const DofEntity_multiIndex * get_dofs() const =0
Get the dofs object.
virtual const Field_multiIndex * get_fields() const =0
Get the fields object.
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#define MOFEM_LOG_ATTRIBUTES(channel, bit)
Add attributes to channel.
#define MOFEM_LOG_FUNCTION()
Set scope.
MoFEMErrorCode vecCreateGhost(const std::string name, RowColData rc, Vec *V) const
create ghost vector for problem (collective)
MoFEMErrorCode setOtherLocalGhostVector(const Problem *problem_ptr, const std::string field_name, const std::string cpy_field_name, RowColData rc, Vec V, InsertMode mode, ScatterMode scatter_mode) const
Copy vector to field which is not part of the problem.
MoFEMErrorCode vecScatterCreate(Vec xin, const std::string x_problem, const std::string x_field_name, RowColData x_rc, Vec yin, const std::string y_problem, const std::string y_field_name, RowColData y_rc, VecScatter *newctx) const
create scatter for vectors from one to another problem (collective)
MoFEMErrorCode vecCreateSeq(const std::string name, RowColData rc, Vec *V) const
create local vector for problem
MoFEMErrorCode setLocalGhostVector(const Problem *problem_ptr, RowColData rc, Vec V, InsertMode mode, ScatterMode scatter_mode) const
set values of vector from/to mesh database
MoFEMErrorCode setOtherGlobalGhostVector(const Problem *problem_ptr, const std::string field_name, const std::string cpy_field_name, RowColData rc, Vec V, InsertMode mode, ScatterMode scatter_mode) const
Copy vector to field which is not part of the problem (collective)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
constexpr auto field_name
virtual FieldBitNumber get_field_bit_number(const std::string name) const =0
get field bit number
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Deprecated interface functions.
static UId getUniqueIdCalculate(const DofIdx dof, UId ent_uid)
static UId getHiBitNumberUId(const FieldBitNumber bit_number)
UId getLocalUniqueIdCalculate()
Get the Local Unique Id Calculate object.
static UId getLoBitNumberUId(const FieldBitNumber bit_number)
MultiIndex Tag for field name.
Section manager is used to create indexes and sections.
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
static boost::shared_ptr< std::ostream > getStrmSync()
Get the strm sync object.
static bool checkIfChannelExist(const std::string channel)
Check if channel exist.
static boost::shared_ptr< std::ostream > getStrmSelf()
Get the strm self object.
keeps basic data about problem
DofIdx getNbLocalDofsRow() const
DofIdx getNbDofsRow() const
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredRowDofsPtr
store DOFs on rows for this problem
DofIdx getNbGhostDofsCol() const
DofIdx getNbDofsCol() const
DofIdx getNbLocalDofsCol() const
DofIdx getNbGhostDofsRow() const
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredColDofsPtr
store DOFs on columns for this problem
MoFEMErrorCode operator()(A0 dofs_ptr, A1 array, A2 miit, A3 hi_miit, A4 &cpy_bit_number)
MoFEMErrorCode operator()(A0 dofs_ptr, A1 array, A2 miit, A3 hi_miit, A4 &cpy_bit_number, const std::string cpy_field_name)
intrusive_ptr for managing petsc objects
base class for all interface classes
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Vector manager is used to create vectors \mofem_vectors.
MoFEMErrorCode setGlobalGhostVector(const Problem *problem_ptr, RowColData rc, Vec V, InsertMode mode, ScatterMode scatter_mode) const
MoFEMErrorCode query_interface(boost::typeindex::type_index type_index, UnknownInterface **iface) const
const MoFEM::Interface & cOre
VecManager(const MoFEM::Core &core)