pyyeti.nastran.n2p.getcoordinates

pyyeti.nastran.n2p.getcoordinates(uset, gid, csys, coordref=None)[source]

Get coordinates of a grid or location in a specified coordinate system.

Parameters:
  • uset (pandas DataFrame) – A DataFrame as output by pyyeti.nastran.op2.OP2.rdn2cop2()

  • gid (integer, 1d array_like, or 2d array_like) – If integer, it is a grid id in uset. If 1d array_like, it is a list of integer grid ids in uset. If 2d array_like, it must have 3 columns and each row specifies [x, y, z] location in basic.

  • csys (integer or 4x3 matrix) – Specifies coordinate system to get coordinates of gid in. If integer, it is the id of the coordinate system which must be defined in either uset or coordref (unless it is 0). If a 4x3 matrix, it completely defines the coordinate system:

    [ cid type reference_id ]
    [ Ax   Ay   Az          ]
    [ Bx   By   Bz          ]
    [ Cx   Cy   Cz          ]
    

    See help on addgrid() for more information on the 4x3.

  • coordref (dictionary or None; optional) – If None, this input is ignored. Otherwise, it is a read/write dictionary with the keys being the coordinate system id and the values being the 5x3 matrix returned below. For speed reasons, this routine will look in coordref before uset for a coordinate system. Can be empty.

Returns:

coords (ndarray) –

3-element ndarray of location in csys:

- Rectangular: [x, y, z]
- Cylindrical: [R, theta, z]    (theta is in deg)
- Spherical:   [R, theta, phi]  (theta and phi are in deg)

Notes

Coordinate conversions from global to basic are (where [xo; yo; zo] is the coordinate system location in basic and T is the coordinate transform to basic):

Rectangular (type = 1):

[xb; yb; zb] = T*[x; y; z] + [xo; yo; zo]
\[\begin{split}\left\{ \begin{array}{c} x_b \\ y_b \\ z_b \end{array} \right\} = \textbf{T} \left\{ \begin{array}{c} x \\ y \\ z \end{array} \right\} + \left\{ \begin{array}{c} x_o \\ y_o \\ z_o \end{array} \right\}\end{split}\]

Cylindrical (type = 2):

# c = cos(theta); s = sin(theta)
[xb; yb; zb] = T*[R c; R s; z] + [xo; yo; zo]
\[\begin{split}\left\{ \begin{array}{c} x_b \\ y_b \\ z_b \end{array} \right\} = \textbf{T} \left\{ \begin{array}{c} R \cos \theta \\ R \sin \theta \\ z \end{array} \right\} + \left\{ \begin{array}{c} x_o \\ y_o \\ z_o \end{array} \right\}\end{split}\]

Spherical (type = 3):

# s1 = sin(theta); s2 = sin(phi)
[xb; yb; zb] = T*[R s1 c2; R s1 s2; R c1] + [xo; yo; zo]
\[\begin{split}\left\{ \begin{array}{c} x_b \\ y_b \\ z_b \end{array} \right\} = \textbf{T} \left\{ \begin{array}{c} R \sin \theta \cos \phi \\ R \sin \theta \sin \phi \\ R \cos \theta \end{array} \right\} + \left\{ \begin{array}{c} x_o \\ y_o \\ z_o \end{array} \right\}\end{split}\]

This routine does the inverse of those equations, as follows:

Rectangular (type = 1):

[x; y; z] = T'*([xb; yb; zb] - [xo; yo; zo])
\[\begin{split}\left\{ \begin{array}{c} x \\ y \\ z \end{array} \right\} = \textbf{T}^{\rm T} \left\{ \begin{array}{c} x_b - x_o \\ y_b - y_o \\ z_b - z_o \end{array} \right\}\end{split}\]

Cylindrical (type = 2):

[x; y; z] = T'*([xb; yb; zb] - [xo; yo; zo])
R = rss(x, y)
theta = atan2(y, x)
\[ \begin{align}\begin{aligned}\begin{split}\left\{ \begin{array}{c} x \\ y \\ z \end{array} \right\} = \textbf{T}^{\rm T} \left\{ \begin{array}{c} x_b - x_o \\ y_b - y_o \\ z_b - z_o \end{array} \right\}\end{split}\\R = \sqrt{x^2 + y^2}\\\theta = \mathrm{atan2}(y, x)\end{aligned}\end{align} \]

