gel.header

Import statements common to all source files on the backend.

If an environment variable named SUPPRESS_ADJOINT is set in the Python process importing this module, then dolfin will not be overridden with dolfin_adjoint. This is useful for saving memory if one is merely performing forward solves.

Passing Forward Model Solutions as Guesses

For the inverse model, in order to pass previous displacement solutions as initial guesses between L-BFGS iterations, a bit of a hack is required. FEniCS-adjoint is designed to automatically figure out an appropriate way to (1) resolve and (2) solve the adjoint problem after an initial forward solve. However, this does not easily permit changing how solves are performed across multiple resolves. So, we must intercept default nonlinear solve block behavior to use previous solutions as initial guesses. Implemented wrappers include:

API

 1"""Import statements common to all source files on the backend.
 2
 3If an environment variable named `SUPPRESS_ADJOINT` is set in the Python
 4process importing this module, then dolfin will not be overridden with
 5dolfin_adjoint. This is useful for saving memory if one is merely
 6performing forward solves.
 7
 8# Passing Forward Model Solutions as Guesses
 9
10For the inverse model, in order to pass previous displacement solutions
11as initial guesses between L-BFGS iterations, a bit of a hack is
12required. FEniCS-adjoint is designed to automatically figure out an
13appropriate way to (1) resolve and (2) solve the adjoint problem after
14an initial forward solve. However, this does not easily permit changing
15how solves are performed across multiple resolves. So, we must
16intercept default nonlinear solve block behavior to use previous
17solutions as initial guesses. Implemented wrappers include:
18* `new_forward_solve` 
19* `new_init_guess` 
20
21# API
22"""
23import os
24from dolfin import *
25
26
27if "SUPPRESS_ADJOINT" not in os.environ:
28    from dolfin_adjoint import *
29    import dolfin as df
30    # Make previous guesses get passed
31    from fenics_adjoint.solving import SolveBlock
32    from fenics_adjoint.variational_solver import NonlinearVariationalSolveBlock
33
34    NonlinearVariationalSolveBlock._intercepted_solve = NonlinearVariationalSolveBlock._forward_solve
35
36    def new_forward_solve(self, *args, **kwargs):
37        """Wrapper for _forward_solve to save output."""
38        self.prev_soln = self._intercepted_solve(*args, **kwargs)
39        df.Function.assign(self.block_var_to_save.output, self.prev_soln)
40        self.block_var_to_save.save_output() # NEED TO SET LATER
41        return self.prev_soln
42
43    NonlinearVariationalSolveBlock._forward_solve = new_forward_solve
44
45    SolveBlock._intercepted_create_initial_guess = SolveBlock._create_initial_guess
46
47    def new_init_guess(self):
48        """Wrapper for _create_initial_guess returning saved soln."""
49        if not hasattr(self, "prev_soln"):
50            return self._intercepted_create_initial_guess()
51        else:
52            return self.prev_soln
53
54    SolveBlock._create_initial_guess = new_init_guess
55
56
57import pyadjoint as pa
58import numpy as np
59import sys
60import meshio
61
62
63comm = MPI.comm_world
64"""MPI comm interface"""
65rank = MPI.comm_world.rank
66"""MPI rank number"""
67if rank != 0:
68    set_log_level(50)  # Mute output
69
70
71do_nothing_print = lambda *args : None # Do nothing
72"""A substitute for print and logging functions that does nothing."""
comm = <mpi4py.MPI.Intracomm object>

MPI comm interface

rank = 0

MPI rank number

def do_nothing_print(*args):
72do_nothing_print = lambda *args : None # Do nothing

A substitute for print and logging functions that does nothing.

def new_forward_solve(self, *args, **kwargs):
37    def new_forward_solve(self, *args, **kwargs):
38        """Wrapper for _forward_solve to save output."""
39        self.prev_soln = self._intercepted_solve(*args, **kwargs)
40        df.Function.assign(self.block_var_to_save.output, self.prev_soln)
41        self.block_var_to_save.save_output() # NEED TO SET LATER
42        return self.prev_soln

Wrapper for _forward_solve to save output.

def new_init_guess(self):
48    def new_init_guess(self):
49        """Wrapper for _create_initial_guess returning saved soln."""
50        if not hasattr(self, "prev_soln"):
51            return self._intercepted_create_initial_guess()
52        else:
53            return self.prev_soln

Wrapper for _create_initial_guess returning saved soln.