Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
iMOAB.h File Reference
#include "moab/MOABConfig.h"
#include "moab/Types.hpp"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
+ Include dependency graph for iMOAB.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define iMOAB_AppID   int*
 
#define iMOAB_String   char*
 
#define iMOAB_GlobalID   int
 
#define iMOAB_LocalID   int
 
#define ErrCode   int
 
#define __PRETTY_FUNCTION__   __func__
 
#define CHK_MPI_ERR(ierr)
 
#define IMOAB_CHECKPOINTER(prmObj, position)
 
#define IMOAB_THROW_ERROR(message, retval)
 
#define IMOAB_ASSERT_RET(condition, message, retval)
 
#define IMOAB_ASSERT(condition, message)   IMOAB_ASSERT_RET( condition, message, moab::MB_UNHANDLED_OPTION )
 

Enumerations

enum  MOAB_TAG_TYPE {
  DENSE_INTEGER = 0 , DENSE_DOUBLE = 1 , DENSE_ENTITYHANDLE = 2 , SPARSE_INTEGER = 3 ,
  SPARSE_DOUBLE = 4 , SPARSE_ENTITYHANDLE = 5
}
 MOAB tag types can be: dense/sparse, and of int/double/EntityHandle types. They can also be defined on both elements and vertices of the mesh. More...
 
enum  MOAB_TAG_OWNER_TYPE { TAG_VERTEX = 0 , TAG_EDGE = 1 , TAG_FACE = 2 , TAG_ELEMENT = 3 }
 Define MOAB tag ownership information i.e., the entity where the tag is primarily defined This is typically used to query the tag data and to set it back. More...
 

Functions

ErrCode iMOAB_Initialize (int argc, iMOAB_String *argv)
 Initialize the iMOAB interface implementation. More...
 
ErrCode iMOAB_InitializeFortran (void)
 Initialize the iMOAB interface implementation from Fortran driver. More...
 
ErrCode iMOAB_Finalize (void)
 Finalize the iMOAB interface implementation. More...
 
ErrCode iMOAB_RegisterApplication (const iMOAB_String app_name, int *compid, iMOAB_AppID pid)
 Register application - Create a unique application ID and bootstrap interfaces for further queries. More...
 
ErrCode iMOAB_DeregisterApplication (iMOAB_AppID pid)
 De-Register application: delete mesh (set) associated with the application ID. More...
 
ErrCode iMOAB_RegisterApplicationFortran (const iMOAB_String app_name, int *compid, iMOAB_AppID pid)
 Register a Fortran-based application - Create a unique application ID and bootstrap interfaces for further queries. More...
 
ErrCode iMOAB_DeregisterApplicationFortran (iMOAB_AppID pid)
 De-Register the Fortran based application: delete mesh (set) associated with the application ID. More...
 
ErrCode iMOAB_ReadHeaderInfo (const iMOAB_String filename, int *num_global_vertices, int *num_global_elements, int *num_dimension, int *num_parts)
 It should be called on master task only, and information obtained could be broadcasted by the user. It is a fast lookup in the header of the file. More...
 
ErrCode iMOAB_LoadMesh (iMOAB_AppID pid, const iMOAB_String filename, const iMOAB_String read_options, int *num_ghost_layers)
 Load a MOAB mesh file in parallel and exchange ghost layers as requested. More...
 
ErrCode iMOAB_CreateVertices (iMOAB_AppID pid, int *coords_len, int *dim, double *coordinates)
 Create vertices for an app; it assumes no other vertices. More...
 
ErrCode iMOAB_CreateElements (iMOAB_AppID pid, int *num_elem, int *type, int *num_nodes_per_element, int *connectivity, int *block_ID)
 Create elements for an app; it assumes connectivity from local vertices, in order. More...
 
ErrCode iMOAB_ResolveSharedEntities (iMOAB_AppID pid, int *num_verts, int *marker)
 Resolve shared entities using global markers on shared vertices. More...
 
ErrCode iMOAB_DetermineGhostEntities (iMOAB_AppID pid, int *ghost_dim, int *num_ghost_layers, int *bridge_dim)
 Create the requested number of ghost layers for the parallel mesh. More...
 
ErrCode iMOAB_WriteMesh (iMOAB_AppID pid, const iMOAB_String filename, const iMOAB_String write_options)
 Write a MOAB mesh along with the solution tags to a file. More...
 
ErrCode iMOAB_WriteLocalMesh (iMOAB_AppID pid, iMOAB_String prefix)
 Write a local MOAB mesh copy. More...
 
ErrCode iMOAB_UpdateMeshInfo (iMOAB_AppID pid)
 Update local mesh data structure, from file information. More...
 
ErrCode iMOAB_GetMeshInfo (iMOAB_AppID pid, int *num_visible_vertices, int *num_visible_elements, int *num_visible_blocks, int *num_visible_surfaceBC, int *num_visible_vertexBC)
 Retrieve all the important mesh information related to vertices, elements, vertex and surface boundary conditions. More...
 
ErrCode iMOAB_GetVertexID (iMOAB_AppID pid, int *vertices_length, iMOAB_GlobalID *global_vertex_ID)
 Get the global vertex IDs for all locally visible (owned and shared/ghosted) vertices. More...
 
ErrCode iMOAB_GetVertexOwnership (iMOAB_AppID pid, int *vertices_length, int *visible_global_rank_ID)
 Get vertex ownership information. More...
 
ErrCode iMOAB_GetVisibleVerticesCoordinates (iMOAB_AppID pid, int *coords_length, double *coordinates)
 Get vertex coordinates for all local (owned and ghosted) vertices. More...
 
ErrCode iMOAB_GetBlockID (iMOAB_AppID pid, int *block_length, iMOAB_GlobalID *global_block_IDs)
 Get the global block IDs for all locally visible (owned and shared/ghosted) blocks. More...
 
ErrCode iMOAB_GetBlockInfo (iMOAB_AppID pid, iMOAB_GlobalID *global_block_ID, int *vertices_per_element, int *num_elements_in_block)
 Get the global block information and number of visible elements of belonging to a block (MATERIAL SET). More...
 
ErrCode iMOAB_GetVisibleElementsInfo (iMOAB_AppID pid, int *num_visible_elements, iMOAB_GlobalID *element_global_IDs, int *ranks, iMOAB_GlobalID *block_IDs)
 Get the visible elements information. More...
 
ErrCode iMOAB_GetBlockElementConnectivities (iMOAB_AppID pid, iMOAB_GlobalID *global_block_ID, int *connectivity_length, int *element_connectivity)
 Get the connectivities for elements contained within a certain block. More...
 
ErrCode iMOAB_GetElementConnectivity (iMOAB_AppID pid, iMOAB_LocalID *elem_index, int *connectivity_length, int *element_connectivity)
 Get the connectivity for one element only. More...
 
ErrCode iMOAB_GetElementOwnership (iMOAB_AppID pid, iMOAB_GlobalID *global_block_ID, int *num_elements_in_block, int *element_ownership)
 Get the element ownership within a certain block i.e., processor ID of the element owner. More...
 
ErrCode iMOAB_GetElementID (iMOAB_AppID pid, iMOAB_GlobalID *global_block_ID, int *num_elements_in_block, iMOAB_GlobalID *global_element_ID, iMOAB_LocalID *local_element_ID)
 Get the global IDs for all locally visible elements belonging to a particular block. More...
 
ErrCode iMOAB_GetPointerToSurfaceBC (iMOAB_AppID pid, int *surface_BC_length, iMOAB_LocalID *local_element_ID, int *reference_surface_ID, int *boundary_condition_value)
 Get the surface boundary condition information. More...
 
ErrCode iMOAB_GetPointerToVertexBC (iMOAB_AppID pid, int *vertex_BC_length, iMOAB_LocalID *local_vertex_ID, int *boundary_condition_value)
 Get the vertex boundary condition information. More...
 
ErrCode iMOAB_DefineTagStorage (iMOAB_AppID pid, const iMOAB_String tag_storage_name, int *tag_type, int *components_per_entity, int *tag_index)
 Define a MOAB Tag corresponding to the application depending on requested types. More...
 
ErrCode iMOAB_SetIntTagStorage (iMOAB_AppID pid, const iMOAB_String tag_storage_name, int *num_tag_storage_length, int *entity_type, int *tag_storage_data)
 Store the specified values in a MOAB integer Tag. More...
 
ErrCode iMOAB_GetIntTagStorage (iMOAB_AppID pid, const iMOAB_String tag_storage_name, int *num_tag_storage_length, int *entity_type, int *tag_storage_data)
 Get the specified values in a MOAB integer Tag. More...
 
ErrCode iMOAB_SetDoubleTagStorage (iMOAB_AppID pid, const iMOAB_String tag_storage_name, int *num_tag_storage_length, int *entity_type, double *tag_storage_data)
 Store the specified values in a MOAB double Tag. More...
 
ErrCode iMOAB_SetDoubleTagStorageWithGid (iMOAB_AppID pid, const iMOAB_String tag_storage_names, int *num_tag_storage_length, int *entity_type, double *tag_storage_data, int *globalIds)
 Store the specified values in a MOAB double Tag, for given ids. More...
 
ErrCode iMOAB_GetDoubleTagStorage (iMOAB_AppID pid, const iMOAB_String tag_storage_name, int *num_tag_storage_length, int *entity_type, double *tag_storage_data)
 Retrieve the specified values in a MOAB double Tag. More...
 
ErrCode iMOAB_SynchronizeTags (iMOAB_AppID pid, int *num_tag, int *tag_indices, int *ent_type)
 Exchange tag values for the given tags across process boundaries. More...
 
ErrCode iMOAB_ReduceTagsMax (iMOAB_AppID pid, int *tag_index, int *ent_type)
 Perform global reductions with the processes in the current applications communicator. Specifically this routine performs reductions on the maximum value of the tag indicated by tag_index. More...
 
ErrCode iMOAB_GetNeighborElements (iMOAB_AppID pid, iMOAB_LocalID *local_index, int *num_adjacent_elements, iMOAB_LocalID *adjacent_element_IDs)
 Retrieve the adjacencies for the element entities. More...
 
ErrCode iMOAB_GetNeighborVertices (iMOAB_AppID pid, iMOAB_LocalID *local_vertex_ID, int *num_adjacent_vertices, iMOAB_LocalID *adjacent_vertex_IDs)
 Get the adjacencies for the vertex entities. More...
 
ErrCode iMOAB_SetGlobalInfo (iMOAB_AppID pid, int *num_global_verts, int *num_global_elems)
 Set global information for number of vertices and number of elements; It is usually available from the h5m file, or it can be computed with a MPI_Reduce. More...
 
ErrCode iMOAB_GetGlobalInfo (iMOAB_AppID pid, int *num_global_verts, int *num_global_elems)
 Get global information about number of vertices and number of elements. More...
 

Detailed Description

iMOAB: a language-agnostic, lightweight interface to MOAB.

Supports usage from C/C++, Fortran (77/90/2003), Python.

Remarks
1) All data in the interface are exposed via POD-types.
2) Pass everything by reference, so we do not have to use VAL()
3) Arrays are allocated by the user code. No concerns about de-allocation of the data will be taken up by the interface.
4) Always pass the pointer to the start of array along with the total allocated size for the array.
5) Return the filled array requested by user along with optionally the actual length of the array that was filled. (for typical cases, should be the allocated length)

Definition in file iMOAB.h.

Macro Definition Documentation

◆ __PRETTY_FUNCTION__

#define __PRETTY_FUNCTION__   __func__

Definition at line 65 of file iMOAB.h.

