Mesh Oriented datABase  (version 5.5.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.

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 462 of file ScdInterface.cpp.

463 {
464  scdBoxes.push_back( box );
465  return MB_SUCCESS;
466 }

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 252 of file ScdInterface.cpp.

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

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 381 of file ScdInterface.cpp.

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

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 364 of file ScdInterface.cpp.

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

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 431 of file ScdInterface.cpp.

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

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, nr, 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, and nr.

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, and nr.

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, and nr.

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, and nr.

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() ) 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, and nr.

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

Definition at line 112 of file ScdInterface.cpp.

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

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 337 of file ScdInterface.cpp.

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

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 284 of file ScdInterface.cpp.

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

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  ErrorCode rval = MB_SUCCESS;
78  box_dims_tag();
79  Range boxes;
80  if( !searchedBoxes )
81  {
83  searchedBoxes = true;
84  if( !boxes.empty() )
85  {
86  scdBoxes.resize( boxes.size() );
87  rval = mbImpl->tag_get_data( boxSetTag, boxes, &scdBoxes[0] );
88  ScdBox* dum = NULL;
89  // std::remove_if(scdBoxes.begin(), scdBoxes.end(),
90  // std::bind2nd(std::equal_to<ScdBox*>(), dum) ) ;
91  std::remove_if( scdBoxes.begin(), scdBoxes.end(),
92  std::bind( std::equal_to< ScdBox* >(), std::placeholders::_1, dum ) );
93  // https://stackoverflow.com/questions/32739018/a-replacement-for-stdbind2nd
94  }
95  }
96 
97  for( std::vector< ScdBox* >::iterator vit = scdBoxes.begin(); vit != scdBoxes.end(); ++vit )
98  scd_boxes.insert( ( *vit )->box_set() );
99 
100  return rval;
101 }

References box_dims_tag(), boxDimsTag, boxSetTag, moab::dum, moab::Range::empty(), ErrorCode, moab::Interface::get_entities_by_type_and_tag(), moab::Range::insert(), 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 468 of file ScdInterface.cpp.

469 {
470  std::copy( scdBoxes.begin(), scdBoxes.end(), std::back_inserter( boxes ) );
471  return MB_SUCCESS;
472 }

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 861 of file ScdInterface.cpp.

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

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 1341 of file ScdInterface.cpp.

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

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 977 of file ScdInterface.cpp.

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

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 1240 of file ScdInterface.cpp.

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

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 1122 of file ScdInterface.cpp.

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

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 103 of file ScdInterface.cpp.

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

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 1442 of file ScdInterface.cpp.

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

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 397 of file ScdInterface.cpp.

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

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 414 of file ScdInterface.cpp.

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

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 449 of file ScdInterface.cpp.

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

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 733 of file ScdInterface.cpp.

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

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: