patme 0.4.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of patme might be problematic. Click here for more details.

Files changed (46) hide show
  1. patme/__init__.py +52 -0
  2. patme/buildtools/__init__.py +7 -0
  3. patme/buildtools/rce_releasecreator.py +336 -0
  4. patme/buildtools/release.py +26 -0
  5. patme/femtools/__init__.py +5 -0
  6. patme/femtools/abqmsgfilechecker.py +137 -0
  7. patme/femtools/fecall.py +1092 -0
  8. patme/geometry/__init__.py +0 -0
  9. patme/geometry/area.py +124 -0
  10. patme/geometry/coordinatesystem.py +635 -0
  11. patme/geometry/intersect.py +284 -0
  12. patme/geometry/line.py +183 -0
  13. patme/geometry/misc.py +420 -0
  14. patme/geometry/plane.py +464 -0
  15. patme/geometry/rotate.py +244 -0
  16. patme/geometry/scale.py +152 -0
  17. patme/geometry/shape2d.py +50 -0
  18. patme/geometry/transformations.py +1831 -0
  19. patme/geometry/translate.py +139 -0
  20. patme/mechanics/__init__.py +4 -0
  21. patme/mechanics/loads.py +435 -0
  22. patme/mechanics/material.py +1260 -0
  23. patme/service/__init__.py +7 -0
  24. patme/service/decorators.py +85 -0
  25. patme/service/duration.py +96 -0
  26. patme/service/exceptionhook.py +104 -0
  27. patme/service/exceptions.py +36 -0
  28. patme/service/io/__init__.py +3 -0
  29. patme/service/io/basewriter.py +122 -0
  30. patme/service/logger.py +375 -0
  31. patme/service/mathutils.py +108 -0
  32. patme/service/misc.py +71 -0
  33. patme/service/moveimports.py +217 -0
  34. patme/service/stringutils.py +419 -0
  35. patme/service/systemutils.py +290 -0
  36. patme/sshtools/__init__.py +3 -0
  37. patme/sshtools/cara.py +435 -0
  38. patme/sshtools/clustercaller.py +420 -0
  39. patme/sshtools/facluster.py +350 -0
  40. patme/sshtools/sshcall.py +168 -0
  41. patme-0.4.4.dist-info/LICENSE +21 -0
  42. patme-0.4.4.dist-info/LICENSES/MIT.txt +9 -0
  43. patme-0.4.4.dist-info/METADATA +168 -0
  44. patme-0.4.4.dist-info/RECORD +46 -0
  45. patme-0.4.4.dist-info/WHEEL +4 -0
  46. patme-0.4.4.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,244 @@
