diff --git a/src/Mod/Fem/App/FemMesh.cpp b/src/Mod/Fem/App/FemMesh.cpp index aeb214a8e8..ebe59b30d9 100644 --- a/src/Mod/Fem/App/FemMesh.cpp +++ b/src/Mod/Fem/App/FemMesh.cpp @@ -1312,6 +1312,184 @@ public: void read(const std::string&, const std::string&) { } }; + +// NASTRAN-95 + +class GRIDNastran95Element : public GRIDElement { + void read(const std::string& str, const std::string&) { + element_id = atoi(str.substr(8, 16).c_str()); + node.x = atof(str.substr(24, 32).c_str()); + node.y = atof(str.substr(32, 40).c_str()); + node.z = atof(str.substr(40, 48).c_str()); + } +}; + +class CBARElement : public NastranElement { + 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())); + } + void addToMesh(SMESHDS_Mesh* meshds) { + meshds->AddEdgeWithID( + elements[0], + elements[1], + element_id + ); + } +}; + +class CTRMEMElement : public NastranElement { + 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())); + } + void addToMesh(SMESHDS_Mesh* meshds) { + meshds->AddFaceWithID( + elements[0], + elements[1], + elements[2], + element_id + ); + } +}; + +class CTRIA1Element : public NastranElement { + 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())); + } + void addToMesh(SMESHDS_Mesh* meshds) { + meshds->AddFaceWithID( + elements[0], + elements[1], + elements[2], + element_id + ); + } +}; + +class CQUAD1Element : public NastranElement { + 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())); + elements.push_back(atoi(str.substr(48, 56).c_str())); + } + void addToMesh(SMESHDS_Mesh* meshds) { + meshds->AddFaceWithID( + elements[0], + elements[1], + elements[2], + elements[3], + element_id + ); + } +}; + +class CTETRANastran95Element : public NastranElement { + 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())); + elements.push_back(atoi(str.substr(48, 56).c_str())); + } + void addToMesh(SMESHDS_Mesh* meshds) { + meshds->AddFaceWithID( + elements[0], + elements[1], + elements[2], + elements[3], + element_id + ); + } +}; + +class CWEDGEElement : public NastranElement { + 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())); + elements.push_back(atoi(str.substr(48,56).c_str())); + elements.push_back(atoi(str.substr(56,64).c_str())); + elements.push_back(atoi(str.substr(64,72).c_str())); + } + void addToMesh(SMESHDS_Mesh* meshds) { + meshds->AddVolumeWithID( + elements[0], + elements[1], + elements[2], + elements[3], + elements[4], + elements[5], + element_id + ); + } +}; + +class CHEXA1Element : public NastranElement { + void read(const std::string& str1, const std::string& str2) { + element_id = atoi(str1.substr(8,16).c_str()); + 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,16).c_str())); + elements.push_back(atoi(str2.substr(16,24).c_str())); + } + void addToMesh(SMESHDS_Mesh* meshds) { + meshds->AddVolumeWithID( + elements[0], + elements[1], + elements[2], + elements[3], + elements[4], + elements[5], + elements[6], + elements[7], + element_id + ); + } +}; + +class CHEXA2Element : public NastranElement { + void read(const std::string& str1, const std::string& str2) { + element_id = atoi(str1.substr(8,16).c_str()); + 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,16).c_str())); + elements.push_back(atoi(str2.substr(16,24).c_str())); + } + void addToMesh(SMESHDS_Mesh* meshds) { + meshds->AddVolumeWithID( + elements[0], + elements[1], + elements[2], + elements[3], + elements[4], + elements[5], + elements[6], + elements[7], + element_id + ); + } +}; + } void FemMesh::readNastran(const std::string &Filename) @@ -1416,416 +1594,129 @@ void FemMesh::readNastran95(const std::string &Filename) inputfile.open(Filename.c_str()); inputfile.seekg(std::ifstream::beg); std::string line1,line2,tcard; - float cx, cy, cz; - std::vector token_results; - token_results.clear(); - Base::Vector3d current_node; - std::vector vertices; - vertices.clear(); - std::vector nodal_id; - nodal_id.clear(); + std::vector mesh_nodes; + std::vector mesh_elements; - std::vector bar_element; - std::vector tri_element; - std::vector quad_element; - std::vector tetra_element; - std::vector wedge_element; - std::vector hexa_element; - - std::vector > all_elements; - - std::vector element_id; - std::vector element_type; - - element_id.clear(); - element_type.clear(); - - bool nastran_free_format = false; do { - std::getline(inputfile,line1); + NastranElementPtr node; + NastranElementPtr elem; + std::getline(inputfile, line1); //cout << line1 << endl; - if (line1.size() == 0) continue; - //if (!nastran_free_format && line1.find(',')!= std::string::npos) - // nastran_free_format = true; + if (line1.size() == 0) + continue; + tcard = line1.substr(0, 8).c_str(); //boost::algorithm::trim(tcard); - if (!nastran_free_format && line1.find("GRID*")!= std::string::npos ) //We found a Grid line + 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); + node = std::make_shared(); + node->read(line1, line2); } - else if (!nastran_free_format && line1.find("GRID") != std::string::npos) //We found a Grid line + else if (line1.find("GRID") != std::string::npos) //We found a Grid line { //Base::Console().Log("Found a GRID\n"); //D06.inp //GRID 109 .9 .7 //Now lets extract the GRID Points = Nodes //Get the Nodal ID - unsigned int id = atoi(line1.substr(8, 16).c_str()); - - //Extract X Value - cx = atof(line1.substr(24, 32).c_str()); - current_node.x = cx; - //Extract Y Value - cy = atof(line1.substr(32, 40).c_str()); - current_node.y = cy; - //Extract Z Value - cz = atof(line1.substr(40, 48).c_str()); - current_node.z = cz; - // atof(line1.substr(40, 48).c_str()); - //Base::Console().Log("nid = %d %f %f %f\n", id, cx, cy, cz); - - nodal_id.push_back(id); - vertices.push_back(current_node); + node = std::make_shared(); + node->read(line1, ""); } //1D else if (line1.substr(0,6)=="CBAR") { - //Base::Console().Log("Found a CTRMEM\n"); - bar_element.clear(); - unsigned int id = atoi(line1.substr(8,16).c_str()); - - element_type.push_back(100); - element_id.push_back(id); - bar_element.push_back(atoi(line1.substr(24,32).c_str())); - bar_element.push_back(atoi(line1.substr(32,40).c_str())); - - all_elements.push_back(bar_element); + elem = std::make_shared(); + elem->read(line1, ""); } //2d -// else if (!nastran_free_format && line1.find("CTRMEM")!= std::string::npos) else if (line1.substr(0,6)=="CTRMEM") { - //Base::Console().Log("Found a CTRMEM\n"); - tri_element.clear(); - unsigned int id = atoi(line1.substr(8,16).c_str()); - //D06 - //CTRMEM 322 1 179 180 185 - element_type.push_back(230); - element_id.push_back(id); - tri_element.push_back(atoi(line1.substr(24,32).c_str())); - tri_element.push_back(atoi(line1.substr(32,40).c_str())); - tri_element.push_back(atoi(line1.substr(40,48).c_str())); - - all_elements.push_back(tri_element); + //CTRMEM 322 1 179 180 185 + elem = std::make_shared(); + elem->read(line1, ""); } else if (line1.substr(0, 6) == "CTRIA1") { - //Base::Console().Log("Found a CTRMEM\n"); - tri_element.clear(); - unsigned int id = atoi(line1.substr(8, 16).c_str()); - //D06 - //CTRMEM 322 1 179 180 185 - element_type.push_back(231); - element_id.push_back(id); - tri_element.push_back(atoi(line1.substr(24, 32).c_str())); - tri_element.push_back(atoi(line1.substr(32, 40).c_str())); - tri_element.push_back(atoi(line1.substr(40, 48).c_str())); - - all_elements.push_back(tri_element); + //CTRMEM 322 1 179 180 185 + elem = std::make_shared(); + elem->read(line1, ""); } else if (line1.substr(0, 6) == "CQUAD1") { - //Base::Console().Log("Found a CQUAD1\n"); - quad_element.clear(); - unsigned int id = atoi(line1.substr(8, 16).c_str()); - //D06 //CTRMEM 322 1 179 180 185 - element_type.push_back(241); - element_id.push_back(id); - quad_element.push_back(atoi(line1.substr(24, 32).c_str())); - quad_element.push_back(atoi(line1.substr(32, 40).c_str())); - quad_element.push_back(atoi(line1.substr(40, 48).c_str())); - quad_element.push_back(atoi(line1.substr(48, 56).c_str())); - - all_elements.push_back(quad_element); + elem = std::make_shared(); + elem->read(line1, ""); } //3d element - else if (!nastran_free_format && line1.find("CTETRA")!= std::string::npos) + else if (line1.find("CTETRA")!= std::string::npos) { //d011121a.inp //CTETRA 3 200 104 114 3 103 - tetra_element.clear(); - unsigned int id = atoi(line1.substr(8,16).c_str()); - element_type.push_back(340); - - element_id.push_back(id); - 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())); - - all_elements.push_back(tetra_element); + elem = std::make_shared(); + elem->read(line1, ""); } - else if (!nastran_free_format && line1.find("CWEDGE")!= std::string::npos) + else if (line1.find("CWEDGE")!= std::string::npos) { //d011121a.inp //CWEDGE 11 200 6 17 16 106 117 116 - tetra_element.clear(); - unsigned int id = atoi(line1.substr(8,16).c_str()); - element_type.push_back(360); - - element_id.push_back(id); - wedge_element.push_back(atoi(line1.substr(24,32).c_str())); - wedge_element.push_back(atoi(line1.substr(32,40).c_str())); - wedge_element.push_back(atoi(line1.substr(40,48).c_str())); - wedge_element.push_back(atoi(line1.substr(48,56).c_str())); - wedge_element.push_back(atoi(line1.substr(56,64).c_str())); - wedge_element.push_back(atoi(line1.substr(64,72).c_str())); - - all_elements.push_back(wedge_element); + elem = std::make_shared(); + elem->read(line1, ""); } - else if (!nastran_free_format && line1.find("CHEXA1")!= std::string::npos) + else if (line1.find("CHEXA1")!= std::string::npos) { //d011121a.inp //CHEXA1 1 200 1 2 13 12 101 102 +SOL1 //+SOL1 113 112 - tetra_element.clear(); std::getline(inputfile,line2); - unsigned int id = atoi(line1.substr(8,16).c_str()); - element_type.push_back(381); - - element_id.push_back(id); - hexa_element.push_back(atoi(line1.substr(24,32).c_str())); - hexa_element.push_back(atoi(line1.substr(32,40).c_str())); - hexa_element.push_back(atoi(line1.substr(40,48).c_str())); - hexa_element.push_back(atoi(line1.substr(48,56).c_str())); - hexa_element.push_back(atoi(line1.substr(56,64).c_str())); - hexa_element.push_back(atoi(line1.substr(64,72).c_str())); - - hexa_element.push_back(atoi(line2.substr(8,16).c_str())); - hexa_element.push_back(atoi(line2.substr(16,24).c_str())); - - all_elements.push_back(hexa_element); + elem = std::make_shared(); + elem->read(line1, line2); } - else if (!nastran_free_format && line1.find("CHEXA2")!= std::string::npos) + else if (line1.find("CHEXA2")!= std::string::npos) { //d011121a.inp //CHEXA1 1 200 1 2 13 12 101 102 +SOL1 //+SOL1 113 112 - tetra_element.clear(); std::getline(inputfile,line2); - unsigned int id = atoi(line1.substr(8,16).c_str()); - element_type.push_back(382); - - element_id.push_back(id); - hexa_element.push_back(atoi(line1.substr(24,32).c_str())); - hexa_element.push_back(atoi(line1.substr(32,40).c_str())); - hexa_element.push_back(atoi(line1.substr(40,48).c_str())); - hexa_element.push_back(atoi(line1.substr(48,56).c_str())); - hexa_element.push_back(atoi(line1.substr(56,64).c_str())); - hexa_element.push_back(atoi(line1.substr(64,72).c_str())); - - hexa_element.push_back(atoi(line2.substr(8,16).c_str())); - hexa_element.push_back(atoi(line2.substr(16,24).c_str())); - - all_elements.push_back(hexa_element); + elem = std::make_shared(); + elem->read(line1, line2); } -// free format - else if (nastran_free_format && line1.find("GRID")!= std::string::npos ) //We found a Grid line - { - //Base::Console().Log("Found a free format GRID\n"); - char_separator sep(","); - tokenizer > tokens(line1, sep); - token_results.assign(tokens.begin(),tokens.end()); - if (token_results.size() < 3) - 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("CTETRA")!= std::string::npos) - { - //Quadratic Tetrahedral Elements - //Base::Console().Log("Found a CTETRA\n"); - tetra_element.clear(); - std::getline(inputfile,line2); - char_separator sep(","); - tokenizer > tokens(line1.append(line2), sep); - token_results.assign(tokens.begin(),tokens.end()); - if (token_results.size() < 11) - continue;//Line does not include enough nodal IDs - element_id.push_back(atoi(token_results[1].c_str())); - 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 (node && node->isValid()) { + mesh_nodes.push_back(node); } + if (elem && elem->isValid()) { + mesh_elements.push_back(elem); + } } while (inputfile.good()); inputfile.close(); -// Base::Console().Log("Done saving node.\n"); Base::Console().Log(" %f: File read, start building mesh\n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); //Now fill the SMESH datastructure - std::vector::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]); - //Base::Console().Log("nid = %d %f %f %f\n", nodal_id[j], (*anodeiterator).x, (*anodeiterator).y, (*anodeiterator).z); - j++; + + for (auto it : mesh_nodes) { + it->addToMesh(meshds); } - - for(size_t i=0;iAddVolumeWithID - ( - //tetra 10 point - meshds->FindNode(all_elements[i][1]), - meshds->FindNode(all_elements[i][0]), - meshds->FindNode(all_elements[i][2]), - meshds->FindNode(all_elements[i][3]), - meshds->FindNode(all_elements[i][4]), - meshds->FindNode(all_elements[i][6]), - meshds->FindNode(all_elements[i][5]), - meshds->FindNode(all_elements[i][8]), - meshds->FindNode(all_elements[i][7]), - meshds->FindNode(all_elements[i][9]), - element_id[i] - ); - - } - //1D element - else if (element_type[i] == 100) - { - //Base::Console().Log("eid = %d %d %d %d\n", element_id[i], all_elements[i][0], all_elements[i][1], all_elements[i][2]); - //cbar - meshds->AddEdgeWithID( - all_elements[i][0], - all_elements[i][1], - element_id[i] - ); - } - //2d element - else if (element_type[i] == 230) - { - //Base::Console().Log("eid = %d %d %d %d\n", element_id[i], all_elements[i][0], all_elements[i][1], all_elements[i][2]); - //ctramem - meshds->AddFaceWithID( - all_elements[i][0], - all_elements[i][1], - all_elements[i][2], - element_id[i] - ); - } - else if (element_type[i] == 231) - { - //ctria1 - meshds->AddFaceWithID( - all_elements[i][0], - all_elements[i][1], - all_elements[i][2], - element_id[i] - ); - } - else if (element_type[i] == 241) - { - //cquad1 - meshds->AddFaceWithID( - all_elements[i][0], - all_elements[i][1], - all_elements[i][2], - all_elements[i][3], - element_id[i] - ); - } - - //3d element - else if (element_type[i] == 340) - { - //ctetra - meshds->AddVolumeWithID( - all_elements[i][0], - all_elements[i][1], - all_elements[i][2], - all_elements[i][3], - element_id[i] - ); - } - else if (element_type[i] == 360) - { - //cwedge - meshds->AddVolumeWithID( - all_elements[i][0], - all_elements[i][1], - all_elements[i][2], - all_elements[i][3], - all_elements[i][4], - all_elements[i][5], - element_id[i] - ); - } - else if (element_type[i] == 381) - { - //chexa1 - meshds->AddVolumeWithID( - all_elements[i][0], - all_elements[i][1], - all_elements[i][2], - all_elements[i][3], - all_elements[i][4], - all_elements[i][5], - all_elements[i][6], - all_elements[i][7], - element_id[i] - ); - } - else if (element_type[i] == 382) - { - //chexa2 - meshds->AddVolumeWithID( - all_elements[i][0], - all_elements[i][1], - all_elements[i][2], - all_elements[i][3], - all_elements[i][4], - all_elements[i][5], - all_elements[i][6], - all_elements[i][7], - element_id[i] - ); - } + for (auto it : mesh_elements) { + it->addToMesh(meshds); } + Base::Console().Log(" %f: Done \n",Base::TimeInfo::diffTimeF(Start,Base::TimeInfo())); }