Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
bb3388e
Add initial testing matrix
mandli Aug 26, 2025
38ef2ae
Fix bugs in testing script
mandli Aug 26, 2025
d9ce97a
Add macos to testing
mandli Aug 26, 2025
3f7766c
Cleanup some source that was failing via pyflake
mandli Aug 26, 2025
ebce146
Tweak flake8 call
mandli Aug 26, 2025
6dbc5c4
Limit build options and python versions to see if the testing can pas…
mandli Aug 26, 2025
449197e
Try using current numpy
mandli Aug 26, 2025
de9baa1
Verbose pytest output.
ketch Sep 3, 2025
9bcbb12
Add test summary action
mandli Sep 4, 2025
8788601
Restrict coverage uploading to one config
mandli Sep 4, 2025
9912138
Fix errant .
mandli Sep 4, 2025
b91bce4
Correct some github action syntax bugs
mandli Sep 4, 2025
3069683
Correct missing path info
mandli Sep 4, 2025
33307b4
Fix bad path/naming again
mandli Sep 4, 2025
9650824
Fix another path problem
mandli Sep 4, 2025
6506f85
Try confusing pathing fix
mandli Sep 4, 2025
f6c82ef
Fix linting path
mandli Sep 4, 2025
bf6b195
One more try at getting pathing right
mandli Sep 4, 2025
1d3feae
This is on me, clearly I cannot deal with paths
mandli Sep 4, 2025
42a61ca
Turn off fast fail
mandli Sep 4, 2025
dbc8e26
Adjust archive source file path
mandli Sep 4, 2025
a16fcb8
Uniquely identify test results
mandli Sep 4, 2025
a60230c
Fix missing variable declarations in archiving step
mandli Sep 4, 2025
d30fdcb
Do not capture output in pytest
mandli Sep 5, 2025
ffc2ece
Update the expected dimension of limiters array.
ketch Oct 6, 2025
ed97c6d
Make sure limiters is a list.
ketch Oct 6, 2025
92b956c
Fix stupid bug I just introduced.
ketch Oct 6, 2025
0fefb49
Avoid explicitly indexing into empty aux array.
ketch Oct 6, 2025
86c212b
Remove debugging print statements.
ketch Oct 6, 2025
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
119 changes: 104 additions & 15 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,53 @@ env:
CLAW: ${{ github.workspace }}

jobs:
build:
runs-on: ubuntu-latest
tests:
name: >
${{ matrix.os }} - py ${{ matrix.python-version }} - ${{ matrix.toolchain.compiler }} ${{ matrix.build }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false # Probably want to turn this off for a large matrix
matrix:
os: [ubuntu-latest, macos-latest]
python-version: ["3.12"]
build: [debug, opt]
toolchain:
- {compiler: gcc, version: 14}
- {compiler: gcc, version: 15}
# - {compiler: intel, version: '2025.0'}
# - {compiler: intel-classic, version: '2021.10'}
# - {compiler: nvidia-hpc, version: '25.1'} # does not build python
# - {compiler: lfortran, version: '0.45.0'} # lfortran not yet supported
# - {compiler: flang, version: '20.1.0'} # flang not yet supported
# include:
# - os: ubuntu-latest
# python-version: 3.10
# build: opt
# toolchain: {compiler: gcc, version: 14}
exclude:
- os: ubuntu-latest
toolchain: {compiler: gcc, version: 15}
- os: macos-latest
toolchain: {compiler: gcc, version: 14}

steps:
- name: Set up Python 3.10
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install gfortran
python-version: ${{ matrix.python-version }}

- name: Set up compilers
uses: fortran-lang/setup-fortran@v1
id: setup-fortran
with:
compiler: ${{ matrix.toolchain.compiler }}
version: ${{ matrix.toolchain.version }}

- name: Install python dependencies
run: |
python -m pip install --upgrade pip
pip install 'numpy<2.0'
# pip install 'numpy<2.0'
pip install numpy
pip install matplotlib #Some imports require matplotlib
pip install scipy #To not skip tests
pip install flake8 meson-python ninja pytest coveralls
Expand All @@ -44,21 +77,77 @@ jobs:
uses: actions/[email protected]
with:
path: pyclaw

- name: Install clawpack
run: |
cd ${CLAW}
if [ "${{ matrix.toolchain.compiler }}" = "gcc" ]; then
if [ "${{ matrix.build }}" = "debug" ]; then
export FFLAGS="-O0 -g -fcheck=all -fbacktrace -fbounds-check -ffpe-trap=invalid,zero,overflow -finit-real=nan -finit-integer=nan -Wall -Wunderflow -Wextra -Wconversion -Wuninitialized -Warray-bounds -Wshadow -Wno-unused-function -Wno-unused-variable -Wno-unused-parameter -Wno-unused-label -Wno-unused-but-set-variable"
export CFLAGS=""
elif [ "${{ matrix.build }}" = "opt" ]; then
# export FFLAGS="-O1 -funroll-loops -finline-functions -ftree-vectorize -fstack-protector-strong -flto -march=native"
export FFLAGS=""
export CFLAGS=""
else
echo "Unknown build type: ${{ matrix.build }}"
exit 1
fi
elif [ "${{ matrix.toolchain.compiler }}" = "intel" ] || [ "${{ matrix.toolchain.compiler }}" = "intel-classic" ]; then
if [ "${{ matrix.build }}" = "debug" ]; then
export FFLAGS=""
export CFLAGS=""
elif [ "${{ matrix.build }}" = "opt" ]; then
export FFLAGS=""
export CFLAGS=""
else
echo "Unknown build type: ${{ matrix.build }}"
exit 1
fi
else
echo "Unknown compiler: ${{ matrix.toolchain.compiler }}"
exit 1
fi
echo "Using `$FC --version`"
echo "FFLAGS: $FFLAGS"
echo "CFLAGS: $CFLAGS"
cd ${{ env.CLAW }}
pip install --no-build-isolation --editable .

- name: Lint with flake8
if: ${{ matrix.build == 'debug' }}
run: |
cd ${{ env.CLAW }}/pyclaw
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude "development","src/pyclaw/fileio/netcdf.py"
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

- name: Test with pytest
run: |
cd ${CLAW}/pyclaw
coverage run --source=src -m pytest --ignore=development -k "not test_shallow_sphere"
cd ${{ env.CLAW }}/pyclaw
coverage run --source=src -m pytest -vv -s --showlocals --ignore=development -k "not test_shallow_sphere" --junitxml=test-report.xml

- name: Upload to Coveralls
- name: Process test results
uses: test-summary/[email protected]
if: always()
with:
paths: ${{ env.CLAW }}/pyclaw/test-report.xml
output: ${{ env.CLAW }}/pyclaw/test-summary.md
show: "all"

- name: Upload test results
# if: failure()
if: always()
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.os }}-py${{ matrix.python-version }}-${{ matrix.toolchain.compiler }}-${{ matrix.build }}
path: ${{ env.CLAW }}/pyclaw/test-summary.md
if-no-files-found: ignore

