317 std::string typestr,
int nEntWgts):
318 dimension_(0), nWeightsPerEntity_(nEntWgts), entityDegreeWeight_()
325 int num_elem_blk, num_node_sets, num_side_sets;
326 error += im_ex_get_init(exoid, title, &dimension_,
327 &num_nodes_, &num_elem_, &num_elem_blk,
328 &num_node_sets, &num_side_sets);
330 if (typestr.compare(
"region") == 0) {
337 else if (typestr.compare(
"vertex") == 0) {
347 double *dcoords =
new double [num_nodes_ * dimension_];
348 coords_ =
new scalar_t [num_nodes_ * dimension_];
350 error += im_ex_get_coord(exoid, dcoords, dcoords + num_nodes_,
351 dcoords + 2 * num_nodes_);
353 size_t dlen = num_nodes_ * dimension_;
354 for (
size_t i = 0; i < dlen; i++) coords_[i] = as<scalar_t>(dcoords[i]);
357 element_num_map_ =
new gno_t[num_elem_];
358 std::vector<int> tmp;
359 tmp.resize(num_elem_);
364 error += im_ex_get_elem_num_map(exoid, &tmp[0]);
365 for(
size_t i = 0; i < tmp.size(); i++)
366 element_num_map_[i] =
static_cast<gno_t>(tmp[i]);
369 tmp.resize(num_nodes_);
370 node_num_map_ =
new gno_t [num_nodes_];
375 error += im_ex_get_node_num_map(exoid, &tmp[0]);
376 for(
size_t i = 0; i < tmp.size(); i++)
377 node_num_map_[i] =
static_cast<gno_t>(tmp[i]);
380 for (
int i=0;i<num_nodes_;i++)
381 nodeTopology[i] =
POINT;
383 for (
int i=0;i<num_elem_;i++) {
390 int *elem_blk_ids =
new int [num_elem_blk];
391 error += im_ex_get_elem_blk_ids(exoid, elem_blk_ids);
393 int *num_nodes_per_elem =
new int [num_elem_blk];
394 int *num_attr =
new int [num_elem_blk];
395 int *num_elem_this_blk =
new int [num_elem_blk];
396 char **elem_type =
new char * [num_elem_blk];
397 int **connect =
new int * [num_elem_blk];
399 for(
int i = 0; i < num_elem_blk; i++){
400 elem_type[i] =
new char [MAX_STR_LENGTH + 1];
401 error += im_ex_get_elem_block(exoid, elem_blk_ids[i], elem_type[i],
402 (
int*)&(num_elem_this_blk[i]),
403 (
int*)&(num_nodes_per_elem[i]),
404 (
int*)&(num_attr[i]));
405 delete[] elem_type[i];
412 Acoords_ =
new scalar_t [num_elem_ * dimension_];
414 std::vector<std::vector<gno_t> > sur_elem;
415 sur_elem.resize(num_nodes_);
417 for(
int b = 0; b < num_elem_blk; b++) {
418 connect[b] =
new int [num_nodes_per_elem[b]*num_elem_this_blk[b]];
419 error += im_ex_get_elem_conn(exoid, elem_blk_ids[b], connect[b]);
421 for(
int i = 0; i < num_elem_this_blk[b]; i++) {
423 Acoords_[num_elem_ + a] = 0;
425 if (3 == dimension_) {
426 Acoords_[2 * num_elem_ + a] = 0;
429 for(
int j = 0; j < num_nodes_per_elem[b]; j++) {
430 int node = connect[b][i * num_nodes_per_elem[b] + j] - 1;
431 Acoords_[a] += coords_[node];
432 Acoords_[num_elem_ + a] += coords_[num_nodes_ + node];
434 if(3 == dimension_) {
435 Acoords_[2 * num_elem_ + a] += coords_[2 * num_nodes_ + node];
444 if (sur_elem[node].empty() ||
445 element_num_map_[a] != sur_elem[node][sur_elem[node].size()-1]) {
447 sur_elem[node].push_back(element_num_map_[a]);
451 Acoords_[a] /= num_nodes_per_elem[b];
452 Acoords_[num_elem_ + a] /= num_nodes_per_elem[b];
454 if(3 == dimension_) {
455 Acoords_[2 * num_elem_ + a] /= num_nodes_per_elem[b];
463 delete[] elem_blk_ids;
465 int nnodes_per_elem = num_nodes_per_elem[0];
466 elemToNode_ =
new gno_t[num_elem_ * nnodes_per_elem];
468 elemOffsets_ =
new offset_t [num_elem_+1];
470 int **reconnect =
new int * [num_elem_];
473 for (
int b = 0; b < num_elem_blk; b++) {
474 for (
int i = 0; i < num_elem_this_blk[b]; i++) {
475 elemOffsets_[telct] = tnoct_;
476 reconnect[telct] =
new int [num_nodes_per_elem[b]];
478 for (
int j = 0; j < num_nodes_per_elem[b]; j++) {
480 as<gno_t>(node_num_map_[connect[b][i*num_nodes_per_elem[b] + j]-1]);
481 reconnect[telct][j] = connect[b][i*num_nodes_per_elem[b] + j];
488 elemOffsets_[telct] = tnoct_;
490 delete[] num_nodes_per_elem;
491 num_nodes_per_elem = NULL;
492 delete[] num_elem_this_blk;
493 num_elem_this_blk = NULL;
495 for(
int b = 0; b < num_elem_blk; b++) {
502 int max_side_nodes = nnodes_per_elem;
503 int *side_nodes =
new int [max_side_nodes];
504 int *mirror_nodes =
new int [max_side_nodes];
507 eStart_ =
new lno_t [num_elem_+1];
508 nStart_ =
new lno_t [num_nodes_+1];
509 std::vector<int> eAdj;
510 std::vector<int> nAdj;
512 for (
int i=0; i < max_side_nodes; i++) {
514 mirror_nodes[i]=-999;
520 for(
int ncnt=0; ncnt < num_nodes_; ncnt++) {
521 if(sur_elem[ncnt].empty()) {
522 std::cout <<
"WARNING: Node = " << ncnt+1 <<
" has no elements"
525 size_t nsur = sur_elem[ncnt].size();
531 nodeToElem_ =
new gno_t[num_nodes_ * max_nsur];
532 nodeOffsets_ =
new offset_t[num_nodes_+1];
535 for (
int ncnt = 0; ncnt < num_nodes_; ncnt++) {
536 nodeOffsets_[ncnt] = telct_;
537 nStart_[ncnt] = nNadj_;
540 for (
size_t i = 0; i < sur_elem[ncnt].size(); i++) {
541 nodeToElem_[telct_] = sur_elem[ncnt][i];
544#ifndef USE_MESH_ADAPTER
545 for(
int ecnt = 0; ecnt < num_elem_; ecnt++) {
546 if (element_num_map_[ecnt] == sur_elem[ncnt][i]) {
547 for (
int j = 0; j < nnodes_per_elem; j++) {
548 typename MapType::iterator iter =
549 nAdjMap.find(elemToNode_[elemOffsets_[ecnt]+j]);
551 if (node_num_map_[ncnt] != elemToNode_[elemOffsets_[ecnt]+j] &&
552 iter == nAdjMap.end() ) {
553 nAdj.push_back(elemToNode_[elemOffsets_[ecnt]+j]);
555 nAdjMap.insert({elemToNode_[elemOffsets_[ecnt]+j],
556 elemToNode_[elemOffsets_[ecnt]+j]});
569 nodeOffsets_[num_nodes_] = telct_;
570 nStart_[num_nodes_] = nNadj_;
572 nAdj_ =
new gno_t [nNadj_];
574 for (
size_t i=0; i < nNadj_; i++) {
575 nAdj_[i] = as<gno_t>(nAdj[i]);
578 int nprocs = comm.getSize();
580 int neid=0,num_elem_blks_global,num_node_sets_global,num_side_sets_global;
581 error += im_ne_get_init_global(neid,&num_nodes_global_,&num_elems_global_,
582 &num_elem_blks_global,&num_node_sets_global,
583 &num_side_sets_global);
585 int num_internal_nodes, num_border_nodes, num_external_nodes;
586 int num_internal_elems, num_border_elems, num_node_cmaps, num_elem_cmaps;
588 error += im_ne_get_loadbal_param(neid, &num_internal_nodes,
589 &num_border_nodes, &num_external_nodes,
590 &num_internal_elems, &num_border_elems,
591 &num_node_cmaps, &num_elem_cmaps, proc);
593 int *node_cmap_ids =
new int [num_node_cmaps];
594 int *node_cmap_node_cnts =
new int [num_node_cmaps];
595 int *elem_cmap_ids =
new int [num_elem_cmaps];
596 int *elem_cmap_elem_cnts =
new int [num_elem_cmaps];
597 error += im_ne_get_cmap_params(neid, node_cmap_ids, node_cmap_node_cnts,
598 elem_cmap_ids, elem_cmap_elem_cnts, proc);
599 delete[] elem_cmap_ids;
600 elem_cmap_ids = NULL;
601 delete[] elem_cmap_elem_cnts;
602 elem_cmap_elem_cnts = NULL;
604 int **node_ids =
new int * [num_node_cmaps];
605 int **node_proc_ids =
new int * [num_node_cmaps];
606 for(
int j = 0; j < num_node_cmaps; j++) {
607 node_ids[j] =
new int [node_cmap_node_cnts[j]];
608 node_proc_ids[j] =
new int [node_cmap_node_cnts[j]];
609 error += im_ne_get_node_cmap(neid, node_cmap_ids[j], node_ids[j],
610 node_proc_ids[j], proc);
612 delete[] node_cmap_ids;
613 node_cmap_ids = NULL;
614 int *sendCount =
new int [nprocs];
615 int *recvCount =
new int [nprocs];
618 RCP<CommRequest<int> >*requests=
new RCP<CommRequest<int> >[num_node_cmaps];
619 for (
int cnt = 0, i = 0; i < num_node_cmaps; i++) {
622 Teuchos::ireceive<int,int>(comm,
623 rcp(&(recvCount[node_proc_ids[i][0]]),
625 node_proc_ids[i][0]);
630 Teuchos::barrier<int>(comm);
631 size_t totalsend = 0;
633 for(
int j = 0; j < num_node_cmaps; j++) {
634 sendCount[node_proc_ids[j][0]] = 1;
635 for(
int i = 0; i < node_cmap_node_cnts[j]; i++) {
636 sendCount[node_proc_ids[j][i]] += sur_elem[node_ids[j][i]-1].size()+2;
638 totalsend += sendCount[node_proc_ids[j][0]];
642 for (
int i = 0; i < num_node_cmaps; i++) {
644 Teuchos::readySend<int,int>(comm, sendCount[node_proc_ids[i][0]],
645 node_proc_ids[i][0]);
652 Teuchos::waitAll<int>(comm, arrayView(requests, num_node_cmaps));
659 size_t totalrecv = 0;
662 for(
int i = 0; i < num_node_cmaps; i++) {
663 if (recvCount[node_proc_ids[i][0]] > 0) {
664 totalrecv += recvCount[node_proc_ids[i][0]];
666 if (recvCount[node_proc_ids[i][0]] > maxMsg)
667 maxMsg = recvCount[node_proc_ids[i][0]];
672 if (totalrecv) rbuf =
new gno_t[totalrecv];
674 requests =
new RCP<CommRequest<int> > [nrecvranks];
683 if (
size_t(maxMsg) *
sizeof(
int) > INT_MAX) OK[0] =
false;
684 if (totalrecv && !rbuf) OK[1] = 0;
685 if (!requests) OK[1] = 0;
691 if (OK[0] && OK[1]) {
693 for (
int i = 0; i < num_node_cmaps; i++) {
694 if (recvCount[node_proc_ids[i][0]]) {
698 ireceive<int,gno_t>(comm,
699 Teuchos::arcp(&rbuf[offset], 0,
700 recvCount[node_proc_ids[i][0]],
702 node_proc_ids[i][0]);
706 offset += recvCount[node_proc_ids[i][0]];
713 Teuchos::reduceAll<int>(comm, Teuchos::REDUCE_MIN, 2, OK, gOK);
714 if (!gOK[0] || !gOK[1]) {
718 throw std::runtime_error(
"Max single message length exceeded");
720 throw std::bad_alloc();
724 if (totalsend) sbuf =
new gno_t[totalsend];
727 for(
int j = 0; j < num_node_cmaps; j++) {
728 sbuf[a++] = node_cmap_node_cnts[j];
729 for(
int i = 0; i < node_cmap_node_cnts[j]; i++) {
730 sbuf[a++] = node_num_map_[node_ids[j][i]-1];
731 sbuf[a++] = sur_elem[node_ids[j][i]-1].size();
732 for(
size_t ecnt=0; ecnt < sur_elem[node_ids[j][i]-1].size(); ecnt++) {
733 sbuf[a++] = sur_elem[node_ids[j][i]-1][ecnt];
738 delete[] node_cmap_node_cnts;
739 node_cmap_node_cnts = NULL;
741 for(
int j = 0; j < num_node_cmaps; j++) {
742 delete[] node_ids[j];
747 ArrayRCP<gno_t> sendBuf;
750 sendBuf = ArrayRCP<gno_t>(sbuf, 0, totalsend,
true);
752 sendBuf = Teuchos::null;
756 for (
int i = 0; i < num_node_cmaps; i++) {
757 if (sendCount[node_proc_ids[i][0]]) {
759 Teuchos::readySend<int, gno_t>(comm,
760 Teuchos::arrayView(&sendBuf[offset],
761 sendCount[node_proc_ids[i][0]]),
762 node_proc_ids[i][0]);
766 offset += sendCount[node_proc_ids[i][0]];
769 for(
int j = 0; j < num_node_cmaps; j++) {
770 delete[] node_proc_ids[j];
773 delete[] node_proc_ids;
774 node_proc_ids = NULL;
779 Teuchos::waitAll<int>(comm, Teuchos::arrayView(requests, nrecvranks));
786 for (
int i = 0; i < num_node_cmaps; i++) {
787 int num_nodes_this_processor = rbuf[a++];
789 for (
int j = 0; j < num_nodes_this_processor; j++) {
790 int this_node = rbuf[a++];
791 int num_elem_this_node = rbuf[a++];
793 for (
int ncnt = 0; ncnt < num_nodes_; ncnt++) {
794 if (node_num_map_[ncnt] == this_node) {
795 for (
int ecnt = 0; ecnt < num_elem_this_node; ecnt++) {
796 sur_elem[ncnt].push_back(rbuf[a++]);
808#ifndef USE_MESH_ADAPTER
809 for(
int ecnt=0; ecnt < num_elem_; ecnt++) {
810 eStart_[ecnt] = nEadj_;
812 int nnodes = nnodes_per_elem;
813 for(
int ncnt=0; ncnt < nnodes; ncnt++) {
814 int node = reconnect[ecnt][ncnt]-1;
815 for(
size_t i=0; i < sur_elem[node].size(); i++) {
816 int entry = sur_elem[node][i];
817 typename MapType::iterator iter = eAdjMap.find(entry);
819 if(element_num_map_[ecnt] != entry &&
820 iter == eAdjMap.end()) {
821 eAdj.push_back(entry);
823 eAdjMap.insert({entry, entry});
832 for(
int b = 0; b < num_elem_; b++) {
833 delete[] reconnect[b];
838 eStart_[num_elem_] = nEadj_;
840 eAdj_ =
new gno_t [nEadj_];
842 for (
size_t i=0; i < nEadj_; i++) {
843 eAdj_[i] = as<gno_t>(eAdj[i]);
848 delete[] mirror_nodes;
851 if (nWeightsPerEntity_ > 0) {
852 entityDegreeWeight_ =
new bool [nWeightsPerEntity_];
853 for (
int i=0; i < nWeightsPerEntity_; i++) {
854 entityDegreeWeight_[i] =
false;