Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
moab::ScdInterface Class Reference

A structured mesh interface for MOAB-based data. More...

#include "moab/ScdInterface.hpp"

+ Collaboration diagram for moab::ScdInterface:

Public Member Functions

 ScdInterface (Interface *impl, bool find_boxes=false)
 Constructor. More...
 
 ~ScdInterface ()
 
Interfaceimpl () const
 Return the MOAB Interface instance *. More...
 
ErrorCode construct_box (HomCoord low, HomCoord high, const double *const coords, unsigned int num_coords, ScdBox *&new_box, int *const lperiodic=NULL, ScdParData *const par_data=NULL, bool assign_global_ids=false, int resolve_shared_ents=-1)
 Construct new structured mesh box, including both vertices and elements. More...
 
ErrorCode create_scd_sequence (const HomCoord &low, const HomCoord &high, EntityType type, int starting_id, ScdBox *&new_box, int *is_periodic=NULL)
 Create a structured sequence of vertices, quads, or hexes. More...
 
ErrorCode find_boxes (std::vector< ScdBox * > &boxes)
 Return all the structured mesh blocks in this MOAB instance, as ScdBox objects. More...
 
ErrorCode find_boxes (Range &boxes)
 Return all the structured mesh blocks in this MOAB instance, as entity set handles. More...
 
ErrorCode get_boxes (std::vector< ScdBox * > &boxes)
 Return all the structured mesh blocks known by ScdInterface (does not search) More...
 
Tag box_dims_tag (bool create_if_missing=true)
 Return the tag marking the lower and upper corners of boxes. More...
 
Tag global_box_dims_tag (bool create_if_missing=true)
 Return the tag marking the global lower and upper corners of boxes. More...
 
Tag part_method_tag (bool create_if_missing=true)
 Return the tag marking the partitioning method used to partition the box in parallel. More...
 
Tag box_periodic_tag (bool create_if_missing=true)
 Return the tag marking whether box is periodic in i and j. More...
 
Tag box_set_tag (bool create_if_missing=true)
 Return the tag marking the ScdBox for a set. More...
 
ScdBoxget_scd_box (EntityHandle eh)
 Return the ScdBox corresponding to the entity set passed in. More...
 
ErrorCode tag_shared_vertices (ParallelComm *pcomm, EntityHandle seth)
 Tag vertices with sharing data for parallel representations. More...
 
ErrorCode tag_shared_vertices (ParallelComm *pcomm, ScdBox *box)
 Tag vertices with sharing data for parallel representations. More...
 

Static Public Member Functions

static ErrorCode compute_partition (int np, int nr, const ScdParData &par_data, int *ldims, int *lperiodic=NULL, int *pdims=NULL)
 Compute a partition of structured parameter space. More...
 
static ErrorCode get_neighbor (int np, int nr, const ScdParData &spd, const int *const dijk, int &pto, int *rdims, int *facedims, int *across_bdy)
 Get information about the neighbor in the dijk[] direction, where dijk can be -1 or 1 for all 3 params. More...
 

Protected Member Functions

ErrorCode remove_box (ScdBox *box)
 Remove the box from the list on ScdInterface. More...
 
ErrorCode add_box (ScdBox *box)
 Add the box to the list on ScdInterface. More...
 

Private Member Functions

ErrorCode create_box_set (const HomCoord &low, const HomCoord &high, EntityHandle &scd_set, int *is_periodic=NULL)
 Create an entity set for a box, and tag with the parameters. More...
 
ErrorCode assign_global_ids (ScdBox *box)
 assign global ids to vertices in this box More...
 

Static Private Member Functions

static ErrorCode compute_partition_alljorkori (int np, int nr, const int gijk[6], const int *const gperiodic, int *lijk, int *lperiodic, int *pijk)
 Compute a partition of structured parameter space. More...
 
static ErrorCode compute_partition_alljkbal (int np, int nr, const int gijk[6], const int *const gperiodic, int *lijk, int *lperiodic, int *pijk)
 Compute a partition of structured parameter space. More...
 
static ErrorCode compute_partition_sqij (int np, int nr, const int gijk[6], const int *const gperiodic, int *lijk, int *lperiodic, int *pijk)
 Compute a partition of structured parameter space. More...
 
static ErrorCode compute_partition_sqjk (int np, int nr, const int gijk[6], const int *const gperiodic, int *lijk, int *lperiodic, int *pijk)
 Compute a partition of structured parameter space. More...
 
static ErrorCode compute_partition_sqijk (int np, int nr, const int gijk[6], const int *const gperiodic, int *lijk, int *lperiodic, int *pijk)
 Compute a partition of structured parameter space. More...
 
static ErrorCode get_shared_vertices (ParallelComm *pcomm, ScdBox *box, std::vector< int > &procs, std::vector< int > &offsets, std::vector< int > &shared_indices)
 Get vertices shared with other processors. More...
 
static ErrorCode get_indices (const int *const ldims, const int *const rdims, const int *const across_bdy, int *face_dims, std::vector< int > &shared_indices)
 
static ErrorCode get_neighbor_alljorkori (int np, int pfrom, const int *const gdims, const int *const gperiodic, const int *const dijk, int &pto, int *rdims, int *facedims, int *across_bdy)
 
static ErrorCode get_neighbor_alljkbal (int np, int pfrom, const int *const gdims, const int *const gperiodic, const int *const dijk, int &pto, int *rdims, int *facedims, int *across_bdy)
 
static ErrorCode get_neighbor_sqij (int np, int pfrom, const int *const gdims, const int *const gperiodic, const int *const dijk, int &pto, int *rdims, int *facedims, int *across_bdy)
 
static ErrorCode get_neighbor_sqjk (int np, int pfrom, const int *const gdims, const int *const gperiodic, const int *const dijk, int &pto, int *rdims, int *facedims, int *across_bdy)
 
static ErrorCode get_neighbor_sqijk (int np, int pfrom, const int *const gdims, const int *const gperiodic, const int *const dijk, int &pto, int *rdims, int *facedims, int *across_bdy)
 
static int gtol (const int *gijk, int i, int j, int k)
 

Private Attributes

InterfacembImpl
 interface instance More...
 
bool searchedBoxes
 whether we've searched the database for boxes yet More...
 
std::vector< ScdBox * > scdBoxes
 structured mesh blocks; stored as ScdBox objects, can get sets from those More...
 
Tag boxPeriodicTag
 tag representing whether box is periodic in i and j More...
 
Tag boxDimsTag
 tag representing box lower and upper corners More...
 
Tag globalBoxDimsTag
 tag representing global lower and upper corners More...
 
Tag partMethodTag
 tag representing partition method More...
 
Tag boxSetTag
 tag pointing from set to ScdBox More...
 

Friends

class ScdBox
 

Detailed Description

A structured mesh interface for MOAB-based data.

Structured mesh in MOAB is created and accessed through the ScdInterface and ScdBox classes.

Construction and Representation

Structured mesh can be constructed in one of two ways. First, a rectangular block of mesh, both vertices and edges/quads/hexes, can be created in one shot, using the construct_box method. In this case, there are single sequences of vertices/entities. The second method for creating structured mesh is to create the structured blocks of vertices and elements separately. In this case, different blocks of elements can share blocks of vertices, and each block of elements has its own independent parametric space. The algorithms behind this representation are described in T. Tautges, "MOAB-SD: Integrated structured and unstructured mesh representation", Eng. w Comp, vol 20 no. 3.

Structured mesh is represented in MOAB down at the element sequence level, which is something applications don't see. In addition, when structured mesh is created, entity sets are also created and tagged with information about the parametric space. In particular, the BOX_DIMS tag is used to indicate the lower and upper corners in parametric space (this tag is integer size 6). Structured mesh blocks are also available through ScdBox class objects returned by ScdInterface. These class objects should be treated only as references to the structured mesh blocks; that is, the structured mesh referenced by these objects is not deleted when the ScdBox instance is destroyed. Functions for destroying the actual mesh are available on this class, though.

Structured mesh blocks are returned in the form of ScdBox class objects. Each ScdBox instance represents a rectangular block of vertices and possibly elements (edges, quads, or hexes). The edge/quad/hex entity handles for a ScdBox are guaranteed to be contiguous, starting at a starting value which is also available through the ScdBox class. However, vertex handles may or may not be contiguous, depending on the construction method. The start vertex handle is also available from the ScdBox class.

Parametric Space

Each structured box has a parametric (ijk) space, which can be queried through the ScdBox interface. For non-periodic boxes, the edge/quad/hex parameter bounds are one less in each dimension than that of the vertices, otherwise they are the same as the vertex parameter bounds. In a parallel representation, boxes are locally non-periodic by default, but global ids are assigned such that the last set of vertices in a periodic direction match those of the first set of vertices in that direction.

Entity handles are allocated with the i parameter varying fastest, then j, then k.

Periodic Meshes

Boxes can be periodic in i, or j, or both i and j. If only i or j is periodic, the corresponding mesh is a strip or an annular cylinder; if both i and j are periodic, the corresponding mesh is an annular torus. A box cannot be periodic in all three parameters. If i and/or j is periodic, and assuming IMIN/JMIN is zero, the parameter extents in the/each periodic direction (IMAX/JMAX) for vertices and edges/faces/hexes are the same, and the vertices on the "top" end in the periodic direction are at parameter value IMIN/JMIN.

Parallel Representation

For parallel structured meshes, each local mesh (the mesh on a given process) looks like a non-periodic structured mesh, and there are both local and global parameters of the structured mesh. If the mesh is periodic in a given direction, the last process in the periodic direction has local IMAX/JMAX that is one greater than the global IMAX/JMAX.

In parallel, the periodicity described in the previous paragraph is "local periodicity"; there is also the notion of global periodicity. For serial meshes, those concepts are the same. In parallel, a mesh can be locally non-periodic but globally periodic in a given direction. In that case, the local mesh is still non-periodic, i.e. the parametric extents for edges is one fewer than that of vertices in that direction. However, vertices are given global ids such that they match those of the parametric minimum in that direction. Geometric positions of the vertices at the high end should still be greater than the ones just below.

Adjacent Entities

This interface supports parametric access to intermediate-dimension entities, e.g. adjacent faces and edges in a 3d mesh. In this case, a direction parameter is added, to identify the parametric direction of the entities being requested. For example, to retrieve the faces adjacent to a hex with parameters ijk, in the i parametric direction, you would use the parameters ijk0. These intermediate entities are not stored in a structured representation, but their parametric positions can be evaluated based on their adjacencies to higher-dimensional entities. Thanks to Milad Fatenejad for the thinking behind this.

Evaluation

The ScdBox class provides functions for evaluating the mesh based on the ijk parameter space. These functions are inlined where possible, for efficiency.

Examples
mbex3.cpp, and mbex4.cpp.

Definition at line 151 of file ScdInterface.hpp.

Constructor & Destructor Documentation

◆ ScdInterface()

moab::ScdInterface::ScdInterface ( Interface impl,
bool  find_boxes = false 
)

Constructor.

Constructor; if find_boxes is true, this will search for entity sets marked as structured blocks, based on the BOX_DIMS tag. Structured mesh blocks will be stored in this interface class for future retrieval. Structured mesh blocks created through this interface will also be stored here.

Parameters
implMOAB instance
find_boxesIf true, search all the entity sets, caching the structured mesh blocks

Definition at line 33 of file ScdInterface.cpp.

34  : mbImpl( imp ), searchedBoxes( false ), boxPeriodicTag( 0 ), boxDimsTag( 0 ), globalBoxDimsTag( 0 ),
35  partMethodTag( 0 ), boxSetTag( 0 )
36 {
37  if( boxes ) find_boxes( scdBoxes );
38 }

References find_boxes(), and scdBoxes.

◆ ~ScdInterface()

moab::ScdInterface::~ScdInterface ( )

Definition at line 41 of file ScdInterface.cpp.

42 {
43  std::vector< ScdBox* > tmp_boxes;
44  tmp_boxes.swap( scdBoxes );
45 
46  for( std::vector< ScdBox* >::iterator rit = tmp_boxes.begin(); rit != tmp_boxes.end(); ++rit )
47  delete *rit;
48 
49  if( box_set_tag( false ) ) mbImpl->tag_delete( box_set_tag() );
50 }

References box_set_tag(), mbImpl, scdBoxes, and moab::Interface::tag_delete().

Member Function Documentation

◆ add_box()

ErrorCode moab::ScdInterface::add_box ( ScdBox box)
protected

Add the box to the list on ScdInterface.

Definition at line 465 of file ScdInterface.cpp.

466 {
467  scdBoxes.push_back( box );
468  return MB_SUCCESS;
469 }

References MB_SUCCESS, and scdBoxes.

Referenced by moab::ScdBox::ScdBox().

◆ assign_global_ids()

ErrorCode moab::ScdInterface::assign_global_ids ( ScdBox box)
private

assign global ids to vertices in this box

Definition at line 255 of file ScdInterface.cpp.

256 {
257  // Get a ptr to global id memory
258  void* data;
259  int count = 0;
260  Tag gid_tag = mbImpl->globalId_tag();
261  Range tmp_range( box->start_vertex(), box->start_vertex() + box->num_vertices() );
262  ErrorCode rval = mbImpl->tag_iterate( gid_tag, tmp_range.begin(), tmp_range.end(), count, data );ERRORR( rval, "Failed to get tag iterator." );
263  assert( count == box->num_vertices() );
264  int* gid_data = (int*)data;
265  int di = box->par_data().gDims[3] - box->par_data().gDims[0] + 1;
266  int dj = box->par_data().gDims[4] - box->par_data().gDims[1] + 1;
267 
268  for( int kl = box->box_dims()[2]; kl <= box->box_dims()[5]; kl++ )
269  {
270  for( int jl = box->box_dims()[1]; jl <= box->box_dims()[4]; jl++ )
271  {
272  for( int il = box->box_dims()[0]; il <= box->box_dims()[3]; il++ )
273  {
274  int itmp =
275  ( !box->locally_periodic()[0] && box->par_data().gPeriodic[0] && il == box->par_data().gDims[3]
276  ? box->par_data().gDims[0]
277  : il );
278  *gid_data = ( -1 != kl ? kl * di * dj : 0 ) + jl * di + itmp + 1;
279  gid_data++;
280  }
281  }
282  }
283 
284  return MB_SUCCESS;
285 }

