Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FourierPlanarCurve basis option #1017

Merged
merged 12 commits into from
May 16, 2024
15 changes: 9 additions & 6 deletions desc/coils.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,17 +458,19 @@
Parameters
----------
current : float
current through the coil, in Amperes
Current through the coil, in Amperes.
center : array-like, shape(3,)
x,y,z coordinates of center of coil
Coordinates of center of curve, in system determined by basis.
normal : array-like, shape(3,)
x,y,z components of normal vector to planar surface
Components of normal vector to planar surface, in system determined by basis.
r_n : array-like
fourier coefficients for radius from center as function of polar angle
Fourier coefficients for radius from center as function of polar angle
modes : array-like
mode numbers associated with r_n
basis : {'xyz', 'rpz'}
Coordinate system for center and normal vectors. Default = 'xyz'.
name : str
name for this coil
Name for this coil.

Examples
--------
Expand Down Expand Up @@ -514,9 +516,10 @@
normal=[0, 1, 0],
r_n=2,
modes=None,
basis="xyz",
name="",
):
super().__init__(current, center, normal, r_n, modes, name)
super().__init__(current, center, normal, r_n, modes, basis, name)

Check warning on line 522 in desc/coils.py

View check run for this annotation

Codecov / codecov/patch

desc/coils.py#L522

Added line #L522 was not covered by tests


class SplineXYZCoil(_Coil, SplineXYZCurve):
Expand Down
108 changes: 52 additions & 56 deletions desc/compute/_curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,16 +168,21 @@
description="Position vector along curve",
dim=3,
params=["r_n", "center", "normal", "rotmat", "shift"],
transforms={
"r": [[0, 0, 0]],
},
transforms={"r": [[0, 0, 0]]},
profiles=[],
coordinates="s",
data=["s"],
parameterization="desc.geometry.curve.FourierPlanarCurve",
basis="{'rpz', 'xyz'}: Basis for returned vectors, Default 'rpz'",
basis_in="{'rpz', 'xyz'}: Basis for input params vectors, Default 'xyz'",
)
def _x_FourierPlanarCurve(params, transforms, profiles, data, **kwargs):
if kwargs.get("basis_in", "xyz").lower() == "rpz":
ddudt marked this conversation as resolved.
Show resolved Hide resolved
center = rpz2xyz(params["center"])
normal = rpz2xyz_vec(params["normal"], phi=params["center"][1])

Check warning on line 182 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L180-L182

Added lines #L180 - L182 were not covered by tests
else:
center = params["center"]
normal = params["normal"]

Check warning on line 185 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L184-L185

Added lines #L184 - L185 were not covered by tests
# create planar curve at Z==0
r = transforms["r"].transform(params["r_n"], dz=0)
Z = jnp.zeros_like(r)
Expand All @@ -186,10 +191,10 @@
coords = jnp.array([X, Y, Z]).T
# rotate into place
Zaxis = jnp.array([0.0, 0.0, 1.0]) # 2D curve in X-Y plane has normal = +Z axis
axis = cross(Zaxis, params["normal"])
angle = jnp.arccos(dot(Zaxis, safenormalize(params["normal"])))
axis = cross(Zaxis, normal)
angle = jnp.arccos(dot(Zaxis, safenormalize(normal)))

Check warning on line 195 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L194-L195

Added lines #L194 - L195 were not covered by tests
A = rotation_matrix(axis=axis, angle=angle)
coords = jnp.matmul(coords, A.T) + params["center"]
coords = jnp.matmul(coords, A.T) + center

Check warning on line 197 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L197

