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

Release v2.2.0 #184

Merged
merged 11 commits into from
Oct 31, 2024
6 changes: 3 additions & 3 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
pip3 install --break-system-packages setuptools wheel twine
BenjaminRodenberg marked this conversation as resolved.
Show resolved Hide resolved
- name: Build distribution
run: python3 setup.py sdist
test:
name: Run mock unit tests
runs-on: ubuntu-latest
container: quay.io/fenicsproject/stable:current
container: benjaminrodenberg/fenics
BenjaminRodenberg marked this conversation as resolved.
Show resolved Hide resolved
steps:
- name: Checkout Repository
uses: actions/checkout@v2
Expand All @@ -37,7 +37,7 @@ jobs:
mkdir -p precice
echo "from setuptools import setup" >> precice/setup.py
echo "setup(name='pyprecice', version='3.0.0.0')" >> precice/setup.py
python3 -m pip install ./precice/
pip3 install --break-system-packages ./precice/
BenjaminRodenberg marked this conversation as resolved.
Show resolved Hide resolved
- name: Run unit tests
run: python3 setup.py test -s tests.unit
- name: Run integration tests
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# FEniCS-preCICE adapter changelog

## v2.2.0

* Use `copy(deepcopy=True)` when checkpointing to make checkpointing more user-friendly and secure. IMPORTANT: might increase runtime, please open an issue if you face serious problems. [#172](https://github.com/precice/fenics-adapter/pull/172)
* Add unit tests for checkpointing. [#173](https://github.com/precice/fenics-adapter/pull/173)
* Add required version of `mpi4py` to `<4` to avoid crash during installation. [#181](https://github.com/precice/fenics-adapter/pull/181)
* Remove checks for FEniCS installation and python3 from `setup.py` since the approach is deprecated. [#182](https://github.com/precice/fenics-adapter/pull/182)

## 2.1.0

* Additionally support checkpoints being provided as a list or tuple (of FEniCS Functions). [#170](https://github.com/precice/fenics-adapter/pull/170)
Expand Down
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ abstract: >-
preCICE-adapter for the open source computing platform
FEniCS.
license: LGPL-3.0
version: 2.1.0
version: 2.2.0
preferred-citation:
title: "FEniCS-preCICE: Coupling FEniCS to other Simulation Software"
type: "article"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ To create and install the `fenicsprecice` python package the following instructi

## Development history

The initial version of this adapter was developed by [Benjamin Rodenberg](https://www.cs.cit.tum.de/sccs/personen/benjamin-rodenberg/) during his research stay at Lund University in the group for [Numerical Analysis](http://www.maths.lu.se/english/research/research-divisions/numerical-analysis/) in close collaboration with Peter Meisrimel.
The initial version of this adapter was developed by [Benjamin Rodenberg](https://www.cs.cit.tum.de/sccs/personen/benjamin-rodenberg/) during his research stay at Lund University in the group for [Numerical Analysis (Philipp Birken)](https://www.maths.lu.se/forskning/forskningsavdelningar/numerisk-analys/forskning/) in close collaboration with Peter Meisrimel.

[Richard Hertrich](https://github.com/richahert) contributed the possibility to perform FSI simulations using the adapter in his [Bachelor thesis](https://mediatum.ub.tum.de/node?id=1520579).

Expand Down
12 changes: 6 additions & 6 deletions fenicsprecice/solverstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ def __init__(self, payload, t, n):
Iteration number.
"""
try:
self.payload = payload.copy()
except AttributeError: # if .copy() does not exist, it probably is a list
self.payload = [item.copy() for item in payload]
self.payload = payload.copy(deepcopy=True)
except (AttributeError, TypeError): # AttributeError, if .copy() does not exist; TypeError, if .copy(deepcopy) does not exist. -> Probably a list
self.payload = [item.copy(deepcopy=True) for item in payload]

self.t = t
self.n = n
Expand All @@ -34,9 +34,9 @@ def get_state(self):
Iteration number.
"""
try:
return self.payload.copy(), self.t, self.n
except AttributeError: # if .copy() does not exist, it probably is a list
return [item.copy() for item in self.payload], self.t, self.n
return self.payload.copy(deepcopy=True), self.t, self.n
except (AttributeError, TypeError): # AttributeError, if .copy() does not exist; TypeError, if .copy(deepcopy) does not exist. -> Probably a list
return [item.copy(deepcopy=True) for item in self.payload], self.t, self.n

def print_state(self):
payload, t, n = self.get_state()
Expand Down
25 changes: 1 addition & 24 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,6 @@
import os
from setuptools import setup
import versioneer
import warnings

# from https://stackoverflow.com/a/9079062
import sys
if sys.version_info[0] < 3:
raise Exception("fenicsprecice only supports Python3. Did you run $python setup.py <option>.? "
"Try running $python3 setup.py <option>.")

if sys.version_info[1] == 6 and sys.version_info[2] == 9:
warnings.warn("It seems like you are using Python version 3.6.9. There is a known bug with this Python version "
"when running the tests (see https://github.com/precice/fenics-adapter/pull/61). If you want to "
"run the tests, please install a different Python version.")

try:
from fenics import *
except ModuleNotFoundError:
warnings.warn("No FEniCS installation found on system. Please install FEniCS and check the installation.\n\n"
"You can check this by running the command\n\n"
"python3 -c 'from fenics import *'\n\n"
"Please check https://fenicsproject.org/download/ for installation guidance.\n"
"The installation will continue, but please be aware that your installed version of the "
"fenics-adapter might not work as expected.")

this_directory = os.path.abspath(os.path.dirname(__file__))
with open(os.path.join(this_directory, 'README.md'), encoding='utf-8') as f:
long_description = f.read()
Expand All @@ -39,6 +16,6 @@
author_email='[email protected]',
license='LGPL-3.0',
packages=['fenicsprecice'],
install_requires=['pyprecice>=3.0.0.0', 'scipy', 'numpy>=1.13.3', 'mpi4py'],
install_requires=['pyprecice>=3.0.0.0', 'scipy', 'numpy>=1.13.3, <2', 'mpi4py<4'],
test_suite='tests',
zip_safe=False)
6 changes: 5 additions & 1 deletion tests/integration/test_fenicsprecice.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ def assign(self, new_value):
"""
self.value = new_value.value

def copy(self):
def copy(self, deepcopy=False):
"""
mock of dolfin.Function.copy
:param deepcopy: has no effect but we need to provide it to avoid throwing TypeError if copy(deepcopy=True) is called
"""
returned_array = MockedArray()
returned_array.value = self.value
return returned_array
Expand Down
96 changes: 96 additions & 0 deletions tests/unit/test_checkpointing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
from unittest.mock import MagicMock
from unittest import TestCase
from fenics import FunctionSpace, UnitSquareMesh, Expression, interpolate
from fenicsprecice.solverstate import SolverState


class TestCheckpointing(TestCase):
def test_solverstate_basic(self):
"""
Check if correct values are read from the checkpoint, while the state of the object that is copied is not changed
"""
n = 1
size = 5
mesh = UnitSquareMesh(size, size)
V = FunctionSpace(mesh, 'P', 2)
dummy_value = 1
E = Expression("t", t=dummy_value, degree=2)
u = interpolate(E, V)

# "write checkpoint"
sstate = SolverState(u, dummy_value, n)
# "read checkpoint"
u_cp, t_cp, n_cp = sstate.get_state()

# check values
self.assertEqual(t_cp, dummy_value)
self.assertEqual(n, n_cp)
# function should be the same everywhere (-> check vector values of the function)
vec_u = u.vector()
vec_u_cp = u_cp.vector()
for i in range(size * size):
self.assertAlmostEqual(vec_u[i], vec_u_cp[i])

def test_solverstate_modification_vector(self):
"""
Check if correct values are read from the checkpoint, if the dof vector of the dolfin functions are changed directly

Motivation for this test: Related to https://github.com/precice/fenics-adapter/pull/172 and https://github.com/precice/tutorials/pull/554
"""
n = 1
size = 5
mesh = UnitSquareMesh(size, size)
V = FunctionSpace(mesh, 'P', 2)
ref_value = 1
E = Expression("t", t=ref_value, degree=2)
u = interpolate(E, V)

# "write checkpoint"
sstate = SolverState(u, ref_value, n)

# modify state of u
dummy_value = ref_value + 2
u.vector()[:] = dummy_value

# "read checkpoint"
u_cp, _, _ = sstate.get_state()

# check values
# function should be the same everywhere
# (so the vector values should all be ref_value)
vec_u_cp = u_cp.vector()
for i in range(size * size):
self.assertAlmostEqual(ref_value, vec_u_cp[i])

def test_solverstate_modification_assign(self):
"""
Check if correct values are read from the checkpoint, if the dof of the dolfin functions are changed with the assign function
and not directly via the dof vector
"""
n = 1
size = 5
mesh = UnitSquareMesh(size, size)
V = FunctionSpace(mesh, 'P', 2)
ref_value = 1
E = Expression("t", t=ref_value, degree=2)
u = interpolate(E, V)

# "write checkpoint"
sstate = SolverState(u, ref_value, n)

# modify state of u
# "compute" new solution
dummy_value = ref_value + 2
E.t = dummy_value
u2 = interpolate(E, V)
u.assign(u2)

# "read checkpoint"
u_cp, _, _ = sstate.get_state()

# check values
# function should be the same everywhere
# (so the vector values should all be ref_value)
vec_u_cp = u_cp.vector()
for i in range(size * size):
self.assertAlmostEqual(ref_value, vec_u_cp[i])
14 changes: 14 additions & 0 deletions tools/testing/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Dockerfile to build a ubuntu image containing the installed Debian package of a release
FROM ubuntu:24.04

# Add the precice user to run test with mpi
RUN useradd -m -s /bin/bash precice
ENV PRECICE_USER=precice

# Installing necessary dependencies
RUN apt-get -qq update && \
apt-get -qq install software-properties-common && \
add-apt-repository -y ppa:fenics-packages/fenics && \
apt-get -qq update && \
apt-get -qq install --no-install-recommends fenics python3-pip && \
rm -rf /var/lib/apt/lists/*
Loading