- name: Upload to Coveralls
if: ${{ matrix.os == 'ubuntu-latest' && matrix.toolchain.compiler == 'gcc' && matrix.build == 'opt' && matrix.python-version == '3.12' }}
run: |
cd ${CLAW}/pyclaw
cd ${{ env.CLAW }}/pyclaw
ls -l .coverage
coveralls
env:
Expand Down
18 changes: 9 additions & 9 deletions cleanup_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,32 @@
Cleans up by deleting object files, executable, and _output directory.
"""

import os,sys,glob
import os
import sys
import shutil

if __name__ == "__main__":

examples_dir = os.path.abspath('./examples')
print "Will remove all _output, _plots, and build directories from ",examples_dir
ans = raw_input("Ok? ")
print(f"Will remove all _output, _plots, and build directories from {examples_dir}")
ans = input("Ok? ")
if ans.lower() not in ['y','yes']:
print "Aborting."
print("Aborting.")
sys.exit()

os.chdir(examples_dir)
exdirlist = []
for (dirpath, subdirs, files) in os.walk('.'):
currentdir = os.path.abspath(os.getcwd())
os.chdir(os.path.abspath(dirpath))
print 'In directory ',dirpath

print(f'In directory {dirpath}')

if os.path.isdir('_output'):
shutil.rmtree('./_output')
if os.path.isdir('_plots'):
shutil.rmtree('./_plots')
if os.path.isdir('build'):
shutil.rmtree('./build')

os.chdir(currentdir)

os.chdir(currentdir)
6 changes: 3 additions & 3 deletions examples/compare_solvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,20 +160,20 @@ def compare_2D(nx=(250,250)):
import sys

vis = True

if vis:
compare_solvers.outdir='./_output'
else:
compare_solvers.outdir = None

if len(sys.argv) > 1:
nx_1D = int(sys.argv[1])
else:
nx_1D = 500

if len(sys.argv) > 2:
# '(2,2)' -> (2,2)
nx_2D = tuple(int(i) for i in argv.split(','))
nx_2D = tuple(int(i) for i in sys.argv.split(','))
else:
nx_2D = 100,100

Expand Down
29 changes: 14 additions & 15 deletions fvmbook/chap22/inclusion/inclusion.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Variable-coefficient elasticity example.
"""
import numpy as np
from six.moves import range

t0wall = 0.025
tperiod = 0.05