Added line #L197 was not covered by tests
coords = jnp.matmul(coords, params["rotmat"].reshape((3, 3)).T) + params["shift"]
if kwargs.get("basis", "rpz").lower() == "rpz":
coords = xyz2rpz(coords)
Expand All @@ -205,16 +210,21 @@
description="Position vector along curve, first derivative",
dim=3,
params=["r_n", "center", "normal", "rotmat", "shift"],
transforms={
"r": [[0, 0, 0], [0, 0, 1]],
},
transforms={"r": [[0, 0, 0], [0, 0, 1]]},
profiles=[],
coordinates="s",
data=["s"],
parameterization="desc.geometry.curve.FourierPlanarCurve",
basis="{'rpz', 'xyz'}: Basis for returned vectors, Default 'rpz'",
basis_in="{'rpz', 'xyz'}: Basis for input params vectors, Default 'xyz'",
)
def _x_s_FourierPlanarCurve(params, transforms, profiles, data, **kwargs):
if kwargs.get("basis_in", "xyz").lower() == "rpz":
center = rpz2xyz(params["center"])
normal = rpz2xyz_vec(params["normal"], phi=params["center"][1])

Check warning on line 224 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L222-L224

Added lines #L222 - L224 were not covered by tests
else:
center = params["center"]
normal = params["normal"]

Check warning on line 227 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L226-L227

Added lines #L226 - L227 were not covered by tests
r = transforms["r"].transform(params["r_n"], dz=0)
dr = transforms["r"].transform(params["r_n"], dz=1)
dX = dr * jnp.cos(data["s"]) - r * jnp.sin(data["s"])
Expand All @@ -223,8 +233,8 @@
coords = jnp.array([dX, dY, dZ]).T
# rotate into place
Zaxis = jnp.array([0.0, 0.0, 1.0]) # 2D curve in X-Y plane has normal = +Z axis
axis = cross(Zaxis, params["normal"])
angle = jnp.arccos(dot(Zaxis, safenormalize(params["normal"])))
axis = cross(Zaxis, normal)
angle = jnp.arccos(dot(Zaxis, safenormalize(normal)))

Check warning on line 237 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L236-L237

Added lines #L236 - L237 were not covered by tests
A = rotation_matrix(axis=axis, angle=angle)
coords = jnp.matmul(coords, A.T)
coords = jnp.matmul(coords, params["rotmat"].reshape((3, 3)).T)
Expand All @@ -233,7 +243,7 @@
Y = r * jnp.sin(data["s"])
Z = jnp.zeros_like(X)
xyzcoords = jnp.array([X, Y, Z]).T
xyzcoords = jnp.matmul(xyzcoords, A.T) + params["center"]
xyzcoords = jnp.matmul(xyzcoords, A.T) + center

Check warning on line 246 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L246

Added line #L246 was not covered by tests
xyzcoords = (
jnp.matmul(xyzcoords, params["rotmat"].reshape((3, 3)).T) + params["shift"]
)
Expand All @@ -251,16 +261,21 @@
description="Position vector along curve, second derivative",
dim=3,
params=["r_n", "center", "normal", "rotmat", "shift"],
transforms={
"r": [[0, 0, 0], [0, 0, 1], [0, 0, 2]],
},
transforms={"r": [[0, 0, 0], [0, 0, 1], [0, 0, 2]]},
profiles=[],
coordinates="s",
data=["s"],
parameterization="desc.geometry.curve.FourierPlanarCurve",
basis="{'rpz', 'xyz'}: Basis for returned vectors, Default 'rpz'",
basis_in="{'rpz', 'xyz'}: Basis for input params vectors, Default 'xyz'",
)
def _x_ss_FourierPlanarCurve(params, transforms, profiles, data, **kwargs):
if kwargs.get("basis_in", "xyz").lower() == "rpz":
center = rpz2xyz(params["center"])
normal = rpz2xyz_vec(params["normal"], phi=params["center"][1])

Check warning on line 275 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L273-L275

Added lines #L273 - L275 were not covered by tests
else:
center = params["center"]
normal = params["normal"]

Check warning on line 278 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L277-L278

Added lines #L277 - L278 were not covered by tests
r = transforms["r"].transform(params["r_n"], dz=0)
dr = transforms["r"].transform(params["r_n"], dz=1)
d2r = transforms["r"].transform(params["r_n"], dz=2)
Expand All @@ -274,8 +289,8 @@
coords = jnp.array([d2X, d2Y, d2Z]).T
# rotate into place
Zaxis = jnp.array([0.0, 0.0, 1.0]) # 2D curve in X-Y plane has normal = +Z axis
axis = cross(Zaxis, params["normal"])
angle = jnp.arccos(dot(Zaxis, safenormalize(params["normal"])))
axis = cross(Zaxis, normal)
angle = jnp.arccos(dot(Zaxis, safenormalize(normal)))

