Skip to content

Commit

Permalink
V0.1.0rc (#33)
Browse files Browse the repository at this point in the history
* initial code skeleton with travis, docker, and codecov

* Basicfunc (#10)

* wrote basic class for observational data

* added code and unit tests for basis components

* ported code for assembling forcing covariance to repo

* implemented tests for interpolation matrix

* implemented parallel version of interpolation matrix

* added model discrepancy constant factor to class

* updated forcing covariance to be consistent with parallelization

* modified coordinates to extract full degree of freedom information for computations

* changed interpolation calculation to projection for generality

* reordered arguments to interpolation matrix

* fixed bugs in forcing covariance implementaiton

* added unit test for forcing covariance solve

* changes to assembly and added multiplication to forcing covariance class

* parallelized solves to form forcing covariance

* modified data and discrepancy classes to handle parallel solves

* minor tweak to forcing covariance to determine local ownership

* reworked solving routines

* tweaks to init file and setup file

* expanded readme file

* refactored ObsData and ModelDiscrepancy to a single class with external parameters

* refactored interpolation matrix parallelization

* various fixes, implementation of solver routines

* modified solving routines and fixed some unit tests

* reorganized tests to move common test cases to a set of shared functions

* added test for solve_posterior_covariance

* added parallel test for posterior solves

* finished testing of intial solving routines

* modified travis file and added makefile to run mpi tests

* added additional covariance function derivatives and reworked some unit tests in parallel

* fixed an issue with parallelization and cleaned up implementation

* initial implementation of estimation pieces

* reworked estimation routines to cache the prior mean and covariance to improve performance

* commented out parallel solves test that is hanging

* commented out more solving tests

* added back in the parallel test

* debugging test that is hanging

* commented out tests for debugging travis

* uncommenting for debugging purposes

* continue debugging

* more debugging

* more debugging changes

* added additional solving unit test

* solving unit tests

* data unit tests

* interpolation matrix tests

* added forcing covariance tests

* added back all unit tests

* added assemble function and tests

* added generating process solvers

* commented out solve tests for debugging

* added back in new unit tests

* added back in another unit test

* additional unit test

* rewrote posterior covariance solve to avoid explicitly inverting any matrices and added in a test

* continuing additional unit tests

* all unit tests are back in the code

* still have a hanging test, commenting out again

* removed explicit parallel tests

* removed all tests except solving

* added utility solves

* added data tests

* new combination of unit tests

* forcing covariance unit tests

* estimation unit tests

* all unit tests back in

* putting in assertions to figure out where it hangs

* putting in assertions in parallel

* move up assertion to see where it hangs

* move up assertion again

* move up assertion further

* dialing in location of problem

* more checks on where it hangs

* multiple checks in new tests

* attempting to use fixtures to avoid problems

* more fixtures added to test suite

* replaced all helpers with fixtures and have solves working

* refactoring unit tests to use fixtures

* finished refactor of tests to use fixtures

* improved forcing covariance computational efficiency

* minor changes to readme

* fixed unit test for rewritten forcing covariance computation

* improved docstrings for ObsData class

* refactored interpolation matrix to externalize covariance solve

* added prediction solves and unit tests

* moved solves to LinearSolver class

* refactored MAP routines into linear solver and added priors

* added docstrings for assembly, covariance functions, and estimation functions

* added example script of Poisson demo

* added docstrings for linear solver class

* initial commit of sphinx documentation

* filled out documentation files and renamed covariance functions for consistency

* added requirements file for testing and for building documentation

* fixed assemble function to match updated firedrake interface

* fixed import for Poisson example

* tweaks to readme

* modified docker file to install and run test suite straight away

* fixed bug in poisson example, tweaked params, added comments

* added firedrake to mock imports list

* adding all packages to mock list

* set up mocking to allow import of stat-fem

* added ufl to mock list

* added mpi to mock list

* removed firedrake from requirements as it breaks installation procedures

* cleaned up conf file

* added yaml file to configure readthedocs build

* added badges to readme and trying to fix coverage reports

* trying to fix coverage reports

* removing coverage from mpi tests again

* cleaned up travis file and added update

* Travisbuild (#18)

* trying to do a native firedrake install on travis

* modified travis script

* fixed install command

* fixed waiting command

* increased waiting time for firedrake install

* configuring build to avoid problems

* trying to look at install log

* print log if failure

* changed script for debugging

* print contents of include directory

* deactivating venv

* more tweaking install process

* checking python version

* looking for base python installation

* trying a minimal image

* fixed install, now try to run tests

* fixed typo in travis file

* fixed issue with garbage collection during tests (#21)

* revised readme

* removed imports in interpolation matrix

* fixed string method in interpolation matrix

* set up placeholder for unassembled Forcing Covariance matrix

* cleaned up a bit of code

* removed unneeded imports

* removed imports from solving utilities

* removed unused imports from observational data class

* added more details to assertion statements

* updated dockerfile to use devel for merge

* corrected unit test to match string formatting change

* Feature/docs (#30)

* reworked docs and added installation page, started on overview and tutorial

* expanded overview in docs

finished first version of the overview page

* updated tutorial in documentation

* updated example and created files for tutorial

* corrected typesetting in docs page

* incremented version for merge into devel

* Fix/docker (#32)

* reworked docs and added installation page, started on overview and tutorial

* expanded overview in docs

finished first version of the overview page

* updated tutorial in documentation

* updated example and created files for tutorial

* corrected typesetting in docs page

* incremented version for merge into devel

* fixed dockerfile

* set version number for release
  • Loading branch information
edaub authored Oct 19, 2020
1 parent fa02f5f commit 606c413
Show file tree
Hide file tree
Showing 48 changed files with 4,830 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,6 @@ venv.bak/

# mypy
.mypy_cache/

# version file
stat_fem/version.py
13 changes: 13 additions & 0 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: 2

sphinx:
configuration: docs/conf.py

formats: all

python:
version: 3.7
install:
- requirements: requirements.txt
- method: setuptools
path: .
19 changes: 19 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
language: minimal
dist: bionic
before_install:
- sudo apt-get -y install build-essential autoconf automake bison flex cmake gfortran git libblas-dev liblapack-dev libtool python3-dev python3-pip python3-tk python3-venv zlib1g-dev libboost-dev
- cd /home/travis/build/alan-turing-institute/
- curl -O https://raw.githubusercontent.com/firedrakeproject/firedrake/master/scripts/firedrake-install
- travis_wait 90 python3 firedrake-install --no-package-manager --disable-ssh
install:
- source /home/travis/build/alan-turing-institute/firedrake/bin/activate
- cd /home/travis/build/alan-turing-institute/stat-fem/
- pip install -r requirements.txt
- pip install -r requirements-dev.txt
- python setup.py install
script:
- cd /home/travis/build/alan-turing-institute/stat-fem/stat_fem/tests
- make tests
after_success:
- codecov

149 changes: 149 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,151 @@
# stat-fem

Python tools for solving data-constrained finite element problems

[![Build Status](https://travis-ci.com/alan-turing-institute/stat-fem.svg?branch=master)](https://travis-ci.com/alan-turing-institute/stat-fem)
[![codecov](https://codecov.io/gh/alan-turing-institute/stat-fem/branch/master/graph/badge.svg)](https://codecov.io/gh/alan-turing-institute/stat-fem)
[![Documentation Status](https://readthedocs.org/projects/stat-fem/badge/?version=latest)](https://stat-fem.readthedocs.io/en/latest/?badge=latest)

## Overview

This package provides a Python implementation of the Statistical Finite Element Method (FEM) as
described in the paper by Girolami et al. [1] to use data observations to constrain
FEM models. The package builds on top of Firedrake [2] to assemble the underlying FEM system
and uses PETSc [3-4] to perform the sparse linear algebra routines. These tools should allow
the user to create efficient, scalable solvers based on high level Python code to address
challenging problems in data-driven numerical analysis.

## Installation

### Installing Firedrake

`stat-fem` requires a working Firedrake installation. The easiest way to obtain Firedrake is to
follow the installation instructions on the [firedrake homepage](https://www.firedrakeproject.org).

### Installing stat-fem

Once you have installed Firedrake, activate the virtual environment that was created as part of
the installation process. Within the running virtual environment, switch to the main `stat-fem`
directory and proceed with the installation by entering:

```bash
$ pip install -r requirements.txt
$ python setup.py install
```

This will use `pip` to install any missing dependencies (notably Scipy) and install the `stat-fem`
package within the Firedrake virtual environment.

### Using a Docker Container

Alternatively, we provide a working Firedrake Docker container that has the `stat-fem` code
and dependencies installed within the Firedrake virtual environment. See the `docker`
directory in the `stat-fem` repository.

### Testing the installation

The code comes with a full suite of unit tests. Running the test suite uses pytest and pytest-mpi
to collect and run the tests. To run the tests on a single process, simply enter `pytest` into
the running virtual environment from any location in the stat-fem directory. To run the test
suite in parallel, enter `mpiexec -n 2 python -m pytest --with-mpi` or
`mpiexec -n 4 python -m pytest --with-mpi` depending on the number of desired
processes to be used. Tests have only been written for 2 and 4 processes, so
you may get a failure if you attempt to use other choices for the number
of processes.

## Parallelism

The various solves required for the Statistical FEM can be done in parallel in several ways.

### Parallel base solves

To parallelize the solution of the base FEM model, you can simply run your Python script under MPI
to divide the FEM mesh among the given number of processes. This is handled natively in Firedrake
as well as stat-fem. For instance, depending on your system setup you would enter:

```bash
$ mpiexec -n 4 python model.py
```

The nodes owned by each process are determined when forming the mesh, and this manages all interprocess
communication when performing the matrix inversion to solve the resulting linear system.

While the mesh degrees of freedom in the FEM are divided among the processors, the data is always
held at the root process, as the data dimension is usually significantly less than the number
of degrees of freedom in the mesh and the solves involving the data are unlikely to benefit from
running in parallel due to the communication overhead involved. Therefore, all matrix computations
done in the "data space" that are needed for the solves are done on the root process The collection
of data at root and dispersal of data to the mesh is handled through the interpolation matrix, which
is automatically constructed when performing a solve and should not require any modification when
solving a given problem.

### Parallel Covariance Solves

To compute the FEM model posterior conditioned on the data, one must perform 2 FEM solves per data
constraint. This is the principal computational cost in computing the model posterior once the
other matrices in the system have been assembled. Each data constraint can be handled independently,
and thus this step in the computation can be parallelized.

This parallelization is handled through the Firedrake `Ensemble` class. An ensemble creates
two different MPI communicators: one that parallelizes the base solves (the base communicator,
which is an `Ensemble` class attribute `comm`), and one that parallelizes the covariance solves
(the ensemble communicator, an `Ensemble` class attributed `ensemble_comm`). Each process has a
unique pair of ranks across the two communicators. When creating a Firedrake Ensemble, you must
do so before creating the mesh, and use the base communicator in the ensemble to create the mesh.
The ensemble communicator, if used, is passed to the solving routine when it is called.

When running a script using this type of parallelism, the user must specify how to divide the
MPI processes across the two different types of solves. This is done when constructing the
`Ensemble` instance. For example, if you wish you use 4 processes total, with 2 dedicated to each
base solve and 2 processes over which the data constraint solves will be done, you would do the
following in the file `model.py`:

```python
from firedrake import Ensemble, COMM_WORLD, UnitSquareMesh

my_ensemble = Ensemble(COMM_WORLD, 2)

# divide mesh across two processes in base comm
mesh = UnitSquareMesh(51, 51, comm=my_ensemble.comm)

...
```

Then run the python script with `mpiexec -n 4 python model.py`

Note that it is up to the user to ensure that the total number of processes is divisible by the base
number of processes. One way to handle this more robustly would be to use input arguments to manage
the number of processes in a particular script.

## Example Scripts

An example illustrating the various code capabilities and features is included in
the `stat-fem/examples` directory.

## Contact

This software was written by Eric Daub as part of a project with the Research Engineering Group at the
Alan Turing Institute.

Any bugs or issues should be filed in the issue tracker on the main Github page.

## References

[1] Mark Girolami, Alastair Gregory, Ge Yin, and Fehmi Cirak. The Statistical Finite Element
Method. 2019. URL: http://arxiv.org/abs/1905.06391, arXiv:1905.06391.

[2] Florian Rathgeber, David A. Ham, Lawrence Mitchell, Michael Lange, Fabio Luporini,
Andrew T. T. Mcrae, Gheorghe-Teodor Bercea, Graham R. Markall, and Paul H. J. Kelly.
Firedrake: automating the finite element method by composing abstractions. *ACM Trans.
Math. Softw.*, 43(3):24:1–24:27, 2016. URL: http://arxiv.org/abs/1501.01809,
arXiv:1501.01809, doi:10.1145/2998441.

[3] L. Dalcin, P. Kler, R. Paz, and A. Cosimo, Parallel Distributed Computing using Python,
Advances in Water Resources, 34(9):1124-1139, 2011.
http://dx.doi.org/10.1016/j.advwatres.2011.04.013

[4] S. Balay, S. Abhyankar, M. Adams, J. Brown, P. Brune, K. Buschelman, L. Dalcin, A. Dener,
V. Eijkhout, W. Gropp, D. Karpeyev, D. Kaushik, M. Knepley, D. May, L. Curfman McInnes,
R. Mills, T. Munson, K. Rupp, P. Sanan, B. Smith, S. Zampini, H. Zhang, and H. Zhang,
PETSc Users Manual, ANL-95/11 - Revision 3.12, 2019.
http://www.mcs.anl.gov/petsc/petsc-current/docs/manual.pdf
31 changes: 31 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# DockerFile for stat-fem

FROM firedrakeproject/firedrake:latest

# This DockerFile is looked after by
MAINTAINER Eric Daub <[email protected]>

# install stat-fem

USER firedrake
WORKDIR /home/firedrake/firedrake/src
RUN bash -c "source /home/firedrake/firedrake/bin/activate && \
git clone https://github.com/alan-turing-institute/stat-fem.git && \
cd stat-fem && \
pip install -r requirements.txt && \
pip install -r requirements-dev.txt && \
python setup.py install"

# create share directory for outputs

USER firedrake
WORKDIR /home/firedrake
RUN bash -c "mkdir -p share"

# set up bashrc to automatically activate virtualenv

RUN echo "source /home/firedrake/firedrake/bin/activate" >> /home/firedrake/.bashrc

USER firedrake
WORKDIR /home/firedrake/
ENTRYPOINT /bin/bash
19 changes: 19 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SOURCEDIR = .
BUILDDIR = _build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
Loading

0 comments on commit 606c413

Please sign in to comment.