Expand All @@ -13,20 +13,20 @@ def moving_wall_bc(state,dim,t,qbc,auxbc,num_ghost):
if t<t0wall:
s = np.sin(np.pi*t/tperiod)
else:
s = 0.
s = 0.0

for i in range(num_ghost):
# First reflect-extrapolate
qbc[:,i,:] = qbc[:,2*num_ghost-i-1,:]
# Now set velocity
qbc[3,i,:] = 2.0*s - qbc[3,i,:]
qbc[4,i,:] = - qbc[4,i,:]


#def no_stress_bc(state,dim,t,qbc,num_ghost):
# """No-stress boundary condition: sigma_{12} = sigma_{11} = 0"""
# if state.grid.on_lower_boundary[idim]:
# jghost =
# jghost =
# # First extrapolate
# tmp = qbc[:,:,self.num_ghost]
# tmp = np.tile(tmp,(1,1,num_ghost))
Expand All @@ -35,8 +35,8 @@ def moving_wall_bc(state,dim,t,qbc,auxbc,num_ghost):
# # Then negate the sig12 and sig11 components

def integrate_displacement(solver,state):
aux[5,:,:] = aux[5,:,:] + dt*q[3,:,:]
aux[6,:,:] = aux[6,:,:] + dt*q[4,:,:]
state.aux[5,:,:] = state.aux[5,:,:] + solver.dt * state.q[3,:,:]
state.aux[6,:,:] = state.aux[6,:,:] + solver.dt * state.q[4,:,:]


def inclusion():
Expand Down Expand Up @@ -116,19 +116,19 @@ def inclusion():
#--------------------------
def setplot(plotdata):
#--------------------------
"""

"""
Specify what is to be plotted at each frame.
Input: plotdata, an instance of visclaw.data.ClawPlotData.
Output: a modified version of plotdata.
"""

"""


from clawpack.visclaw import colormaps

plotdata.clearfigures() # clear any old figures,axes,items data


# Figure for pressure
# -------------------
Expand All @@ -148,11 +148,11 @@ def setplot(plotdata):
plotitem.pcolor_cmap = colormaps.yellow_red_blue
plotitem.add_colorbar = True
plotitem.show = True # show on plot?


# Figure for x-velocity plot
# -----------------------

plotfigure = plotdata.new_plotfigure(name='x-Velocity', figno=1)

# Set up for axes in this figure:
Expand All @@ -166,7 +166,7 @@ def setplot(plotdata):
plotitem.pcolor_cmap = colormaps.yellow_red_blue
plotitem.add_colorbar = True
plotitem.show = True # show on plot?

# Parameters used only when creating html and/or latex hardcopy
# e.g., via visclaw.frametools.printframes:

Expand All @@ -190,4 +190,3 @@ def setplot(plotdata):

from clawpack.pyclaw import plot
plot.interactive_plot()

2 changes: 1 addition & 1 deletion src/pyclaw/classic/flux3.f90
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ subroutine flux3(ixyz,maxm,num_eqn,num_waves,num_ghost,mx, &

! aux2(1-num_ghost,1,2) is the start of a 1d array now used by rpn3
call rpn3(ixyz,maxm,num_eqn,num_waves,num_aux,num_ghost,mx,q1d,q1d, &
aux2(1,1-num_ghost,2),aux2(1,1-num_ghost,2),wave,s,amdq,apdq)
aux2(:,1-num_ghost,2),aux2(:,1-num_ghost,2),wave,s,amdq,apdq)

! Set qadd for the donor-cell upwind method (Godunov)
forall (m = 1:num_eqn, i = 1:mx+1)
Expand Down
11 changes: 8 additions & 3 deletions src/pyclaw/sharpclaw/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,9 +519,14 @@ def check_3rd_ord_cond(self,state,step_index,dtFE):
def _set_mthlim(self):
self._mthlim = self.limiters
if not isinstance(self.limiters,list): self._mthlim=[self._mthlim]
if len(self._mthlim)==1: self._mthlim = self._mthlim * self.num_waves
if len(self._mthlim)!=self.num_waves:
raise Exception('Length of solver.limiters is not equal to 1 or to solver.num_waves')
if self.char_decomp == 0: # entry-wise limiting
if len(self._mthlim)==1: self._mthlim = self._mthlim * self.num_eqn
if len(self._mthlim)!=self.num_eqn:
raise Exception('Length of solver.limiters is not equal to 1 or to solver.num_eqn')
else: # Wave-wise limiting
if len(self._mthlim)==1: self._mthlim = self._mthlim * self.num_waves
if len(self._mthlim)!=self.num_waves:
raise Exception('Length of solver.limiters is not equal to 1 or to solver.num_waves')


def dq(self,state):
Expand Down
Loading