1
+ # Copyright (C) 2020 Deutsches Zentrum fuer Luft- und Raumfahrt(DLR, German Aerospace Center) <www.dlr.de>
2
+ # SPDX-FileCopyrightText: 2022 German Aerospace Center (DLR)
3
+ #
4
+ # SPDX-License-Identifier: MIT
5
+ """
6
+ documentation
7
+ """
8
+ import numpy as np
9
+
10
+ from patme import epsilon
11
+ from patme.geometry.transformations import euler_from_matrix, euler_matrix
12
+ from patme.geometry.translate import Translation
13
+ from patme.service.exceptions import GeometryError, ImproperParameterError
14
+ from patme.service.logger import log
15
+
16
+
17
+ class Rotation(np.ndarray):
18
+ """
19
+ This class describes a rotation in 3D space which is represented by a 3x3 matrix.
20
+
21
+ With this class rotations in 3D space can be created and operations may be performed.
22
+ For that purpose the class inherits from np.ndarray which is a class for storing
23
+ matrix values and performing operations on them. For further details on np.ndarray
24
+ please refer to the numpy/scipy documentation.
25
+
26
+ Rotations are represented by a 3x3 symmetirc rotation matrix.
27
+
28
+ Usage::
29
+
30
+ >>> import numpy as np
31
+ >>> from patme.geometry.rotate import Rotation
32
+ >>> # creating identity rotation
33
+ >>> r=Rotation()
34
+ >>> r
35
+ Rotation([[1., 0., 0.],
36
+ [0., 1., 0.],
37
+ [0., 0., 1.]])
38
+ >>> # creating empty rotation objects for demonstration below
39
+ >>> rx=r.copy()
40
+ >>> ry=r.copy()
41
+ >>> rxy=r.copy()
42
+ >>> # creating rotation by defining angles in radians!
43
+ >>> # by default the rotation is performed in a static reference frame in the
44
+ >>> # order x,y,z. Those 24 rotationstypes may be used: 'sxyz', 'sxyx', 'sxzy',
45
+ >>> # 'sxzx', 'syzx', 'syzy', 'syxz', 'syxy', 'szxy', 'szxz', 'szyx', 'szyz',
46
+ >>> # 'rzyx', 'rxyx', 'ryzx', 'rxzx', 'rxzy', 'ryzy', 'rzxy', 'ryxy', 'ryxz',
47
+ >>> # 'rzxz', 'rxyz'(default), 'rzyz'.
48
+ >>> # The first item represents a static or rotating reference frame respectively.
49
+ >>> # Static reference frame means that also the rotation around the second and thrid
50
+ >>> # angle is performed in reference to the initial rotation. Rotating reference frame
51
+ >>> # means that rotation around the second angle is done in respect to the reference
52
+ >>> # frame that is created by the rotation around the first angle; respectively
53
+ >>> # for the third angle.
54
+ >>> # Additionally a rotation 'sxyz' is equal to 'rzyx' and so on.
55
+ >>> #
56
+ >>> # rotating by 90 degrees by x-coordinate
57
+ >>> rx.angles = [np.pi/2,0,0] # or
58
+ >>> rx.angles = [np.pi/2,0,0,'rxyz']
59
+ >>> rx.round()
60
+ Rotation([[ 1., 0., -0.],
61
+ [-0., 0., -1.],
62
+ [ 0., 1., 0.]])
63
+ >>> # rotating by 90 degrees around x and subsequently by 90 degrees around y
64
+ >>> # with a rotating reference frame
65
+ >>> rxy.angles = [np.pi/2,np.pi/2,0,'rxyz']
66
+ >>> rxy
67
+ Rotation([[ 6.12323400e-17, 0.00000000e+00, 1.00000000e+00],
68
+ [ 1.00000000e+00, 6.12323400e-17, -6.12323400e-17],
69
+ [-6.12323400e-17, 1.00000000e+00, 3.74939946e-33]])
70
+
71
+ >>> # multiplying rotations
72
+ >>> ry.angles = [0,np.pi/2,0,'rxyz']
73
+ >>> ry
74
+ Rotation([[ 6.123234e-17, 0.000000e+00, 1.000000e+00],
75
+ [-0.000000e+00, 1.000000e+00, 0.000000e+00],
76
+ [-1.000000e+00, -0.000000e+00, 6.123234e-17]])
77
+ >>> rx * ry
78
+ Rotation([[ 6.12323400e-17, 0.00000000e+00, 1.00000000e+00],
79
+ [ 1.00000000e+00, 6.12323400e-17, -6.12323400e-17],
80
+ [-6.12323400e-17, 1.00000000e+00, 3.74939946e-33]])
81
+
82
+ >>> # rotating points
83
+ >>> from patme.geometry.translate import Translation
84
+ >>> t = Translation([1,2,0])
85
+ >>> # rotating around x
86
+ >>> rx * t
87
+ Translation([1., 0., 2.])
88
+ >>> # rotating around x and then y with rotating reference frame
89
+ >>> rxy * t
90
+ Translation([0., 1., 2.])
91
+ """
92
+
93
+ __hash__ = object.__hash__
94
+ """hash reimplementation due to definition of __eq__. See __hash__ doc for more details.
95
+ https://docs.python.org/3.4/reference/datamodel.html#object.__hash__"""
96
+
97
+ def __new__(cls, input_array=None):
98
+ """constructing np.ndarray instance. For more information see
99
+ http://docs.scipy.org/doc/numpy/user/basics.subclassing.html#basics-subclassing"""
100
+ # Input array is an already formed ndarray instance
101
+ # We first cast to be our class type
102
+ if input_array is None:
103
+ input_array = np.identity(3, dtype=np.float64)
104
+ if not hasattr(input_array, "shape"):
105
+ input_array = np.asarray(input_array)
106
+ if not input_array.shape == (3, 3):
107
+ raise ImproperParameterError(
108
+ "The given rotation must be a 3x3 matrix like object. Got this instead: " + str(input_array)
109
+ )
110
+ obj = input_array.view(cls)
111
+ # add the new attribute to the created instance
112
+ # Finally, we must return the newly created object:
113
+ return obj
114
+
115
+ def __array_finalize__(self, obj):
116
+ """constructing np.ndarray instance. For more information see
117
+ http://docs.scipy.org/doc/numpy/user/basics.subclassing.html#basics-subclassing"""
118
+ # see InfoArray.__array_finalize__ for comments
119
+ if obj is None:
120
+ return
121
+
122
+ def _isIdentity(self):
123
+ """doc"""
124
+ return np.allclose(self, np.identity(3))
125
+
126
+ def getInverse(self):
127
+ """:return: returns a copy of the inverted array"""
128
+ return np.linalg.inv(self)
129
+
130
+ def setRotationByPoints(self, origin, xCoordinate, xyPlaneCoordinate):
131
+ """doc"""
132
+ if not isinstance(origin, Translation):
133
+ origin = Translation(origin)
134
+ if not isinstance(xCoordinate, Translation):
135
+ xCoordinate = Translation(xCoordinate)
136
+ if not isinstance(xyPlaneCoordinate, Translation):
137
+ xyPlaneCoordinate = Translation(xyPlaneCoordinate)
138
+
139
+ xAxisLocal = xCoordinate - origin
140
+ yxAxisLocal = xyPlaneCoordinate - origin
141
+ if xCoordinate.distance(origin) < epsilon or xyPlaneCoordinate.distance(origin) < epsilon:
142
+ raise GeometryError("Given points are not distinct from each other.")
143
+
144
+ xAxisLocal = xAxisLocal / np.linalg.norm(xAxisLocal, 2)
145
+ zAxisLocal = np.cross(xAxisLocal, yxAxisLocal)
146
+ # check for linear dependency
147
+ if np.linalg.norm(zAxisLocal, 2) < epsilon:
148
+ raise ImproperParameterError("given vectors are linear dependent")
149
+ zAxisLocal = zAxisLocal / np.linalg.norm(zAxisLocal, 2)
150
+
151
+ yAxisLocal = np.cross(xAxisLocal, zAxisLocal) * -1
152
+ yAxisLocal = yAxisLocal / np.linalg.norm(yAxisLocal, 2)
153
+
154
+ self[:, 0] = xAxisLocal
155
+ self[:, 1] = yAxisLocal
156
+ self[:, 2] = zAxisLocal
157
+
158
+ def getPointsByRotation(self, rotation, origin):
159
+ """doc"""
160
+ if not isinstance(origin, Translation):
161
+ origin = Translation(origin)
162
+
163
+ xAxisLocal = Translation(rotation[:, 0])
164
+ yAxisLocal = Translation(rotation[:, 1])
165
+ yCoordinate = yAxisLocal + origin
166
+ xCoordinate = xAxisLocal + origin
167
+
168
+ return [xCoordinate, yCoordinate]
169
+
170
+ def __invert__(self):
171
+ """doc"""
172
+ self[:3, :3] = self.getInverse()
173
+
174
+ def __mul__(self, other):
175
+ """doc"""
176
+ try:
177
+ ret = np.dot(self, other)
178
+ if ret.shape == (3,):
179
+ cls = other.__class__
180
+ if cls is np.ndarray:
181
+ cls = np.array
182
+ return cls(ret)
183
+ else:
184
+ return ret
185
+ except ValueError:
186
+ # possibly multiplication with coordinatesystem
187
+ return np.dot(self, other[:3, :3])
188
+
189
+ def __imul__(self, other):
190
+ """doc"""
191
+ if other.shape == (3,):
192
+ raise GeometryError("Operator *= cannot be used with (rotation, translation) operands!")
193
+ self = self * other
194
+
195
+ def __eq__(self, other):
196
+ """doc"""
197
+ try:
198
+ return np.allclose(self, other)
199
+ except TypeError:
200
+ return False
201
+
202
+ def _setAngles(self, angles):
203
+ """
204
+ :param angles: iterable with at least 3 items: (x,y,z,[rotationtype])
205
+ - the input angles have to be in radians"""
206
+ if len(angles) == 4:
207
+ alpha, beta, gamma, rotationType = angles[:4]
208
+ elif len(angles) == 3:
209
+ alpha, beta, gamma = angles[:3]
210
+ rotationType = "rxyz"
211
+ else:
212
+ log.error("There must be 3 or 4 scalar parameters! Using identity rotation instead")
213
+ alpha, beta, gamma, rotationType = 0, 0, 0, "rxyz"
214
+
215
+ if np.any(np.array([alpha, beta, gamma]) > np.pi * 2):
216
+ log.warning(
217
+ "Rotation object will set angle that is bigger than 2*pi. Maybe the angles are not given in radians!"
218
+ )
219
+
220
+ self.setfield(euler_matrix(alpha, beta, gamma, rotationType)[:3, :3], np.float64)
221
+
222
+ return self
223
+
224
+ def _getAngles(self):
225
+ """returns the 'rxyz' Euler angles"""
226
+ return self.getAngles("rxyz")
227
+
228
+ def getAngles(self, axis):
229
+ """returns the Euler angles depending on the desired axis. See class description
230
+ for details about the axis parameter."""
231
+ return euler_from_matrix(self, axis)
232
+
233
+ angles = property(fset=_setAngles, fget=_getAngles)
234
+
235
+ isIdentity = property(fget=_isIdentity)
236
+
237
+
238
+ if __name__ == "__main__":
239
+ import doctest
240
+
241
+ doctest.testmod()
242
+ # alpha, beta, gamma, rotationType = np.pi*0.25, 0, np.pi*0.5, "rxyz"
243
+ # myArr = trafo.euler_matrix(alpha, beta, gamma, rotationType)[:3, :3]
244
+ # print()
@@ -0,0 +1,152 @@
1
+ # Copyright (C) 2020 Deutsches Zentrum fuer Luft- und Raumfahrt(DLR, German Aerospace Center) <www.dlr.de>
2
+ # SPDX-FileCopyrightText: 2022 German Aerospace Center (DLR)
3
+ #
4
+ # SPDX-License-Identifier: MIT
5
+ """
6
+ documentation
7
+ """
8
+ import numpy as np
9
+
10
+ from patme.service.exceptions import GeometryError, ImproperParameterError
11
+
12
+
13
+ class Scaling(np.ndarray):
14
+ """
15
+ This class describes a scaling in 3D space which is represented by a 3x3 matrix.
16
+
17
+ With this class scalings in 3D space can be created and operations may be performed.
18
+ For that purpose the class inherits from np.ndarray which is a class for storing
19
+ matrix values and performing operations on them. For further details on np.ndarray
20
+ please refer to the numpy/scipy documentation.
21
+
22
+ Scalings are represented by a 3x3 diagonal scaling matrix.
23
+
24
+ Usage::
25
+
26
+ >>> import numpy as np
27
+ >>> from patme.geometry.scale import Scaling
28
+ >>> # creating identity Scaling
29
+ >>> s=Scaling()
30
+ >>> s
31
+ Scaling([[1., 0., 0.],
32
+ [0., 1., 0.],
33
+ [0., 0., 1.]])
34
+ >>> # creating empty scaling objects for demonstration below
35
+ >>> sx=s.copy()
36
+ >>> sxy=s.copy()
37
+ >>> # creating scaling by defining scaling factors!
38
+ >>> # scaling by 2.0 by x-coordinate
39
+ >>> sx.factors = (2.0,1.0,1.0)
40
+ >>> sx
41
+ Scaling([[2., 0., 0.],
42
+ [0., 1., 0.],
43
+ [0., 0., 1.]])
44
+ >>> # scaling by 2.0 by x-, y-coordinate and z-coordinate
45
+ >>> sxyz=s.copy()
46
+ >>> sxyz.factors = (2.0,2.0,2.0)
47
+ >>> sxyz
48
+ Scaling([[2., 0., 0.],
49
+ [0., 2., 0.],
50
+ [0., 0., 2.]])
51
+
52
+ >>> # multiplying scalings
53
+ >>> sx * sxyz
54
+ Scaling([[4., 0., 0.],
55
+ [0., 2., 0.],
56
+ [0., 0., 2.]])
57
+
58
+ >>> # scaling points
59
+ >>> from patme.geometry.translate import Translation
60
+ >>> t = Translation([1,2,0])
61
+ >>> # scaling in x
62
+ >>> sx * t
63
+ Translation([2., 2., 0.])
64
+ >>> # scaling in all directions
65
+ >>> sxyz * t
66
+ Translation([2., 4., 0.])
67
+ """
68
+
69
+ __hash__ = object.__hash__
70
+ """hash reimplementation due to definition of __eq__. See __hash__ doc for more details.
71
+ https://docs.python.org/3.4/reference/datamodel.html#object.__hash__"""
72
+
73
+ def __new__(cls, input_array=None):
74
+ """constructing np.ndarray instance. For more information see
75
+ http://docs.scipy.org/doc/numpy/user/basics.subclassing.html#basics-subclassing"""
76
+ # Input array is an already formed ndarray instance
77
+ # We first cast to be our class type
78
+ if input_array is None:
79
+ input_array = np.identity(3, dtype=np.float64)
80
+ if not hasattr(input_array, "shape"):
81
+ input_array = np.asarray(input_array)
82
+ if not input_array.shape == (3, 3):
83
+ raise ImproperParameterError(
84
+ "The given scaling must be a 3x3 matrix like object. Got this instead: " + str(input_array)
85
+ )
86
+ obj = input_array.view(cls)
87
+ # add the new attribute to the created instance
88
+ # Finally, we must return the newly created object:
89
+ return obj
90
+
91
+ def __array_finalize__(self, obj):
92
+ """constructing np.ndarray instance. For more information see
93
+ http://docs.scipy.org/doc/numpy/user/basics.subclassing.html#basics-subclassing"""
94
+ # see InfoArray.__array_finalize__ for comments
95
+ if obj is None:
96
+ return
97
+ """ID of the Point within the FEM"""
98
+
99
+ def isIdentity(self):
100
+ """doc"""
101
+ return np.allclose(self, np.identity(3, dtype=np.float64))
102
+
103
+ def getInverse(self):
104
+ """:return: returns a copy of the inverted array"""
105
+ return np.linalg.inv(self)
106
+
107
+ def __invert__(self):
108
+ """doc"""
109
+ self[:3, :3] = self.getInverse()
110
+
111
+ def __mul__(self, other):
112
+ """doc"""
113
+ try:
114
+ ret = np.dot(self, other)
115
+ if ret.shape == (3,):
116
+ cls = other.__class__
117
+ if cls is np.ndarray:
118
+ cls = np.array
119
+ return cls(ret)
120
+ return ret
121
+ except ValueError: # possibly multiplication with coordinatesystem
122
+ return np.dot(self, other[:3, :3])
123
+
124
+ def __imul__(self, other):
125
+ """doc"""
126
+ if other.shape == (3,):
127
+ raise GeometryError("Operator *= cannot be used with (rotation, translation) operands!")
128
+ self = self * other
129
+
130
+ def __eq__(self, other):
131
+ """doc"""
132
+ try:
133
+ return np.allclose(self, other)
134
+ except TypeError:
135
+ return False
136
+
137
+ def _getScaling(self):
138
+ """doc"""
139
+ return tuple(np.diag(self[:3, :3]))
140
+
141
+ def _setScaling(self, factors):
142
+ """doc"""
143
+ self.setfield(np.diag(factors[:3]), np.float64)
144
+ return self
145
+
146
+ factors = property(fget=_getScaling, fset=_setScaling)
147
+
148
+
149
+ if __name__ == "__main__":
150
+ import doctest
151
+
152
+ doctest.testmod()
@@ -0,0 +1,50 @@
1
+ # Copyright (C) 2020 Deutsches Zentrum fuer Luft- und Raumfahrt(DLR, German Aerospace Center) <www.dlr.de>
2
+ # SPDX-FileCopyrightText: 2022 German Aerospace Center (DLR)
3
+ #
4
+ # SPDX-License-Identifier: MIT
5
+ """methods for 2d shapes"""
6
+
7
+ import numpy as np
8
+
9
+ from patme import epsilon
10
+ from patme.geometry.rotate import Rotation
11
+
12
+
13
+ def getSuperEllipseCoords(
14
+ halfAxisHoriz, halfAxisVert, ellipseParamHoriz, ellipseParamVert, ellipseRotationAngle, samplePointsEllipse
15
+ ):
16
+ """
17
+
18
+ :param halfAxisHoriz: horizontal half axis
19
+ :param halfAxisVert: vertical half axis
20
+ :param ellipseParamHoriz: horizontal ellipse power parameter
21
+ :param ellipseParamVert: vertical ellipse power parameter
22
+ :param ellipseRotationAngle: rotation in deg of the ellipse
23
+ :param samplePointsEllipse: number of sample points of the ellipse
24
+ :return: np array of shape (samplePointsEllipse, 2) with ellipse coords
25
+ """
26
+ ellipse = np.ones((samplePointsEllipse, 3))
27
+
28
+ angles = np.linspace(0, 2 * np.pi, samplePointsEllipse, endpoint=False)
29
+
30
+ ellipse[:, 0] = _calcPowerForEllipse(np.cos, halfAxisHoriz, angles, ellipseParamHoriz)
31
+ ellipse[:, 1] = _calcPowerForEllipse(np.sin, halfAxisVert, angles, ellipseParamVert)
32
+
33
+ # rotate ellipse
34
+ if abs(ellipseRotationAngle) > epsilon:
35
+ rot = Rotation()
36
+ rot.angles = (0, 0, np.deg2rad(ellipseRotationAngle))
37
+ ellipse = np.dot(rot, ellipse.T).T
38
+ ellipse = ellipse[:, :2]
39
+
40
+ return ellipse
41
+
42
+
43
+ def _calcPowerForEllipse(sinOrCosFunc, halfAxis, angles, ellipseParameter):
44
+ """The power calculation for negative values does not work for float exponents. Use a workaround for it."""
45
+ sinOrCos = sinOrCosFunc(angles)
46
+ sinOrCosIsNeg = sinOrCos < 0.0
47
+ sinOrCos[sinOrCosIsNeg] *= -1
48
+ ellipse = halfAxis * np.power(sinOrCos, 2.0 / ellipseParameter)
49
+ ellipse[sinOrCosIsNeg] *= -1
50
+ return ellipse