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 - "" - -