From 06d7e00360bd2985622ca922478945b808ed8337 Mon Sep 17 00:00:00 2001
From: Jean-Baptiste Keck <Jean-Baptiste.Keck@imag.fr>
Date: Wed, 4 Nov 2020 16:11:57 +0100
Subject: [PATCH] fix last tests

---
 ci/scripts/test.sh                            |  48 ++---
 hysop/backend/host/host_operator.py           |   2 +-
 hysop/core/tests/test_checkpoint.sh           | 165 +++++++++---------
 hysop/operator/adapt_timestep.py              |   4 +-
 hysop/operator/base/poisson_curl.py           |   5 +-
 hysop/operator/base/spectral_operator.py      |   7 +-
 hysop/operator/hdf_io.py                      |  24 +--
 hysop/operator/parameter_plotter.py           |   7 +-
 hysop/simulation.py                           |  13 --
 hysop/tools/spectral_utils.py                 |   5 +-
 hysop/topology/cartesian_descriptor.py        |   2 +
 hysop/topology/cartesian_topology.py          |   4 +-
 .../turbulent_scalar_advection.py             |   9 +-
 .../examples/shear_layer/shear_layer.py       |  12 +-
 .../examples/taylor_green/taylor_green.py     |   2 +-
 15 files changed, 154 insertions(+), 155 deletions(-)

diff --git a/ci/scripts/test.sh b/ci/scripts/test.sh
index 7bd8ca02f..9726ca639 100755
--- a/ci/scripts/test.sh
+++ b/ci/scripts/test.sh
@@ -116,30 +116,30 @@ example_test() {
 }
 
 if [ "$RUN_TESTS" = true ]; then
-    #hysop_test "core/arrays/tests/test_array.py"
-    #hysop_test "core/graph/tests/test_graph.py"
-    #hysop_test "fields/tests/test_fields.py"
-    #hysop_test "numerics/tests/test_fft.py"
-    #hysop_test "operator/tests/test_analytic.py"
-    #hysop_test "operator/tests/test_transpose.py"
-    #hysop_test "operator/tests/test_fd_derivative.py"
-    #hysop_test "operator/tests/test_absorption.py"
-    #hysop_test "operator/tests/test_penalization.py"
-    #hysop_test "operator/tests/test_velocity_correction.py"
-    #hysop_test "operator/tests/test_restriction_filter.py"
-    #hysop_test "operator/tests/test_scales_advection.py"
-    #hysop_test "operator/tests/test_bilevel_advection.py"
-    #hysop_test "operator/tests/test_directional_advection.py"
-    #hysop_test "operator/tests/test_directional_diffusion.py"
-    #hysop_test "operator/tests/test_directional_stretching.py"
-    #hysop_test "operator/tests/test_custom_symbolic.py"
-    #hysop_test "operator/tests/test_spectral_derivative.py"
-    #hysop_test "operator/tests/test_spectral_curl.py"
-    #hysop_test "operator/tests/test_diffusion.py"
-    #hysop_test "operator/tests/test_poisson.py"
-    #hysop_test "operator/tests/test_solenoidal_projection.py"
-    #hysop_test "operator/tests/test_poisson_curl.py"
-    #${HYSOP_DIR}/fields/tests/test_cartesian.sh
+    hysop_test "core/arrays/tests/test_array.py"
+    hysop_test "core/graph/tests/test_graph.py"
+    hysop_test "fields/tests/test_fields.py"
+    hysop_test "numerics/tests/test_fft.py"
+    hysop_test "operator/tests/test_analytic.py"
+    hysop_test "operator/tests/test_transpose.py"
+    hysop_test "operator/tests/test_fd_derivative.py"
+    hysop_test "operator/tests/test_absorption.py"
+    hysop_test "operator/tests/test_penalization.py"
+    hysop_test "operator/tests/test_velocity_correction.py"
+    hysop_test "operator/tests/test_restriction_filter.py"
+    hysop_test "operator/tests/test_scales_advection.py"
+    hysop_test "operator/tests/test_bilevel_advection.py"
+    hysop_test "operator/tests/test_directional_advection.py"
+    hysop_test "operator/tests/test_directional_diffusion.py"
+    hysop_test "operator/tests/test_directional_stretching.py"
+    hysop_test "operator/tests/test_custom_symbolic.py"
+    hysop_test "operator/tests/test_spectral_derivative.py"
+    hysop_test "operator/tests/test_spectral_curl.py"
+    hysop_test "operator/tests/test_diffusion.py"
+    hysop_test "operator/tests/test_poisson.py"
+    hysop_test "operator/tests/test_solenoidal_projection.py"
+    hysop_test "operator/tests/test_poisson_curl.py"
+    ${HYSOP_DIR}/fields/tests/test_cartesian.sh
     ${HYSOP_DIR}/core/tests/test_checkpoint.sh
 fi
 