References moab::Range::begin(), moab::ScdBox::box_dims(), moab::Range::end(), ErrorCode, ERRORR, moab::ScdParData::gDims, moab::Interface::globalId_tag(), moab::ScdParData::gPeriodic, moab::ScdBox::locally_periodic(), MB_SUCCESS, mbImpl, moab::ScdBox::num_vertices(), moab::ScdBox::par_data(), moab::ScdBox::start_vertex(), and moab::Interface::tag_iterate().

Referenced by construct_box().

◆ box_dims_tag()

Tag moab::ScdInterface::box_dims_tag ( bool  create_if_missing = true)

Return the tag marking the lower and upper corners of boxes.

Parameters
create_if_missingIf the tag does not yet exist, create it

Definition at line 384 of file ScdInterface.cpp.

385 {
386  // Reset boxDimsTag in case it has been deleted (e.g. by clean_up_failed_read)
387  if( boxDimsTag )
388  {
389  std::string tag_name;
390  if( MB_TAG_NOT_FOUND == mbImpl->tag_get_name( boxDimsTag, tag_name ) ) boxDimsTag = NULL;
391  }
392 
393  if( boxDimsTag || !create_if_missing ) return boxDimsTag;
394 
396  if( MB_SUCCESS != rval ) return 0;
397  return boxDimsTag;
398 }

References boxDimsTag, ErrorCode, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_NOT_FOUND, MB_TAG_SPARSE, MB_TYPE_INTEGER, mbImpl, moab::Interface::tag_get_handle(), and moab::Interface::tag_get_name().

Referenced by create_box_set(), and find_boxes().

◆ box_periodic_tag()

Tag moab::ScdInterface::box_periodic_tag ( bool  create_if_missing = true)

Return the tag marking whether box is periodic in i and j.

Parameters
create_if_missingIf the tag does not yet exist, create it

Definition at line 367 of file ScdInterface.cpp.

368 {
369  // Reset boxPeriodicTag in case it has been deleted (e.g. by Core::clean_up_failed_read)
370  if( boxPeriodicTag )
371  {
372  std::string tag_name;
373  if( MB_TAG_NOT_FOUND == mbImpl->tag_get_name( boxPeriodicTag, tag_name ) ) boxPeriodicTag = NULL;
374  }
375 
376  if( boxPeriodicTag || !create_if_missing ) return boxPeriodicTag;
377 
378  ErrorCode rval =
380  if( MB_SUCCESS != rval ) return 0;
381  return boxPeriodicTag;
382 }

References boxPeriodicTag, ErrorCode, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_NOT_FOUND, MB_TAG_SPARSE, MB_TYPE_INTEGER, mbImpl, moab::Interface::tag_get_handle(), and moab::Interface::tag_get_name().

Referenced by create_box_set().

◆ box_set_tag()

Tag moab::ScdInterface::box_set_tag ( bool  create_if_missing = true)

Return the tag marking the ScdBox for a set.

Parameters
create_if_missingIf the tag does not yet exist, create it

Definition at line 434 of file ScdInterface.cpp.

