Skip to content
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: [email protected] 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
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)
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)
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()