diff --git a/hysop/backend/host/host_operator.py b/hysop/backend/host/host_operator.py
index 368cb9c3e..cd20d2223 100644
--- a/hysop/backend/host/host_operator.py
+++ b/hysop/backend/host/host_operator.py
@@ -35,7 +35,7 @@ class HostOperatorBase(ComputationalGraphOperator, metaclass=ABCMeta):
         super(HostOperatorBase, self).__init__(**kwds)
 
 
-class HostOperator(ComputationalGraphOperator, metaclass=ABCMeta):
+class HostOperator(HostOperatorBase, metaclass=ABCMeta):
     """
     Abstract class for discrete operators working on cpu.
     HostOperator extra cl_env keyword parameter and enforces HOST backend.
diff --git a/hysop/core/tests/test_checkpoint.sh b/hysop/core/tests/test_checkpoint.sh
index f748ad47c..0872748bc 100755
--- a/hysop/core/tests/test_checkpoint.sh
+++ b/hysop/core/tests/test_checkpoint.sh
@@ -1,6 +1,5 @@
 #!/usr/bin/env bash
 set -feu -o pipefail
-set -x
 PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE:-python3.8}
 MPIRUN_EXECUTABLE=${MPIRUN_EXECUTABLE:-mpirun}
 
@@ -31,93 +30,93 @@ function compare_files {
 #
 # Basic test with 2D diffusion (serial)
 #
-#EXAMPLE_FILE="${EXAMPLE_DIR}/scalar_diffusion/scalar_diffusion.py"
-#TEST_DIR='/tmp/hysop_tests/checkpoints/scalar_diffusion'
-#COMMON_OPTIONS="-NC -impl opencl -cp fp32 -d64 --debug-dump-target dump -nu 0.02 -niter 20 -te 0.1 --dump-tstart 0.05 --dump-freq 1 "
-
-#echo
-#echo "TEST SCALAR DIFFUSION CHECKPOINT (SERIAL)"
-#if [[ ! -f "${EXAMPLE_FILE}" ]]; then
-    #echo "Cannot find example file '${EXAMPLE_FILE}'."
-    #exit 1
-#fi
-
-#echo ' Running simulations...'
-#"${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -S "${TEST_DIR}/checkpoint0.tar" --dump-dir "${TEST_DIR}/run0" --checkpoint-dump-time 0.05 --checkpoint-dump-freq 0
-#"${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -S "${TEST_DIR}/checkpoint1.tar" --dump-dir "${TEST_DIR}/run1" --checkpoint-dump-time 0.05 --checkpoint-dump-freq 0
-
-#echo ' Comparing solutions...'
-#echo "  >debug dumps match"
-#compare_files "${TEST_DIR}/run0/dump/run.txt" "${TEST_DIR}/run1/dump/run.txt"
-#for f0 in $(find "${TEST_DIR}/run0" -name '*.h5' | sort -n); do
-    #f1=$(echo "${f0}" | sed 's/run0/run1/')
-    #compare_files "${f0}" "${f1}"
-    #echo "  >$(basename ${f0}) match"
-#done
-
-#echo
-#echo ' Running simulations from checkpoints...'
-#"${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -L "${TEST_DIR}/checkpoint0.tar" --dump-dir "${TEST_DIR}/run2"
-#"${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -L "${TEST_DIR}/checkpoint1.tar" --dump-dir "${TEST_DIR}/run3"
-
-#echo ' Comparing solutions...'
-#compare_files "${TEST_DIR}/run2/dump/run.txt" "${TEST_DIR}/run3/dump/run.txt"
-#echo "  >debug dumps match"
-#for f0 in $(find "${TEST_DIR}/run2" -name '*.h5' | sort -n); do
-    #f1=$(echo "${f0}" | sed 's/run2/run3/')
-    #f2=$(echo "${f0}" | sed 's/run2/run0/')
-    #f3=$(echo "${f0}" | sed 's/run2/run1/')
-    #compare_files "${f0}" "${f1}"
-    #compare_files "${f0}" "${f2}"
-    #compare_files "${f0}" "${f3}"
-    #echo "  >$(basename ${f0}) match"
-#done
+EXAMPLE_FILE="${EXAMPLE_DIR}/scalar_diffusion/scalar_diffusion.py"
+TEST_DIR='/tmp/hysop_tests/checkpoints/scalar_diffusion'
+COMMON_OPTIONS="-NC -impl opencl -cp fp32 -d64 --debug-dump-target dump -nu 0.02 -niter 20 -te 0.1 --dump-tstart 0.05 --dump-freq 1 "
+
+echo
+echo "TEST SCALAR DIFFUSION CHECKPOINT (SERIAL)"
+if [[ ! -f "${EXAMPLE_FILE}" ]]; then
+    echo "Cannot find example file '${EXAMPLE_FILE}'."
+    exit 1
+fi
+
+echo ' Running simulations...'
+"${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -S "${TEST_DIR}/checkpoint0.tar" --dump-dir "${TEST_DIR}/run0" --checkpoint-dump-time 0.05 --checkpoint-dump-freq 0
+"${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -S "${TEST_DIR}/checkpoint1.tar" --dump-dir "${TEST_DIR}/run1" --checkpoint-dump-time 0.05 --checkpoint-dump-freq 0
+
+echo ' Comparing solutions...'
+echo "  >debug dumps match"
+compare_files "${TEST_DIR}/run0/dump/run.txt" "${TEST_DIR}/run1/dump/run.txt"
+for f0 in $(find "${TEST_DIR}/run0" -name '*.h5' | sort -n); do
+    f1=$(echo "${f0}" | sed 's/run0/run1/')
+    compare_files "${f0}" "${f1}"
+    echo "  >$(basename ${f0}) match"
+done
+
+echo
+echo ' Running simulations from checkpoints...'
+"${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -L "${TEST_DIR}/checkpoint0.tar" --dump-dir "${TEST_DIR}/run2"
+"${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -L "${TEST_DIR}/checkpoint1.tar" --dump-dir "${TEST_DIR}/run3"
+
+echo ' Comparing solutions...'
+compare_files "${TEST_DIR}/run2/dump/run.txt" "${TEST_DIR}/run3/dump/run.txt"
+echo "  >debug dumps match"
+for f0 in $(find "${TEST_DIR}/run2" -name '*.h5' | sort -n); do
+    f1=$(echo "${f0}" | sed 's/run2/run3/')
+    f2=$(echo "${f0}" | sed 's/run2/run0/')
+    f3=$(echo "${f0}" | sed 's/run2/run1/')
+    compare_files "${f0}" "${f1}"
+    compare_files "${f0}" "${f2}"
+    compare_files "${f0}" "${f3}"
+    echo "  >$(basename ${f0}) match"
+done
 
 
 #
 # Basic test with 2D diffusion (MPI)
 #
-#EXAMPLE_FILE="${EXAMPLE_DIR}/scalar_diffusion/scalar_diffusion.py"
-#TEST_DIR='/tmp/hysop_tests/checkpoints/scalar_diffusion_mpi'
-#COMMON_OPTIONS="-NC -impl opencl -cp fp32 -d64 --debug-dump-target dump -nu 0.02 -niter 20 -te 0.1 --dump-tstart 0.05 --dump-freq 1 "
-
-#echo
-#echo "TEST SCALAR DIFFUSION CHECKPOINT (MPI)"
-#if [[ ! -f "${EXAMPLE_FILE}" ]]; then
-    #echo "Cannot find example file '${EXAMPLE_FILE}'."
-    #exit 1
-#fi
-
-#echo ' Running simulations...'
-#${MPIRUN_EXECUTABLE} -np 4 "${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -S "${TEST_DIR}/checkpoint0.tar" --dump-dir "${TEST_DIR}/run0" --checkpoint-dump-time 0.05 --checkpoint-dump-freq 0
-#${MPIRUN_EXECUTABLE} -np 4 "${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -S "${TEST_DIR}/checkpoint1.tar" --dump-dir "${TEST_DIR}/run1" --checkpoint-dump-time 0.05 --checkpoint-dump-freq 0
-
-#echo ' Comparing solutions...'
-#echo "  >debug dumps match"
-#compare_files "${TEST_DIR}/run0/dump/run.txt" "${TEST_DIR}/run1/dump/run.txt"
-#for f0 in $(find "${TEST_DIR}/run0" -name '*.h5' | sort -n); do
-    #f1=$(echo "${f0}" | sed 's/run0/run1/')
-    #compare_files "${f0}" "${f1}"
-    #echo "  >$(basename ${f0}) match"
-#done
-
-#echo
-#echo ' Running simulations from checkpoints...'
-#${MPIRUN_EXECUTABLE} -np 4 "${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -L "${TEST_DIR}/checkpoint0.tar" --dump-dir "${TEST_DIR}/run2"
-#${MPIRUN_EXECUTABLE} -np 4 "${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -L "${TEST_DIR}/checkpoint1.tar" --dump-dir "${TEST_DIR}/run3"
-
-#echo ' Comparing solutions...'
-#compare_files "${TEST_DIR}/run2/dump/run.txt" "${TEST_DIR}/run3/dump/run.txt"
-#echo "  >debug dumps match"
-#for f0 in $(find "${TEST_DIR}/run2" -name '*.h5' | sort -n); do
-    #f1=$(echo "${f0}" | sed 's/run2/run3/')
-    #f2=$(echo "${f0}" | sed 's/run2/run0/')
-    #f3=$(echo "${f0}" | sed 's/run2/run1/')
-    #compare_files "${f0}" "${f1}"
-    #compare_files "${f0}" "${f2}"
-    #compare_files "${f0}" "${f3}"
-    #echo "  >$(basename ${f0}) match"
-#done
+EXAMPLE_FILE="${EXAMPLE_DIR}/scalar_diffusion/scalar_diffusion.py"
+TEST_DIR='/tmp/hysop_tests/checkpoints/scalar_diffusion_mpi'
+COMMON_OPTIONS="-NC -impl opencl -cp fp32 -d64 --debug-dump-target dump -nu 0.02 -niter 20 -te 0.1 --dump-tstart 0.05 --dump-freq 1 "
+
+echo
+echo "TEST SCALAR DIFFUSION CHECKPOINT (MPI)"
+if [[ ! -f "${EXAMPLE_FILE}" ]]; then
+    echo "Cannot find example file '${EXAMPLE_FILE}'."
+    exit 1
+fi
+
+echo ' Running simulations...'
+${MPIRUN_EXECUTABLE} -np 4 "${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -S "${TEST_DIR}/checkpoint0.tar" --dump-dir "${TEST_DIR}/run0" --checkpoint-dump-time 0.05 --checkpoint-dump-freq 0
+${MPIRUN_EXECUTABLE} -np 4 "${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -S "${TEST_DIR}/checkpoint1.tar" --dump-dir "${TEST_DIR}/run1" --checkpoint-dump-time 0.05 --checkpoint-dump-freq 0
+
+echo ' Comparing solutions...'
+echo "  >debug dumps match"
+compare_files "${TEST_DIR}/run0/dump/run.txt" "${TEST_DIR}/run1/dump/run.txt"
+for f0 in $(find "${TEST_DIR}/run0" -name '*.h5' | sort -n); do
+    f1=$(echo "${f0}" | sed 's/run0/run1/')
+    compare_files "${f0}" "${f1}"
+    echo "  >$(basename ${f0}) match"
+done
+
+echo
+echo ' Running simulations from checkpoints...'
+${MPIRUN_EXECUTABLE} -np 4 "${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -L "${TEST_DIR}/checkpoint0.tar" --dump-dir "${TEST_DIR}/run2"
+${MPIRUN_EXECUTABLE} -np 4 "${PYTHON_EXECUTABLE}" "${EXAMPLE_FILE}" ${COMMON_OPTIONS} -L "${TEST_DIR}/checkpoint1.tar" --dump-dir "${TEST_DIR}/run3"
+
+echo ' Comparing solutions...'
+compare_files "${TEST_DIR}/run2/dump/run.txt" "${TEST_DIR}/run3/dump/run.txt"
+echo "  >debug dumps match"
+for f0 in $(find "${TEST_DIR}/run2" -name '*.h5' | sort -n); do
+    f1=$(echo "${f0}" | sed 's/run2/run3/')
+    f2=$(echo "${f0}" | sed 's/run2/run0/')
+    f3=$(echo "${f0}" | sed 's/run2/run1/')
+    compare_files "${f0}" "${f1}"
+    compare_files "${f0}" "${f2}"
+    compare_files "${f0}" "${f3}"
+    echo "  >$(basename ${f0}) match"
+done
 
 
 #
diff --git a/hysop/operator/adapt_timestep.py b/hysop/operator/adapt_timestep.py
index 465cb51aa..b09ce9cfa 100755
--- a/hysop/operator/adapt_timestep.py
+++ b/hysop/operator/adapt_timestep.py
@@ -91,8 +91,8 @@ class TimestepCriteria(HostOperatorBase, metaclass=ABCMeta):
     def apply(self, **kwds):
         dt = self.compute_criteria(**kwds)
         dt *= self.dt_coeff
-        dt = self._collect_max(np.maximum(dt, self.min_dt, dtype=dt.dtype))
-        dt = self._collect_min(np.minimum(dt, self.max_dt, dtype=dt.dtype))
+        dt = self._collect_max(np.maximum(dt, self.min_dt))
+        dt = self._collect_min(np.minimum(dt, self.max_dt))
         assert (dt > 0.0), 'negative or zero timestep encountered.'
         self.dt.set_value(dt)
 
diff --git a/hysop/operator/base/poisson_curl.py b/hysop/operator/base/poisson_curl.py
index ee049b87a..af59caebd 100644
--- a/hysop/operator/base/poisson_curl.py
+++ b/hysop/operator/base/poisson_curl.py
@@ -381,9 +381,10 @@ class SpectralPoissonCurlOperatorBase(PoissonCurlOperatorBase, SpectralOperatorB
                 plt = None
 
             freqs = self.compute_energy_frequencies[k]
+            iops = tuple(self.io_params.clone(frequency=f, with_last=True) for f in freqs)
 
-            def compute_fn(simulation, plt=plt, dmp=dmp, dst=Ep._value, srcs=E_buffers, freqs=freqs):
-                should_compute = any(simulation.should_dump(frequency=f, with_last=True) for f in freqs)
+            def compute_fn(simulation, plt=plt, dmp=dmp, dst=Ep._value, srcs=E_buffers, iops=iops):
+                should_compute = any(iop.sould_dump(simulation=simulation) for iop in iops)
                 if should_compute:
                     dst[...] = 0.0
                     for src in srcs:
diff --git a/hysop/operator/base/spectral_operator.py b/hysop/operator/base/spectral_operator.py
index 700508771..9ee4d0aaf 100644
--- a/hysop/operator/base/spectral_operator.py
+++ b/hysop/operator/base/spectral_operator.py
@@ -2083,6 +2083,9 @@ SPECTRAL TRANSFORM SETUP
         else:
             compute_energy_queue = None
 
+        self._frequency_ioparams = tuple(self.io_params.clone(frequency=f, with_last=True)
+                                    for f in self._compute_energy_frequencies)
+
         self._queue = queue
         self._compute_energy_queue = compute_energy_queue
         self._ready = True
@@ -2119,8 +2122,7 @@ SPECTRAL TRANSFORM SETUP
         msg = 'No simulation was passed in {}.__call__().'.format(type(self))
         assert (simulation is not None), msg
         evt = wait_for
-        should_compute_energy = any(simulation.should_dump(frequency=f, with_last=True)
-                                    for f in self._compute_energy_frequencies)
+        should_compute_energy = any(iop.should_dump(simulation=simulation) for iop in self._frequency_ioparams)
         if should_compute_energy:
             evt = self._compute_energy_queue(wait_for=evt)
             if self._do_dump_energy:
@@ -2133,3 +2135,4 @@ SPECTRAL TRANSFORM SETUP
         evt = wait_for
         self._energy_plotter.update(simulation=simulation, wait_for=evt)
         return wait_for
+
diff --git a/hysop/operator/hdf_io.py b/hysop/operator/hdf_io.py
index c04a0b82d..dea988f9f 100755
--- a/hysop/operator/hdf_io.py
+++ b/hysop/operator/hdf_io.py
@@ -224,7 +224,7 @@ class HDF_IO(HostOperatorBase, metaclass=ABCMeta):
             assert npw.array_equal(refmesh.grid_resolution, mesh.grid_resolution), 'global grid resolution mismatch'
             assert (mesh.on_proc == refmesh.on_proc)
             if mesh.on_proc:
-                local_compute_slices[field] = mesh.local_compute_slices
+                local_compute_slices[field]  = mesh.local_compute_slices
                 global_compute_slices[field] = mesh.global_compute_slices
             else:
                 local_compute_slices[field]  = tuple(slice(0, 0) for _ in range(self.domain.dim))
@@ -525,26 +525,26 @@ class HDF_Writer(HDF_IO):
         # Get the names of output input_fields and create the corresponding
         # datasets
         if self.use_local_hdf5:
-            for name in self.dataset:
-                ds = self._hdf_file.create_dataset(name,
-                                                   self._local_grid_resolution,
-                                                   dtype=npw.float64,
+            for name in sorted(self.dataset):
+                ds = self._hdf_file.create_dataset(name=name,
+                                                   shape=self._local_grid_resolution,
+                                                   dtype=self.dataset[name].dtype,
                                                    compression=compression,
                                                    track_times=False) # required if we want to compare checksums in tests
-                ds[...] = self._data_getters[name]().astype(npw.float64)
+                ds[...] = self._data_getters[name]()
         elif self.use_parallel_hdf5:
-            for name in self.dataset:
-                ds = self._hdf_file.create_dataset(name,
-                                                   self._global_grid_resolution,
-                                                   dtype=npw.float64,
+            for name in sorted(self.dataset):
+                ds = self._hdf_file.create_dataset(name=name,
+                                                   shape=self._global_grid_resolution,
+                                                   dtype=self.dataset[name].dtype,
                                                    compression=compression,
                                                    track_times=False) # required if we want to compare checksums in tests
                 if (compression is None):
                     # no need for collective here because we do not use any filter
-                    ds[self._global_compute_slices[name]] = self._data_getters[name]().astype(npw.float64)
+                    ds[self._global_compute_slices[name]] = self._data_getters[name]()
                 else:
                     with ds.collective:
-                        ds[self._global_compute_slices[name]] = self._data_getters[name]().astype(npw.float64)
+                        ds[self._global_compute_slices[name]] = self._data_getters[name]()
         else:
             msg = 'Unknown HDF5 mode.'
             raise RuntimeError(msg)
diff --git a/hysop/operator/parameter_plotter.py b/hysop/operator/parameter_plotter.py
index 1b510d2fd..85a058eaf 100644
--- a/hysop/operator/parameter_plotter.py
+++ b/hysop/operator/parameter_plotter.py
@@ -71,6 +71,9 @@ class PlottingOperator(HostOperatorBase):
         self.running = True
         self.plt = plt
 
+        self.update_ioparams = self.io_params.clone(frequency=self.update_frequency, with_last=True)
+        self.save_ioparams   = self.io_params.clone(frequency=self.save_frequency, with_last=True)
+
     def draw(self):
         if (not self.running):
             return
@@ -84,13 +87,13 @@ class PlottingOperator(HostOperatorBase):
         self._save(**kwds)
 
     def _update(self, simulation, **kwds):
-        if simulation.should_dump(frequency=self.update_frequency, with_last=True):
+        if self.update_ioparams.should_dump(simulation=simulation):
             self.update(simulation=simulation, **kwds)
             if self.should_draw:
                 self.draw()
 
     def _save(self, simulation, **kwds):
-        if simulation.should_dump(frequency=self.save_frequency, with_last=True):
+        if self.save_ioparams.should_dump(simulation=simulation):
             self.save(simulation=simulation, **kwds)
 
     @abstractmethod
diff --git a/hysop/simulation.py b/hysop/simulation.py
index d288337bd..c96cefdfb 100644
--- a/hysop/simulation.py
+++ b/hysop/simulation.py
@@ -463,16 +463,3 @@ class Simulation(object):
         s += str(self.current_iteration) + ', max number of iterations : '
         s += str(self.max_iter)
         return s
-
-    def should_dump(self, frequency, with_last=False):
-        import warnings
-        from hysop.tools.warning import HysopDeprecationWarning
-        msg = 'This method will be deprecated soon. Please use io_params.should_dump(simulation, with_last) instead.'
-        warnings.warn(msg, HysopDeprecationWarning)
-
-        dump = (frequency >= 0) and (with_last and self._next_is_last)
-        if (frequency >= 0):
-            dump |= self.is_time_of_interest
-        if (frequency > 0):
-            dump |= ((self.current_iteration % frequency) == 0)
-        return dump
diff --git a/hysop/tools/spectral_utils.py b/hysop/tools/spectral_utils.py
index c7c3dbfec..7bbddaa5d 100644
--- a/hysop/tools/spectral_utils.py
+++ b/hysop/tools/spectral_utils.py
@@ -755,7 +755,7 @@ class EnergyDumper(object):
     def update(self, simulation, wait_for):
         if not self.should_write:
             return
-        if not self.io_params.should_dump(simulation=simulation, with_last=True):
+        if not self.io_params.should_dump(simulation=simulation):
             return
         if (wait_for is not None):
             wait_for.wait()
@@ -795,6 +795,7 @@ class EnergyDumper(object):
             param = None
         return param
 
+
 class EnergyPlotter(object):
     def __init__(self, energy_parameters, io_params, fname,
             fig_title=None, axes_shape=(1,), figsize=(15,9),
@@ -891,7 +892,7 @@ class EnergyPlotter(object):
     def update(self, simulation, wait_for):
         if not self.should_draw:
             return
-        if not simulation.should_dump(frequency=self.io_params.frequency, with_last=True):
+        if not self.io_params.should_dump(simulation=simulation):
            return
         if (wait_for is not None):
             wait_for.wait()
diff --git a/hysop/topology/cartesian_descriptor.py b/hysop/topology/cartesian_descriptor.py
index 47aaffbda..d60fba98b 100644
--- a/hysop/topology/cartesian_descriptor.py
+++ b/hysop/topology/cartesian_descriptor.py
@@ -112,6 +112,8 @@ class CartesianTopologyDescriptor(TopologyDescriptor):
         return self.match(other)
     def __ne__(self, other):
         return self.match(other, invert=True)
+    def __lt__(self, other):
+        return (self != other) and (str(self) < str(other))
 
     def __hash__(self):
         # hash(super(...)) does not work as expected so be call __hash__ directly
diff --git a/hysop/topology/cartesian_topology.py b/hysop/topology/cartesian_topology.py
index 18642f8fa..3ed303837 100644
--- a/hysop/topology/cartesian_topology.py
+++ b/hysop/topology/cartesian_topology.py
@@ -807,9 +807,9 @@ class CartesianTopology(CartesianTopologyView, Topology):
                 assert dim <= domain_dim, 'cutdirs is not of size domain_dim'
                 cart_shape = npw.asintegerarray(MPI.Compute_dims(parent_size,dim))
                 cls._optimize_shape(cart_shape)
-                assert np.sum(cutdirs > 0) == cart_shape.size,\
+                assert sum(cutdirs) == cart_shape.size,\
                     "Created shape {} doesnt respect specified cutdirs {}".format(
-                        np.sum(cutdirs > 0), cart_shape.size)
+                        sum(cutdirs), cart_shape.size)
                 shape[is_distributed>0] = cart_shape
             else:
                 assert parent_size==1
diff --git a/hysop_examples/examples/scalar_advection/turbulent_scalar_advection.py b/hysop_examples/examples/scalar_advection/turbulent_scalar_advection.py
index 3c1f91519..7ef95d057 100644
--- a/hysop_examples/examples/scalar_advection/turbulent_scalar_advection.py
+++ b/hysop_examples/examples/scalar_advection/turbulent_scalar_advection.py
@@ -48,7 +48,7 @@ def init_scal(data, coords, component):
     data[...] *= (1. + ampl3 * np.sin(8. * pi * x))
 
 
-from hysop import Box, Simulation, Problem, MPIParams, Field
+from hysop import Box, Simulation, Problem, MPIParams, Field, IOParams
 from hysop.defaults import VelocityField, VorticityField, \
                            EnstrophyParameter, TimeParameters
 from hysop.constants import Implementation, AdvectionCriteria, HYSOP_REAL, \
@@ -198,9 +198,10 @@ dt_advec = adapt_dt.push_advection_criteria(lcfl=lcfl, Finf=min_max_W.Finf,
                                             criteria=AdvectionCriteria.W_INF)
 
 #> We ask to dump the outputs of this operator
-poisson.dump_inputs(fields=(vorti,), frequency=dump_freq)
-poisson.dump_outputs(fields=(velo,),  frequency=dump_freq)
-splitting_scal.dump_outputs(fields=(scal,),  frequency=dump_freq)
+io_params = IOParams(filename='dummy', dump_freq=dump_freq)
+poisson.dump_inputs(fields=(vorti,), io_params=io_params.clone(filename='vorti'))
+poisson.dump_outputs(fields=(velo,), io_params=io_params.clone(filename='velo'))
+splitting_scal.dump_outputs(fields=(scal,), frequency=dump_freq, io_params=io_params.clone(filename='scalar'))
 
 ## Create the problem we want to solve and insert our
 # directional splitting subgraph and the standard operators.
diff --git a/hysop_examples/examples/shear_layer/shear_layer.py b/hysop_examples/examples/shear_layer/shear_layer.py
index 2bbddc273..e915ff0ef 100644
--- a/hysop_examples/examples/shear_layer/shear_layer.py
+++ b/hysop_examples/examples/shear_layer/shear_layer.py
@@ -21,6 +21,8 @@ def compute(args):
 
     from hysop.symbolic import space_symbols
 
+    msg='Parameters are: delta={}, rho={}, visco={}'.format(args.delta, args.rho, args.nu)
+
     # Define the domain
     dim  = args.ndim
     npts = args.npts
@@ -220,11 +222,11 @@ if __name__=='__main__':
             description+='\n  CASE     0        1        2'
             description+='\n  delta    0.5      0.5      0.5'
             description+='\n  rho      30       100      100'
-            description+='\n  visco    1.0e-4   0.5e-4   0.25e-4'
+            description+='\n  visco    1.0e-4   1.0e-4   0.5e-4'
             description+='\n  comment  thick    thin     thin'
             description+='\n'
             description+='\nSee the original paper at '
-            description+='http://crd.lbl.gov/assets/pubs_presos/underIIJCP.pdf.'
+            description+='http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.27.7942&rep=rep1&type=pdf'
 
             super(ShearLayerArgParser, self).__init__(
                  prog_name=prog_name,
@@ -287,21 +289,21 @@ if __name__=='__main__':
             rho_defaults   = (30.0,   100.0,  100.0)
             nu_defaults    = (1.0e-4, 0.5e-4, 0.25e-4)
 
-            args.rho   = first_not_None(args.rho, rho_defaults[case])
             args.delta = first_not_None(args.delta, delta_defaults[case])
+            args.rho   = first_not_None(args.rho, rho_defaults[case])
             args.nu    = first_not_None(args.nu, nu_defaults[case])
 
             self._check_positive(args, ('rho','delta','nu'), strict=True, allow_none=False)
 
             if (args.ndim != 2):
-                msg='This example only works for 2D domains.'
+                msg='This example only works on 2D domains.'
                 self.error(msg)
 
     parser = ShearLayerArgParser()
 
     parser.set_defaults(impl='cl', ndim=2, npts=(256,),
                         box_origin=(0.0,), box_length=(1.0,),
-                        tstart=0.0, tend=1.25,
+                        tstart=0.0, tend=1.2,
                         dt=1e-4, cfl=0.5, lcfl=0.125,
                         case=0, dump_freq=0, dump_times=(0.8, 1.20))
 
diff --git a/hysop_examples/examples/taylor_green/taylor_green.py b/hysop_examples/examples/taylor_green/taylor_green.py
index 39e4a016b..a436d3e5b 100644
--- a/hysop_examples/examples/taylor_green/taylor_green.py
+++ b/hysop_examples/examples/taylor_green/taylor_green.py
@@ -252,7 +252,7 @@ def compute(args):
                     axe2.axhline(y=args.cfl, color='r', linestyle='--')
                     axe2.set_ylim(0., 1.1*args.cfl)
         plot = EnstrophyPlotter(update_frequency=args.plot_freq,
-                                visu_rank=args.visu_rank)
+                                visu_rank=args.visu_rank, io_params=args.io_params)
     else:
         plot = None
 
-- 
GitLab