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

add flag to PlasmaVesselDistance to avoid recomputing surface coordinates when the surface is fixed during optimization #746

Merged
merged 6 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ Changelog

- Adds ``desc.compat.rescale`` for rescaling equilibria to a specified size and field
strength.
- Adds new keyword ``surface_fixed`` to ``PlasmaVesselDistance`` objective which says
whether or not the surface comparing the distance from the plasma to is fixed or not.
If True, then the surface coordinates can be precomputed, saving on computation during
optimization. Set to False by default.
- Adds objective function `desc.objectives.GoodCoordinates` for finding "good" (ie,
non-singular, non-degenerate) coordinate mappings for initial guesses. This is applied
automatically when creating a new `Equilibrium` if the default initial guess of scaling
Expand Down
46 changes: 38 additions & 8 deletions desc/objectives/_geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,12 @@
will only be an upper bound on the minimum separation between the plasma and the
surrounding surface.

NOTE: By default, assumes the surface is not fixed and its coordinates are computed
at every iteration, for example if the winding surface you compare to is part of the
optimization and thus changing.
If the bounding surface is fixed, set surface_fixed=True to precompute the surface
coordinates and improve the efficiency of the calculation

NOTE: for best results, use this objective in combination with either MeanCurvature
or PrincipalCurvature, to penalize the tendency for the optimizer to only move the
points on surface corresponding to the grid that the plasma-vessel distance
Expand Down Expand Up @@ -440,6 +446,12 @@
Collocation grid containing the nodes to evaluate plasma geometry at.
use_softmin: bool, optional
Use softmin or hard min.
surface_fixed: bool, optional
Whether the surface the distance from the plasma is computed to
is fixed or not. If True, the surface is fixed and its coordinates are
precomputed, which saves on computation time during optimization.
If False, the surface coordinates are computed at every iteration.
False by default.
alpha: float, optional
Parameter used for softmin. The larger alpha, the closer the softmin
approximates the hardmin. softmin -> hardmin as alpha -> infinity.
Expand Down Expand Up @@ -467,6 +479,7 @@
surface_grid=None,
plasma_grid=None,
use_softmin=False,
surface_fixed=False,
alpha=1.0,
name="plasma-vessel distance",
):
Expand All @@ -476,6 +489,7 @@
self._surface_grid = surface_grid
self._plasma_grid = plasma_grid
self._use_softmin = use_softmin
self._surface_fixed = surface_fixed
self._alpha = alpha
super().__init__(
things=[eq, self._surface],
Expand Down Expand Up @@ -559,6 +573,19 @@
"quad_weights": w,
}

if self._surface_fixed:
# precompute the surface coordinates
# as the surface is fixed during the optimization
surface_coords = compute_fun(

Check warning on line 579 in desc/objectives/_geometry.py

View check run for this annotation

Codecov / codecov/patch

desc/objectives/_geometry.py#L579

Added line #L579 was not covered by tests
self._surface,
self._surface_data_keys,
params=self._surface.params_dict,
transforms=surface_transforms,
profiles={},
basis="xyz",
)["x"]
self._constants["surface_coords"] = surface_coords

Check warning on line 587 in desc/objectives/_geometry.py

View check run for this annotation

Codecov / codecov/patch

desc/objectives/_geometry.py#L587

Added line #L587 was not covered by tests

timer.stop("Precomputing transforms")
if verbose > 1:
timer.disp("Precomputing transforms")
Expand Down Expand Up @@ -598,14 +625,17 @@
profiles=constants["equil_profiles"],
)
plasma_coords = rpz2xyz(jnp.array([data["R"], data["phi"], data["Z"]]).T)
surface_coords = compute_fun(
self._surface,
self._surface_data_keys,
params=surface_params,
transforms=constants["surface_transforms"],
profiles={},
basis="xyz",
)["x"]
if self._surface_fixed:
surface_coords = constants["surface_coords"]

Check warning on line 629 in desc/objectives/_geometry.py

View check run for this annotation

Codecov / codecov/patch

desc/objectives/_geometry.py#L629

Added line #L629 was not covered by tests
else:
surface_coords = compute_fun(
self._surface,
self._surface_data_keys,
params=surface_params,
transforms=constants["surface_transforms"],
profiles={},
basis="xyz",
)["x"]
d = jnp.linalg.norm(
plasma_coords[:, None, :] - surface_coords[None, :, :], axis=-1
)
Expand Down
6 changes: 5 additions & 1 deletion tests/test_objective_funs.py
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,11 @@ def test_plasma_vessel_distance():
surf_grid = LinearGrid(M=5, N=6)
plas_grid = LinearGrid(M=10, N=6)
obj = PlasmaVesselDistance(
eq=eq, plasma_grid=plas_grid, surface_grid=surf_grid, surface=surface
eq=eq,
plasma_grid=plas_grid,
surface_grid=surf_grid,
surface=surface,
surface_fixed=True,
)
obj.build()
d = obj.compute_unscaled(*obj.xs(eq, surface))
Expand Down
Loading