Check warning on line 293 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L292-L293

Added lines #L292 - L293 were not covered by tests
A = rotation_matrix(axis=axis, angle=angle)
coords = jnp.matmul(coords, A.T)
coords = jnp.matmul(coords, params["rotmat"].reshape((3, 3)).T)
Expand All @@ -284,7 +299,7 @@
Y = r * jnp.sin(data["s"])
Z = jnp.zeros_like(X)
xyzcoords = jnp.array([X, Y, Z]).T
xyzcoords = jnp.matmul(xyzcoords, A.T) + params["center"]
xyzcoords = jnp.matmul(xyzcoords, A.T) + center

Check warning on line 302 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L302

Added line #L302 was not covered by tests
xyzcoords = (
jnp.matmul(xyzcoords, params["rotmat"].reshape((3, 3)).T) + params["shift"]
)
Expand All @@ -302,16 +317,21 @@
description="Position vector along curve, third derivative",
dim=3,
params=["r_n", "center", "normal", "rotmat", "shift"],
transforms={
"r": [[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3]],
},
transforms={"r": [[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3]]},
profiles=[],
coordinates="s",
data=["s"],
parameterization="desc.geometry.curve.FourierPlanarCurve",
basis="{'rpz', 'xyz'}: Basis for returned vectors, Default 'rpz'",
basis_in="{'rpz', 'xyz'}: Basis for input params vectors, Default 'xyz'",
)
def _x_sss_FourierPlanarCurve(params, transforms, profiles, data, **kwargs):
if kwargs.get("basis_in", "xyz").lower() == "rpz":
center = rpz2xyz(params["center"])
normal = rpz2xyz_vec(params["normal"], phi=params["center"][1])

Check warning on line 331 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L329-L331

Added lines #L329 - L331 were not covered by tests
else:
center = params["center"]
normal = params["normal"]

Check warning on line 334 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L333-L334

Added lines #L333 - L334 were not covered by tests
r = transforms["r"].transform(params["r_n"], dz=0)
dr = transforms["r"].transform(params["r_n"], dz=1)
d2r = transforms["r"].transform(params["r_n"], dz=2)
Expand All @@ -332,8 +352,8 @@
coords = jnp.array([d3X, d3Y, d3Z]).T
# rotate into place
Zaxis = jnp.array([0.0, 0.0, 1.0]) # 2D curve in X-Y plane has normal = +Z axis
axis = cross(Zaxis, params["normal"])
angle = jnp.arccos(dot(Zaxis, safenormalize(params["normal"])))
axis = cross(Zaxis, normal)
angle = jnp.arccos(dot(Zaxis, safenormalize(normal)))

Check warning on line 356 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L355-L356

Added lines #L355 - L356 were not covered by tests
A = rotation_matrix(axis=axis, angle=angle)
coords = jnp.matmul(coords, A.T)
coords = jnp.matmul(coords, params["rotmat"].reshape((3, 3)).T)
Expand All @@ -342,7 +362,7 @@
Y = r * jnp.sin(data["s"])
Z = jnp.zeros_like(X)
xyzcoords = jnp.array([X, Y, Z]).T
xyzcoords = jnp.matmul(xyzcoords, A.T) + params["center"]
xyzcoords = jnp.matmul(xyzcoords, A.T) + center

Check warning on line 365 in desc/compute/_curve.py

View check run for this annotation

Codecov / codecov/patch

desc/compute/_curve.py#L365