Spherical (type = 3):

[x; y; z] = T'*([xb; yb; zb] - [xo; yo; zo])
R = rss(x, y, z)
phi = atan2(y, x)
if abs(sin(phi)) > abs(cos(phi)):
    theta = atan2(y/sin(phi), z)
else:
    theta = atan2(x/cos(phi), z)
\[ \begin{align}\begin{aligned}\begin{split}\left\{ \begin{array}{c} x \\ y \\ z \end{array} \right\} = \textbf{T}^{\rm T} \left\{ \begin{array}{c} x_b - x_o \\ y_b - y_o \\ z_b - z_o \end{array} \right\}\end{split}\\R = \sqrt{x^2 + y^2 + z^2}\\\phi = \mathrm{atan2}(y, x)\\\begin{split}\theta = \begin{cases} \mathrm{atan2}(y/(\sin \phi), z), &\text{if } \left|{\sin \phi}\right| > \left|{\cos \phi}\right| \\ \mathrm{atan2}(x/(\cos \phi), z), &\text{otherwise} \end{cases}\end{split}\end{aligned}\end{align} \]
Raises:
  • ValueError – If gid is 2d, but does not have 3 columns

  • ValueError – If gid has more than 2 dimensions

Examples

>>> import numpy as np
>>> from pyyeti.nastran import n2p
>>>
>>> # node 100 in basic is @ [5, 10, 15]
>>> # node 200 in cylindrical coordinate system is @
>>> #   [r, theta, z] = [32, 90, 10]
>>> # node 300 in spherical coordinate system is @
>>> #   [r, theta, phi] = [50, 45, 90]
>>>
>>> cylcoord = np.array([[1, 2, 0], [0, 0, 0], [1, 0, 0],
...                     [0, 1, 0]])
>>> sphcoord = np.array([[2, 3, 0], [0, 0, 0], [0, 1, 0],
...                      [0, 0, 1]])
>>> uset = None
>>> uset = n2p.addgrid(uset, 100, 'b', 0, [5, 10, 15], 0)
>>> uset = n2p.addgrid(uset, 200, 'b', cylcoord,
...                        [32, 90, 10], cylcoord)
>>> uset = n2p.addgrid(uset, 300, 'b', sphcoord,
...                        [50, 45, 90], sphcoord)
>>> np.set_printoptions(precision=2, suppress=True)
>>> # get coordinates of node 200 in basic:
>>> n2p.getcoordinates(uset, 200, 0)
array([ 10.,   0.,  32.])
>>> # get coordinates of node 200 in cylindrical (cid 1):
>>> n2p.getcoordinates(uset, 200, 1)
array([ 32.,  90.,  10.])
>>> # get coordinates of node 200 in spherical (cid 2):
>>> r = np.hypot(10., 32.)
>>> th = 90.
>>> phi = math.atan2(10., 32.)*180/math.pi
>>> n2p.getcoordinates(uset, 200, 2) - np.array([r, th, phi])
array([ 0.,  0.,  0.])
>>>
>>> # manually calculated locations in cid 1:
>>> theta100 = math.atan2(15, 10) * 180 / math.pi
>>> locs = np.array(
...     [
...         [math.sqrt(10**2 + 15**2), theta100, 5.0],
...         [32.0, 90.0, 10.0],
...         [50.0 / math.sqrt(2), 0.0, 50.0 / math.sqrt(2)],
...     ]
... )
>>> np.allclose(locs, n2p.getcoordinates(uset, [100, 200, 300], 1))
True
>>>
>>> # note the difference in the following two calls:
>>> # - the 1st gets the coordinates of the 3 nodes in basic
>>> # - the 2nd gets the coordinates of [100., 200., 300.] in basic
>>> n2p.getcoordinates(uset, [100, 200, 300], 0)
array([[  5.  ,  10.  ,  15.  ],
       [ 10.  ,   0.  ,  32.  ],
       [ 35.36,  35.36,   0.  ]])
>>> n2p.getcoordinates(uset, [[100, 200, 300]], 0)
array([100, 200, 300])