Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
54 changes: 54 additions & 0 deletions .github/workflows/run-benchmark-examples.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Examples-CI
on:
push:

pull_request:
branches: [ main ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Runs the workflow once per day at 3:15am
schedule:
- cron: '3 16 * * *'

env:
CACHE_NUMBER: 1 # increase to reset cache manually
SNAKEMAKE_RESULT_FILE: metadata4ing_provenance
PROVENANACE_FILE_NAME: element_size_vs_max_mises_stress.pdf

jobs:
run-examples:
runs-on: ubuntu-latest
steps:
- name: checkout repo content
uses: actions/checkout@v2

- name: Setup Mambaforge
uses: conda-incubator/setup-miniconda@v3
with:
miniforge-version: latest
activate-environment: model-validation
use-mamba: true

- name: Set strict channel priority
run: conda config --set channel_priority strict

- name: Update environment
run: mamba env update -n model-validation -f environment_benchmarks.yml

- name: Run linear-elastic-plate-with-hole using fenics
shell: bash -l {0}
run: |
cd $GITHUB_WORKSPACE/examples/linear-elastic-plate-with-hole/fenics/
python run_benchmark.py

- name: Archive results of the fenics run of linear-elastic-plate-with-hole
uses: actions/upload-artifact@v4
with:
name: snakemake_results_linear-elastic-plate-with-hole
path: |
examples/linear-elastic-plate-with-hole/fenics/results/



Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: fenics_simulation
# Environment file for fenics simulation scripts. Called by fenics tool workflow.

channels:
- conda-forge

channel_priority: strict

dependencies:
- python=3.12
- fenics-dolfinx=0.9.*
- mpich
- petsc4py
- pint
- python-gmsh
- sympy
75 changes: 75 additions & 0 deletions examples/linear-elastic-plate-with-hole/fenics/run_benchmark.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from pathlib import Path
import zipfile
import json
import shutil
import subprocess

"""
The script performs the following steps:

1. Extracts the benchmark files from a zip archive (currently assuming that it is an RO-Crate of the benchmark).
2. Iterates through the parameter configuration files, checks the "element-size" value, and if it meets the specified condition (>= 0.025)
, it executes the Snakemake workflow for that configuration.

The results of each run (and the files used by it) are stored in the directory with the configuration name.
"""

####################################################################################################
####################################################################################################
# Benchmark Extraction
####################################################################################################
####################################################################################################

root_zipped_benchmark_dir = Path(__file__).resolve().parent.parent
root_unzipped_benchmark_dir = Path(__file__).resolve().parent

with zipfile.ZipFile(root_zipped_benchmark_dir / "linear-elastic-plate-with-hole.zip", 'r') as zip_ref:
# Extract all files
zip_ref.extractall(root_unzipped_benchmark_dir)


#Creates a directory to store the conda environments. The environments are shared across different parameter configurations.
#To avoid redundant creation of environments, this path will be passed to all snakemake files during execution.

shared_env_dir = root_unzipped_benchmark_dir / "conda_envs"
shared_env_dir.mkdir(parents=True, exist_ok=True)

####################################################################################################
####################################################################################################
# Conditional execution of parameter configurations
####################################################################################################
####################################################################################################

for file in root_unzipped_benchmark_dir.glob("parameters_*.json"):
with open(file, "r") as f:
data = json.load(f)
if data.get("element-size").get("value") >= 0.025:

# Create output directory for the configuration
output_dir = root_unzipped_benchmark_dir / "results" / data.get("configuration")
output_dir.mkdir(parents=True, exist_ok=True)

# Copy the selected parameter file to the output directory with a standardised name
with open(output_dir / "parameters.json", "w") as outfile:
json.dump(data, outfile, indent=2)

# Copy files from benchmark_dir to output_dir, excluding non-matching parameter files.
for item in root_unzipped_benchmark_dir.iterdir():
if item.is_file():
if item.name.startswith("parameters_") and item.suffix == ".json":
continue
else:
shutil.copy(item, output_dir / item.name)

# Run the Snakemake workflow for the configuration
subprocess.run(["snakemake", "--use-conda", "--force", "--cores", "all", "--conda-prefix", str(shared_env_dir)], check=True, cwd=output_dir)
print("Workflow executed successfully.")

# For the scenario where the snakemake workflow doesn't exist, one can directly run the simulation script using the subprocess module, e.g.:
#subprocess.run(["python", "run_fenics_simulation.py" \
#"--input_parameter_file" "parameters.json" \
#"--input_mesh_file" "mesh.msh" \
#"--output_solution_file_zip" "solution_field_data.zip" \
#"--output_metrics_file" "solution_metrics.json"], check=True, cwd=output_dir)

#Assuming the mesh.msh and parameters.json files are present/copied to the output_dir.
Loading
Loading