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

Make t and n optional arguments in store_checkpoint #178

Merged
merged 17 commits into from
Mar 8, 2025
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## develop

* Set required version of `scipy` to `<1.15.0` to prevent failing tests because of a required module that is not found for later versions of scipy. [#195](https://github.com/precice/fenics-adapter/pull/195)
* `store_checkpoint` no longer requires the time `t` and the current time window number `n` as parameters as they are now optional. If they are not specified in `store_checkpoint`, `retrieve_checkpoint` still returns a tuple of three elements but for unspecified parameters, it returns `None`.

## 2.2.0

Expand Down
10 changes: 5 additions & 5 deletions fenicsprecice/fenicsprecice.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,17 +432,17 @@ def initialize(self, coupling_subdomain, read_function_space=None, write_object=

self._participant.initialize()

def store_checkpoint(self, payload, t, n):
def store_checkpoint(self, payload, t=None, n=None):
"""
Defines an object of class SolverState which stores the current state of the variable and the time stamp.

Parameters
----------
payload : fenics.function or a list of fenics.functions
Current state of the physical variable(s) of interest for this participant.
t : double
t : double (optional)
Current simulation time.
n : int
n : int (optional)
Current time window (iteration) number.
"""
if self._first_advance_done:
Expand All @@ -460,9 +460,9 @@ def retrieve_checkpoint(self):
u : FEniCS Function
Current state of the physical variable of interest for this participant.
t : double
Current simulation time.
Current simulation time or None if not specified in store_checkpoint
n : int
Current time window (iteration) number.
Current time window (iteration) number or None if not specified in store_checkpoint
"""
assert (not self.is_time_window_complete())
logger.debug("Restore solver state")
Expand Down
73 changes: 72 additions & 1 deletion tests/integration/test_write_read.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from unittest.mock import MagicMock, patch
from unittest import TestCase
from tests import MockedPrecice
from fenics import Expression, UnitSquareMesh, FunctionSpace, VectorFunctionSpace, interpolate, SubDomain, near
from fenics import Expression, UnitSquareMesh, FunctionSpace, VectorFunctionSpace, interpolate, SubDomain, near, UnitIntervalMesh
import numpy as np

x_left, x_right = 0, 1
Expand Down Expand Up @@ -185,3 +185,74 @@ def return_dummy_data(n_points):
self.fail(f"Unexpected combination of arg: {arg}, expected_arg: {expected_arg}")

np.testing.assert_almost_equal(list(read_data.values()), return_dummy_data(self.n_vertices))

def test_optional_parameters(self):
from precice import Participant
import fenicsprecice

def test_all_parameters(adapter):
# init variables that are tested against
nx = 10
mesh = UnitIntervalMesh(nx)
V = FunctionSpace(mesh, 'P', 2)
dummy_value = 1
E = Expression("t", t=dummy_value, degree=2)
u = interpolate(E, V)
t = 0.5
n = 42
# test adapter
adapter.store_checkpoint(u, t, n) # is the old implementation still working?
res_u, res_t, res_n = adapter.retrieve_checkpoint()
self.assertEqual(res_t, t)
self.assertEqual(res_n, n)
np.testing.assert_array_equal(res_u.vector(), u.vector())

def test_opt_parameters(adapter):
# init variables that are tested against
nx = 10
mesh = UnitIntervalMesh(nx)
V = FunctionSpace(mesh, 'P', 2)
dummy_value = 1
E = Expression("t", t=dummy_value, degree=2)
u = interpolate(E, V)
t = 0.5
n = 42
# test adapter
adapter.store_checkpoint(u, t=t) # without n
res = adapter.retrieve_checkpoint()
self.assertEqual(len(res), 3) # correct number of return values
res_u, res_t, res_n = res
self.assertEqual(res_t, t)
self.assertEqual(res_n, None)
np.testing.assert_array_equal(res_u.vector(), u.vector())

adapter.store_checkpoint(u, n=n) # without t
res = adapter.retrieve_checkpoint()
self.assertEqual(len(res), 3) # correct number of return values
res_u, res_t, res_n = res
self.assertEqual(res_n, n)
self.assertEqual(res_t, None)
np.testing.assert_array_equal(res_u.vector(), u.vector())

def test_payload_only(adapter):
nx = 10
mesh = UnitIntervalMesh(nx)
V = FunctionSpace(mesh, 'P', 2)
dummy_value = 1
E = Expression("t", t=dummy_value, degree=2)
u = interpolate(E, V)
# test adapter
adapter.store_checkpoint(u) # no optional parameters
res_u, res_t, res_n = adapter.retrieve_checkpoint()
self.assertEqual(res_t, None)
self.assertEqual(res_n, None)
np.testing.assert_array_equal(res_u.vector(), u.vector())

Participant.is_time_window_complete = MagicMock(return_value=False)

precice = fenicsprecice.Adapter(self.dummy_config)

# call the tests
test_all_parameters(precice)
test_opt_parameters(precice)
test_payload_only(precice)