◆ CHK_MPI_ERR

#define CHK_MPI_ERR (   ierr)
Value:
{ \
if( 0 != ( ierr ) ) return moab::MB_FAILURE; \
}

Definition at line 95 of file iMOAB.h.

◆ ErrCode

#define ErrCode   int

Definition at line 58 of file iMOAB.h.

◆ iMOAB_AppID

#define iMOAB_AppID   int*

\notes 1) Fortran MPI_Comm won't work. Take an integer argument and use MPI_F2C calls to get the C-Comm object 2) ReadHeaderInfo - Does it need the pid ? 3) Reuse the comm object from the registration for both load and write operations. Do not take comm objects again to avoid confusion and retain consistency. 4) Decipher the global comm object and the subset partioning for each application based on the comm object 5) GetMeshInfo - return separately the owned and ghosted vertices/elements – not together in visible_** but rather owned_** and ghosted_**. Make these arrays of size 2. 6) Should we sort the vertices after ghosting, such that the locally owned is first, and the ghosted appended next. 7) RCM only for the owned part of the mesh – do not screw with the ghosted layers 8) GetBlockID - identical to GetVertexID – return the global numbering for block 9) GetVertexID – remember that the order of vertices returned have an implicit numbering embedded in it. DO NOT CHANGE THIS ORDERING... 10) GetBlockInfo takes global Block ID; Remove blockname unless there is a separate use case for it.. 11) GetElementConnectivity - clarify whether we return global or local vertex numbering. Preferably local numbering else lot of deciphering for global.

Definition at line 51 of file iMOAB.h.

◆ IMOAB_ASSERT

#define IMOAB_ASSERT (   condition,
  message 
)    IMOAB_ASSERT_RET( condition, message, moab::MB_UNHANDLED_OPTION )

Definition at line 126 of file iMOAB.h.

◆ IMOAB_ASSERT_RET

#define IMOAB_ASSERT_RET (   condition,
  message,
  retval 
)
Value:
{ \
if( !( condition ) ) \
{ \
printf( "iMOAB Error: %s.\n Failed condition: %s\n Location: %s in %s:%d.\n", message, #condition, \
__PRETTY_FUNCTION__, __FILE__, __LINE__ ); \
return retval; \
} \
}

Definition at line 116 of file iMOAB.h.

◆ IMOAB_CHECKPOINTER

#define IMOAB_CHECKPOINTER (   prmObj,
  position 
)
Value:
{ \
if( prmObj == nullptr ) \
{ \
printf( "InputParamError at %d: '%s' is invalid and null.\n", position, #prmObj ); \
} \
}

Definition at line 100 of file iMOAB.h.

◆ iMOAB_GlobalID

#define iMOAB_GlobalID   int

Definition at line 53 of file iMOAB.h.

◆ iMOAB_LocalID

#define iMOAB_LocalID   int

Definition at line 54 of file iMOAB.h.

◆ iMOAB_String

#define iMOAB_String   char*

Definition at line 52 of file iMOAB.h.

◆ IMOAB_THROW_ERROR

#define IMOAB_THROW_ERROR (   message,
  retval 
)
Value:
{ \
printf( "iMOAB Error: %s.\n Location: %s in %s:%d.\n", message, __PRETTY_FUNCTION__, __FILE__, __LINE__ ); \
return retval; \
}

Definition at line 109 of file iMOAB.h.

Enumeration Type Documentation

◆ MOAB_TAG_OWNER_TYPE

Define MOAB tag ownership information i.e., the entity where the tag is primarily defined This is typically used to query the tag data and to set it back.

Enumerator
TAG_VERTEX 
TAG_EDGE 
TAG_FACE 
TAG_ELEMENT 

Definition at line 87 of file iMOAB.h.

88 {
89  TAG_VERTEX = 0,
90  TAG_EDGE = 1,
91  TAG_FACE = 2,
92  TAG_ELEMENT = 3
93 };

◆ MOAB_TAG_TYPE

MOAB tag types can be: dense/sparse, and of int/double/EntityHandle types. They can also be defined on both elements and vertices of the mesh.

Enumerator
DENSE_INTEGER 
DENSE_DOUBLE 
DENSE_ENTITYHANDLE 
SPARSE_INTEGER 
SPARSE_DOUBLE 
SPARSE_ENTITYHANDLE 

Definition at line 73 of file iMOAB.h.

74 {
75  DENSE_INTEGER = 0,
76  DENSE_DOUBLE = 1,
78  SPARSE_INTEGER = 3,
79  SPARSE_DOUBLE = 4,
81 };

Function Documentation

◆ iMOAB_CreateElements()

ErrCode iMOAB_CreateElements ( iMOAB_AppID  pid,
int *  num_elem,
int *  type,
int *  num_nodes_per_element,
int *  connectivity,
int *  block_ID 
)

Create elements for an app; it assumes connectivity from local vertices, in order.

Note
Operations: Not collective
Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]num_elem(int*) Number of elements.
[in]type(int*) Type of element (moab type).
[in]num_nodes_per_element(int*) Number of nodes per element.
[in]connectivity(int *) Connectivity array, with respect to vertices (assumed contiguous).
[in]block_ID(int *) The local block identifier, which will now contain the elements.
Returns
ErrCode The error code indicating success or failure.

add the new ents to the clock set

Definition at line 2931 of file iMOAB.cpp.

2937 {
2938  // Create elements
2939  appData& data = context.appDatas[*pid];
2940 
2941  ReadUtilIface* read_iface;
2942  MB_CHK_ERR( context.MBI->query_interface( read_iface ) );
2943 
2944  EntityType mbtype = (EntityType)( *type );
2945  EntityHandle actual_start_handle;
2946  EntityHandle* array = nullptr;
2947  MB_CHK_ERR(
2948  read_iface->get_element_connect( *num_elem, *num_nodes_per_element, mbtype, 1, actual_start_handle, array ) );
2949 
2950  // fill up with actual connectivity from input; assume the vertices are in order, and start
2951  // vertex is the first in the current data vertex range
2952  EntityHandle firstVertex = data.local_verts[0];
2953 
2954  for( int j = 0; j < *num_elem * ( *num_nodes_per_element ); j++ )
2955  {
2956  array[j] = connectivity[j] + firstVertex - 1;
2957  } // assumes connectivity uses 1 based array (from fortran, mostly)
2958 
2959  Range new_elems( actual_start_handle, actual_start_handle + *num_elem - 1 );
2960 
2961  MB_CHK_ERR( context.MBI->add_entities( data.file_set, new_elems ) );
2962 
2963  data.primary_elems.merge( new_elems );
2964 
2965  // add to adjacency
2966  MB_CHK_ERR( read_iface->update_adjacencies( actual_start_handle, *num_elem, *num_nodes_per_element, array ) );
2967 
2968  // organize all new elements in block, with the given block ID; if the block set is not
2969  // existing, create a new mesh set;
2970  Range sets;
2971  int set_no = *block_ID;
2972  const void* setno_ptr = &set_no;
2973 
2974  EntityHandle block_set;
2976  &setno_ptr, 1, sets );
2977 
2978  if( MB_FAILURE == rval || sets.empty() )
2979  {
2980  // create a new set, with this block ID
2981  MB_CHK_ERR( context.MBI->create_meshset( MESHSET_SET, block_set ) );
2982 
2983  MB_CHK_ERR( context.MBI->tag_set_data( context.material_tag, &block_set, 1, &set_no ) );
2984 
2985  // add the material set to file set
2986  MB_CHK_ERR( context.MBI->add_entities( data.file_set, &block_set, 1 ) );
2987  }
2988  else
2989  {
2990  block_set = sets[0];
2991  } // first set is the one we want
2992 
2993  /// add the new ents to the clock set
2994  MB_CHK_ERR( context.MBI->add_entities( block_set, new_elems ) );
2995 
2996  return moab::MB_SUCCESS;
2997 }

References moab::Interface::add_entities(), GlobalContext::appDatas, context, moab::Interface::create_meshset(), moab::Range::empty(), ErrorCode, appData::file_set, moab::ReadUtilIface::get_element_connect(), moab::Interface::get_entities_by_type_and_tag(), appData::local_verts, GlobalContext::material_tag, MB_CHK_ERR, MB_SUCCESS, MBENTITYSET, GlobalContext::MBI, moab::Range::merge(), MESHSET_SET, appData::primary_elems, moab::Interface::query_interface(), moab::Interface::tag_set_data(), and moab::ReadUtilIface::update_adjacencies().

◆ iMOAB_CreateVertices()

ErrCode iMOAB_CreateVertices ( iMOAB_AppID  pid,
int *  coords_len,
int *  dim,
double *  coordinates 
)

Create vertices for an app; it assumes no other vertices.

Note
Operations: Not collective
Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]coords_len(int*) Size of the coordinates array (nverts * dim).
[in]dim(int*) Dimension of the vertex coordinates (usually 3).
[in]coordinates(double*) Coordinates of all vertices, interleaved.
Returns
ErrCode The error code indicating success or failure.

Definition at line 2911 of file iMOAB.cpp.

2912 {
2913  appData& data = context.appDatas[*pid];
2914 
2915  if( !data.local_verts.empty() ) // we should have no vertices in the app
2916  {
2917  return moab::MB_FAILURE;
2918  }
2919 
2920  int nverts = *coords_len / *dim;
2921 
2922  MB_CHK_ERR( context.MBI->create_vertices( coordinates, nverts, data.local_verts ) );
2923 
2925 
2926  // also add the vertices to the all_verts range
2927  data.all_verts.merge( data.local_verts );
2928  return moab::MB_SUCCESS;
2929 }

References moab::Interface::add_entities(), appData::all_verts, GlobalContext::appDatas, context, moab::Interface::create_vertices(), moab::Range::empty(), appData::file_set, appData::local_verts, MB_CHK_ERR, MB_SUCCESS, GlobalContext::MBI, and moab::Range::merge().

◆ iMOAB_DefineTagStorage()

ErrCode iMOAB_DefineTagStorage ( iMOAB_AppID  pid,
const iMOAB_String  tag_storage_name,
int *  tag_type,
int *  components_per_entity,
int *  tag_index 
)

Define a MOAB Tag corresponding to the application depending on requested types.

Note
In MOAB, for most solution vectors, we only need to create a "Dense", "Double" Tag. A sparse tag can be created too. If the tag is already existing in the file, it will not be created. If it is a new tag, memory will be allocated when setting the values. Default values are 0 for for integer tags, 0.0 for double tags, 0 for entity handle tags.

Operations: Collective

Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]tag_storage_name(iMOAB_String) The tag name to store/retrieve the data in MOAB.
[in]tag_type(int*) The type of MOAB tag (Dense/Sparse, Double/Int/EntityHandle), enum MOAB_TAG_TYPE.
[in]components_per_entity(int*) The total size of vector dimension per entity for the tag (e.g., number of doubles per entity).
[out]tag_index(int*) The tag index which can be used as identifier in synchronize methods.
Returns
ErrCode The error code indicating success or failure.

Definition at line 2068 of file iMOAB.cpp.

