v0.16.0
Loading...
Searching...
No Matches
CommInterface.hpp
Go to the documentation of this file.
1/** \file CommInterface.hpp
2 * \brief Interface for communication functions
3 * \ingroup mofem_comm
4 *
5 * Functions used to communicate, share entities, share data, etc.
6 *
7 */
8
9#ifndef __COMMINTERFACE_HPP__
10#define __COMMINTERFACE_HPP__
11
12#include "UnknownInterface.hpp"
13
14namespace MoFEM {
15
17
18 // This is not fully safe, very unlikely to cause problems in practice,
19 // but it is possible that a ParallelComm is created for a mesh, then
20 // the mesh is deleted and a new mesh is created at the same address, and then getOrCreate
21 // is called again, which will return the old ParallelComm for the new mesh.
22 // This can be avoided that we create tag in moab with uniqe ID, that
23 // is incremented each time mesh is created, and we store this ID in the
24 // registry along with the pointer, and check it when we get ParallelComm from registry.
25 static auto &getMap() {
26 static std::map<moab::Core *, boost::weak_ptr<ParallelComm>> pcomm_map;
27 return pcomm_map;
28 }
29
30 static auto getOrCreate(moab::Core *core_mesh_ptr) {
31 auto *mesh_ptr = core_mesh_ptr;
32 auto &pcomm_map = getMap();
33
34 if (auto it = pcomm_map.find(mesh_ptr); it != pcomm_map.end()) {
35 if (auto pcomm_ptr = it->second.lock())
36 return pcomm_ptr;
37 }
38
39 if (auto *raw_pcomm = ParallelComm::get_pcomm(mesh_ptr, MYPCOMM_INDEX)) {
40 auto pcomm_ptr = boost::shared_ptr<ParallelComm>(
41 raw_pcomm, [mesh_ptr](ParallelComm *pcomm) {});
42 pcomm_map[mesh_ptr] = pcomm_ptr;
43 return pcomm_ptr;
44 }
45
46 auto pcomm_ptr = boost::shared_ptr<ParallelComm>(
47 new ParallelComm(mesh_ptr, PETSC_COMM_WORLD),
48 [mesh_ptr](ParallelComm *pcomm) {
49 delete pcomm;
50 return;
51 });
52 return pcomm_ptr;
53 }
54
55 /** @deprecated Do not use this function, use getOrCreate(moab::Core*) instead */
56 static auto getOrCreate(const boost::shared_ptr<moab::Core> &core_mesh_ptr) {
57 return MeshPCommRegistry::getOrCreate(core_mesh_ptr.get());
58 }
59};
60
61/**
62 * \brief Managing BitRefLevels
63 * \ingroup mofem_bit_ref
64 * \nosubgrouping
65 */
67
68 inline static bool debug = false;
69 inline static Sev sev = Sev::verbose;
70
71 MoFEMErrorCode query_interface(boost::typeindex::type_index type_index,
72 UnknownInterface **iface) const;
73
75 bool dEbug;
76
77 CommInterface(const MoFEM::Core &core);
78
79 /**
80 * \brief Destructor
81 */
82 ~CommInterface() = default;
83
84 /** \name Make elements multishared */
85
86 /**@{*/
87
88 /**
89 * \brief resolve shared entities for finite elements in the problem
90 * \ingroup mofem_problems
91
92 * @param problem_ptr problem pointer
93 * @param fe_name finite element name
94 * @param verb verbosity level
95 * @return error code
96 *
97 * This allows for tag reduction or tag exchange, f.e.
98
99 \code
100 CHKERR m_field.resolveSharedFiniteElements(problem_ptr,"SHELL_ELEMENT");
101 Tag th;
102 CHKERR mField.get_moab().tag_get_handle("ADAPT_ORDER",th);
103 CHKERR ParallelComm* pcomm =
104 ParallelComm::get_pcomm(&mField.get_moab(),MYPCOMM_INDEX);
105 CHKERR pcomm->exchange_tags(th,prisms);
106 \endcode
107
108 *
109 */
111 const std::string &fe_name,
112 int verb = DEFAULT_VERBOSITY);
113
114 /**
115 * \brief resolve shared entities for finite elements in the problem
116 * \ingroup mofem_problems
117
118 * @param name problem name
119 * @param fe_name finite element name
120 * @param verb verbosity level
121 * @return error code
122 *
123 * This allows for tag reduction or tag exchange, f.e.
124
125 \code
126 CHKERR m_field.resolveSharedFiniteElements(problem_ptr,"SHELL_ELEMENT");
127 Tag th;
128 CHKERR mField.get_moab().tag_get_handle("ADAPT_ORDER",th);
129 ParallelComm* pcomm =
130 ParallelComm::get_pcomm(&mField.get_moab(),MYPCOMM_INDEX);
131 // CHKERR pcomm->reduce_tags(th,MPI_SUM,prisms);
132 CHKERR pcomm->exchange_tags(th,prisms);
133 \endcode
134
135 *
136 */
137 MoFEMErrorCode resolveSharedFiniteElements(const std::string name,
138 const std::string &fe_name,
139 int verb = DEFAULT_VERBOSITY);
140
141 /** \name Make entities multishared */
142
143 /**
144 * @brief make entities from proc 0 shared on all proc
145 *
146 * \note collective - need to be run on all processors in communicator
147 *
148 * @param entities
149 * @param num_entities
150 * @param my_proc default proc id to share from
151 * @param verb
152 * @return MoFEMErrorCode
153 */
155 const int num_entities,
156 const int owner_proc = 0,
157 int verb = DEFAULT_VERBOSITY);
158
159 /**
160 * @brief make entities from proc 0 shared on all proc
161 *
162 * \note collective - need to be run on all processors in communicator
163 *
164 * @param entities
165 * @param my_proc default proc id to share from
166 * @param verb
167 * @return MoFEMErrorCode
168 */
170 const int owner_proc = 0,
171 int verb = DEFAULT_VERBOSITY);
172
173 /**
174 * @brief make field entities multi shared
175 *
176 * \note collective - need to be run on all processors in communicator
177 *
178 * @param field_name
179 * @param owner_proc
180 * @param verb
181 * @return MoFEMErrorCode
182 */
184 const int owner_proc = 0,
185 int verb = DEFAULT_VERBOSITY);
186
187 /**
188 * @brief Exchange field data
189 *
190 * Exchange field for all shared and ghosted entities. This function should be
191 * called collectively over the communicator for this ParallelComm. If the
192 * entities vector is empty, all shared entities participate in the exchange.
193 * If a proc has no owned entities this function must still be called since it
194 * is collective.
195 *
196 * \note collective - need to be run on all processors in communicator
197 *
198 * \todo It is not working if field has entities different than vertices.
199 *
200 * @param verb
201 * @param field_name @return MoFEMErrorCode
202 */
204 int verb = DEFAULT_VERBOSITY);
205
206 /**@}*/
207
208 /** \name Synchronize entities (Following functions in future will be
209 * deprecated) */
210
211 /**@{*/
212
213 /** synchronize entity range on processors (collective)
214 *
215 * \note collective - need to be run on all processors in communicator
216 *
217 */
218
219 /**
220 * @brief synchronize entity range on processors (collective)
221 *
222 * \note collective - need to be run on all processors in communicator
223 *
224 * @param ent ents to send and received
225 * @param received_ents pointer to map with received entities
226 * @param verb
227 * @return MoFEMErrorCode
228 */
230 std::map<int, Range> *received_ents,
231 int verb = DEFAULT_VERBOSITY);
232
233 /**
234 * @brief synchronize entity range on processors (collective)
235 *
236 * \note collective - need to be run on all processors in communicator
237 *
238 * @param ent ents to send and received
239 * @param verb
240 * @return MoFEMErrorCode
241 */
243
244 /** synchronize entity range on processors (collective)
245 * \ingroup mofem_field
246 *
247 * \note collective - need to be run on all processors in communicator
248 *
249 * \param name field
250 * \param verbose level
251 *
252 */
253 MoFEMErrorCode synchroniseFieldEntities(const std::string name,
254 int verb = DEFAULT_VERBOSITY);
255
256 /**
257 * @brief Synchronise parent entities
258 *
259 * \note collective - need to be run on all processors in communicator
260 *
261 * Exchange parent entity tag and bitref of entity. Note thar parent handle
262 * can be different on each processor.
263 *
264 * @param ent
265 * @param verb
266 * @return MoFEMErrorCode
267 */
269 int verb = DEFAULT_VERBOSITY);
270
271 /**@}*/
272
273 /**@*/
274
275 /** \name Read, load and broadcast */
276
277 /**
278 * \brief Set partition tag to each finite element in the problem
279 * \ingroup mofem_problems_manager
280 *
281 * This will use one of the mesh partitioning programs available from PETSc
282 * See
283 * <http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Mat/MatPartitioningType.html>
284 *
285 * @param ents Entities to partition
286 * @param dim Dimension of entities to partition
287 * @param adj_dim Adjacency dimension
288 * @param n_parts Number of partitions
289 * @param verb Verbosity level
290 * @return Error code
291 */
292 MoFEMErrorCode partitionMesh(const Range &ents, const int dim,
293 const int adj_dim, const int n_parts,
294 Tag *th_vertex_weights = nullptr,
295 Tag *th_edge_weights = nullptr,
296 Tag *th_part_weights = nullptr,
297 int verb = VERBOSE, const bool debug = false);
298
299
300 /**@}*/
301
302 /**@{*/
303
304 /** \name Load file */
305
306 using LoadFileFun = std::function<std::array<Range, 4>(
307 std::array<Range, 4> &&, std::vector<const CubitMeshSets *> &&)>;
308
309 static std::array<Range, 4>
310 defaultProcSkinFun(std::array<Range, 4> &&proc_ents_skin,
311 std::vector<const CubitMeshSets *> &&vec_ptr) {
312 return proc_ents_skin;
313 }
314
315 /**
316 * @brief Root proc has whole mesh, other procs only part of it
317 *
318 * @param moab
319 * @param file_name
320 * @param dim
321 * @param proc_skin_fun
322 * @param options
323 * @return MoFEMErrorCode
324 */
326 moab::Interface &moab, const char *file_name, int dim,
327 LoadFileFun proc_skin_fun = defaultProcSkinFun,
328 const char *options = "PARALLEL=BCAST;PARTITION=");
329
330 static Range getPartEntities(moab::Interface &moab, int part);
331
332 /**@}*/
333 /**@*/
334
335 /** \name Functions when root proc has all entities */
336
338 std::pair<std::pair<Range, Range>, SmartPetscObj<Vec>>;
339
340 /**
341 * @brief Create a ghost vector for exchanging data
342 *
343 * @note Only works if loadFileRootProcAllRestDistributed function is used.
344 *
345 * @param comm
346 * @param moab
347 * @param get_entities_fun function to get entities to partition
348 * @param dim dimension of partition entities
349 * @param adj_dim dimension of adjacent entities
350 * @param nb_coeffs number of coefficients
351 * @param sev
352 * @param root_rank
353 * @param get_vertices whether to get vertices along with entities
354 *
355 * Example:
356 * \code
357 auto face_exchange = CommInterface::createEntitiesPetscVector(
358 mField.get_comm(), mField.get_moab(),
359 [](Range part_ents) { return part_ents.subset_by_dimension(2); },
360 3, Sev::inform);
361 CHKERR CommInterface::updateEntitiesPetscVector(
362 mField.get_moab(), face_exchange, tag_value_to_exchange);
363 * \endcode
364 *
365 * @return std::pair<Range, SmartPetscObj<Vec>>
366 */
368 createEntitiesPetscVector(MPI_Comm comm, moab::Interface &moab,
369 std::function<Range(Range)> get_entities_fun,
370 const int nb_coeffs, Sev sev = Sev::verbose,
371 int root_rank = 0, bool get_vertices = true);
372
373 /**
374 * @brief Create a ghost vector for exchanging data
375 *
376 * @note Only works if loadFileRootProcAllRestDistributed function is used.
377 *
378 * @param comm
379 * @param moab
380 * @param dim dimension of partition entities
381 * @param adj_dim dimension of adjacent entities
382 * @param nb_coeffs number of coefficients
383 * @param sev
384 * @param root_rank
385 *
386 * Example:
387 * \code
388 auto face_exchange = CommInterface::createEntitiesPetscVector(
389 mField.get_comm(), mField.get_moab(), 2, 3, Sev::inform);
390 \endcode
391 *
392 * @return std::pair<Range, SmartPetscObj<Vec>>
393 */
395 createEntitiesPetscVector(MPI_Comm comm, moab::Interface &moab, int dim,
396 const int nb_coeffs, Sev sev = Sev::verbose,
397 int root_rank = 0);
398
399 using UpdateGhosts = std::function<MoFEMErrorCode(Vec vec)>;
400
403 CHKERR VecAssemblyBegin(v);
404 CHKERR VecAssemblyEnd(v);
405 CHKERR VecGhostUpdateBegin(v, ADD_VALUES, SCATTER_REVERSE);
406 CHKERR VecGhostUpdateEnd(v, ADD_VALUES, SCATTER_REVERSE);
407 CHKERR VecGhostUpdateBegin(v, INSERT_VALUES, SCATTER_FORWARD);
408 CHKERR VecGhostUpdateEnd(v, INSERT_VALUES, SCATTER_FORWARD);
410 };
411
412 /**
413 * @brief Set the Vector From Tag object
414 *
415 * @param moab
416 * @param vec
417 * @param tag
418 *
419 * Example:
420 * \code
421 CHKERR CommInterface::setVectorFromTag(
422 mField.get_moab(), face_exchange, tag_value_to_exchange);
423 \endcode
424 *
425 * @return MoFEMErrorCode
426 */
427 static MoFEMErrorCode setVectorFromTag(moab::Interface &moab,
428 EntitiesPetscVector &vec, Tag tag);
429
430 /**
431 * @brief Set the Tag From Vector object
432 *
433 * @param moab
434 * @param vec
435 * @param tag
436 *
437 * Example:
438 * \code
439 CHKERR CommInterface::setTagFromVector(
440 mField.get_moab(), face_exchange, tag_value_to_exchange);
441 \endcode
442 *
443 * @return MoFEMErrorCode
444 */
445 static MoFEMErrorCode setTagFromVector(moab::Interface &moab,
446 EntitiesPetscVector &vec, Tag tag);
447
448 /**
449 * @brief Exchange data between vector and data
450 *
451 * @param tag
452 *
453 * This reads values from the tag, exchanges ghost values, and writes the
454 * exchanged values back to the tag.
455 *
456 * Example:
457 * \code
458 CHKERR CommInterface::updateEntitiesPetscVector(
459 mField.get_moab(), face_exchange, tag_value_to_exchange);
460 \endcode
461 *
462 * @return MoFEMErrorCode
463 */
464 static MoFEMErrorCode
465 updateEntitiesPetscVector(moab::Interface &moab, EntitiesPetscVector &vec,
466 Tag tag,
467 UpdateGhosts update_gosts = defaultUpdateGhosts);
468
469 /**@}*/
470
471};
472} // namespace MoFEM
473
474#endif //__COMMINTERFACE_HPP__
475
476/**
477 * \defgroup mofem_comm Comm interface
478 * \brief Communication interface
479 *
480 * \ingroup mofem
481 */
MoFEM interface.
@ DEFAULT_VERBOSITY
@ VERBOSE
#define MYPCOMM_INDEX
default communicator number PCOMM
#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.
MoFEMErrorCode synchroniseFieldEntities(const std::string name, int verb=DEFAULT_VERBOSITY)
SeverityLevel
Severity levels.
MoFEMErrorCode partitionMesh(const Range &ents, const int dim, const int adj_dim, const int n_parts, Tag *th_vertex_weights=nullptr, Tag *th_edge_weights=nullptr, Tag *th_part_weights=nullptr, int verb=VERBOSE, const bool debug=false)
Set partition tag to each finite element in the problem.
MoFEMErrorCode resolveSharedFiniteElements(const Problem *problem_ptr, const std::string &fe_name, int verb=DEFAULT_VERBOSITY)
resolve shared entities for finite elements in the problem
const double v
phase velocity of light in medium (cm/ns)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
constexpr auto field_name
Managing BitRefLevels.
static MoFEMErrorCode updateEntitiesPetscVector(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag, UpdateGhosts update_gosts=defaultUpdateGhosts)
Exchange data between vector and data.
MoFEMErrorCode query_interface(boost::typeindex::type_index type_index, UnknownInterface **iface) const
std::function< MoFEMErrorCode(Vec vec)> UpdateGhosts
static Range getPartEntities(moab::Interface &moab, int part)
~CommInterface()=default
Destructor.
static MoFEMErrorCode defaultUpdateGhosts(Vec v)
MoFEMErrorCode makeEntitiesMultishared(const EntityHandle *entities, const int num_entities, const int owner_proc=0, int verb=DEFAULT_VERBOSITY)
make entities from proc 0 shared on all proc
static std::array< Range, 4 > defaultProcSkinFun(std::array< Range, 4 > &&proc_ents_skin, std::vector< const CubitMeshSets * > &&vec_ptr)
static MoFEMErrorCode loadFileRootProcAllRestDistributed(moab::Interface &moab, const char *file_name, int dim, LoadFileFun proc_skin_fun=defaultProcSkinFun, const char *options="PARALLEL=BCAST;PARTITION=")
Root proc has whole mesh, other procs only part of it.
MoFEMErrorCode synchroniseEntities(Range &ent, std::map< int, Range > *received_ents, int verb=DEFAULT_VERBOSITY)
synchronize entity range on processors (collective)
std::function< std::array< Range, 4 >(std::array< Range, 4 > &&, std::vector< const CubitMeshSets * > &&)> LoadFileFun
static MoFEMErrorCode setVectorFromTag(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag)
Set the Vector From Tag object.
static MoFEMErrorCode setTagFromVector(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag)
Set the Tag From Vector object.
MoFEMErrorCode makeFieldEntitiesMultishared(const std::string field_name, const int owner_proc=0, int verb=DEFAULT_VERBOSITY)
make field entities multi shared
std::pair< std::pair< Range, Range >, SmartPetscObj< Vec > > EntitiesPetscVector
MoFEMErrorCode resolveParentEntities(const Range &ent, int verb=DEFAULT_VERBOSITY)
Synchronise parent entities.
MoFEMErrorCode exchangeFieldData(const std::string field_name, int verb=DEFAULT_VERBOSITY)
Exchange field data.
static EntitiesPetscVector createEntitiesPetscVector(MPI_Comm comm, moab::Interface &moab, std::function< Range(Range)> get_entities_fun, const int nb_coeffs, Sev sev=Sev::verbose, int root_rank=0, bool get_vertices=true)
Create a ghost vector for exchanging data.
Core (interface) class.
Definition Core.hpp:83
static auto getOrCreate(const boost::shared_ptr< moab::Core > &core_mesh_ptr)
static auto getOrCreate(moab::Core *core_mesh_ptr)
keeps basic data about problem
intrusive_ptr for managing petsc objects
base class for all interface classes