9 #ifdef MOAB_HAVE_ZOLTAN
22 std::vector< std::string >& dimNames = readNC->
dimNames;
26 if( ( std::find( dimNames.begin(), dimNames.end(), std::string(
"ni" ) ) != dimNames.end() ) &&
27 ( std::find( dimNames.begin(), dimNames.end(), std::string(
"nj" ) ) != dimNames.end() ) &&
28 ( std::find( dimNames.begin(), dimNames.end(), std::string(
"nv" ) ) != dimNames.end() ) )
42 std::map< std::string, ReadNC::VarData >& varInfo =
_readNC->
varInfo;
52 std::vector< std::string >::iterator vit;
54 if( ( vit = std::find( dimNames.begin(), dimNames.end(),
"ni" ) ) != dimNames.end() )
55 idx = vit - dimNames.begin();
58 MB_SET_ERR( MB_FAILURE,
"Couldn't find 'ni' variable" );
62 gDims[3] = dimLens[idx];
65 if( ( vit = std::find( dimNames.begin(), dimNames.end(),
"nj" ) ) != dimNames.end() )
66 idx = vit - dimNames.begin();
69 MB_SET_ERR( MB_FAILURE,
"Couldn't find 'nj' variable" );
73 gDims[4] = dimLens[idx];
82 if( ( vit = std::find( dimNames.begin(), dimNames.end(),
"nv" ) ) != dimNames.end() )
83 idx = vit - dimNames.begin();
86 MB_SET_ERR( MB_FAILURE,
"Couldn't find 'nv' dimension" );
92 int rank = 0, procs = 1;
103 for(
int i = 0; i < 6; i++ )
110 for(
int i = 0; i < 3; i++ )
111 parData.
pDims[i] = pdims[i];
116 dbgOut.
tprintf( 1,
"Contiguous chunks of size %d bytes.\n",
121 for(
int i = 0; i < 6; i++ )
154 std::map< std::string, ReadNC::VarData >::iterator mit;
155 for( mit = varInfo.begin(); mit != varInfo.end(); ++mit )
177 std::vector< std::string > ijdimNames( 2 );
178 ijdimNames[0] =
"__ni";
179 ijdimNames[1] =
"__nj";
180 std::string tag_name;
184 for(
unsigned int i = 0; i != ijdimNames.size(); i++ )
186 std::vector< int > val( 2, 0 );
187 if( ijdimNames[i] ==
"__ni" )
192 else if( ijdimNames[i] ==
"__nj" )
198 std::stringstream ss_tag_name;
199 ss_tag_name << ijdimNames[i] <<
"_LOC_MINMAX";
200 tag_name = ss_tag_name.str();
203 "Trouble creating conventional tag " << tag_name );
205 "Trouble setting data to conventional tag " << tag_name );
206 dbgOut.
tprintf( 2,
"Conventional tag %s is created.\n", tag_name.c_str() );
211 switch( varInfo[
"xc"].varDataType )
217 MB_SET_ERR( MB_FAILURE,
"Unexpected variable data type for 'lon'" );
221 Tag convTagsCreated = 0;
225 "Trouble getting _CONV_TAGS_CREATED tag" );
226 int create_conv_tags_flag = 1;
228 "Trouble setting _CONV_TAGS_CREATED tag" );
247 dbgOut.
tprintf( 1,
"local cells: %d \n", local_elems );
251 std::string maskstr(
"mask" );
259 std::vector< int > mask( local_elems );
261 if( success )
MB_SET_ERR( MB_FAILURE,
"Failed to read int data for mask variable " );
263 std::vector< int > gids( local_elems );
270 gids[elem_index] = j * global_row_size + i + 1;
273 std::vector< NCDF_SIZE > startsv( 3 );
277 std::vector< NCDF_SIZE > countsv( 3 );
283 std::string xvstr(
"xv" );
285 std::vector< double > xv( local_elems *
nv );
287 std::vector< NCDF_SIZE > starts_vv, counts_vv;
288 starts_vv.resize( 3 );
289 counts_vv.resize( 3 );
294 starts_vv[1] = startsv[0];
295 starts_vv[2] = startsv[1];
297 counts_vv[1] = countsv[0];
298 counts_vv[2] = countsv[1];
306 dbgOut.
tprintf( 1,
" nv is the last dimension in xv array (0 or 1) %d \n", (
int)nv_last );
307 success =
NCFUNCAG( _vara_double )(
_fileId, var_xv.
varId, &starts_vv[0], &counts_vv[0], &xv[0] );
308 if( success )
MB_SET_ERR( MB_FAILURE,
"Failed to read double data for xv variable " );
310 std::string yvstr(
"yv" );
312 std::vector< double > yv( local_elems *
nv );
313 success =
NCFUNCAG( _vara_double )(
_fileId, var_yv.
varId, &starts_vv[0], &counts_vv[0], &yv[0] );
314 if( success )
MB_SET_ERR( MB_FAILURE,
"Failed to read double data for yv variable " );
317 std::string xcstr(
"xc" );
319 std::vector< double > xc( local_elems );
321 if( success )
MB_SET_ERR( MB_FAILURE,
"Failed to read double data for xc variable " );
323 std::string ycstr(
"yc" );
325 std::vector< double > yc( local_elems );
327 if( success )
MB_SET_ERR( MB_FAILURE,
"Failed to read double data for yc variable " );
329 std::string fracstr(
"frac" );
331 std::vector< double > frac( local_elems );
332 if( var_frac.
varId >= 0 )
336 if( success )
MB_SET_ERR( MB_FAILURE,
"Failed to read double data for frac variable " );
338 std::string areastr(
"area" );
339 std::vector< double > area( local_elems );
342 if( success )
MB_SET_ERR( MB_FAILURE,
"Failed to read double data for area variable " );
344 Tag areaTag, fracTag, xcTag, ycTag;
346 "Trouble creating area tag" );
348 "Trouble creating frac tag" );
350 "Trouble creating xc tag" );
352 "Trouble creating yc tag" );
360 "Trouble creating GRID_IMASK tag" );
374 if( procs >= 2 && repartition )
377 MB_CHK_SET_ERR( redistribute_cells( myPcomm, xc, yc, xv, yv, frac, mask, area, gids,
nv, nv_last ),
378 "Failed to redistribute local cells" );
379 local_elems = (int)xc.size();
380 dbgOut.
tprintf( 1,
"local cells after repartition: %d \n", local_elems );
385 int nb_with_mask1 = 0;
386 for(
int i = 0; i < local_elems; i++ )
387 if( 1 == mask[i] ) nb_with_mask1++;
388 dbgOut.
tprintf( 1,
"local cells with mask 1: %d \n", nb_with_mask1 );
406 int num_actual_cells = local_elems;
407 if( culling ) num_actual_cells = nb_with_mask1;
409 if(
nv > 1 && num_actual_cells > 0 )
413 "Failed to create local cells" );
414 tmp_range.
insert( start_cell, start_cell + num_actual_cells - 1 );
418 std::map< Node3D, EntityHandle > vertex_map;
420 if( num_actual_cells > 0 )
426 const double pideg = acos( -1.0 ) / 180.0;
428 for( elem_index = 0; elem_index < local_elems; elem_index++ )
430 if( culling && 0 == mask[elem_index] )
433 dbgOut.
tprintf( 3,
"elem index %d \n", elem_index );
434 for(
int k = 0; k <
nv; k++ )
436 int index_v_arr =
nv * elem_index + k;
437 if( !nv_last ) index_v_arr = k * local_elems + elem_index;
443 double cosphi = cos(
pideg * y );
444 double zmult = sin(
pideg * y );
445 double xmult = cosphi * cos( x *
pideg );
446 double ymult = cosphi * sin( x *
pideg );
447 Node3D pt( xmult, ymult, zmult );
449 dbgOut.
tprintf( 3,
" %d x=%5.1f y=%5.1f pt: %f %f %f \n", k, x, y, pt.
coords[0], pt.
coords[1],
461 int nLocalVertices = (int)vertex_map.size();
462 std::vector< double* > arrays;
465 "Failed to create local vertices" );
467 vtx_handle = start_vertex;
470 double *x = arrays[0], *y = arrays[1], *z = arrays[2];
471 for(
auto i = vertex_map.begin(); i != vertex_map.end(); ++i )
473 i->second = vtx_handle;
475 *x = i->first.coords[0];
477 *y = i->first.coords[1];
479 *z = i->first.coords[2];
489 for( elem_index = 0; elem_index < local_elems; elem_index++ )
491 if( culling && 0 == mask[elem_index] )
494 for(
int k = 0; k <
nv; k++ )
496 int index_v_arr =
nv * elem_index + k;
497 if( !nv_last ) index_v_arr = k * local_elems + elem_index;
500 double x = xv[index_v_arr];
501 double y = yv[index_v_arr];
502 double cosphi = cos(
pideg * y );
503 double zmult = sin(
pideg * y );
504 double xmult = cosphi * cos( x *
pideg );
505 double ymult = cosphi * sin( x *
pideg );
506 Node3D pt( xmult, ymult, zmult );
507 conn_arr[
index *
nv + k] = vertex_map[pt];
511 if(
nv > 1 ) cell = start_cell +
index;
520 int globalId = gids[elem_index];
528 std::vector< Tag > tagList;
529 tagList.push_back( mGlobalIdTag );
530 tagList.push_back( xcTag );
531 tagList.push_back( ycTag );
532 tagList.push_back( areaTag );
533 tagList.push_back( fracTag );
534 tagList.push_back( maskTag );
536 "Failed to remove duplicate vertices" );
557 MB_CHK_ERR(
mb->get_connectivity( eh, conn, num_nodes ) );
565 if( myPcomm && procs >= 2 )
572 "Failed to merge vertices in parallel" );
583 std::vector< double >& xc,
584 std::vector< double >& yc,
585 std::vector< double >& xv,
586 std::vector< double >& yv,
587 std::vector< double >& frac,
588 std::vector< int >& masks,
589 std::vector< double >& area,
590 std::vector< int >& gids,
596 #ifdef MOAB_HAVE_ZOLTAN
598 if( !my_rank ) std::cout <<
"Using Zoltan RCB spatial partitioning method\n";
600 size_t num_local_cells = gids.size();
603 num_local_cells = std::count( masks.begin(), masks.end(), 1 );
606 size_t actual_index = 0;
607 std::vector< double > xi( num_local_cells ), yi( num_local_cells ), zi( num_local_cells );
608 std::vector< int > gids2( num_local_cells );
611 const double deg_to_rad = std::acos( -1.0 ) / 180.0;
612 for(
size_t i = 0; i < xc.size(); ++i )
616 const double lon_rad = xc[i] * deg_to_rad;
617 const double lat_rad = yc[i] * deg_to_rad;
618 const double cos_lat = std::cos( lat_rad );
619 const double sin_lat = std::sin( lat_rad );
621 xi[actual_index] = cos_lat * std::cos( lon_rad );
622 yi[actual_index] = cos_lat * std::sin( lon_rad );
623 zi[actual_index] = sin_lat;
624 gids2[actual_index] = gids[i];
629 std::vector< int > dest( num_local_cells );
633 MB_CHK_SET_ERR( mbZTool.repartition_to_procs( xi, yi, zi, gids2,
"RCB", dest ),
634 "Error in Zoltan partitioning" );
639 const unsigned num_real = 2 *
nv + 4;
640 tl.
initialize( 3, 0, 0, num_real, num_local_cells );
644 size_t index_in_dest = 0;
645 for(
size_t i = 0; i < xc.size(); ++i )
649 const int to_proc = dest[index_in_dest];
650 const int global_id = gids2[index_in_dest];
651 const int mask = masks[i];
652 const int n = tl.
get_n();
654 tl.
vi_wr[3 * n + 0] = to_proc;
655 tl.
vi_wr[3 * n + 1] = global_id;
656 tl.
vi_wr[3 * n + 2] = mask;
658 tl.
vr_wr[n * num_real + 0] = area[i];
659 tl.
vr_wr[n * num_real + 1] = xc[i];
660 tl.
vr_wr[n * num_real + 2] = yc[i];
661 tl.
vr_wr[n * num_real + 3] = frac[i];
663 for(
int k = 0; k <
nv; ++k )
665 const size_t index_v = nv_last ?
nv * i + k : k * xc.size() + i;
666 tl.
vr_wr[n * num_real + 4 + k] = xv[index_v];
667 tl.
vr_wr[n * num_real + 4 +
nv + k] = yv[index_v];
681 sort_buffer.buffer_init( N );
682 tl.
sort( 1, &sort_buffer );
694 for(
int n = 0; n < N; ++n )
696 gids[n] = tl.
vi_wr[3 * n + 1];
697 masks[n] = tl.
vi_wr[3 * n + 2];
698 area[n] = tl.
vr_wr[n * num_real + 0];
699 xc[n] = tl.
vr_wr[n * num_real + 1];
700 yc[n] = tl.
vr_wr[n * num_real + 2];
701 frac[n] = tl.
vr_wr[n * num_real + 3];
703 for(
int k = 0; k <
nv; ++k )
705 const size_t index_v = nv_last ?
nv * n + k : k * N + n;
706 xv[index_v] = tl.
vr_wr[n * num_real + 4 + k];
707 yv[index_v] = tl.
vr_wr[n * num_real + 4 +
nv + k];
715 constexpr
bool use_spatial_partitioning =
true;
720 std::cout <<
"Using native spatial partitioning method\n";
722 std::cout <<
"Using native trivial partitioning method\n";
725 size_t num_local_cells = gids.size();
728 num_local_cells = std::count( masks.begin(), masks.end(), 1 );
732 const unsigned num_real = 2 *
nv + 4;
733 tl.
initialize( 3, 0, 0, num_real, num_local_cells );
736 auto clamp = [](
int v,
int lo,
int hi ) {
return ( v < lo ) ? lo : ( v > hi ) ? hi : v; };
738 size_t actual_index = 0;
739 for(
size_t i = 0; i < xc.size(); ++i )
743 const int n = tl.
get_n();
750 while( lon < -180.0 )
755 double lon_norm = ( lon + 180.0 ) / 360.0;
758 to_proc =
static_cast< int >( lon_norm * num_procs );
760 to_proc = clamp( to_proc, 0, num_procs - 1 );
767 to_proc = actual_index * num_procs / num_local_cells;
770 tl.
vi_wr[3 * n + 0] = to_proc;
771 tl.
vi_wr[3 * n + 1] = gids[i];
772 tl.
vi_wr[3 * n + 2] = masks[i];
774 tl.
vr_wr[n * num_real + 0] = area[i];
775 tl.
vr_wr[n * num_real + 1] = xc[i];
776 tl.
vr_wr[n * num_real + 2] = yc[i];
777 tl.
vr_wr[n * num_real + 3] = frac[i];
779 for(
int k = 0; k <
nv; ++k )
781 const size_t index_v = nv_last ?
nv * i + k : k * xc.size() + i;
782 tl.
vr_wr[n * num_real + 4 + k] = xv[index_v];
783 tl.
vr_wr[n * num_real + 4 +
nv + k] = yv[index_v];
795 const int N = tl.
get_n();
796 sort_buffer.buffer_init( N );
797 tl.
sort( 1, &sort_buffer );
809 for(
int n = 0; n < N; ++n )
811 gids[n] = tl.
vi_wr[3 * n + 1];
812 masks[n] = tl.
vi_wr[3 * n + 2];
813 area[n] = tl.
vr_wr[n * num_real + 0];
814 xc[n] = tl.
vr_wr[n * num_real + 1];
815 yc[n] = tl.
vr_wr[n * num_real + 2];
816 frac[n] = tl.
vr_wr[n * num_real + 3];
818 for(
int k = 0; k <
nv; ++k )
820 const size_t index_v = nv_last ?
nv * n + k : k * N + n;
821 xv[index_v] = tl.
vr_wr[n * num_real + 4 + k];
822 yv[index_v] = tl.
vr_wr[n * num_real + 4 +
nv + k];