evalf / nutils

The nutils project
http://www.nutils.org/
MIT License
88 stars 48 forks source link

linear constraints #836

Closed joostvanzwieten closed 9 months ago

joostvanzwieten commented 9 months ago

This PR introduces a new way to impose constraints. Example with inhomogeneous Dirichlet boundary condition, old style (remains valid):

ns.add_field(('u', 'v'), basis)
ns.f = ...
res = ...
sqr = domain.boundary.integral('(u - f)^2 dS' @ ns, degree=...)
cons = solver.optimze('u,', sqr, droptol=...)
args = solver.solve_linear('u:v', res, constrain=cons)

New style:

ns.add_field(('u', 'v', 'w'), basis)
ns.f = ...
res = ...
res += domain.boundary.integral('w (u - f) dS' @ ns, degree=...)
args = solver.solve_linear('u:v:w', res)

The new field w serves as 'test' function for the constraints and the constraint now has the form of a projection.

In addition it is possible to apply asymmetric constraints. Continuing the above example: Boundary value f is the result of another problem with test space g, which depends on u. This can be achieved by the constraint

res = += domain.boundary.integral('(w (u - f) + w v) dS', degree=...)
args = solver.solve_linear('u:v:w*,f:g', res)

In addition to the constraint w (u - f) we also add w v, which explicitly constrains the test space. To signal that we have asymmetric constraints, the constraint argument w has a star in the targets passed to solve_linear.

joostvanzwieten commented 9 months ago

Closing in favor of Lagrange multipliers.