Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MultiFab tutorial with pyamrex #95

Merged
merged 9 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/dependencies/dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ sudo apt-get install -y --no-install-recommends\
build-essential \
g++ gfortran \
libopenmpi-dev \
openmpi-bin
openmpi-bin \
python3 \
python3-pip

python3 -m pip install -U pip setuptools wheel
6 changes: 5 additions & 1 deletion .github/workflows/dependencies/dependencies_clang6.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@ sudo apt-get update

sudo apt-get install -y \
build-essential \
clang gfortran
clang gfortran \
python3 \
python3-pip

python3 -m pip install -U pip setuptools wheel
6 changes: 5 additions & 1 deletion .github/workflows/dependencies/dependencies_gcc10.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ sudo apt-get install -y --no-install-recommends \
build-essential \
g++-10 gfortran-10 \
libopenmpi-dev \
openmpi-bin
openmpi-bin \
python3 \
python3-pip

python3 -m pip install -U pip setuptools wheel
6 changes: 5 additions & 1 deletion .github/workflows/dependencies/dependencies_nofortran.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@ sudo apt-get install -y --no-install-recommends\
build-essential \
g++ \
libopenmpi-dev \
openmpi-bin
openmpi-bin \
python3 \
python3-pip

python3 -m pip install -U pip setuptools wheel
68 changes: 44 additions & 24 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,21 @@ jobs:
- name: Build & Install
run: |
cd ExampleCodes
mkdir build
cd build
cmake .. \
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DAMReX_LINEAR_SOLVERS=ON \
-DAMReX_FORTRAN=ON \
-DAMReX_FORTRAN_INTERFACES=ON \
-DAMReX_EB=ON \
-DAMReX_PARTICLES=ON
make -j 2
-DAMReX_PARTICLES=ON \
-DTUTORIAL_PYTHON=ON
cmake --build build -j 2
cmake --build build -j 2 --target pyamrex_pip_install
- name: Run Python
run: |
cd GuidedTutorials/MultiFab/
python main.py

# Build all tutorials
tutorials_cxx20:
Expand All @@ -40,22 +44,26 @@ jobs:
- name: Build & Install
run: |
cd ExampleCodes
mkdir build
cd build
cmake .. \
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DAMReX_OMP=ON \
-DAMReX_PARTICLES=ON \
-DAMReX_LINEAR_SOLVERS=ON \
-DAMReX_FORTRAN=ON \
-DAMReX_FORTRAN_INTERFACES=ON \
-DAMReX_EB=ON \
-DAMReX_EB=ON \
-DTUTORIAL_PYTHON=ON \
-DCMAKE_CXX_STANDARD=20 \
-DCMAKE_C_COMPILER=$(which gcc-10) \
-DCMAKE_CXX_COMPILER=$(which g++-10) \
-DCMAKE_Fortran_COMPILER=$(which mpif90)
make -j 2
cmake --build build -j 2
cmake --build build -j 2 --target pyamrex_pip_install
- name: Run Python
run: |
cd GuidedTutorials/MultiFab/
python main.py

tutorials_clang:
name: Clang@6.0 C++14 SP Particles DP Mesh Debug [tutorials]
Expand All @@ -68,9 +76,7 @@ jobs:
- name: Build & Install
run: |
cd ExampleCodes
mkdir build
cd build
cmake .. \
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DAMReX_MPI=OFF \
Expand All @@ -81,11 +87,17 @@ jobs:
-DAMReX_EB=ON \
-DAMReX_PRECISION=DOUBLE \
-DAMReX_PARTICLES_PRECISION=SINGLE \
-DTUTORIAL_PYTHON=ON \
-DCMAKE_CXX_STANDARD=14 \
-DCMAKE_C_COMPILER=$(which clang) \
-DCMAKE_CXX_COMPILER=$(which clang++) \
-DCMAKE_Fortran_COMPILER=$(which gfortran)
make -j 2
cmake --build build -j 2
cmake --build build -j 2 --target pyamrex_pip_install
- name: Run Python
run: |
cd GuidedTutorials/MultiFab/
python main.py

# Build all tutorials w/o MPI
tutorials-nonmpi:
Expand All @@ -99,18 +111,22 @@ jobs:
- name: Build & Install
run: |
cd ExampleCodes
mkdir build
cd build
cmake .. \
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DAMReX_MPI=OFF \
-DAMReX_LINEAR_SOLVERS=ON \
-DAMReX_FORTRAN=ON \
-DAMReX_FORTRAN_INTERFACES=ON \
-DAMReX_EB=ON \
-DAMReX_PARTICLES=ON
make -j 2
-DAMReX_PARTICLES=ON \
-DTUTORIAL_PYTHON=ON
cmake --build build -j 2
cmake --build build -j 2 --target pyamrex_pip_install
- name: Run Python
run: |
cd GuidedTutorials/MultiFab/
python main.py

