Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ab84e5c
Patch to work around discretization error affecting optimizer
unalmis Sep 2, 2025
49fb37f
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Sep 3, 2025
c5ecc0f
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Sep 4, 2025
c43f2dc
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Sep 4, 2025
afd3306
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Sep 9, 2025
04dc582
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Sep 12, 2025
7946d8a
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Sep 13, 2025
4c5a1ee
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Sep 13, 2025
003b517
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Sep 14, 2025
eb63745
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Sep 14, 2025
897281b
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Sep 15, 2025
ce6e25e
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Sep 15, 2025
6df7f5f
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Sep 15, 2025
2c2ed4d
Update changelog
unalmis Sep 15, 2025
4888798
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Sep 21, 2025
bdaa0d6
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Sep 25, 2025
5c99d8e
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Oct 1, 2025
24e99ab
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Oct 9, 2025
a6ef903
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Oct 13, 2025
61ec679
Merge branch 'dp/laplace' into ku/laplace_patch
dpanici Oct 16, 2025
2c04a9a
Merge branch 'dp/laplace' into ku/laplace_patch
dpanici Oct 24, 2025
af6d99e
Merge branch 'dp/laplace' into ku/laplace_patch
unalmis Dec 16, 2025
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Changelog

New Features
------------
- Inverse method free surface optimization.
- Automatically-differentiable, non-singular Laplace BIE solver.
- Improved performance and accuracy of FFT interpolation in singular integrals
([1](https://github.com/f0uriest/interpax/pull/116), [2](https://github.com/f0uriest/interpax/pull/117)).
Expand Down
52 changes: 47 additions & 5 deletions desc/objectives/_free_boundary.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from desc.backend import jnp
from desc.compute import get_profiles, get_transforms
from desc.compute.utils import _compute as compute_fun
from desc.compute.utils import _compute_RpZ_data as compute_fun_rpz
from desc.grid import LinearGrid
from desc.integrals import get_interpolator, virtual_casing_biot_savart
from desc.nestor import Nestor
Expand Down Expand Up @@ -1023,10 +1024,24 @@ def __init__(
self._chunk_size = chunk_size
self._B_coil_chunk_size = B_coil_chunk_size
self._grad_keys = ["grad(theta)", "grad(zeta)", "n_rho"]
self._inner_keys = ["|B|^2", "p", "I", "|e_theta x e_zeta|"] + self._grad_keys
self._inner_keys = [
"|B|^2",
"p",
"I",
"|e_theta x e_zeta|",
"R",
"phi",
"zeta",
"omega",
"Z",
] + self._grad_keys
self._reuseable_keys = [
"0",
"R",
"Z",
"phi",
"zeta",
"omega",
"R_t",
"R_z",
"Z_t",
Expand Down Expand Up @@ -1210,7 +1225,11 @@ def compute(self, params, constants=None):

outer = compute_fun(
self._field,
["K_vc", "n_rho x B_coil"] if self._is_neumann else "|K_vc|^2",
(
["K_vc", "n_rho x B_coil", "K_vc (periodic)"]
if self._is_neumann
else "|K_vc|^2"
),
field_params,
constants["eval_transforms"],
constants["profiles"],
Expand All @@ -1223,11 +1242,34 @@ def compute(self, params, constants=None):
field_grid=self._coil_grid,
**problem,
)

outer_rpz = compute_fun_rpz(
self._field,
["B"],
field_params,
constants["eval_transforms"],
constants["profiles"],
data=outer,
maxiter=self._maxiter,
chunk_size=self._chunk_size,
B_coil_chunk_size=self._B_coil_chunk_size,
B_coil=self._B_coil,
field_grid=self._coil_grid,
RpZ_data={"R": outer["R"], "Z": outer["Z"], "phi": outer["phi"]},
RpZ_grid=constants["eval_transforms"]["grid"],
eval_interpolator=outer["interpolator"],
B0=self._field._B0,
on_boundary=True,
**problem,
)

if self._is_neumann:
outer["K_vc"] -= outer["n_rho x B_coil"]
outer["|K_vc|^2"] = dot(outer["K_vc"], outer["K_vc"])
# Compute from equation 4.26 instead of the equation
# sandwhiched between 4.23 and 4.24 due to discretization error
# in quadrature messing up the optimizer.
outer["|B|^2"] = dot(outer_rpz["B"], outer_rpz["B"])

return (outer["|K_vc|^2"] - inner["|B|^2"] - 2 * mu_0 * inner["p"]) * inner[
return (outer["|B|^2"] - inner["|B|^2"] - 2 * mu_0 * inner["p"]) * inner[
"|e_theta x e_zeta|"
]

Expand Down