diff --git a/CHANGELOG.md b/CHANGELOG.md index 17f19c1b..eecc0b88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/fenicsprecice/fenicsprecice.py b/fenicsprecice/fenicsprecice.py index e766f7d7..7bdeff20 100644 --- a/fenicsprecice/fenicsprecice.py +++ b/fenicsprecice/fenicsprecice.py @@ -432,7 +432,7 @@ 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. @@ -440,9 +440,9 @@ def store_checkpoint(self, payload, t, n): ---------- 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: @@ -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") diff --git a/tests/integration/test_write_read.py b/tests/integration/test_write_read.py index bc11e848..73a45411 100644 --- a/tests/integration/test_write_read.py +++ b/tests/integration/test_write_read.py @@ -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 @@ -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)