Fem: refactor FemMesh::readNastran
This commit is contained in:
@@ -1105,6 +1105,215 @@ std::set<int> FemMesh::getFacesOnly(void) const
|
||||
return resultIDs;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class NastranElement {
|
||||
public:
|
||||
virtual ~NastranElement() = default;
|
||||
bool isValid() const {
|
||||
return element_id >= 0;
|
||||
}
|
||||
virtual void read(const std::string& str1, const std::string& str2) = 0;
|
||||
virtual void addToMesh(SMESHDS_Mesh* meshds) = 0;
|
||||
|
||||
protected:
|
||||
int element_id = -1;
|
||||
std::vector<int> elements;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<NastranElement> NastranElementPtr;
|
||||
|
||||
class GRIDElement : public NastranElement {
|
||||
void addToMesh(SMESHDS_Mesh* meshds) {
|
||||
meshds->AddNodeWithID(node.x, node.y, node.z, element_id);
|
||||
}
|
||||
|
||||
protected:
|
||||
Base::Vector3d node;
|
||||
};
|
||||
|
||||
class GRIDFreeFieldElement : public GRIDElement {
|
||||
void read(const std::string& str, const std::string&) {
|
||||
char_separator<char> sep(",");
|
||||
tokenizer<char_separator<char> > tokens(str, sep);
|
||||
std::vector<string> token_results;
|
||||
token_results.assign(tokens.begin(),tokens.end());
|
||||
if (token_results.size() < 6)
|
||||
return;//Line does not include Nodal coordinates
|
||||
|
||||
element_id = atoi(token_results[1].c_str());
|
||||
node.x = atof(token_results[3].c_str());
|
||||
node.y = atof(token_results[4].c_str());
|
||||
node.z = atof(token_results[5].c_str());
|
||||
}
|
||||
};
|
||||
|
||||
class GRIDLongFieldElement : public GRIDElement {
|
||||
void read(const std::string& str1, const std::string& str2) {
|
||||
element_id = atoi(str1.substr(8,24).c_str());
|
||||
node.x = atof(str1.substr(40,56).c_str());
|
||||
node.y = atof(str1.substr(56,72).c_str());
|
||||
node.z = atof(str2.substr(8,24).c_str());
|
||||
}
|
||||
};
|
||||
|
||||
class GRIDSmallFieldElement : public GRIDElement {
|
||||
void read(const std::string&, const std::string&) {
|
||||
}
|
||||
};
|
||||
|
||||
class CTRIA3Element : public NastranElement {
|
||||
public:
|
||||
void addToMesh(SMESHDS_Mesh* meshds) {
|
||||
const SMDS_MeshNode* n0 = meshds->FindNode(elements[0]);
|
||||
const SMDS_MeshNode* n1 = meshds->FindNode(elements[1]);
|
||||
const SMDS_MeshNode* n2 = meshds->FindNode(elements[2]);
|
||||
if (n0 && n1 && n2) {
|
||||
meshds->AddFaceWithID
|
||||
(
|
||||
n0, n1, n2,
|
||||
element_id
|
||||
);
|
||||
}
|
||||
else {
|
||||
Base::Console().Warning("NASTRAN: Failed to add face %d from nodes: (%d, %d, %d,)\n",
|
||||
element_id,
|
||||
elements[0],
|
||||
elements[1],
|
||||
elements[2]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CTRIA3FreeFieldElement : public CTRIA3Element {
|
||||
public:
|
||||
void read(const std::string& str, const std::string&) {
|
||||
char_separator<char> sep(",");
|
||||
tokenizer<char_separator<char> > tokens(str, sep);
|
||||
std::vector<string> token_results;
|
||||
token_results.assign(tokens.begin(),tokens.end());
|
||||
if (token_results.size() < 6)
|
||||
return;//Line does not include enough nodal IDs
|
||||
|
||||
element_id = atoi(token_results[1].c_str());
|
||||
elements.push_back(atoi(token_results[3].c_str()));
|
||||
elements.push_back(atoi(token_results[4].c_str()));
|
||||
elements.push_back(atoi(token_results[5].c_str()));
|
||||
}
|
||||
};
|
||||
|
||||
class CTRIA3LongFieldElement : public CTRIA3Element {
|
||||
public:
|
||||
void read(const std::string& str, const std::string&) {
|
||||
element_id = atoi(str.substr(8,16).c_str());
|
||||
elements.push_back(atoi(str.substr(24,32).c_str()));
|
||||
elements.push_back(atoi(str.substr(32,40).c_str()));
|
||||
elements.push_back(atoi(str.substr(40,48).c_str()));
|
||||
}
|
||||
};
|
||||
|
||||
class CTRIA3SmallFieldElement : public CTRIA3Element {
|
||||
public:
|
||||
void read(const std::string&, const std::string&) {
|
||||
}
|
||||
};
|
||||
|
||||
class CTETRAElement : public NastranElement {
|
||||
public:
|
||||
void addToMesh(SMESHDS_Mesh* meshds) {
|
||||
const SMDS_MeshNode* n0 = meshds->FindNode(elements[1]);
|
||||
const SMDS_MeshNode* n1 = meshds->FindNode(elements[0]);
|
||||
const SMDS_MeshNode* n2 = meshds->FindNode(elements[2]);
|
||||
const SMDS_MeshNode* n3 = meshds->FindNode(elements[3]);
|
||||
const SMDS_MeshNode* n4 = meshds->FindNode(elements[4]);
|
||||
const SMDS_MeshNode* n5 = meshds->FindNode(elements[6]);
|
||||
const SMDS_MeshNode* n6 = meshds->FindNode(elements[5]);
|
||||
const SMDS_MeshNode* n7 = meshds->FindNode(elements[8]);
|
||||
const SMDS_MeshNode* n8 = meshds->FindNode(elements[7]);
|
||||
const SMDS_MeshNode* n9 = meshds->FindNode(elements[9]);
|
||||
if (n0 && n1 && n2 && n3 && n4 && n5 && n6 && n7 && n8 && n9) {
|
||||
meshds->AddVolumeWithID
|
||||
(
|
||||
n0, n1, n2, n3, n4, n5, n6, n7, n8, n9,
|
||||
element_id
|
||||
);
|
||||
}
|
||||
else {
|
||||
Base::Console().Warning("NASTRAN: Failed to add volume %d from nodes: (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\n",
|
||||
element_id,
|
||||
elements[1],
|
||||
elements[0],
|
||||
elements[2],
|
||||
elements[3],
|
||||
elements[4],
|
||||
elements[6],
|
||||
elements[5],
|
||||
elements[8],
|
||||
elements[7],
|
||||
elements[9]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CTETRAFreeFieldElement : public CTETRAElement {
|
||||
public:
|
||||
void read(const std::string& str, const std::string&) {
|
||||
char_separator<char> sep(",");
|
||||
tokenizer<char_separator<char> > tokens(str, sep);
|
||||
std::vector<string> token_results;
|
||||
token_results.assign(tokens.begin(),tokens.end());
|
||||
if (token_results.size() < 14)
|
||||
return;//Line does not include enough nodal IDs
|
||||
|
||||
element_id = atoi(token_results[1].c_str());
|
||||
elements.push_back(atoi(token_results[3].c_str()));
|
||||
elements.push_back(atoi(token_results[4].c_str()));
|
||||
elements.push_back(atoi(token_results[5].c_str()));
|
||||
elements.push_back(atoi(token_results[6].c_str()));
|
||||
elements.push_back(atoi(token_results[7].c_str()));
|
||||
elements.push_back(atoi(token_results[8].c_str()));
|
||||
elements.push_back(atoi(token_results[10].c_str()));
|
||||
elements.push_back(atoi(token_results[11].c_str()));
|
||||
elements.push_back(atoi(token_results[12].c_str()));
|
||||
elements.push_back(atoi(token_results[13].c_str()));
|
||||
}
|
||||
};
|
||||
|
||||
class CTETRALongFieldElement : public CTETRAElement {
|
||||
public:
|
||||
void read(const std::string& str1, const std::string& str2) {
|
||||
int id = atoi(str1.substr(8,16).c_str());
|
||||
int offset = 0;
|
||||
|
||||
if(id < 1000000)
|
||||
offset = 0;
|
||||
else if (id < 10000000)
|
||||
offset = 1;
|
||||
else if (id < 100000000)
|
||||
offset = 2;
|
||||
|
||||
|
||||
element_id = id;
|
||||
elements.push_back(atoi(str1.substr(24,32).c_str()));
|
||||
elements.push_back(atoi(str1.substr(32,40).c_str()));
|
||||
elements.push_back(atoi(str1.substr(40,48).c_str()));
|
||||
elements.push_back(atoi(str1.substr(48,56).c_str()));
|
||||
elements.push_back(atoi(str1.substr(56,64).c_str()));
|
||||
elements.push_back(atoi(str1.substr(64,72).c_str()));
|
||||
elements.push_back(atoi(str2.substr(8+offset,16+offset).c_str()));
|
||||
elements.push_back(atoi(str2.substr(16+offset,24+offset).c_str()));
|
||||
elements.push_back(atoi(str2.substr(24+offset,32+offset).c_str()));
|
||||
elements.push_back(atoi(str2.substr(32+offset,40+offset).c_str()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CTETRASmallFieldElement : public CTETRAElement {
|
||||
public:
|
||||
void read(const std::string&, const std::string&) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void FemMesh::readNastran(const std::string &Filename)
|
||||
{
|
||||
Base::TimeInfo Start;
|
||||
@@ -1116,129 +1325,68 @@ void FemMesh::readNastran(const std::string &Filename)
|
||||
inputfile.open(Filename.c_str());
|
||||
inputfile.seekg(std::ifstream::beg);
|
||||
std::string line1,line2;
|
||||
std::vector<string> token_results;
|
||||
Base::Vector3d current_node;
|
||||
std::vector<Base::Vector3d> vertices;
|
||||
std::vector<unsigned int> nodal_id;
|
||||
std::vector<std::vector<unsigned int> > all_elements;
|
||||
std::vector<unsigned int> element_id;
|
||||
bool nastran_free_format = false;
|
||||
std::vector<NastranElementPtr> mesh_elements;
|
||||
enum Format {
|
||||
FreeField,
|
||||
SmallField,
|
||||
LongField
|
||||
};
|
||||
Format nastranFormat = Format::LongField;
|
||||
|
||||
do
|
||||
{
|
||||
std::getline(inputfile,line1);
|
||||
if (line1.size() == 0) continue;
|
||||
if (!nastran_free_format && line1.find(',')!= std::string::npos)
|
||||
nastran_free_format = true;
|
||||
if (!nastran_free_format && line1.find("GRID*")!= std::string::npos ) //We found a Grid line
|
||||
{
|
||||
if (line1.size() == 0)
|
||||
continue;
|
||||
if (line1.find(',') != std::string::npos)
|
||||
nastranFormat = Format::FreeField;
|
||||
|
||||
NastranElementPtr ptr;
|
||||
if (line1.find("GRID*") != std::string::npos) { //We found a Grid line
|
||||
//Now lets extract the GRID Points = Nodes
|
||||
//As each GRID Line consists of two subsequent lines we have to
|
||||
//take care of that as well
|
||||
std::getline(inputfile,line2);
|
||||
//Get the Nodal ID
|
||||
nodal_id.push_back(atoi(line1.substr(8,24).c_str()));
|
||||
//Extract X Value
|
||||
current_node.x = atof(line1.substr(40,56).c_str());
|
||||
//Extract Y Value
|
||||
current_node.y = atof(line1.substr(56,72).c_str());
|
||||
//Extract Z Value
|
||||
current_node.z = atof(line2.substr(8,24).c_str());
|
||||
|
||||
vertices.push_back(current_node);
|
||||
if (nastranFormat == Format::LongField) {
|
||||
std::getline(inputfile,line2);
|
||||
ptr = std::make_shared<GRIDLongFieldElement>();
|
||||
ptr->read(line1, line2);
|
||||
}
|
||||
}
|
||||
else if (!nastran_free_format && line1.find("CTETRA")!= std::string::npos)
|
||||
{
|
||||
else if (line1.find("GRID") != std::string::npos) { //We found a Grid line
|
||||
if (nastranFormat == Format::FreeField) {
|
||||
ptr = std::make_shared<GRIDFreeFieldElement>();
|
||||
ptr->read(line1, "");
|
||||
}
|
||||
}
|
||||
else if (line1.find("CTRIA3") != std::string::npos) {
|
||||
if (nastranFormat == Format::FreeField) {
|
||||
ptr = std::make_shared<CTRIA3FreeFieldElement>();
|
||||
ptr->read(line1, "");
|
||||
}
|
||||
else {
|
||||
ptr = std::make_shared<CTRIA3LongFieldElement>();
|
||||
ptr->read(line1, "");
|
||||
}
|
||||
}
|
||||
else if (line1.find("CTETRA") != std::string::npos) {
|
||||
//Lets extract the elements
|
||||
//As each Element Line consists of two subsequent lines as well
|
||||
//we have to take care of that
|
||||
//At a first step we only extract Quadratic Tetrahedral Elements
|
||||
std::getline(inputfile,line2);
|
||||
unsigned int id = atoi(line1.substr(8,16).c_str());
|
||||
int offset = 0;
|
||||
|
||||
if(id < 1000000)
|
||||
offset = 0;
|
||||
else if (id < 10000000)
|
||||
offset = 1;
|
||||
else if (id < 100000000)
|
||||
offset = 2;
|
||||
|
||||
|
||||
element_id.push_back(id);
|
||||
std::vector<unsigned int> tetra_element;
|
||||
tetra_element.push_back(atoi(line1.substr(24,32).c_str()));
|
||||
tetra_element.push_back(atoi(line1.substr(32,40).c_str()));
|
||||
tetra_element.push_back(atoi(line1.substr(40,48).c_str()));
|
||||
tetra_element.push_back(atoi(line1.substr(48,56).c_str()));
|
||||
tetra_element.push_back(atoi(line1.substr(56,64).c_str()));
|
||||
tetra_element.push_back(atoi(line1.substr(64,72).c_str()));
|
||||
tetra_element.push_back(atoi(line2.substr(8+offset,16+offset).c_str()));
|
||||
tetra_element.push_back(atoi(line2.substr(16+offset,24+offset).c_str()));
|
||||
tetra_element.push_back(atoi(line2.substr(24+offset,32+offset).c_str()));
|
||||
tetra_element.push_back(atoi(line2.substr(32+offset,40+offset).c_str()));
|
||||
|
||||
all_elements.push_back(tetra_element);
|
||||
}
|
||||
else if (nastran_free_format && line1.find("GRID")!= std::string::npos ) //We found a Grid line
|
||||
{
|
||||
char_separator<char> sep(",");
|
||||
tokenizer<char_separator<char> > tokens(line1, sep);
|
||||
token_results.assign(tokens.begin(),tokens.end());
|
||||
if (token_results.size() < 6)
|
||||
continue;//Line does not include Nodal coordinates
|
||||
|
||||
nodal_id.push_back(atoi(token_results[1].c_str()));
|
||||
current_node.x = atof(token_results[3].c_str());
|
||||
current_node.y = atof(token_results[4].c_str());
|
||||
current_node.z = atof(token_results[5].c_str());
|
||||
vertices.push_back(current_node);
|
||||
}
|
||||
else if (nastran_free_format && line1.find("CTRIA3")!= std::string::npos )
|
||||
{
|
||||
char_separator<char> sep(",");
|
||||
tokenizer<char_separator<char> > tokens(line1, sep);
|
||||
token_results.assign(tokens.begin(),tokens.end());
|
||||
if (token_results.size() < 6)
|
||||
continue;//Line does not include enough nodal IDs
|
||||
|
||||
element_id.push_back(atoi(token_results[1].c_str()));
|
||||
std::vector<unsigned int> face_element;
|
||||
face_element.push_back(atoi(token_results[3].c_str()));
|
||||
face_element.push_back(atoi(token_results[4].c_str()));
|
||||
face_element.push_back(atoi(token_results[5].c_str()));
|
||||
|
||||
all_elements.push_back(face_element);
|
||||
}
|
||||
else if (nastran_free_format && line1.find("CTETRA")!= std::string::npos)
|
||||
{
|
||||
//Lets extract the elements
|
||||
//As each Element Line consists of two subsequent lines as well
|
||||
//we have to take care of that
|
||||
//At a first step we only extract Quadratic Tetrahedral Elements
|
||||
std::getline(inputfile,line2);
|
||||
char_separator<char> sep(",");
|
||||
tokenizer<char_separator<char> > tokens(line1.append(line2), sep);
|
||||
token_results.assign(tokens.begin(),tokens.end());
|
||||
if (token_results.size() < 14)
|
||||
continue;//Line does not include enough nodal IDs
|
||||
|
||||
element_id.push_back(atoi(token_results[1].c_str()));
|
||||
std::vector<unsigned int> tetra_element;
|
||||
tetra_element.push_back(atoi(token_results[3].c_str()));
|
||||
tetra_element.push_back(atoi(token_results[4].c_str()));
|
||||
tetra_element.push_back(atoi(token_results[5].c_str()));
|
||||
tetra_element.push_back(atoi(token_results[6].c_str()));
|
||||
tetra_element.push_back(atoi(token_results[7].c_str()));
|
||||
tetra_element.push_back(atoi(token_results[8].c_str()));
|
||||
tetra_element.push_back(atoi(token_results[10].c_str()));
|
||||
tetra_element.push_back(atoi(token_results[11].c_str()));
|
||||
tetra_element.push_back(atoi(token_results[12].c_str()));
|
||||
tetra_element.push_back(atoi(token_results[13].c_str()));
|
||||
|
||||
all_elements.push_back(tetra_element);
|
||||
if (nastranFormat == Format::FreeField) {
|
||||
ptr = std::make_shared<CTETRAFreeFieldElement>();
|
||||
ptr->read(line1.append(line2), "");
|
||||
}
|
||||
else {
|
||||
ptr = std::make_shared<CTETRALongFieldElement>();
|
||||
ptr->read(line1, line2);
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr && ptr->isValid()) {
|
||||
mesh_elements.push_back(ptr);
|
||||
}
|
||||
}
|
||||
while (inputfile.good());
|
||||
inputfile.close();
|
||||
@@ -1246,74 +1394,13 @@ void FemMesh::readNastran(const std::string &Filename)
|
||||
Base::Console().Log(" %f: File read, start building mesh\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo()));
|
||||
|
||||
//Now fill the SMESH datastructure
|
||||
std::vector<Base::Vector3d>::const_iterator anodeiterator;
|
||||
SMESHDS_Mesh* meshds = this->myMesh->GetMeshDS();
|
||||
meshds->ClearMesh();
|
||||
unsigned int j=0;
|
||||
for(anodeiterator=vertices.begin(); anodeiterator!=vertices.end(); anodeiterator++)
|
||||
{
|
||||
meshds->AddNodeWithID((*anodeiterator).x,(*anodeiterator).y,(*anodeiterator).z,nodal_id[j]);
|
||||
j++;
|
||||
|
||||
for (auto it : mesh_elements) {
|
||||
it->addToMesh(meshds);
|
||||
}
|
||||
|
||||
for(size_t i=0;i<all_elements.size();i++)
|
||||
{
|
||||
// an consistent data structure is only possible
|
||||
// if the elements are added in the right order
|
||||
// thus the order is very important
|
||||
if (all_elements[i].size() == 3) {
|
||||
const SMDS_MeshNode* n0 = meshds->FindNode(all_elements[i][0]);
|
||||
const SMDS_MeshNode* n1 = meshds->FindNode(all_elements[i][1]);
|
||||
const SMDS_MeshNode* n2 = meshds->FindNode(all_elements[i][2]);
|
||||
if (n0 && n1 && n2) {
|
||||
meshds->AddFaceWithID
|
||||
(
|
||||
n0, n1, n2,
|
||||
element_id[i]
|
||||
);
|
||||
}
|
||||
else {
|
||||
Base::Console().Warning("NASTRAN: Failed to add face %d from nodes: (%d, %d, %d,)\n",
|
||||
element_id[i],
|
||||
all_elements[i][0],
|
||||
all_elements[i][1],
|
||||
all_elements[i][2]);
|
||||
}
|
||||
}
|
||||
else if (all_elements[i].size() == 10) {
|
||||
const SMDS_MeshNode* n0 = meshds->FindNode(all_elements[i][1]);
|
||||
const SMDS_MeshNode* n1 = meshds->FindNode(all_elements[i][0]);
|
||||
const SMDS_MeshNode* n2 = meshds->FindNode(all_elements[i][2]);
|
||||
const SMDS_MeshNode* n3 = meshds->FindNode(all_elements[i][3]);
|
||||
const SMDS_MeshNode* n4 = meshds->FindNode(all_elements[i][4]);
|
||||
const SMDS_MeshNode* n5 = meshds->FindNode(all_elements[i][6]);
|
||||
const SMDS_MeshNode* n6 = meshds->FindNode(all_elements[i][5]);
|
||||
const SMDS_MeshNode* n7 = meshds->FindNode(all_elements[i][8]);
|
||||
const SMDS_MeshNode* n8 = meshds->FindNode(all_elements[i][7]);
|
||||
const SMDS_MeshNode* n9 = meshds->FindNode(all_elements[i][9]);
|
||||
if (n0 && n1 && n2 && n3 && n4 && n5 && n6 && n7 && n8 && n9) {
|
||||
meshds->AddVolumeWithID
|
||||
(
|
||||
n0, n1, n2, n3, n4, n5, n6, n7, n8, n9,
|
||||
element_id[i]
|
||||
);
|
||||
}
|
||||
else {
|
||||
Base::Console().Warning("NASTRAN: Failed to add volume %d from nodes: (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\n",
|
||||
element_id[i],
|
||||
all_elements[i][1],
|
||||
all_elements[i][0],
|
||||
all_elements[i][2],
|
||||
all_elements[i][3],
|
||||
all_elements[i][4],
|
||||
all_elements[i][6],
|
||||
all_elements[i][5],
|
||||
all_elements[i][8],
|
||||
all_elements[i][7],
|
||||
all_elements[i][9]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Base::Console().Log(" %f: Done \n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo()));
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user