A structured mesh interface for MOAB-based data. More...
#include "moab/ScdInterface.hpp"
Public Member Functions | |
ScdInterface (Interface *impl, bool find_boxes=false) | |
Constructor. More... | |
~ScdInterface () | |
Interface * | impl () 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... | |
ScdBox * | get_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 | |
Interface * | mbImpl |
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 |
A structured mesh interface for MOAB-based data.
Structured mesh in MOAB is created and accessed through the ScdInterface and ScdBox classes.
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.
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.
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.
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.
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.
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.
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.
impl | MOAB instance |
find_boxes | If 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.
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().
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 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().
Tag moab::ScdInterface::box_dims_tag | ( | bool | create_if_missing = true | ) |
Return the tag marking the lower and upper corners of boxes.
create_if_missing | If 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
392 ErrorCode rval = mbImpl->tag_get_handle( "BOX_DIMS", 6, MB_TYPE_INTEGER, boxDimsTag, MB_TAG_SPARSE | MB_TAG_CREAT );
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().
Tag moab::ScdInterface::box_periodic_tag | ( | bool | create_if_missing = true | ) |
Return the tag marking whether box is periodic in i and j.
create_if_missing | If 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 =
376 mbImpl->tag_get_handle( "BOX_PERIODIC", 3, MB_TYPE_INTEGER, boxPeriodicTag, MB_TAG_SPARSE | MB_TAG_CREAT );
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().
Tag moab::ScdInterface::box_set_tag | ( | bool | create_if_missing = true | ) |
Return the tag marking the ScdBox for a set.
create_if_missing | If 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,
443 MB_TAG_SPARSE | MB_TAG_CREAT );
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().
|
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.
np | Number of processors |
nr | Rank of this processor |
par_data | ScdParData object that contains input global parameter space, desired partitioning method, and information about global periodicity. |
ldims | Local parameters for grid |
lperiodic | Whether or not a given dimension is locally periodic |
pdims | Number 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 {
859 case ScdParData::ALLJORKORI:
860 case -1:
861 rval = compute_partition_alljorkori( np, nr, par_data.gDims, par_data.gPeriodic, ldims, lperiodic, pdims );
862 break;
863 case ScdParData::ALLJKBAL:
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().
|
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().
|
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().
|
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().
|
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().
|
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, and nr.
Referenced by compute_partition(), and get_neighbor_sqjk().
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.
low | Lower corner in parameter space |
high | Higher corner in parameter space |
coords | Coordinates of vertices, interleaved (xyzxyz...); if NULL, coords are set to parametric values |
num_coords | Number of coordinate values |
new_box | Reference to box of structured mesh |
lperiodic[3] | If lperiodic[s] != 0, direction s is locally periodic |
par_data | If non-NULL, this will get stored on the ScdBox once created, contains info about global parallel nature of ScdBox across procs |
assign_global_ids | If true, assigns 1-based global ids to vertices using GLOBAL_ID_TAG_NAME |
resolve_shared_ents | If != -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().
|
private |
Create an entity set for a box, and tag with the parameters.
low | Lower corner parameters for this box |
high | Upper corner parameters for this box |
scd_set | Entity 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().
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.
low | Lower corner of structured box |
high | Higher corner of structured box |
type | EntityType, one of MBVERTEX, MBEDGE, MBQUAD, MBHEX |
starting_id | Requested start id of entities |
new_box | Reference 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().
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.
boxes | Range 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 {
82 rval = mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &boxDimsTag, NULL, 1, boxes, Interface::UNION );
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 = nullptr;
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.
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.
boxes | Vector 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().
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.
boxes | Structured 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.
|
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().
|
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
np | (in) Total # procs |
nr | Processor 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 {
1428 case ScdParData::ALLJORKORI:
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().
|
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().
|
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().
|
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().
|
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().
|
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().
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.
eh | Entity 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().
|
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
box | Box used to get parametric space info |
procs | Procs this proc shares vertices with |
offsets | Offsets into indices list for each proc |
shared_indices | local/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().
Tag moab::ScdInterface::global_box_dims_tag | ( | bool | create_if_missing = true | ) |
Return the tag marking the global lower and upper corners of boxes.
create_if_missing | If 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;
403 if( MB_TAG_NOT_FOUND == mbImpl->tag_get_name( globalBoxDimsTag, tag_name ) ) globalBoxDimsTag = NULL;
404 }
405
406 if( globalBoxDimsTag || !create_if_missing ) return globalBoxDimsTag;
407
408 ErrorCode rval =
409 mbImpl->tag_get_handle( "GLOBAL_BOX_DIMS", 6, MB_TYPE_INTEGER, globalBoxDimsTag, MB_TAG_SPARSE | MB_TAG_CREAT );
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().
|
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().
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().
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.
create_if_missing | If 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 =
426 mbImpl->tag_get_handle( "PARTITION_METHOD", 1, MB_TYPE_INTEGER, partMethodTag, MB_TAG_SPARSE | MB_TAG_CREAT );
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 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().
|
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().
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.
|
friend |
Definition at line 154 of file ScdInterface.hpp.
Referenced by create_scd_sequence().
|
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().
|
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().
|
private |
tag pointing from set to ScdBox
Definition at line 503 of file ScdInterface.hpp.
Referenced by box_set_tag(), and find_boxes().
|
private |
tag representing global lower and upper corners
Definition at line 497 of file ScdInterface.hpp.
Referenced by global_box_dims_tag().
|
private |
interface instance
Definition at line 482 of file ScdInterface.hpp.
Referenced by assign_global_ids(), moab::ScdBox::box_dimension(), box_dims_tag(), box_periodic_tag(), box_set_tag(), construct_box(), create_box_set(), create_scd_sequence(), find_boxes(), get_scd_box(), global_box_dims_tag(), impl(), part_method_tag(), moab::ScdBox::ScdBox(), tag_shared_vertices(), moab::ScdBox::~ScdBox(), and ~ScdInterface().
|
private |
tag representing partition method
Definition at line 500 of file ScdInterface.hpp.
Referenced by part_method_tag().
|
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().
|
private |
whether we've searched the database for boxes yet
Definition at line 485 of file ScdInterface.hpp.
Referenced by find_boxes().