forked from lijiext/lammps
218 lines
6.7 KiB
C++
218 lines
6.7 KiB
C++
#include "MeshReader.h"
|
|
#include "LammpsInterface.h"
|
|
#include "Utility.h"
|
|
#ifdef HAS_EXODUS
|
|
//#include <stdio.h>
|
|
//#include "netcdf.h"
|
|
#include "exodusII.h"
|
|
#endif
|
|
|
|
namespace ATC {
|
|
using ATC_Utility::to_string;
|
|
/** constructor, takes a filename */
|
|
MeshReader::MeshReader(string filename,
|
|
Array<bool> periodicity,
|
|
double tol)
|
|
: meshfile_(filename),
|
|
periodicity_(periodicity),
|
|
nNodes_(0),
|
|
nElements_(0),
|
|
coordTol_(tol)
|
|
{
|
|
conn_ = new Array2D<int>();
|
|
nodeCoords_ = new DENS_MAT;
|
|
nodeSets_ = new Array< pair< string,set<int> > >();
|
|
|
|
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()
|
|
{
|
|
}
|
|
|
|
/** creates handle to new mesh object */
|
|
FE_Mesh* MeshReader::create_mesh()
|
|
{
|
|
return new FE_3DMesh(elementType_,
|
|
nNodes_, nElements_,
|
|
conn_, nodeCoords_,
|
|
periodicity_,
|
|
nodeSets_);
|
|
}
|
|
|
|
/** 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 = int_from_str(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<nelemblk; i++){
|
|
error = ex_get_elem_block (exoid, blkIds[i], etype,
|
|
&(nblkelem[i]), &(nnpe[i]), &(na[i]));
|
|
elementType_ = etype;
|
|
if (i > 0 && elementType_ != lastType )
|
|
{ throw ATC_Error(meshfile_+" is composed of multiple types"); }
|
|
lastType = etype;
|
|
}
|
|
int nVerts = int_from_str(elementType_);
|
|
conn_->reset(nVerts, nElements_);
|
|
int n = 0;
|
|
for (int i=0; i<nelemblk; i++) {
|
|
int bconn[nnpe[i]*nblkelem[i]];
|
|
error = ex_get_elem_conn (exoid, blkIds[i], &bconn);
|
|
for (int j=0; j<nblkelem[i]; j++) {
|
|
for (int k=0; k<nnpe[i]; k++) {
|
|
(*conn_)(k,n) = bconn[k+j*nnpe[i]]-1;
|
|
}
|
|
n++;
|
|
}
|
|
ATC::LammpsInterface::instance()->print_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<int> > >();
|
|
nodeSets_->reset(nNodeSets_);
|
|
for (int i=0; i<nNodeSets_; i++) {
|
|
(*nodeSets_)(i).first = to_string(nsetIds[i]);
|
|
error = ex_get_node_set_param (exoid, nsetIds[i], &nnodes, &ndist);
|
|
int nodes[nnodes];
|
|
error = ex_get_node_set (exoid, nsetIds[i], nodes);
|
|
for (int j=0; j<nnodes; j++) {
|
|
(*nodeSets_)(i).second.insert(nodes[j]-1);
|
|
}
|
|
}
|
|
error = ex_close(exoid);
|
|
if (error > 0) { throw ATC_Error("problem with closing "+meshfile_); }
|
|
#endif
|
|
}
|
|
|
|
int MeshReader::int_from_str(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<str.size(); a++) {
|
|
temp += str[a];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
istringstream(temp) >> number;
|
|
return number;
|
|
}
|
|
|
|
}; // end namespace ATC
|