435 {
436  // Reset boxSetTag in case it has been deleted (e.g. by Core::clean_up_failed_read)
437  if( boxSetTag )
438  {
439  std::string tag_name;
440  if( MB_TAG_NOT_FOUND == mbImpl->tag_get_name( boxSetTag, tag_name ) ) boxSetTag = NULL;
441  }
442 
443  if( boxSetTag || !create_if_missing ) return boxSetTag;
444 
445  ErrorCode rval = mbImpl->tag_get_handle( "__BOX_SET", sizeof( ScdBox* ), MB_TYPE_OPAQUE, boxSetTag,
447  if( MB_SUCCESS != rval ) return 0;
448  return boxSetTag;
449 }

References boxSetTag, ErrorCode, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_NOT_FOUND, MB_TAG_SPARSE, MB_TYPE_OPAQUE, mbImpl, moab::Interface::tag_get_handle(), and moab::Interface::tag_get_name().

Referenced by create_scd_sequence(), get_scd_box(), moab::ScdBox::~ScdBox(), and ~ScdInterface().

◆ compute_partition()

ErrorCode moab::ScdInterface::compute_partition ( int  np,
int  nr,
const ScdParData par_data,
int *  ldims,
int *  lperiodic = NULL,
int *  pdims = NULL 
)
inlinestatic

Compute a partition of structured parameter space.

Compute a partition of structured parameter space, based on data in the ScdParData passed in. Results are passed back in arguments, which application can set back into par_data argument if they so desire.

Parameters
npNumber of processors
nrRank of this processor
par_dataScdParData object that contains input global parameter space, desired partitioning method, and information about global periodicity.
ldimsLocal parameters for grid
lperiodicWhether or not a given dimension is locally periodic
pdimsNumber of procs in i, j, k directions

Definition at line 849 of file ScdInterface.hpp.

855 {
856  ErrorCode rval = MB_SUCCESS;
857  switch( par_data.partMethod )
858  {
860  case -1:
861  rval = compute_partition_alljorkori( np, nr, par_data.gDims, par_data.gPeriodic, ldims, lperiodic, pdims );
862  break;
864  rval = compute_partition_alljkbal( np, nr, par_data.gDims, par_data.gPeriodic, ldims, lperiodic, pdims );
865  break;
866  case ScdParData::SQIJ:
867  rval = compute_partition_sqij( np, nr, par_data.gDims, par_data.gPeriodic, ldims, lperiodic, pdims );
868  break;
869  case ScdParData::SQJK:
870  rval = compute_partition_sqjk( np, nr, par_data.gDims, par_data.gPeriodic, ldims, lperiodic, pdims );
871  break;
872  case ScdParData::SQIJK:
873  rval = compute_partition_sqijk( np, nr, par_data.gDims, par_data.gPeriodic, ldims, lperiodic, pdims );
874  break;
875  default:
876  rval = MB_FAILURE;
877  break;
878  }
879 
880  return rval;
881 }

References moab::ScdParData::ALLJKBAL, moab::ScdParData::ALLJORKORI, compute_partition_alljkbal(), compute_partition_alljorkori(), compute_partition_sqij(), compute_partition_sqijk(), compute_partition_sqjk(), ErrorCode, moab::ScdParData::gDims, moab::ScdParData::gPeriodic, MB_SUCCESS, moab::ScdParData::partMethod, moab::ScdParData::SQIJ, moab::ScdParData::SQIJK, and moab::ScdParData::SQJK.

Referenced by construct_box(), moab::NCHelperDomain::init_mesh_vals(), moab::NCHelperEuler::init_mesh_vals(), and moab::NCHelperFV::init_mesh_vals().

◆ compute_partition_alljkbal()

ErrorCode moab::ScdInterface::compute_partition_alljkbal ( int  np,
int  nr,
const int  gijk[6],
const int *const  gperiodic,
int *  lijk,
int *  lperiodic,
int *  pijk 
)
inlinestaticprivate

Compute a partition of structured parameter space.

Partitions the structured parametric space by partitioning j, and possibly k, seeking square regions of jk space For description of arguments, see ScdInterface::compute_partition.

Definition at line 983 of file ScdInterface.hpp.

990 {
991  int tmp_lp[3], tmp_pijk[3];
992  if( !lperiodic ) lperiodic = tmp_lp;
993  if( !pijk ) pijk = tmp_pijk;
994 
995  for( int i = 0; i < 3; i++ )
996  lperiodic[i] = gperiodic[i];
997 
998  if( np == 1 )
999  {
1000  if( ldims )
1001  {
1002  ldims[0] = gijk[0];
1003  ldims[3] = gijk[3];
1004  ldims[1] = gijk[1];
1005  ldims[4] = gijk[4];
1006  ldims[2] = gijk[2];
1007  ldims[5] = gijk[5];
1008  }
1009  pijk[0] = pijk[1] = pijk[2] = 1;
1010  }
1011  else
1012  {
1013  // improved, possibly 2-d partition
1014  std::vector< double > kfactors;
1015  kfactors.push_back( 1 );
1016  int K = gijk[5] - gijk[2];
1017  for( int i = 2; i < K; i++ )
1018  if( !( K % i ) && !( np % i ) ) kfactors.push_back( i );
1019  kfactors.push_back( K );
1020 
1021  // compute the ideal nj and nk
1022  int J = gijk[4] - gijk[1];
1023  double njideal = sqrt( ( (double)( np * J ) ) / ( (double)K ) );
1024  double nkideal = ( njideal * K ) / J;
1025 
1026  int nk, nj;
1027  if( nkideal < 1.0 )
1028  {
1029  nk = 1;
1030  nj = np;
1031  }
1032  else
1033  {
1034  std::vector< double >::iterator vit = std::lower_bound( kfactors.begin(), kfactors.end(), nkideal );
1035  if( vit == kfactors.begin() )
1036  nk = 1;
1037  else
1038  nk = (int)*( --vit );
1039  nj = np / nk;
1040  }
1041 
1042  int dk = K / nk;
1043  int dj = J / nj;
1044 
1045  ldims[2] = gijk[2] + ( nr % nk ) * dk;
1046  ldims[5] = ldims[2] + dk;
1047 
1048  int extra = J % nj;
1049 
1050  ldims[1] = gijk[1] + ( nr / nk ) * dj + std::min( nr / nk, extra );
1051  ldims[4] = ldims[1] + dj + ( nr / nk < extra ? 1 : 0 );
1052 
1053  ldims[0] = gijk[0];
1054  ldims[3] = gijk[3];
1055 
1056  if( gperiodic[1] && np > 1 )
1057  {
1058  lperiodic[1] = 0;
1059  if( nr / nk == nj - 1 )
1060  {
1061  ldims[1]++;
1062  }
1063  }
1064 
1065  pijk[0] = 1;
1066  pijk[1] = nj;
1067  pijk[2] = nk;
1068  }
1069 
1070  return MB_SUCCESS;
1071 }

References MB_SUCCESS.

Referenced by compute_partition(), and get_neighbor_alljkbal().

◆ compute_partition_alljorkori()

ErrorCode moab::ScdInterface::compute_partition_alljorkori ( int  np,
int  nr,
const int  gijk[6],
const int *const  gperiodic,
int *  lijk,
int *  lperiodic,
int *  pijk 
)
inlinestaticprivate

Compute a partition of structured parameter space.

Partitions the structured parametric space by partitioning j, k, or i only. If j is greater than #procs, partition that, else k, else i. For description of arguments, see ScdInterface::compute_partition.

Definition at line 883 of file ScdInterface.hpp.

890 {
891  // partition *the elements* over the parametric space; 1d partition for now, in the j, k, or i
892  // parameters
893  int tmp_lp[3], tmp_pijk[3];
894  if( !lperiodic ) lperiodic = tmp_lp;
895  if( !pijk ) pijk = tmp_pijk;
896 
897  for( int i = 0; i < 3; i++ )
898  lperiodic[i] = gperiodic[i];
899 
900  if( np == 1 )
901  {
902  if( ldims )
903  {
904  ldims[0] = gijk[0];
905  ldims[3] = gijk[3];
906  ldims[1] = gijk[1];
907  ldims[4] = gijk[4];
908  ldims[2] = gijk[2];
909  ldims[5] = gijk[5];
910  }
911  pijk[0] = pijk[1] = pijk[2] = 1;
912  }
913  else
914  {
915  if( gijk[4] - gijk[1] > np )
916  {
917  // partition j over procs
918  int dj = ( gijk[4] - gijk[1] ) / np;
919  int extra = ( gijk[4] - gijk[1] ) % np;
920  ldims[1] = gijk[1] + nr * dj + std::min( nr, extra );
921  ldims[4] = ldims[1] + dj + ( nr < extra ? 1 : 0 );
922 
923  if( gperiodic[1] && np > 1 )
924  {
925  lperiodic[1] = 0;
926  ldims[4]++;
927  }
928 
929  ldims[2] = gijk[2];
930  ldims[5] = gijk[5];
931  ldims[0] = gijk[0];
932  ldims[3] = gijk[3];
933  pijk[0] = pijk[2] = 1;
934  pijk[1] = np;
935  }
936  else if( gijk[5] - gijk[2] > np )
937  {
938  // partition k over procs
939  int dk = ( gijk[5] - gijk[2] ) / np;
940  int extra = ( gijk[5] - gijk[2] ) % np;
941  ldims[2] = gijk[2] + nr * dk + std::min( nr, extra );
942  ldims[5] = ldims[2] + dk + ( nr < extra ? 1 : 0 );
943 
944  ldims[1] = gijk[1];
945  ldims[4] = gijk[4];
946  ldims[0] = gijk[0];
947  ldims[3] = gijk[3];
948  pijk[0] = pijk[1] = 1;
949  pijk[2] = np;
950  }
951  else if( gijk[3] - gijk[0] > np )
952  {
953  // partition i over procs
954  int di = ( gijk[3] - gijk[0] ) / np;
955  int extra = ( gijk[3] - gijk[0] ) % np;
956  ldims[0] = gijk[0] + nr * di + std::min( nr, extra );
957  ldims[3] = ldims[0] + di + ( nr < extra ? 1 : 0 );
958 
959  if( gperiodic[0] && np > 1 )
960  {
961  lperiodic[0] = 0;
962  ldims[3]++;
963  }
964 
965  ldims[2] = gijk[2];
966  ldims[5] = gijk[5];
967  ldims[1] = gijk[1];
968  ldims[4] = gijk[4];
969 
970  pijk[1] = pijk[2] = 1;
971  pijk[0] = np;
972  }
973  else
974  {
975  // Couldn't find a suitable partition...
976  return MB_FAILURE;
977  }
978  }
979 
980  return MB_SUCCESS;
981 }

References MB_SUCCESS.

Referenced by compute_partition(), and get_neighbor_alljorkori().

◆ compute_partition_sqij()

ErrorCode moab::ScdInterface::compute_partition_sqij ( int  np,
int  nr,
const int  gijk[6],
const int *const  gperiodic,
int *  lijk,
int *  lperiodic,
int *  pijk 
)
inlinestaticprivate

Compute a partition of structured parameter space.

Partitions the structured parametric space by seeking square ij partitions For description of arguments, see ScdInterface::compute_partition.

Definition at line 1073 of file ScdInterface.hpp.

1080 {
1081  int tmp_lp[3], tmp_pijk[3];
1082  if( !lperiodic ) lperiodic = tmp_lp;
1083  if( !pijk ) pijk = tmp_pijk;
1084 
1085  // square IxJ partition
1086 
1087  for( int i = 0; i < 3; i++ )
1088  lperiodic[i] = gperiodic[i];
1089 
1090  if( np == 1 )
1091  {
1092  if( ldims )
1093  {
1094  ldims[0] = gijk[0];
1095  ldims[3] = gijk[3];
1096  ldims[1] = gijk[1];
1097  ldims[4] = gijk[4];
1098  ldims[2] = gijk[2];
1099  ldims[5] = gijk[5];
1100  }
1101  pijk[0] = pijk[1] = pijk[2] = 1;
1102  }
1103  else
1104  {
1105  std::vector< double > pfactors, ppfactors;
1106  for( int i = 2; i <= np / 2; i++ )
1107  if( !( np % i ) )
1108  {
1109  pfactors.push_back( i );
1110  ppfactors.push_back( ( (double)( i * i ) ) / np );
1111  }
1112  pfactors.push_back( np );
1113  ppfactors.push_back( (double)np );
1114 
1115  // ideally, Px/Py = I/J
1116  double ijratio = ( (double)( gijk[3] - gijk[0] ) ) / ( (double)( gijk[4] - gijk[1] ) );
1117 
1118  unsigned int ind = 0;
1119  std::vector< double >::iterator optimal = std::lower_bound( ppfactors.begin(), ppfactors.end(), ijratio );
1120  if( optimal == ppfactors.end() )
1121  {
1122  ind = ppfactors.size() - 1;
1123  }
1124  else
1125  {
1126  ind = optimal - ppfactors.begin();
1127  if( ind && fabs( ppfactors[ind - 1] - ijratio ) < fabs( ppfactors[ind] - ijratio ) ) ind--;
1128  }
1129 
1130  // VARIABLES DESCRIBING THE MESH:
1131  // pi, pj = # procs in i and j directions
1132  // nri, nrj = my proc's position in i, j directions
1133  // I, J = # edges/elements in i, j directions
1134  // iextra, jextra = # procs having extra edge in i/j direction
1135  // top_i, top_j = if true, I'm the last proc in the i/j direction
1136  // i, j = # edges locally in i/j direction, *not* including one for iextra/jextra
1137  int pi = pfactors[ind];
1138  int pj = np / pi;
1139 
1140  int I = ( gijk[3] - gijk[0] ), J = ( gijk[4] - gijk[1] );
1141  int iextra = I % pi, jextra = J % pj, i = I / pi, j = J / pj;
1142  int nri = nr % pi, nrj = nr / pi;
1143 
1144  if( ldims )
1145  {
1146  ldims[0] = gijk[0] + i * nri + std::min( iextra, nri );
1147  ldims[3] = ldims[0] + i + ( nri < iextra ? 1 : 0 );
1148  ldims[1] = gijk[1] + j * nrj + std::min( jextra, nrj );
1149  ldims[4] = ldims[1] + j + ( nrj < jextra ? 1 : 0 );
1150 
1151  ldims[2] = gijk[2];
1152  ldims[5] = gijk[5];
1153 
1154  if( gperiodic[0] && pi > 1 )
1155  {
1156  lperiodic[0] = 0;
1157  if( nri == pi - 1 ) ldims[3]++;
1158  }
1159  if( gperiodic[1] && pj > 1 )
1160  {
1161  lperiodic[1] = 0;
1162  if( nrj == pj - 1 ) ldims[4]++;
1163  }
1164  }
1165 
1166  pijk[0] = pi;
1167  pijk[1] = pj;
1168  pijk[2] = 1;
1169  }
1170 
1171  return MB_SUCCESS;
1172 }

References MB_SUCCESS.

Referenced by compute_partition(), and get_neighbor_sqij().

◆ compute_partition_sqijk()

ErrorCode moab::ScdInterface::compute_partition_sqijk ( int  np,
int  nr,
const int  gijk[6],
const int *const  gperiodic,
int *  lijk,
int *  lperiodic,
int *  pijk 
)
inlinestaticprivate

Compute a partition of structured parameter space.

Partitions the structured parametric space by seeking square ijk partitions For description of arguments, see ScdInterface::compute_partition.

Definition at line 1261 of file ScdInterface.hpp.

1268 {
1269  if( gperiodic[0] || gperiodic[1] || gperiodic[2] ) return MB_FAILURE;
1270 
1271  int tmp_lp[3], tmp_pijk[3];
1272  if( !lperiodic ) lperiodic = tmp_lp;
1273  if( !pijk ) pijk = tmp_pijk;
1274 
1275  // square IxJxK partition
1276 
1277  for( int i = 0; i < 3; i++ )
1278  lperiodic[i] = gperiodic[i];
1279 
1280  if( np == 1 )
1281  {
1282  if( ldims )
1283  for( int i = 0; i < 6; i++ )
1284  ldims[i] = gijk[i];
1285  pijk[0] = pijk[1] = pijk[2] = 1;
1286  return MB_SUCCESS;
1287  }
1288 
1289  std::vector< int > pfactors;
1290  pfactors.push_back( 1 );
1291  for( int i = 2; i <= np / 2; i++ )
1292  if( !( np % i ) ) pfactors.push_back( i );
1293  pfactors.push_back( np );
1294 
1295  // test for IJ, JK, IK
1296  int IJK[3], dIJK[3];
1297  for( int i = 0; i < 3; i++ )
1298  IJK[i] = std::max( gijk[3 + i] - gijk[i], 1 );
1299  // order IJK from lo to hi
1300  int lo = 0, hi = 0;
1301  for( int i = 1; i < 3; i++ )
1302  {
1303  if( IJK[i] < IJK[lo] ) lo = i;
1304  if( IJK[i] > IJK[hi] ) hi = i;
1305  }
1306  if( lo == hi ) hi = ( lo + 1 ) % 3;
1307  int mid = 3 - lo - hi;
1308  // search for perfect subdivision of np that balances #cells
1309  int perfa_best = -1, perfb_best = -1;
1310  double ratio = 0.0;
1311  for( int po = 0; po < (int)pfactors.size(); po++ )
1312  {
1313  for( int pi = po; pi < (int)pfactors.size() && np / ( pfactors[po] * pfactors[pi] ) >= pfactors[pi]; pi++ )
1314  {
1315  int p3 =
1316  std::find( pfactors.begin(), pfactors.end(), np / ( pfactors[po] * pfactors[pi] ) ) - pfactors.begin();
1317  if( p3 == (int)pfactors.size() || pfactors[po] * pfactors[pi] * pfactors[p3] != np )
1318  continue; // po*pi should exactly factor np
1319  assert( po <= pi && pi <= p3 );
1320  // by definition, po <= pi <= p3
1321  double minl =
1322  std::min( std::min( IJK[lo] / pfactors[po], IJK[mid] / pfactors[pi] ), IJK[hi] / pfactors[p3] ),
1323  maxl =
1324  std::max( std::max( IJK[lo] / pfactors[po], IJK[mid] / pfactors[pi] ), IJK[hi] / pfactors[p3] );
1325  if( minl / maxl > ratio )
1326  {
1327  ratio = minl / maxl;
1328  perfa_best = po;
1329  perfb_best = pi;
1330  }
1331  }
1332  }
1333  if( perfa_best == -1 || perfb_best == -1 ) return MB_FAILURE;
1334 
1335  // VARIABLES DESCRIBING THE MESH:
1336  // pijk[i] = # procs in direction i
1337  // numr[i] = my proc's position in direction i
1338  // dIJK[i] = # edges/elements in direction i
1339  // extra[i]= # procs having extra edge in direction i
1340  // top[i] = if true, I'm the last proc in direction i
1341 
1342  pijk[lo] = pfactors[perfa_best];
1343  pijk[mid] = pfactors[perfb_best];
1344  pijk[hi] = ( np / ( pfactors[perfa_best] * pfactors[perfb_best] ) );
1345  int extra[3] = { 0, 0, 0 }, numr[3];
1346  for( int i = 0; i < 3; i++ )
1347  {
1348  dIJK[i] = IJK[i] / pijk[i];
1349  extra[i] = IJK[i] % pijk[i];
1350  }
1351  numr[2] = nr / ( pijk[0] * pijk[1] );
1352  int rem = nr % ( pijk[0] * pijk[1] );
1353  numr[1] = rem / pijk[0];
1354  numr[0] = rem % pijk[0];
1355  for( int i = 0; i < 3; i++ )
1356  {
1357  extra[i] = IJK[i] % dIJK[i];
1358  ldims[i] = gijk[i] + numr[i] * dIJK[i] + std::min( extra[i], numr[i] );
1359  ldims[3 + i] = ldims[i] + dIJK[i] + ( numr[i] < extra[i] ? 1 : 0 );
1360  }
1361 
1362  return MB_SUCCESS;
1363 }

References MB_SUCCESS.

Referenced by compute_partition(), and get_neighbor_sqijk().

◆ compute_partition_sqjk()

ErrorCode moab::ScdInterface::compute_partition_sqjk ( int  np,
int  nr,
const int  gijk[6],
const int *const  gperiodic,
int *  lijk,
int *  lperiodic,
int *  pijk 
)
inlinestaticprivate

Compute a partition of structured parameter space.

Partitions the structured parametric space by seeking square jk partitions For description of arguments, see ScdInterface::compute_partition.

Definition at line 1174 of file ScdInterface.hpp.

1181 {
1182  int tmp_lp[3], tmp_pijk[3];
1183  if( !lperiodic ) lperiodic = tmp_lp;
1184  if( !pijk ) pijk = tmp_pijk;
1185 
1186  // square JxK partition
1187  for( int i = 0; i < 3; i++ )
1188  lperiodic[i] = gperiodic[i];
1189 
1190  if( np == 1 )
1191  {
1192  if( ldims )
1193  {
1194  ldims[0] = gijk[0];
1195  ldims[3] = gijk[3];
1196  ldims[1] = gijk[1];
1197  ldims[4] = gijk[4];
1198  ldims[2] = gijk[2];
1199  ldims[5] = gijk[5];
1200  }
1201  pijk[0] = pijk[1] = pijk[2] = 1;
1202  }
1203  else
1204  {
1205  std::vector< double > pfactors, ppfactors;
1206  for( int p = 2; p <= np; p++ )
1207  if( !( np % p ) )
1208  {
1209  pfactors.push_back( p );
1210  ppfactors.push_back( ( (double)( p * p ) ) / np );
1211  }
1212 
1213  // ideally, Pj/Pk = J/K
1214  int pj, pk;
1215  if( gijk[5] == gijk[2] )
1216  {
1217  pk = 1;
1218  pj = np;
1219  }
1220  else
1221  {
1222  double jkratio = ( (double)( gijk[4] - gijk[1] ) ) / ( (double)( gijk[5] - gijk[2] ) );
1223 
1224  std::vector< double >::iterator vit = std::lower_bound( ppfactors.begin(), ppfactors.end(), jkratio );
1225  if( vit == ppfactors.end() )
1226  --vit;
1227  else if( vit != ppfactors.begin() && fabs( *( vit - 1 ) - jkratio ) < fabs( ( *vit ) - jkratio ) )
1228  --vit;
1229  int ind = vit - ppfactors.begin();
1230 
1231  pj = 1;
1232  if( ind >= 0 && !pfactors.empty() ) pj = pfactors[ind];
1233  pk = np / pj;
1234  }
1235 
1236  int K = ( gijk[5] - gijk[2] ), J = ( gijk[4] - gijk[1] );
1237  int jextra = J % pj, kextra = K % pk, j = J / pj, k = K / pk;
1238  int nrj = nr % pj, nrk = nr / pj;
1239  ldims[1] = gijk[1] + j * nrj + std::min( jextra, nrj );
1240  ldims[4] = ldims[1] + j + ( nrj < jextra ? 1 : 0 );
1241  ldims[2] = gijk[2] + k * nrk + std::min( kextra, nrk );
1242  ldims[5] = ldims[2] + k + ( nrk < kextra ? 1 : 0 );
1243 
1244  ldims[0] = gijk[0];
1245  ldims[3] = gijk[3];
1246 
1247  if( gperiodic[1] && pj > 1 )
1248  {
1249  lperiodic[1] = 0;
1250  if( nrj == pj - 1 ) ldims[4]++;
1251  }
1252 
1253  pijk[0] = 1;
1254  pijk[1] = pj;
1255  pijk[2] = pk;
1256  }
1257 
1258  return MB_SUCCESS;
1259 }

References MB_SUCCESS.

Referenced by compute_partition(), and get_neighbor_sqjk().

◆ construct_box()

ErrorCode moab::ScdInterface::construct_box ( HomCoord  low,
HomCoord  high,
const double *const  coords,
unsigned int  num_coords,
ScdBox *&  new_box,
int *const  lperiodic = NULL,
ScdParData *const  par_data = NULL,
bool  assign_global_ids = false,
int  resolve_shared_ents = -1 
)

Construct new structured mesh box, including both vertices and elements.

Parameter range for vertex box is [low-high], for elements is [low-high). Construct quads by passing in low[2] == high[2], and edges by passing in low[1] == high[1] and low[2] == high[2]. The result is passed back in a ScdBox*, which is a reference to the box of structured mesh. That is, the actual mesh is retained in MOAB when the ScdBox is destroyed. To actually destroy the mesh, call the destroy_mesh function on the ScdBox object first, before destroying it.

Parameters
lowLower corner in parameter space
highHigher corner in parameter space
coordsCoordinates of vertices, interleaved (xyzxyz...); if NULL, coords are set to parametric values
num_coordsNumber of coordinate values
new_boxReference to box of structured mesh
lperiodic[3]If lperiodic[s] != 0, direction s is locally periodic
par_dataIf non-NULL, this will get stored on the ScdBox once created, contains info about global parallel nature of ScdBox across procs
assign_global_idsIf true, assigns 1-based global ids to vertices using GLOBAL_ID_TAG_NAME
resolve_shared_entsIf != -1, resolves shared entities up to and including dimension equal to value
Examples
mbex3.cpp, and mbex4.cpp.

Definition at line 115 of file ScdInterface.cpp.

124 {
125  // create a rectangular structured mesh block
126  ErrorCode rval;
127 
128  int tmp_lper[3] = { 0, 0, 0 };
129  if( lperiodic ) std::copy( lperiodic, lperiodic + 3, tmp_lper );
130 
131 #ifndef MOAB_HAVE_MPI
132  if( -1 != tag_shared_ents ) ERRORR( MB_FAILURE, "Parallel capability requested but MOAB not compiled parallel." );
133  if( -1 == tag_shared_ents && !assign_gids ) assign_gids = true; // need to assign gids in order to tag shared verts
134 #else
135  if( par_data && low == high && ScdParData::NOPART != par_data->partMethod )
136  {
137  // requesting creation of parallel mesh, so need to compute partition
138  if( !par_data->pComm )
139  {
140  // this is a really boneheaded way to have to create a PC
141  par_data->pComm = ParallelComm::get_pcomm( mbImpl, 0 );
142  if( NULL == par_data->pComm ) par_data->pComm = new ParallelComm( mbImpl, MPI_COMM_WORLD );
143  }
144  int ldims[6];
145  rval = compute_partition( par_data->pComm->size(), par_data->pComm->rank(), *par_data, ldims, tmp_lper,
146  par_data->pDims );ERRORR( rval, "Error returned from compute_partition." );
147  low.set( ldims[0], ldims[1], ldims[2] );
148  high.set( ldims[3], ldims[4], ldims[5] );
149  if( par_data->pComm->get_debug_verbosity() > 0 )
150  {
151  std::cout << "Proc " << par_data->pComm->rank() << ": " << *par_data;
152  std::cout << "Proc " << par_data->pComm->rank() << " local dims: " << low << "-" << high << std::endl;
153  }
154  }
155 #endif
156 
157  HomCoord tmp_size = high - low + HomCoord( 1, 1, 1, 0 );
158  if( ( tmp_size[1] && num_coords && (int)num_coords < tmp_size[0] ) ||
159  ( tmp_size[2] && num_coords && (int)num_coords < tmp_size[0] * tmp_size[1] ) )
160  return MB_FAILURE;
161 
162  rval = create_scd_sequence( low, high, MBVERTEX, 0, new_box );ERRORR( rval, "Trouble creating scd vertex sequence." );
163 
164  // set the vertex coordinates
165  double *xc, *yc, *zc;
166  rval = new_box->get_coordinate_arrays( xc, yc, zc );ERRORR( rval, "Couldn't get vertex coordinate arrays." );
167 
168  if( coords && num_coords )
169  {
170  unsigned int i = 0;
171  for( int kl = low[2]; kl <= high[2]; kl++ )
172  {
173  for( int jl = low[1]; jl <= high[1]; jl++ )
174  {
175  for( int il = low[0]; il <= high[0]; il++ )
176  {
177  xc[i] = coords[3 * i];
178  if( new_box->box_size()[1] ) yc[i] = coords[3 * i + 1];
179  if( new_box->box_size()[2] ) zc[i] = coords[3 * i + 2];
180  i++;
181  }
182  }
183  }
184  }
185  else
186  {
187  unsigned int i = 0;
188  for( int kl = low[2]; kl <= high[2]; kl++ )
189  {
190  for( int jl = low[1]; jl <= high[1]; jl++ )
191  {
192  for( int il = low[0]; il <= high[0]; il++ )
193  {
194  xc[i] = (double)il;
195  if( new_box->box_size()[1] )
196  yc[i] = (double)jl;
197  else
198  yc[i] = 0.0;
199  if( new_box->box_size()[2] )
200  zc[i] = (double)kl;
201  else
202  zc[i] = 0.0;
203  i++;
204  }
205  }
206  }
207  }
208 
209  // create element sequence
210  Core* mbcore = dynamic_cast< Core* >( mbImpl );
211  SequenceManager* seq_mgr = mbcore->sequence_manager();
212 
213  EntitySequence* tmp_seq;
214  EntityHandle start_ent;
215 
216  // construct the sequence
217  EntityType this_tp = MBHEX;
218  if( 1 >= tmp_size[2] ) this_tp = MBQUAD;
219  if( 1 >= tmp_size[2] && 1 >= tmp_size[1] ) this_tp = MBEDGE;
220  rval = seq_mgr->create_scd_sequence( low, high, this_tp, 0, start_ent, tmp_seq, tmp_lper );ERRORR( rval, "Trouble creating scd element sequence." );
221 
222  new_box->elem_seq( tmp_seq );
223  new_box->start_element( start_ent );
224 
225  // add vertex seq to element seq, forward orientation, unity transform
226  rval = new_box->add_vbox( new_box,
227  // p1: imin,jmin
228  low, low,
229  // p2: imax,jmin
230  low + HomCoord( 1, 0, 0 ), low + HomCoord( 1, 0, 0 ),
231  // p3: imin,jmax
232  low + HomCoord( 0, 1, 0 ), low + HomCoord( 0, 1, 0 ) );ERRORR( rval, "Error constructing structured element sequence." );
233 
234  // add the new hexes to the scd box set; vertices were added in call to create_scd_sequence
235  Range tmp_range( new_box->start_element(), new_box->start_element() + new_box->num_elements() - 1 );
236  rval = mbImpl->add_entities( new_box->box_set(), tmp_range );ERRORR( rval, "Couldn't add new hexes to box set." );
237 
238  if( par_data ) new_box->par_data( *par_data );
239 
240  if( assign_gids )
241  {
242  rval = assign_global_ids( new_box );ERRORR( rval, "Trouble assigning global ids" );
243  }
244 
245 #ifdef MOAB_HAVE_MPI
246  if( par_data && -1 != tag_shared_ents )
247  {
248  rval = tag_shared_vertices( par_data->pComm, new_box );
249  }
250 #endif
251 
252  return MB_SUCCESS;
253 }

References moab::Interface::add_entities(), moab::ScdBox::add_vbox(), assign_global_ids(), moab::ScdBox::box_set(), moab::ScdBox::box_size(), compute_partition(), create_scd_sequence(), moab::SequenceManager::create_scd_sequence(), moab::ScdBox::elem_seq(), ErrorCode, ERRORR, moab::ScdBox::get_coordinate_arrays(), moab::ParallelComm::get_debug_verbosity(), moab::ParallelComm::get_pcomm(), MB_SUCCESS, MBEDGE, MBHEX, mbImpl, MBQUAD, MBVERTEX, moab::ScdParData::NOPART, moab::ScdBox::num_elements(), moab::ScdBox::par_data(), moab::ScdParData::partMethod, moab::ScdParData::pComm, moab::ScdParData::pDims, moab::ParallelComm::rank(), moab::Core::sequence_manager(), moab::HomCoord::set(), moab::ParallelComm::size(), moab::ScdBox::start_element(), and tag_shared_vertices().

Referenced by moab::ScdNCHelper::create_mesh(), and main().

◆ create_box_set()

ErrorCode moab::ScdInterface::create_box_set ( const HomCoord low,
const HomCoord high,
EntityHandle scd_set,
int *  is_periodic = NULL 
)
private

Create an entity set for a box, and tag with the parameters.

Parameters
lowLower corner parameters for this box
highUpper corner parameters for this box
scd_setEntity set created
is_periodic[3]If is_periodic[s] is non-zero, mesh should be periodic in direction s (s=[0,1,2])

Definition at line 340 of file ScdInterface.cpp.

344 {
345  // create the set and put the entities in it
346  ErrorCode rval = mbImpl->create_meshset( MESHSET_SET, scd_set );
347  if( MB_SUCCESS != rval ) return rval;
348 
349  // tag the set with parameter extents
350  int boxdims[6];
351  for( int i = 0; i < 3; i++ )
352  boxdims[i] = low[i];
353  for( int i = 0; i < 3; i++ )
354  boxdims[3 + i] = high[i];
355  rval = mbImpl->tag_set_data( box_dims_tag(), &scd_set, 1, boxdims );
356  if( MB_SUCCESS != rval ) return rval;
357 
358  if( is_periodic )
359  {
360  rval = mbImpl->tag_set_data( box_periodic_tag(), &scd_set, 1, is_periodic );
361  if( MB_SUCCESS != rval ) return rval;
362  }
363 
364  return rval;
365 }

References box_dims_tag(), box_periodic_tag(), moab::Interface::create_meshset(), ErrorCode, MB_SUCCESS, mbImpl, MESHSET_SET, and moab::Interface::tag_set_data().

Referenced by create_scd_sequence().

◆ create_scd_sequence()

ErrorCode moab::ScdInterface::create_scd_sequence ( const HomCoord low,
const HomCoord high,
EntityType  type,
int  starting_id,
ScdBox *&  new_box,
int *  is_periodic = NULL 
)

Create a structured sequence of vertices, quads, or hexes.

Starting handle for the sequence is available from the returned ScdBox. If creating a structured quad or hex box, subsequent calls must be made to ScdBox::add_vbox, until all the vertices have been filled in for the box.

Parameters
lowLower corner of structured box
highHigher corner of structured box
typeEntityType, one of MBVERTEX, MBEDGE, MBQUAD, MBHEX
starting_idRequested start id of entities
new_boxReference to the newly created box of entities
is_periodic[3]If is_periodic[s] is non-zero, mesh should be periodic in direction s (s=[0,1,2])

Definition at line 287 of file ScdInterface.cpp.

293 {
294  HomCoord tmp_size = high - low + HomCoord( 1, 1, 1, 0 );
295  if( ( tp == MBHEX && 1 >= tmp_size[2] ) || ( tp == MBQUAD && 1 >= tmp_size[1] ) ||
296  ( tp == MBEDGE && 1 >= tmp_size[0] ) )
297  return MB_TYPE_OUT_OF_RANGE;
298 
299  Core* mbcore = dynamic_cast< Core* >( mbImpl );
300  assert( mbcore != NULL );
301  SequenceManager* seq_mgr = mbcore->sequence_manager();
302 
303  EntitySequence* tmp_seq;
304  EntityHandle start_ent, scd_set;
305 
306  // construct the sequence
307  ErrorCode rval = seq_mgr->create_scd_sequence( low, high, tp, starting_id, start_ent, tmp_seq, is_periodic );
308  if( MB_SUCCESS != rval ) return rval;
309 
310  // create the set for this rectangle
311  rval = create_box_set( low, high, scd_set );
312  if( MB_SUCCESS != rval ) return rval;
313 
314  // make the ScdBox
315  new_box = new ScdBox( this, scd_set, tmp_seq );
316  if( !new_box ) return MB_FAILURE;
317 
318  // set the start vertex/element
319  Range new_range;
320  if( MBVERTEX == tp )
321  {
322  new_range.insert( start_ent, start_ent + new_box->num_vertices() - 1 );
323  }
324  else
325  {
326  new_range.insert( start_ent, start_ent + new_box->num_elements() - 1 );
327  }
328 
329  // put the entities in the box set
330  rval = mbImpl->add_entities( scd_set, new_range );
331  if( MB_SUCCESS != rval ) return rval;
332 
333  // tag the set with the box
334  rval = mbImpl->tag_set_data( box_set_tag(), &scd_set, 1, &new_box );
335  if( MB_SUCCESS != rval ) return rval;
336 
337  return MB_SUCCESS;
338 }

References moab::Interface::add_entities(), box_set_tag(), create_box_set(), moab::SequenceManager::create_scd_sequence(), ErrorCode, moab::Range::insert(), MB_SUCCESS, MB_TYPE_OUT_OF_RANGE, MBEDGE, MBHEX, mbImpl, MBQUAD, MBVERTEX, moab::ScdBox::num_elements(), moab::ScdBox::num_vertices(), ScdBox, moab::Core::sequence_manager(), and moab::Interface::tag_set_data().

Referenced by construct_box().

◆ find_boxes() [1/2]

ErrorCode moab::ScdInterface::find_boxes ( Range boxes)

Return all the structured mesh blocks in this MOAB instance, as entity set handles.

Return the structured blocks in this MOAB instance. If these were not searched for at instantiation time, then the search is done now.

Parameters
boxesRange of entity set objects representing structured mesh blocks

Definition at line 75 of file ScdInterface.cpp.

76 {
77  box_dims_tag();
78  Range boxes;
79  if( !searchedBoxes )
80  {
82  "failed to get entitities by type and tag" );
83  searchedBoxes = true;
84  if( !boxes.empty() )
85  {
86  scdBoxes.resize( boxes.size() );
87  MB_CHK_SET_ERR( mbImpl->tag_get_data( boxSetTag, boxes, &scdBoxes[0] ), "failed to get tag data" );
88  ScdBox* dum = nullptr;
89  scdBoxes.erase(
90  std::remove_if(
91  scdBoxes.begin(),
92  scdBoxes.end(),
93  [dum](ScdBox* ptr) { return ptr == dum; }
94  ),
95  scdBoxes.end()
96  );
97  }
98  }
99 
100  for( std::vector< ScdBox* >::iterator vit = scdBoxes.begin(); vit != scdBoxes.end(); ++vit )
101  scd_boxes.insert( ( *vit )->box_set() );
102 
103  return MB_SUCCESS;
104 }

