Overview

ADCME is suitable for conducting inverse modeling in scientific computing. The purpose of the package is to: (1) provide differentiable programming framework for scientific computing based on TensorFlow automatic differentiation (AD) backend; (2) adapt syntax to facilitate implementing scientific computing, particularly for numerical PDE discretization schemes; (3) supply missing functionalities in the backend (TensorFlow) that are important for engineering, such as sparse linear algebra, constrained optimization, etc. Applications include

  • full wavelength inversion

  • reduced order modeling in solid mechanics

  • learning hidden geophysical dynamics

  • physics based machine learning

  • parameter estimation in stochastic processes

The package inherents the scalability and efficiency from the well-optimized backend TensorFlow. Meanwhile, it provides access to incooperate existing C/C++ codes via the custom operators. For example, some functionalities for sparse matrices are implemented in this way and serve as extendable "plugins" for ADCME.

Read more about the methodology and philosophy about ADCME: slides.

Getting Started

To install ADCME, simply type the following commands in Julia REPL

julia> using Pkg; Pkg.add("ADCME")

To enable GPU support for custom operators (if you do not need to compile custom operators, you do not need this step), make sure nvcc command is available on your machine, then

using ADCME
enable_gpu()

We consider a simple inverse modeling problem: consider the following partial differential equation

\[-bu''(x)+u(x)=f(x)\quad x\in[0,1], u(0)=u(1)=0\]

where

\[f(x) = 8 + 4x - 4x^2\]

Assume that we have observed $u(0.5)=1$, we want to estimate $b$. The true value in this case should be $b=1$. We can discretize the system using finite difference method, and the resultant linear system will be

\[(bA+I)\mathbf{u} = \mathbf{f}\]

where

\[A = \begin{bmatrix} \frac{2}{h^2} & -\frac{1}{h^2} & \dots & 0\\ -\frac{1}{h^2} & \frac{2}{h^2} & \dots & 0\\ \dots \\ 0 & 0 & \dots & \frac{2}{h^2} \end{bmatrix}, \quad \mathbf{u} = \begin{bmatrix} u_2\\ u_3\\ \vdots\\ u_{n} \end{bmatrix}, \quad \mathbf{f} = \begin{bmatrix} f(x_2)\\ f(x_3)\\ \vdots\\ f(x_{n}) \end{bmatrix}\]

The idea for implementing the inverse modeling method in ADCME is that we make the unknown $b$ a Variable and then solve the forward problem pretending $b$ is known. The following code snippet shows the implementation

using LinearAlgebra
using ADCME

n = 101 # number of grid nodes in [0,1]
h = 1/(n-1)
x = LinRange(0,1,n)[2:end-1]

b = Variable(10.0) # we use Variable keyword to mark the unknowns
A = diagm(0=>2/h^2*ones(n-2), -1=>-1/h^2*ones(n-3), 1=>-1/h^2*ones(n-3)) 
B = b*A + I  # I stands for the identity matrix
f = @. 4*(2 + x - x^2) 
u = B\f # solve the equation using built-in linear solver
ue = u[div(n+1,2)] # extract values at x=0.5

loss = (ue-1.0)^2 

# Optimization
sess = Session(); init(sess) 
BFGS!(sess, loss)

println("Estimated b = ", run(sess, b))

The expected output is

Estimated b = 0.9995582304494237