2073 {
2074  // we have 6 types of tags supported so far
2075  // check if tag type is valid
2076  if( *tag_type < 0 || *tag_type > 5 ) return moab::MB_FAILURE;
2077 
2078  DataType tagDataType;
2079  TagType tagType;
2080  void* defaultVal = nullptr;
2081  int* defInt = new int[*components_per_entity];
2082  double* defDouble = new double[*components_per_entity];
2083  EntityHandle* defHandle = new EntityHandle[*components_per_entity];
2084 
2085  for( int i = 0; i < *components_per_entity; i++ )
2086  {
2087  defInt[i] = 0;
2088  defDouble[i] = -1e+10;
2089  defHandle[i] = static_cast< EntityHandle >( 0 );
2090  }
2091 
2092  switch( *tag_type )
2093  {
2094  case 0:
2095  tagDataType = MB_TYPE_INTEGER;
2096  tagType = MB_TAG_DENSE;
2097  defaultVal = defInt;
2098  break;
2099 
2100  case 1:
2101  tagDataType = MB_TYPE_DOUBLE;
2102  tagType = MB_TAG_DENSE;
2103  defaultVal = defDouble;
2104  break;
2105 
2106  case 2:
2107  tagDataType = MB_TYPE_HANDLE;
2108  tagType = MB_TAG_DENSE;
2109  defaultVal = defHandle;
2110  break;
2111 
2112  case 3:
2113  tagDataType = MB_TYPE_INTEGER;
2114  tagType = MB_TAG_SPARSE;
2115  defaultVal = defInt;
2116  break;
2117 
2118  case 4:
2119  tagDataType = MB_TYPE_DOUBLE;
2120  tagType = MB_TAG_SPARSE;
2121  defaultVal = defDouble;
2122  break;
2123 
2124  case 5:
2125  tagDataType = MB_TYPE_HANDLE;
2126  tagType = MB_TAG_SPARSE;
2127  defaultVal = defHandle;
2128  break;
2129 
2130  default: {
2131  delete[] defInt;
2132  delete[] defDouble;
2133  delete[] defHandle;
2134  return moab::MB_FAILURE;
2135  } // error
2136  }
2137 
2138  // split storage names if separated list
2139  std::string tag_name( tag_storage_name );
2140  // first separate the names of the tags
2141  // we assume that there are separators ":" between the tag names
2142  std::vector< std::string > tagNames;
2143  std::string separator( ":" );
2144  split_tag_names( tag_name, separator, tagNames );
2145 
2146  ErrorCode rval = moab::MB_SUCCESS; // assume success already :)
2147  appData& data = context.appDatas[*pid];
2148  int already_defined_tags = 0;
2149 
2150  Tag tagHandle;
2151  for( size_t i = 0; i < tagNames.size(); i++ )
2152  {
2153  rval = context.MBI->tag_get_handle( tagNames[i].c_str(), *components_per_entity, tagDataType, tagHandle,
2154  tagType | MB_TAG_EXCL | MB_TAG_CREAT, defaultVal );
2155 
2156  if( MB_ALREADY_ALLOCATED == rval )
2157  {
2158  std::map< std::string, Tag >& mTags = data.tagMap;
2159  std::map< std::string, Tag >::iterator mit = mTags.find( tagNames[i].c_str() );
2160 
2161  if( mit == mTags.end() )
2162  {
2163  // add it to the map
2164  mTags[tagNames[i]] = tagHandle;
2165  // push it to the list of tags, too
2166  *tag_index = (int)data.tagList.size();
2167  data.tagList.push_back( tagHandle );
2168  }
2169  rval = MB_SUCCESS;
2170  already_defined_tags++;
2171  }
2172  else if( MB_SUCCESS == rval )
2173  {
2174  data.tagMap[tagNames[i]] = tagHandle;
2175  *tag_index = (int)data.tagList.size();
2176  data.tagList.push_back( tagHandle );
2177  }
2178  else
2179  {
2180  rval = moab::MB_FAILURE; // some tags were not created
2181  }
2182  }
2183  // we don't need default values anymore, avoid leaks
2184  int rankHere = 0;
2185 #ifdef MOAB_HAVE_MPI
2186  ParallelComm* pco = context.appDatas[*pid].pcomm;
2187  rankHere = pco->rank();
2188 #endif
2189  if( !rankHere && already_defined_tags )
2190  std::cout << " application with ID: " << *pid << " global id: " << data.global_id << " name: " << data.name
2191  << " has " << already_defined_tags << " already defined tags out of " << tagNames.size()
2192  << " tags \n";
2193  delete[] defInt;
2194  delete[] defDouble;
2195  delete[] defHandle;
2196  return rval;
2197 }

References GlobalContext::appDatas, context, ErrorCode, appData::global_id, MB_ALREADY_ALLOCATED, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TAG_EXCL, MB_TAG_SPARSE, MB_TYPE_DOUBLE, MB_TYPE_HANDLE, MB_TYPE_INTEGER, GlobalContext::MBI, appData::name, moab::ParallelComm::rank(), split_tag_names(), moab::Interface::tag_get_handle(), appData::tagList, appData::tagMap, and TagType.

Referenced by iMOAB_ReceiveMesh().

◆ iMOAB_DetermineGhostEntities()

ErrCode iMOAB_DetermineGhostEntities ( iMOAB_AppID  pid,
int *  ghost_dim,
int *  num_ghost_layers,
int *  bridge_dim 
)

Create the requested number of ghost layers for the parallel mesh.

Note
The routine assumes that the shared entities were resolved successfully, and that the mesh is properly distributed on separate tasks.

Operations: Collective.

Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]ghost_dim(int*) Desired ghost dimension (2 or 3, most of the time).
[in]num_ghost_layers(int*) Number of ghost layers requested.
[in]bridge_dim(int*) Bridge dimension (0 for vertices, 1 for edges, 2 for faces).
Returns
ErrCode The error code indicating success or failure.

Definition at line 3076 of file iMOAB.cpp.

3077 {
3078  // verify we have valid ghost layers input specified. If invalid, exit quick.
3079  if( num_ghost_layers && *num_ghost_layers <= 0 )
3080  {
3081  return moab::MB_SUCCESS;
3082  } // nothing to do
3083 
3084  appData& data = context.appDatas[*pid];
3085  ParallelComm* pco = context.appDatas[*pid].pcomm;
3086 
3087  // maybe we should be passing this too; most of the time we do not need additional ents collective call
3088  constexpr int addl_ents = 0;
3089  MB_CHK_ERR( pco->exchange_ghost_cells( *ghost_dim, *bridge_dim, 1, // get only one layer of ghost entities
3090  addl_ents, true, true, &data.file_set ) );
3091  for( int i = 2; i <= *num_ghost_layers; i++ )
3092  {
3093  MB_CHK_ERR( pco->correct_thin_ghost_layers() ); // correct for thin layers
3094  MB_CHK_ERR( pco->exchange_ghost_cells( *ghost_dim, *bridge_dim, i, // iteratively get one extra layer
3095  addl_ents, true, true, &data.file_set ) );
3096  }
3097 
3098  // Update ghost layer information
3099  data.num_ghost_layers = *num_ghost_layers;
3100 
3101  // now re-establish all mesh info; will reconstruct mesh info, based solely on what is in the file set
3102  return iMOAB_UpdateMeshInfo( pid );
3103 }

References GlobalContext::appDatas, context, moab::ParallelComm::correct_thin_ghost_layers(), moab::ParallelComm::exchange_ghost_cells(), appData::file_set, iMOAB_UpdateMeshInfo(), MB_CHK_ERR, MB_SUCCESS, and appData::num_ghost_layers.

◆ iMOAB_GetBlockElementConnectivities()

ErrCode iMOAB_GetBlockElementConnectivities ( iMOAB_AppID  pid,
iMOAB_GlobalID global_block_ID,
int *  connectivity_length,
int *  element_connectivity 
)

Get the connectivities for elements contained within a certain block.

Note
input is the block ID. Should we change to visible block local index?

Operations: Not Collective

Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]global_block_ID(iMOAB_GlobalID*) The global block ID of the set being queried.
[in]connectivity_length(int*) The allocated size of array. (typical size := vertices_per_element*num_elements_in_block)
[out]element_connectivity(int*) The connectivity array to store element ordering in MOAB canonical numbering scheme (array allocated by user); array contains vertex indices in the local numbering order for vertices elements are in the same order as provided by GetElementOwnership and GetElementID.
Returns
ErrCode The error code indicating success or failure.

Definition at line 1745 of file iMOAB.cpp.

1749 {
1750  assert( global_block_ID ); // ensure global block ID argument is not null
1751  assert( connectivity_length ); // ensure connectivity length argument is not null
1752 
1753  appData& data = context.appDatas[*pid];
1754  std::map< int, int >& matMap = data.matIndex;
1755  std::map< int, int >::iterator it = matMap.find( *global_block_ID );
1756 
1757  if( it == matMap.end() )
1758  {
1759  return moab::MB_FAILURE;
1760  } // error in finding block with id
1761 
1762  int blockIndex = matMap[*global_block_ID];
1763  EntityHandle matMeshSet = data.mat_sets[blockIndex];
1764  std::vector< EntityHandle > elems;
1765 
1766  MB_CHK_SET_ERR( context.MBI->get_entities_by_handle( matMeshSet, elems ), "can't get block elements" );
1767 
1768  if( elems.empty() ) return moab::MB_FAILURE;
1769 
1770  std::vector< EntityHandle > vconnect;
1771  MB_CHK_SET_ERR( context.MBI->get_connectivity( &elems[0], elems.size(), vconnect ), "can't get connectivity" );
1772 
1773  if( *connectivity_length != (int)vconnect.size() )
1774  {
1775  return moab::MB_FAILURE;
1776  } // mismatched sizes
1777 
1778  for( int i = 0; i < *connectivity_length; i++ )
1779  {
1780  int inx = data.all_verts.index( vconnect[i] );
1781 
1782  if( -1 == inx )
1783  {
1784  return moab::MB_FAILURE;
1785  } // error, vertex not in local range
1786 
1787  element_connectivity[i] = inx;
1788  }
1789 
1790  return moab::MB_SUCCESS;
1791 }

References appData::all_verts, GlobalContext::appDatas, context, moab::Interface::get_connectivity(), moab::Interface::get_entities_by_handle(), moab::Range::index(), appData::mat_sets, appData::matIndex, MB_CHK_SET_ERR, MB_SUCCESS, and GlobalContext::MBI.

◆ iMOAB_GetDoubleTagStorage()

ErrCode iMOAB_GetDoubleTagStorage ( iMOAB_AppID  pid,
const iMOAB_String  tag_storage_name,
int *  num_tag_storage_length,
int *  entity_type,
double *  tag_storage_data 
)

Retrieve the specified values in a MOAB double Tag.

Note
Operations: Collective
Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]tag_storage_name(iMOAB_String) The tag names to retrieve the data in MOAB.
[in]num_tag_storage_length(int) The size of total tag storage data (e.g., num_visible_vertices*components_per_entity*num_tags or num_visible_elements*components_per_entity*num_tags)
[in]entity_type(int*) Type=0 for vertices, and Type=1 for primary elements.
[out]tag_storage_data(double*) The array data of type double to replace the internal tag memory; The data is assumed to be contiguous over the local set of visible entities (either vertices or elements). unrolled by tags
Returns
ErrCode The error code indicating success or failure.

Definition at line 2729 of file iMOAB.cpp.

