FEM: improvements in Abaqus (CalculiX) FEM mesh im- and export:

- add hexa8, hex20, penta6, penta15, quad4, quad8 to writeAbaqus in FemMesh
- make node order in ccxFrdReader and writeAbaqus fitting each other
This commit is contained in:
Bernd Hahnebach 2016-05-14 19:42:56 +01:00 committed by wmayer
parent c60da6c6e9
commit 4bef49bb51
2 changed files with 226 additions and 139 deletions

View File

@ -891,9 +891,16 @@ void FemMesh::writeABAQUS(const std::string &Filename) const
static std::map<int, std::string> faceTypeMap;
static std::map<int, std::string> volTypeMap;
if (elemOrderMap.empty()) {
// node order fits with node order in ccxFrdReader.py module to import CalculiX result meshes
// dimension 1
//
// seg2 FreeCAD --> CalculiX B31
// N1, N2
std::vector<int> b31 = boost::assign::list_of(0)(1);
//
// seg3 FreeCAD --> CalculiX B32
// N1, N3, N2
std::vector<int> b32 = boost::assign::list_of(0)(2)(1);
elemOrderMap.insert(std::make_pair("B31", b31));
@ -903,49 +910,89 @@ void FemMesh::writeABAQUS(const std::string &Filename) const
// dimension 2
//
// tria3 FreeCAD --> S3 CalculiX
// N1, N2, N3
std::vector<int> s3 = boost::assign::list_of(0)(1)(2);
//
// tria6 FreeCAD --> S6 CalculiX
// N1, N2, N3, N4, N5, N6
std::vector<int> s6 = boost::assign::list_of(0)(1)(2)(3)(4)(5);
// FIXME: get the right order
std::vector<int> s4r;
std::vector<int> s8r;
//
// quad4 FreeCAD --> S4 CalculiX
// N1, N2, N3, N4
std::vector<int> s4 = boost::assign::list_of(0)(1)(2)(3);
//
// quad8 FreeCAD --> S8 CalculiX
// N1, N2, N3, N4, N5, N6, N7, N8
std::vector<int> s8 = boost::assign::list_of(0)(1)(2)(3)(4)(5)(6)(7);
elemOrderMap.insert(std::make_pair("S3", s3));
faceTypeMap.insert(std::make_pair(elemOrderMap["S3"].size(), "S3"));
elemOrderMap.insert(std::make_pair("S6", s6));
faceTypeMap.insert(std::make_pair(elemOrderMap["S6"].size(), "S6"));
#if 0
elemOrderMap.insert(std::make_pair("S4R", s4r));
faceTypeMap.insert(std::make_pair(elemOrderMap["S4R"].size(), "S4R"));
elemOrderMap.insert(std::make_pair("S8R", s8r));
faceTypeMap.insert(std::make_pair(elemOrderMap["S8R"].size(), "S8R"));
#endif
elemOrderMap.insert(std::make_pair("S4", s4));
faceTypeMap.insert(std::make_pair(elemOrderMap["S4"].size(), "S4"));
elemOrderMap.insert(std::make_pair("S8", s8));
faceTypeMap.insert(std::make_pair(elemOrderMap["S8"].size(), "S8"));
// dimension 3
//
// tetras
// master 0.14 release
// changed to this in August 2013, commited by juergen (jriedel)
// https://github.com/FreeCAD/FreeCAD/commit/af56b324b9566b20f3b6e7880c29354c1dbe7a99
//std::vector<int> c3d4 = boost::assign::list_of(0)(3)(1)(2);
//std::vector<int> c3d10 = boost::assign::list_of(0)(2)(1)(3)(6)(5)(4)(7)(9)(8);
// since master 0.15
// added by werner (wmayer) March 2015, http://forum.freecadweb.org/viewtopic.php?f=18&t=10110&start=10#p81681
// https://github.com/FreeCAD/FreeCAD/commit/5d159f5cf352a93b1aff4fb7b82e8b747ee4f35b
// https://github.com/FreeCAD/FreeCAD/commit/b007bd19e4e4608caa4cdad350a9f480287fac6b
// tetra4 FreeCAD --> C3D4 CalculiX
// N2, N1, N3, N4
std::vector<int> c3d4 = boost::assign::list_of(1)(0)(2)(3);
// tetra10: FreeCAD --> C3D10 CalculiX
// N2, N1, N3, N4, N5, N7, N6, N9, N8, N10
std::vector<int> c3d10 = boost::assign::list_of(1)(0)(2)(3)(4)(6)(5)(8)(7)(9);
// FIXME: get the right order
std::vector<int> c3d6;
std::vector<int> c3d8;
std::vector<int> c3d15;
std::vector<int> c3d20;
// tetra node order for the system which is used for hexa8, hexa20, penta6 and penda15
// be careful with activating because of method getccxVolumesByFace())
// tetra4 FreeCAD --> C3D4 CalculiX
// N2, N3, N4, N1
//std::vector<int> c3d4 = boost::assign::list_of(1)(2)(3)(0);
//
// tetra10: FreeCAD --> C3D10 CalculiX
// N2, N3, N4, N1, N6, N10, N9, N5, N7, N8
//std::vector<int> c3d10 = boost::assign::list_of(1)(2)(3)(0)(5)(9)(8)(4)(6)(7);
// hexa8 FreeCAD --> C3D8 CalculiX
// N6, N7, N8, N5, N2, N3, N4, N1
std::vector<int> c3d8 = boost::assign::list_of(5)(6)(7)(4)(1)(2)(3)(0) ;
//
// hexa20 FreeCAD --> C3D20 CalculiX
// N6, N7, N8, N5, N2, N3, N4, N1, N14, N15, N16, N13, N10, N11, N12, N9, N18, N19, N20, N17
std::vector<int> c3d20 = boost::assign::list_of(5)(6)(7)(4)(1)(2)(3)(0)(13)(14)(15)(12)(9)(10)(11)(8)(17)(18)(19)(16) ;
//
// penta6 FreeCAD --> C3D6 CalculiX
// N5, N6, N4, N2, N3, N1
std::vector<int> c3d6 = boost::assign::list_of(4)(5)(3)(1)(2)(0) ;
//
// penta15 FreeCAD --> C3D15 CalculiX
// N5, N6, N4, N2, N3, N1, N11, N12, N10, N8, N9, N7, N14, N15, N13
std::vector<int> c3d15 = boost::assign::list_of(4)(5)(3)(1)(2)(0)(10)(11)(9)(7)(8)(6)(13)(14)(12) ;
elemOrderMap.insert(std::make_pair("C3D4", c3d4));
volTypeMap.insert(std::make_pair(elemOrderMap["C3D4"].size(), "C3D4"));
elemOrderMap.insert(std::make_pair("C3D10", c3d10));
volTypeMap.insert(std::make_pair(elemOrderMap["C3D10"].size(), "C3D10"));
#if 0
elemOrderMap.insert(std::make_pair("C3D6", c3d6));
volTypeMap.insert(std::make_pair(elemOrderMap["C3D6"].size(), "C3D6"));
elemOrderMap.insert(std::make_pair("C3D8", c3d8));
volTypeMap.insert(std::make_pair(elemOrderMap["C3D8"].size(), "C3D8"));
elemOrderMap.insert(std::make_pair("C3D15", c3d15));
volTypeMap.insert(std::make_pair(elemOrderMap["C3D15"].size(), "C3D15"));
elemOrderMap.insert(std::make_pair("C3D20", c3d20));
volTypeMap.insert(std::make_pair(elemOrderMap["C3D20"].size(), "C3D20"));
#endif
elemOrderMap.insert(std::make_pair("C3D6", c3d6));
volTypeMap.insert(std::make_pair(elemOrderMap["C3D6"].size(), "C3D6"));
elemOrderMap.insert(std::make_pair("C3D15", c3d15));
volTypeMap.insert(std::make_pair(elemOrderMap["C3D15"].size(), "C3D15"));
}
std::ofstream anABAQUS_Output;
@ -1002,9 +1049,21 @@ void FemMesh::writeABAQUS(const std::string &Filename) const
for (ElementsMap::iterator it = elementsMap.begin(); it != elementsMap.end(); ++it) {
anABAQUS_Output << "*Element, TYPE=" << it->first << ", ELSET=Eall" << std::endl;
for (NodesMap::iterator jt = it->second.begin(); jt != it->second.end(); ++jt) {
anABAQUS_Output << jt->first << ", ";
for (std::vector<int>::iterator kt = jt->second.begin(); kt != jt->second.end(); ++kt) {
anABAQUS_Output << *kt << ", ";
anABAQUS_Output << jt->first;
// Calculix allows max 16 enntries in one line, an hexa20 has more !
int ct = 0; // counter
bool first_line = true;
for (std::vector<int>::iterator kt = jt->second.begin(); kt != jt->second.end(); ++kt, ++ct) {
if (ct < 15) {
anABAQUS_Output << ", " << *kt;
}
else {
if (first_line == true) {
anABAQUS_Output << "," << std::endl;
first_line = false;
}
anABAQUS_Output << *kt << ", ";
}
}
anABAQUS_Output << std::endl;
}
@ -1037,9 +1096,9 @@ void FemMesh::writeABAQUS(const std::string &Filename) const
for (ElementsMap::iterator it = elementsMap.begin(); it != elementsMap.end(); ++it) {
anABAQUS_Output << "*Element, TYPE=" << it->first << ", ELSET=Eall" << std::endl;
for (NodesMap::iterator jt = it->second.begin(); jt != it->second.end(); ++jt) {
anABAQUS_Output << jt->first << ", ";
anABAQUS_Output << jt->first;
for (std::vector<int>::iterator kt = jt->second.begin(); kt != jt->second.end(); ++kt) {
anABAQUS_Output << *kt << ", ";
anABAQUS_Output << ", " << *kt;
}
anABAQUS_Output << std::endl;
}
@ -1072,9 +1131,9 @@ void FemMesh::writeABAQUS(const std::string &Filename) const
for (ElementsMap::iterator it = elementsMap.begin(); it != elementsMap.end(); ++it) {
anABAQUS_Output << "*Element, TYPE=" << it->first << ", ELSET=Eall" << std::endl;
for (NodesMap::iterator jt = it->second.begin(); jt != it->second.end(); ++jt) {
anABAQUS_Output << jt->first << ", ";
anABAQUS_Output << jt->first;
for (std::vector<int>::iterator kt = jt->second.begin(); kt != jt->second.end(); ++kt) {
anABAQUS_Output << *kt << ", ";
anABAQUS_Output << ", " << *kt;
}
anABAQUS_Output << std::endl;
}
@ -1412,3 +1471,4 @@ Base::Quantity FemMesh::getVolume(void)const
}

View File

@ -83,122 +83,149 @@ def readResult(frd_input):
elemType = int(line[14:18])
#then import elements
if elements_found and (line[1:3] == "-2"):
if elemType == 1: # HEXA8 element
node_id_5 = int(line[3:13])
node_id_6 = int(line[13:23])
node_id_7 = int(line[23:33])
node_id_8 = int(line[33:43])
node_id_1 = int(line[43:53])
node_id_2 = int(line[53:63])
node_id_3 = int(line[63:73])
node_id_4 = int(line[73:83])
elements_hexa8[elem] = (node_id_1, node_id_2, node_id_3, node_id_4, node_id_5, node_id_6, node_id_7, node_id_8)
elif elemType == 2: # PENTA6 element
node_id_4 = int(line[3:13])
node_id_5 = int(line[13:23])
node_id_6 = int(line[23:33])
node_id_1 = int(line[33:43])
node_id_2 = int(line[43:53])
node_id_3 = int(line[53:63])
elements_penta6[elem] = (node_id_1, node_id_2, node_id_3, node_id_4, node_id_5, node_id_6)
elif elemType == 3: # TETRA4 element
node_id_2 = int(line[3:13])
node_id_1 = int(line[13:23])
node_id_3 = int(line[23:33])
node_id_4 = int(line[33:43])
elements_tetra4[elem] = (node_id_1, node_id_2, node_id_3, node_id_4)
elif elemType == 4 and input_continues is False: # HEXA20 element (1st line)
node_id_5 = int(line[3:13])
node_id_6 = int(line[13:23])
node_id_7 = int(line[23:33])
node_id_8 = int(line[33:43])
node_id_1 = int(line[43:53])
node_id_2 = int(line[53:63])
node_id_3 = int(line[63:73])
node_id_4 = int(line[73:83])
node_id_13 = int(line[83:93])
node_id_14 = int(line[93:103])
# node order fits with node order in writeAbaqus() in FemMesh.cpp
if elemType == 1:
# C3D8 CalculiX --> hexa8 FreeCAD
# N6, N7, N8, N5, N2, N3, N4, N1
nd1 = int(line[3:13])
nd2 = int(line[13:23])
nd3 = int(line[23:33])
nd4 = int(line[33:43])
nd5 = int(line[43:53])
nd6 = int(line[53:63])
nd7 = int(line[63:73])
nd8 = int(line[73:83])
elements_hexa8[elem] = (nd6, nd7, nd8, nd5, nd2, nd3, nd4, nd1)
elif elemType == 2:
# C3D6 Calculix --> penta6 FreeCAD
# N5, N6, N4, N2, N3, N1
nd1 = int(line[3:13])
nd2 = int(line[13:23])
nd3 = int(line[23:33])
nd4 = int(line[33:43])
nd5 = int(line[43:53])
nd6 = int(line[53:63])
elements_penta6[elem] = (nd5, nd6, nd4, nd2, nd3, nd1)
elif elemType == 3:
# C3D4 Calculix --> tetra4 FreeCAD
# N2, N1, N3, N4
nd1 = int(line[3:13])
nd2 = int(line[13:23])
nd3 = int(line[23:33])
nd4 = int(line[33:43])
elements_tetra4[elem] = (nd2, nd1, nd3, nd4)
elif elemType == 4 and input_continues is False:
# first line
# C3D20 Calculix --> hexa20 FreeCAD
# N6, N7, N8, N5, N2, N3, N4, N1, N14, N15, N16, N13, N10, N11, N12, N9, N18, N19, N20, N17
nd1 = int(line[3:13])
nd2 = int(line[13:23])
nd3 = int(line[23:33])
nd4 = int(line[33:43])
nd5 = int(line[43:53])
nd6 = int(line[53:63])
nd7 = int(line[63:73])
nd8 = int(line[73:83])
nd9 = int(line[83:93])
nd10 = int(line[93:103])
input_continues = True
elif elemType == 4 and input_continues is True: # HEXA20 element (2nd line)
node_id_15 = int(line[3:13])
node_id_16 = int(line[13:23])
node_id_9 = int(line[23:33])
node_id_10 = int(line[33:43])
node_id_11 = int(line[43:53])
node_id_12 = int(line[53:63])
node_id_17 = int(line[63:73])
node_id_18 = int(line[73:83])
node_id_19 = int(line[83:93])
node_id_20 = int(line[93:103])
elif elemType == 4 and input_continues is True:
# second line
nd11 = int(line[3:13])
nd12 = int(line[13:23])
nd13 = int(line[23:33])
nd14 = int(line[33:43])
nd15 = int(line[43:53])
nd16 = int(line[53:63])
nd17 = int(line[63:73])
nd18 = int(line[73:83])
nd19 = int(line[83:93])
nd20 = int(line[93:103])
input_continues = False
elements_hexa20[elem] = (node_id_1, node_id_2, node_id_3, node_id_4, node_id_5, node_id_6, node_id_7, node_id_8, node_id_9, node_id_10,
node_id_11, node_id_12, node_id_13, node_id_14, node_id_15, node_id_16, node_id_17, node_id_18, node_id_19, node_id_20)
elif elemType == 5 and input_continues is False: # PENTA15 element (1st line)
node_id_4 = int(line[3:13])
node_id_5 = int(line[13:23])
node_id_6 = int(line[23:33])
node_id_1 = int(line[33:43])
node_id_2 = int(line[43:53])
node_id_3 = int(line[53:63])
node_id_10 = int(line[63:73])
node_id_11 = int(line[73:83])
node_id_12 = int(line[83:93])
node_id_13 = int(line[93:103])
elements_hexa20[elem] = (nd6, nd7, nd8, nd5, nd2, nd3, nd4, nd1, nd14, nd15,
nd16, nd13, nd10, nd11, nd12, nd9, nd18, nd19, nd20, nd17)
elif elemType == 5 and input_continues is False:
# first line
# C3D15 Calculix --> penta15 FreeCAD
# N5, N6, N4, N2, N3, N1, N11, N12, N10, N8, N9, N7, N14, N15, N13
nd1 = int(line[3:13])
nd2 = int(line[13:23])
nd3 = int(line[23:33])
nd4 = int(line[33:43])
nd5 = int(line[43:53])
nd6 = int(line[53:63])
nd7 = int(line[63:73])
nd8 = int(line[73:83])
nd9 = int(line[83:93])
nd10 = int(line[93:103])
input_continues = True
elif elemType == 5 and input_continues is True: # PENTA15 element (2nd line)
node_id_14 = int(line[3:13])
node_id_15 = int(line[13:23])
node_id_7 = int(line[23:33])
node_id_8 = int(line[33:43])
node_id_9 = int(line[43:53])
elif elemType == 5 and input_continues is True:
# second line
nd11 = int(line[3:13])
nd12 = int(line[13:23])
nd13 = int(line[23:33])
nd14 = int(line[33:43])
nd15 = int(line[43:53])
input_continues = False
elements_penta15[elem] = (node_id_1, node_id_2, node_id_3, node_id_4, node_id_5, node_id_6, node_id_7, node_id_8, node_id_9, node_id_10,
node_id_11, node_id_12, node_id_13, node_id_14, node_id_15)
elif elemType == 6: # TETRA10 element
node_id_2 = int(line[3:13])
node_id_1 = int(line[13:23])
node_id_3 = int(line[23:33])
node_id_4 = int(line[33:43])
node_id_5 = int(line[43:53])
node_id_7 = int(line[53:63])
node_id_6 = int(line[63:73])
node_id_9 = int(line[73:83])
node_id_8 = int(line[83:93])
node_id_10 = int(line[93:103])
elements_tetra10[elem] = (node_id_1, node_id_2, node_id_3, node_id_4, node_id_5, node_id_6, node_id_7, node_id_8, node_id_9, node_id_10)
elif elemType == 7: # TRIA3 element
node_id_1 = int(line[3:13])
node_id_2 = int(line[13:23])
node_id_3 = int(line[23:33])
elements_tria3[elem] = (node_id_1, node_id_2, node_id_3)
elif elemType == 8: # TRIA6 element
node_id_1 = int(line[3:13])
node_id_2 = int(line[13:23])
node_id_3 = int(line[23:33])
node_id_4 = int(line[33:43])
node_id_5 = int(line[43:53])
node_id_6 = int(line[53:63])
elements_tria6[elem] = (node_id_1, node_id_2, node_id_3, node_id_4, node_id_5, node_id_6)
elif elemType == 9: # QUAD4 element
node_id_1 = int(line[3:13])
node_id_2 = int(line[13:23])
node_id_3 = int(line[23:33])
node_id_4 = int(line[33:43])
elements_quad4[elem] = (node_id_1, node_id_2, node_id_3, node_id_4)
elif elemType == 10: # QUAD8 element
node_id_1 = int(line[3:13])
node_id_2 = int(line[13:23])
node_id_3 = int(line[23:33])
node_id_4 = int(line[33:43])
node_id_5 = int(line[43:53])
node_id_6 = int(line[53:63])
node_id_7 = int(line[63:73])
node_id_8 = int(line[73:83])
elements_quad8[elem] = (node_id_1, node_id_2, node_id_3, node_id_4, node_id_5, node_id_6, node_id_7, node_id_8)
elif elemType == 11: # SEG2 element
node_id_1 = int(line[3:13])
node_id_2 = int(line[13:23])
elements_seg2[elem] = (node_id_1, node_id_2)
elements_penta15[elem] = (nd5, nd6, nd4, nd2, nd3, nd1, nd11, nd12, nd10, nd8,
nd9, nd7, nd14, nd15, nd13)
elif elemType == 6:
# C3D10 Calculix --> tetra10 FreeCAD
# N2, N1, N3, N4, N5, N7, N6, N9, N8, N10
nd1 = int(line[3:13])
nd2 = int(line[13:23])
nd3 = int(line[23:33])
nd4 = int(line[33:43])
nd5 = int(line[43:53])
nd6 = int(line[53:63])
nd7 = int(line[63:73])
nd8 = int(line[73:83])
nd9 = int(line[83:93])
nd10 = int(line[93:103])
elements_tetra10[elem] = (nd2, nd1, nd3, nd4, nd5, nd7, nd6, nd9, nd8, nd10)
elif elemType == 7:
# S3 Calculix --> tria3 FreeCAD
# N1, N2, N3
nd1 = int(line[3:13])
nd2 = int(line[13:23])
nd3 = int(line[23:33])
elements_tria3[elem] = (nd1, nd2, nd3)
elif elemType == 8:
# S6 CalculiX --> tria6 FreeCAD
# N1, N2, N3, N4, N5, N6
nd1 = int(line[3:13])
nd2 = int(line[13:23])
nd3 = int(line[23:33])
nd4 = int(line[33:43])
nd5 = int(line[43:53])
nd6 = int(line[53:63])
elements_tria6[elem] = (nd1, nd2, nd3, nd4, nd5, nd6)
elif elemType == 9:
# S4 CalculiX --> quad4 FreeCAD
# N1, N2, N3, N4
nd1 = int(line[3:13])
nd2 = int(line[13:23])
nd3 = int(line[23:33])
nd4 = int(line[33:43])
elements_quad4[elem] = (nd1, nd2, nd3, nd4)
elif elemType == 10:
# S8 CalculiX --> quad8 FreeCAD
# N1, N2, N3, N4, N5, N6, N7, N8
nd1 = int(line[3:13])
nd2 = int(line[13:23])
nd3 = int(line[23:33])
nd4 = int(line[33:43])
nd5 = int(line[43:53])
nd6 = int(line[53:63])
nd7 = int(line[63:73])
nd8 = int(line[73:83])
elements_quad8[elem] = (nd1, nd2, nd3, nd4, nd5, nd6, nd7, nd8)
elif elemType == 11:
# B31 CalculiX --> seg2 FreeCAD
# N1, N2
nd1 = int(line[3:13])
nd2 = int(line[13:23])
elements_seg2[elem] = (nd1, nd2)
#Check if we found new eigenmode
if line[5:10] == "PMODE":