diff --git a/INSTALL.md b/INSTALL.md
new file mode 100644
index 00000000..dcd61d51
--- /dev/null
+++ b/INSTALL.md
@@ -0,0 +1,178 @@
+# Installation Guide
+
+## Basic install
+
+Most users will be fine using the binary bundled in the default `pip` install:
+
+```shell
+pip install mfem
+```
+The above installation will download and install a *serial* version of `MFEM`.
+
+## Building from source
+PyMFEM has many options for installation, when building from source, including:
+ - Serial and parallel (MPI) wrappers
+ - Using pre-built local dependencies
+ - Installing additional dependencies such as
+ - `hypre`
+ - `gslib`
+ - `libceed`
+ - `metis`
+
+Most of the options for PyMFEM can be used directly when installing via `python setup.py install`, e.g.
+```shell
+git clone git@github:mfem/PyMFEM.git
+cd PyMFEM
+python setup.py install --user
+```
+For example, parallel (MPI) support is built with the `--with-parallel` flag:
+```shell
+python setup.py install --with-parallel
+```
+
+Note: this option turns on building `metis` and `Hypre`
+
+## Commonly used flags
+
+| Flag | Description |
+|------|-------------|
+| `--with-parallel` | Install both serial and parallel versions of `MFEM` and the wrapper
(note: this option turns on building `metis` and `hypre`) |
+| `--mfem-branch=` | Download/install MFEM using a specific reference (`git` `branch`, `hash`, or `tag`) |
+| `--user` | Install in user's site-package |
+
+In order to see the full list of options, use
+
+```shell
+python setup.py install --help
+```
+
+## Advanced options
+
+### Suitesparse
+`--with-suitesparse` : build MFEM with `suitesparse`. `suitesparse` needs to be installed separately.
+Point to the location of `suitesparse` using the flag `--suitesparse-prefix=`
+
+Note: this option turns on building `metis` in serial
+
+### CUDA
+`--with-cuda` : build MFEM with CUDA. Hypre cuda build is also supported using
+`--with-cuda-hypre`. `--cuda-arch` can be used to specify cuda compute capablility.
+(See table in https://en.wikipedia.org/wiki/CUDA#Supported_GPUs)
+
+CUDA needs to be installed separately and nvcc must be found in PATH ([Example](https://github.com/mfem/PyMFEM/blob/e1466a6a/.github/workflows/build-and-test-callable.yml#L111-L122)).
+
+(examples)
+```shell
+python setup.py install --with-cuda
+
+python setup.py install --with-cuda --with-cuda-hypre
+
+python setup.py install --with-cuda --with-cuda-hypre --cuda-arch=80 (A100)
+
+python setup.py install --with-cuda --with-cuda-hypre --cuda-arch=75 (Turing)
+```
+
+### gslib
+`--with-gslib` : build MFEM with [GSlib](https://github.com/Nek5000/gslib)
+
+Note: this option downloads and builds GSlib
+
+### libCEED
+`--with-libceed` : build MFEM with [libCEED](https://github.com/CEED/libCEED)
+
+Note: this option downloads and builds libCEED
+
+### Specifying compilers
+| Flag | Description |
+|------|--------|
+| `--CC` | c compiler |
+| `--CXX` | c++ compiler |
+| `--MPICC` | mpic compiler |
+| `--MPICXX` | mpic++ compiler |
+
+(example)
+Using Intel compiler
+```shell
+python setup.py install --with-parallel --CC=icc, --CXX=icpc, --MPICC=mpiicc, --MPICXX=mpiicpc
+```
+
+### Building MFEM with specific version
+By default, setup.py build MFEM with specific SHA (which is usually the released latest version).
+In order to use the latest MFEM in Github. One can specify the branch name or SHA using mfem-branch
+option.
+
+`--mfem-branch = `
+
+(example)
+```shell
+python setup.py install --mfem-branch=master
+```
+
+### Using MFEM build externally.
+These options are used to link PyMFEM wrapper with existing MFEM library. We need `--mfem-source`
+and `--mfem-prefix`
+
+| Flag | Description |
+|----------------------------|-------------------------------------------------------------------|
+| `--mfem-source ` | The location of MFEM source used to build MFEM |
+| `--mfem-prefix ` | The location of the MFEM library. `libmfem.so` needs to be found in `/lib` |
+| `--mfems-prefix `| (optional) Specify serial MFEM location separately |
+| `--mfemp-prefix `| (optional) Specify parallel MFEM location separately |
+
+
+### Blas and Lapack
+--with-lapack : build MFEM with lapack
+
+`` is used for CMAKE call to buid MFEM
+`--blas-libraries=`
+`--lapack-libraries=`
+
+### Options for development and testing
+| Flag | Description |
+|------|--------|
+| `--swig` | run swig only |
+| `--skip-swig` | build without running swig` |
+| `--skip-ext` | skip building external libraries.|
+| `--ext-only` | build exteranl libraries and exit.|
+
+During the development, often we update depenencies (such as MFEM) and edit `*.i` file.
+
+
+First clean everything.
+
+```shell
+python setup.py clean --all
+```
+
+Then, build externals alone
+```shell
+python setup.py install --with-parallel --ext-only --mfem-branch=master
+```
+
+Then, genrate swig wrappers.
+```shell
+python setup.py install --with-parallel --swig --mfem-branch=master
+```
+
+If you are not happy with the wrapper (`*.cxx` and `*.py`), you edit `*.i` and redo
+the same. When you are happy, build the wrapper. `--swig` does not clean the
+existing wrapper. So, it will only update wrapper for updated `*.i`
+
+When building a wrapper, you can use `--skip-ext` option. By default, it will re-run
+swig to generate entire wrapper codes.
+```shell
+python setup.py install --with-parallel --skip-ext --mfem-branch=master
+```
+
+If you are sure, you could use `--skip-swig` option, so that it compiles the wrapper
+codes without re-generating it.
+```shell
+python setup.py install --with-parallel --skip-ext --skip-swig --mfem-branch=master
+```
+
+### Other options
+`--unverifiedSSL` :
+ This addresses error relating SSL certificate. Typical error message is
+ ``
+
+
diff --git a/README.md b/README.md
index ef100cd9..ac293a66 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ By default, "pip install mfem" downloads and builds the serial version of MFEM a
Additionally, the installer supports building MFEM with specific options together with other external libraries, including MPI version.
## Install
-```bash
+```shell
pip install mfem # binary install is available only on linux platforms (Py36-310)
pip install mfem --no-binary mfem # install serial MFEM + wrapper from source
@@ -24,12 +24,12 @@ and build parallel version of MFEM library (linked with Metis and Hypre)
and installs under /mfem. See also, docs/install.txt
### Using pip
-```bash
-$ pip install mfem --install-option="--with-parallel"
+```shell
+pip install mfem --install-option="--with-parallel"
```
### Build from local source file
-```python
+```shell
# Download source and build
$ pip download mfem --no-binary mfem (expand tar.gz file and move to the downloaded directory)
or clone this repository
@@ -59,36 +59,42 @@ $ python setup.py install --help
```
## Usage
-Here is an example to solve div(alpha grad(u)) = f in a square and to plot the result
-with matplotlib (modified from ex1.cpp). Use the badge above to open this in Binder.
+This example (modified from `ex1.cpp`) solves the Poisson equation,
+$$\nabla \cdot (\alpha \nabla u) = f$$
+in a square and plots the result using matplotlib.
+Use the badge above to open this in Binder.
+
```python
import mfem.ser as mfem
-# create sample mesh for square shape
+# Create a square mesh
mesh = mfem.Mesh(10, 10, "TRIANGLE")
-# create finite element function space
+# Define the finite element function space
fec = mfem.H1_FECollection(1, mesh.Dimension()) # H1 order=1
fespace = mfem.FiniteElementSpace(mesh, fec)
-#
+# Define the essential dofs
ess_tdof_list = mfem.intArray()
ess_bdr = mfem.intArray([1]*mesh.bdr_attributes.Size())
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list)
-# constant coefficient (diffusion coefficient and RHS)
+# Define constants for alpha (diffusion coefficient) and f (RHS)
alpha = mfem.ConstantCoefficient(1.0)
rhs = mfem.ConstantCoefficient(1.0)
-# Note:
-# Diffusion coefficient can be variable. To use numba-JIT compiled
-# functio. Use the following, where x is numpy-like array.
-# @mfem.jit.scalar
-# def alpha(x):
-# return x+1.0
-#
+"""
+Note
+-----
+In order to represent a variable diffusion coefficient, you
+must use a numba-JIT compiled function. For example:
-# define Bilinear and Linear operator
+>>> @mfem.jit.scalar
+>>> def alpha(x):
+>>> return x+1.0
+"""
+
+# Define the bilinear and linear operators
a = mfem.BilinearForm(fespace)
a.AddDomainIntegrator(mfem.DiffusionIntegrator(alpha))
a.Assemble()
@@ -96,38 +102,37 @@ b = mfem.LinearForm(fespace)
b.AddDomainIntegrator(mfem.DomainLFIntegrator(rhs))
b.Assemble()
-# create gridfunction, which is where the solution vector is stored
-x = mfem.GridFunction(fespace);
+# Initialize a gridfunction to store the solution vector
+x = mfem.GridFunction(fespace)
x.Assign(0.0)
-# form linear equation (AX=B)
+# Form the linear system of equations (AX=B)
A = mfem.OperatorPtr()
B = mfem.Vector()
X = mfem.Vector()
-a.FormLinearSystem(ess_tdof_list, x, b, A, X, B);
+a.FormLinearSystem(ess_tdof_list, x, b, A, X, B)
print("Size of linear system: " + str(A.Height()))
-# solve it using PCG solver and store the solution to x
+# Solve the linear system using PCG and store the solution in x
AA = mfem.OperatorHandle2SparseMatrix(A)
M = mfem.GSSmoother(AA)
mfem.PCG(AA, M, B, X, 1, 200, 1e-12, 0.0)
a.RecoverFEMSolution(X, b, x)
-# extract vertices and solution as numpy array
+# Extract vertices and solution as numpy arrays
verts = mesh.GetVertexArray()
sol = x.GetDataArray()
-# plot solution using Matplotlib
-
+# Plot the solution using matplotlib
import matplotlib.pyplot as plt
import matplotlib.tri as tri
triang = tri.Triangulation(verts[:,0], verts[:,1])
-fig1, ax1 = plt.subplots()
-ax1.set_aspect('equal')
-tpc = ax1.tripcolor(triang, sol, shading='gouraud')
-fig1.colorbar(tpc)
+fig, ax = plt.subplots()
+ax.set_aspect('equal')
+tpc = ax.tripcolor(triang, sol, shading='gouraud')
+fig.colorbar(tpc)
plt.show()
```
![](https://raw.githubusercontent.com/mfem/PyMFEM/master/docs/example_image.png)
diff --git a/docs/install.txt b/docs/install.txt
deleted file mode 100644
index c3a7224f..00000000
--- a/docs/install.txt
+++ /dev/null
@@ -1,130 +0,0 @@
-# Install Guide
-
-PyMFEM wrapper provides MPI version and non-MPI version of wrapper.
-
-Default pip install installs serial MFEM + wrapper
-
-$ pip install mfem
-or
-$ pip install mfem --no-binary mfem
-
-For other configuration such as parallel version, one can either use --install-option
-flags with pip or download the package as follows and run setup script, manually.
-
-$ pip download mfem --no-binary mfem
-
-In order to see the full list of options, use
-
-$ python setup.py install --help
-
-In below, for the brevity, examples are mostly shown using "python setup.py install" convention.
-When using PIP, each option needs to be passed using --install-option.
-
-## Parallel MFEM
---with-parallel : build both serial and parallel version of MFEM and wrapper
-
-Note: this option turns on building metis and Hypre
-
-## Suitesparse
---with-suitesparse : build MFEM with suitesparse. SuiteSparse needs to be installed separately.
---suitesparse-prefix=
-
-Note: this option turns on building metis in serial
-
-## CUDA
---with-cuda option build MFEM with CUDA. Hypre cuda build is also supported using
---with-cuda-hypre. --cuda-arch can be used to specify cuda compute capablility.
-(See table in https://en.wikipedia.org/wiki/CUDA#Supported_GPUs)
-
--with-cuda : build MFEM using CUDA on
---cuda-arch= : specify cuda compute capability version
---with-cuda-hypre : build Hypre with cuda
-
-(example)
-$ python setup.py install --with-cuda
-$ python setup.py install --with-cuda --with-cuda-hypre
-$ python setup.py install --with-cuda --with-cuda-hypre --cuda-arch=80 (A100)
-$ python setup.py install --with-cuda --with-cuda-hypre --cuda-arch=75 (Turing)
-
-## gslib
---with-gslib : build MFEM with GSlib
-
-Note: this option builds GSlib
-
-## libceed
---with-libceed : build MFEM with libceed
-Note: this option builds libceed
-
-## Specify compilers
---CC c compiler
---CXX c++ compiler
---MPICC mpic compiler
---MPICXX mpic++ compiler
-
-(example)
-Using Intel compiler
-$ python setup.py install --with-parallel --CC=icc, --CXX=icpc, --MPICC=mpiicc, --MPICXX=mpiicpc
-
-## Building MFEM with specific version
-By default, setup.py build MFEM with specific SHA (which is usually the released latest version).
-In order to use the latest MFEM in Github. One can specify the branch name or SHA using mfem-branch
-option.
-
--mfem-branch =
-
-(example)
-$ python setup.py install --mfem-branch=master
-
-## Using MFEM build externally.
-These options are used to link PyMFEM wrapper with existing MFEM library. We need --mfem-source
-and --mfem-prefix
-
---mfem-source : : the location of MFEM source used to build MFEM
---mfem-prefix : : the location of MFEM library. libmfem.so needs to be found in /lib
---mfems-prefix : : (optional) specify serial MFEM location separately
---mfemp-prefix : : (ooptional)specify parallel MFEM location separately
-
-## Blas and Lapack
---with-lapack : build MFEM with lapack
-
- is used for CMAKE call to buid MFEM
---blas_-libraries=
---lapack-libraries=
-
-## Development and testing options
---swig : run swig only
---skip-swig : build without running swig
---skip-ext : skip building external libraries.
---ext-only : build exteranl libraries and exit.
-
-During the development, often we update depenencies (such as MFEM) and edit *.i file.
-
-First clean everything.
-
-$ python setup.py clean --all
-
-Then, build externals alone
-$ python setup.py install --with-parallel --ext-only --mfem-branch="master"
-
-Then, genrate swig wrappers.
-$ python setup.py install --with-parallel --swig --mfem-branch="master"
-
-If you are not happy with the wrapper (*.cxx and *.py), you edit *.i and redo
-the same. When you are happy, build the wrapper. --swig does not clean the
-existing wrapper. So, it will only update wrapper for updated *.i
-
-When building a wrapper, you can use --skip-ext option. By default, it will re-run
-swig to generate entire wrapper codes.
-$ python setup.py install --with-parallel --skip-ext --mfem-branch="master"
-
-If you are sure, you could use --skip-swig option, so that it compiles the wrapper
-codes without re-generating it.
-$ python setup.py install --with-parallel --skip-ext --skip-swig --mfem-branch="master"
-
-
-## Other options
---unverifiedSSL :
- This addresses error relating SSL certificate. Typical error message is
- ""
-
-