2734 {
2735  // exactly the same code, except tag type check
2736  std::string tag_names( tag_storage_names );
2737  // exactly the same code as for int tag :) maybe should check the type of tag too
2738  std::vector< std::string > tagNames;
2739  std::vector< Tag > tagHandles;
2740  std::string separator( ":" );
2741  split_tag_names( tag_names, separator, tagNames );
2742 
2743  appData& data = context.appDatas[*pid];
2744 
2745  // set it on a subset of entities, based on type and length
2746  Range* ents_to_get = nullptr;
2747 
2748  if( *ent_type == 0 ) // vertices
2749  {
2750  ents_to_get = &data.all_verts;
2751  }
2752  else if( *ent_type == 1 )
2753  {
2754  ents_to_get = &data.primary_elems;
2755  }
2756  int nents_to_get = (int)ents_to_get->size();
2757  int position = 0;
2758  for( size_t i = 0; i < tagNames.size(); i++ )
2759  {
2760  if( data.tagMap.find( tagNames[i] ) == data.tagMap.end() )
2761  {
2762  return moab::MB_FAILURE;
2763  } // tag not defined
2764 
2765  Tag tag = data.tagMap[tagNames[i]];
2766 
2767  int tagLength = 0;
2768  MB_CHK_ERR( context.MBI->tag_get_length( tag, tagLength ) );
2769 
2770  DataType dtype;
2771  MB_CHK_ERR( context.MBI->tag_get_data_type( tag, dtype ) );
2772 
2773  if( dtype != MB_TYPE_DOUBLE )
2774  {
2775  return moab::MB_FAILURE;
2776  }
2777 
2778  if( position + nents_to_get * tagLength > *num_tag_storage_length )
2779  return moab::MB_FAILURE; // too many entity values to get
2780 
2781  MB_CHK_ERR( context.MBI->tag_get_data( tag, *ents_to_get, &tag_storage_data[position] ) );
2782  position = position + nents_to_get * tagLength;
2783  }
2784 
2785  return moab::MB_SUCCESS; // no error
2786 }

References appData::all_verts, GlobalContext::appDatas, context, MB_CHK_ERR, MB_SUCCESS, MB_TYPE_DOUBLE, GlobalContext::MBI, appData::primary_elems, moab::Range::size(), split_tag_names(), moab::Interface::tag_get_data(), moab::Interface::tag_get_data_type(), moab::Interface::tag_get_length(), and appData::tagMap.

◆ iMOAB_GetElementConnectivity()

ErrCode iMOAB_GetElementConnectivity ( iMOAB_AppID  pid,
iMOAB_LocalID elem_index,
int *  connectivity_length,
int *  element_connectivity 
)

Get the connectivity for one element only.

Note
This is a convenience method and in general should not be used unless necessary. You should use colaesced calls for multiple elements for efficiency.

Operations: Not Collective

Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]elem_index(iMOAB_LocalID *) Local element index.
[in,out]connectivity_length(int *) On input, maximum length of connectivity. On output, actual length.
[out]element_connectivity(int*) The connectivity array to store connectivity in MOAB canonical numbering scheme. Array contains vertex indices in the local numbering order for vertices.
Returns
ErrCode The error code indicating success or failure.

Definition at line 1793 of file iMOAB.cpp.

1797 {
1798  assert( elem_index ); // ensure element index argument is not null
1799  assert( connectivity_length ); // ensure connectivity length argument is not null
1800 
1801  appData& data = context.appDatas[*pid];
1802  assert( ( *elem_index >= 0 ) && ( *elem_index < (int)data.primary_elems.size() ) );
1803 
1804  int num_nodes;
1805  const EntityHandle* conn;
1806 
1807  EntityHandle eh = data.primary_elems[*elem_index];
1808 
1809  MB_CHK_SET_ERR( context.MBI->get_connectivity( eh, conn, num_nodes ), "can't get connectivity" );
1810 
1811  if( *connectivity_length < num_nodes )
1812  {
1813  return moab::MB_FAILURE;
1814  } // wrong number of vertices
1815 
1816  for( int i = 0; i < num_nodes; i++ )
1817  {
1818  int index = data.all_verts.index( conn[i] );
1819 
1820  if( -1 == index )
1821  {
1822  return moab::MB_FAILURE;
1823  }
1824 
1825  element_connectivity[i] = index;
1826  }
1827 
1828  *connectivity_length = num_nodes;
1829 
1830  return moab::MB_SUCCESS;
1831 }

References appData::all_verts, GlobalContext::appDatas, context, moab::Interface::get_connectivity(), moab::index, moab::Range::index(), MB_CHK_SET_ERR, MB_SUCCESS, GlobalContext::MBI, appData::primary_elems, and moab::Range::size().

◆ iMOAB_GetElementID()

ErrCode iMOAB_GetElementID ( iMOAB_AppID  pid,
iMOAB_GlobalID global_block_ID,
int *  num_elements_in_block,
iMOAB_GlobalID global_element_ID,
iMOAB_LocalID local_element_ID 
)

Get the global IDs for all locally visible elements belonging to a particular block.

Note
The method will return also the local index of each element, in the local range that contains all visible elements.

Operations: Not Collective

Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]global_block_ID(iMOAB_GlobalID*) The global block ID of the set being queried.
[in]num_elements_in_block(int*) The allocated size of global element ID array, same as num_elements_in_block returned from GetBlockInfo().
[out]global_element_ID(iMOAB_GlobalID*) The global IDs for all locally visible elements (array allocated by user).
[out]local_element_ID(iMOAB_LocalID*) (Optional) The local IDs for all locally visible elements (index in the range of all primary elements in the rank)
Returns
ErrCode The error code indicating success or failure.

Definition at line 1880 of file iMOAB.cpp.

1885 {
1886  assert( global_block_ID ); // ensure global block ID argument is not null
1887  assert( num_elements_in_block ); // ensure number of elements in block argument is not null
1888 
1889  appData& data = context.appDatas[*pid];
1890  std::map< int, int >& matMap = data.matIndex;
1891 
1892  std::map< int, int >::iterator it = matMap.find( *global_block_ID );
1893 
1894  if( it == matMap.end() )
1895  {
1896  return moab::MB_FAILURE;
1897  } // error in finding block with id
1898 
1899  int blockIndex = matMap[*global_block_ID];
1900  EntityHandle matMeshSet = data.mat_sets[blockIndex];
1901  Range elems;
1902  MB_CHK_SET_ERR( context.MBI->get_entities_by_handle( matMeshSet, elems ), "can't get block elements" );
1903 
1904  if( elems.empty() ) return moab::MB_FAILURE;
1905 
1906  if( *num_elements_in_block != (int)elems.size() )
1907  {
1908  return moab::MB_FAILURE;
1909  } // bad memory allocation
1910 
1911  MB_CHK_SET_ERR( context.MBI->tag_get_data( context.globalID_tag, elems, global_element_ID ),
1912  "can't get global IDs" );
1913 
1914  // check that elems are among primary_elems in data
1915  for( int i = 0; i < *num_elements_in_block; i++ )
1916  {
1917  local_element_ID[i] = data.primary_elems.index( elems[i] );
1918 
1919  if( -1 == local_element_ID[i] )
1920  {
1921  return moab::MB_FAILURE;
1922  } // error, not in local primary elements
1923  }
1924 
1925  return moab::MB_SUCCESS;
1926 }

References GlobalContext::appDatas, context, moab::Range::empty(), moab::Interface::get_entities_by_handle(), GlobalContext::globalID_tag, moab::Range::index(), appData::mat_sets, appData::matIndex, MB_CHK_SET_ERR, MB_SUCCESS, GlobalContext::MBI, appData::primary_elems, moab::Range::size(), and moab::Interface::tag_get_data().

◆ iMOAB_GetElementOwnership()

ErrCode iMOAB_GetElementOwnership ( iMOAB_AppID  pid,
iMOAB_GlobalID global_block_ID,
int *  num_elements_in_block,
int *  element_ownership 
)

Get the element ownership within a certain block i.e., processor ID of the element owner.

Note
: Should we use local block index for input, instead of the global block ID ?

Operations: Not Collective

Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]global_block_ID(iMOAB_GlobalID) The global block ID of the set being queried.
[in]num_elements_in_block(int*) The allocated size of ownership array, same as num_elements_in_block returned from GetBlockInfo().
[out]element_ownership(int*) The ownership array to store processor ID for all elements (array allocated by user).
Returns
ErrCode The error code indicating success or failure.

Definition at line 1833 of file iMOAB.cpp.

1837 {
1838  assert( global_block_ID ); // ensure global block ID argument is not null
1839  assert( num_elements_in_block ); // ensure number of elements in block argument is not null
1840 
1841  std::map< int, int >& matMap = context.appDatas[*pid].matIndex;
1842 
1843  std::map< int, int >::iterator it = matMap.find( *global_block_ID );
1844 
1845  if( it == matMap.end() )
1846  {
1847  return moab::MB_FAILURE;
1848  } // error in finding block with id
1849 
1850  int blockIndex = matMap[*global_block_ID];
1851  EntityHandle matMeshSet = context.appDatas[*pid].mat_sets[blockIndex];
1852  Range elems;
1853 
1854  MB_CHK_SET_ERR( context.MBI->get_entities_by_handle( matMeshSet, elems ), "can't get block elements" );
1855 
1856  if( elems.empty() ) return moab::MB_FAILURE;
1857 
1858  if( *num_elements_in_block != (int)elems.size() )
1859  {
1860  return moab::MB_FAILURE;
1861  } // bad memory allocation
1862 
1863  int i = 0;
1864 #ifdef MOAB_HAVE_MPI
1865  ParallelComm* pco = context.appDatas[*pid].pcomm;
1866 #endif
1867 
1868  for( Range::iterator vit = elems.begin(); vit != elems.end(); vit++, i++ )
1869  {
1870 #ifdef MOAB_HAVE_MPI
1871  MB_CHK_SET_ERR( pco->get_owner( *vit, element_ownership[i] ), "can't get owner" );
1872 #else
1873  element_ownership[i] = 0; /* owned by 0 */
1874 #endif
1875  }
1876 
1877  return moab::MB_SUCCESS;
1878 }

References GlobalContext::appDatas, moab::Range::begin(), context, moab::Range::empty(), moab::Range::end(), moab::Interface::get_entities_by_handle(), moab::ParallelComm::get_owner(), MB_CHK_SET_ERR, MB_SUCCESS, GlobalContext::MBI, and moab::Range::size().

◆ iMOAB_GetGlobalInfo()

ErrCode iMOAB_GetGlobalInfo ( iMOAB_AppID  pid,
int *  num_global_verts,
int *  num_global_elems 
)

Get global information about number of vertices and number of elements.

Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]num_global_verts(int*) The number of total vertices in the mesh.
[in]num_global_elems(MPI_Comm) The number of total elements in the mesh.
Returns
ErrCode The error code indicating success or failure.

Definition at line 3007 of file iMOAB.cpp.

3008 {
3009  appData& data = context.appDatas[*pid];
3010  if( nullptr != num_global_verts )
3011  {
3012  *num_global_verts = data.num_global_vertices;
3013  }
3014  if( nullptr != num_global_elems )
3015  {
3016  *num_global_elems = data.num_global_elements;
3017  }
3018 
3019  return moab::MB_SUCCESS;
3020 }

References GlobalContext::appDatas, context, MB_SUCCESS, appData::num_global_elements, and appData::num_global_vertices.

◆ iMOAB_GetIntTagStorage()

ErrCode iMOAB_GetIntTagStorage ( iMOAB_AppID  pid,
const iMOAB_String  tag_storage_name,
int *  num_tag_storage_length,
int *  entity_type,
int *  tag_storage_data 
)

Get the specified values in a MOAB integer Tag.

Note
Operations: Collective
Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]tag_storage_name(iMOAB_String) The tag name to store/retreive the data in MOAB.
[in]num_tag_storage_length(int*) The size of tag storage data (e.g., num_visible_vertices*components_per_entity or num_visible_elements*components_per_entity).
[in]entity_type(int*) Type=0 for vertices, and Type=1 for primary elements.
[out]tag_storage_data(int*) The array data of type int to be copied from the internal tag memory; The data is assumed to be contiguous over the local set of visible entities (either vertices or elements).
Returns
ErrCode The error code indicating success or failure.

