51 std::map<elementType, VTKCellType> eMap = {
57 {elementType::OTHER, VTK_EMPTY_CELL}};
62 std::map<VTKCellType, elementType> eMap = {
68 {VTK_QUADRATIC_TRIANGLE, elementType::TRIANGLE},
69 {VTK_QUADRATIC_QUAD, elementType::QUAD},
70 {VTK_QUADRATIC_TETRA, elementType::TETRA},
71 {VTK_QUADRATIC_HEXAHEDRON, elementType::HEX},
72 {VTK_EMPTY_CELL, elementType::OTHER}};
81 if (tag ==
"symmz")
return surfaceBCTag::SYMMZ;
82 std::cerr <<
"Unknown surface tag " << tag << std::endl;
91 case surfaceBCTag::SYMMZ:
return "SYMMZ";
93 std::cerr <<
"Unknown surface tag." << std::endl;
124 std::cout <<
"Warning : Element type " << tag <<
" may be unsupported.\n";
125 return elementType::OTHER;
149 std::cerr <<
"Unknown element/order combination " <<
elmTypeStr(tag) <<
" " << order
161 case elementType::OTHER:
break;
163 std::cerr <<
"Unknown element type " <<
elmTypeStr(tag) <<
"\n";
204 std::cerr <<
"Error: " << msg <<
" with error code " << errCode
207 }
else if (errCode > 0) {
208 std::cerr <<
"Warning: " << msg <<
" with warning code " << errCode
221 _fid = ex_create(
_ifname.c_str(), EX_CLOBBER, &comp_ws, &io_ws);
237 ieb.nElm, ieb.ndePerElm, 0);
253 _exErr = ex_put_elem_conn(
_fid, ieb.id, ieb.conn.data());
266 _exErr = ex_put_node_set_param(
_fid, ins.id, ins.nNde, 0);
268 _exErr = ex_put_node_set(
_fid, ins.id, ins.ndeIds.data());
274 _exErr = ex_put_side_set_param(
_fid, iss.id, iss.nSde, 0);
277 ex_put_side_set(
_fid, iss.id, iss.elmIds.data(), iss.sdeIds.data());
282 std::vector<char *> names;
283 for (
auto &&_elmBlkName :
_elmBlkNames) names.push_back(&_elmBlkName[0]);
284 if (!names.empty()) {
285 _exErr = ex_put_names(
_fid, EX_ELEM_BLOCK, names.data());
290 for (
auto &&_ndeSetName :
_ndeSetNames) names.push_back(&_ndeSetName[0]);
291 if (!names.empty()) {
292 _exErr = ex_put_names(
_fid, EX_NODE_SET, names.data());
297 for (
auto &&_sdeSetName :
_sdeSetNames) names.push_back(&_sdeSetName[0]);
298 if (!names.empty()) {
299 _exErr = ex_put_names(
_fid, EX_SIDE_SET, names.data());
313 for (
auto &&ieb :
_elmBlks) ieb.elmIds.clear();
320 std::vector<elmBlkType> nebs;
322 if (ieb.nElm > 0) nebs.emplace_back(std::move(ieb));
326 std::vector<ndeSetType> nnss;
328 if (ins.nNde > 0) nnss.emplace_back(std::move(ins));
332 std::vector<sdeSetType> nsss;
334 if (iss.nSde > 0) nsss.emplace_back(std::move(iss));
339 for (
auto &&ieb : _elmBlks) {
344 if (ieb.ndeIdOffset != 0) {
345 for (
auto &&conn : ieb.conn) conn += ieb.ndeIdOffset;
352 int nn = ieb.ndePerElm;
353 for (
int elmIdx = 0; elmIdx < ieb.nElm; ++elmIdx) {
354 std::vector<int> elmConn;
355 for (
int idx = elmIdx * nn; idx < (elmIdx + 1) * nn; ++idx)
356 elmConn.emplace_back(ieb.conn[idx]);
357 ieb.elmIds.emplace_back(
_numElms + elmIdx + 1);
362 if (ieb.nElm != ieb.elmIds.size())
363 std::cerr <<
"WARNING: Malformed element block " << ieb.name <<
".\n";
367 if (ieb.nElm * ieb.ndePerElm != ieb.conn.size())
368 std::cerr <<
"WARNING: Malformed element block " << ieb.name <<
".\n";
375 for (
auto &&ins : _ndeSets) {
380 if (ins.ndeIdOffset != 0) {
381 for (
auto &&it2 : ins.ndeIds) it2 += ins.ndeIdOffset;
386 if (ins.nNde != ins.ndeIds.size())
387 std::cerr <<
"WARNING: Malformed node set " << ins.name <<
".\n";
392 for (
auto &&iss : _sdeSets) {
397 if (iss.elmIdOffset != 0) {
398 for (
auto &&elm : iss.elmIds) elm += iss.elmIdOffset;
403 if (iss.nSde != iss.sdeIds.size() || iss.nSde != iss.elmIds.size())
404 std::cerr <<
"WARNING: Malformed side set " << iss.name <<
".\n";
413 std::cout <<
" ----- Exodus II Database Report ----- \n";
414 std::cout <<
"Database: " <<
_ifname <<
"\n";
415 std::cout <<
"Dimension: " <<
_numDim <<
"\n";
416 std::cout <<
"Nodes: " <<
_numNdes <<
"\n";
417 std::cout <<
"Elements: " <<
_numElms <<
"\n";
422 std::cout <<
" Blk nElm eType Name\n";
423 std::cout <<
" --- ---- ----- ------\n";
425 std::cout << std::setw(5) << ieb.id << std::setw(10) << ieb.nElm
426 << std::setw(10) <<
elmTypeStr(ieb.eTpe) << std::setw(20)
430 std::cout <<
" Nde nNde Name\n";
431 std::cout <<
" --- ---- ------\n";
433 std::cout << std::setw(5) << ins.id << std::setw(10) << ins.nNde
434 << std::setw(20) << ins.name <<
"\n";
437 std::cout <<
" Sde nSde Name\n";
438 std::cout <<
" --- ---- ------\n";
440 std::cout << std::setw(5) << iss.id << std::setw(10) << iss.nSde
441 << std::setw(20) << iss.name <<
"\n";
443 std::cout << std::flush;
449 const std::string &newName) {
454 std::cerr <<
"Error: Duplicate block IDs defined." << std::endl;
458 if (blkIdLst.size() < 2) {
459 std::cerr <<
"Error: More than one block ID is needed." << std::endl;
464 std::vector<elementType> eType_vec;
465 for (
auto &
id : blkIdLst) {
468 std::cerr <<
"Error: Block ID " <<
id <<
" does not exist." << std::endl;
473 eType_vec.push_back(elmtype);
476 for (
int i = 0; i < eType_vec.size(); ++i) {
480 else if (eType_vec[i] != e) {
481 std::cerr <<
"Error: Block element types are not the same. Cannot " 489 std::vector<int> blkIds;
491 blkIds.push_back(blk.id);
494 std::vector<int> arrange_list;
496 int first = blkIdLst[0];
498 arrange_list.push_back(blkIds[0]);
499 for (
int &
id : blkIds) {
503 auto it = std::find(arrange_list.begin(), arrange_list.end(),
id);
504 if (it == arrange_list.end()) arrange_list.push_back(
id);
508 for (
const int &comId : blkIdLst) {
509 for (
int i = 0; i < arrange_list.size(); ++i) {
510 if (comId == arrange_list[i]) {
511 arrange_list.erase(arrange_list.begin() + i);
516 for (
const int &j : blkIdLst) {
517 arrange_list.push_back(j);
523 std::map<int, int> old2NewElmIds;
526 for (
int &
id : arrange_list) {
527 for (
auto &elmBlk : _elmBlks) {
528 if (
id == elmBlk.id) {
529 for (
auto &eid : elmBlk.elmIds) {
531 old2NewElmIds.insert(std::pair<int, int>(eid, i));
549 std::cout <<
"\nModifying sidesets..." << std::flush;
552 for (
auto &
id : blkIdLst) {
554 numNodes += _elmBlks[idx].ndeCoords.size();
561 std::map<int, int> tree_ndeId_map;
562 ANNpointArray pntCrd;
563 pntCrd = annAllocPts(numNodes, nDim);
565 for (
auto &
id : blkIdLst) {
567 auto it = _elmBlks[idx].ndeCoords.begin();
568 while (it != _elmBlks[idx].ndeCoords.end()) {
569 pntCrd[ipts][0] = it->second[0];
570 pntCrd[ipts][1] = it->second[1];
571 pntCrd[ipts][2] = it->second[2];
572 tree_ndeId_map[ipts] = it->first;
577 ANNkd_tree *kdTree =
new ANNkd_tree(pntCrd, numNodes, nDim);
580 std::set<int> commonNodes;
583 ANNidxArray nnIdx =
new ANNidx[nNib];
584 ANNdistArray dists =
new ANNdist[nNib];
585 qryPnt = annAllocPt(nDim);
587 for (
int iNde = 0; iNde <
_numNdes; iNde++) {
591 kdTree->annkSearch(qryPnt, nNib, nnIdx, dists);
593 if (dists[1] <= 1e-12) {
594 int id1 = tree_ndeId_map[nnIdx[0]];
595 int id2 = tree_ndeId_map[nnIdx[1]];
596 commonNodes.insert(id1);
597 commonNodes.insert(id2);
603 std::set<int> commonElms;
604 int idx, num_nodes_per_elem, ndeID, c;
606 for (
auto &
id : blkIdLst) {
608 numElms = _elmBlks[idx].nElm;
609 num_nodes_per_elem = _elmBlks[idx].ndePerElm;
611 for (
int el = 0; el < numElms; ++el) {
612 for (
int n = 0; n < num_nodes_per_elem; ++n) {
613 c = el * num_nodes_per_elem + n;
614 ndeID = _elmBlks[idx].conn[c];
615 auto pos = commonNodes.find(ndeID);
616 if (pos != commonNodes.end())
617 commonElms.insert(_elmBlks[idx].elmIds[el]);
623 std::map<int, std::vector<int>> tri_face_conn_map = {
624 {1, {1, 2}}, {2, {2, 3}}, {3, {3, 1}}};
625 std::map<int, std::vector<int>> quad_face_conn_map = {
626 {1, {1, 2}}, {2, {2, 3}}, {3, {3, 4}}, {4, {4, 1}}};
627 std::map<int, std::vector<int>> tet_face_conn_map = {
628 {1, {1, 2, 4}}, {2, {2, 3, 4}}, {3, {1, 4, 3}}, {4, {1, 3, 2}}};
629 std::map<int, std::vector<int>> hex_face_conn_map = {
630 {1, {1, 2, 6, 5}}, {2, {2, 3, 7, 6}}, {3, {3, 4, 8, 7}},
631 {4, {1, 5, 8, 4}}, {5, {1, 4, 3, 2}}, {6, {5, 6, 7, 8}}};
632 std::map<int, std::vector<int>> wedge_face_conn_map = {{1, {1, 2, 5, 4}},
642 auto itf = sdeSet.sdeIds.begin();
645 for (
auto ite = sdeSet.elmIds.begin(); ite != sdeSet.elmIds.end();) {
646 loc = ite - sdeSet.elmIds.begin();
647 elmID = sdeSet.elmIds[loc];
648 auto pos = commonElms.find(elmID);
649 if (pos != commonElms.end()) {
650 int faceID = sdeSet.sdeIds[loc];
653 std::vector<int> elmConn =
glbConn[elmID - 1];
654 std::vector<int> faceConn;
657 faceConn = tet_face_conn_map[faceID];
659 faceConn = hex_face_conn_map[faceID];
661 faceConn = wedge_face_conn_map[faceID];
663 faceConn = tri_face_conn_map[faceID];
665 faceConn = quad_face_conn_map[faceID];
667 std::cerr <<
"Error: Mesh element type not supported." << std::endl;
672 bool allCommon =
false;
673 for (
int i = 0; i < faceConn.size(); ++i) {
675 int ndeID = elmConn[faceConn[i] - 1];
676 auto pos = commonNodes.find(ndeID);
677 if (pos == commonNodes.end()) {
685 ite = sdeSet.elmIds.erase(ite);
686 itf = sdeSet.sdeIds.erase(itf);
699 std::cout <<
"done." << std::endl;
704 std::cout <<
"Combining blocks..." << std::flush;
707 for (
int i = 0; i < blkIdLst.size(); ++i) {
711 for (
const auto &eid : _elmBlks[idx].elmIds) {
713 _elmBlks[firstBlk].elmIds.emplace_back(eid);
714 _elmBlks[firstBlk].nElm++;
716 for (
int ni = ei * _elmBlks[idx].ndePerElm;
717 ni < (ei + 1) * _elmBlks[idx].ndePerElm; ni++) {
718 _elmBlks[firstBlk].conn.emplace_back(_elmBlks[idx].conn[ni]);
722 if (newName !=
"") _elmBlks[firstBlk].name = newName;
725 std::cout <<
"done." << std::endl;
726 std::cout <<
"Updating sideset element IDs..." << std::flush;
729 std::cout <<
"done." << std::endl;
733 for (
int i = 0; i < blkIdLst.size(); ++i) {
738 std::cout <<
"Combined blocks and updated sidesets in " 739 << T.
elapsed() / 1000.0 <<
" seconds.\n" 748 for (
auto &elmId : sSet.elmIds) {
749 auto it = old2NewElmIds.find(elmId);
750 if (it != old2NewElmIds.end())
753 std::cerr <<
"Error: element not found in sideset" << std::endl;
762 wrnErrMsg(-1,
"Block Id is out of the range.");
786 for (
const auto &eid : oeb.
elmIds) {
790 for (
const auto &
id : idLst)
795 if (!stays)
continue;
798 neb.
elmIds.emplace_back(eid);
800 neb.
conn.emplace_back(oeb.
conn[ni]);
802 std::cout <<
"Removed " << oeb.
elmIds.size() - neb.
elmIds.size()
803 <<
" elements from original" << std::endl;
808 std::vector<int> &lst) {
810 std::cerr <<
"WARNING: Attempting to add element block " << name
811 <<
" with no elements." << std::endl;
829 if (blkIdx == -1)
wrnErrMsg(-1,
"Elements ids are not registered.");
833 std::vector<int> owndLst;
837 std::cout << owndLst.size() <<
" Elements are in the block.\n";
838 std::cout <<
"Some of the elements in the list are outside the block.\n";
843 neb.
nElm = lst.size();
846 for (
const auto &eid : lst)
847 for (
int idx = 0; idx < neb.
ndePerElm; ++idx)
858 const std::vector<int> &idLst) {
866 nns.
nNde = idLst.size();
881 for (
auto i = 0; i <
_numNdes; ++i) {
883 if (std::abs(
_xCrds[i]) <= tol) {
887 if (std::abs(
_yCrds[i]) <= tol) {
891 if (std::abs(
_zCrds[i]) <= tol) {
898 std::cout <<
"Number of points snapped : " << nPnt << std::endl;
902 if (blkName.empty())
return;
904 std::vector<elmBlkType> nebs;
906 if (ieb.name != blkName)
907 nebs.emplace_back(ieb);
916 std::vector<elmBlkType> nebs;
919 nebs.emplace_back(ieb);
930 for (
const auto &eid : ieb.elmIds)
931 if (eid == elmId)
return blkIdx;
939 if (elmIds.empty())
return -1;
945 for (
int ieb = 0; ieb <
_elmBlks.size(); ++ieb) {
946 std::vector<int> intfLst;
951 }
else if (intfLst.size() > intfCnt) {
952 intfCnt = intfLst.size();
958 std::cerr <<
"WARNING: Elements in list are not all in one element block. " 959 "Only block containing largest amount of elements is " 960 "processed. This might indicate selected elements overlap or " 961 "are different element types (e.g., HEX and TETRA)." 968 const std::vector<int> &elmIds,
970 std::vector<int> out;
974 std::set<int> current;
975 for (
const auto &elmId :
_elmBlks[blkIdx].elmIds) current.insert(elmId);
976 for (
const auto &elmId : elmIds)
977 if (!current.insert(elmId).second)
978 out.emplace_back(elmId);
1004 if (!ifname.empty())
_ifname = ifname;
1009 int CPU_word_size =
sizeof(double);
1010 int IO_word_size = 0;
1015 _fid = ex_open(
_ifname.c_str(), EX_READ, &CPU_word_size, &IO_word_size,
1029 _exErr = ex_inquire(
_fid, EX_INQ_API_VERS, &idum, &fdum, &cdum);
1031 std::cout <<
"Exodus II API version is " << fdum << std::endl;
1034 _exErr = ex_inquire(
_fid, EX_INQ_DB_VERS, &idum, &fdum, &cdum);
1036 std::cout <<
"Exodus II Database version is " << fdum << std::endl;
1039 _exErr = ex_inquire(
_fid, EX_INQ_DIM, &idum, &fdum, &cdum);
1042 std::cout <<
"Number of coordinate dimensions is " << idum << std::endl;
1044 _exErr = ex_inquire(
_fid, EX_INQ_NODES, &idum, &fdum, &cdum);
1046 std::cout <<
"Number of points " << idum << std::endl;
1049 _exErr = ex_inquire(
_fid, EX_INQ_ELEM, &idum, &fdum, &cdum);
1051 std::cout <<
"Number of elements " << idum << std::endl;
1054 _exErr = ex_inquire(
_fid, EX_INQ_ELEM_BLK, &idum, &fdum, &cdum);
1056 std::cout <<
"Number of element blocks " << idum << std::endl;
1059 _exErr = ex_inquire(
_fid, EX_INQ_NODE_SETS, &idum, &fdum, &cdum);
1061 std::cout <<
"Number of node sets " << idum << std::endl;
1064 _exErr = ex_inquire(
_fid, EX_INQ_SIDE_SETS, &idum, &fdum, &cdum);
1066 std::cout <<
"Number of side sets " << idum << std::endl;
1077 std::vector<int> elmBlkIds(numElmBlks, 0);
1078 if (numElmBlks > 0) {
1079 _exErr = ex_get_elem_blk_ids(
_fid, elmBlkIds.data());
1082 for (
int i = 0; i < numElmBlks; ++i) {
1087 std::vector<int> ndeSetIds(numNdeSets, 0);
1088 if (numNdeSets > 0) {
1089 _exErr = ex_get_node_set_ids(
_fid, ndeSetIds.data());
1093 std::vector<int> sdeSetIds(numSdeSets, 0);
1094 if (numSdeSets > 0) {
1095 _exErr = ex_get_side_set_ids(
_fid, sdeSetIds.data());
1100 std::string blk_name;
1101 for (
int iEB = 0; iEB < numElmBlks; ++iEB) {
1103 blk_name.resize(MAX_STR_LENGTH);
1104 int blk_id = elmBlkIds[iEB];
1105 _exErr = ex_get_name(
_fid, EX_ELEM_BLOCK, blk_id, &blk_name[0]);
1107 blk_name.erase(std::remove(blk_name.begin(), blk_name.end(),
'\0'),
1115 for (
int iNS = 0; iNS < numNdeSets; ++iNS) {
1117 blk_name.resize(MAX_STR_LENGTH);
1118 int blk_id = ndeSetIds[iNS];
1119 _exErr = ex_get_name(
_fid, EX_NODE_SET, blk_id, &blk_name[0]);
1121 blk_name.erase(std::remove(blk_name.begin(), blk_name.end(),
'\0'),
1128 for (
int iSS = 0; iSS < numSdeSets; ++iSS) {
1130 blk_name.resize(MAX_STR_LENGTH);
1131 int blk_id = sdeSetIds[iSS];
1132 _exErr = ex_get_name(
_fid, EX_SIDE_SET, blk_id, &blk_name[0]);
1134 blk_name.erase(std::remove(blk_name.begin(), blk_name.end(),
'\0'),
1141 std::string elem_type;
1143 for (
int iEB = 0; iEB < numElmBlks; ++iEB) {
1145 elem_type.resize(MAX_STR_LENGTH);
1147 eb.
id = elmBlkIds[iEB];
1148 int num_el_in_blk, num_nod_per_el, num_attr;
1149 _exErr = ex_get_elem_block(
_fid, elmBlkIds[iEB], &elem_type[0],
1150 &num_el_in_blk, &num_nod_per_el, &num_attr);
1152 elem_type.erase(std::remove(elem_type.begin(), elem_type.end(),
'\0'),
1154 eb.
nElm = num_el_in_blk;
1163 eb.
conn.resize(num_el_in_blk * num_nod_per_el, 0);
1169 for (
int &ndeId : eb.
conn) {
1174 std::pair<
int, std::vector<double>>(ndeId, {x, y, z}));
1179 eb.
elmIds.resize(num_el_in_blk);
1181 elmId += num_el_in_blk;
1185 for (
int elmIdx = 0; elmIdx < eb.
nElm; ++elmIdx) {
1186 std::vector<int> elmConn;
1187 for (
int idx = elmIdx * nn; idx < (elmIdx + 1) * nn; ++idx)
1188 elmConn.emplace_back(eb.
conn[idx]);
1189 glbConn.emplace_back(elmConn);
1196 for (
int iNS = 0; iNS < numNdeSets; ++iNS) {
1198 ns.
id = ndeSetIds[iNS];
1211 for (
int iSS = 0; iSS < numSdeSets; ++iSS) {
1213 ss.
id = sdeSetIds[iSS];
1222 wrnErrMsg(
_exErr,
"Problem reading side set element and side ids.\n");
1235 ANNpointArray pntCrd;
1236 pntCrd = annAllocPts(
_numNdes, nDim);
1237 for (
int iPnt = 0; iPnt <
_numNdes; iPnt++) {
1238 pntCrd[iPnt][0] =
_xCrds[iPnt];
1239 pntCrd[iPnt][1] =
_yCrds[iPnt];
1240 pntCrd[iPnt][2] =
_zCrds[iPnt];
1242 ANNkd_tree *kdTree =
new ANNkd_tree(pntCrd, _numNdes, nDim);
1245 std::map<int, int> dupNdeMap;
1248 ANNidxArray nnIdx =
new ANNidx[nNib];
1249 ANNdistArray dists =
new ANNdist[nNib];
1250 qryPnt = annAllocPt(nDim);
1251 for (
int iNde = 0; iNde <
_numNdes; iNde++) {
1252 qryPnt[0] =
_xCrds[iNde];
1253 qryPnt[1] =
_yCrds[iNde];
1254 qryPnt[2] =
_zCrds[iNde];
1255 kdTree->annkSearch(qryPnt, nNib, nnIdx, dists);
1256 if (dists[1] <= tol) dupNdeMap[nnIdx[0] + 1] = nnIdx[1] + 1;
1258 std::cout <<
"Found " << dupNdeMap.size() <<
" duplicate nodes.\n";
1261 std::vector<double> xn, yn, zn;
1262 std::map<int, int> old2NewNde;
1263 for (
int iNde = 0; iNde <
_numNdes; iNde++) {
1264 if (dupNdeMap.find(iNde + 1) == dupNdeMap.end()) {
1265 xn.push_back(
_xCrds[iNde]);
1266 yn.push_back(
_yCrds[iNde]);
1267 zn.push_back(
_zCrds[iNde]);
1274 for (
int iPnt = 0; iPnt < xn.size(); iPnt++) {
1275 pntCrd[iPnt][0] = xn[iPnt];
1276 pntCrd[iPnt][1] = yn[iPnt];
1277 pntCrd[iPnt][2] = zn[iPnt];
1279 kdTree =
new ANNkd_tree(pntCrd, xn.size(), nDim);
1282 for (
int iNde = 0; iNde <
_numNdes; iNde++) {
1283 qryPnt[0] =
_xCrds[iNde];
1284 qryPnt[1] =
_yCrds[iNde];
1285 qryPnt[2] =
_zCrds[iNde];
1286 kdTree->annkSearch(qryPnt, 1, nnIdx, dists);
1287 if (dists[0] <= tol) {
1288 old2NewNde[iNde + 1] = nnIdx[0] + 1;
1290 std::cerr <<
"ERROR: Found a node in database not properly copied.\n";
1297 int min = std::numeric_limits<int>::max();
1298 for (
const auto &im : old2NewNde) {
1299 max = std::max(max, im.second);
1300 min = std::min(min, im.second);
1302 std::cout <<
"Max new node id = " << max <<
"\n";
1303 std::cout <<
"Min new node id = " << min <<
"\n";
1309 _xCrds.assign(xn.begin(), xn.end());
1310 _yCrds.assign(yn.begin(), yn.end());
1311 _zCrds.assign(zn.begin(), zn.end());
1312 std::cout <<
"Number of nodes changed from " << _numNdes <<
" to " 1313 << xn.size() <<
"\n";
1314 _numNdes = xn.size();
1318 min = std::numeric_limits<int>::max();
1320 for (
auto &&icn : ieb.conn) {
1322 icn = old2NewNde[nid];
1323 max = std::max(max, icn);
1324 min = std::min(min, icn);
1327 std::cout <<
"Max conn = " << max <<
"\n";
1328 std::cout <<
"Min conn = " << min <<
"\n";
1333 std::set<int> newNSNdeIds;
1335 for (
const auto &nid : ins.ndeIds) newNSNdeIds.insert(old2NewNde[nid]);
1338 ins.ndeIds.assign(newNSNdeIds.begin(), newNSNdeIds.end());
1339 std::cout <<
"Original node set with " << ins.nNde
1340 <<
" nodes after cleaning becomes " << ins.ndeIds.size() <<
"\n";
1343 ins.nNde = ins.ndeIds.size();
1358 using nemAux::operator*;
1371 for (
const auto &elmBlk : otherMesh.
_elmBlks) {
1373 auto offElmBlk = elmBlk;
1380 for (
const auto &ndeSet : otherMesh.
_ndeSets) {
1381 auto offNdeSet = ndeSet;
1388 for (
const auto &sdeSet : otherMesh.
_sdeSets) {
1389 auto offSdeSet = sdeSet;
1406 if (eb->id ==
id)
return (eb->eTpe);
1410 std::cerr <<
"Warning: There is no element block with id " <<
id 1413 return (NEM::MSH::EXOMesh::elementType::OTHER);
1419 if (eb->name == ebName)
return (eb->eTpe);
1423 std::cerr <<
"Warning: There is no element block with name " << ebName
1426 return (NEM::MSH::EXOMesh::elementType::OTHER);
1432 if (eb->name == ebName)
return (eb->nElm);
1436 std::cerr <<
"Warning: There is no element block with name " << ebName
1445 if (eb->id ==
id)
return (eb->nElm);
1449 std::cerr <<
"Warning: There is no element block with ID " <<
id 1458 if (eb->id ==
id)
return (eb->name);
1462 std::cerr <<
"Warning: There is no element block with ID " <<
id 1470 for (
int i = 0; i < numElmBlks; ++i) {
1471 if (
_elmBlks[i].
id ==
id)
return i;
1478 for (
int i = 0; i < numElmBlks; ++i) {
1479 if (
_elmBlks[i].name == name)
return i;
1487 if (eb->name == ebName)
return (eb->id);
1491 std::cerr <<
"Warning: There is no element block with name " << ebName
1500 if (ns->id ==
id)
return (ns->name);
1504 std::cerr <<
"Warning: There is no nodeset with ID " <<
id << std::endl;
1512 if (ns->name == nsName)
return (ns->nNde);
1516 std::cerr <<
"Warning: There is no nodeset with name " << nsName
1525 if (ns->id ==
id)
return (ns->nNde);
1529 std::cerr <<
"Warning: There is no nodeset with ID " <<
id << std::endl;
1537 if (ns->name == nsName)
return (ns->id);
1541 std::cerr <<
"Warning: There is no nodeset with name " << nsName
1550 if (ns->name == nsName)
return ns -
_ndeSets.begin();
1554 std::cerr <<
"Warning: There is no nodeset with name " << nsName
1563 if (ss->name == ssName)
return (ss->id);
1567 std::cerr <<
"Warning: There is no sideset with name " << ssName
1576 if (ss->name == ssName)
return ss -
_sdeSets.begin();
1580 std::cerr <<
"Warning: There is no sideset with name " << ssName
1589 if (ss->name == ssName)
return (ss->nSde);
1593 std::cerr <<
"Warning: There is no sideset with name " << ssName
1602 if (ss->id ==
id)
return (ss->nSde);
1606 std::cerr <<
"Warning: There is no sideset with ID " <<
id << std::endl;
int getElmBlkId(int idx) const
Returns the id for the element block for given index.
int getNumSdesInSdeSet(int idx) const
Returns the number of sides for the sideset.
void updateSidesets(const std::map< int, int > &old2NewElmIds)
Updates sidesets from combining blocks.
const std::string getElmBlkNameById(int id) const
Returns the name the element block for given element block ID.
std::vector< int > _elmBlkIds
void addElmBlkByElmIdLst(const std::string &name, std::vector< int > &idLst)
Creates a new element block and augments previous owners.
elementType v2eEMap(VTKCellType vt)
Convert VTK cell type to EXODUS element type.
int getNumSdesInSdeSetById(int id) const
Returns the number of sides for the sideset.
void combineElmBlks(const std::vector< int > &blkIdLst, const std::string &newName)
Combines element blocks into one block.
elementType getElmBlkType(int idx) const
Returns the element type for the block.
std::vector< std::string > _ndeSetNames
std::vector< double > _xCrds
int findElmBlkIdxByElmIdLst(const std::vector< int > &elmIds) const
Finds index of the block containing most or all of the list (slower)
A complete I/O class for EXODUS II file format.
std::vector< int > sdeIds
int getNumElmsInBlkById(int id) const
Returns the number of elements for the block.
int getNumberOfNodeSets() const
Returns total number of node sets.
int getNdeSetId(int idx) const
Returns the id for the nodeset for given index.
std::string elmTypeStr(elementType et)
Convert EXODUS element type to string tab.
int elmNumSrf(elementType tag)
Get number of surfaces given EXODUS element type.
std::vector< int > elmIds
elementType elmTypeNum(std::string tag)
Convert string to EXODUS element type.
std::map< T, int > findDuplicates(const std::vector< T > &vecOfElements)
std::string getNdeSetNameById(int id) const
Returns the name the nodeset for given nodeset id.
int getNumberOfSideSets() const
Returns total number of side sets.
void write()
Write to file name specified at construction or using setFileName method.
int getNumElmsInBlk(int idx) const
Returns the number of elements for the block.
void snapNdeCrdsZero(double tol=1e-5)
Filter nodal coordinates and snap to zero.
void removeByElmIdLst(int blkIdx, const std::vector< int > &idLst)
Removes a list of elements from an element block.
Stores side set information.
std::vector< std::string > _elmBlkNames
surfaceBCTag bcTagNum(std::string &tag)
void toLower(std::string &str)
vtkIdType id
id in .inp file
std::string bcTagStr(surfaceBCTag tag)
int getNdeSetIndex(const std::string &nsName) const
Returns the index for the nodeset for nodeset name.
int getSdeSetIndex(const std::string &ssName) const
Returns the index of the sideset for sideset name.
int getNumNdesInNdeSet(int idx) const
Returns the number of nodes for the nodeset.
void addNdeSetByNdeIdLst(const std::string &name, const std::vector< int > &idLst)
Creates a new node set and augments previous ones if needed.
Stores element block information.
void exoPopulate(bool updElmLst=false)
std::vector< int > lstElmInBlk(int blkIdx, const std::vector< int > &elmIds, bool &allIn) const
Finds all elements that are within the block and generates a list of them.
int findElmBlkIdxByElmId(int elmId) const
Finds index of the first block containing element.
void addSdeSet(const sdeSetType &ss)
Add side set to the database.
std::vector< std::vector< int > > glbConn
std::vector< double > _zCrds
void stitch(const exoMesh &otherMesh)
Stitch another mesh into the current.
std::vector< std::string > _sdeSetNames
void addElmBlk(const elmBlkType &eb)
Add element block to the database.
void addNdeSet(const ndeSetType &ns)
Add node set to the database.
void reset()
Resets the EXODUS database.
Stores node set information.
int getElmBlkIndex(int id) const
Returns the index for the element block for given id.
void scaleNodes(double sc=1.0)
scales the nodal coordinates
std::vector< int > ndeIds
elementType getElmBlkTypeById(int id) const
Returns the element type for the block.
void removeElmBlkById(int id)
Remove an element block by ID.
void report() const
Print out a report of the current EXODUS database.
int getNumberOfElements() const
Returns total number of elements.
VTKCellType e2vEMap(elementType et)
Convert EXODUS element type to VTK cell type.
void read(const std::string &ifname=std::string())
Resets the class and reads from file name provided.
void mergeNodes(double tol=1e-15)
Merges duplicated and nodes within given proximity.
void removeElmBlkByName(const std::string &blkName)
Remove an element block by name.
int elmNumNde(elementType tag, int order)
Get number of nodes given EXODUS element type and order.
int getNumberOfElementBlocks() const
Returns total number of element blocks.
void wrnErrMsg(int errCode, const std::string &msg)
Logging method.
std::vector< double > _yCrds
std::map< int, std::vector< double > > ndeCoords
int getSdeSetId(int idx) const
Returns the id for the sideset for given index.
int getNumNdesInNdeSetById(int id) const
Returns the number of nodes for the nodeset.
std::vector< int > elmIds