#include "MeshReader.h" #include "LammpsInterface.h" #include "Utility.h" #ifdef HAS_EXODUS //#include //#include "netcdf.h" #include "exodusII.h" #endif using ATC_Utility::to_string; using std::ifstream; using std::istringstream; using std::stringstream; using std::map; using std::pair; using std::set; using std::string; namespace ATC { /** constructor, takes a filename */ MeshReader::MeshReader(string filename, Array periodicity, double tol) : meshfile_(filename), periodicity_(periodicity), nNodes_(0), nElements_(0) { conn_ = new Array2D(); nodeCoords_ = new DENS_MAT; nodeSets_ = new Array< std::pair< string,set > >(); size_t idx = filename.rfind('.'); if (idx == string::npos) { throw ATC_Error("Given mesh file is of unknown type."); } string ext = filename.substr(idx+1); if (ext == "mesh"){ read_mesh_file(); } else { throw ATC_Error("mesh file is of unknown type."); } } /** destructor */ MeshReader::~MeshReader() { if (conn_) delete conn_; if (nodeCoords_) delete nodeCoords_; if (nodeSets_) delete nodeSets_; } /** creates handle to new mesh object */ FE_Mesh* MeshReader::create_mesh() { return new FE_3DMesh(elementType_, nNodes_, nElements_, conn_, nodeCoords_, periodicity_, nodeSets_); } int MeshReader::number_of_vertices(string str) { string temp; int number=0; for (unsigned int i=0; i < str.size(); i++) { if (isdigit(str[i])) { for (unsigned int a=i; a> number; return number; } /** reads .mesh format file */ void MeshReader::read_mesh_file() { ifstream in; in.open(meshfile_.c_str(), ifstream::in); string header; while (getline(in,header)) { istringstream words(header); string section; words >> section; if (section == "Coordinates") { words >> nNodes_; nodeCoords_->reset(3, nNodes_, false); string line; for (int i = 0; i < nNodes_; ++i) { getline(in,line); istringstream coords(line); coords >> (*nodeCoords_)(0, i); coords >> (*nodeCoords_)(1, i); coords >> (*nodeCoords_)(2, i); } stringstream ss; ss << "read " << nNodes_ << " nodes"; ATC::LammpsInterface::instance()->print_msg_once(ss.str()); } else if (section == "Elements") { words >> nElements_; words >> elementType_; int nVerts = number_of_vertices(elementType_); conn_->reset(nVerts, nElements_); string line; for (int i = 0; i < nElements_; ++i) { getline(in,line); istringstream verts(line); for (int j = 0; j < nVerts; ++j ) { int node; verts >> node; (*conn_)(j,i) = node-1; } } stringstream ss; ss << "read " << nElements_ << " " << elementType_ << " elements"; ATC::LammpsInterface::instance()->print_msg_once(ss.str()); } else if (section == "Nodesets") { words >> nNodeSets_; nodeSets_->reset(nNodeSets_); string infoline; string setName; int nNodes; string line; for (int i = 0; i < nNodeSets_; ++i) { getline(in,infoline); istringstream info(infoline); info >> setName; info >> nNodes; (*nodeSets_)(i).first = setName; getline(in,line); istringstream nodes(line); for (int j = 0; j < nNodes; ++j ) { int node; nodes >> node; (*nodeSets_)(i).second.insert(node-1); } } } } in.close(); if (nodeCoords_->size() == 0) { throw ATC_Error("Could not find mesh file, or mesh file empty."); } } /** reads .exo format file */ void MeshReader::read_exo_file() { #ifndef HAS_EXODUS throw ATC_Error("Reading ExodusII .exo files not supported."); #else int CPU_word_size=0,IO_word_size=0; float version; int exoid = ex_open (meshfile_.c_str(), EX_READ, &CPU_word_size, &IO_word_size, &version); if (exoid < 0) { throw ATC_Error("couldn't open "+meshfile_); } int nsd,nelemblk,nfsets; char title[MAX_LINE_LENGTH+1]; int error = ex_get_init (exoid, title, &nsd, &nNodes_, &nElements_, &nelemblk, &nNodeSets_, &nfsets); if (error > 0) { throw ATC_Error("problem with init "+meshfile_+" "+title); } // coordinates float x[nNodes_], y[nNodes_], z[nNodes_]; error = ex_get_coord (exoid, x, y, z); if (error > 0) { throw ATC_Error("problem with getting coordinates "+meshfile_); } nodeCoords_->reset(nsd,nNodes_); DENS_MAT & nodes = *nodeCoords_; for (int i = 0; i < nNodes_; ++i) { nodes(0,i) = x[i]; // this is a float to double conversion nodes(1,i) = y[i]; // this is a float to double conversion nodes(2,i) = z[i]; // this is a float to double conversion } ATC::LammpsInterface::instance()->print_msg_once("read "+to_string(nNodes_)+ " nodes"); // elements int blkIds[nelemblk],nblkelem[nelemblk],nnpe[nelemblk],na[nelemblk]; error = ex_get_elem_blk_ids(exoid, blkIds); char etype[MAX_STR_LENGTH+1]; string lastType; for (int i=0; i 0 && elementType_ != lastType ) { throw ATC_Error(meshfile_+" is composed of multiple types"); } lastType = etype; } int nVerts = number_of_vertices(elementType_); conn_->reset(nVerts, nElements_); int n = 0; for (int i=0; iprint_msg_once("read "+to_string(n)+" "+elementType_+" elements, block "+to_string(i+1)+"/"+to_string(nelemblk)); } // nodesets int nsetIds[nNodeSets_]; error = ex_get_node_set_ids (exoid, nsetIds); int nnodes,ndist; //nodeSets_ = new Array< pair< string,set > >(); nodeSets_->reset(nNodeSets_); for (int i=0; i 0) { throw ATC_Error("problem with closing "+meshfile_); } #endif } }; // end namespace ATC