Definition at line 2241 of file iMOAB.cpp.

2246 {
2247  std::string tag_name( tag_storage_name );
2248 
2249  appData& data = context.appDatas[*pid];
2250 
2251  if( data.tagMap.find( tag_name ) == data.tagMap.end() )
2252  {
2253  return moab::MB_FAILURE;
2254  } // tag not defined
2255 
2256  Tag tag = data.tagMap[tag_name];
2257 
2258  int tagLength = 0;
2259  MB_CHK_ERR( context.MBI->tag_get_length( tag, tagLength ) );
2260 
2261  DataType dtype;
2262  MB_CHK_ERR( context.MBI->tag_get_data_type( tag, dtype ) );
2263 
2264  if( dtype != MB_TYPE_INTEGER )
2265  {
2266  MB_CHK_SET_ERR( moab::MB_FAILURE, "The tag is not of integer type." );
2267  }
2268 
2269  // set it on a subset of entities, based on type and length
2270  // if *entity_type = 0, then use vertices; else elements
2271  Range* ents_to_get = ( *ent_type == 0 ? &data.all_verts : &data.primary_elems );
2272  int nents_to_get = *num_tag_storage_length / tagLength;
2273 
2274  if( nents_to_get > (int)ents_to_get->size() )
2275  {
2276  return moab::MB_FAILURE;
2277  } // to many entities to get, or too little
2278 
2279  // now set the tag data
2280  MB_CHK_ERR( context.MBI->tag_get_data( tag, *ents_to_get, tag_storage_data ) );
2281 
2282  return moab::MB_SUCCESS; // no error
2283 }

References appData::all_verts, GlobalContext::appDatas, context, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, MB_TYPE_INTEGER, GlobalContext::MBI, appData::primary_elems, moab::Range::size(), moab::Interface::tag_get_data(), moab::Interface::tag_get_data_type(), moab::Interface::tag_get_length(), and appData::tagMap.

◆ iMOAB_GetNeighborElements()

ErrCode iMOAB_GetNeighborElements ( iMOAB_AppID  pid,
iMOAB_LocalID local_index,
int *  num_adjacent_elements,
iMOAB_LocalID adjacent_element_IDs 
)

Retrieve the adjacencies for the element entities.

Note
Operations: Not Collective
Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]local_index(iMOAB_LocalID*) The local element ID for which adjacency information is needed.
[out]num_adjacent_elements(int*) The total number of adjacent elements.
[out]adjacent_element_IDs(iMOAB_LocalID*) The local element IDs of all adjacent elements to the current one (typically, num_total_sides for internal elements or num_total_sides-num_sides_on_boundary for boundary elements).
Returns
ErrCode The error code indicating success or failure.

Definition at line 2872 of file iMOAB.cpp.

2876 {
2877  assert( local_index && *local_index >= 0 );
2878 
2879  // one neighbor for each subentity of dimension-1
2880  MeshTopoUtil mtu( context.MBI );
2881  appData& data = context.appDatas[*pid];
2882  EntityHandle eh = data.primary_elems[*local_index];
2883  Range adjs;
2884  MB_CHK_SET_ERR( mtu.get_bridge_adjacencies( eh, data.dimension - 1, data.dimension, adjs ),
2885  "Getting bridge adjacencies failed" );
2886 
2887  if( *num_adjacent_elements < (int)adjs.size() )
2888  {
2889  return moab::MB_FAILURE;
2890  } // not dimensioned correctly
2891 
2892  *num_adjacent_elements = (int)adjs.size();
2893 
2894  for( int i = 0; i < *num_adjacent_elements; i++ )
2895  {
2896  adjacent_element_IDs[i] = data.primary_elems.index( adjs[i] );
2897  }
2898 
2899  return moab::MB_SUCCESS;
2900 }

References GlobalContext::appDatas, context, appData::dimension, moab::MeshTopoUtil::get_bridge_adjacencies(), moab::Range::index(), MB_CHK_SET_ERR, MB_SUCCESS, GlobalContext::MBI, appData::primary_elems, and moab::Range::size().

◆ iMOAB_GetNeighborVertices()

ErrCode iMOAB_GetNeighborVertices ( iMOAB_AppID  pid,
iMOAB_LocalID local_vertex_ID,
int *  num_adjacent_vertices,
iMOAB_LocalID adjacent_vertex_IDs 
)

Get the adjacencies for the vertex entities.

Note
Operations: Not Collective
Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]local_vertex_ID(iMOAB_LocalID*) The local vertex ID for which adjacency information is needed.
[out]num_adjacent_vertices(int*) The total number of adjacent vertices.
[out]adjacent_vertex_IDs(iMOAB_LocalID*) The local element IDs of all adjacent vertices to the current one (typically, num_total_sides for internal elements or num_total_sides-num_sides_on_boundary for boundary elements).
Returns
ErrCode The error code indicating success or failure.

◆ iMOAB_GetPointerToSurfaceBC()

ErrCode iMOAB_GetPointerToSurfaceBC ( iMOAB_AppID  pid,
int *  surface_BC_length,
iMOAB_LocalID local_element_ID,
int *  reference_surface_ID,
int *  boundary_condition_value 
)

Get the surface boundary condition information.

Note
Operations: Not Collective
Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]surface_BC_length(int*) The allocated size of surface boundary condition array, same as num_visible_surfaceBC returned by GetMeshInfo().
[out]local_element_ID(iMOAB_LocalID*) The local element IDs that contains the side with the surface BC.
[out]reference_surface_ID(int*) The surface number with the BC in the canonical reference element (e.g., 1 to 6 for HEX, 1-4 for TET).
[out]boundary_condition_value(int*) The boundary condition type as obtained from the mesh description (value of the NeumannSet defined on the element).
Returns
ErrCode The error code indicating success or failure.

Definition at line 1928 of file iMOAB.cpp.

1933 {
1934  // we have to fill bc data for neumann sets;/
1935 
1936  // it was counted above, in GetMeshInfo
1937  appData& data = context.appDatas[*pid];
1938  int numNeuSets = (int)data.neu_sets.size();
1939 
1940  int index = 0; // index [0, surface_BC_length) for the arrays returned
1941 
1942  for( int i = 0; i < numNeuSets; i++ )
1943  {
1944  Range subents;
1945  EntityHandle nset = data.neu_sets[i];
1946  MB_CHK_SET_ERR( context.MBI->get_entities_by_dimension( nset, data.dimension - 1, subents ),
1947  "can't get subentities" );
1948 
1949  int neuVal;
1950  MB_CHK_SET_ERR( context.MBI->tag_get_data( context.neumann_tag, &nset, 1, &neuVal ), "can't get neumann tag" );
1951 
1952  for( Range::iterator it = subents.begin(); it != subents.end(); ++it )
1953  {
1954  EntityHandle subent = *it;
1955  Range adjPrimaryEnts;
1956  MB_CHK_SET_ERR( context.MBI->get_adjacencies( &subent, 1, data.dimension, false, adjPrimaryEnts ),
1957  "can't get adjacencies" );
1958 
1959  // get global id of the primary ents, and side number of the quad/subentity
1960  // this is moab ordering
1961  for( Range::iterator pit = adjPrimaryEnts.begin(); pit != adjPrimaryEnts.end(); pit++ )
1962  {
1963  EntityHandle primaryEnt = *pit;
1964  // get global id
1965  /*int globalID;
1966  rval = context.MBI->tag_get_data(gtags[3], &primaryEnt, 1, &globalID);
1967  if (MB_SUCCESS!=rval)
1968  return moab::MB_FAILURE;
1969  global_element_ID[index] = globalID;*/
1970 
1971  // get local element id
1972  local_element_ID[index] = data.primary_elems.index( primaryEnt );
1973 
1974  if( -1 == local_element_ID[index] )
1975  {
1976  return moab::MB_FAILURE;
1977  } // did not find the element locally
1978 
1979  int side_number, sense, offset;
1980  MB_CHK_SET_ERR( context.MBI->side_number( primaryEnt, subent, side_number, sense, offset ),
1981  "can't get side number" );
1982 
1983  reference_surface_ID[index] = side_number + 1; // moab is from 0 to 5, it needs 1 to 6
1984  boundary_condition_value[index] = neuVal;
1985  index++;
1986  }
1987  }
1988  }
1989 
1990  if( index != *surface_BC_length )
1991  {
1992  return moab::MB_FAILURE;
1993  } // error in array allocations
1994 
1995  return moab::MB_SUCCESS;
1996 }

References GlobalContext::appDatas, moab::Range::begin(), context, appData::dimension, moab::Range::end(), moab::Interface::get_adjacencies(), moab::Interface::get_entities_by_dimension(), moab::index, moab::Range::index(), MB_CHK_SET_ERR, MB_SUCCESS, GlobalContext::MBI, appData::neu_sets, GlobalContext::neumann_tag, appData::primary_elems, moab::Interface::side_number(), moab::side_number(), moab::Range::size(), and moab::Interface::tag_get_data().

◆ iMOAB_GetPointerToVertexBC()

ErrCode iMOAB_GetPointerToVertexBC ( iMOAB_AppID  pid,
int *  vertex_BC_length,
iMOAB_LocalID local_vertex_ID,
int *  boundary_condition_value 
)

Get the vertex boundary condition information.

Note
Operations: Not Collective
Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]vertex_BC_length(int) The allocated size of vertex boundary condition array, same as num_visible_vertexBC returned by GetMeshInfo().
[out]local_vertex_ID(iMOAB_LocalID*) The local vertex ID that has Dirichlet BC defined.
[out]boundary_condition_value(int*) The boundary condition type as obtained from the mesh description (value of the Dirichlet_Set tag defined on the vertex).
Returns
ErrCode The error code indicating success or failure.

Definition at line 1998 of file iMOAB.cpp.

2002 {
2003  // it was counted above, in GetMeshInfo
2004  appData& data = context.appDatas[*pid];
2005  int numDiriSets = (int)data.diri_sets.size();
2006  int index = 0; // index [0, *vertex_BC_length) for the arrays returned
2007 
2008  for( int i = 0; i < numDiriSets; i++ )
2009  {
2010  Range verts;
2011  EntityHandle diset = data.diri_sets[i];
2012  MB_CHK_SET_ERR( context.MBI->get_entities_by_dimension( diset, 0, verts ), "can't get vertices" );
2013 
2014  int diriVal;
2015  MB_CHK_SET_ERR( context.MBI->tag_get_data( context.dirichlet_tag, &diset, 1, &diriVal ),
2016  "can't get dirichlet tag" );
2017 
2018  for( Range::iterator vit = verts.begin(); vit != verts.end(); ++vit )
2019  {
2020  EntityHandle vt = *vit;
2021  /*int vgid;
2022  rval = context.MBI->tag_get_data(gtags[3], &vt, 1, &vgid);
2023  if (MB_SUCCESS!=rval)
2024  return moab::MB_FAILURE;
2025  global_vertext_ID[index] = vgid;*/
2026  local_vertex_ID[index] = data.all_verts.index( vt );
2027 
2028  if( -1 == local_vertex_ID[index] )
2029  {
2030  return moab::MB_FAILURE;
2031  } // vertex was not found
2032 
2033  boundary_condition_value[index] = diriVal;
2034  index++;
2035  }
2036  }
2037 
2038  if( *vertex_BC_length != index )
2039  {
2040  return moab::MB_FAILURE;
2041  } // array allocation issue
2042 
2043  return moab::MB_SUCCESS;
2044 }