# Build all tutorials
tutorials-nofortran:
Expand All @@ -124,16 +140,20 @@ jobs:
- name: Build & Install
run: |
cd ExampleCodes
mkdir build
cd build
cmake .. \
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DAMReX_LINEAR_SOLVERS=ON \
-DAMReX_EB=ON \
-DAMReX_PARTICLES=ON \
-DAMReX_FORTRAN=OFF
make -j 2
-DAMReX_FORTRAN=OFF \
-DTUTORIAL_PYTHON=ON
cmake --build build -j 2
cmake --build build -j 2 --target pyamrex_pip_install
- name: Run Python
run: |
cd GuidedTutorials/MultiFab/
python main.py

# Build all tutorials with CUDA 11.0.2 (recent supported)
tutorials-cuda11:
Expand Down
17 changes: 17 additions & 0 deletions Docs/source/Python_Tutorial.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.. _tutorials_python:

======
Python
======

These examples show how to use AMReX from Python.
AMReX applications can also be interfaced to Python with the same logic.

In order to build the Python tutorials, add ``-DTUTORIAL_PYTHON=ON`` to the CMake configuration options.
Then install with ``cmake --build build --target pyamrex_pip_install``.

Examples:

- ``GuidedTutorials/MultiFab/main.py``

Please see `pyAMReX <https://github.com/AMReX-Codes/pyamrex/>`__ for more details.
4 changes: 4 additions & 0 deletions Docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ sorted by the following categories:
- :ref:`Linear Solvers<tutorials_linearsolvers>` -- Examples of several linear solvers.
- :ref:`MUI<tutorials_mui>` -- Incorporates the MxUI/MUI (Multiscale Universal interface) frame into AMReX.
- :ref:`Particles<tutorials_particles>` -- Basic usage of AMReX's particle data structures.
- :ref:`Python<tutorials_python>` -- Using AMReX and interfacing with AMReX applications form Python - via `pyAMReX <https://github.com/AMReX-Codes/pyamrex/>`__
- :ref:`SDC<tutorials_sdc>` -- Example usage of a "Multi-Implicit" Spectral Deferred Corrections (MISDC) integrator
to solve a scalar advection-diffusion-reaction equation.
- :ref:`SENSEI<tutorials_sensei>` -- In situ data analysis and visualization through a unified interface.
Expand All @@ -71,6 +72,7 @@ sorted by the following categories:
ML_Tutorial
MUI_Tutorial
Particles_Tutorial
Python_Tutorial
SDC_Tutorial
SENSEI_Tutorial
SUNDIALS_Tutorial
Expand All @@ -95,6 +97,8 @@ sorted by the following categories:

.. _`Particles`: Particles_Tutorial.html

.. _`Python`: Python_Tutorial.html

.. _`SDC`: SDC_Tutorial.html

.. _`SENSEI`: SENSEI_Tutorial.html
Expand Down
50 changes: 47 additions & 3 deletions ExampleCodes/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,34 @@ set( CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake )
# If AMReX_DIR is passed then we link to the library found there. Otherwise
# the sources are fetched and compiled from the repo pointed to by AMReX_GIT_REPO
#
set ( AMReX_GIT_REPO "https://github.com/AMReX-Codes/amrex.git/"
CACHE STRING "The URL identifying the repo to fetchg AMReX from" )
set ( AMReX_GIT_REPO "https://github.com/AMReX-Codes/amrex.git"
CACHE STRING "The URL identifying the repo to fetch AMReX from" )

#
# Fetch and compile AMReX or link to an existing CMake build install of libamrex.
# If AMReX_DIR is passed then we link to the library found there. Otherwise
# the sources are fetched and compiled from the repo pointed to by AMReX_GIT_REPO
# the sources are fetched and compiled from the repo pointed to by pyAMReX_GIT_REPO
#
set ( pyAMReX_GIT_REPO "https://github.com/AMReX-Codes/pyamrex.git"
CACHE STRING "The URL identifying the repo to fetch pyAMReX from" )
option(TUTORIAL_PYTHON OFF)

#
# Fetch and compile AMReX or link to an existing CMake build install of libamrex.
# If AMReX_DIR is passed then we link to the library found there. Otherwise
# the sources are fetched and compiled from the repo pointed to by SUNDIALS_GIT_REPO
#
set ( SUNDIALS_GIT_REPO "https://github.com/LLNL/sundials.git"
CACHE STRING "The URL identifying the repo to fetch SUNDIALS from" )

#
# For Python, we need AMReX as a a sahred library, otherwise we cannot share all
# its global variables between multiple Python modules
#
if(TUTORIAL_PYTHON)
set(AMReX_BUILD_SHARED_LIBS ON CACHE BOOL "Build AMReX shared library" FORCE)
endif()

if( NOT DEFINED AMReX_DIR )
#
# Fetch amrex repo
Expand Down Expand Up @@ -174,6 +191,33 @@ else()
endif()
endif()