References box_dims_tag(), boxDimsTag, boxSetTag, moab::dum, moab::Range::empty(), moab::Interface::get_entities_by_type_and_tag(), moab::Range::insert(), MB_CHK_SET_ERR, MB_SUCCESS, MBENTITYSET, mbImpl, scdBoxes, searchedBoxes, moab::Range::size(), moab::Interface::tag_get_data(), and moab::Interface::UNION.

◆ find_boxes() [2/2]

ErrorCode moab::ScdInterface::find_boxes ( std::vector< ScdBox * > &  boxes)

Return all the structured mesh blocks in this MOAB instance, as ScdBox objects.

Return the structured blocks in this MOAB instance. If these were not searched for at instantiation time, then the search is done now.

Parameters
boxesVector of ScdBox objects representing structured mesh blocks

Definition at line 57 of file ScdInterface.cpp.

58 {
59  Range tmp_boxes;
60  ErrorCode rval = find_boxes( tmp_boxes );
61  if( MB_SUCCESS != rval ) return rval;
62 
63  for( Range::iterator rit = tmp_boxes.begin(); rit != tmp_boxes.end(); ++rit )
64  {
65  ScdBox* tmp_box = get_scd_box( *rit );
66  if( tmp_box )
67  scd_boxes.push_back( tmp_box );
68  else
69  rval = MB_FAILURE;
70  }
71 
72  return rval;
73 }