References appData::all_verts, GlobalContext::appDatas, moab::Range::begin(), context, appData::diri_sets, GlobalContext::dirichlet_tag, moab::Range::end(), moab::Interface::get_entities_by_dimension(), moab::index, moab::Range::index(), MB_CHK_SET_ERR, MB_SUCCESS, GlobalContext::MBI, moab::Range::size(), and moab::Interface::tag_get_data().

◆ iMOAB_GetVisibleElementsInfo()

ErrCode iMOAB_GetVisibleElementsInfo ( iMOAB_AppID  pid,
int *  num_visible_elements,
iMOAB_GlobalID element_global_IDs,
int *  ranks,
iMOAB_GlobalID block_IDs 
)

Get the visible elements information.

Return for all visible elements the global IDs, ranks they belong to, block ids they belong to.

Note
Operations: Not Collective
Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]num_visible_elements(int*) The number of visible elements (returned by GetMeshInfo).
[out]element_global_IDs(iMOAB_GlobalID*) Element global ids to be added to the block.
[out]ranks(int*) The owning ranks of elements.
[out]block_IDs(iMOAB_GlobalID*) The block ids containing the elements.
Returns
ErrCode The error code indicating success or failure.

Definition at line 1686 of file iMOAB.cpp.

1691 {
1692  appData& data = context.appDatas[*pid];
1693 #ifdef MOAB_HAVE_MPI
1694  ParallelComm* pco = context.appDatas[*pid].pcomm;
1695 #endif
1696 
1697  MB_CHK_SET_ERR( context.MBI->tag_get_data( context.globalID_tag, data.primary_elems, element_global_IDs ),
1698  "can't get global IDs" );
1699 
1700  int i = 0;
1701 
1702  for( Range::iterator eit = data.primary_elems.begin(); eit != data.primary_elems.end(); ++eit, ++i )
1703  {
1704 #ifdef MOAB_HAVE_MPI
1705  MB_CHK_SET_ERR( pco->get_owner( *eit, ranks[i] ), "can't get owner" );
1706 
1707 #else
1708  /* everything owned by task 0 */
1709  ranks[i] = 0;
1710 #endif
1711  }
1712 
1713  for( Range::iterator mit = data.mat_sets.begin(); mit != data.mat_sets.end(); ++mit )
1714  {
1715  EntityHandle matMeshSet = *mit;
1716  Range elems;
1717  MB_CHK_SET_ERR( context.MBI->get_entities_by_handle( matMeshSet, elems ), "can't get block elements" );
1718 
1719  int valMatTag;
1720  MB_CHK_SET_ERR( context.MBI->tag_get_data( context.material_tag, &matMeshSet, 1, &valMatTag ),
1721  "can't get material tag" );
1722 
1723  for( Range::iterator eit = elems.begin(); eit != elems.end(); ++eit )
1724  {
1725  EntityHandle eh = *eit;
1726  int index = data.primary_elems.index( eh );
1727 
1728  if( -1 == index )
1729  {
1730  return moab::MB_FAILURE;
1731  }
1732 
1733  if( -1 >= *num_visible_elements )
1734  {
1735  return moab::MB_FAILURE;
1736  }
1737 
1738  block_IDs[index] = valMatTag;
1739  }
1740  }
1741 
1742  return moab::MB_SUCCESS;
1743 }

References GlobalContext::appDatas, moab::Range::begin(), context, moab::Range::end(), moab::Interface::get_entities_by_handle(), moab::ParallelComm::get_owner(), GlobalContext::globalID_tag, moab::index, moab::Range::index(), appData::mat_sets, GlobalContext::material_tag, MB_CHK_SET_ERR, MB_SUCCESS, GlobalContext::MBI, appData::primary_elems, and moab::Interface::tag_get_data().

◆ iMOAB_ReduceTagsMax()

ErrCode iMOAB_ReduceTagsMax ( iMOAB_AppID  pid,
int *  tag_index,
int *  ent_type 
)

Perform global reductions with the processes in the current applications communicator. Specifically this routine performs reductions on the maximum value of the tag indicated by tag_index.

Note
Operations: Collective
Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]tag_index(int*) The tag index of interest.
[in]ent_type(int*) The type of entity for tag reduction operation (vertices = 0, elements = 1)
Returns
ErrCode The error code indicating success or failure.

Definition at line 2833 of file iMOAB.cpp.

2834 {
2835 #ifdef MOAB_HAVE_MPI
2836  appData& data = context.appDatas[*pid];
2837  Range ent_exchange;
2838 
2839  if( *tag_index < 0 || *tag_index >= (int)data.tagList.size() )
2840  {
2841  return moab::MB_FAILURE;
2842  } // error in tag index
2843 
2844  Tag tagh = data.tagList[*tag_index];
2845 
2846  if( *ent_type == 0 )
2847  {
2848  ent_exchange = data.all_verts;
2849  }
2850  else if( *ent_type == 1 )
2851  {
2852  ent_exchange = data.primary_elems;
2853  }
2854  else
2855  {
2856  return moab::MB_FAILURE;
2857  } // unexpected type
2858 
2859  ParallelComm* pco = context.appDatas[*pid].pcomm;
2860  // we could do different MPI_Op; do not bother now, we will call from fortran
2861  MB_CHK_ERR( pco->reduce_tags( tagh, MPI_MAX, ent_exchange ) );
2862 
2863 #else
2864  /* do nothing if serial */
2865  UNUSED( pid );
2866  UNUSED( tag_index );
2867  UNUSED( ent_type );
2868 #endif
2869  return moab::MB_SUCCESS;
2870 }

References appData::all_verts, GlobalContext::appDatas, context, MB_CHK_ERR, MB_SUCCESS, appData::primary_elems, moab::ParallelComm::reduce_tags(), appData::tagList, and UNUSED.

◆ iMOAB_RegisterApplication()

ErrCode iMOAB_RegisterApplication ( const iMOAB_String  app_name,
int *  compid,
iMOAB_AppID  pid 
)

Register application - Create a unique application ID and bootstrap interfaces for further queries.

Note
Internally, a mesh set will be associated with the application ID and all subsequent queries on the MOAB instance will be directed to this mesh/file set.

Operations: Collective

Parameters
[in]app_name(iMOAB_String) Application name (PROTEUS, NEK5000, etc)
[in]comm(MPI_Comm*) MPI communicator to be used for all mesh-related queries originating from this application
[in]compid(int*) The unique external component identifier
[out]pid(iMOAB_AppID) The unique pointer to the application ID
Returns
ErrCode The error code indicating success or failure.

◆ iMOAB_RegisterApplicationFortran()

ErrCode iMOAB_RegisterApplicationFortran ( const iMOAB_String  app_name,
int *  compid,
iMOAB_AppID  pid 
)

Register a Fortran-based application - Create a unique application ID and bootstrap interfaces for further queries.

Note
Internally, the comm object, usually a 32 bit integer in Fortran, will be converted using MPI_Comm_f2c and stored as MPI_Comm. A mesh set will be associated with the application ID and all subsequent queries on the MOAB instance will be directed to this mesh/file set.

Operations: Collective

Parameters
[in]app_name(iMOAB_String) Application name ("MySolver", "E3SM", "DMMoab", "PROTEUS", "NEK5000", etc)
[in]communicator(int*) Fortran MPI communicator to be used for all mesh-related queries originating from this application.
[in]compid(int*) External component id, (A const unique identifier).
[out]pid(iMOAB_AppID) The unique pointer to the application ID.
Returns
ErrCode The error code indicating success or failure.

◆ iMOAB_ResolveSharedEntities()

ErrCode iMOAB_ResolveSharedEntities ( iMOAB_AppID  pid,
int *  num_verts,
int *  marker 
)

Resolve shared entities using global markers on shared vertices.

Note
Global markers can be a global node id, for example, or a global DoF number (as for HOMME)

Operations: Collective .

Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]num_verts(int*) Number of vertices.
[in]marker(int*) Resolving marker (global id marker).
Returns
ErrCode The error code indicating success or failure.

Definition at line 3025 of file iMOAB.cpp.

3026 {
3027  appData& data = context.appDatas[*pid];
3028  ParallelComm* pco = context.appDatas[*pid].pcomm;
3029  EntityHandle cset = data.file_set;
3030  int dum_id = 0;
3031  ErrorCode rval;
3032  if( data.primary_elems.empty() )
3033  {
3034  // skip actual resolve, assume vertices are distributed already ,
3035  // no need to share them
3036  }
3037  else
3038  {
3039  // create an integer tag for resolving ; maybe it can be a long tag in the future
3040  // (more than 2 B vertices;)
3041 
3042  Tag stag;
3043  MB_CHK_ERR( context.MBI->tag_get_handle( "__sharedmarker", 1, MB_TYPE_INTEGER, stag,
3044  MB_TAG_CREAT | MB_TAG_DENSE, &dum_id ) );
3045 
3046  if( *num_verts > (int)data.local_verts.size() )
3047  {
3048  return moab::MB_FAILURE;
3049  } // we are not setting the size
3050 
3051  MB_CHK_ERR( context.MBI->tag_set_data( stag, data.local_verts, (void*)marker ) ); // assumes integer tag
3052 
3053  MB_CHK_ERR( pco->resolve_shared_ents( cset, -1, -1, &stag ) );
3054 
3055  MB_CHK_ERR( context.MBI->tag_delete( stag ) );
3056  }
3057  // provide partition tag equal to rank
3058  Tag part_tag;
3059  dum_id = -1;
3060  rval = context.MBI->tag_get_handle( "PARALLEL_PARTITION", 1, MB_TYPE_INTEGER, part_tag,
3061  MB_TAG_CREAT | MB_TAG_SPARSE, &dum_id );
3062 
3063  if( part_tag == nullptr || ( ( rval != MB_SUCCESS ) && ( rval != MB_ALREADY_ALLOCATED ) ) )
3064  {
3065  std::cout << " can't get par part tag.\n";
3066  return moab::MB_FAILURE;
3067  }
3068 
3069  int rank = pco->rank();
3070  MB_CHK_ERR( context.MBI->tag_set_data( part_tag, &cset, 1, &rank ) );
3071 
3072  return moab::MB_SUCCESS;
3073 }

References GlobalContext::appDatas, context, moab::Range::empty(), ErrorCode, appData::file_set, appData::local_verts, MB_ALREADY_ALLOCATED, MB_CHK_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TAG_SPARSE, MB_TYPE_INTEGER, GlobalContext::MBI, appData::primary_elems, moab::ParallelComm::rank(), moab::ParallelComm::resolve_shared_ents(), moab::Range::size(), moab::Interface::tag_delete(), moab::Interface::tag_get_handle(), and moab::Interface::tag_set_data().

◆ iMOAB_SetDoubleTagStorage()

ErrCode iMOAB_SetDoubleTagStorage ( iMOAB_AppID  pid,
const iMOAB_String  tag_storage_name,
int *  num_tag_storage_length,
int *  entity_type,
double *  tag_storage_data 
)

Store the specified values in a MOAB double Tag.

Note
Operations: Collective
Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]tag_storage_name(iMOAB_String) The tag names, separated, to store the data.
[in]num_tag_storage_length(int*) The size of total tag storage data (e.g., num_visible_vertices*components_per_entity or num_visible_elements*components_per_entity*num_tags).
[in]entity_type(int*) Type=0 for vertices, and Type=1 for primary elements.
[out]tag_storage_data(double*) The array data of type double to replace the internal tag memory; The data is assumed to be contiguous over the local set of visible entities (either vertices or elements). unrolled by tags
Returns
ErrCode The error code indicating success or failure.