if(TUTORIAL_PYTHON)
if(DEFINED pyAMReX_DIR)
add_subdirectory(${pyAMReX_DIR})
else()
#
# Fetch pyAMReX repo
#
message(STATUS "Fetching from ${pyAMReX_GIT_REPO} branch ${pyAMReX_GIT_BRANCH}" )

set(pyAMReX_GIT_BRANCH "development" CACHE STRING "The pyAMReX branch to checkout")
set(pyAMReX_INSTALL "NO" CACHE INTERNAL "Disable install target for pyAMReX")

include(FetchContent)
#set(FETCHCONTENT_QUIET OFF) # Verbose ON

FetchContent_Declare( fetchedpyamrex
GIT_REPOSITORY ${pyAMReX_GIT_REPO}
GIT_TAG ${pyAMReX_GIT_BRANCH}
)

if(NOT fetchedpyamrex_POPULATED)
FetchContent_Populate(fetchedpyamrex)
add_subdirectory(${fetchedpyamrex_SOURCE_DIR} ${fetchedpyamrex_BINARY_DIR})
endif()
endif()
endif()

#
# List of subdirectories to search for CMakeLists.
# For now, we do not include MUI, SDC, SWFFT
Expand Down
92 changes: 92 additions & 0 deletions GuidedTutorials/MultiFab/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import numpy as np
ax3l marked this conversation as resolved.
Show resolved Hide resolved
import amrex.space3d as amr

# Initialize AMReX
amr.initialize([])

if amr.ParallelDescriptor.IOProcessor():
print(f"Hello world from pyAMReX version {amr.__version__}\n")

# Goals:
# * Define a MultiFab
# * Fill a MultiFab with data
# * Plot it

# Parameters

# Number of data components at each grid point in the MultiFab
ncomp = 1
# How many grid cells in each direction over the problem domain
n_cell = 32
# How many grid cells are allowed in each direction over each box
max_grid_size = 16

# BoxArray: abstract domain setup

# Integer vector indicating the lower coordinate bounds
dom_lo = amr.IntVect(0,0,0)
# Integer vector indicating the upper coordinate bounds
dom_hi = amr.IntVect(n_cell-1, n_cell-1, n_cell-1)
# Box containing the coordinates of this domain
domain = amr.Box(dom_lo, dom_hi)

# Will contain a list of boxes describing the problem domain
ba = amr.BoxArray(domain)

# Chop the single grid into many small boxes
ba.max_size(max_grid_size)

# Distribution Mapping
dm = amr.DistributionMapping(ba)

# Define MultiFab
mf = amr.MultiFab(ba, dm, ncomp, 0)
mf.set_val(0.)

# Geometry: physical properties for data on our domain
real_box = amr.RealBox([0., 0., 0.], [1. , 1., 1.])

coord = 0 # Cartesian
is_per = [0, 0, 0] # periodicity
geom = amr.Geometry(domain, real_box, coord, is_per)

# Calculate cell sizes
dx = geom.data().CellSize() # dx[0]=dx dx[1]=dy dx[2]=dz

# Fill a MultiFab with data
mf_val = 0.
for mfi in mf:
bx = mfi.validbox()
# Preferred way to fill array using NumPy operations:
# - mf_array is indexed in reversed order (n,z,y,x)
# - indices are local (range from 0 to box size)
mf_array = np.array(mf.array(mfi), copy=False)
ax3l marked this conversation as resolved.
Show resolved Hide resolved
x = (np.arange(bx.small_end[0], bx.big_end[0]+1)+0.5)*dx[0]
y = (np.arange(bx.small_end[1], bx.big_end[1]+1)+0.5)*dx[1]
z = (np.arange(bx.small_end[2], bx.big_end[2]+1)+0.5)*dx[2]
v = (x[np.newaxis,np.newaxis,:]
+ y[np.newaxis,:,np.newaxis]*0.1
+ z[:,np.newaxis,np.newaxis]*0.01)
mf_array = 1. + np.exp(-v)
# Alternative way to fill array using standard for loop over box indices:
# - mf_array_ref is indexed in standard order (x,y,z,n)
# - indices are global
mf_array_ref = mf.array(mfi)
for i, j, k in bx:
x = (i+0.5)*dx[0]
y = (j+0.5)*dx[1]
z = (k+0.5)*dx[2]
v = x + y*0.1 + z*0.01
mf_array_ref[i,j,k,0] = 1. + np.exp(-v)
# Check that mf_array has been filled correctly, compare it with
# mf_array_ref (filled as Array4 and transformed to NumPy array)
mf_array_ref_np = np.array(mf_array_ref, copy=False)
ax3l marked this conversation as resolved.
Show resolved Hide resolved
assert np.allclose(mf_array, mf_array_ref_np, rtol=1e-16, atol=1e-16)

# Plot MultiFab data
plotfile = amr.concatenate(root="plt", num=1, mindigits=3)
varnames = amr.Vector_string(["comp0"])
amr.write_single_level_plotfile(plotfile, mf, varnames, geom, time=0., level_step=0)

# Finalize AMReX
amr.finalize()
Loading