References moab::Range::begin(), moab::Range::end(), ErrorCode, get_scd_box(), and MB_SUCCESS.

Referenced by moab::HalfFacetRep::check_mixed_entity_type(), moab::Skinner::find_skin_scd(), and ScdInterface().

◆ get_boxes()

ErrorCode moab::ScdInterface::get_boxes ( std::vector< ScdBox * > &  boxes)

Return all the structured mesh blocks known by ScdInterface (does not search)

Return the structured blocks in this ScdInterface instance. Does not search for new boxes, just returns the contents of the list.

Parameters
boxesStructured boxes

Definition at line 471 of file ScdInterface.cpp.

472 {
473  std::copy( scdBoxes.begin(), scdBoxes.end(), std::back_inserter( boxes ) );
474  return MB_SUCCESS;
475 }

References MB_SUCCESS, and scdBoxes.

◆ get_indices()

ErrorCode moab::ScdInterface::get_indices ( const int *const  ldims,
const int *const  rdims,
const int *const  across_bdy,
int *  face_dims,
std::vector< int > &  shared_indices 
)
inlinestaticprivate

Definition at line 1371 of file ScdInterface.hpp.

1376 {
1377  // check for going across periodic bdy and face_dims not in my ldims (I'll always be on top in
1378  // that case)...
1379  if( across_bdy[0] > 0 && face_dims[0] != ldims[3] )
1380  face_dims[0] = face_dims[3] = ldims[3];
1381  else if( across_bdy[0] < 0 && face_dims[0] != ldims[0] )
1382  face_dims[0] = face_dims[3] = ldims[0];
1383  if( across_bdy[1] > 0 && face_dims[1] != ldims[4] )
1384  face_dims[1] = face_dims[4] = ldims[4];
1385  else if( across_bdy[1] < 0 && face_dims[1] != ldims[1] )
1386  face_dims[0] = face_dims[3] = ldims[1];
1387 
1388  for( int k = face_dims[2]; k <= face_dims[5]; k++ )
1389  for( int j = face_dims[1]; j <= face_dims[4]; j++ )
1390  for( int i = face_dims[0]; i <= face_dims[3]; i++ )
1391  shared_indices.push_back( gtol( ldims, i, j, k ) );
1392 
1393  if( across_bdy[0] > 0 && face_dims[0] != rdims[0] )
1394  face_dims[0] = face_dims[3] = rdims[0];
1395  else if( across_bdy[0] < 0 && face_dims[0] != rdims[3] )
1396  face_dims[0] = face_dims[3] = rdims[3];
1397  if( across_bdy[1] > 0 && face_dims[1] != rdims[1] )
1398  face_dims[1] = face_dims[4] = rdims[1];
1399  else if( across_bdy[1] < 0 && face_dims[1] != rdims[4] )
1400  face_dims[0] = face_dims[3] = rdims[4];
1401 
1402  for( int k = face_dims[2]; k <= face_dims[5]; k++ )
1403  for( int j = face_dims[1]; j <= face_dims[4]; j++ )
1404  for( int i = face_dims[0]; i <= face_dims[3]; i++ )
1405  shared_indices.push_back( gtol( rdims, i, j, k ) );
1406 
1407  return MB_SUCCESS;
1408 }

References gtol(), and MB_SUCCESS.

Referenced by get_shared_vertices().

◆ get_neighbor()

ErrorCode moab::ScdInterface::get_neighbor ( int  np,
int  nr,
const ScdParData spd,
const int *const  dijk,
int &  pto,
int *  rdims,
int *  facedims,
int *  across_bdy 
)
inlinestatic

Get information about the neighbor in the dijk[] direction, where dijk can be -1 or 1 for all 3 params.

Get information about the neighbor in the dijk[] direction, where dijk can be -1 or 1 for all 3 params

Parameters
np(in) Total # procs
nrProcessor from which neighbor is requested
spd(in) ScdParData containing part method, gdims, gperiodic data
dijk(*)(in) Direction being queried, = +/-1 or 0
pto(out) Processor holding the destination part
rdims(6)(out) Parametric min/max of destination part
facedims(6)(out) Parametric min/max of interface between pfrom and pto; if at the max in a periodic direction, set to global min of that direction
across_bdy(3)(out) If across_bdy[i] is -1(1), interface with pto is across periodic lower(upper) bdy in parameter i, 0 otherwise

Definition at line 1410 of file ScdInterface.hpp.

1418 {
1419  if( !dijk[0] && !dijk[1] && !dijk[2] )
1420  {
1421  // not going anywhere, return
1422  pto = -1;
1423  return MB_SUCCESS;
1424  }
1425 
1426  switch( spd.partMethod )
1427  {
1429  case -1:
1430  return get_neighbor_alljorkori( np, pfrom, spd.gDims, spd.gPeriodic, dijk, pto, rdims, facedims,
1431  across_bdy );
1432  case ScdParData::ALLJKBAL:
1433  return get_neighbor_alljkbal( np, pfrom, spd.gDims, spd.gPeriodic, dijk, pto, rdims, facedims, across_bdy );
1434  case ScdParData::SQIJ:
1435  return get_neighbor_sqij( np, pfrom, spd.gDims, spd.gPeriodic, dijk, pto, rdims, facedims, across_bdy );
1436  case ScdParData::SQJK:
1437  return get_neighbor_sqjk( np, pfrom, spd.gDims, spd.gPeriodic, dijk, pto, rdims, facedims, across_bdy );
1438  case ScdParData::SQIJK:
1439  return get_neighbor_sqijk( np, pfrom, spd.gDims, spd.gPeriodic, dijk, pto, rdims, facedims, across_bdy );
1440  default:
1441  break;
1442  }
1443 
1444  return MB_FAILURE;
1445 }

References moab::ScdParData::ALLJKBAL, moab::ScdParData::ALLJORKORI, moab::ScdParData::gDims, get_neighbor_alljkbal(), get_neighbor_alljorkori(), get_neighbor_sqij(), get_neighbor_sqijk(), get_neighbor_sqjk(), moab::ScdParData::gPeriodic, MB_SUCCESS, moab::ScdParData::partMethod, moab::ScdParData::SQIJ, moab::ScdParData::SQIJK, and moab::ScdParData::SQJK.

Referenced by get_shared_vertices().

◆ get_neighbor_alljkbal()

ErrorCode moab::ScdInterface::get_neighbor_alljkbal ( int  np,
int  pfrom,
const int *const  gdims,
const int *const  gperiodic,
const int *const  dijk,
int &  pto,
int *  rdims,
int *  facedims,
int *  across_bdy 
)
staticprivate

Definition at line 864 of file ScdInterface.cpp.

873 {
874  if( dijk[0] != 0 )
875  {
876  pto = -1;
877  return MB_SUCCESS;
878  }
879 
880  pto = -1;
881  across_bdy[0] = across_bdy[1] = across_bdy[2] = 0;
882 
883  int ldims[6], pijk[3], lperiodic[3];
884  ErrorCode rval = compute_partition_alljkbal( np, pfrom, gdims, gperiodic, ldims, lperiodic, pijk );
885  if( MB_SUCCESS != rval ) return rval;
886  assert( pijk[1] * pijk[2] == np );
887  pto = -1;
888  bool bot_j = pfrom< pijk[2], top_j = pfrom > np - pijk[2];
889  if( ( 1 == pijk[2] && dijk[2] ) || // 1d in j means no neighbors with dk != 0
890  ( !( pfrom % pijk[2] ) && -1 == dijk[2] ) || // at -k bdy
891  ( pfrom % pijk[2] == pijk[2] - 1 && 1 == dijk[2] ) || // at +k bdy
892  ( pfrom < pijk[2] && -1 == dijk[1] && !gperiodic[1] ) || // down and not periodic
893  ( pfrom >= np - pijk[2] && 1 == dijk[1] && !gperiodic[1] ) ) // up and not periodic
894  return MB_SUCCESS;
895 
896  pto = pfrom;
897  std::copy( ldims, ldims + 6, rdims );
898  std::copy( ldims, ldims + 6, facedims );
899 
900  if( 0 != dijk[1] )
901  {
902  pto = ( pto + dijk[1] * pijk[2] + np ) % np;
903  assert( pto >= 0 && pto < np );
904  int dj = ( gdims[4] - gdims[1] ) / pijk[1], extra = ( gdims[4] - gdims[1] ) % pijk[1];
905  if( -1 == dijk[1] )
906  {
907  facedims[4] = facedims[1];
908  if( bot_j )
909  {
910  // going across periodic lower bdy in j
911  rdims[4] = gdims[4];
912  across_bdy[1] = -1;
913  }
914  else
915  {
916  rdims[4] = ldims[1];
917  }
918  rdims[1] = rdims[4] - dj;
919  if( pto < extra ) rdims[1]--;
920  }
921  else
922  {
923  if( pfrom > np - pijk[2] ) facedims[4] = gdims[1];
924  facedims[1] = facedims[4];
925  if( top_j )
926  {
927  // going across periodic upper bdy in j
928  rdims[1] = gdims[1];
929  across_bdy[1] = 1;
930  }
931  else
932  {
933  rdims[1] = ldims[4];
934  }
935  rdims[4] = rdims[1] + dj;
936  if( pto < extra ) rdims[4]++;
937  }
938  }
939  if( 0 != dijk[2] )
940  {
941  pto = ( pto + dijk[2] ) % np;
942  assert( pto >= 0 && pto < np );
943  facedims[2] = facedims[5] = ( -1 == dijk[2] ? facedims[2] : facedims[5] );
944  int dk = ( gdims[5] - gdims[2] ) / pijk[2];
945  if( -1 == dijk[2] )
946  {
947  facedims[5] = facedims[2];
948  rdims[5] = ldims[2];
949  rdims[2] = rdims[5] - dk; // never any kextra for alljkbal
950  }
951  else
952  {
953  facedims[2] = facedims[5];
954  rdims[2] = ldims[5];
955  rdims[5] = rdims[2] + dk; // never any kextra for alljkbal
956  }
957  }
958 
959  assert( -1 == pto || ( rdims[0] >= gdims[0] && rdims[3] <= gdims[3] ) );
960  assert( -1 == pto || ( rdims[1] >= gdims[1] && ( rdims[4] <= gdims[4] || ( across_bdy[1] && bot_j ) ) ) );
961  assert( -1 == pto || ( rdims[2] >= gdims[2] && rdims[5] <= gdims[5] ) );
962  assert( -1 == pto || ( ( facedims[0] >= rdims[0] ||
963  ( gperiodic[0] && rdims[3] == gdims[3] + 1 && facedims[0] == gdims[0] ) ) ) );
964  assert( -1 == pto || ( facedims[3] <= rdims[3] ) );
965  assert( -1 == pto || ( ( facedims[1] >= rdims[1] ||
966  ( gperiodic[1] && rdims[4] == gdims[4] + 1 && facedims[1] == gdims[1] ) ) ) );
967  assert( -1 == pto || ( facedims[4] <= rdims[4] ) );
968  assert( -1 == pto || ( facedims[2] >= rdims[2] ) );
969  assert( -1 == pto || ( facedims[5] <= rdims[5] ) );
970  assert( -1 == pto || ( facedims[0] >= ldims[0] ) );
971  assert( -1 == pto || ( facedims[3] <= ldims[3] ) );
972  assert( -1 == pto || ( facedims[1] >= ldims[1] ) );
973  assert( -1 == pto || ( facedims[4] <= ldims[4] ) );
974  assert( -1 == pto || ( facedims[2] >= ldims[2] ) );
975  assert( -1 == pto || ( facedims[5] <= ldims[5] ) );
976 
977  return MB_SUCCESS;
978 }

References compute_partition_alljkbal(), ErrorCode, and MB_SUCCESS.

Referenced by get_neighbor().

◆ get_neighbor_alljorkori()

ErrorCode moab::ScdInterface::get_neighbor_alljorkori ( int  np,
int  pfrom,
const int *const  gdims,
const int *const  gperiodic,
const int *const  dijk,
int &  pto,
int *  rdims,
int *  facedims,
int *  across_bdy 
)
staticprivate

Definition at line 1344 of file ScdInterface.cpp.

