@@ -1929,7 +1929,12 @@ void FemMesh::read(const char* FileName)
1929
1929
}
1930
1930
}
1931
1931
1932
- void FemMesh::writeABAQUS (const std::string& Filename, int elemParam, bool groupParam) const
1932
+ void FemMesh::writeABAQUS (const std::string& Filename,
1933
+ int elemParam,
1934
+ bool groupParam,
1935
+ ABAQUS_VolumeVariant volVariant,
1936
+ ABAQUS_FaceVariant faceVariant,
1937
+ ABAQUS_EdgeVariant edgeVariant) const
1933
1938
{
1934
1939
/*
1935
1940
* elemParam:
@@ -1940,121 +1945,222 @@ void FemMesh::writeABAQUS(const std::string& Filename, int elemParam, bool group
1940
1945
* groupParam:
1941
1946
* true = write group data
1942
1947
* false = do not write group data
1948
+
1949
+ * volVariant, faceVariant, edgeVariant:
1950
+ * Element type according to availability in CalculiX
1943
1951
*/
1944
1952
1945
- static std::map<std::string, std::vector<int >> elemOrderMap;
1946
- static std::map<int , std::string> edgeTypeMap;
1947
- static std::map<int , std::string> faceTypeMap;
1948
- static std::map<int , std::string> volTypeMap;
1949
- if (elemOrderMap.empty ()) {
1950
- // node order fits with node order in importCcxFrdResults.py module to import
1951
- // CalculiX result meshes
1952
-
1953
- // dimension 1
1954
- //
1955
- // seg2 FreeCAD --> CalculiX B31
1956
- // N1, N2
1957
- std::vector<int > b31 = boost::assign::list_of (0 )(1 );
1958
- //
1959
- // seg3 FreeCAD --> CalculiX B32
1960
- // N1, N3, N2
1961
- std::vector<int > b32 = boost::assign::list_of (0 )(2 )(1 );
1962
-
1963
- elemOrderMap.insert (std::make_pair (" B31" , b31));
1964
- edgeTypeMap.insert (std::make_pair (elemOrderMap[" B31" ].size (), " B31" ));
1965
- elemOrderMap.insert (std::make_pair (" B32" , b32));
1966
- edgeTypeMap.insert (std::make_pair (elemOrderMap[" B32" ].size (), " B32" ));
1967
-
1968
- // dimension 2
1969
- //
1970
- // tria3 FreeCAD --> S3 CalculiX
1971
- // N1, N2, N3
1972
- std::vector<int > s3 = boost::assign::list_of (0 )(1 )(2 );
1973
- //
1974
- // tria6 FreeCAD --> S6 CalculiX
1975
- // N1, N2, N3, N4, N5, N6
1976
- std::vector<int > s6 = boost::assign::list_of (0 )(1 )(2 )(3 )(4 )(5 );
1977
- //
1978
- // quad4 FreeCAD --> S4 CalculiX
1979
- // N1, N2, N3, N4
1980
- std::vector<int > s4 = boost::assign::list_of (0 )(1 )(2 )(3 );
1981
- //
1982
- // quad8 FreeCAD --> S8 CalculiX
1983
- // N1, N2, N3, N4, N5, N6, N7, N8
1984
- std::vector<int > s8 = boost::assign::list_of (0 )(1 )(2 )(3 )(4 )(5 )(6 )(7 );
1985
-
1986
- elemOrderMap.insert (std::make_pair (" S3" , s3));
1987
- faceTypeMap.insert (std::make_pair (elemOrderMap[" S3" ].size (), " S3" ));
1988
- elemOrderMap.insert (std::make_pair (" S6" , s6));
1989
- faceTypeMap.insert (std::make_pair (elemOrderMap[" S6" ].size (), " S6" ));
1990
- elemOrderMap.insert (std::make_pair (" S4" , s4));
1991
- faceTypeMap.insert (std::make_pair (elemOrderMap[" S4" ].size (), " S4" ));
1992
- elemOrderMap.insert (std::make_pair (" S8" , s8));
1993
- faceTypeMap.insert (std::make_pair (elemOrderMap[" S8" ].size (), " S8" ));
1994
-
1995
- // dimension 3
1996
- //
1997
- // tetras
1998
- // master 0.14 release
1999
- // changed to this in August 2013, committed by juergen (jriedel)
2000
- // https://github.com/FreeCAD/FreeCAD/commit/af56b324b9566b20f3b6e7880c29354c1dbe7a99
2001
- // std::vector<int> c3d4 = boost::assign::list_of(0)(3)(1)(2);
2002
- // std::vector<int> c3d10 = boost::assign::list_of(0)(2)(1)(3)(6)(5)(4)(7)(9)(8);
2003
-
2004
- // since master 0.15
2005
- // added by werner (wmayer) March 2015,
2006
- // https://forum.freecad.org/viewtopic.php?f=18&t=10110&start=10#p81681
2007
- // https://github.com/FreeCAD/FreeCAD/commit/5d159f5cf352a93b1aff4fb7b82e8b747ee4f35b
2008
- // https://github.com/FreeCAD/FreeCAD/commit/b007bd19e4e4608caa4cdad350a9f480287fac6b
2009
- // tetra4 FreeCAD --> C3D4 CalculiX
2010
- // N2, N1, N3, N4
2011
- std::vector<int > c3d4 = boost::assign::list_of (1 )(0 )(2 )(3 );
2012
- // tetra10: FreeCAD --> C3D10 CalculiX
2013
- // N2, N1, N3, N4, N5, N7, N6, N9, N8, N10
2014
- std::vector<int > c3d10 = boost::assign::list_of (1 )(0 )(2 )(3 )(4 )(6 )(5 )(8 )(7 )(9 );
1953
+ std::map<std::string, std::string> variants;
1954
+
1955
+ // volume elements
1956
+ variants[" Tetra4" ] = " C3D4" ;
1957
+ variants[" Penta6" ] = " C3D6" ;
1958
+ variants[" Hexa8" ] = " C3D8" ;
1959
+ variants[" Tetra10" ] = " C3D10" ;
1960
+ variants[" Penta15" ] = " C3D15" ;
1961
+ variants[" Hexa20" ] = " C3D20" ;
1962
+
1963
+ switch (volVariant) {
1964
+ case ABAQUS_VolumeVariant::Standard:
1965
+ break ;
1966
+ case ABAQUS_VolumeVariant::Reduced:
1967
+ variants[" Hexa8" ] = " C3D8R" ;
1968
+ variants[" Hexa20" ] = " C3D20R" ;
1969
+ break ;
1970
+ case ABAQUS_VolumeVariant::Incompatible:
1971
+ variants[" Hexa8" ] = " C3D8I" ;
1972
+ break ;
1973
+ case ABAQUS_VolumeVariant::Modified:
1974
+ variants[" Tetra10" ] = " C3D10T" ;
1975
+ break ;
1976
+ case ABAQUS_VolumeVariant::Fluid:
1977
+ variants[" Tetra4" ] = " F3D4" ;
1978
+ variants[" Penta6" ] = " F3D6" ;
1979
+ variants[" Hexa8" ] = " F3D8" ;
1980
+ break ;
1981
+ }
2015
1982
2016
- // tetra node order for the system which is used for hexa8, hexa20, penta6 and penda15
2017
- // be careful with activating because of method getccxVolumesByFace())
2018
- // tetra4 FreeCAD --> C3D4 CalculiX
2019
- // N2, N3, N4, N1
2020
- // std::vector<int> c3d4 = boost::assign::list_of(1)(2)(3)(0);
2021
- //
2022
- // tetra10: FreeCAD --> C3D10 CalculiX
2023
- // N2, N3, N4, N1, N6, N10, N9, N5, N7, N8
2024
- // std::vector<int> c3d10 = boost::assign::list_of(1)(2)(3)(0)(5)(9)(8)(4)(6)(7);
2025
-
2026
- // hexa8 FreeCAD --> C3D8 CalculiX
2027
- // N6, N7, N8, N5, N2, N3, N4, N1
2028
- std::vector<int > c3d8 = boost::assign::list_of (5 )(6 )(7 )(4 )(1 )(2 )(3 )(0 );
2029
- //
2030
- // hexa20 FreeCAD --> C3D20 CalculiX
2031
- // N6, N7, N8, N5, N2, N3, N4, N1, N14, N15, N16, N13, N10, N11, N12, N9, N18, N19, N20, N17
2032
- std::vector<int > c3d20 = boost::assign::list_of (5 )(6 )(7 )(4 )(1 )(2 )(3 )(0 )(13 )(14 )(15 )(12 )(9 )(
2033
- 10 )(11 )(8 )(17 )(18 )(19 )(16 );
2034
- //
2035
- // penta6 FreeCAD --> C3D6 CalculiX
2036
- // N5, N6, N4, N2, N3, N1
2037
- std::vector<int > c3d6 = boost::assign::list_of (4 )(5 )(3 )(1 )(2 )(0 );
2038
- //
2039
- // penta15 FreeCAD --> C3D15 CalculiX
2040
- // N5, N6, N4, N2, N3, N1, N11, N12, N10, N8, N9, N7, N14, N15, N13
2041
- std::vector<int > c3d15 =
2042
- boost::assign::list_of (4 )(5 )(3 )(1 )(2 )(0 )(10 )(11 )(9 )(7 )(8 )(6 )(13 )(14 )(12 );
2043
-
2044
- elemOrderMap.insert (std::make_pair (" C3D4" , c3d4));
2045
- volTypeMap.insert (std::make_pair (elemOrderMap[" C3D4" ].size (), " C3D4" ));
2046
- elemOrderMap.insert (std::make_pair (" C3D10" , c3d10));
2047
- volTypeMap.insert (std::make_pair (elemOrderMap[" C3D10" ].size (), " C3D10" ));
2048
- elemOrderMap.insert (std::make_pair (" C3D8" , c3d8));
2049
- volTypeMap.insert (std::make_pair (elemOrderMap[" C3D8" ].size (), " C3D8" ));
2050
- elemOrderMap.insert (std::make_pair (" C3D20" , c3d20));
2051
- volTypeMap.insert (std::make_pair (elemOrderMap[" C3D20" ].size (), " C3D20" ));
2052
- elemOrderMap.insert (std::make_pair (" C3D6" , c3d6));
2053
- volTypeMap.insert (std::make_pair (elemOrderMap[" C3D6" ].size (), " C3D6" ));
2054
- elemOrderMap.insert (std::make_pair (" C3D15" , c3d15));
2055
- volTypeMap.insert (std::make_pair (elemOrderMap[" C3D15" ].size (), " C3D15" ));
1983
+ // face elements
1984
+ switch (faceVariant) {
1985
+ case ABAQUS_FaceVariant::Shell:
1986
+ variants[" Tria3" ] = " S3" ;
1987
+ variants[" Quad4" ] = " S4" ;
1988
+ variants[" Tria6" ] = " S6" ;
1989
+ variants[" Quad8" ] = " S8" ;
1990
+ break ;
1991
+ case ABAQUS_FaceVariant::Shell_Reduced:
1992
+ variants[" Tria3" ] = " S3" ;
1993
+ variants[" Quad4" ] = " S4R" ;
1994
+ variants[" Tria6" ] = " S6" ;
1995
+ variants[" Quad8" ] = " S8R" ;
1996
+ break ;
1997
+ case ABAQUS_FaceVariant::Membrane:
1998
+ variants[" Tria3" ] = " M3D3" ;
1999
+ variants[" Quad4" ] = " M3D4" ;
2000
+ variants[" Tria6" ] = " M3D6" ;
2001
+ variants[" Quad8" ] = " M3D8" ;
2002
+ break ;
2003
+ case ABAQUS_FaceVariant::Membrane_Reduced:
2004
+ variants[" Tria3" ] = " M3D3" ;
2005
+ variants[" Quad4" ] = " M3D4R" ;
2006
+ variants[" Tria6" ] = " M3D6" ;
2007
+ variants[" Quad8" ] = " M3D8R" ;
2008
+ break ;
2009
+ case ABAQUS_FaceVariant::Stress:
2010
+ variants[" Tria3" ] = " CPS3" ;
2011
+ variants[" Quad4" ] = " CPS4" ;
2012
+ variants[" Tria6" ] = " CPS6" ;
2013
+ variants[" Quad8" ] = " CPS8" ;
2014
+ break ;
2015
+ case ABAQUS_FaceVariant::Stress_Reduced:
2016
+ variants[" Tria3" ] = " CPS3" ;
2017
+ variants[" Quad4" ] = " CPS4R" ;
2018
+ variants[" Tria6" ] = " CPS6" ;
2019
+ variants[" Quad8" ] = " CPS8R" ;
2020
+ break ;
2021
+ case ABAQUS_FaceVariant::Strain:
2022
+ variants[" Tria3" ] = " CPE3" ;
2023
+ variants[" Quad4" ] = " CPE4" ;
2024
+ variants[" Tria6" ] = " CPE6" ;
2025
+ variants[" Quad8" ] = " CPE8" ;
2026
+ break ;
2027
+ case ABAQUS_FaceVariant::Strain_Reduced:
2028
+ variants[" Tria3" ] = " CPE3" ;
2029
+ variants[" Quad4" ] = " CPE4R" ;
2030
+ variants[" Tria6" ] = " CPE6" ;
2031
+ variants[" Quad8" ] = " CPE8R" ;
2032
+ break ;
2033
+ case ABAQUS_FaceVariant::Axisymmetric:
2034
+ variants[" Tria3" ] = " CAX3" ;
2035
+ variants[" Quad4" ] = " CAX4" ;
2036
+ variants[" Tria6" ] = " CAX6" ;
2037
+ variants[" Quad8" ] = " CAX8" ;
2038
+ break ;
2039
+ case ABAQUS_FaceVariant::Axisymmetric_Reduced:
2040
+ variants[" Tria3" ] = " CAX3" ;
2041
+ variants[" Quad4" ] = " CAX4R" ;
2042
+ variants[" Tria6" ] = " CAX6" ;
2043
+ variants[" Quad8" ] = " CAX8R" ;
2044
+ break ;
2056
2045
}
2057
2046
2047
+ // edge elements
2048
+ switch (edgeVariant) {
2049
+ case ABAQUS_EdgeVariant::Beam:
2050
+ variants[" Seg2" ] = " B31" ;
2051
+ variants[" Seg3" ] = " B32" ;
2052
+ break ;
2053
+ case ABAQUS_EdgeVariant::Beam_Reduced:
2054
+ variants[" Seg2" ] = " B31R" ;
2055
+ variants[" Seg3" ] = " B32R" ;
2056
+ break ;
2057
+ case ABAQUS_EdgeVariant::Truss:
2058
+ variants[" Seg2" ] = " T3D2" ;
2059
+ variants[" Seg3" ] = " T3D3" ;
2060
+ break ;
2061
+ case ABAQUS_EdgeVariant::Network:
2062
+ variants[" Seg2" ] = " B31" ;
2063
+ variants[" Seg3" ] = " D" ;
2064
+ break ;
2065
+ }
2066
+
2067
+ std::map<std::string, std::vector<int >> elemOrderMap;
2068
+ std::map<int , std::string> edgeTypeMap;
2069
+ std::map<int , std::string> faceTypeMap;
2070
+ std::map<int , std::string> volTypeMap;
2071
+
2072
+
2073
+ // node order fits with node order in importCcxFrdResults.py module to import
2074
+ // CalculiX result meshes
2075
+
2076
+ // dimension 1
2077
+ //
2078
+ // seg2 FreeCAD --> B31, B31R, T3D2 CalculiX
2079
+ // N1, N2
2080
+ std::vector<int > seg2 = boost::assign::list_of (0 )(1 );
2081
+ //
2082
+ // seg3 FreeCAD --> B32, B32R, T3D3 D CalculiX
2083
+ // N1, N3, N2
2084
+ std::vector<int > seg3 = boost::assign::list_of (0 )(2 )(1 );
2085
+
2086
+ elemOrderMap.insert (std::make_pair (variants[" Seg2" ], seg2));
2087
+ edgeTypeMap.insert (std::make_pair (elemOrderMap[variants[" Seg2" ]].size (), variants[" Seg2" ]));
2088
+ elemOrderMap.insert (std::make_pair (variants[" Seg3" ], seg3));
2089
+ edgeTypeMap.insert (std::make_pair (elemOrderMap[variants[" Seg3" ]].size (), variants[" Seg3" ]));
2090
+
2091
+ // dimension 2
2092
+ //
2093
+ // tria3 FreeCAD --> S3, M3D3, CPS3, CPE3, CAX3 CalculiX
2094
+ // N1, N2, N3
2095
+ std::vector<int > tria3 = boost::assign::list_of (0 )(1 )(2 );
2096
+ //
2097
+ // tria6 FreeCAD --> S6 M3D6, CPS6, CPE6, CAX6 CalculiX
2098
+ // N1, N2, N3, N4, N5, N6
2099
+ std::vector<int > tria6 = boost::assign::list_of (0 )(1 )(2 )(3 )(4 )(5 );
2100
+ //
2101
+ // quad4 FreeCAD --> S4, S4R, M3D4, M3D4R, CPS4, CPS4R, CPE4, CPE4R, CAX4, CAX4R CalculiX
2102
+ // N1, N2, N3, N4
2103
+ std::vector<int > quad4 = boost::assign::list_of (0 )(1 )(2 )(3 );
2104
+ //
2105
+ // quad8 FreeCAD --> S8, S8R, M3D8, M3D8R, CPS8, CPS8R, CPE8, CPE8R, CAX8, CAX8R CalculiX
2106
+ // N1, N2, N3, N4, N5, N6, N7, N8
2107
+ std::vector<int > quad8 = boost::assign::list_of (0 )(1 )(2 )(3 )(4 )(5 )(6 )(7 );
2108
+
2109
+ elemOrderMap.insert (std::make_pair (variants[" Tria3" ], tria3));
2110
+ faceTypeMap.insert (std::make_pair (elemOrderMap[variants[" Tria3" ]].size (), variants[" Tria3" ]));
2111
+ elemOrderMap.insert (std::make_pair (variants[" Tria6" ], tria6));
2112
+ faceTypeMap.insert (std::make_pair (elemOrderMap[variants[" Tria6" ]].size (), variants[" Tria6" ]));
2113
+ elemOrderMap.insert (std::make_pair (variants[" Quad4" ], quad4));
2114
+ faceTypeMap.insert (std::make_pair (elemOrderMap[variants[" Quad4" ]].size (), variants[" Quad4" ]));
2115
+ elemOrderMap.insert (std::make_pair (variants[" Quad8" ], quad8));
2116
+ faceTypeMap.insert (std::make_pair (elemOrderMap[variants[" Quad8" ]].size (), variants[" Quad8" ]));
2117
+
2118
+
2119
+ // dimension 3
2120
+ //
2121
+ // tetra4 FreeCAD --> C3D4, F3D4 CalculiX
2122
+ // N2, N1, N3, N4
2123
+ std::vector<int > tetra4 = boost::assign::list_of (1 )(0 )(2 )(3 );
2124
+ // tetra10: FreeCAD --> C3D10, C3D10T CalculiX
2125
+ // N2, N1, N3, N4, N5, N7, N6, N9, N8, N10
2126
+ std::vector<int > tetra10 = boost::assign::list_of (1 )(0 )(2 )(3 )(4 )(6 )(5 )(8 )(7 )(9 );
2127
+
2128
+ // tetra node order for the system which is used for hexa8, hexa20, penta6 and penta15
2129
+ // be careful with activating because of method getccxVolumesByFace())
2130
+ // hexa8 FreeCAD --> C3D8, C3D8R, C3D8I, F3D8 CalculiX
2131
+ // N6, N7, N8, N5, N2, N3, N4, N1
2132
+ std::vector<int > hexa8 = boost::assign::list_of (5 )(6 )(7 )(4 )(1 )(2 )(3 )(0 );
2133
+ //
2134
+ // hexa20 FreeCAD --> C3D20, C3D20R CalculiX
2135
+ // N6, N7, N8, N5, N2, N3, N4, N1, N14, N15, N16, N13, N10, N11, N12, N9, N18, N19, N20, N17
2136
+ std::vector<int > hexa20 = boost::assign::list_of (5 )(6 )(7 )(4 )(1 )(2 )(3 )(0 )(13 )(14 )(15 )(12 )(9 )(10 )(
2137
+ 11 )(8 )(17 )(18 )(19 )(16 );
2138
+ //
2139
+ // penta6 FreeCAD --> C3D6, F3D6 CalculiX
2140
+ // N5, N6, N4, N2, N3, N1
2141
+ std::vector<int > penta6 = boost::assign::list_of (4 )(5 )(3 )(1 )(2 )(0 );
2142
+ //
2143
+ // penta15 FreeCAD --> C3D15 CalculiX
2144
+ // N5, N6, N4, N2, N3, N1, N11, N12, N10, N8, N9, N7, N14, N15, N13
2145
+ std::vector<int > penta15 =
2146
+ boost::assign::list_of (4 )(5 )(3 )(1 )(2 )(0 )(10 )(11 )(9 )(7 )(8 )(6 )(13 )(14 )(12 );
2147
+
2148
+ elemOrderMap.insert (std::make_pair (variants[" Tetra4" ], tetra4));
2149
+ volTypeMap.insert (std::make_pair (elemOrderMap[variants[" Tetra4" ]].size (), variants[" Tetra4" ]));
2150
+ elemOrderMap.insert (std::make_pair (variants[" Tetra10" ], tetra10));
2151
+ volTypeMap.insert (
2152
+ std::make_pair (elemOrderMap[variants[" Tetra10" ]].size (), variants[" Tetra10" ]));
2153
+ elemOrderMap.insert (std::make_pair (variants[" Hexa8" ], hexa8));
2154
+ volTypeMap.insert (std::make_pair (elemOrderMap[variants[" Hexa8" ]].size (), variants[" Hexa8" ]));
2155
+ elemOrderMap.insert (std::make_pair (variants[" Hexa20" ], hexa20));
2156
+ volTypeMap.insert (std::make_pair (elemOrderMap[variants[" Hexa20" ]].size (), variants[" Hexa20" ]));
2157
+ elemOrderMap.insert (std::make_pair (variants[" Penta6" ], penta6));
2158
+ volTypeMap.insert (std::make_pair (elemOrderMap[variants[" Penta6" ]].size (), variants[" Penta6" ]));
2159
+ elemOrderMap.insert (std::make_pair (variants[" Penta15" ], penta15));
2160
+ volTypeMap.insert (
2161
+ std::make_pair (elemOrderMap[variants[" Penta15" ]].size (), variants[" Penta15" ]));
2162
+
2163
+
2058
2164
// get all data --> Extract Nodes and Elements of the current SMESH datastructure
2059
2165
using VertexMap = std::map<int , Base::Vector3d>;
2060
2166
using NodesMap = std::map<int , std::vector<int >>;
0 commit comments