Definition at line 2285 of file iMOAB.cpp.

2290 {
2291  std::string tag_names( tag_storage_names );
2292  // exactly the same code as for int tag :) maybe should check the type of tag too
2293  std::vector< std::string > tagNames;
2294  std::vector< Tag > tagHandles;
2295  std::string separator( ":" );
2296  split_tag_names( tag_names, separator, tagNames );
2297 
2298  appData& data = context.appDatas[*pid];
2299  // set it on a subset of entities, based on type and length
2300  // if *entity_type = 0, then use vertices; else elements
2301  Range* ents_to_set = ( *ent_type == 0 ? &data.all_verts : &data.primary_elems );
2302 
2303  int nents_to_be_set = (int)( *ents_to_set ).size();
2304  int position = 0;
2305  for( size_t i = 0; i < tagNames.size(); i++ )
2306  {
2307  if( data.tagMap.find( tagNames[i] ) == data.tagMap.end() )
2308  {
2309  return moab::MB_FAILURE;
2310  } // some tag not defined yet in the app
2311 
2312  Tag tag = data.tagMap[tagNames[i]];
2313 
2314  int tagLength = 0;
2315  MB_CHK_ERR( context.MBI->tag_get_length( tag, tagLength ) );
2316 
2317  DataType dtype;
2318  MB_CHK_ERR( context.MBI->tag_get_data_type( tag, dtype ) );
2319 
2320  if( dtype != MB_TYPE_DOUBLE )
2321  {
2322  return moab::MB_FAILURE;
2323  }
2324 
2325  // set it on the subset of entities, based on type and length
2326  if( position + tagLength * nents_to_be_set > *num_tag_storage_length )
2327  return moab::MB_FAILURE; // too many entity values to be set
2328 
2329  MB_CHK_ERR( context.MBI->tag_set_data( tag, *ents_to_set, &tag_storage_data[position] ) );
2330  // increment position to next tag
2331  position = position + tagLength * nents_to_be_set;
2332  }
2333  return moab::MB_SUCCESS; // no error
2334 }

References appData::all_verts, GlobalContext::appDatas, context, MB_CHK_ERR, MB_SUCCESS, MB_TYPE_DOUBLE, GlobalContext::MBI, appData::primary_elems, moab::Range::size(), split_tag_names(), moab::Interface::tag_get_data_type(), moab::Interface::tag_get_length(), moab::Interface::tag_set_data(), and appData::tagMap.

◆ iMOAB_SetDoubleTagStorageWithGid()

ErrCode iMOAB_SetDoubleTagStorageWithGid ( iMOAB_AppID  pid,
const iMOAB_String  tag_storage_names,
int *  num_tag_storage_length,
int *  entity_type,
double *  tag_storage_data,
int *  globalIds 
)

Store the specified values in a MOAB double Tag, for given ids.

Note
Operations: Collective
Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]tag_storage_name(iMOAB_String) The tag names, separated, to store the data.
[in]num_tag_storage_length(int*) The size of total tag storage data (e.g., num_visible_vertices*components_per_entity or num_visible_elements*components_per_entity*num_tags).
[in]entity_type(int*) Type=0 for vertices, and Type=1 for primary elements.
[in]tag_storage_data(double*) The array data of type double to replace the internal tag memory; The data is assumed to be permuted over the local set of visible entities (either vertices or elements). unrolled by tags in parallel, might be different order, or different entities on the task
[in]globalIdsglobal ids of the cells to be set;
Returns
ErrCode The error code indicating success or failure.

Definition at line 2336 of file iMOAB.cpp.

2342 {
2343  std::string tag_names( tag_storage_names );
2344  // exactly the same code as for int tag :) maybe should check the type of tag too
2345  std::vector< std::string > tagNames;
2346  std::vector< Tag > tagHandles;
2347  std::string separator( ":" );
2348  split_tag_names( tag_names, separator, tagNames );
2349 
2350  appData& data = context.appDatas[*pid];
2351  // set it on a subset of entities, based on type and length
2352  // if *entity_type = 0, then use vertices; else elements
2353  Range* ents_to_set = ( *ent_type == 0 ? &data.all_verts : &data.primary_elems );
2354  int nents_to_be_set = (int)( *ents_to_set ).size();
2355 
2356  Tag gidTag = context.MBI->globalId_tag();
2357  std::vector< int > gids;
2358  gids.resize( nents_to_be_set );
2359  MB_CHK_ERR( context.MBI->tag_get_data( gidTag, *ents_to_set, &gids[0] ) );
2360 
2361  // so we will need to set the tags according to the global id passed;
2362  // so the order in tag_storage_data is the same as the order in globalIds, but the order
2363  // in local range is gids
2364  std::map< int, EntityHandle > eh_by_gid;
2365  int i = 0;
2366  for( Range::iterator it = ents_to_set->begin(); it != ents_to_set->end(); ++it, ++i )
2367  {
2368  eh_by_gid[gids[i]] = *it;
2369  }
2370 
2371  /// @todo Allow for tags of different length
2372  size_t nbLocalVals = *num_tag_storage_length / tagNames.size(); // assumes all tags have the same length?
2373 
2374  // check global ids to have different values
2375  std::set< int > globalIdsSet( globalIds, globalIds + nbLocalVals );
2376  if( globalIdsSet.size() < nbLocalVals )
2377  {
2378  std::cout << "iMOAB_SetDoubleTagStorageWithGid: for pid:" << *pid << " tags[0]:" << tagNames[0]
2379  << " global ids passed are not unique, major error\n";
2380  std::cout << " nbLocalVals:" << nbLocalVals << " globalIdsSet.size():" << globalIdsSet.size()
2381  << " first global id:" << globalIds[0] << "\n";
2382  return moab::MB_FAILURE;
2383  }
2384 
2385  std::vector< int > tagLengths( tagNames.size() );
2386  std::vector< Tag > tagList;
2387 #ifdef MOAB_HAVE_MPI
2388  size_t total_tag_len = 0;
2389 #endif
2390  for( size_t i = 0; i < tagNames.size(); i++ )
2391  {
2392  if( data.tagMap.find( tagNames[i] ) == data.tagMap.end() )
2393  {
2394  MB_SET_ERR( moab::MB_FAILURE, "tag missing" );
2395  } // some tag not defined yet in the app
2396 
2397  Tag tag = data.tagMap[tagNames[i]];
2398  tagList.push_back( tag );
2399 
2400  int tagLength = 0;
2401  MB_CHK_ERR( context.MBI->tag_get_length( tag, tagLength ) );
2402 
2403 #ifdef MOAB_HAVE_MPI
2404  total_tag_len += tagLength;
2405 #endif
2406  tagLengths[i] = tagLength;
2407  DataType dtype;
2408  MB_CHK_ERR( context.MBI->tag_get_data_type( tag, dtype ) );
2409 
2410  if( dtype != MB_TYPE_DOUBLE )
2411  {
2412  MB_SET_ERR( moab::MB_FAILURE, "tag not double type" );
2413  }
2414  }
2415  bool serial = true;
2416 #ifdef MOAB_HAVE_MPI
2417  ParallelComm* pco = context.appDatas[*pid].pcomm;
2418  unsigned num_procs = pco->size();
2419  if( num_procs > 1 ) serial = false;
2420 #endif
2421 
2422  if( serial )
2423  {
2424  // we do not assume anymore that the number of entities has to match
2425  // we will set only what matches, and skip entities that do not have corresponding global ids
2426  //assert( total_tag_len * nents_to_be_set - *num_tag_storage_length == 0 );
2427  // tags are unrolled, we loop over global ids first, then careful about tags
2428  for( int i = 0; i < nents_to_be_set; i++ )
2429  {
2430  int gid = globalIds[i];
2431  std::map< int, EntityHandle >::iterator mapIt = eh_by_gid.find( gid );
2432  if( mapIt == eh_by_gid.end() ) continue;
2433  EntityHandle eh = mapIt->second;
2434  // now loop over tags
2435  int indexInTagValues = 0; //
2436  for( size_t j = 0; j < tagList.size(); j++ )
2437  {
2438  indexInTagValues += i * tagLengths[j];
2439  MB_CHK_ERR( context.MBI->tag_set_data( tagList[j], &eh, 1, &tag_storage_data[indexInTagValues] ) );
2440  // advance the pointer/index
2441  indexInTagValues += ( nents_to_be_set - i ) * tagLengths[j]; // at the end of tag data
2442  }
2443  }
2444  }
2445 #ifdef MOAB_HAVE_MPI
2446  else // it can be not serial only if pco->size() > 1, parallel
2447  {
2448  // in this case, we have to use 2 crystal routers, to send data to the processor that needs it
2449  // we will create first a tuple to rendevous points, then from there send to the processor that requested it
2450  // it is a 2-hop global gather scatter
2451  // we do not expect the sizes to match
2452  //assert( nbLocalVals * tagNames.size() - *num_tag_storage_length == 0 );
2453  TupleList TLsend;
2454  TLsend.initialize( 2, 0, 0, total_tag_len, nbLocalVals ); // to proc, marker(gid), total_tag_len doubles
2455  TLsend.enableWriteAccess();
2456  // the processor id that processes global_id is global_id / num_ents_per_proc
2457 
2458  int indexInRealLocal = 0;
2459  for( size_t i = 0; i < nbLocalVals; i++ )
2460  {
2461  // to proc, marker, element local index, index in el
2462  int marker = globalIds[i];
2463  int to_proc = marker % num_procs;
2464  int n = TLsend.get_n();
2465  TLsend.vi_wr[2 * n] = to_proc; // send to processor
2466  TLsend.vi_wr[2 * n + 1] = marker;
2467  int indexInTagValues = 0;
2468  // tag data collect by number of tags
2469  for( size_t j = 0; j < tagList.size(); j++ )
2470  {
2471  indexInTagValues += i * tagLengths[j];
2472  for( int k = 0; k < tagLengths[j]; k++ )
2473  {
2474  TLsend.vr_wr[indexInRealLocal++] = tag_storage_data[indexInTagValues + k];
2475  }
2476  indexInTagValues += ( nbLocalVals - i ) * tagLengths[j];
2477  }
2478  TLsend.inc_n();
2479  }
2480 
2481  //assert( nbLocalVals * total_tag_len - indexInRealLocal == 0 );
2482  // send now requests, basically inform the rendez-vous point who needs a particular global id
2483  // send the data to the other processors:
2484  ( pco->proc_config().crystal_router() )->gs_transfer( 1, TLsend, 0 );
2485  TupleList TLreq;
2486  TLreq.initialize( 2, 0, 0, 0, nents_to_be_set );
2487  TLreq.enableWriteAccess();
2488  for( int i = 0; i < nents_to_be_set; i++ )
2489  {
2490  // to proc, marker
2491  int marker = gids[i];
2492  int to_proc = marker % num_procs;
2493  int n = TLreq.get_n();
2494  TLreq.vi_wr[2 * n] = to_proc; // send to processor
2495  TLreq.vi_wr[2 * n + 1] = marker;
2496  // tag data collect by number of tags
2497  TLreq.inc_n();
2498  }
2499 
2500  // perform communication with crystal router
2501  pco->proc_config().crystal_router()->gs_transfer( 1, TLreq, 0 );
2502 
2503  // we know now that process TLreq.vi_wr[2 * n] needs tags for gid TLreq.vi_wr[2 * n + 1]
2504  // we should first order by global id, and then build the new TL with send to proc, global id and
2505  // tags for it
2506  // sort by global ids the tuple lists
2507  moab::TupleList::buffer sort_buffer;
2508  sort_buffer.buffer_init( TLreq.get_n() );
2509  TLreq.sort( 1, &sort_buffer );
2510  sort_buffer.reset();
2511  sort_buffer.buffer_init( TLsend.get_n() );
2512  TLsend.sort( 1, &sort_buffer );
2513  sort_buffer.reset();
2514  // now send the tag values to the proc that requested it
2515  // in theory, for a full partition, TLreq and TLsend should have the same size, and
2516  // each dof should have exactly one target proc. Is that true or not in general ?
2517  // how do we plan to use this? Is it better to store the comm graph for future
2518 
2519  // start copy from comm graph settle
2520  TupleList TLBack;
2521  TLBack.initialize( 3, 0, 0, total_tag_len, 0 ); // to proc, marker, tag from proc , tag values
2522  TLBack.enableWriteAccess();
2523 
2524  int n1 = TLreq.get_n();
2525  int n2 = TLsend.get_n();
2526 
2527  int indexInTLreq = 0;
2528  int indexInTLsend = 0; // advance both, according to the marker
2529  if( n1 > 0 && n2 > 0 )
2530  {
2531 
2532  while( indexInTLreq < n1 && indexInTLsend < n2 ) // if any is over, we are done
2533  {
2534  int currentValue1 = TLreq.vi_rd[2 * indexInTLreq + 1];
2535  int currentValue2 = TLsend.vi_rd[2 * indexInTLsend + 1];
2536  if( currentValue1 < currentValue2 )
2537  {
2538  // we have a big problem; basically, we are saying that
2539  // dof currentValue is on one model and not on the other
2540  indexInTLreq++;
2541  continue;
2542  }
2543 
2544  if( currentValue1 > currentValue2 )
2545  {
2546  indexInTLsend++;
2547  continue;
2548  }
2549 
2550  int size1 = 1;
2551  while( indexInTLreq + size1 < n1 && currentValue1 == TLreq.vi_rd[2 * ( indexInTLreq + size1 ) + 1] )
2552  size1++;
2553  int size2 = 1;
2554  while( indexInTLsend + size2 < n2 && currentValue2 == TLsend.vi_rd[2 * ( indexInTLsend + size2 ) + 1] )
2555  size2++;
2556 
2557  // must be found in both lists, find the start and end indices
2558  for( int i1 = 0; i1 < size1; i1++ )
2559  {
2560  for( int i2 = 0; i2 < size2; i2++ )
2561  {
2562  // send the info back to components
2563  int n = TLBack.get_n();
2564  TLBack.reserve();
2565  TLBack.vi_wr[3 * n] = TLreq.vi_rd[2 * ( indexInTLreq + i1 )]; // send back to the proc marker
2566  // came from, info from comp2
2567  TLBack.vi_wr[3 * n + 1] = currentValue1; // initial value (resend, just for verif ?)
2568  TLBack.vi_wr[3 * n + 2] = TLsend.vi_rd[2 * ( indexInTLsend + i2 )]; // from proc on comp2
2569  // also fill tag values
2570  for( size_t k = 0; k < total_tag_len; k++ )
2571  {
2572  TLBack.vr_rd[total_tag_len * n + k] =
2573  TLsend.vr_rd[total_tag_len * indexInTLsend + k]; // deep copy of tag values
2574  }
2575  }
2576  }
2577  indexInTLreq += size1;
2578  indexInTLsend += size2;
2579  }
2580  }
2581 
2582  // invoke crystal router
2583  pco->proc_config().crystal_router()->gs_transfer( 1, TLBack, 0 );
2584 
2585  // end copy from comm graph
2586  // after we are done sending, we need to set those tag values, in a reverse process compared to send
2587  n1 = TLBack.get_n();
2588  double* ptrVal = &TLBack.vr_rd[0]; //
2589  for( int i = 0; i < n1; i++ )
2590  {
2591  const int gid = TLBack.vi_rd[3 * i + 1]; // marker
2592  const auto mapIt = eh_by_gid.find( gid );
2593  if( mapIt == eh_by_gid.end() ) continue;
2594 
2595  EntityHandle eh = mapIt->second;
2596  // now loop over tags
2597  for( size_t j = 0; j < tagList.size(); j++ )
2598  {
2599  MB_CHK_ERR( context.MBI->tag_set_data( tagList[j], &eh, 1, (void*)ptrVal ) );
2600  // advance the pointer/index
2601  ptrVal += tagLengths[j]; // at the end of tag data per call
2602  }
2603  }
2604  }
2605 #endif
2606  return MB_SUCCESS;
2607 }