1353 {
1354  ErrorCode rval = MB_SUCCESS;
1355  pto = -1;
1356  if( np == 1 ) return MB_SUCCESS;
1357 
1358  int pijk[3], lperiodic[3], ldims[6];
1359  rval = compute_partition_alljorkori( np, pfrom, gdims, gperiodic, ldims, lperiodic, pijk );
1360  if( MB_SUCCESS != rval ) return rval;
1361 
1362  int ind = -1;
1363  across_bdy[0] = across_bdy[1] = across_bdy[2] = 0;
1364 
1365  for( int i = 0; i < 3; i++ )
1366  {
1367  if( pijk[i] > 1 )
1368  {
1369  ind = i;
1370  break;
1371  }
1372  }
1373 
1374  assert( -1 < ind );
1375 
1376  if( !dijk[ind] )
1377  // no neighbor, pto is already -1, return
1378  return MB_SUCCESS;
1379 
1380  bool is_periodic = ( ( gperiodic[0] && ind == 0 ) || ( gperiodic[1] && ind == 1 ) );
1381  if( dijk[( ind + 1 ) % 3] || dijk[( ind + 2 ) % 3] || // stepping in either other two directions
1382  ( !is_periodic && ldims[ind] == gdims[ind] && dijk[ind] == -1 ) || // lower side and going lower
1383  ( !is_periodic && ldims[3 + ind] >= gdims[3 + ind] &&
1384  dijk[ind] == 1 ) ) // not >= because ldims is only > gdims when periodic;
1385  // higher side and going higher
1386  return MB_SUCCESS;
1387 
1388  std::copy( ldims, ldims + 6, facedims );
1389  std::copy( ldims, ldims + 6, rdims );
1390 
1391  int dind = ( gdims[ind + 3] - gdims[ind] ) / np;
1392  int extra = ( gdims[ind + 3] - gdims[ind] ) % np;
1393  if( -1 == dijk[ind] && pfrom )
1394  {
1395  // actual left neighbor
1396  pto = pfrom - 1; // no need for %np, because pfrom > 0
1397  facedims[ind + 3] = facedims[ind];
1398  rdims[ind + 3] = ldims[ind];
1399  rdims[ind] = rdims[ind + 3] - dind - ( pto < extra ? 1 : 0 );
1400  }
1401  else if( 1 == dijk[ind] && pfrom < np - 1 )
1402  {
1403  // actual right neighbor
1404  pto = pfrom + 1;
1405  facedims[ind] = facedims[ind + 3];
1406  rdims[ind] = ldims[ind + 3];
1407  rdims[ind + 3] = rdims[ind] + dind + ( pto < extra ? 1 : 0 );
1408  if( is_periodic && pfrom == np - 2 ) rdims[ind + 3]++; // neighbor is on periodic bdy
1409  }
1410  else if( -1 == dijk[ind] && !pfrom && gperiodic[ind] )
1411  {
1412  // downward across periodic bdy
1413  pto = np - 1;
1414  facedims[ind + 3] = facedims[ind] = gdims[ind]; // by convention, facedims is within gdims, so lower value
1415  rdims[ind + 3] =
1416  gdims[ind + 3] + 1; // by convention, local dims one greater than gdims to indicate global lower value
1417  rdims[ind] = rdims[ind + 3] - dind - 1;
1418  across_bdy[ind] = -1;
1419  }
1420  else if( 1 == dijk[ind] && pfrom == np - 1 && is_periodic )
1421  {
1422  // right across periodic bdy
1423  pto = 0;
1424  facedims[ind + 3] = facedims[ind] = gdims[ind]; // by convention, facedims is within gdims, so lowest value
1425  rdims[ind] = gdims[ind];
1426  rdims[ind + 3] = rdims[ind] + dind + ( pto < extra ? 1 : 0 );
1427  across_bdy[ind] = 1;
1428  }
1429 
1430  assert( -1 == pto || ( rdims[0] >= gdims[0] && ( rdims[3] <= gdims[3] || ( across_bdy[0] && !pfrom ) ) ) );
1431  assert( -1 == pto || ( rdims[1] >= gdims[1] && ( rdims[4] <= gdims[4] || ( across_bdy[1] && !pfrom ) ) ) );
1432  assert( -1 == pto || ( rdims[2] >= gdims[2] && rdims[5] <= gdims[5] ) );
1433  assert( -1 == pto || ( facedims[0] >= rdims[0] && facedims[3] <= rdims[3] ) );
1434  assert( -1 == pto || ( facedims[1] >= rdims[1] && facedims[4] <= rdims[4] ) );
1435  assert( -1 == pto || ( facedims[2] >= rdims[2] && facedims[5] <= rdims[5] ) );
1436  assert( -1 == pto || ( facedims[0] >= ldims[0] && facedims[3] <= ldims[3] ) );
1437  assert( -1 == pto || ( facedims[1] >= ldims[1] && facedims[4] <= ldims[4] ) );
1438  assert( -1 == pto || ( facedims[2] >= ldims[2] && facedims[5] <= ldims[5] ) );
1439 
1440  return rval;
1441 }

References compute_partition_alljorkori(), ErrorCode, and MB_SUCCESS.

Referenced by get_neighbor().

◆ get_neighbor_sqij()

ErrorCode moab::ScdInterface::get_neighbor_sqij ( int  np,
int  pfrom,
const int *const  gdims,
const int *const  gperiodic,
const int *const  dijk,
int &  pto,
int *  rdims,
int *  facedims,
int *  across_bdy 
)
staticprivate

Definition at line 980 of file ScdInterface.cpp.

989 {
990  if( dijk[2] != 0 )
991  {
992  // for sqij, there is no k neighbor, ever
993  pto = -1;
994  return MB_SUCCESS;
995  }
996 
997  pto = -1;
998  across_bdy[0] = across_bdy[1] = across_bdy[2] = 0;
999  int lperiodic[3], pijk[3], ldims[6];
1000  ErrorCode rval = compute_partition_sqij( np, pfrom, gdims, gperiodic, ldims, lperiodic, pijk );
1001  if( MB_SUCCESS != rval ) return rval;
1002  assert( pijk[0] * pijk[1] == np );
1003  pto = -1;
1004  bool top_i = 0, top_j = 0, bot_i = 0, bot_j = 0;
1005  int ni = pfrom % pijk[0], nj = pfrom / pijk[0]; // row / column number of me
1006  if( ni == pijk[0] - 1 ) top_i = 1;
1007  if( nj == pijk[1] - 1 ) top_j = 1;
1008  if( !ni ) bot_i = 1;
1009  if( !nj ) bot_j = 1;
1010  if( ( !gperiodic[0] && bot_i && -1 == dijk[0] ) || // left and not periodic
1011  ( !gperiodic[0] && top_i && 1 == dijk[0] ) || // right and not periodic
1012  ( !gperiodic[1] && bot_j && -1 == dijk[1] ) || // bottom and not periodic
1013  ( !gperiodic[1] && top_j && 1 == dijk[1] ) ) // top and not periodic
1014  return MB_SUCCESS;
1015 
1016  std::copy( ldims, ldims + 6, facedims );
1017  std::copy( ldims, ldims + 6, rdims );
1018  pto = pfrom;
1019  int j = gdims[4] - gdims[1], dj = j / pijk[1], jextra = ( gdims[4] - gdims[1] ) % dj, i = gdims[3] - gdims[0],
1020  di = i / pijk[0], iextra = ( gdims[3] - gdims[0] ) % di;
1021 
1022  if( 0 != dijk[0] )
1023  {
1024  pto = ( ni + dijk[0] + pijk[0] ) % pijk[0]; // get pto's ni value
1025  pto = nj * pijk[0] + pto; // then convert to pto
1026  assert( pto >= 0 && pto < np );
1027  if( -1 == dijk[0] )
1028  {
1029  facedims[3] = facedims[0];
1030  if( bot_i )
1031  {
1032  // going across lower periodic bdy in i
1033  across_bdy[0] = -1;
1034  rdims[3] = gdims[3] + 1; // +1 because ldims[3] on remote proc is gdims[3]+1
1035  rdims[0] = rdims[3] - di - 1; // -1 to account for rdims[3] being one larger
1036  }
1037  else
1038  {
1039  rdims[3] = ldims[0];
1040  rdims[0] = rdims[3] - di;
1041  }
1042 
1043  if( pto % pijk[0] < iextra ) rdims[0]--;
1044  }
1045  else
1046  {
1047  if( top_i )
1048  {
1049  // going across lower periodic bdy in i
1050  facedims[3] = gdims[0];
1051  across_bdy[0] = 1;
1052  }
1053  facedims[0] = facedims[3];
1054  rdims[0] = ( top_i ? gdims[0] : ldims[3] );
1055  rdims[3] = rdims[0] + di;
1056  if( pto % pijk[0] < iextra ) rdims[3]++;
1057  if( gperiodic[0] && ni == pijk[0] - 2 ) rdims[3]++; // remote proc is top_i and periodic
1058  }
1059  }
1060  if( 0 != dijk[1] )
1061  {
1062  pto = ( pto + dijk[1] * pijk[0] + np ) % np;
1063  assert( pto >= 0 && pto < np );
1064  if( -1 == dijk[1] )
1065  {
1066  facedims[4] = facedims[1];
1067  if( bot_j )
1068  {
1069  // going across lower periodic bdy in j
1070  rdims[4] = gdims[4] + 1; // +1 because ldims[4] on remote proc is gdims[4]+1
1071  rdims[1] = rdims[4] - dj - 1; // -1 to account for gdims[4] being one larger
1072  across_bdy[1] = -1;
1073  }
1074  else
1075  {
1076  rdims[4] = ldims[1];
1077  rdims[1] = rdims[4] - dj;
1078  }
1079  if( pto / pijk[0] < jextra ) rdims[1]--;
1080  }
1081  else
1082  {
1083  if( top_j )
1084  {
1085  // going across lower periodic bdy in j
1086  facedims[4] = gdims[1];
1087  rdims[1] = gdims[1];
1088  across_bdy[1] = 1;
1089  }
1090  else
1091  {
1092  rdims[1] = ldims[4];
1093  }
1094  facedims[1] = facedims[4];
1095  rdims[4] = rdims[1] + dj;
1096  if( nj + 1 < jextra ) rdims[4]++;
1097  if( gperiodic[1] && nj == pijk[1] - 2 ) rdims[4]++; // remote proc is top_j and periodic
1098  }
1099  }
1100 
1101  // rdims within gdims
1102  assert( -1 == pto || ( rdims[0] >= gdims[0] &&
1103  ( rdims[3] <= gdims[3] + ( gperiodic[0] && pto % pijk[0] == pijk[0] - 1 ? 1 : 0 ) ) ) );
1104  assert( -1 == pto || ( rdims[1] >= gdims[1] &&
1105  ( rdims[4] <= gdims[4] + ( gperiodic[1] && pto / pijk[0] == pijk[1] - 1 ? 1 : 0 ) ) ) );
1106  assert( -1 == pto || ( rdims[2] >= gdims[2] && rdims[5] <= gdims[5] ) );
1107  // facedims within rdims
1108  assert( -1 == pto || ( ( facedims[0] >= rdims[0] ||
1109  ( gperiodic[0] && pto % pijk[0] == pijk[0] - 1 && facedims[0] == gdims[0] ) ) ) );
1110  assert( -1 == pto || ( facedims[3] <= rdims[3] ) );
1111  assert( -1 == pto || ( ( facedims[1] >= rdims[1] ||
1112  ( gperiodic[1] && pto / pijk[0] == pijk[1] - 1 && facedims[1] == gdims[1] ) ) ) );
1113  assert( -1 == pto || ( facedims[4] <= rdims[4] ) );
1114  assert( -1 == pto || ( facedims[2] >= rdims[2] && facedims[5] <= rdims[5] ) );
1115  // facedims within ldims
1116  assert( -1 == pto || ( ( facedims[0] >= ldims[0] || ( top_i && facedims[0] == gdims[0] ) ) ) );
1117  assert( -1 == pto || ( facedims[3] <= ldims[3] ) );
1118  assert( -1 == pto || ( ( facedims[1] >= ldims[1] || ( gperiodic[1] && top_j && facedims[1] == gdims[1] ) ) ) );
1119  assert( -1 == pto || ( facedims[4] <= ldims[4] ) );
1120  assert( -1 == pto || ( facedims[2] >= ldims[2] && facedims[5] <= ldims[5] ) );
1121 
1122  return MB_SUCCESS;
1123 }

References compute_partition_sqij(), ErrorCode, and MB_SUCCESS.

Referenced by get_neighbor().

◆ get_neighbor_sqijk()

ErrorCode moab::ScdInterface::get_neighbor_sqijk ( int  np,
int  pfrom,
const int *const  gdims,
const int *const  gperiodic,
const int *const  dijk,
int &  pto,
int *  rdims,
int *  facedims,
int *  across_bdy 
)
staticprivate

Definition at line 1243 of file ScdInterface.cpp.

