319 std::string typestr,
int nEntWgts):
320 dimension_(0), num_nodes_global_(0), num_elems_global_(0), num_nodes_(0), num_elem_(0),
321 element_num_map_(nullptr), node_num_map_(nullptr), elemToNode_(nullptr), elemOffsets_(nullptr),
322 nodeToElem_(nullptr), nodeOffsets_(nullptr), nWeightsPerEntity_(nEntWgts), entityDegreeWeight_(nullptr),
323 coords_(nullptr), Acoords_(nullptr), eStart_(nullptr), nStart_(nullptr), eAdj_(nullptr), nAdj_(nullptr),
324 nodeTopology(nullptr), elemTopology(nullptr)
331 int num_elem_blk, num_node_sets, num_side_sets;
332 error += im_ex_get_init(exoid, title, &dimension_,
333 &num_nodes_, &num_elem_, &num_elem_blk,
334 &num_node_sets, &num_side_sets);
336 if (typestr.compare(
"region") == 0) {
343 else if (typestr.compare(
"vertex") == 0) {
353 double *dcoords =
new double [num_nodes_ * dimension_];
354 coords_ =
new scalar_t [num_nodes_ * dimension_];
356 error += im_ex_get_coord(exoid, dcoords, dcoords + num_nodes_,
357 dcoords + 2 * num_nodes_);
359 size_t dlen = num_nodes_ * dimension_;
360 for (
size_t i = 0; i < dlen; i++) coords_[i] = as<scalar_t>(dcoords[i]);
363 element_num_map_ =
new gno_t[num_elem_];
364 std::vector<int> tmp;
365 tmp.resize(num_elem_);
370 error += im_ex_get_elem_num_map(exoid, &tmp[0]);
371 for(
size_t i = 0; i < tmp.size(); i++)
372 element_num_map_[i] =
static_cast<gno_t>(tmp[i]);
375 tmp.resize(num_nodes_);
376 node_num_map_ =
new gno_t [num_nodes_];
381 error += im_ex_get_node_num_map(exoid, &tmp[0]);
382 for(
size_t i = 0; i < tmp.size(); i++)
383 node_num_map_[i] =
static_cast<gno_t>(tmp[i]);
386 for (
int i=0;i<num_nodes_;i++)
387 nodeTopology[i] =
POINT;
389 for (
int i=0;i<num_elem_;i++) {
396 int *elem_blk_ids =
new int [num_elem_blk];
397 error += im_ex_get_elem_blk_ids(exoid, elem_blk_ids);
399 int *num_nodes_per_elem =
new int [num_elem_blk];
400 int *num_attr =
new int [num_elem_blk];
401 int *num_elem_this_blk =
new int [num_elem_blk];
402 char **elem_type =
new char * [num_elem_blk];
403 int **connect =
new int * [num_elem_blk];
405 for(
int i = 0; i < num_elem_blk; i++){
406 elem_type[i] =
new char [MAX_STR_LENGTH + 1];
407 error += im_ex_get_elem_block(exoid, elem_blk_ids[i], elem_type[i],
408 (
int*)&(num_elem_this_blk[i]),
409 (
int*)&(num_nodes_per_elem[i]),
410 (
int*)&(num_attr[i]));
411 delete[] elem_type[i];
418 Acoords_ =
new scalar_t [num_elem_ * dimension_];
420 std::vector<std::vector<gno_t> > sur_elem;
421 sur_elem.resize(num_nodes_);
423 for(
int b = 0; b < num_elem_blk; b++) {
424 connect[b] =
new int [num_nodes_per_elem[b]*num_elem_this_blk[b]];
425 error += im_ex_get_elem_conn(exoid, elem_blk_ids[b], connect[b]);
427 for(
int i = 0; i < num_elem_this_blk[b]; i++) {
429 Acoords_[num_elem_ + a] = 0;
431 if (3 == dimension_) {
432 Acoords_[2 * num_elem_ + a] = 0;
435 for(
int j = 0; j < num_nodes_per_elem[b]; j++) {
436 int node = connect[b][i * num_nodes_per_elem[b] + j] - 1;
437 Acoords_[a] += coords_[node];
438 Acoords_[num_elem_ + a] += coords_[num_nodes_ + node];
440 if(3 == dimension_) {
441 Acoords_[2 * num_elem_ + a] += coords_[2 * num_nodes_ + node];
450 if (sur_elem[node].empty() ||
451 element_num_map_[a] != sur_elem[node][sur_elem[node].size()-1]) {
453 sur_elem[node].push_back(element_num_map_[a]);
457 Acoords_[a] /= num_nodes_per_elem[b];
458 Acoords_[num_elem_ + a] /= num_nodes_per_elem[b];
460 if(3 == dimension_) {
461 Acoords_[2 * num_elem_ + a] /= num_nodes_per_elem[b];
469 delete[] elem_blk_ids;
471 int nnodes_per_elem = num_nodes_per_elem[0];
472 elemToNode_ =
new gno_t[num_elem_ * nnodes_per_elem];
474 elemOffsets_ =
new offset_t [num_elem_+1];
476 int **reconnect =
new int * [num_elem_];
479 for (
int b = 0; b < num_elem_blk; b++) {
480 for (
int i = 0; i < num_elem_this_blk[b]; i++) {
481 elemOffsets_[telct] = tnoct_;
482 reconnect[telct] =
new int [num_nodes_per_elem[b]];
484 for (
int j = 0; j < num_nodes_per_elem[b]; j++) {
486 as<gno_t>(node_num_map_[connect[b][i*num_nodes_per_elem[b] + j]-1]);
487 reconnect[telct][j] = connect[b][i*num_nodes_per_elem[b] + j];
494 elemOffsets_[telct] = tnoct_;
496 delete[] num_nodes_per_elem;
497 num_nodes_per_elem = NULL;
498 delete[] num_elem_this_blk;
499 num_elem_this_blk = NULL;
501 for(
int b = 0; b < num_elem_blk; b++) {
508 int max_side_nodes = nnodes_per_elem;
509 int *side_nodes =
new int [max_side_nodes];
510 int *mirror_nodes =
new int [max_side_nodes];
513 eStart_ =
new lno_t [num_elem_+1];
514 nStart_ =
new lno_t [num_nodes_+1];
515 std::vector<int> eAdj;
516 std::vector<int> nAdj;
518 for (
int i=0; i < max_side_nodes; i++) {
520 mirror_nodes[i]=-999;
526 for(
int ncnt=0; ncnt < num_nodes_; ncnt++) {
527 if(sur_elem[ncnt].empty()) {
528 std::cout <<
"WARNING: Node = " << ncnt+1 <<
" has no elements"
531 size_t nsur = sur_elem[ncnt].size();
537 nodeToElem_ =
new gno_t[num_nodes_ * max_nsur];
538 nodeOffsets_ =
new offset_t[num_nodes_+1];
541 for (
int ncnt = 0; ncnt < num_nodes_; ncnt++) {
542 nodeOffsets_[ncnt] = telct_;
543 nStart_[ncnt] = nNadj_;
546 for (
size_t i = 0; i < sur_elem[ncnt].size(); i++) {
547 nodeToElem_[telct_] = sur_elem[ncnt][i];
550#ifndef USE_MESH_ADAPTER
551 for(
int ecnt = 0; ecnt < num_elem_; ecnt++) {
552 if (element_num_map_[ecnt] == sur_elem[ncnt][i]) {
553 for (
int j = 0; j < nnodes_per_elem; j++) {
554 typename MapType::iterator iter =
555 nAdjMap.find(elemToNode_[elemOffsets_[ecnt]+j]);
557 if (node_num_map_[ncnt] != elemToNode_[elemOffsets_[ecnt]+j] &&
558 iter == nAdjMap.end() ) {
559 nAdj.push_back(elemToNode_[elemOffsets_[ecnt]+j]);
561 nAdjMap.insert({elemToNode_[elemOffsets_[ecnt]+j],
562 elemToNode_[elemOffsets_[ecnt]+j]});
575 nodeOffsets_[num_nodes_] = telct_;
576 nStart_[num_nodes_] = nNadj_;
578 nAdj_ =
new gno_t [nNadj_];
580 for (
size_t i=0; i < nNadj_; i++) {
581 nAdj_[i] = as<gno_t>(nAdj[i]);
584 int nprocs = comm.getSize();
586 int neid=0,num_elem_blks_global,num_node_sets_global,num_side_sets_global;
587 error += im_ne_get_init_global(neid,&num_nodes_global_,&num_elems_global_,
588 &num_elem_blks_global,&num_node_sets_global,
589 &num_side_sets_global);
591 int num_internal_nodes, num_border_nodes, num_external_nodes;
592 int num_internal_elems, num_border_elems, num_node_cmaps, num_elem_cmaps;
594 error += im_ne_get_loadbal_param(neid, &num_internal_nodes,
595 &num_border_nodes, &num_external_nodes,
596 &num_internal_elems, &num_border_elems,
597 &num_node_cmaps, &num_elem_cmaps, proc);
599 int *node_cmap_ids =
new int [num_node_cmaps];
600 int *node_cmap_node_cnts =
new int [num_node_cmaps];
601 int *elem_cmap_ids =
new int [num_elem_cmaps];
602 int *elem_cmap_elem_cnts =
new int [num_elem_cmaps];
603 error += im_ne_get_cmap_params(neid, node_cmap_ids, node_cmap_node_cnts,
604 elem_cmap_ids, elem_cmap_elem_cnts, proc);
605 delete[] elem_cmap_ids;
606 elem_cmap_ids = NULL;
607 delete[] elem_cmap_elem_cnts;
608 elem_cmap_elem_cnts = NULL;
610 int **node_ids =
new int * [num_node_cmaps];
611 int **node_proc_ids =
new int * [num_node_cmaps];
612 for(
int j = 0; j < num_node_cmaps; j++) {
613 node_ids[j] =
new int [node_cmap_node_cnts[j]];
614 node_proc_ids[j] =
new int [node_cmap_node_cnts[j]];
615 error += im_ne_get_node_cmap(neid, node_cmap_ids[j], node_ids[j],
616 node_proc_ids[j], proc);
618 delete[] node_cmap_ids;
619 node_cmap_ids = NULL;
620 int *sendCount =
new int [nprocs];
621 int *recvCount =
new int [nprocs];
624 RCP<CommRequest<int> >*requests=
new RCP<CommRequest<int> >[num_node_cmaps];
625 for (
int cnt = 0, i = 0; i < num_node_cmaps; i++) {
628 Teuchos::ireceive<int,int>(comm,
629 rcp(&(recvCount[node_proc_ids[i][0]]),
631 node_proc_ids[i][0]);
636 Teuchos::barrier<int>(comm);
637 size_t totalsend = 0;
639 for(
int j = 0; j < num_node_cmaps; j++) {
640 sendCount[node_proc_ids[j][0]] = 1;
641 for(
int i = 0; i < node_cmap_node_cnts[j]; i++) {
642 sendCount[node_proc_ids[j][i]] += sur_elem[node_ids[j][i]-1].size()+2;
644 totalsend += sendCount[node_proc_ids[j][0]];
648 for (
int i = 0; i < num_node_cmaps; i++) {
650 Teuchos::readySend<int,int>(comm, sendCount[node_proc_ids[i][0]],
651 node_proc_ids[i][0]);
658 Teuchos::waitAll<int>(comm, arrayView(requests, num_node_cmaps));
665 size_t totalrecv = 0;
668 for(
int i = 0; i < num_node_cmaps; i++) {
669 if (recvCount[node_proc_ids[i][0]] > 0) {
670 totalrecv += recvCount[node_proc_ids[i][0]];
672 if (recvCount[node_proc_ids[i][0]] > maxMsg)
673 maxMsg = recvCount[node_proc_ids[i][0]];
678 if (totalrecv) rbuf =
new gno_t[totalrecv];
680 requests =
new RCP<CommRequest<int> > [nrecvranks];
689 if (
size_t(maxMsg) *
sizeof(
int) > INT_MAX) OK[0] =
false;
690 if (totalrecv && !rbuf) OK[1] = 0;
691 if (!requests) OK[1] = 0;
697 if (OK[0] && OK[1]) {
699 for (
int i = 0; i < num_node_cmaps; i++) {
700 if (recvCount[node_proc_ids[i][0]]) {
704 ireceive<int,gno_t>(comm,
705 Teuchos::arcp(&rbuf[offset], 0,
706 recvCount[node_proc_ids[i][0]],
708 node_proc_ids[i][0]);
712 offset += recvCount[node_proc_ids[i][0]];
719 Teuchos::reduceAll<int>(comm, Teuchos::REDUCE_MIN, 2, OK, gOK);
720 if (!gOK[0] || !gOK[1]) {
724 throw std::runtime_error(
"Max single message length exceeded");
726 throw std::bad_alloc();
730 if (totalsend) sbuf =
new gno_t[totalsend];
733 for(
int j = 0; j < num_node_cmaps; j++) {
734 sbuf[a++] = node_cmap_node_cnts[j];
735 for(
int i = 0; i < node_cmap_node_cnts[j]; i++) {
736 sbuf[a++] = node_num_map_[node_ids[j][i]-1];
737 sbuf[a++] = sur_elem[node_ids[j][i]-1].size();
738 for(
size_t ecnt=0; ecnt < sur_elem[node_ids[j][i]-1].size(); ecnt++) {
739 sbuf[a++] = sur_elem[node_ids[j][i]-1][ecnt];
744 delete[] node_cmap_node_cnts;
745 node_cmap_node_cnts = NULL;
747 for(
int j = 0; j < num_node_cmaps; j++) {
748 delete[] node_ids[j];
753 ArrayRCP<gno_t> sendBuf;
756 sendBuf = ArrayRCP<gno_t>(sbuf, 0, totalsend,
true);
758 sendBuf = Teuchos::null;
762 for (
int i = 0; i < num_node_cmaps; i++) {
763 if (sendCount[node_proc_ids[i][0]]) {
765 Teuchos::readySend<int, gno_t>(comm,
766 Teuchos::arrayView(&sendBuf[offset],
767 sendCount[node_proc_ids[i][0]]),
768 node_proc_ids[i][0]);
772 offset += sendCount[node_proc_ids[i][0]];
775 for(
int j = 0; j < num_node_cmaps; j++) {
776 delete[] node_proc_ids[j];
779 delete[] node_proc_ids;
780 node_proc_ids = NULL;
785 Teuchos::waitAll<int>(comm, Teuchos::arrayView(requests, nrecvranks));
792 for (
int i = 0; i < num_node_cmaps; i++) {
793 int num_nodes_this_processor = rbuf[a++];
795 for (
int j = 0; j < num_nodes_this_processor; j++) {
796 int this_node = rbuf[a++];
797 int num_elem_this_node = rbuf[a++];
799 for (
int ncnt = 0; ncnt < num_nodes_; ncnt++) {
800 if (node_num_map_[ncnt] == this_node) {
801 for (
int ecnt = 0; ecnt < num_elem_this_node; ecnt++) {
802 sur_elem[ncnt].push_back(rbuf[a++]);
814#ifndef USE_MESH_ADAPTER
815 for(
int ecnt=0; ecnt < num_elem_; ecnt++) {
816 eStart_[ecnt] = nEadj_;
818 int nnodes = nnodes_per_elem;
819 for(
int ncnt=0; ncnt < nnodes; ncnt++) {
820 int node = reconnect[ecnt][ncnt]-1;
821 for(
size_t i=0; i < sur_elem[node].size(); i++) {
822 int entry = sur_elem[node][i];
823 typename MapType::iterator iter = eAdjMap.find(entry);
825 if(element_num_map_[ecnt] != entry &&
826 iter == eAdjMap.end()) {
827 eAdj.push_back(entry);
829 eAdjMap.insert({entry, entry});
838 for(
int b = 0; b < num_elem_; b++) {
839 delete[] reconnect[b];
844 eStart_[num_elem_] = nEadj_;
846 eAdj_ =
new gno_t [nEadj_];
848 for (
size_t i=0; i < nEadj_; i++) {
849 eAdj_[i] = as<gno_t>(eAdj[i]);
854 delete[] mirror_nodes;
857 if (nWeightsPerEntity_ > 0) {
858 entityDegreeWeight_ =
new bool [nWeightsPerEntity_];
859 for (
int i=0; i < nWeightsPerEntity_; i++) {
860 entityDegreeWeight_[i] =
false;