def test_overload_function(): tape = Tape() set_working_tape(tape) sin = overload_function(ad_sin, SinBlock) z = AdjFloat(5) t = AdjFloat(3) r = sin(z) q = cos(r * t) Jhat = ReducedFunctional(q, Control(z)) assert (Jhat.derivative() == -np.sin(t * np.sin(z)) * t * np.cos(z))
# flake8: noqa F401 from fenics_adjoint.assembly import assemble, assemble_system from fenics_adjoint.solving import solve from fenics_adjoint.projection import project from fenics_adjoint.types import Constant, DirichletBC from fenics_adjoint.variational_solver import (NonlinearVariationalProblem, NonlinearVariationalSolver, LinearVariationalProblem, LinearVariationalSolver) from fenics_adjoint.interpolation import interpolate from fenics_adjoint.ufl_constraints import UFLInequalityConstraint, UFLEqualityConstraint from firedrake_adjoint.types.expression import Expression from firedrake_adjoint.types.function import Function from pyadjoint.tape import (Tape, set_working_tape, get_working_tape, pause_annotation, continue_annotation) from pyadjoint.reduced_functional import ReducedFunctional from pyadjoint.verification import taylor_test from pyadjoint.drivers import compute_gradient, compute_hessian from pyadjoint.adjfloat import AdjFloat from pyadjoint.control import Control from pyadjoint import IPOPTSolver, ROLSolver, MinimizationProblem, InequalityConstraint, minimize tape = Tape() set_working_tape(tape)
# flake8: noqa import pyadjoint __version__ = pyadjoint.__version__ import sys if 'backend' not in sys.modules: import firedrake sys.modules['backend'] = firedrake else: raise ImportError("'backend' module already exists?") from pyadjoint.tape import (Tape, set_working_tape, get_working_tape, pause_annotation, continue_annotation, stop_annotating, annotate_tape) from pyadjoint.reduced_functional import ReducedFunctional from pyadjoint.verification import taylor_test, taylor_to_dict from pyadjoint.drivers import compute_gradient, compute_hessian from pyadjoint.adjfloat import AdjFloat from pyadjoint.control import Control from pyadjoint import IPOPTSolver, ROLSolver, MinimizationProblem, InequalityConstraint, minimize from dolfin_adjoint_common.ufl_constraints import UFLInequalityConstraint, UFLEqualityConstraint import numpy_adjoint continue_annotation() set_working_tape(Tape())
def test_poisson_inverse_conductivity(): # Have to import inside test to make sure cleanup fixtures work as intended from firedrake_adjoint import Control, ReducedFunctional, minimize # Manually set up annotation since test suite may have stopped it tape = get_working_tape() tape.clear_tape() set_working_tape(tape) continue_annotation() # Use pyadjoint to estimate an unknown conductivity in a # poisson-like forward model from point measurements m = UnitSquareMesh(2, 2) V = FunctionSpace(m, family='CG', degree=2) Q = FunctionSpace(m, family='CG', degree=2) # generate random "true" conductivity with beta distribution pcg = PCG64(seed=0) rg = RandomGenerator(pcg) # beta distribution q_true = rg.beta(Q, 1.0, 2.0) # Compute the true solution of the PDE. u_true = Function(V) v = TestFunction(V) f = Constant(1.0) k0 = Constant(0.5) bc = DirichletBC(V, 0, 'on_boundary') F = (k0 * exp(q_true) * inner(grad(u_true), grad(v)) - f * v) * dx solve(F == 0, u_true, bc) # Generate random point cloud num_points = 2 np.random.seed(0) xs = np.random.random_sample((num_points, 2)) point_cloud = VertexOnlyMesh(m, xs) # Prove the the point cloud coordinates are correct assert((point_cloud.coordinates.dat.data_ro == xs).all()) # Generate "observed" data generator = np.random.default_rng(0) signal_to_noise = 20 U = u_true.dat.data_ro[:] u_range = U.max() - U.min() σ = Constant(u_range / signal_to_noise) ζ = generator.standard_normal(len(xs)) u_obs_vals = np.array(u_true.at(xs)) + float(σ) * ζ # Store data on the point_cloud P0DG = FunctionSpace(point_cloud, 'DG', 0) u_obs = Function(P0DG) u_obs.dat.data[:] = u_obs_vals # Run the forward model u = Function(V) q = Function(Q) bc = DirichletBC(V, 0, 'on_boundary') F = (k0 * exp(q) * inner(grad(u), grad(v)) - f * v) * dx solve(F == 0, u, bc) # Two terms in the functional misfit_expr = 0.5 * ((u_obs - interpolate(u, P0DG)) / σ)**2 α = Constant(0.5) regularisation_expr = 0.5 * α**2 * inner(grad(q), grad(q)) # Form functional and reduced functional J = assemble(misfit_expr * dx) + assemble(regularisation_expr * dx) q̂ = Control(q) Ĵ = ReducedFunctional(J, q̂) # Estimate q using Newton-CG which evaluates the hessian action minimize(Ĵ, method='Newton-CG', options={'disp': True}) # Make sure annotation is stopped tape.clear_tape() pause_annotation()