diff --git a/src/Mod/Fem/App/FemMesh.cpp b/src/Mod/Fem/App/FemMesh.cpp index a468bbae5..6533de6e3 100644 --- a/src/Mod/Fem/App/FemMesh.cpp +++ b/src/Mod/Fem/App/FemMesh.cpp @@ -891,9 +891,16 @@ void FemMesh::writeABAQUS(const std::string &Filename) const static std::map faceTypeMap; static std::map 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 b31 = boost::assign::list_of(0)(1); + // + // seg3 FreeCAD --> CalculiX B32 + // N1, N3, N2 std::vector 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 s3 = boost::assign::list_of(0)(1)(2); + // + // tria6 FreeCAD --> S6 CalculiX + // N1, N2, N3, N4, N5, N6 std::vector s6 = boost::assign::list_of(0)(1)(2)(3)(4)(5); - // FIXME: get the right order - std::vector s4r; - std::vector s8r; + // + // quad4 FreeCAD --> S4 CalculiX + // N1, N2, N3, N4 + std::vector s4 = boost::assign::list_of(0)(1)(2)(3); + // + // quad8 FreeCAD --> S8 CalculiX + // N1, N2, N3, N4, N5, N6, N7, N8 + std::vector 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 c3d4 = boost::assign::list_of(0)(3)(1)(2); //std::vector 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 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 c3d10 = boost::assign::list_of(1)(0)(2)(3)(4)(6)(5)(8)(7)(9); - // FIXME: get the right order - std::vector c3d6; - std::vector c3d8; - std::vector c3d15; - std::vector 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 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 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 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 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 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 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::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::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::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::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 } + diff --git a/src/Mod/Fem/ccxFrdReader.py b/src/Mod/Fem/ccxFrdReader.py index 8a32a5dfb..fe15c2fc3 100644 --- a/src/Mod/Fem/ccxFrdReader.py +++ b/src/Mod/Fem/ccxFrdReader.py @@ -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":