18 class StructuredElementSeq;
191 const double*
const coords,
192 unsigned int num_coords,
194 int*
const lperiodic = NULL,
196 bool assign_global_ids =
false,
197 int resolve_shared_ents = -1 );
216 int* is_periodic = NULL );
223 ErrorCode find_boxes( std::vector< ScdBox* >& boxes );
237 ErrorCode get_boxes( std::vector< ScdBox* >& boxes );
243 Tag box_dims_tag(
bool create_if_missing =
true );
249 Tag global_box_dims_tag(
bool create_if_missing =
true );
255 Tag part_method_tag(
bool create_if_missing =
true );
261 Tag box_periodic_tag(
bool create_if_missing =
true );
267 Tag box_set_tag(
bool create_if_missing =
true );
287 static ErrorCode compute_partition(
int np,
291 int* lperiodic = NULL,
309 const int*
const dijk,
343 int* is_periodic = NULL );
350 inline static ErrorCode compute_partition_alljorkori(
int np,
353 const int*
const gperiodic,
363 inline static ErrorCode compute_partition_alljkbal(
int np,
366 const int*
const gperiodic,
375 inline static ErrorCode compute_partition_sqij(
int np,
378 const int*
const gperiodic,
387 inline static ErrorCode compute_partition_sqjk(
int np,
390 const int*
const gperiodic,
399 inline static ErrorCode compute_partition_sqijk(
int np,
402 const int*
const gperiodic,
416 std::vector< int >& procs,
417 std::vector< int >& offsets,
418 std::vector< int >& shared_indices );
420 static ErrorCode get_indices(
const int*
const ldims,
421 const int*
const rdims,
422 const int*
const across_bdy,
424 std::vector< int >& shared_indices );
426 static ErrorCode get_neighbor_alljorkori(
int np,
428 const int*
const gdims,
429 const int*
const gperiodic,
430 const int*
const dijk,
436 static ErrorCode get_neighbor_alljkbal(
int np,
438 const int*
const gdims,
439 const int*
const gperiodic,
440 const int*
const dijk,
446 static ErrorCode get_neighbor_sqij(
int np,
448 const int*
const gdims,
449 const int*
const gperiodic,
450 const int*
const dijk,
456 static ErrorCode get_neighbor_sqjk(
int np,
458 const int*
const gdims,
459 const int*
const gperiodic,
460 const int*
const dijk,
466 static ErrorCode get_neighbor_sqijk(
int np,
468 const int*
const gdims,
469 const int*
const gperiodic,
470 const int*
const dijk,
476 static int gtol(
const int* gijk,
int i,
int j,
int k );
537 bool bb_input =
false,
548 bool boundary_complete()
const;
551 inline int box_dimension()
const;
564 inline int num_elements()
const;
569 inline int num_vertices()
const;
575 inline const int* box_dims()
const;
590 inline void box_size(
int* ijk )
const;
598 void box_size(
int& i,
int& j,
int& k )
const;
612 EntityHandle get_element(
int i,
int j = 0,
int k = 0 )
const;
626 EntityHandle get_vertex(
int i,
int j = 0,
int k = 0 )
const;
677 bool create_if_missing =
true )
const;
685 bool contains(
int i,
int j,
int k )
const;
693 bool contains(
const HomCoord& ijk )
const;
705 ErrorCode get_coordinate_arrays(
double*& xc,
double*& yc,
double*& zc );
713 ErrorCode get_coordinate_arrays(
const double*& xc,
const double*& yc,
const double*& zc )
const;
719 bool locally_periodic_i()
const;
725 bool locally_periodic_j()
const;
731 bool locally_periodic_k()
const;
737 void locally_periodic(
bool lperiodic[3] );
743 const int* locally_periodic()
const;
792 EntityHandle get_vertex_from_seq(
int i,
int j,
int k )
const;
835 int locallyPeriodic[3];
886 const int*
const gperiodic,
893 int tmp_lp[3], tmp_pijk[3];
894 if( !lperiodic ) lperiodic = tmp_lp;
895 if( !pijk ) pijk = tmp_pijk;
897 for(
int i = 0; i < 3; i++ )
898 lperiodic[i] = gperiodic[i];
911 pijk[0] = pijk[1] = pijk[2] = 1;
915 if( gijk[4] - gijk[1] > np )
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 );
923 if( gperiodic[1] && np > 1 )
933 pijk[0] = pijk[2] = 1;
936 else if( gijk[5] - gijk[2] > np )
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 );
948 pijk[0] = pijk[1] = 1;
951 else if( gijk[3] - gijk[0] > np )
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 );
959 if( gperiodic[0] && np > 1 )
970 pijk[1] = pijk[2] = 1;
986 const int*
const gperiodic,
991 int tmp_lp[3], tmp_pijk[3];
992 if( !lperiodic ) lperiodic = tmp_lp;
993 if( !pijk ) pijk = tmp_pijk;
995 for(
int i = 0; i < 3; i++ )
996 lperiodic[i] = gperiodic[i];
1009 pijk[0] = pijk[1] = pijk[2] = 1;
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 );
1022 int J = gijk[4] - gijk[1];
1023 double njideal = sqrt( ( (
double)( np * J ) ) / ( (
double)K ) );
1024 double nkideal = ( njideal * K ) / J;
1034 std::vector< double >::iterator vit = std::lower_bound( kfactors.begin(), kfactors.end(), nkideal );
1035 if( vit == kfactors.begin() )
1038 nk = (int)*( --vit );
1045 ldims[2] = gijk[2] + (
nr % nk ) * dk;
1046 ldims[5] = ldims[2] + dk;
1050 ldims[1] = gijk[1] + (
nr / nk ) * dj + std::min(
nr / nk, extra );
1051 ldims[4] = ldims[1] + dj + (
nr / nk < extra ? 1 : 0 );
1056 if( gperiodic[1] && np > 1 )
1059 if(
nr / nk == nj - 1 )
1076 const int*
const gperiodic,
1081 int tmp_lp[3], tmp_pijk[3];
1082 if( !lperiodic ) lperiodic = tmp_lp;
1083 if( !pijk ) pijk = tmp_pijk;
1087 for(
int i = 0; i < 3; i++ )
1088 lperiodic[i] = gperiodic[i];
1101 pijk[0] = pijk[1] = pijk[2] = 1;
1105 std::vector< double > pfactors, ppfactors;
1106 for(
int i = 2; i <= np / 2; i++ )
1109 pfactors.push_back( i );
1110 ppfactors.push_back( ( (
double)( i * i ) ) / np );
1112 pfactors.push_back( np );
1113 ppfactors.push_back( (
double)np );
1116 double ijratio = ( (double)( gijk[3] - gijk[0] ) ) / ( (
double)( gijk[4] - gijk[1] ) );
1118 unsigned int ind = 0;
1119 std::vector< double >::iterator optimal = std::lower_bound( ppfactors.begin(), ppfactors.end(), ijratio );
1120 if( optimal == ppfactors.end() )
1122 ind = ppfactors.size() - 1;
1126 ind = optimal - ppfactors.begin();
1127 if( ind && fabs( ppfactors[ind - 1] - ijratio ) < fabs( ppfactors[ind] - ijratio ) ) ind--;
1137 int pi = pfactors[ind];
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;
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 );
1154 if( gperiodic[0] && pi > 1 )
1157 if( nri == pi - 1 ) ldims[3]++;
1159 if( gperiodic[1] && pj > 1 )
1162 if( nrj == pj - 1 ) ldims[4]++;
1177 const int*
const gperiodic,
1182 int tmp_lp[3], tmp_pijk[3];
1183 if( !lperiodic ) lperiodic = tmp_lp;
1184 if( !pijk ) pijk = tmp_pijk;
1187 for(
int i = 0; i < 3; i++ )
1188 lperiodic[i] = gperiodic[i];
1201 pijk[0] = pijk[1] = pijk[2] = 1;
1205 std::vector< double > pfactors, ppfactors;
1206 for(
int p = 2; p <= np; p++ )
1209 pfactors.push_back( p );
1210 ppfactors.push_back( ( (
double)( p * p ) ) / np );
1215 if( gijk[5] == gijk[2] )
1222 double jkratio = ( (double)( gijk[4] - gijk[1] ) ) / ( (
double)( gijk[5] - gijk[2] ) );
1224 std::vector< double >::iterator vit = std::lower_bound( ppfactors.begin(), ppfactors.end(), jkratio );
1225 if( vit == ppfactors.end() )
1227 else if( vit != ppfactors.begin() && fabs( *( vit - 1 ) - jkratio ) < fabs( ( *vit ) - jkratio ) )
1229 int ind = vit - ppfactors.begin();
1232 if( ind >= 0 && !pfactors.empty() ) pj = pfactors[ind];
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 );
1247 if( gperiodic[1] && pj > 1 )
1250 if( nrj == pj - 1 ) ldims[4]++;
1263 const int*
const gijk,
1264 const int*
const gperiodic,
1269 if( gperiodic[0] || gperiodic[1] || gperiodic[2] )
return MB_FAILURE;
1271 int tmp_lp[3], tmp_pijk[3];
1272 if( !lperiodic ) lperiodic = tmp_lp;
1273 if( !pijk ) pijk = tmp_pijk;
1277 for(
int i = 0; i < 3; i++ )
1278 lperiodic[i] = gperiodic[i];
1283 for(
int i = 0; i < 6; i++ )
1285 pijk[0] = pijk[1] = pijk[2] = 1;
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 );
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 );
1301 for(
int i = 1; i < 3; i++ )
1303 if( IJK[i] < IJK[lo] ) lo = i;
1304 if( IJK[i] > IJK[hi] ) hi = i;
1306 if( lo == hi ) hi = ( lo + 1 ) % 3;
1307 int mid = 3 - lo - hi;
1309 int perfa_best = -1, perfb_best = -1;
1311 for(
int po = 0; po < (int)pfactors.size(); po++ )
1313 for(
int pi = po; pi < (int)pfactors.size() && np / ( pfactors[po] * pfactors[pi] ) >= pfactors[pi]; pi++ )
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 )
1319 assert( po <= pi && pi <= p3 );
1322 std::min( std::min( IJK[lo] / pfactors[po], IJK[mid] / pfactors[pi] ), IJK[hi] / pfactors[p3] ),
1324 std::max( std::max( IJK[lo] / pfactors[po], IJK[mid] / pfactors[pi] ), IJK[hi] / pfactors[p3] );
1325 if( minl / maxl > ratio )
1327 ratio = minl / maxl;
1333 if( perfa_best == -1 || perfb_best == -1 )
return MB_FAILURE;
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++ )
1348 dIJK[i] = IJK[i] / pijk[i];
1349 extra[i] = IJK[i] % pijk[i];
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++ )
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 );
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] );
1372 const int*
const rdims,
1373 const int*
const across_bdy,
1375 std::vector< int >& shared_indices )
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];
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 ) );
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];
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 ) );
1413 const int*
const dijk,
1419 if( !dijk[0] && !dijk[1] && !dijk[2] )
1463 if( !box )
return MB_FAILURE;
1512 return num_e_i * num_e_j * num_e_k;
1655 for(
int i = 0; i < 3; i++ )