References appData::all_verts, GlobalContext::appDatas, moab::Range::begin(), context, moab::ProcConfig::crystal_router(), moab::TupleList::enableWriteAccess(), moab::Range::end(), moab::TupleList::get_n(), moab::Interface::globalId_tag(), moab::TupleList::inc_n(), moab::TupleList::initialize(), MB_CHK_ERR, MB_SET_ERR, MB_SUCCESS, MB_TYPE_DOUBLE, GlobalContext::MBI, appData::primary_elems, moab::ParallelComm::proc_config(), moab::TupleList::reserve(), moab::TupleList::buffer::reset(), moab::Range::size(), moab::ParallelComm::size(), moab::TupleList::sort(), split_tag_names(), moab::Interface::tag_get_data(), moab::Interface::tag_get_data_type(), moab::Interface::tag_get_length(), moab::Interface::tag_set_data(), appData::tagMap, moab::TupleList::vi_rd, moab::TupleList::vi_wr, moab::TupleList::vr_rd, and moab::TupleList::vr_wr.

◆ iMOAB_SetGlobalInfo()

ErrCode iMOAB_SetGlobalInfo ( iMOAB_AppID  pid,
int *  num_global_verts,
int *  num_global_elems 
)

Set global information for number of vertices and number of elements; It is usually available from the h5m file, or it can be computed with a MPI_Reduce.

Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]num_global_verts(int*) The number of total vertices in the mesh.
[in]num_global_elems(MPI_Comm) The number of total elements in the mesh.
Returns
ErrCode The error code indicating success or failure.

Definition at line 2999 of file iMOAB.cpp.

3000 {
3001  appData& data = context.appDatas[*pid];
3002  data.num_global_vertices = *num_global_verts;
3003  data.num_global_elements = *num_global_elems;
3004  return moab::MB_SUCCESS;
3005 }

References GlobalContext::appDatas, context, MB_SUCCESS, appData::num_global_elements, and appData::num_global_vertices.

Referenced by iMOAB_UpdateMeshInfo().

◆ iMOAB_SetIntTagStorage()

ErrCode iMOAB_SetIntTagStorage ( iMOAB_AppID  pid,
const iMOAB_String  tag_storage_name,
int *  num_tag_storage_length,
int *  entity_type,
int *  tag_storage_data 
)

Store the specified values in a MOAB integer Tag.

Values are set on vertices or elements, depending on entity_type

Note
we could change the api to accept as input the tag index, as returned by iMOAB_DefineTagStorage.

Operations: Collective

Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]tag_storage_name(iMOAB_String) The tag name to store/retreive the data in MOAB.
[in]num_tag_storage_length(int*) The size of tag storage data (e.g., num_visible_vertices*components_per_entity or num_visible_elements*components_per_entity).
[in]entity_type(int*) Type=0 for vertices, and Type=1 for primary elements.
[out]tag_storage_data(int*) The array data of type int to replace the internal tag memory; The data is assumed to be contiguous over the local set of visible entities (either vertices or elements).
Returns
ErrCode The error code indicating success or failure.

Definition at line 2199 of file iMOAB.cpp.

2204 {
2205  std::string tag_name( tag_storage_name );
2206 
2207  // Get the application data
2208  appData& data = context.appDatas[*pid];
2209  // check if tag is defined
2210  if( data.tagMap.find( tag_name ) == data.tagMap.end() ) return moab::MB_FAILURE;
2211 
2212  Tag tag = data.tagMap[tag_name];
2213 
2214  int tagLength = 0;
2215  MB_CHK_ERR( context.MBI->tag_get_length( tag, tagLength ) );
2216 
2217  DataType dtype;
2218  MB_CHK_ERR( context.MBI->tag_get_data_type( tag, dtype ) );
2219 
2220  if( dtype != MB_TYPE_INTEGER )
2221  {
2222  MB_CHK_SET_ERR( moab::MB_FAILURE, "The tag is not of integer type." );
2223  }
2224 
2225  // set it on a subset of entities, based on type and length
2226  // if *entity_type = 0, then use vertices; else elements
2227  Range* ents_to_set = ( *ent_type == 0 ? &data.all_verts : &data.primary_elems );
2228  int nents_to_be_set = *num_tag_storage_length / tagLength;
2229 
2230  if( nents_to_be_set > (int)ents_to_set->size() )
2231  {
2232  return moab::MB_FAILURE;
2233  } // to many entities to be set or too few
2234 
2235  // now set the tag data
2236  MB_CHK_ERR( context.MBI->tag_set_data( tag, *ents_to_set, tag_storage_data ) );
2237 
2238  return moab::MB_SUCCESS; // no error
2239 }

References appData::all_verts, GlobalContext::appDatas, context, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, MB_TYPE_INTEGER, GlobalContext::MBI, appData::primary_elems, moab::Range::size(), moab::Interface::tag_get_data_type(), moab::Interface::tag_get_length(), moab::Interface::tag_set_data(), and appData::tagMap.

◆ iMOAB_SynchronizeTags()

ErrCode iMOAB_SynchronizeTags ( iMOAB_AppID  pid,
int *  num_tag,
int *  tag_indices,
int *  ent_type 
)

Exchange tag values for the given tags across process boundaries.

Note
Operations: Collective
Parameters
[in]pid(iMOAB_AppID) The unique pointer to the application ID.
[in]num_tags(int*) Number of tags to exchange.
[in]tag_indices(int*) Array with tag indices of interest (size = *num_tags).
[in]ent_type(int*) The type of entity for tag exchange.
Returns
ErrCode The error code indicating success or failure.

Definition at line 2788 of file iMOAB.cpp.

2789 {
2790 #ifdef MOAB_HAVE_MPI
2791  appData& data = context.appDatas[*pid];
2792  Range ent_exchange;
2793  std::vector< Tag > tags;
2794 
2795  for( int i = 0; i < *num_tag; i++ )
2796  {
2797  if( tag_indices[i] < 0 || tag_indices[i] >= (int)data.tagList.size() )
2798  {
2799  return moab::MB_FAILURE;
2800  } // error in tag index
2801 
2802  tags.push_back( data.tagList[tag_indices[i]] );
2803  }
2804 
2805  if( *ent_type == 0 )
2806  {
2807  ent_exchange = data.all_verts;
2808  }
2809  else if( *ent_type == 1 )
2810  {
2811  ent_exchange = data.primary_elems;
2812  }
2813  else
2814  {
2815  return moab::MB_FAILURE;
2816  } // unexpected type
2817 
2818  ParallelComm* pco = context.appDatas[*pid].pcomm;
2819 
2820  MB_CHK_ERR( pco->exchange_tags( tags, tags, ent_exchange ) );
2821 
2822 #else
2823  /* do nothing if serial */
2824  UNUSED( pid );
2825  UNUSED( num_tag );
2826  UNUSED( tag_indices );
2827  UNUSED( ent_type );
2828 #endif
2829 
2830  return moab::MB_SUCCESS;
2831 }

References appData::all_verts, GlobalContext::appDatas, context, moab::ParallelComm::exchange_tags(), MB_CHK_ERR, MB_SUCCESS, appData::primary_elems, appData::tagList, and UNUSED.