1252 {
1253  if( gperiodic[0] || gperiodic[1] || gperiodic[2] ) return MB_FAILURE;
1254 
1255  pto = -1;
1256  across_bdy[0] = across_bdy[1] = across_bdy[2] = 0;
1257  int pijk[3], lperiodic[3], ldims[6];
1258  ErrorCode rval = compute_partition_sqijk( np, pfrom, gdims, gperiodic, ldims, lperiodic, pijk );
1259  if( MB_SUCCESS != rval ) return rval;
1260  assert( pijk[0] * pijk[1] * pijk[2] == np );
1261  pto = -1;
1262  bool top[3] = { false, false, false }, bot[3] = { false, false, false };
1263  // nijk: rank in i/j/k direction
1264  int nijk[3] = { pfrom % pijk[0], ( pfrom % ( pijk[0] * pijk[1] ) ) / pijk[0], pfrom / ( pijk[0] * pijk[1] ) };
1265 
1266  for( int i = 0; i < 3; i++ )
1267  {
1268  if( nijk[i] == pijk[i] - 1 ) top[i] = true;
1269  if( !nijk[i] ) bot[i] = true;
1270  if( ( !gperiodic[i] && bot[i] && -1 == dijk[i] ) || // downward && not periodic
1271  ( !gperiodic[i] && top[i] && 1 == dijk[i] ) ) // upward && not periodic
1272  return MB_SUCCESS;
1273  }
1274 
1275  std::copy( ldims, ldims + 6, facedims );
1276  std::copy( ldims, ldims + 6, rdims );
1277  pto = pfrom;
1278  int delijk[3], extra[3];
1279  // nijk_to: rank of pto in i/j/k direction
1280  int nijk_to[3];
1281  for( int i = 0; i < 3; i++ )
1282  {
1283  delijk[i] = ( gdims[i + 3] == gdims[i] ? 0 : ( gdims[i + 3] - gdims[i] ) / pijk[i] );
1284  extra[i] = ( gdims[i + 3] - gdims[i] ) % delijk[i];
1285  nijk_to[i] = ( nijk[i] + dijk[i] + pijk[i] ) % pijk[i];
1286  }
1287  pto = nijk_to[2] * pijk[0] * pijk[1] + nijk_to[1] * pijk[0] + nijk_to[0];
1288  assert( pto >= 0 && pto < np );
1289  for( int i = 0; i < 3; i++ )
1290  {
1291  if( 0 != dijk[i] )
1292  {
1293  if( -1 == dijk[i] )
1294  {
1295  facedims[i + 3] = facedims[i];
1296  if( bot[i] )
1297  {
1298  // going across lower periodic bdy in i
1299  rdims[i + 3] = gdims[i + 3] + 1; // +1 because ldims[4] on remote proc is gdims[4]+1
1300  across_bdy[i] = -1;
1301  }
1302  else
1303  {
1304  rdims[i + 3] = ldims[i];
1305  }
1306  rdims[i] = rdims[i + 3] - delijk[i];
1307  if( nijk[i] < extra[i] ) rdims[i]--;
1308  }
1309  else
1310  {
1311  if( top[i] )
1312  {
1313  // going across upper periodic bdy in i
1314  rdims[i] = gdims[i];
1315  facedims[i + 3] = gdims[i];
1316  across_bdy[i] = 1;
1317  }
1318  else
1319  {
1320  rdims[i] = ldims[i + 3];
1321  }
1322  facedims[i] = facedims[i + 3];
1323  rdims[i + 3] = rdims[i] + delijk[i];
1324  if( nijk[i] < extra[i] ) rdims[i + 3]++;
1325  if( gperiodic[i] && nijk[i] == dijk[i] - 2 ) rdims[i + 3]++; // +1 because next proc is on periodic bdy
1326  }
1327  }
1328  }
1329 
1330  assert( -1 != pto );
1331 #ifndef NDEBUG
1332  for( int i = 0; i < 3; i++ )
1333  {
1334  assert( ( rdims[i] >= gdims[i] && ( rdims[i + 3] <= gdims[i + 3] || ( across_bdy[i] && bot[i] ) ) ) );
1335  assert( ( ( facedims[i] >= rdims[i] ||
1336  ( gperiodic[i] && rdims[i + 3] == gdims[i + 3] && facedims[i] == gdims[i] ) ) ) );
1337  assert( ( facedims[i] >= ldims[i] && facedims[i + 3] <= ldims[i + 3] ) );
1338  }
1339 #endif
1340 
1341  return MB_SUCCESS;
1342 }

References compute_partition_sqijk(), ErrorCode, and MB_SUCCESS.

Referenced by get_neighbor().

◆ get_neighbor_sqjk()

ErrorCode moab::ScdInterface::get_neighbor_sqjk ( int  np,
int  pfrom,
const int *const  gdims,
const int *const  gperiodic,
const int *const  dijk,
int &  pto,
int *  rdims,
int *  facedims,
int *  across_bdy 
)
staticprivate

Definition at line 1125 of file ScdInterface.cpp.

1134 {
1135  if( dijk[0] != 0 )
1136  {
1137  pto = -1;
1138  return MB_SUCCESS;
1139  }
1140 
1141  pto = -1;
1142  across_bdy[0] = across_bdy[1] = across_bdy[2] = 0;
1143  int pijk[3], lperiodic[3], ldims[6];
1144  ErrorCode rval = compute_partition_sqjk( np, pfrom, gdims, gperiodic, ldims, lperiodic, pijk );
1145  if( MB_SUCCESS != rval ) return rval;
1146  assert( pijk[1] * pijk[2] == np );
1147  pto = -1;
1148  bool top_j = 0, top_k = 0, bot_j = 0, bot_k = 0;
1149  int nj = pfrom % pijk[1], nk = pfrom / pijk[1];
1150  if( nj == pijk[1] - 1 ) top_j = 1;
1151  if( nk == pijk[2] - 1 ) top_k = 1;
1152  if( !nj ) bot_j = 1;
1153  if( !nk ) bot_k = 1;
1154  if( ( !gperiodic[1] && bot_j && -1 == dijk[1] ) || // down and not periodic
1155  ( !gperiodic[1] && top_j && 1 == dijk[1] ) || // up and not periodic
1156  ( bot_k && -1 == dijk[2] ) || // k- bdy
1157  ( top_k && 1 == dijk[2] ) ) // k+ bdy
1158  return MB_SUCCESS;
1159 
1160  std::copy( ldims, ldims + 6, facedims );
1161  std::copy( ldims, ldims + 6, rdims );
1162  pto = pfrom;
1163  int dj = ( gdims[4] - gdims[1] ) / pijk[1], jextra = ( gdims[4] - gdims[1] ) % dj,
1164  dk = ( gdims[5] == gdims[2] ? 0 : ( gdims[5] - gdims[2] ) / pijk[2] ),
1165  kextra = ( gdims[5] - gdims[2] ) - dk * pijk[2];
1166  assert( ( dj * pijk[1] + jextra == ( gdims[4] - gdims[1] ) ) &&
1167  ( dk * pijk[2] + kextra == ( gdims[5] - gdims[2] ) ) );
1168  if( 0 != dijk[1] )
1169  {
1170  pto = ( nj + dijk[1] + pijk[1] ) % pijk[1]; // get pto's ni value
1171  pto = nk * pijk[1] + pto; // then convert to pto
1172  assert( pto >= 0 && pto < np );
1173  if( -1 == dijk[1] )
1174  {
1175  facedims[4] = facedims[1];
1176  if( bot_j )
1177  {
1178  // going across lower periodic bdy in j
1179  rdims[4] = gdims[4] + 1; // +1 because ldims[4] on remote proc is gdims[4]+1
1180  across_bdy[1] = -1;
1181  }
1182  else
1183  {
1184  rdims[4] = ldims[1];
1185  }
1186  rdims[1] = rdims[4] - dj;
1187  if( nj < jextra ) rdims[1]--;
1188  }
1189  else
1190  {
1191  if( top_j )
1192  {
1193  // going across upper periodic bdy in j
1194  rdims[1] = gdims[1];
1195  facedims[4] = gdims[1];
1196  across_bdy[1] = 1;
1197  }
1198  else
1199  {
1200  rdims[1] = ldims[4];
1201  }
1202  facedims[1] = facedims[4];
1203  rdims[4] = rdims[1] + dj;
1204  if( nj < jextra ) rdims[4]++;
1205  if( gperiodic[1] && nj == dijk[1] - 2 ) rdims[4]++; // +1 because next proc is on periodic bdy
1206  }
1207  }
1208  if( 0 != dijk[2] )
1209  {
1210  pto = ( pto + dijk[2] * pijk[1] + np ) % np;
1211  assert( pto >= 0 && pto < np );
1212  if( -1 == dijk[2] )
1213  {
1214  facedims[5] = facedims[2];
1215  rdims[5] = ldims[2];
1216  rdims[2] -= dk;
1217  if( pto / pijk[1] < kextra ) rdims[2]--;
1218  }
1219  else
1220  {
1221  facedims[2] = facedims[5];
1222  rdims[2] = ldims[5];
1223  rdims[5] += dk;
1224  if( pto / pijk[1] < kextra ) rdims[5]++;
1225  }
1226  }
1227 
1228  assert( -1 == pto || ( rdims[0] >= gdims[0] && rdims[3] <= gdims[3] ) );
1229  assert( -1 == pto || ( rdims[1] >= gdims[1] && ( rdims[4] <= gdims[4] || ( across_bdy[1] && bot_j ) ) ) );
1230  assert( -1 == pto || ( rdims[2] >= gdims[2] && rdims[5] <= gdims[5] ) );
1231  assert( -1 == pto || ( facedims[0] >= rdims[0] && facedims[3] <= rdims[3] ) );
1232  assert( -1 == pto ||
1233  ( ( facedims[1] >= rdims[1] || ( gperiodic[1] && rdims[4] == gdims[4] && facedims[1] == gdims[1] ) ) ) );
1234  assert( -1 == pto || ( facedims[4] <= rdims[4] ) );
1235  assert( -1 == pto || ( facedims[2] >= rdims[2] && facedims[5] <= rdims[5] ) );
1236  assert( -1 == pto || ( facedims[0] >= ldims[0] && facedims[3] <= ldims[3] ) );
1237  assert( -1 == pto || ( facedims[1] >= ldims[1] && facedims[4] <= ldims[4] ) );
1238  assert( -1 == pto || ( facedims[2] >= ldims[2] && facedims[5] <= ldims[5] ) );
1239 
1240  return MB_SUCCESS;
1241 }

References compute_partition_sqjk(), ErrorCode, and MB_SUCCESS.

Referenced by get_neighbor().

◆ get_scd_box()

ScdBox * moab::ScdInterface::get_scd_box ( EntityHandle  eh)

Return the ScdBox corresponding to the entity set passed in.

If the entity isn't a structured box set, NULL is returned.

Parameters
ehEntity whose box is being queried

Definition at line 106 of file ScdInterface.cpp.

107 {
108  ScdBox* scd_box = NULL;
109  if( !box_set_tag( false ) ) return scd_box;
110 
111  mbImpl->tag_get_data( box_set_tag(), &eh, 1, &scd_box );
112  return scd_box;
113 }

References box_set_tag(), mbImpl, and moab::Interface::tag_get_data().

Referenced by find_boxes(), and tag_shared_vertices().

◆ get_shared_vertices()

ErrorCode moab::ScdInterface::get_shared_vertices ( ParallelComm pcomm,
ScdBox box,
std::vector< int > &  procs,
std::vector< int > &  offsets,
std::vector< int > &  shared_indices 
)
staticprivate

Get vertices shared with other processors.

get shared vertices for alljorkori partition scheme

Shared vertices returned as indices into each proc's handle space

Parameters
boxBox used to get parametric space info
procsProcs this proc shares vertices with
offsetsOffsets into indices list for each proc
shared_indiceslocal/remote indices of shared vertices

Definition at line 1445 of file ScdInterface.cpp.