Added line #L365 was not covered by tests
xyzcoords = (
jnp.matmul(xyzcoords, params["rotmat"].reshape((3, 3)).T) + params["shift"]
)
Expand All @@ -360,11 +380,7 @@
description="Position vector along curve",
dim=3,
params=["R_n", "Z_n", "rotmat", "shift"],
transforms={
"R": [[0, 0, 0]],
"Z": [[0, 0, 0]],
"grid": [],
},
transforms={"R": [[0, 0, 0]], "Z": [[0, 0, 0]], "grid": []},
profiles=[],
coordinates="s",
data=[],
Expand Down Expand Up @@ -395,11 +411,7 @@
description="Position vector along curve, first derivative",
dim=3,
params=["R_n", "Z_n", "rotmat"],
transforms={
"R": [[0, 0, 0], [0, 0, 1]],
"Z": [[0, 0, 1]],
"grid": [],
},
transforms={"R": [[0, 0, 0], [0, 0, 1]], "Z": [[0, 0, 1]], "grid": []},
profiles=[],
coordinates="s",
data=[],
Expand Down Expand Up @@ -429,11 +441,7 @@
description="Position vector along curve, second derivative",
dim=3,
params=["R_n", "Z_n", "rotmat"],
transforms={
"R": [[0, 0, 0], [0, 0, 1], [0, 0, 2]],
"Z": [[0, 0, 2]],
"grid": [],
},
transforms={"R": [[0, 0, 0], [0, 0, 1], [0, 0, 2]], "Z": [[0, 0, 2]], "grid": []},
profiles=[],
coordinates="s",
data=[],
Expand Down Expand Up @@ -505,11 +513,7 @@
description="Position vector along curve",
dim=3,
params=["X_n", "Y_n", "Z_n", "rotmat", "shift"],
transforms={
"X": [[0, 0, 0]],
"Y": [[0, 0, 0]],
"Z": [[0, 0, 0]],
},
transforms={"X": [[0, 0, 0]], "Y": [[0, 0, 0]], "Z": [[0, 0, 0]]},
profiles=[],
coordinates="s",
data=[],
Expand Down Expand Up @@ -643,9 +647,7 @@
description="Position vector along curve",
dim=3,
params=["X", "Y", "Z", "knots", "rotmat", "shift"],
transforms={
"method": [],
},
transforms={"method": []},
profiles=[],
coordinates="s",
data=["s"],
Expand Down Expand Up @@ -698,9 +700,7 @@
description="Position vector along curve, first derivative",
dim=3,
params=["X", "Y", "Z", "knots", "rotmat", "shift"],
transforms={
"method": [],
},
transforms={"method": []},
profiles=[],
coordinates="s",
data=["s"],
Expand Down Expand Up @@ -784,9 +784,7 @@
description="Position vector along curve, second derivative",
dim=3,
params=["X", "Y", "Z", "knots", "rotmat", "shift"],
transforms={
"method": [],
},
transforms={"method": []},
profiles=[],
coordinates="s",
data=["s"],
Expand Down Expand Up @@ -869,9 +867,7 @@
description="Position vector along curve, third derivative",
dim=3,
params=["X", "Y", "Z", "knots", "rotmat", "shift"],
transforms={
"method": [],
},
transforms={"method": []},
profiles=[],
coordinates="s",
data=["s"],
Expand Down
6 changes: 3 additions & 3 deletions desc/geometry/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,17 +178,17 @@ def compute(
return data

def translate(self, displacement=[0, 0, 0]):
"""Translate the curve by a rigid displacement in X, Y, Z."""
"""Translate the curve by a rigid displacement in X,Y,Z coordinates."""
self.shift = self.shift + jnp.asarray(displacement)

def rotate(self, axis=[0, 0, 1], angle=0):
"""Rotate the curve by a fixed angle about axis in X, Y, Z coordinates."""
"""Rotate the curve by a fixed angle about axis in X,Y,Z coordinates."""
R = rotation_matrix(axis=axis, angle=angle)
self.rotmat = (R @ self.rotmat.reshape(3, 3)).flatten()
self.shift = self.shift @ R.T

def flip(self, normal=[0, 0, 1]):
"""Flip the curve about the plane with specified normal."""
"""Flip the curve about the plane with specified normal in X,Y,Z coordinates."""
F = reflection_matrix(normal)
self.rotmat = (F @ self.rotmat.reshape(3, 3)).flatten()
self.shift = self.shift @ F.T
Expand Down
Loading
Loading