Branch data Line data Source code
1 : : #include "moab/ScdInterface.hpp"
2 : : #include "moab/Core.hpp"
3 : : #include "SequenceManager.hpp"
4 : : #include "EntitySequence.hpp"
5 : : #include "StructuredElementSeq.hpp"
6 : : #include "VertexSequence.hpp"
7 : : #include "ScdVertexData.hpp"
8 : : #include "MBTagConventions.hpp"
9 : : #ifdef MOAB_HAVE_MPI
10 : : #include "moab/ParallelComm.hpp"
11 : : #include "moab/TupleList.hpp"
12 : : #include "moab/gs.hpp"
13 : : #endif
14 : : #include "assert.h"
15 : : #include <iostream>
16 : : #include <functional>
17 : :
18 : : #define ERRORR( rval, str ) \
19 : : { \
20 : : if( MB_SUCCESS != rval ) \
21 : : { \
22 : : std::cerr << str; \
23 : : return rval; \
24 : : } \
25 : : }
26 : :
27 : : namespace moab
28 : : {
29 : :
30 : : const char* ScdParData::PartitionMethodNames[] = { "alljorkori", "alljkbal", "sqij", "sqjk",
31 : : "sqijk", "trivial", "rcbzoltan", "nopart" };
32 : :
33 : 29 : ScdInterface::ScdInterface( Interface* imp, bool boxes )
34 : : : mbImpl( imp ), searchedBoxes( false ), boxPeriodicTag( 0 ), boxDimsTag( 0 ), globalBoxDimsTag( 0 ),
35 : 29 : partMethodTag( 0 ), boxSetTag( 0 )
36 : : {
37 [ - + ][ # # ]: 29 : if( boxes ) find_boxes( scdBoxes );
38 : 29 : }
39 : :
40 : : // Destructor
41 : 58 : ScdInterface::~ScdInterface()
42 : : {
43 : 29 : std::vector< ScdBox* > tmp_boxes;
44 : 29 : tmp_boxes.swap( scdBoxes );
45 : :
46 [ + + ]: 75 : for( std::vector< ScdBox* >::iterator rit = tmp_boxes.begin(); rit != tmp_boxes.end(); ++rit )
47 [ + - ]: 46 : delete *rit;
48 : :
49 [ + + ]: 29 : if( box_set_tag( false ) ) mbImpl->tag_delete( box_set_tag() );
50 : 29 : }
51 : :
52 : 14761 : Interface* ScdInterface::impl() const
53 : : {
54 : 14761 : return mbImpl;
55 : : }
56 : :
57 : 2 : ErrorCode ScdInterface::find_boxes( std::vector< ScdBox* >& scd_boxes )
58 : : {
59 [ + - ]: 2 : Range tmp_boxes;
60 [ + - ]: 2 : ErrorCode rval = find_boxes( tmp_boxes );
61 [ - + ]: 2 : if( MB_SUCCESS != rval ) return rval;
62 : :
63 [ + - ][ + - ]: 4 : for( Range::iterator rit = tmp_boxes.begin(); rit != tmp_boxes.end(); ++rit )
[ + - ][ + - ]
[ + + ]
64 : : {
65 [ + - ][ + - ]: 2 : ScdBox* tmp_box = get_scd_box( *rit );
66 [ + - ]: 2 : if( tmp_box )
67 [ + - ]: 2 : scd_boxes.push_back( tmp_box );
68 : : else
69 : 0 : rval = MB_FAILURE;
70 : : }
71 : :
72 : 2 : return rval;
73 : : }
74 : :
75 : 19 : ErrorCode ScdInterface::find_boxes( Range& scd_boxes )
76 : : {
77 : 19 : ErrorCode rval = MB_SUCCESS;
78 [ + - ]: 19 : box_dims_tag();
79 [ + - ]: 19 : Range boxes;
80 [ + + ]: 19 : if( !searchedBoxes )
81 : : {
82 [ + - ]: 18 : rval = mbImpl->get_entities_by_type_and_tag( 0, MBENTITYSET, &boxDimsTag, NULL, 1, boxes, Interface::UNION );
83 : 18 : searchedBoxes = true;
84 [ + - ][ + + ]: 18 : if( !boxes.empty() )
85 : : {
86 [ + - ][ + - ]: 1 : scdBoxes.resize( boxes.size() );
87 [ + - ][ + - ]: 1 : rval = mbImpl->tag_get_data( boxSetTag, boxes, &scdBoxes[0] );
88 : 1 : 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 [ + - ][ + - ]: 18 : std::bind( std::equal_to< ScdBox* >(), std::placeholders::_1, dum ) );
93 : : // https://stackoverflow.com/questions/32739018/a-replacement-for-stdbind2nd
94 : : }
95 : : }
96 : :
97 [ + - ][ + - ]: 21 : for( std::vector< ScdBox* >::iterator vit = scdBoxes.begin(); vit != scdBoxes.end(); ++vit )
[ + + ]
98 [ + - ][ + - ]: 2 : scd_boxes.insert( ( *vit )->box_set() );
[ + - ]
99 : :
100 : 19 : return rval;
101 : : }
102 : :
103 : 2 : ScdBox* ScdInterface::get_scd_box( EntityHandle eh )
104 : : {
105 : 2 : ScdBox* scd_box = NULL;
106 [ + - ][ - + ]: 2 : if( !box_set_tag( false ) ) return scd_box;
107 : :
108 [ + - ][ + - ]: 2 : mbImpl->tag_get_data( box_set_tag(), &eh, 1, &scd_box );
109 : 2 : return scd_box;
110 : : }
111 : :
112 : 13 : ErrorCode ScdInterface::construct_box( HomCoord low, HomCoord high, const double* const coords, unsigned int num_coords,
113 : : ScdBox*& new_box, int* const lperiodic, ScdParData* par_data, bool assign_gids,
114 : : int tag_shared_ents )
115 : : {
116 : : // create a rectangular structured mesh block
117 : : ErrorCode rval;
118 : :
119 : 13 : int tmp_lper[3] = { 0, 0, 0 };
120 [ + + ][ + - ]: 13 : if( lperiodic ) std::copy( lperiodic, lperiodic + 3, tmp_lper );
121 : :
122 : : #ifndef MOAB_HAVE_MPI
123 : : if( -1 != tag_shared_ents ) ERRORR( MB_FAILURE, "Parallel capability requested but MOAB not compiled parallel." );
124 : : if( -1 == tag_shared_ents && !assign_gids ) assign_gids = true; // need to assign gids in order to tag shared verts
125 : : #else
126 [ - + ][ # # ]: 13 : if( par_data && low == high && ScdParData::NOPART != par_data->partMethod )
[ # # ][ # # ]
[ - + ]
127 : : {
128 : : // requesting creation of parallel mesh, so need to compute partition
129 [ # # ]: 0 : if( !par_data->pComm )
130 : : {
131 : : // this is a really boneheaded way to have to create a PC
132 [ # # ]: 0 : par_data->pComm = ParallelComm::get_pcomm( mbImpl, 0 );
133 [ # # ][ # # ]: 0 : if( NULL == par_data->pComm ) par_data->pComm = new ParallelComm( mbImpl, MPI_COMM_WORLD );
[ # # ]
134 : : }
135 : : int ldims[6];
136 [ # # ][ # # ]: 0 : rval = compute_partition( par_data->pComm->size(), par_data->pComm->rank(), *par_data, ldims, tmp_lper,
137 [ # # ][ # # ]: 0 : par_data->pDims );ERRORR( rval, "Error returned from compute_partition." );
[ # # ]
138 [ # # ]: 0 : low.set( ldims[0], ldims[1], ldims[2] );
139 [ # # ]: 0 : high.set( ldims[3], ldims[4], ldims[5] );
140 [ # # ][ # # ]: 0 : if( par_data->pComm->get_debug_verbosity() > 0 )
141 : : {
142 [ # # ][ # # ]: 0 : std::cout << "Proc " << par_data->pComm->rank() << ": " << *par_data;
[ # # ][ # # ]
[ # # ]
143 [ # # ][ # # ]: 0 : std::cout << "Proc " << par_data->pComm->rank() << " local dims: " << low << "-" << high << std::endl;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
144 : : }
145 : : }
146 : : #endif
147 : :
148 [ + - ][ + - ]: 13 : HomCoord tmp_size = high - low + HomCoord( 1, 1, 1, 0 );
[ + - ]
149 [ + - ][ + - ]: 52 : if( ( tmp_size[1] && num_coords && (int)num_coords < tmp_size[0] ) ||
[ - + ][ # # ]
[ # # ][ + - ]
[ - + ][ + - ]
[ - + # #
# # ]
150 [ + - ][ - + ]: 39 : ( tmp_size[2] && num_coords && (int)num_coords < tmp_size[0] * tmp_size[1] ) )
[ # # ][ # # ]
[ # # ][ - + ]
[ - + ][ + - ]
[ # # # #
# # ]
151 : 0 : return MB_FAILURE;
152 : :
153 [ + - ][ - + ]: 13 : rval = create_scd_sequence( low, high, MBVERTEX, 0, new_box );ERRORR( rval, "Trouble creating scd vertex sequence." );
[ # # ]
154 : :
155 : : // set the vertex coordinates
156 : : double *xc, *yc, *zc;
157 [ + - ][ - + ]: 13 : rval = new_box->get_coordinate_arrays( xc, yc, zc );ERRORR( rval, "Couldn't get vertex coordinate arrays." );
[ # # ]
158 : :
159 [ - + ][ # # ]: 13 : if( coords && num_coords )
160 : : {
161 : 0 : unsigned int i = 0;
162 [ # # ][ # # ]: 0 : for( int kl = low[2]; kl <= high[2]; kl++ )
[ # # ]
163 : : {
164 [ # # ][ # # ]: 0 : for( int jl = low[1]; jl <= high[1]; jl++ )
[ # # ]
165 : : {
166 [ # # ][ # # ]: 0 : for( int il = low[0]; il <= high[0]; il++ )
[ # # ]
167 : : {
168 : 0 : xc[i] = coords[3 * i];
169 [ # # ][ # # ]: 0 : if( new_box->box_size()[1] ) yc[i] = coords[3 * i + 1];
[ # # ]
170 [ # # ][ # # ]: 0 : if( new_box->box_size()[2] ) zc[i] = coords[3 * i + 2];
[ # # ]
171 : 0 : i++;
172 : : }
173 : : }
174 : 0 : }
175 : : }
176 : : else
177 : : {
178 : 13 : unsigned int i = 0;
179 [ + - ][ + - ]: 75 : for( int kl = low[2]; kl <= high[2]; kl++ )
[ + + ]
180 : : {
181 [ + - ][ + - ]: 772 : for( int jl = low[1]; jl <= high[1]; jl++ )
[ + + ]
182 : : {
183 [ + - ][ + - ]: 15412 : for( int il = low[0]; il <= high[0]; il++ )
[ + + ]
184 : : {
185 : 14702 : xc[i] = (double)il;
186 [ + - ][ + - ]: 14702 : if( new_box->box_size()[1] )
[ + - ]
187 : 14702 : yc[i] = (double)jl;
188 : : else
189 : 0 : yc[i] = 0.0;
190 [ + - ][ + - ]: 14702 : if( new_box->box_size()[2] )
[ + - ]
191 : 14702 : zc[i] = (double)kl;
192 : : else
193 : 0 : zc[i] = 0.0;
194 : 14702 : i++;
195 : : }
196 : : }
197 : : }
198 : : }
199 : :
200 : : // create element sequence
201 [ - + ]: 13 : Core* mbcore = dynamic_cast< Core* >( mbImpl );
202 [ + - ]: 13 : SequenceManager* seq_mgr = mbcore->sequence_manager();
203 : :
204 : : EntitySequence* tmp_seq;
205 : : EntityHandle start_ent;
206 : :
207 : : // construct the sequence
208 : 13 : EntityType this_tp = MBHEX;
209 [ + - ][ + + ]: 13 : if( 1 >= tmp_size[2] ) this_tp = MBQUAD;
210 [ + - ][ + + ]: 13 : if( 1 >= tmp_size[2] && 1 >= tmp_size[1] ) this_tp = MBEDGE;
[ + - ][ - + ]
[ + + ][ + - ]
[ - + ]
[ # # # # ]
211 [ + - ][ - + ]: 13 : rval = seq_mgr->create_scd_sequence( low, high, this_tp, 0, start_ent, tmp_seq, tmp_lper );ERRORR( rval, "Trouble creating scd element sequence." );
[ # # ]
212 : :
213 [ + - ]: 13 : new_box->elem_seq( tmp_seq );
214 [ + - ]: 13 : new_box->start_element( start_ent );
215 : :
216 : : // add vertex seq to element seq, forward orientation, unity transform
217 : : rval = new_box->add_vbox( new_box,
218 : : // p1: imin,jmin
219 : : low, low,
220 : : // p2: imax,jmin
221 [ + - ][ + - ]: 13 : low + HomCoord( 1, 0, 0 ), low + HomCoord( 1, 0, 0 ),
[ + - ][ + - ]
222 : : // p3: imin,jmax
223 [ + - ][ + - ]: 26 : low + HomCoord( 0, 1, 0 ), low + HomCoord( 0, 1, 0 ) );ERRORR( rval, "Error constructing structured element sequence." );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ - + ]
[ # # ]
224 : :
225 : : // add the new hexes to the scd box set; vertices were added in call to create_scd_sequence
226 [ + - ][ + - ]: 13 : Range tmp_range( new_box->start_element(), new_box->start_element() + new_box->num_elements() - 1 );
[ + - ][ + - ]
227 [ + - ][ + - ]: 13 : rval = mbImpl->add_entities( new_box->box_set(), tmp_range );ERRORR( rval, "Couldn't add new hexes to box set." );
[ - + ][ # # ]
228 : :
229 [ - + ][ # # ]: 13 : if( par_data ) new_box->par_data( *par_data );
230 : :
231 [ + + ]: 13 : if( assign_gids )
232 : : {
233 [ + - ][ - + ]: 2 : rval = assign_global_ids( new_box );ERRORR( rval, "Trouble assigning global ids" );
[ # # ]
234 : : }
235 : :
236 : : #ifdef MOAB_HAVE_MPI
237 [ - + ][ # # ]: 13 : if( par_data && -1 != tag_shared_ents ) { rval = tag_shared_vertices( par_data->pComm, new_box ); }
[ # # ]
238 : : #endif
239 : :
240 : 13 : return MB_SUCCESS;
241 : : }
242 : :
243 : 2 : ErrorCode ScdInterface::assign_global_ids( ScdBox* box )
244 : : {
245 : : // Get a ptr to global id memory
246 : : void* data;
247 : 2 : int count = 0;
248 [ + - ]: 2 : Tag gid_tag = mbImpl->globalId_tag();
249 [ + - ][ + - ]: 2 : Range tmp_range( box->start_vertex(), box->start_vertex() + box->num_vertices() );
[ + - ][ + - ]
250 [ + - ][ + - ]: 2 : ErrorCode rval = mbImpl->tag_iterate( gid_tag, tmp_range.begin(), tmp_range.end(), count, data );ERRORR( rval, "Failed to get tag iterator." );
[ + - ][ - + ]
[ # # ]
251 [ + - ][ - + ]: 2 : assert( count == box->num_vertices() );
252 : 2 : int* gid_data = (int*)data;
253 [ + - ][ + - ]: 2 : int di = box->par_data().gDims[3] - box->par_data().gDims[0] + 1;
254 [ + - ][ + - ]: 2 : int dj = box->par_data().gDims[4] - box->par_data().gDims[1] + 1;
255 : :
256 [ + - ][ + - ]: 4 : for( int kl = box->box_dims()[2]; kl <= box->box_dims()[5]; kl++ )
[ + + ]
257 : : {
258 [ + - ][ + - ]: 132 : for( int jl = box->box_dims()[1]; jl <= box->box_dims()[4]; jl++ )
[ + + ]
259 : : {
260 [ + - ][ + - ]: 8580 : for( int il = box->box_dims()[0]; il <= box->box_dims()[3]; il++ )
[ + + ]
261 : : {
262 : : int itmp =
263 [ + - ][ + - ]: 16900 : ( !box->locally_periodic()[0] && box->par_data().gPeriodic[0] && il == box->par_data().gDims[3]
[ - + ][ # # ]
[ # # ]
264 [ # # ]: 0 : ? box->par_data().gDims[0]
265 [ + - ]: 16900 : : il );
266 [ + - ]: 8450 : *gid_data = ( -1 != kl ? kl * di * dj : 0 ) + jl * di + itmp + 1;
267 : 8450 : gid_data++;
268 : : }
269 : : }
270 : : }
271 : :
272 : 2 : return MB_SUCCESS;
273 : : }
274 : :
275 : 46 : ErrorCode ScdInterface::create_scd_sequence( const HomCoord& low, const HomCoord& high, EntityType tp, int starting_id,
276 : : ScdBox*& new_box, int* is_periodic )
277 : : {
278 [ + - ][ + - ]: 46 : HomCoord tmp_size = high - low + HomCoord( 1, 1, 1, 0 );
[ + - ]
279 [ + + ][ + - ]: 97 : if( ( tp == MBHEX && 1 >= tmp_size[2] ) || ( tp == MBQUAD && 1 >= tmp_size[1] ) ||
[ + - ][ + + ]
[ + - ][ + - ]
[ + + ][ + + ]
[ + + ][ - +
# # # # ]
280 [ + - ][ - + ]: 51 : ( tp == MBEDGE && 1 >= tmp_size[0] ) )
[ + + ][ # # ]
281 : 0 : return MB_TYPE_OUT_OF_RANGE;
282 : :
283 [ - + ]: 46 : Core* mbcore = dynamic_cast< Core* >( mbImpl );
284 [ - + ]: 46 : assert( mbcore != NULL );
285 [ + - ]: 46 : SequenceManager* seq_mgr = mbcore->sequence_manager();
286 : :
287 : : EntitySequence* tmp_seq;
288 : : EntityHandle start_ent, scd_set;
289 : :
290 : : // construct the sequence
291 [ + - ]: 46 : ErrorCode rval = seq_mgr->create_scd_sequence( low, high, tp, starting_id, start_ent, tmp_seq, is_periodic );
292 [ - + ]: 46 : if( MB_SUCCESS != rval ) return rval;
293 : :
294 : : // create the set for this rectangle
295 [ + - ]: 46 : rval = create_box_set( low, high, scd_set );
296 [ - + ]: 46 : if( MB_SUCCESS != rval ) return rval;
297 : :
298 : : // make the ScdBox
299 [ + - ][ + - ]: 46 : new_box = new ScdBox( this, scd_set, tmp_seq );
300 [ - + ]: 46 : if( !new_box ) return MB_FAILURE;
301 : :
302 : : // set the start vertex/element
303 [ + - ]: 46 : Range new_range;
304 [ + + ][ + - ]: 46 : if( MBVERTEX == tp ) { new_range.insert( start_ent, start_ent + new_box->num_vertices() - 1 ); }
[ + - ]
305 : : else
306 : : {
307 [ + - ][ + - ]: 15 : new_range.insert( start_ent, start_ent + new_box->num_elements() - 1 );
308 : : }
309 : :
310 : : // put the entities in the box set
311 [ + - ]: 46 : rval = mbImpl->add_entities( scd_set, new_range );
312 [ - + ]: 46 : if( MB_SUCCESS != rval ) return rval;
313 : :
314 : : // tag the set with the box
315 [ + - ][ + - ]: 46 : rval = mbImpl->tag_set_data( box_set_tag(), &scd_set, 1, &new_box );
316 [ - + ]: 46 : if( MB_SUCCESS != rval ) return rval;
317 : :
318 : 46 : return MB_SUCCESS;
319 : : }
320 : :
321 : 46 : ErrorCode ScdInterface::create_box_set( const HomCoord& low, const HomCoord& high, EntityHandle& scd_set,
322 : : int* is_periodic )
323 : : {
324 : : // create the set and put the entities in it
325 [ + - ]: 46 : ErrorCode rval = mbImpl->create_meshset( MESHSET_SET, scd_set );
326 [ - + ]: 46 : if( MB_SUCCESS != rval ) return rval;
327 : :
328 : : // tag the set with parameter extents
329 : : int boxdims[6];
330 [ + + ]: 184 : for( int i = 0; i < 3; i++ )
331 [ + - ]: 138 : boxdims[i] = low[i];
332 [ + + ]: 184 : for( int i = 0; i < 3; i++ )
333 [ + - ]: 138 : boxdims[3 + i] = high[i];
334 [ + - ][ + - ]: 46 : rval = mbImpl->tag_set_data( box_dims_tag(), &scd_set, 1, boxdims );
335 [ - + ]: 46 : if( MB_SUCCESS != rval ) return rval;
336 : :
337 [ - + ]: 46 : if( is_periodic )
338 : : {
339 [ # # ][ # # ]: 0 : rval = mbImpl->tag_set_data( box_periodic_tag(), &scd_set, 1, is_periodic );
340 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
341 : : }
342 : :
343 : 46 : return rval;
344 : : }
345 : :
346 : 0 : Tag ScdInterface::box_periodic_tag( bool create_if_missing )
347 : : {
348 : : // Reset boxPeriodicTag in case it has been deleted (e.g. by Core::clean_up_failed_read)
349 [ # # ]: 0 : if( boxPeriodicTag )
350 : : {
351 [ # # ]: 0 : std::string tag_name;
352 [ # # ][ # # ]: 0 : if( MB_TAG_NOT_FOUND == mbImpl->tag_get_name( boxPeriodicTag, tag_name ) ) boxPeriodicTag = NULL;
353 : : }
354 : :
355 [ # # ][ # # ]: 0 : if( boxPeriodicTag || !create_if_missing ) return boxPeriodicTag;
356 : :
357 : : ErrorCode rval =
358 : 0 : mbImpl->tag_get_handle( "BOX_PERIODIC", 3, MB_TYPE_INTEGER, boxPeriodicTag, MB_TAG_SPARSE | MB_TAG_CREAT );
359 [ # # ]: 0 : if( MB_SUCCESS != rval ) return 0;
360 : 0 : return boxPeriodicTag;
361 : : }
362 : :
363 : 65 : Tag ScdInterface::box_dims_tag( bool create_if_missing )
364 : : {
365 : : // Reset boxDimsTag in case it has been deleted (e.g. by clean_up_failed_read)
366 [ + + ]: 65 : if( boxDimsTag )
367 : : {
368 [ + - ]: 38 : std::string tag_name;
369 [ + - ][ - + ]: 38 : if( MB_TAG_NOT_FOUND == mbImpl->tag_get_name( boxDimsTag, tag_name ) ) boxDimsTag = NULL;
370 : : }
371 : :
372 [ + + ][ - + ]: 65 : if( boxDimsTag || !create_if_missing ) return boxDimsTag;
373 : :
374 : 27 : ErrorCode rval = mbImpl->tag_get_handle( "BOX_DIMS", 6, MB_TYPE_INTEGER, boxDimsTag, MB_TAG_SPARSE | MB_TAG_CREAT );
375 [ - + ]: 27 : if( MB_SUCCESS != rval ) return 0;
376 : 65 : return boxDimsTag;
377 : : }
378 : :
379 : 0 : Tag ScdInterface::global_box_dims_tag( bool create_if_missing )
380 : : {
381 : : // Reset globalBoxDimsTag in case it has been deleted (e.g. by Core::clean_up_failed_read)
382 [ # # ]: 0 : if( globalBoxDimsTag )
383 : : {
384 [ # # ]: 0 : std::string tag_name;
385 [ # # ][ # # ]: 0 : if( MB_TAG_NOT_FOUND == mbImpl->tag_get_name( globalBoxDimsTag, tag_name ) ) globalBoxDimsTag = NULL;
386 : : }
387 : :
388 [ # # ][ # # ]: 0 : if( globalBoxDimsTag || !create_if_missing ) return globalBoxDimsTag;
389 : :
390 : : ErrorCode rval =
391 : 0 : mbImpl->tag_get_handle( "GLOBAL_BOX_DIMS", 6, MB_TYPE_INTEGER, globalBoxDimsTag, MB_TAG_SPARSE | MB_TAG_CREAT );
392 [ # # ]: 0 : if( MB_SUCCESS != rval ) return 0;
393 : 0 : return globalBoxDimsTag;
394 : : }
395 : :
396 : 0 : Tag ScdInterface::part_method_tag( bool create_if_missing )
397 : : {
398 : : // Reset partMethodTag in case it has been deleted (e.g. by Core::clean_up_failed_read)
399 [ # # ]: 0 : if( partMethodTag )
400 : : {
401 [ # # ]: 0 : std::string tag_name;
402 [ # # ][ # # ]: 0 : if( MB_TAG_NOT_FOUND == mbImpl->tag_get_name( partMethodTag, tag_name ) ) partMethodTag = NULL;
403 : : }
404 : :
405 [ # # ][ # # ]: 0 : if( partMethodTag || !create_if_missing ) return partMethodTag;
406 : :
407 : : ErrorCode rval =
408 : 0 : mbImpl->tag_get_handle( "PARTITION_METHOD", 1, MB_TYPE_INTEGER, partMethodTag, MB_TAG_SPARSE | MB_TAG_CREAT );
409 [ # # ]: 0 : if( MB_SUCCESS != rval ) return 0;
410 : 0 : return partMethodTag;
411 : : }
412 : :
413 : 135 : Tag ScdInterface::box_set_tag( bool create_if_missing )
414 : : {
415 : : // Reset boxSetTag in case it has been deleted (e.g. by Core::clean_up_failed_read)
416 [ + + ]: 135 : if( boxSetTag )
417 : : {
418 [ + - ]: 106 : std::string tag_name;
419 [ + - ][ - + ]: 106 : if( MB_TAG_NOT_FOUND == mbImpl->tag_get_name( boxSetTag, tag_name ) ) boxSetTag = NULL;
420 : : }
421 : :
422 [ + + ][ + + ]: 135 : if( boxSetTag || !create_if_missing ) return boxSetTag;
423 : :
424 : : ErrorCode rval = mbImpl->tag_get_handle( "__BOX_SET", sizeof( ScdBox* ), MB_TYPE_OPAQUE, boxSetTag,
425 : 10 : MB_TAG_SPARSE | MB_TAG_CREAT );
426 [ - + ]: 10 : if( MB_SUCCESS != rval ) return 0;
427 : 135 : return boxSetTag;
428 : : }
429 : :
430 : : //! Remove the box from the list on ScdInterface
431 : 46 : ErrorCode ScdInterface::remove_box( ScdBox* box )
432 : : {
433 [ + - ]: 46 : std::vector< ScdBox* >::iterator vit = std::find( scdBoxes.begin(), scdBoxes.end(), box );
434 [ + - ][ - + ]: 46 : if( vit != scdBoxes.end() )
435 : : {
436 [ # # ]: 0 : scdBoxes.erase( vit );
437 : 0 : return MB_SUCCESS;
438 : : }
439 : : else
440 : 46 : return MB_FAILURE;
441 : : }
442 : :
443 : : //! Add the box to the list on ScdInterface
444 : 46 : ErrorCode ScdInterface::add_box( ScdBox* box )
445 : : {
446 : 46 : scdBoxes.push_back( box );
447 : 46 : return MB_SUCCESS;
448 : : }
449 : :
450 : 0 : ErrorCode ScdInterface::get_boxes( std::vector< ScdBox* >& boxes )
451 : : {
452 : 0 : std::copy( scdBoxes.begin(), scdBoxes.end(), std::back_inserter( boxes ) );
453 : 0 : return MB_SUCCESS;
454 : : }
455 : :
456 : 46 : ScdBox::ScdBox( ScdInterface* impl, EntityHandle bset, EntitySequence* seq1, EntitySequence* seq2 )
457 : 46 : : scImpl( impl ), boxSet( bset ), vertDat( NULL ), elemSeq( NULL ), startVertex( 0 ), startElem( 0 )
458 : : {
459 [ + + ]: 322 : for( int i = 0; i < 6; i++ )
460 : 276 : boxDims[i] = 0;
461 [ + + ]: 184 : for( int i = 0; i < 3; i++ )
462 : 138 : locallyPeriodic[i] = false;
463 [ - + ]: 46 : VertexSequence* vseq = dynamic_cast< VertexSequence* >( seq1 );
464 [ + + ][ - + ]: 46 : if( vseq ) vertDat = dynamic_cast< ScdVertexData* >( vseq->data() );
465 [ + + ]: 46 : if( vertDat )
466 : : {
467 : : // retrieve the parametric space
468 [ + + ]: 124 : for( int i = 0; i < 3; i++ )
469 : : {
470 [ + - ][ + - ]: 93 : boxDims[i] = vertDat->min_params()[i];
471 [ + - ][ + - ]: 93 : boxDims[3 + i] = vertDat->max_params()[i];
472 : : }
473 : 31 : startVertex = vertDat->start_handle();
474 : : }
475 [ + - ]: 15 : else if( impl->boxDimsTag )
476 : : {
477 : : // look for parametric space info on set
478 : 15 : ErrorCode rval = impl->mbImpl->tag_get_data( impl->boxDimsTag, &bset, 1, boxDims );
479 [ + - ]: 15 : if( MB_SUCCESS == rval )
480 : : {
481 [ + - ]: 15 : Range verts;
482 [ + - ]: 15 : impl->mbImpl->get_entities_by_dimension( bset, 0, verts );
483 [ + - ][ - + ]: 15 : if( !verts.empty() ) startVertex = *verts.begin();
[ # # ][ # # ]
484 : : }
485 : : }
486 : :
487 [ + - ]: 46 : elemSeq = dynamic_cast< StructuredElementSeq* >( seq2 );
488 [ + - ][ - + ]: 46 : if( !elemSeq ) elemSeq = dynamic_cast< StructuredElementSeq* >( seq1 );
489 : :
490 [ + + ]: 46 : if( elemSeq )
491 : : {
492 [ - + ]: 15 : if( vertDat )
493 : : {
494 : : // check the parametric space to make sure it's consistent
495 [ # # ][ # # ]: 0 : assert( elemSeq->sdata()->min_params() == HomCoord( boxDims, 3 ) &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # #
# ]
496 [ # # ]: 0 : ( elemSeq->sdata()->max_params() + HomCoord( 1, 1, 1 ) ) == HomCoord( boxDims, 3 ) );
497 : : }
498 : : else
499 : : {
500 : : // get the parametric space from the element sequence
501 [ + + ]: 60 : for( int i = 0; i < 3; i++ )
502 : : {
503 [ + - ][ + - ]: 45 : boxDims[i] = elemSeq->sdata()->min_params()[i];
[ + - ]
504 [ + - ][ + - ]: 45 : boxDims[3 + i] = elemSeq->sdata()->max_params()[i];
[ + - ]
505 : : }
506 : : }
507 : :
508 : 15 : startElem = elemSeq->start_handle();
509 : : }
510 : : else
511 : : {
512 [ + - ]: 31 : Range elems;
513 : : impl->mbImpl->get_entities_by_dimension(
514 [ + + ][ + + ]: 31 : bset, ( boxDims[2] == boxDims[5] ? ( boxDims[1] == boxDims[4] ? 1 : 2 ) : 3 ), elems );
[ + - ]
515 [ + - ][ - + ]: 31 : if( !elems.empty() ) startElem = *elems.begin();
[ # # ][ # # ]
516 : : // call the following w/o looking at return value, since it doesn't really need to be there
517 [ - + ][ # # ]: 31 : if( impl->boxPeriodicTag ) impl->mbImpl->tag_get_data( impl->boxPeriodicTag, &bset, 1, locallyPeriodic );
518 : : }
519 : :
520 [ + + ][ - + ]: 46 : assert( vertDat || elemSeq || boxDims[0] != boxDims[3] || boxDims[1] != boxDims[4] || boxDims[2] != boxDims[5] );
[ # # ][ # # ]
[ # # ]
521 : :
522 [ + - ][ + - ]: 46 : boxSize = HomCoord( boxDims + 3, 3 ) - HomCoord( boxDims, 3 ) + HomCoord( 1, 1, 1 );
[ + - ][ + - ]
[ + - ]
523 [ + - ][ + - ]: 46 : boxSizeIJ = ( boxSize[1] ? boxSize[1] : 1 ) * boxSize[0];
[ + - ][ + - ]
[ + - ][ # # ]
524 [ + - ]: 46 : boxSizeIM1 = boxSize[0] - ( locallyPeriodic[0] ? 0 : 1 );
525 [ + - ][ + - ]: 46 : boxSizeIJM1 = ( boxSize[1] ? ( boxSize[1] - ( locallyPeriodic[1] ? 0 : 1 ) ) : 1 ) * boxSizeIM1;
[ + - ][ + - ]
[ # # ]
526 : :
527 : 46 : scImpl->add_box( this );
528 : 46 : }
529 : :
530 : 46 : ScdBox::~ScdBox()
531 : : {
532 : : // Reset the tag on the set
533 [ + - ]: 46 : if( boxSet )
534 : : {
535 : : // It is possible that the box set entity has been deleted (e.g. by
536 : : // Core::clean_up_failed_read)
537 [ - + ]: 46 : Core* mbcore = dynamic_cast< Core* >( scImpl->mbImpl );
538 [ - + ]: 46 : assert( mbcore != NULL );
539 [ + - ]: 46 : if( mbcore->is_valid( boxSet ) )
540 : : {
541 : 46 : ScdBox* tmp_ptr = NULL;
542 : 46 : scImpl->mbImpl->tag_set_data( scImpl->box_set_tag(), &boxSet, 1, &tmp_ptr );
543 : : }
544 : : else
545 : 46 : boxSet = 0;
546 : : }
547 : :
548 : 46 : scImpl->remove_box( this );
549 : 46 : }
550 : :
551 : 6520 : EntityHandle ScdBox::get_vertex_from_seq( int i, int j, int k ) const
552 : : {
553 [ - + ]: 6520 : assert( elemSeq );
554 : 6520 : return elemSeq->get_vertex( i, j, k );
555 : : }
556 : :
557 : 13229 : int ScdBox::box_dimension() const
558 : : {
559 [ + + ]: 13229 : return ( startElem ? scImpl->mbImpl->dimension_from_handle( startElem ) : -1 );
560 : : }
561 : :
562 : 39 : ErrorCode ScdBox::add_vbox( ScdBox* vbox, HomCoord from1, HomCoord to1, HomCoord from2, HomCoord to2, HomCoord from3,
563 : : HomCoord to3, bool bb_input, const HomCoord& bb_min, const HomCoord& bb_max )
564 : : {
565 [ - + ]: 39 : if( !vbox->vertDat ) return MB_FAILURE;
566 : 39 : ScdVertexData* dum_data = dynamic_cast< ScdVertexData* >( vbox->vertDat );
567 : : ErrorCode rval =
568 : 39 : elemSeq->sdata()->add_vsequence( dum_data, from1, to1, from2, to2, from3, to3, bb_input, bb_min, bb_max );
569 : 39 : return rval;
570 : : }
571 : :
572 : 15 : bool ScdBox::boundary_complete() const
573 : : {
574 : 15 : return elemSeq->boundary_complete();
575 : : }
576 : :
577 : 15 : ErrorCode ScdBox::get_coordinate_arrays( double*& xc, double*& yc, double*& zc )
578 : : {
579 [ - + ]: 15 : if( !vertDat ) return MB_FAILURE;
580 : :
581 : 15 : xc = reinterpret_cast< double* >( vertDat->get_sequence_data( 0 ) );
582 : 15 : yc = reinterpret_cast< double* >( vertDat->get_sequence_data( 1 ) );
583 : 15 : zc = reinterpret_cast< double* >( vertDat->get_sequence_data( 2 ) );
584 : 15 : return MB_SUCCESS;
585 : : }
586 : :
587 : 0 : ErrorCode ScdBox::get_coordinate_arrays( const double*& xc, const double*& yc, const double*& zc ) const
588 : : {
589 [ # # ]: 0 : if( !vertDat ) return MB_FAILURE;
590 : 0 : xc = reinterpret_cast< const double* >( vertDat->get_sequence_data( 0 ) );
591 : 0 : yc = reinterpret_cast< const double* >( vertDat->get_sequence_data( 1 ) );
592 : 0 : zc = reinterpret_cast< const double* >( vertDat->get_sequence_data( 2 ) );
593 : 0 : return MB_SUCCESS;
594 : : }
595 : :
596 : 0 : ErrorCode ScdBox::vert_dat( ScdVertexData* vert_dt )
597 : : {
598 : 0 : vertDat = vert_dt;
599 : 0 : return MB_SUCCESS;
600 : : }
601 : :
602 : 13 : ErrorCode ScdBox::elem_seq( EntitySequence* elem_sq )
603 : : {
604 [ - + ]: 13 : elemSeq = dynamic_cast< StructuredElementSeq* >( elem_sq );
605 [ + - ]: 13 : if( elemSeq ) elemSeq->is_periodic( locallyPeriodic );
606 : :
607 [ + + ][ + - ]: 13 : if( locallyPeriodic[0] ) boxSizeIM1 = boxSize[0] - ( locallyPeriodic[0] ? 0 : 1 );
608 [ + + ][ + + ]: 13 : if( locallyPeriodic[0] || locallyPeriodic[1] )
609 [ + - ][ + - ]: 6 : boxSizeIJM1 = ( boxSize[1] ? ( boxSize[1] - ( locallyPeriodic[1] ? 0 : 1 ) ) : 1 ) * boxSizeIM1;
[ + - ][ + - ]
[ # # ]
610 : :
611 [ + - ]: 13 : return ( elemSeq ? MB_SUCCESS : MB_FAILURE );
612 : : }
613 : :
614 : 13229 : ErrorCode ScdBox::get_params( EntityHandle ent, HomCoord& ijkd ) const
615 : : {
616 : : // check first whether this is an intermediate entity, so we know what to do
617 : 13229 : int dimension = box_dimension();
618 : 13229 : int this_dim = scImpl->impl()->dimension_from_handle( ent );
619 : :
620 [ + + ][ + - ]: 13229 : if( ( 0 == this_dim && !vertDat ) || ( this_dim && this_dim == dimension ) )
[ + + ][ + - ]
621 : : {
622 [ - + ]: 3506 : assert( elemSeq );
623 [ + - ][ + - ]: 3506 : return elemSeq->get_params( ent, ijkd[0], ijkd[1], ijkd[2] );
[ + - ][ + - ]
624 : : }
625 : :
626 [ + - ][ + - ]: 9723 : else if( !this_dim && vertDat )
627 [ + - ][ + - ]: 9723 : return vertDat->get_params( ent, ijkd[0], ijkd[1], ijkd[2] );
[ + - ][ + - ]
628 : :
629 : : else
630 : 13229 : return MB_NOT_IMPLEMENTED;
631 : : }
632 : :
633 : : //! Get the entity of specified dimension adjacent to parametric element
634 : : /**
635 : : * \param dim Dimension of adjacent entity being requested
636 : : * \param i Parametric coordinates of cell being evaluated
637 : : * \param j Parametric coordinates of cell being evaluated
638 : : * \param k Parametric coordinates of cell being evaluated
639 : : * \param dir Direction (0, 1, or 2), for getting adjacent edges (2d, 3d) or faces (3d)
640 : : * \param ent EntityHandle of adjacent entity
641 : : * \param create_if_missing If true, creates the entity if it doesn't already exist
642 : : */
643 : 914 : ErrorCode ScdBox::get_adj_edge_or_face( int dim, int i, int j, int k, int dir, EntityHandle& ent,
644 : : bool create_if_missing ) const
645 : : {
646 : : // describe connectivity of sub-element in static array
647 : : // subconnect[dim-1][dir][numv][ijk] where dimensions are:
648 : : // [dim-1]: dim=1 or 2, so this is 0 or 1
649 : : // [dir]: one of 0..2, for ijk directions in a hex
650 : : // [numv]: number of vertices describing sub entity = 2*dim <= 4
651 : : // [ijk]: 3 values for i, j, k
652 : : int subconnect[2][3][4][3] = { { { { 0, 0, 0 }, { 1, 0, 0 }, { -1, -1, -1 }, { -1, -1, -1 } }, // i edge
653 : : { { 0, 0, 0 }, { 0, 1, 0 }, { -1, -1, -1 }, { -1, -1, -1 } }, // j edge
654 : : { { 0, 0, 0 }, { 0, 0, 1 }, { -1, -1, -1 }, { -1, -1, -1 } } }, // k edge
655 : :
656 : : { { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 1, 1 }, { 0, 0, 1 } }, // i face
657 : : { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 1 }, { 0, 0, 1 } }, // j face
658 : 914 : { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 1, 0 } } } }; // k face
659 : :
660 : : // check proper input dimensions and lower bound
661 [ + - ][ + - ]: 914 : if( dim < 1 || dim > 2 || i < boxDims[0] || j < boxDims[1] || k < boxDims[2] ) return MB_FAILURE;
[ + - ][ + - ]
[ - + ]
662 : :
663 : : // now check upper bound; parameters must be <= upper corner, since edges/faces
664 : : // follow element parameterization, not vertex parameterization
665 [ + - ][ - + ]: 914 : else if( ( boxDims[3] != boxDims[0] && i > ( locallyPeriodic[0] ? boxDims[3] + 1 : boxDims[3] ) ) ||
[ + - ][ + - ]
666 [ - + ][ + - ]: 914 : ( boxDims[4] != boxDims[1] && j > ( locallyPeriodic[1] ? boxDims[4] + 1 : boxDims[4] ) ) ||
[ + + ]
667 [ - + ]: 872 : ( boxDims[5] != boxDims[2] && k > boxDims[5] ) )
668 : 0 : return MB_FAILURE;
669 : :
670 : : // get the vertices making up this entity
671 : : EntityHandle verts[4];
672 [ + + ]: 4414 : for( int ind = 0; ind < 2 * dim; ind++ )
673 : : {
674 : 3500 : int i1 = i + subconnect[dim - 1][dir][ind][0];
675 : 3500 : int j1 = j + subconnect[dim - 1][dir][ind][1];
676 : : // if periodic in i and i1 is boxDims[3]+1, wrap around
677 [ - + ][ # # ]: 3500 : if( locallyPeriodic[0] && i1 == boxDims[3] + 1 ) i1 = boxDims[0];
678 : : // if periodic in j and j1 is boxDims[4]+1, wrap around
679 [ - + ][ # # ]: 3500 : if( locallyPeriodic[1] && j1 == boxDims[4] + 1 ) j1 = boxDims[1];
680 [ + - ]: 3500 : verts[ind] = get_vertex( i1, j1, k + subconnect[dim - 1][dir][ind][2] );
681 [ - + ]: 3500 : if( !verts[ind] ) return MB_FAILURE;
682 : : }
683 : :
684 [ + - ]: 914 : Range ents;
685 [ + - ][ + - ]: 914 : ErrorCode rval = scImpl->impl()->get_adjacencies( verts, 2 * dim, dim, false, ents );
686 [ - + ]: 914 : if( MB_SUCCESS != rval ) return rval;
687 : :
688 [ + - ][ - + ]: 914 : if( ents.size() > 1 )
689 : 0 : return MB_FAILURE;
690 : :
691 [ + - ][ + + ]: 914 : else if( ents.size() == 1 )
692 : : {
693 [ + - ][ + - ]: 411 : ent = *ents.begin();
694 : : }
695 [ + - ]: 503 : else if( create_if_missing )
696 [ + - ][ + + ]: 503 : rval = scImpl->impl()->create_element( ( 1 == dim ? MBEDGE : MBQUAD ), verts, 2 * dim, ent );
[ + - ]
697 : :
698 : 914 : return rval;
699 : : }
700 : :
701 : : #ifndef MOAB_HAVE_MPI
702 : : ErrorCode ScdInterface::tag_shared_vertices( ParallelComm*, ScdBox* )
703 : : {
704 : : return MB_FAILURE;
705 : : #else
706 : 0 : ErrorCode ScdInterface::tag_shared_vertices( ParallelComm* pcomm, ScdBox* box )
707 : : {
708 [ # # ]: 0 : EntityHandle seth = box->box_set();
709 : :
710 : : // check the # ents in the box against the num in the set, to make sure it's only 1 box;
711 : : // reuse tmp_range
712 [ # # ]: 0 : Range tmp_range;
713 [ # # ][ # # ]: 0 : ErrorCode rval = mbImpl->get_entities_by_dimension( seth, box->box_dimension(), tmp_range );
714 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
715 [ # # ][ # # ]: 0 : if( box->num_elements() != (int)tmp_range.size() ) return MB_FAILURE;
[ # # ]
716 : :
717 [ # # ]: 0 : const int* gdims = box->par_data().gDims;
718 [ # # ][ # # ]: 0 : if( ( gdims[0] == gdims[3] && gdims[1] == gdims[4] && gdims[2] == gdims[5] ) || -1 == box->par_data().partMethod )
[ # # ][ # # ]
[ # # ][ # # ]
719 : 0 : return MB_FAILURE;
720 : :
721 : : // ok, we have a partitioned box; get the vertices shared with other processors
722 [ # # ][ # # ]: 0 : std::vector< int > procs, offsets, shared_indices;
[ # # ]
723 [ # # ]: 0 : rval = get_shared_vertices( pcomm, box, procs, offsets, shared_indices );
724 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
725 : :
726 : : // post receives for start handles once we know how many to look for
727 [ # # ][ # # ]: 0 : std::vector< MPI_Request > recv_reqs( procs.size(), MPI_REQUEST_NULL ), send_reqs( procs.size(), MPI_REQUEST_NULL );
728 [ # # ][ # # ]: 0 : std::vector< EntityHandle > rhandles( 4 * procs.size() ), shandles( 4 );
729 [ # # ]: 0 : for( unsigned int i = 0; i < procs.size(); i++ )
730 : : {
731 [ # # ][ # # ]: 0 : int success = MPI_Irecv( (void*)&rhandles[4 * i], 4 * sizeof( EntityHandle ), MPI_UNSIGNED_CHAR, procs[i], 1,
732 [ # # ][ # # ]: 0 : pcomm->proc_config().proc_comm(), &recv_reqs[i] );
[ # # ][ # # ]
733 [ # # ]: 0 : if( success != MPI_SUCCESS ) return MB_FAILURE;
734 : : }
735 : :
736 : : // send our own start handles
737 [ # # ][ # # ]: 0 : shandles[0] = box->start_vertex();
738 [ # # ]: 0 : shandles[1] = 0;
739 [ # # ][ # # ]: 0 : if( box->box_dimension() == 1 )
740 : : {
741 [ # # ][ # # ]: 0 : shandles[1] = box->start_element();
742 [ # # ]: 0 : shandles[2] = 0;
743 [ # # ]: 0 : shandles[3] = 0;
744 : : }
745 [ # # ][ # # ]: 0 : else if( box->box_dimension() == 2 )
746 : : {
747 [ # # ][ # # ]: 0 : shandles[2] = box->start_element();
748 [ # # ]: 0 : shandles[3] = 0;
749 : : }
750 : : else
751 : : {
752 [ # # ]: 0 : shandles[2] = 0;
753 [ # # ][ # # ]: 0 : shandles[3] = box->start_element();
754 : : }
755 [ # # ]: 0 : for( unsigned int i = 0; i < procs.size(); i++ )
756 : : {
757 [ # # ][ # # ]: 0 : int success = MPI_Isend( (void*)&shandles[0], 4 * sizeof( EntityHandle ), MPI_UNSIGNED_CHAR, procs[i], 1,
758 [ # # ][ # # ]: 0 : pcomm->proc_config().proc_comm(), &send_reqs[i] );
[ # # ][ # # ]
759 [ # # ]: 0 : if( success != MPI_SUCCESS ) return MB_FAILURE;
760 : : }
761 : :
762 : : // receive start handles and save info to a tuple list
763 : 0 : int incoming = procs.size();
764 : : int p, j, k;
765 : : MPI_Status status;
766 [ # # ]: 0 : TupleList shared_data;
767 [ # # ]: 0 : shared_data.initialize( 1, 0, 2, 0, shared_indices.size() / 2 );
768 [ # # ]: 0 : shared_data.enableWriteAccess();
769 : :
770 : 0 : j = 0;
771 : 0 : k = 0;
772 [ # # ]: 0 : while( incoming )
773 : : {
774 [ # # ][ # # ]: 0 : int success = MPI_Waitany( procs.size(), &recv_reqs[0], &p, &status );
775 [ # # ]: 0 : if( MPI_SUCCESS != success ) return MB_FAILURE;
776 [ # # ][ # # ]: 0 : unsigned int num_indices = ( offsets[p + 1] - offsets[p] ) / 2;
777 [ # # ][ # # ]: 0 : int *lh = &shared_indices[offsets[p]], *rh = lh + num_indices;
778 [ # # ]: 0 : for( unsigned int i = 0; i < num_indices; i++ )
779 : : {
780 [ # # ]: 0 : shared_data.vi_wr[j++] = procs[p];
781 [ # # ]: 0 : shared_data.vul_wr[k++] = shandles[0] + lh[i];
782 [ # # ]: 0 : shared_data.vul_wr[k++] = rhandles[4 * p] + rh[i];
783 [ # # ]: 0 : shared_data.inc_n();
784 : : }
785 : 0 : incoming--;
786 : : }
787 : :
788 : : // still need to wait for the send requests
789 [ # # ]: 0 : std::vector< MPI_Status > mult_status( procs.size() );
790 [ # # ][ # # ]: 0 : int success = MPI_Waitall( procs.size(), &send_reqs[0], &mult_status[0] );
[ # # ]
791 [ # # ][ # # ]: 0 : if( MPI_SUCCESS != success ) { MB_SET_ERR( MB_FAILURE, "Failed in waitall in ScdInterface::tag_shared_vertices" ); }
[ # # ][ # # ]
[ # # ][ # # ]
792 : : // sort by local handle
793 [ # # ]: 0 : TupleList::buffer sort_buffer;
794 [ # # ]: 0 : sort_buffer.buffer_init( shared_indices.size() / 2 );
795 [ # # ]: 0 : shared_data.sort( 1, &sort_buffer );
796 [ # # ]: 0 : sort_buffer.reset();
797 : :
798 : : // process into sharing data
799 [ # # ]: 0 : std::map< std::vector< int >, std::vector< EntityHandle > > proc_nvecs;
800 [ # # ]: 0 : Range dum;
801 [ # # ]: 0 : rval = pcomm->tag_shared_verts( shared_data, proc_nvecs, dum, 0 );
802 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
803 : :
804 : : // create interface sets
805 [ # # ]: 0 : rval = pcomm->create_interface_sets( proc_nvecs );
806 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
807 : :
808 : : // add the box to the PComm's partitionSets
809 [ # # ][ # # ]: 0 : pcomm->partition_sets().insert( box->box_set() );
[ # # ]
810 : :
811 : : // make sure buffers are allocated for communicating procs
812 [ # # ][ # # ]: 0 : for( std::vector< int >::iterator pit = procs.begin(); pit != procs.end(); ++pit )
[ # # ]
813 [ # # ][ # # ]: 0 : pcomm->get_buffers( *pit );
814 : :
815 [ # # ][ # # ]: 0 : if( pcomm->get_debug_verbosity() > 1 ) pcomm->list_entities( NULL, 1 );
[ # # ]
816 : :
817 : : #ifndef NDEBUG
818 [ # # ]: 0 : rval = pcomm->check_all_shared_handles();
819 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
820 : : #endif
821 : :
822 : 0 : return MB_SUCCESS;
823 : :
824 : : #endif
825 : : }
826 : :
827 : 299 : ErrorCode ScdInterface::get_neighbor_alljkbal( int np, int pfrom, const int* const gdims, const int* const gperiodic,
828 : : const int* const dijk, int& pto, int* rdims, int* facedims,
829 : : int* across_bdy )
830 : : {
831 [ + + ]: 299 : if( dijk[0] != 0 )
832 : : {
833 : 180 : pto = -1;
834 : 180 : return MB_SUCCESS;
835 : : }
836 : :
837 : 119 : pto = -1;
838 : 119 : across_bdy[0] = across_bdy[1] = across_bdy[2] = 0;
839 : :
840 : : int ldims[6], pijk[3], lperiodic[3];
841 [ + - ]: 119 : ErrorCode rval = compute_partition_alljkbal( np, pfrom, gdims, gperiodic, ldims, lperiodic, pijk );
842 [ - + ]: 119 : if( MB_SUCCESS != rval ) return rval;
843 [ - + ]: 119 : assert( pijk[1] * pijk[2] == np );
844 : 119 : pto = -1;
845 : 119 : bool bot_j = pfrom< pijk[2], top_j = pfrom > np - pijk[2];
846 [ + + ][ + + ]: 119 : if( ( 1 == pijk[2] && dijk[2] ) || // 1d in j means no neighbors with dk != 0
[ + + ]
847 [ + + ][ + + ]: 107 : ( !( pfrom % pijk[2] ) && -1 == dijk[2] ) || // at -k bdy
848 [ + + ][ + + ]: 95 : ( pfrom % pijk[2] == pijk[2] - 1 && 1 == dijk[2] ) || // at +k bdy
849 [ + + ][ - + ]: 83 : ( pfrom < pijk[2] && -1 == dijk[1] && !gperiodic[1] ) || // down and not periodic
[ - + ]
850 [ # # ][ # # ]: 0 : ( pfrom >= np - pijk[2] && 1 == dijk[1] && !gperiodic[1] ) ) // up and not periodic
851 : 41 : return MB_SUCCESS;
852 : :
853 : 78 : pto = pfrom;
854 [ + - ]: 78 : std::copy( ldims, ldims + 6, rdims );
855 [ + - ]: 78 : std::copy( ldims, ldims + 6, facedims );
856 : :
857 [ + + ]: 78 : if( 0 != dijk[1] )
858 : : {
859 : 62 : pto = ( pto + dijk[1] * pijk[2] + np ) % np;
860 [ + - ][ - + ]: 62 : assert( pto >= 0 && pto < np );
861 : 62 : int dj = ( gdims[4] - gdims[1] ) / pijk[1], extra = ( gdims[4] - gdims[1] ) % pijk[1];
862 [ + + ]: 62 : if( -1 == dijk[1] )
863 : : {
864 : 31 : facedims[4] = facedims[1];
865 [ - + ]: 31 : if( bot_j )
866 : : {
867 : : // going across periodic lower bdy in j
868 : 0 : rdims[4] = gdims[4];
869 : 0 : across_bdy[1] = -1;
870 : : }
871 : : else
872 : : {
873 : 31 : rdims[4] = ldims[1];
874 : : }
875 : 31 : rdims[1] = rdims[4] - dj;
876 [ - + ]: 31 : if( pto < extra ) rdims[1]--;
877 : : }
878 : : else
879 : : {
880 [ - + ]: 31 : if( pfrom > np - pijk[2] ) facedims[4] = gdims[1];
881 : 31 : facedims[1] = facedims[4];
882 [ - + ]: 31 : if( top_j )
883 : : {
884 : : // going across periodic upper bdy in j
885 : 0 : rdims[1] = gdims[1];
886 : 0 : across_bdy[1] = 1;
887 : : }
888 : : else
889 : : {
890 : 31 : rdims[1] = ldims[4];
891 : : }
892 : 31 : rdims[4] = rdims[1] + dj;
893 [ - + ]: 62 : if( pto < extra ) rdims[4]++;
894 : : }
895 : : }
896 [ + + ]: 78 : if( 0 != dijk[2] )
897 : : {
898 : 44 : pto = ( pto + dijk[2] ) % np;
899 [ + - ][ - + ]: 44 : assert( pto >= 0 && pto < np );
900 [ + + ]: 44 : facedims[2] = facedims[5] = ( -1 == dijk[2] ? facedims[2] : facedims[5] );
901 : 44 : int dk = ( gdims[5] - gdims[2] ) / pijk[2];
902 [ + + ]: 44 : if( -1 == dijk[2] )
903 : : {
904 : 22 : facedims[5] = facedims[2];
905 : 22 : rdims[5] = ldims[2];
906 : 22 : rdims[2] = rdims[5] - dk; // never any kextra for alljkbal
907 : : }
908 : : else
909 : : {
910 : 22 : facedims[2] = facedims[5];
911 : 22 : rdims[2] = ldims[5];
912 : 44 : rdims[5] = rdims[2] + dk; // never any kextra for alljkbal
913 : : }
914 : : }
915 : :
916 [ + - ][ + - ]: 78 : assert( -1 == pto || ( rdims[0] >= gdims[0] && rdims[3] <= gdims[3] ) );
[ - + ]
917 [ + - ][ + - ]: 78 : assert( -1 == pto || ( rdims[1] >= gdims[1] && ( rdims[4] <= gdims[4] || ( across_bdy[1] && bot_j ) ) ) );
[ - + ][ # # ]
[ # # ]
918 [ + - ][ + - ]: 78 : assert( -1 == pto || ( rdims[2] >= gdims[2] && rdims[5] <= gdims[5] ) );
[ - + ]
919 [ - + ][ # # ]: 78 : assert( -1 == pto || ( ( facedims[0] >= rdims[0] ||
[ # # ][ # # ]
920 [ + - ]: 78 : ( gperiodic[0] && rdims[3] == gdims[3] + 1 && facedims[0] == gdims[0] ) ) ) );
921 [ + - ][ - + ]: 78 : assert( -1 == pto || ( facedims[3] <= rdims[3] ) );
922 [ - + ][ # # ]: 78 : assert( -1 == pto || ( ( facedims[1] >= rdims[1] ||
[ # # ][ # # ]
923 [ + - ]: 78 : ( gperiodic[1] && rdims[4] == gdims[4] + 1 && facedims[1] == gdims[1] ) ) ) );
924 [ + - ][ - + ]: 78 : assert( -1 == pto || ( facedims[4] <= rdims[4] ) );
925 [ + - ][ - + ]: 78 : assert( -1 == pto || ( facedims[2] >= rdims[2] ) );
926 [ + - ][ - + ]: 78 : assert( -1 == pto || ( facedims[5] <= rdims[5] ) );
927 [ + - ][ - + ]: 78 : assert( -1 == pto || ( facedims[0] >= ldims[0] ) );
928 [ + - ][ - + ]: 78 : assert( -1 == pto || ( facedims[3] <= ldims[3] ) );
929 [ + - ][ - + ]: 78 : assert( -1 == pto || ( facedims[1] >= ldims[1] ) );
930 [ + - ][ - + ]: 78 : assert( -1 == pto || ( facedims[4] <= ldims[4] ) );
931 [ + - ][ - + ]: 78 : assert( -1 == pto || ( facedims[2] >= ldims[2] ) );
932 [ + - ][ - + ]: 78 : assert( -1 == pto || ( facedims[5] <= ldims[5] ) );
933 : :
934 : 299 : return MB_SUCCESS;
935 : : }
936 : :
937 : 308 : ErrorCode ScdInterface::get_neighbor_sqij( int np, int pfrom, const int* const gdims, const int* const gperiodic,
938 : : const int* const dijk, int& pto, int* rdims, int* facedims, int* across_bdy )
939 : : {
940 [ + + ]: 308 : if( dijk[2] != 0 )
941 : : {
942 : : // for sqij, there is no k neighbor, ever
943 : 180 : pto = -1;
944 : 180 : return MB_SUCCESS;
945 : : }
946 : :
947 : 128 : pto = -1;
948 : 128 : across_bdy[0] = across_bdy[1] = across_bdy[2] = 0;
949 : : int lperiodic[3], pijk[3], ldims[6];
950 [ + - ]: 128 : ErrorCode rval = compute_partition_sqij( np, pfrom, gdims, gperiodic, ldims, lperiodic, pijk );
951 [ - + ]: 128 : if( MB_SUCCESS != rval ) return rval;
952 [ - + ]: 128 : assert( pijk[0] * pijk[1] == np );
953 : 128 : pto = -1;
954 : 128 : bool top_i = 0, top_j = 0, bot_i = 0, bot_j = 0;
955 : 128 : int ni = pfrom % pijk[0], nj = pfrom / pijk[0]; // row / column number of me
956 [ + + ]: 128 : if( ni == pijk[0] - 1 ) top_i = 1;
957 [ + + ]: 128 : if( nj == pijk[1] - 1 ) top_j = 1;
958 [ + + ]: 128 : if( !ni ) bot_i = 1;
959 [ + + ]: 128 : if( !nj ) bot_j = 1;
960 [ + - ][ + + ]: 128 : if( ( !gperiodic[0] && bot_i && -1 == dijk[0] ) || // left and not periodic
[ + + ][ + - ]
961 [ + + ][ + + ]: 119 : ( !gperiodic[0] && top_i && 1 == dijk[0] ) || // right and not periodic
[ + - ]
962 [ + + ][ + + ]: 110 : ( !gperiodic[1] && bot_j && -1 == dijk[1] ) || // bottom and not periodic
[ + - ]
963 [ + + ][ - + ]: 96 : ( !gperiodic[1] && top_j && 1 == dijk[1] ) ) // top and not periodic
964 : 32 : return MB_SUCCESS;
965 : :
966 [ + - ]: 96 : std::copy( ldims, ldims + 6, facedims );
967 [ + - ]: 96 : std::copy( ldims, ldims + 6, rdims );
968 : 96 : pto = pfrom;
969 : 96 : int j = gdims[4] - gdims[1], dj = j / pijk[1], jextra = ( gdims[4] - gdims[1] ) % dj, i = gdims[3] - gdims[0],
970 : 96 : di = i / pijk[0], iextra = ( gdims[3] - gdims[0] ) % di;
971 : :
972 [ + + ]: 96 : if( 0 != dijk[0] )
973 : : {
974 : 68 : pto = ( ni + dijk[0] + pijk[0] ) % pijk[0]; // get pto's ni value
975 : 68 : pto = nj * pijk[0] + pto; // then convert to pto
976 [ + - ][ - + ]: 68 : assert( pto >= 0 && pto < np );
977 [ + + ]: 68 : if( -1 == dijk[0] )
978 : : {
979 : 34 : facedims[3] = facedims[0];
980 [ - + ]: 34 : if( bot_i )
981 : : {
982 : : // going across lower periodic bdy in i
983 : 0 : across_bdy[0] = -1;
984 : 0 : rdims[3] = gdims[3] + 1; // +1 because ldims[3] on remote proc is gdims[3]+1
985 : 0 : rdims[0] = rdims[3] - di - 1; // -1 to account for rdims[3] being one larger
986 : : }
987 : : else
988 : : {
989 : 34 : rdims[3] = ldims[0];
990 : 34 : rdims[0] = rdims[3] - di;
991 : : }
992 : :
993 [ - + ]: 34 : if( pto % pijk[0] < iextra ) rdims[0]--;
994 : : }
995 : : else
996 : : {
997 [ - + ]: 34 : if( top_i )
998 : : {
999 : : // going across lower periodic bdy in i
1000 : 0 : facedims[3] = gdims[0];
1001 : 0 : across_bdy[0] = 1;
1002 : : }
1003 : 34 : facedims[0] = facedims[3];
1004 [ - + ]: 34 : rdims[0] = ( top_i ? gdims[0] : ldims[3] );
1005 : 34 : rdims[3] = rdims[0] + di;
1006 [ - + ]: 34 : if( pto % pijk[0] < iextra ) rdims[3]++;
1007 [ - + ][ # # ]: 34 : if( gperiodic[0] && ni == pijk[0] - 2 ) rdims[3]++; // remote proc is top_i and periodic
1008 : : }
1009 : : }
1010 [ + + ]: 96 : if( 0 != dijk[1] )
1011 : : {
1012 : 68 : pto = ( pto + dijk[1] * pijk[0] + np ) % np;
1013 [ + - ][ - + ]: 68 : assert( pto >= 0 && pto < np );
1014 [ + + ]: 68 : if( -1 == dijk[1] )
1015 : : {
1016 : 34 : facedims[4] = facedims[1];
1017 [ - + ]: 34 : if( bot_j )
1018 : : {
1019 : : // going across lower periodic bdy in j
1020 : 0 : rdims[4] = gdims[4] + 1; // +1 because ldims[4] on remote proc is gdims[4]+1
1021 : 0 : rdims[1] = rdims[4] - dj - 1; // -1 to account for gdims[4] being one larger
1022 : 0 : across_bdy[1] = -1;
1023 : : }
1024 : : else
1025 : : {
1026 : 34 : rdims[4] = ldims[1];
1027 : 34 : rdims[1] = rdims[4] - dj;
1028 : : }
1029 [ - + ]: 34 : if( pto / pijk[0] < jextra ) rdims[1]--;
1030 : : }
1031 : : else
1032 : : {
1033 [ - + ]: 34 : if( top_j )
1034 : : {
1035 : : // going across lower periodic bdy in j
1036 : 0 : facedims[4] = gdims[1];
1037 : 0 : rdims[1] = gdims[1];
1038 : 0 : across_bdy[1] = 1;
1039 : : }
1040 : : else
1041 : : {
1042 : 34 : rdims[1] = ldims[4];
1043 : : }
1044 : 34 : facedims[1] = facedims[4];
1045 : 34 : rdims[4] = rdims[1] + dj;
1046 [ - + ]: 34 : if( nj + 1 < jextra ) rdims[4]++;
1047 [ - + ][ # # ]: 34 : if( gperiodic[1] && nj == pijk[1] - 2 ) rdims[4]++; // remote proc is top_j and periodic
1048 : : }
1049 : : }
1050 : :
1051 : : // rdims within gdims
1052 [ + - ][ - + ]: 96 : assert( -1 == pto || ( rdims[0] >= gdims[0] &&
[ # # ][ - + ]
1053 [ + - ]: 96 : ( rdims[3] <= gdims[3] + ( gperiodic[0] && pto % pijk[0] == pijk[0] - 1 ? 1 : 0 ) ) ) );
1054 [ + - ][ - + ]: 96 : assert( -1 == pto || ( rdims[1] >= gdims[1] &&
[ # # ][ - + ]
1055 [ + - ]: 96 : ( rdims[4] <= gdims[4] + ( gperiodic[1] && pto / pijk[0] == pijk[1] - 1 ? 1 : 0 ) ) ) );
1056 [ + - ][ + - ]: 96 : assert( -1 == pto || ( rdims[2] >= gdims[2] && rdims[5] <= gdims[5] ) );
[ - + ]
1057 : : // facedims within rdims
1058 [ - + ][ # # ]: 96 : assert( -1 == pto || ( ( facedims[0] >= rdims[0] ||
[ # # ][ # # ]
1059 [ + - ]: 96 : ( gperiodic[0] && pto % pijk[0] == pijk[0] - 1 && facedims[0] == gdims[0] ) ) ) );
1060 [ + - ][ - + ]: 96 : assert( -1 == pto || ( facedims[3] <= rdims[3] ) );
1061 [ - + ][ # # ]: 96 : assert( -1 == pto || ( ( facedims[1] >= rdims[1] ||
[ # # ][ # # ]
1062 [ + - ]: 96 : ( gperiodic[1] && pto / pijk[0] == pijk[1] - 1 && facedims[1] == gdims[1] ) ) ) );
1063 [ + - ][ - + ]: 96 : assert( -1 == pto || ( facedims[4] <= rdims[4] ) );
1064 [ + - ][ + - ]: 96 : assert( -1 == pto || ( facedims[2] >= rdims[2] && facedims[5] <= rdims[5] ) );
[ - + ]
1065 : : // facedims within ldims
1066 [ + - ][ - + ]: 96 : assert( -1 == pto || ( ( facedims[0] >= ldims[0] || ( top_i && facedims[0] == gdims[0] ) ) ) );
[ # # ][ # # ]
1067 [ + - ][ - + ]: 96 : assert( -1 == pto || ( facedims[3] <= ldims[3] ) );
1068 [ + - ][ - + ]: 96 : assert( -1 == pto || ( ( facedims[1] >= ldims[1] || ( gperiodic[1] && top_j && facedims[1] == gdims[1] ) ) ) );
[ # # ][ # # ]
[ # # ]
1069 [ + - ][ - + ]: 96 : assert( -1 == pto || ( facedims[4] <= ldims[4] ) );
1070 [ + - ][ + - ]: 96 : assert( -1 == pto || ( facedims[2] >= ldims[2] && facedims[5] <= ldims[5] ) );
[ - + ]
1071 : :
1072 : 308 : return MB_SUCCESS;
1073 : : }
1074 : :
1075 : 278 : ErrorCode ScdInterface::get_neighbor_sqjk( int np, int pfrom, const int* const gdims, const int* const gperiodic,
1076 : : const int* const dijk, int& pto, int* rdims, int* facedims, int* across_bdy )
1077 : : {
1078 [ + + ]: 278 : if( dijk[0] != 0 )
1079 : : {
1080 : 180 : pto = -1;
1081 : 180 : return MB_SUCCESS;
1082 : : }
1083 : :
1084 : 98 : pto = -1;
1085 : 98 : across_bdy[0] = across_bdy[1] = across_bdy[2] = 0;
1086 : : int pijk[3], lperiodic[3], ldims[6];
1087 [ + - ]: 98 : ErrorCode rval = compute_partition_sqjk( np, pfrom, gdims, gperiodic, ldims, lperiodic, pijk );
1088 [ - + ]: 98 : if( MB_SUCCESS != rval ) return rval;
1089 [ - + ]: 98 : assert( pijk[1] * pijk[2] == np );
1090 : 98 : pto = -1;
1091 : 98 : bool top_j = 0, top_k = 0, bot_j = 0, bot_k = 0;
1092 : 98 : int nj = pfrom % pijk[1], nk = pfrom / pijk[1];
1093 [ + - ]: 98 : if( nj == pijk[1] - 1 ) top_j = 1;
1094 [ - + ]: 98 : if( nk == pijk[2] - 1 ) top_k = 1;
1095 [ + - ]: 98 : if( !nj ) bot_j = 1;
1096 [ + + ]: 98 : if( !nk ) bot_k = 1;
1097 [ + - ][ + - ]: 98 : if( ( !gperiodic[1] && bot_j && -1 == dijk[1] ) || // down and not periodic
[ + + ][ + - ]
1098 [ + - ][ + + ]: 68 : ( !gperiodic[1] && top_j && 1 == dijk[1] ) || // up and not periodic
[ + + ]
1099 [ + + ][ - + ]: 38 : ( bot_k && -1 == dijk[2] ) || // k- bdy
1100 [ # # ]: 0 : ( top_k && 1 == dijk[2] ) ) // k+ bdy
1101 : 62 : return MB_SUCCESS;
1102 : :
1103 [ + - ]: 36 : std::copy( ldims, ldims + 6, facedims );
1104 [ + - ]: 36 : std::copy( ldims, ldims + 6, rdims );
1105 : 36 : pto = pfrom;
1106 : 36 : int dj = ( gdims[4] - gdims[1] ) / pijk[1], jextra = ( gdims[4] - gdims[1] ) % dj,
1107 [ + - ]: 36 : dk = ( gdims[5] == gdims[2] ? 0 : ( gdims[5] - gdims[2] ) / pijk[2] ),
1108 : 36 : kextra = ( gdims[5] - gdims[2] ) - dk * pijk[2];
1109 [ - + ]: 36 : assert( ( dj * pijk[1] + jextra == ( gdims[4] - gdims[1] ) ) &&
1110 [ + - ]: 36 : ( dk * pijk[2] + kextra == ( gdims[5] - gdims[2] ) ) );
1111 [ - + ]: 36 : if( 0 != dijk[1] )
1112 : : {
1113 : 0 : pto = ( nj + dijk[1] + pijk[1] ) % pijk[1]; // get pto's ni value
1114 : 0 : pto = nk * pijk[1] + pto; // then convert to pto
1115 [ # # ][ # # ]: 0 : assert( pto >= 0 && pto < np );
1116 [ # # ]: 0 : if( -1 == dijk[1] )
1117 : : {
1118 : 0 : facedims[4] = facedims[1];
1119 [ # # ]: 0 : if( bot_j )
1120 : : {
1121 : : // going across lower periodic bdy in j
1122 : 0 : rdims[4] = gdims[4] + 1; // +1 because ldims[4] on remote proc is gdims[4]+1
1123 : 0 : across_bdy[1] = -1;
1124 : : }
1125 : : else
1126 : : {
1127 : 0 : rdims[4] = ldims[1];
1128 : : }
1129 : 0 : rdims[1] = rdims[4] - dj;
1130 [ # # ]: 0 : if( nj < jextra ) rdims[1]--;
1131 : : }
1132 : : else
1133 : : {
1134 [ # # ]: 0 : if( top_j )
1135 : : {
1136 : : // going across upper periodic bdy in j
1137 : 0 : rdims[1] = gdims[1];
1138 : 0 : facedims[4] = gdims[1];
1139 : 0 : across_bdy[1] = 1;
1140 : : }
1141 : : else
1142 : : {
1143 : 0 : rdims[1] = ldims[4];
1144 : : }
1145 : 0 : facedims[1] = facedims[4];
1146 : 0 : rdims[4] = rdims[1] + dj;
1147 [ # # ]: 0 : if( nj < jextra ) rdims[4]++;
1148 [ # # ][ # # ]: 0 : if( gperiodic[1] && nj == dijk[1] - 2 ) rdims[4]++; // +1 because next proc is on periodic bdy
1149 : : }
1150 : : }
1151 [ + - ]: 36 : if( 0 != dijk[2] )
1152 : : {
1153 : 36 : pto = ( pto + dijk[2] * pijk[1] + np ) % np;
1154 [ + - ][ - + ]: 36 : assert( pto >= 0 && pto < np );
1155 [ + + ]: 36 : if( -1 == dijk[2] )
1156 : : {
1157 : 18 : facedims[5] = facedims[2];
1158 : 18 : rdims[5] = ldims[2];
1159 : 18 : rdims[2] -= dk;
1160 [ + + ]: 18 : if( pto / pijk[1] < kextra ) rdims[2]--;
1161 : : }
1162 : : else
1163 : : {
1164 : 18 : facedims[2] = facedims[5];
1165 : 18 : rdims[2] = ldims[5];
1166 : 18 : rdims[5] += dk;
1167 [ + + ]: 18 : if( pto / pijk[1] < kextra ) rdims[5]++;
1168 : : }
1169 : : }
1170 : :
1171 [ + - ][ + - ]: 36 : assert( -1 == pto || ( rdims[0] >= gdims[0] && rdims[3] <= gdims[3] ) );
[ - + ]
1172 [ + - ][ + - ]: 36 : assert( -1 == pto || ( rdims[1] >= gdims[1] && ( rdims[4] <= gdims[4] || ( across_bdy[1] && bot_j ) ) ) );
[ - + ][ # # ]
[ # # ]
1173 [ + - ][ + - ]: 36 : assert( -1 == pto || ( rdims[2] >= gdims[2] && rdims[5] <= gdims[5] ) );
[ - + ]
1174 [ + - ][ + - ]: 36 : assert( -1 == pto || ( facedims[0] >= rdims[0] && facedims[3] <= rdims[3] ) );
[ - + ]
1175 [ - + ][ # # ]: 36 : assert( -1 == pto ||
[ # # ][ # # ]
1176 [ + - ]: 36 : ( ( facedims[1] >= rdims[1] || ( gperiodic[1] && rdims[4] == gdims[4] && facedims[1] == gdims[1] ) ) ) );
1177 [ + - ][ - + ]: 36 : assert( -1 == pto || ( facedims[4] <= rdims[4] ) );
1178 [ + - ][ + - ]: 36 : assert( -1 == pto || ( facedims[2] >= rdims[2] && facedims[5] <= rdims[5] ) );
[ - + ]
1179 [ + - ][ + - ]: 36 : assert( -1 == pto || ( facedims[0] >= ldims[0] && facedims[3] <= ldims[3] ) );
[ - + ]
1180 [ + - ][ + - ]: 36 : assert( -1 == pto || ( facedims[1] >= ldims[1] && facedims[4] <= ldims[4] ) );
[ - + ]
1181 [ + - ][ + - ]: 36 : assert( -1 == pto || ( facedims[2] >= ldims[2] && facedims[5] <= ldims[5] ) );
[ - + ]
1182 : :
1183 : 278 : return MB_SUCCESS;
1184 : : }
1185 : :
1186 : 308 : ErrorCode ScdInterface::get_neighbor_sqijk( int np, int pfrom, const int* const gdims, const int* const gperiodic,
1187 : : const int* const dijk, int& pto, int* rdims, int* facedims,
1188 : : int* across_bdy )
1189 : : {
1190 [ + - ][ + - ]: 308 : if( gperiodic[0] || gperiodic[1] || gperiodic[2] ) return MB_FAILURE;
[ - + ]
1191 : :
1192 : 308 : pto = -1;
1193 : 308 : across_bdy[0] = across_bdy[1] = across_bdy[2] = 0;
1194 : : int pijk[3], lperiodic[3], ldims[6];
1195 [ + - ]: 308 : ErrorCode rval = compute_partition_sqijk( np, pfrom, gdims, gperiodic, ldims, lperiodic, pijk );
1196 [ - + ]: 308 : if( MB_SUCCESS != rval ) return rval;
1197 [ - + ]: 308 : assert( pijk[0] * pijk[1] * pijk[2] == np );
1198 : 308 : pto = -1;
1199 : 308 : bool top[3] = { false, false, false }, bot[3] = { false, false, false };
1200 : : // nijk: rank in i/j/k direction
1201 : 308 : int nijk[3] = { pfrom % pijk[0], ( pfrom % ( pijk[0] * pijk[1] ) ) / pijk[0], pfrom / ( pijk[0] * pijk[1] ) };
1202 : :
1203 [ + + ]: 870 : for( int i = 0; i < 3; i++ )
1204 : : {
1205 [ + + ]: 774 : if( nijk[i] == pijk[i] - 1 ) top[i] = true;
1206 [ + + ]: 774 : if( !nijk[i] ) bot[i] = true;
1207 [ + - ][ + + ]: 774 : if( ( !gperiodic[i] && bot[i] && -1 == dijk[i] ) || // downward && not periodic
[ + + ][ + - ]
1208 [ + + ][ + + ]: 647 : ( !gperiodic[i] && top[i] && 1 == dijk[i] ) ) // upward && not periodic
1209 : 212 : return MB_SUCCESS;
1210 : : }
1211 : :
1212 [ + - ]: 96 : std::copy( ldims, ldims + 6, facedims );
1213 [ + - ]: 96 : std::copy( ldims, ldims + 6, rdims );
1214 : 96 : pto = pfrom;
1215 : : int delijk[3], extra[3];
1216 : : // nijk_to: rank of pto in i/j/k direction
1217 : : int nijk_to[3];
1218 [ + + ]: 384 : for( int i = 0; i < 3; i++ )
1219 : : {
1220 [ + - ]: 288 : delijk[i] = ( gdims[i + 3] == gdims[i] ? 0 : ( gdims[i + 3] - gdims[i] ) / pijk[i] );
1221 : 288 : extra[i] = ( gdims[i + 3] - gdims[i] ) % delijk[i];
1222 : 288 : nijk_to[i] = ( nijk[i] + dijk[i] + pijk[i] ) % pijk[i];
1223 : : }
1224 : 96 : pto = nijk_to[2] * pijk[0] * pijk[1] + nijk_to[1] * pijk[0] + nijk_to[0];
1225 [ + - ][ - + ]: 96 : assert( pto >= 0 && pto < np );
1226 [ + + ]: 384 : for( int i = 0; i < 3; i++ )
1227 : : {
1228 [ + + ]: 288 : if( 0 != dijk[i] )
1229 : : {
1230 [ + + ]: 136 : if( -1 == dijk[i] )
1231 : : {
1232 : 68 : facedims[i + 3] = facedims[i];
1233 [ - + ]: 68 : if( bot[i] )
1234 : : {
1235 : : // going across lower periodic bdy in i
1236 : 0 : rdims[i + 3] = gdims[i + 3] + 1; // +1 because ldims[4] on remote proc is gdims[4]+1
1237 : 0 : across_bdy[i] = -1;
1238 : : }
1239 : : else
1240 : : {
1241 : 68 : rdims[i + 3] = ldims[i];
1242 : : }
1243 : 68 : rdims[i] = rdims[i + 3] - delijk[i];
1244 [ - + ]: 68 : if( nijk[i] < extra[i] ) rdims[i]--;
1245 : : }
1246 : : else
1247 : : {
1248 [ - + ]: 68 : if( top[i] )
1249 : : {
1250 : : // going across upper periodic bdy in i
1251 : 0 : rdims[i] = gdims[i];
1252 : 0 : facedims[i + 3] = gdims[i];
1253 : 0 : across_bdy[i] = 1;
1254 : : }
1255 : : else
1256 : : {
1257 : 68 : rdims[i] = ldims[i + 3];
1258 : : }
1259 : 68 : facedims[i] = facedims[i + 3];
1260 : 68 : rdims[i + 3] = rdims[i] + delijk[i];
1261 [ - + ]: 68 : if( nijk[i] < extra[i] ) rdims[i + 3]++;
1262 [ - + ][ # # ]: 68 : if( gperiodic[i] && nijk[i] == dijk[i] - 2 ) rdims[i + 3]++; // +1 because next proc is on periodic bdy
1263 : : }
1264 : : }
1265 : : }
1266 : :
1267 [ - + ]: 96 : assert( -1 != pto );
1268 : : #ifndef NDEBUG
1269 [ + + ]: 384 : for( int i = 0; i < 3; i++ )
1270 : : {
1271 [ + - ][ - + ]: 288 : assert( ( rdims[i] >= gdims[i] && ( rdims[i + 3] <= gdims[i + 3] || ( across_bdy[i] && bot[i] ) ) ) );
[ # # ][ # # ]
1272 [ # # ][ # # ]: 0 : assert( ( ( facedims[i] >= rdims[i] ||
[ # # ]
1273 [ - + ]: 288 : ( gperiodic[i] && rdims[i + 3] == gdims[i + 3] && facedims[i] == gdims[i] ) ) ) );
1274 [ + - ][ - + ]: 288 : assert( ( facedims[i] >= ldims[i] && facedims[i + 3] <= ldims[i + 3] ) );
1275 : : }
1276 : : #endif
1277 : :
1278 : 308 : return MB_SUCCESS;
1279 : : }
1280 : :
1281 : 278 : ErrorCode ScdInterface::get_neighbor_alljorkori( int np, int pfrom, const int* const gdims, const int* const gperiodic,
1282 : : const int* const dijk, int& pto, int* rdims, int* facedims,
1283 : : int* across_bdy )
1284 : : {
1285 : 278 : ErrorCode rval = MB_SUCCESS;
1286 : 278 : pto = -1;
1287 [ - + ]: 278 : if( np == 1 ) return MB_SUCCESS;
1288 : :
1289 : : int pijk[3], lperiodic[3], ldims[6];
1290 [ + - ]: 278 : rval = compute_partition_alljorkori( np, pfrom, gdims, gperiodic, ldims, lperiodic, pijk );
1291 [ - + ]: 278 : if( MB_SUCCESS != rval ) return rval;
1292 : :
1293 : 278 : int ind = -1;
1294 : 278 : across_bdy[0] = across_bdy[1] = across_bdy[2] = 0;
1295 : :
1296 [ + - ]: 556 : for( int i = 0; i < 3; i++ )
1297 : : {
1298 [ + + ]: 556 : if( pijk[i] > 1 )
1299 : : {
1300 : 278 : ind = i;
1301 : 278 : break;
1302 : : }
1303 : : }
1304 : :
1305 [ - + ]: 278 : assert( -1 < ind );
1306 : :
1307 [ + + ]: 278 : if( !dijk[ind] )
1308 : : // no neighbor, pto is already -1, return
1309 : 80 : return MB_SUCCESS;
1310 : :
1311 [ - + ][ # # ]: 198 : bool is_periodic = ( ( gperiodic[0] && ind == 0 ) || ( gperiodic[1] && ind == 1 ) );
[ - + ][ # # ]
1312 [ + + ][ + + ]: 198 : if( dijk[( ind + 1 ) % 3] || dijk[( ind + 2 ) % 3] || // stepping in either other two directions
[ + - ]
1313 [ + + ][ + + ]: 38 : ( !is_periodic && ldims[ind] == gdims[ind] && dijk[ind] == -1 ) || // lower side and going lower
[ + - ]
1314 [ - + ][ # # ]: 36 : ( !is_periodic && ldims[3 + ind] >= gdims[3 + ind] &&
1315 : 0 : dijk[ind] == 1 ) ) // not >= because ldims is only > gdims when periodic;
1316 : : // higher side and going higher
1317 : 162 : return MB_SUCCESS;
1318 : :
1319 [ + - ]: 36 : std::copy( ldims, ldims + 6, facedims );
1320 [ + - ]: 36 : std::copy( ldims, ldims + 6, rdims );
1321 : :
1322 : 36 : int dind = ( gdims[ind + 3] - gdims[ind] ) / np;
1323 : 36 : int extra = ( gdims[ind + 3] - gdims[ind] ) % np;
1324 [ + + ][ + - ]: 36 : if( -1 == dijk[ind] && pfrom )
1325 : : {
1326 : : // actual left neighbor
1327 : 18 : pto = pfrom - 1; // no need for %np, because pfrom > 0
1328 : 18 : facedims[ind + 3] = facedims[ind];
1329 : 18 : rdims[ind + 3] = ldims[ind];
1330 [ + + ]: 18 : rdims[ind] = rdims[ind + 3] - dind - ( pto < extra ? 1 : 0 );
1331 : : }
1332 [ + - ][ + - ]: 18 : else if( 1 == dijk[ind] && pfrom < np - 1 )
1333 : : {
1334 : : // actual right neighbor
1335 : 18 : pto = pfrom + 1;
1336 : 18 : facedims[ind] = facedims[ind + 3];
1337 : 18 : rdims[ind] = ldims[ind + 3];
1338 [ + + ]: 18 : rdims[ind + 3] = rdims[ind] + dind + ( pto < extra ? 1 : 0 );
1339 [ - + ][ # # ]: 18 : if( is_periodic && pfrom == np - 2 ) rdims[ind + 3]++; // neighbor is on periodic bdy
1340 : : }
1341 [ # # ][ # # ]: 0 : else if( -1 == dijk[ind] && !pfrom && gperiodic[ind] )
[ # # ]
1342 : : {
1343 : : // downward across periodic bdy
1344 : 0 : pto = np - 1;
1345 : 0 : facedims[ind + 3] = facedims[ind] = gdims[ind]; // by convention, facedims is within gdims, so lower value
1346 : 0 : rdims[ind + 3] =
1347 : 0 : gdims[ind + 3] + 1; // by convention, local dims one greater than gdims to indicate global lower value
1348 : 0 : rdims[ind] = rdims[ind + 3] - dind - 1;
1349 : 0 : across_bdy[ind] = -1;
1350 : : }
1351 [ # # ][ # # ]: 0 : else if( 1 == dijk[ind] && pfrom == np - 1 && is_periodic )
[ # # ]
1352 : : {
1353 : : // right across periodic bdy
1354 : 0 : pto = 0;
1355 : 0 : facedims[ind + 3] = facedims[ind] = gdims[ind]; // by convention, facedims is within gdims, so lowest value
1356 : 0 : rdims[ind] = gdims[ind];
1357 [ # # ]: 0 : rdims[ind + 3] = rdims[ind] + dind + ( pto < extra ? 1 : 0 );
1358 : 0 : across_bdy[ind] = 1;
1359 : : }
1360 : :
1361 [ + - ][ + - ]: 36 : assert( -1 == pto || ( rdims[0] >= gdims[0] && ( rdims[3] <= gdims[3] || ( across_bdy[0] && !pfrom ) ) ) );
[ - + ][ # # ]
[ # # ]
1362 [ + - ][ + - ]: 36 : assert( -1 == pto || ( rdims[1] >= gdims[1] && ( rdims[4] <= gdims[4] || ( across_bdy[1] && !pfrom ) ) ) );
[ - + ][ # # ]
[ # # ]
1363 [ + - ][ + - ]: 36 : assert( -1 == pto || ( rdims[2] >= gdims[2] && rdims[5] <= gdims[5] ) );
[ - + ]
1364 [ + - ][ + - ]: 36 : assert( -1 == pto || ( facedims[0] >= rdims[0] && facedims[3] <= rdims[3] ) );
[ - + ]
1365 [ + - ][ + - ]: 36 : assert( -1 == pto || ( facedims[1] >= rdims[1] && facedims[4] <= rdims[4] ) );
[ - + ]
1366 [ + - ][ + - ]: 36 : assert( -1 == pto || ( facedims[2] >= rdims[2] && facedims[5] <= rdims[5] ) );
[ - + ]
1367 [ + - ][ + - ]: 36 : assert( -1 == pto || ( facedims[0] >= ldims[0] && facedims[3] <= ldims[3] ) );
[ - + ]
1368 [ + - ][ + - ]: 36 : assert( -1 == pto || ( facedims[1] >= ldims[1] && facedims[4] <= ldims[4] ) );
[ - + ]
1369 [ + - ][ + - ]: 36 : assert( -1 == pto || ( facedims[2] >= ldims[2] && facedims[5] <= ldims[5] ) );
[ - + ]
1370 : :
1371 : 278 : return rval;
1372 : : }
1373 : :
1374 : : //! get shared vertices for alljorkori partition scheme
1375 : : #ifndef MOAB_HAVE_MPI
1376 : : ErrorCode ScdInterface::get_shared_vertices( ParallelComm*, ScdBox*, std::vector< int >&, std::vector< int >&,
1377 : : std::vector< int >& )
1378 : : {
1379 : : return MB_FAILURE;
1380 : : #else
1381 : 0 : ErrorCode ScdInterface::get_shared_vertices( ParallelComm* pcomm, ScdBox* box, std::vector< int >& procs,
1382 : : std::vector< int >& offsets, std::vector< int >& shared_indices )
1383 : : {
1384 : : // get index of partitioned dimension
1385 [ # # ]: 0 : const int* ldims = box->box_dims();
1386 : : ErrorCode rval;
1387 : : int ijkrem[6], ijkface[6], across_bdy[3];
1388 : :
1389 [ # # ]: 0 : for( int k = -1; k <= 1; k++ )
1390 : : {
1391 [ # # ]: 0 : for( int j = -1; j <= 1; j++ )
1392 : : {
1393 [ # # ]: 0 : for( int i = -1; i <= 1; i++ )
1394 : : {
1395 [ # # ][ # # ]: 0 : if( !i && !j && !k ) continue;
[ # # ]
1396 : : int pto;
1397 : 0 : int dijk[] = { i, j, k };
1398 [ # # ][ # # ]: 0 : rval = get_neighbor( pcomm->proc_config().proc_size(), pcomm->proc_config().proc_rank(),
[ # # ][ # # ]
1399 [ # # ][ # # ]: 0 : box->par_data(), dijk, pto, ijkrem, ijkface, across_bdy );
1400 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
1401 [ # # ]: 0 : if( -1 != pto )
1402 : : {
1403 [ # # ][ # # ]: 0 : if( procs.empty() || pto != *procs.rbegin() )
[ # # ][ # # ]
[ # # # # ]
1404 : : {
1405 [ # # ]: 0 : procs.push_back( pto );
1406 [ # # ]: 0 : offsets.push_back( shared_indices.size() );
1407 : : }
1408 [ # # ]: 0 : rval = get_indices( ldims, ijkrem, across_bdy, ijkface, shared_indices );
1409 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
1410 : :
1411 : : // check indices against known #verts on local and remote
1412 : : // begin of this block is shared_indices[*offsets.rbegin()], end is
1413 : : // shared_indices.end(), halfway is
1414 : : // (shared_indices.size()-*offsets.rbegin())/2
1415 : : #ifndef NDEBUG
1416 [ # # ]: 0 : int start_idx = *offsets.rbegin(), end_idx = shared_indices.size(),
1417 : 0 : mid_idx = ( start_idx + end_idx ) / 2;
1418 : :
1419 [ # # ]: 0 : int num_local_verts = ( ldims[3] - ldims[0] + 1 ) * ( ldims[4] - ldims[1] + 1 ) *
1420 [ # # ]: 0 : ( -1 == ldims[2] && -1 == ldims[5] ? 1 : ( ldims[5] - ldims[2] + 1 ) ),
1421 [ # # ]: 0 : num_remote_verts = ( ijkrem[3] - ijkrem[0] + 1 ) * ( ijkrem[4] - ijkrem[1] + 1 ) *
1422 [ # # ]: 0 : ( -1 == ijkrem[2] && -1 == ijkrem[5] ? 1 : ( ijkrem[5] - ijkrem[2] + 1 ) );
1423 : :
1424 [ # # ][ # # ]: 0 : assert(
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1425 : : *std::min_element( &shared_indices[start_idx], &shared_indices[mid_idx] ) >= 0 &&
1426 : : *std::max_element( &shared_indices[start_idx], &shared_indices[mid_idx] ) < num_local_verts &&
1427 : : *std::min_element( &shared_indices[mid_idx], &shared_indices[end_idx] ) >= 0 &&
1428 [ # # ]: 0 : *std::max_element( &shared_indices[mid_idx], &shared_indices[end_idx] ) < num_remote_verts );
1429 : : #endif
1430 : : }
1431 : : }
1432 : : }
1433 : : }
1434 : :
1435 [ # # ]: 0 : offsets.push_back( shared_indices.size() );
1436 : :
1437 : 0 : return MB_SUCCESS;
1438 : : #endif
1439 : : }
1440 : :
1441 : 0 : std::ostream& operator<<( std::ostream& str, const ScdParData& pd )
1442 : : {
1443 : 0 : str << "Partition method = " << ScdParData::PartitionMethodNames[pd.partMethod] << ", gDims = (" << pd.gDims[0]
1444 : 0 : << "," << pd.gDims[1] << "," << pd.gDims[2] << ")-(" << pd.gDims[3] << "," << pd.gDims[4] << "," << pd.gDims[5]
1445 : 0 : << "), gPeriodic = (" << pd.gPeriodic[0] << "," << pd.gPeriodic[1] << "," << pd.gPeriodic[2] << "), pDims = ("
1446 : 0 : << pd.pDims[0] << "," << pd.pDims[1] << "," << pd.pDims[2] << ")" << std::endl;
1447 : 0 : return str;
1448 : : }
1449 : :
1450 [ + - ][ + - ]: 228 : } // namespace moab
|