1450 {
1451  return MB_FAILURE;
1452 #else
1453 ErrorCode ScdInterface::get_shared_vertices( ParallelComm* pcomm,
1454  ScdBox* box,
1455  std::vector< int >& procs,
1456  std::vector< int >& offsets,
1457  std::vector< int >& shared_indices )
1458 {
1459  // get index of partitioned dimension
1460  const int* ldims = box->box_dims();
1461  ErrorCode rval;
1462  int ijkrem[6], ijkface[6], across_bdy[3];
1463 
1464  for( int k = -1; k <= 1; k++ )
1465  {
1466  for( int j = -1; j <= 1; j++ )
1467  {
1468  for( int i = -1; i <= 1; i++ )
1469  {
1470  if( !i && !j && !k ) continue;
1471  int pto;
1472  int dijk[] = { i, j, k };
1473  rval = get_neighbor( pcomm->proc_config().proc_size(), pcomm->proc_config().proc_rank(),
1474  box->par_data(), dijk, pto, ijkrem, ijkface, across_bdy );
1475  if( MB_SUCCESS != rval ) return rval;
1476  if( -1 != pto )
1477  {
1478  if( procs.empty() || pto != *procs.rbegin() )
1479  {
1480  procs.push_back( pto );
1481  offsets.push_back( shared_indices.size() );
1482  }
1483  rval = get_indices( ldims, ijkrem, across_bdy, ijkface, shared_indices );
1484  if( MB_SUCCESS != rval ) return rval;
1485 
1486  // check indices against known #verts on local and remote
1487  // begin of this block is shared_indices[*offsets.rbegin()], end is
1488  // shared_indices.end(), halfway is
1489  // (shared_indices.size()-*offsets.rbegin())/2
1490 #ifndef NDEBUG
1491  int start_idx = *offsets.rbegin(), end_idx = shared_indices.size(),
1492  mid_idx = ( start_idx + end_idx ) / 2;
1493 
1494  int num_local_verts = ( ldims[3] - ldims[0] + 1 ) * ( ldims[4] - ldims[1] + 1 ) *
1495  ( -1 == ldims[2] && -1 == ldims[5] ? 1 : ( ldims[5] - ldims[2] + 1 ) ),
1496  num_remote_verts = ( ijkrem[3] - ijkrem[0] + 1 ) * ( ijkrem[4] - ijkrem[1] + 1 ) *
1497  ( -1 == ijkrem[2] && -1 == ijkrem[5] ? 1 : ( ijkrem[5] - ijkrem[2] + 1 ) );
1498 
1499  assert(
1500  *std::min_element( &shared_indices[start_idx], &shared_indices[mid_idx] ) >= 0 &&
1501  *std::max_element( &shared_indices[start_idx], &shared_indices[mid_idx] ) < num_local_verts &&
1502  *std::min_element( &shared_indices[mid_idx], &shared_indices[end_idx] ) >= 0 &&
1503  *std::max_element( &shared_indices[mid_idx], &shared_indices[end_idx] ) < num_remote_verts );
1504 #endif
1505  }
1506  }
1507  }
1508  }
1509 
1510  offsets.push_back( shared_indices.size() );
1511 
1512  return MB_SUCCESS;
1513 #endif
1514 }

References moab::ScdBox::box_dims(), ErrorCode, get_indices(), get_neighbor(), MB_SUCCESS, moab::ScdBox::par_data(), moab::ParallelComm::proc_config(), moab::ProcConfig::proc_rank(), and moab::ProcConfig::proc_size().

Referenced by tag_shared_vertices().

◆ global_box_dims_tag()

Tag moab::ScdInterface::global_box_dims_tag ( bool  create_if_missing = true)

Return the tag marking the global lower and upper corners of boxes.

Parameters
create_if_missingIf the tag does not yet exist, create it

Definition at line 400 of file ScdInterface.cpp.

401 {
402  // Reset globalBoxDimsTag in case it has been deleted (e.g. by Core::clean_up_failed_read)
403  if( globalBoxDimsTag )
404  {
405  std::string tag_name;
407  }
408 
409  if( globalBoxDimsTag || !create_if_missing ) return globalBoxDimsTag;
410 
411  ErrorCode rval =
413  if( MB_SUCCESS != rval ) return 0;
414  return globalBoxDimsTag;
415 }

References ErrorCode, globalBoxDimsTag, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_NOT_FOUND, MB_TAG_SPARSE, MB_TYPE_INTEGER, mbImpl, moab::Interface::tag_get_handle(), and moab::Interface::tag_get_name().

◆ gtol()

int moab::ScdInterface::gtol ( const int *  gijk,
int  i,
int  j,
int  k 
)
inlinestaticprivate

Definition at line 1365 of file ScdInterface.hpp.

1366 {
1367  return ( ( k - gijk[2] ) * ( gijk[3] - gijk[0] + 1 ) * ( gijk[4] - gijk[1] + 1 ) +
1368  ( j - gijk[1] ) * ( gijk[3] - gijk[0] + 1 ) + i - gijk[0] );
1369 }

Referenced by get_indices().

◆ impl()

Interface * moab::ScdInterface::impl ( ) const

Return the MOAB Interface instance *.

Definition at line 52 of file ScdInterface.cpp.

53 {
54  return mbImpl;
55 }

References mbImpl.

Referenced by moab::ScdBox::get_adj_edge_or_face(), and moab::ScdBox::get_params().

◆ part_method_tag()

Tag moab::ScdInterface::part_method_tag ( bool  create_if_missing = true)

Return the tag marking the partitioning method used to partition the box in parallel.

Parameters
create_if_missingIf the tag does not yet exist, create it

Definition at line 417 of file ScdInterface.cpp.

418 {
419  // Reset partMethodTag in case it has been deleted (e.g. by Core::clean_up_failed_read)
420  if( partMethodTag )
421  {
422  std::string tag_name;
423  if( MB_TAG_NOT_FOUND == mbImpl->tag_get_name( partMethodTag, tag_name ) ) partMethodTag = NULL;
424  }
425 
426  if( partMethodTag || !create_if_missing ) return partMethodTag;
427 
428  ErrorCode rval =
430  if( MB_SUCCESS != rval ) return 0;
431  return partMethodTag;
432 }

References ErrorCode, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_NOT_FOUND, MB_TAG_SPARSE, MB_TYPE_INTEGER, mbImpl, partMethodTag, moab::Interface::tag_get_handle(), and moab::Interface::tag_get_name().

Referenced by moab::NCHelper::create_conventional_tags().

◆ remove_box()

ErrorCode moab::ScdInterface::remove_box ( ScdBox box)
protected

Remove the box from the list on ScdInterface.

Definition at line 452 of file ScdInterface.cpp.

453 {
454  std::vector< ScdBox* >::iterator vit = std::find( scdBoxes.begin(), scdBoxes.end(), box );
455  if( vit != scdBoxes.end() )
456  {
457  scdBoxes.erase( vit );
458  return MB_SUCCESS;
459  }
460  else
461  return MB_FAILURE;
462 }

References MB_SUCCESS, and scdBoxes.

Referenced by moab::ScdBox::~ScdBox().

◆ tag_shared_vertices() [1/2]

ErrorCode moab::ScdInterface::tag_shared_vertices ( ParallelComm pcomm,
EntityHandle  seth 
)
inline

Tag vertices with sharing data for parallel representations.

Given the ParallelComm object to use, tag the vertices shared with other processors

Definition at line 1447 of file ScdInterface.hpp.

1448 {
1449  ScdBox* box = get_scd_box( seth );
1450  if( !box )
1451  {
1452  // look for contained boxes
1453  Range tmp_range;
1454  ErrorCode rval = mbImpl->get_entities_by_type( seth, MBENTITYSET, tmp_range );
1455  if( MB_SUCCESS != rval ) return rval;
1456  for( Range::iterator rit = tmp_range.begin(); rit != tmp_range.end(); ++rit )
1457  {
1458  box = get_scd_box( *rit );
1459  if( box ) break;
1460  }
1461  }
1462 
1463  if( !box ) return MB_FAILURE;
1464 
1465  return tag_shared_vertices( pcomm, box );
1466 }

References moab::Range::begin(), moab::Range::end(), ErrorCode, moab::Interface::get_entities_by_type(), get_scd_box(), MB_SUCCESS, MBENTITYSET, and mbImpl.

Referenced by construct_box(), moab::ParallelComm::resolve_shared_ents(), and tag_shared_vertices().

◆ tag_shared_vertices() [2/2]

ErrorCode moab::ScdInterface::tag_shared_vertices ( ParallelComm pcomm,
ScdBox box 
)

Tag vertices with sharing data for parallel representations.

Given the ParallelComm object to use, tag the vertices shared with other processors

Definition at line 736 of file ScdInterface.cpp.

737 {
738  return MB_FAILURE;
739 #else
740 ErrorCode ScdInterface::tag_shared_vertices( ParallelComm* pcomm, ScdBox* box )
741 {
742  EntityHandle seth = box->box_set();
743 
744  // check the # ents in the box against the num in the set, to make sure it's only 1 box;
745  // reuse tmp_range
746  Range tmp_range;
747  ErrorCode rval = mbImpl->get_entities_by_dimension( seth, box->box_dimension(), tmp_range );
748  if( MB_SUCCESS != rval ) return rval;
749  if( box->num_elements() != (int)tmp_range.size() ) return MB_FAILURE;
750 
751  const int* gdims = box->par_data().gDims;
752  if( ( gdims[0] == gdims[3] && gdims[1] == gdims[4] && gdims[2] == gdims[5] ) || -1 == box->par_data().partMethod )
753  return MB_FAILURE;
754 
755  // ok, we have a partitioned box; get the vertices shared with other processors
756  std::vector< int > procs, offsets, shared_indices;
757  rval = get_shared_vertices( pcomm, box, procs, offsets, shared_indices );
758  if( MB_SUCCESS != rval ) return rval;
759 
760  // post receives for start handles once we know how many to look for
761  std::vector< MPI_Request > recv_reqs( procs.size(), MPI_REQUEST_NULL ), send_reqs( procs.size(), MPI_REQUEST_NULL );
762  std::vector< EntityHandle > rhandles( 4 * procs.size() ), shandles( 4 );
763  for( unsigned int i = 0; i < procs.size(); i++ )
764  {
765  int success = MPI_Irecv( (void*)&rhandles[4 * i], 4 * sizeof( EntityHandle ), MPI_UNSIGNED_CHAR, procs[i], 1,
766  pcomm->proc_config().proc_comm(), &recv_reqs[i] );
767  if( success != MPI_SUCCESS ) return MB_FAILURE;
768  }
769 
770  // send our own start handles
771  shandles[0] = box->start_vertex();
772  shandles[1] = 0;
773  if( box->box_dimension() == 1 )
774  {
775  shandles[1] = box->start_element();
776  shandles[2] = 0;
777  shandles[3] = 0;
778  }
779  else if( box->box_dimension() == 2 )
780  {
781  shandles[2] = box->start_element();
782  shandles[3] = 0;
783  }
784  else
785  {
786  shandles[2] = 0;
787  shandles[3] = box->start_element();
788  }
789  for( unsigned int i = 0; i < procs.size(); i++ )
790  {
791  int success = MPI_Isend( (void*)&shandles[0], 4 * sizeof( EntityHandle ), MPI_UNSIGNED_CHAR, procs[i], 1,
792  pcomm->proc_config().proc_comm(), &send_reqs[i] );
793  if( success != MPI_SUCCESS ) return MB_FAILURE;
794  }
795 
796  // receive start handles and save info to a tuple list
797  int incoming = procs.size();
798  int p, j, k;
799  MPI_Status status;
800  TupleList shared_data;
801  shared_data.initialize( 1, 0, 2, 0, shared_indices.size() / 2 );
802  shared_data.enableWriteAccess();
803 
804  j = 0;
805  k = 0;
806  while( incoming )
807  {
808  int success = MPI_Waitany( procs.size(), &recv_reqs[0], &p, &status );
809  if( MPI_SUCCESS != success ) return MB_FAILURE;
810  unsigned int num_indices = ( offsets[p + 1] - offsets[p] ) / 2;
811  int *lh = &shared_indices[offsets[p]], *rh = lh + num_indices;
812  for( unsigned int i = 0; i < num_indices; i++ )
813  {
814  shared_data.vi_wr[j++] = procs[p];
815  shared_data.vul_wr[k++] = shandles[0] + lh[i];
816  shared_data.vul_wr[k++] = rhandles[4 * p] + rh[i];
817  shared_data.inc_n();
818  }
819  incoming--;
820  }
821 
822  // still need to wait for the send requests
823  std::vector< MPI_Status > mult_status( procs.size() );
824  int success = MPI_Waitall( procs.size(), &send_reqs[0], &mult_status[0] );
825  if( MPI_SUCCESS != success )
826  {
827  MB_SET_ERR( MB_FAILURE, "Failed in waitall in ScdInterface::tag_shared_vertices" );
828  }
829  // sort by local handle
830  TupleList::buffer sort_buffer;
831  sort_buffer.buffer_init( shared_indices.size() / 2 );
832  shared_data.sort( 1, &sort_buffer );
833  sort_buffer.reset();
834 
835  // process into sharing data
836  std::map< std::vector< int >, std::vector< EntityHandle > > proc_nvecs;
837  Range dum;
838  rval = pcomm->tag_shared_verts( shared_data, proc_nvecs, dum, 0 );
839  if( MB_SUCCESS != rval ) return rval;
840 
841  // create interface sets
842  rval = pcomm->create_interface_sets( proc_nvecs );
843  if( MB_SUCCESS != rval ) return rval;
844 
845  // add the box to the PComm's partitionSets
846  pcomm->partition_sets().insert( box->box_set() );
847 
848  // make sure buffers are allocated for communicating procs
849  for( std::vector< int >::iterator pit = procs.begin(); pit != procs.end(); ++pit )
850  pcomm->get_buffers( *pit );
851 
852  if( pcomm->get_debug_verbosity() > 1 ) pcomm->list_entities( NULL, 1 );
853 
854 #ifndef NDEBUG
855  rval = pcomm->check_all_shared_handles();
856  if( MB_SUCCESS != rval ) return rval;
857 #endif
858 
859  return MB_SUCCESS;
860 
861 #endif
862 }

References moab::ScdBox::box_dimension(), moab::ScdBox::box_set(), moab::ParallelComm::check_all_shared_handles(), moab::ParallelComm::create_interface_sets(), moab::dum, moab::TupleList::enableWriteAccess(), ErrorCode, moab::ScdParData::gDims, moab::ParallelComm::get_buffers(), moab::ParallelComm::get_debug_verbosity(), moab::Interface::get_entities_by_dimension(), get_shared_vertices(), moab::TupleList::inc_n(), moab::TupleList::initialize(), moab::Range::insert(), moab::ParallelComm::list_entities(), MB_SET_ERR, MB_SUCCESS, mbImpl, moab::ScdBox::num_elements(), moab::ScdBox::par_data(), moab::ParallelComm::partition_sets(), moab::ScdParData::partMethod, moab::ProcConfig::proc_comm(), moab::ParallelComm::proc_config(), moab::TupleList::buffer::reset(), moab::Range::size(), moab::TupleList::sort(), moab::ScdBox::start_element(), moab::ScdBox::start_vertex(), tag_shared_vertices(), moab::ParallelComm::tag_shared_verts(), moab::TupleList::vi_wr, and moab::TupleList::vul_wr.

Friends And Related Function Documentation

◆ ScdBox

friend class ScdBox
friend

Definition at line 154 of file ScdInterface.hpp.

Referenced by create_scd_sequence().

Member Data Documentation

◆ boxDimsTag

Tag moab::ScdInterface::boxDimsTag
private

tag representing box lower and upper corners

Definition at line 494 of file ScdInterface.hpp.

Referenced by box_dims_tag(), find_boxes(), and moab::ScdBox::ScdBox().

◆ boxPeriodicTag

Tag moab::ScdInterface::boxPeriodicTag
private

tag representing whether box is periodic in i and j

Definition at line 491 of file ScdInterface.hpp.

Referenced by box_periodic_tag(), and moab::ScdBox::ScdBox().

◆ boxSetTag

Tag moab::ScdInterface::boxSetTag
private

tag pointing from set to ScdBox

Definition at line 503 of file ScdInterface.hpp.

Referenced by box_set_tag(), and find_boxes().

◆ globalBoxDimsTag

Tag moab::ScdInterface::globalBoxDimsTag
private

tag representing global lower and upper corners

Definition at line 497 of file ScdInterface.hpp.

Referenced by global_box_dims_tag().

◆ mbImpl

◆ partMethodTag

Tag moab::ScdInterface::partMethodTag
private

tag representing partition method

Definition at line 500 of file ScdInterface.hpp.

Referenced by part_method_tag().

◆ scdBoxes

std::vector< ScdBox* > moab::ScdInterface::scdBoxes
private

structured mesh blocks; stored as ScdBox objects, can get sets from those

Definition at line 488 of file ScdInterface.hpp.

Referenced by add_box(), find_boxes(), get_boxes(), remove_box(), ScdInterface(), and ~ScdInterface().

◆ searchedBoxes

bool moab::ScdInterface::searchedBoxes
private

whether we've searched the database for boxes yet

Definition at line 485 of file ScdInterface.hpp.

Referenced by find_boxes().


The documentation for this class was generated from the following files: