-
Notifications
You must be signed in to change notification settings - Fork 86
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
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
nonlinear minimization #642
Comments
Yes. See #643. scikit-fem/docs/examples/ex39.py Lines 16 to 43 in 52c01bf
|
This is all a little bit like #119, which attempted to use |
An awkwardness here is the scikit-fem/docs/examples/ex39.py Lines 33 to 34 in 52c01bf
Initially I had tried something like trace = LinearOperator(lambda z: z[D], (D.size, basis.N)) but this fails as internally SciPy applies it with —— Edit:— This is incorrect. This code isn't on the path. See below. |
According to whpowell96 Feb 19 '20 at 17:27 (Computational Science Stack Exchange, ‘Which SciPy nonlinear solver when Jacobian is analytically known and sparse?’) :
Is that right? (Other answers and comments on the question recover many of the disappointing findings of #119 about |
Actually, correcting the error above, the linear constraint passes through: This doesn't work for a |
The attempt to use |
As a further demonstration though, I did extend the example to include a constraint on the volume, thereby generalizing from a minimal surface to a constant mean-curvature surface. Also flattening the ring of ex10 to a planar unit square and taking the required volume as one half, putting trace = csr_matrix((np.ones(D.size), (np.arange(D.size), D)), (D.size, basis.N))
volume = csr_matrix(unit_load.assemble(basis)[None, :])
constraint = [
LinearConstraint(trace, *[0] * 2),
LinearConstraint(
volume,
*[0.5] * 2,
),
] in the code of produces |
Although
As a next example, I thought to redo ex01, the ‘Poisson equation with unit load’. Since it has the form a (u, v) = b (v) for all v, it is equivalent (Glowinski 1984, App. I, §2.4) to the minimization of J (v) = a(v, v) / 2 − b (v), which has jacobian J' (v) = a (v, ⋅) − b and hessian J'' = a . In scikit-fem, the Dirichlet conditions can again be imposed as a def functional(x: np.ndarray) -> float:
return x @ A @ x / 2 - b @ x
def jacobian(x: np.ndarray) -> np.ndarray:
return x @ A - b
def hessian(x: np.ndarray) -> np.ndarray:
return A
D = m.boundary_nodes()
trace = csr_matrix((np.ones(D.size), (np.arange(D.size), D)), (D.size, basis.N))
constraint = LinearConstraint(trace, *[np.zeros(D.size)]*2)
x = minimize(
functional,
basis.zeros(),
jac=jacobian,
hess=hessian,
method="trust-constr",
constraints=constraint,
options={"verbose": 3},
).x The solution is indistinguishable from that of ex01, and passes the same test. |
This technique also leads to a very succinct expression of the Stokes problem; e.g. redoing ex30 ‘Krylov-Uzawa method for the Stokes equation’ using what Ern & Guermond (2004, §4.1.3) call ‘the constraint formulation’. Basically it's the same functional, jacobian, and hessian, as for ex01, but with the bilinear form being the viscous dissipation of the velocity field. As E. & G. say (p. 179)
(Here a pressure basis is constructed for the assembling of the divergence operator which appears in the constraints.) def functional(u: np.ndarray) -> float:
return u @ A @ u / 2 - f @ u
def jacobian(u: np.ndarray) -> np.ndarray:
return u @ A - f
def hessian(u: np.ndarray) -> np.ndarray:
return A
incompressibility = LinearConstraint(B, 0, 0)
slip = csr_matrix((np.ones(D.size), (np.arange(D.size), D)), (D.size, basis["u"].N))
noslip = LinearConstraint(slip, 0, 0)
velocity = minimize(
functional,
basis["u"].zeros(),
jac=jacobian,
hess=hessian,
method="trust-constr",
constraints=[incompressibility, noslip],
options={"verbose": 3},
).x This passes the same test as ex30: 40c94aa. |
I realize now, as an aside, that ex30 could switch from the unit square scikit-fem/docs/examples/ex30.py Line 64 in fb649d8
to use the same unit circle domain as ex18 scikit-fem/docs/examples/ex18.py Line 54 in fb649d8
but on a finer mesh. The original motivation for using the square rather than the disk here was that before #476, ex18 loaded a static mesh scikit-fem/docs/examples/ex18.py Line 54 in 7eb3016
whereas a finer mesh was wanted for ex30 to demonstrate that the Krylov–Uzawa scheme did scale reasonably to bigger problems. |
Oops. Interesting findings you have here. |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
Some finite element problems can be cast as minimizations rather than boundary value problems; can they be cast as such in scikit-fem and be solved with
scipy.optimize.minimize
?For example, the solution
x
of the Young–Laplace equation in ex10 is a minimal surface, constrained by Dirichlet boundary conditions; can it be solved by minimizing a functional for the area?The text was updated successfully, but these errors were encountered: