class AdvanceTest(AdvanceTestBase):
    @data(
        *per_interp({}),
        *per_interp({"L0": [Box2D(10, 19)]}),
        *per_interp({"L0": [Box2D(5, 9), Box2D(10, 14)]}),
    )
    @unpack
    def test_overlapped_particledatas_have_identical_particles(
            self, interp_order, refinement_boxes):
        self._test_overlapped_particledatas_have_identical_particles(
            ndim,
            interp_order,
            refinement_boxes,
            ppc=ppc,
            cells=40,
            largest_patch_size=20)

    @data(*interp_orders)
    def test_L0_particle_number_conservation(self, interp):
        self._test_L0_particle_number_conservation(ndim, interp, ppc=ppc)

    @data(
        *per_interp(({
            "L0": {
                "B0": Box2D(10, 14)
            }
        })), )
    @unpack
    def test_domain_particles_on_refined_level(self, interp_order,
                                               refinement_boxes):
        self._test_domain_particles_on_refined_level(ndim,
                                                     interp_order,
                                                     refinement_boxes,
                                                     nbr_part_per_cell=ppc)
Example #2
0
    def test_touch_border(self):
        print("GeometryTest.test_touch_border")
        hierarchy = super().basic_hierarchy()

        domain_box = hierarchy.domain_box
        self.assertFalse(touch_domain_border(Box2D(10, 14), domain_box, "upper"))
        self.assertFalse(touch_domain_border(Box2D(10, 14), domain_box, "lower"))
        self.assertTrue(touch_domain_border(Box2D(0, 14), domain_box, "lower"))
        self.assertTrue(touch_domain_border(Box2D(-5, 14), domain_box, "lower"))
        self.assertTrue(touch_domain_border(Box2D(-5, 10), domain_box, "lower"))
        self.assertTrue(touch_domain_border(Box2D(-5, 30), domain_box, "upper"))
        self.assertTrue(touch_domain_border(Box2D(10, 30), domain_box, "upper"))
        self.assertTrue(touch_domain_border(Box2D(10, 24), domain_box, "upper"))
Example #3
0
class BoxTesT(unittest.TestCase):
    @data(
        (Box(10, 20), Box(10, 20)),
        (Box(-5, 5), Box(-5, 5)),
        (Box(-5, -2), Box(-5, -2)),
        (Box([10, 10], [20, 20]), Box([10, 10], [20, 20])),
        (Box([-5, -5], [5, 5]), Box([-5, -5], [5, 5])),
        (Box([-5, -5], [-2, -2]), Box([-5, -5], [-2, -2])),
    )
    @unpack
    def test_box_equality(self, box1, box2):
        self.assertTrue(box1 == box2)

    @data(
        (Box(10, 20), Box(20, 41)),
        (Box(-5, 11), Box(-10, 23)),
        (Box(-5, -2), Box(-10, -3)),
        (Box(1, 1), Box(2, 3)),
        (Box([10, 10], [20, 20]), Box([20, 20], [41, 41])),
        (Box([-5, -5], [11, 11]), Box([-10, -10], [23, 23])),
        (Box([-5, -5], [-2, -2]), Box([-10, -10], [-3, -3])),
        (Box([1, 1], [1, 1]), Box([2, 2], [3, 3])),
    )
    @unpack
    def test_box_refinement(self, coarse, exp_refined):
        actual_refined = boxm.refine(coarse, 2)
        self.assertEqual(actual_refined, exp_refined)

    @data(
        (Box(10, 20), Box(15, 30), Box(15, 20)),  # upper intersection
        (Box(-5, 20), Box(5, 5), Box(5, 5)),  # box2 within and 1 cell
        (Box(-5, -5), Box(-5, -5), Box(-5, -5)),  # all negative & 1 cell
        (Box(-5, 10), Box(-10, -5), Box(-5,
                                        -5)),  # negative and box2 lower inter.
        (Box(10, 11), Box(11, 12), Box(11, 11)),  # positive upper cell inter
        (Box(10, 11), Box(14, 15), None),  # no inter
        # upper intersection
        (Box([10, 10], [20, 20]), Box([15, 15],
                                      [30, 30]), Box([15, 15], [20, 20])),
        # box2 within and 1 cell
        (Box([-5, -5], [20, 20]), Box([5, 5], [5, 5]), Box([5, 5], [5, 5])),
        # all negative & 1 cell
        (Box([-5, -5], [-5, -5]), Box([-5, -5],
                                      [-5, -5]), Box([-5, -5], [-5, -5])),
        # negative and box2 lower inter.
        (Box([-5, -5], [10, 10]), Box([-10, -10],
                                      [-5, -5]), Box([-5, -5], [-5, -5])),
        # positive upper cell inter
        (Box([10, 10], [11, 11]), Box([11, 11],
                                      [12, 12]), Box([11, 11], [11, 11])),
        # no inter
        (Box1D(10, 11), Box1D(14, 15), None),
        (Box2D(10, 11), Box2D(14, 15), None),
        (Box3D(10, 11), Box3D(14, 15), None),
    )
    @unpack
    def test_intersection(self, box1, box2, exp_inter):
        self.assertEqual(box1 * box2, exp_inter)

    @data(
        (Box(10, 20), 5, Box(15, 25)),
        (Box(10, 20), -5, Box(5, 15)),
        (Box(10, 20), -15, Box(-5, 5)),
        (Box(-5, 20), 10, Box(5, 30)),
        (Box(-5, -5), -2, Box(-7, -7)),
        (Box([10, 10], [20, 20]), 5, Box([15, 15], [25, 25])),
        (Box([10, 10], [20, 20]), [5, 0], Box([15, 10], [25, 20])),
        (Box([10, 10], [20, 20]), [0, 5], Box([10, 15], [20, 25])),
        (Box([10, 10], [20, 20]), -5, Box([5, 5], [15, 15])),
        (Box([10, 10], [20, 20]), -15, Box([-5, -5], [5, 5])),
        (Box([-5, -5], [20, 20]), 10, Box([5, 5], [30, 30])),
        (Box([-5, -5], [-5, -5]), -2, Box([-7, -7], [-7, -7])),
    )
    @unpack
    def test_shift(self, box, shift, expected):
        self.assertEqual(boxm.shift(box, shift), expected)

    @data(
        (Box(10, 20), 5, Box(5, 25)),
        (Box(-5, 20), 10, Box(-15, 30)),
        (Box(-5, -5), 2, Box(-7, -3)),
        (Box([10, 10], [20, 20]), 5, Box([5, 5], [25, 25])),
        (Box([-5, -5], [20, 20]), 10, Box([-15, -15], [30, 30])),
        (Box([-5, -5], [-5, -5]), 2, Box([-7, -7], [-3, -3])),
    )
    @unpack
    def test_grow(self, box, size, expected):
        self.assertEqual(boxm.grow(box, [size] * box.dim()), expected)

    @data(
        (Box(10, 12)),
        (Box([10, 10], [12, 12])),
    )
    def test_grow_neg_size_raises(self, box):
        with self.assertRaises(ValueError):
            boxm.grow(box, [-1] * box.dim())

    @data(
        (Box1D(10, 29), Box1D(10, 25), [Box1D(26, 29)]),
        (Box1D(10, 29), Box1D(25, 29), [Box1D(10, 24)]),
        (Box1D(10, 29), Box1D(15, 19), [Box1D(10, 14),
                                        Box1D(20, 29)]),
        (Box1D(10, 29), Box1D(20, 29), [Box1D(10, 19)]),
        (Box(10, 30), Box(15, 25), [Box(10, 14), Box(26, 30)
                                    ]),  # remove middle part
        (Box(10, 30), Box(5, 20), [
            Box(21, 30),
        ]),  # remove lower part
        (Box(10, 30), Box(15, 35), [
            Box(10, 14),
        ]),  # remove upper part
        (Box(10, 30), Box(5, 35), []),  # remove all
        (Box(-10, 30), Box(-5, 25), [Box(-10, -6), Box(26, 30)
                                     ]),  # remove middle part
        (Box(-10, 30), Box(-15, 20), [
            Box(21, 30),
        ]),  # remove lower part
        (Box(-10, 30), Box(15, 35), [
            Box(-10, 14),
        ]),  # remove upper part
        (Box(-10, 30), Box(-15, 35), []),  # remove all
        (Box2D(10, 29), Box([10, 10], [25, 35]), [Box([26, 10], [29, 29])]),
        (Box2D(10, 29), Box([10, 10], [35, 25]), [Box([10, 26], [29, 29])]),
        (
            Box2D(10, 29),
            Box2D(10, 25),
            [  # remove down left
                Box([26, 10], [29, 29]),  # right
                Box([10, 26], [25, 29]),  # up
            ]),
        (
            Box2D(10, 29),
            Box2D(20, 29),
            [  # remove up right
                Box([10, 10], [19, 29]),  # left
                Box([20, 10], [29, 19])  # down
            ]),
        (
            Box2D(10, 29),
            Box2D(15, 25),
            [  # remove middle
                Box([10, 10], [14, 29]),  # left
                Box([26, 10], [29, 29]),  # right
                Box([15, 10], [25, 14]),  # down
                Box([15, 26], [25, 29])  # up
            ]),
        (
            Box2D(10, 29),
            Box2D(20, 25),
            [  # remove middle
                Box([10, 10], [19, 29]),  # left
                Box([26, 10], [29, 29]),  # right
                Box([20, 10], [25, 19]),  # down
                Box([20, 26], [25, 29])  # up
            ]),
        (
            Box2D(10, 29),
            Box([15, 10], [15, 25]),
            [  # enters one side
                Box([10, 10], [14, 29]),  # left
                Box([16, 10], [29, 29]),  # right
                Box([15, 26], [15, 29])  # up
            ]),
        (
            Box3D(10, 29),
            Box3D(10, 15),
            [  # remove down left back
                Box([16, 10, 10], [29, 29, 29]),  # right
                Box([10, 16, 10], [15, 29, 29]),  # up
                Box([10, 10, 16], [15, 15, 29]),  # front
            ]),
        (
            Box3D(10, 29),
            Box3D(20, 25),
            [  # remove middle
                Box([10, 10, 10], [19, 29, 29]),  # left
                Box([26, 10, 10], [29, 29, 29]),  # right
                Box([20, 10, 10], [25, 19, 29]),  # down
                Box([20, 26, 10], [25, 29, 29]),  # up
                Box([20, 20, 10], [25, 25, 19]),  # back
                Box([20, 20, 26], [25, 25, 29]),  # front
            ]),
        (
            Box3D(10, 29),
            Box([20, 10, 20], [20, 29, 20]),
            [  # remove middle Y block
                Box([10, 10, 10], [19, 29, 29]),  # left
                Box([21, 10, 10], [29, 29, 29]),  # right
                Box([20, 10, 10], [20, 29, 19]),  # back
                Box([20, 10, 21], [20, 29, 29]),  # front
            ]),
        (
            Box3D(10, 29),
            Box([10, 10, 10], [10, 29, 29]),
            [  # remove left
                Box([11, 10, 10], [29, 29, 29]),  # right
            ]),
        (
            Box3D(10, 29),
            Box([29, 10, 10], [29, 29, 29]),
            [  # remove right
                Box([10, 10, 10], [28, 29, 29]),  # left
            ]),
        (
            Box3D(10, 29),
            Box([10, 10, 10], [29, 29, 10]),
            [  # remove back
                Box([10, 10, 11], [29, 29, 29]),  # front
            ]),
        (
            Box3D(10, 29),
            Box([10, 10, 29], [29, 29, 29]),
            [  # remove front
                Box([10, 10, 10], [29, 29, 28]),  # back
            ]),
    )
    @unpack
    def test_remove(self, box, to_remove, expected):

        remaining = boxm.remove(box, to_remove)
        self.assertEqual(expected, remaining)

        for i, k0 in enumerate(remaining):
            self.assertTrue(k0 in box)
            self.assertTrue(k0 not in to_remove)
            for k1 in remaining[i + 1:]:
                self.assertTrue(k0 not in k1)

        expectedCells, remainingCells = 0, 0
        for exp, keep in zip(expected, remaining):
            expectedCells += exp.cells()
            remainingCells += keep.cells()

        self.assertTrue(expectedCells == remainingCells)
        self.assertTrue(box.cells() == remainingCells +
                        (box * to_remove).cells())

    @data((Box(10, 20), 10, True), (Box(10, 20), 11, True),
          (Box(10, 20), 20, True), (Box(-20, -10), -10, True),
          (Box(-20, -10), -20, True), (Box(-20, -10), -11, True),
          (Box(-20, -10), -9, False), (Box(10, 20), Box(10, 11), True),
          (Box(10, 20), Box(10, 10), True), (Box(10, 20), Box(15, 20), True),
          (Box(10, 20), Box(20, 20), True), (Box(10, 20), Box(20, 21), False),
          (Box(10, 20), Box(20, 21), False),
          (Box([10, 10], [20, 20]), [10, 10], True),
          (Box([10, 10], [20, 20]), [11, 11], True),
          (Box([10, 10], [20, 20]), [20, 20], True),
          (Box([-20, -20], [-10, -10]), [-10, -10], True),
          (Box([-20, -20], [-10, -10]), [-20, -20], True),
          (Box([-20, -20], [-10, -10]), [-11, -11], True),
          (Box([-20, -20], [-10, -10]), [-9, -9], False),
          (Box([10, 10], [20, 20]), Box([10, 10], [11, 11]), True),
          (Box([10, 10], [20, 20]), Box([10, 10], [10, 10]), True),
          (Box([10, 10], [20, 20]), Box([15, 15], [20, 20]), True), (Box(
              [10, 10], [20, 20]), Box([20, 20], [20, 20]), True), (Box2D(
                  10, 20), Box2D(21, 21), False), (Box3D(10, 20), Box3D(
                      20, 20), True), (Box3D(10, 20), Box3D(21, 21), False))
    @unpack
    def test_in(self, box, element, expected):
        self.assertEqual(element in box, expected)

    @data((Box(33, 64), Box(-5, 69), Box(38, 69)), (Box(
        [33, 33], [64, 64]), Box([-5, -5], [69, 69]), Box([38, 38], [69, 69])))
    @unpack
    def test_amr_to_local(self, box, ref_box, expected):
        self.assertEqual(boxm.amr_to_local(box, ref_box), expected)
class AdvanceTest(AdvanceTestBase):
    @data(
        *per_interp({}),
        *per_interp({"L0": [Box2D(10, 19)]}),
        *per_interp({"L0": [Box2D(8, 20)]}),
    )
    @unpack
    def test_overlaped_fields_are_equal(self, interp_order, refinement_boxes):
        print(f"{self._testMethodName}_{ndim}d")
        time_step_nbr = 3
        time_step = 0.001
        diag_outputs = f"phare_overlaped_fields_are_equal_{ndim}_{self.ddt_test_id()}"
        datahier = self.getHierarchy(interp_order,
                                     refinement_boxes,
                                     "eb",
                                     diag_outputs=diag_outputs,
                                     time_step=time_step,
                                     time_step_nbr=time_step_nbr,
                                     ndim=ndim,
                                     nbr_part_per_cell=ppc)
        self._test_overlaped_fields_are_equal(datahier, time_step_nbr,
                                              time_step)

    @data(
        *per_interp({}),
        *per_interp({"L0": [Box2D(10, 19)]}),
    )
    @unpack
    def test_overlaped_fields_are_equal_with_min_max_patch_size_of_max_ghosts(
            self, interp_order, refinement_boxes):
        print(f"{self._testMethodName}_{ndim}d")
        time_step_nbr = 3
        time_step = 0.001
        from pyphare.pharein.simulation import check_patch_size
        diag_outputs = f"phare_overlaped_fields_are_equal_with_min_max_patch_size_of_max_ghosts/{ndim}/{interp_order}/{self.ddt_test_id()}"
        largest_patch_size, smallest_patch_size = check_patch_size(
            ndim, interp_order=interp_order, cells=[60] * ndim)
        datahier = self.getHierarchy(interp_order,
                                     refinement_boxes,
                                     "eb",
                                     diag_outputs=diag_outputs,
                                     smallest_patch_size=smallest_patch_size,
                                     largest_patch_size=smallest_patch_size,
                                     time_step=time_step,
                                     time_step_nbr=time_step_nbr,
                                     ndim=ndim,
                                     nbr_part_per_cell=ppc)
        self._test_overlaped_fields_are_equal(datahier, time_step_nbr,
                                              time_step)

    @data(
        *per_interp(({
            "L0": {
                "B0": Box2D(10, 14)
            }
        })),
        *per_interp(({
            "L0": {
                "B0": Box2D(10, 14),
                "B1": Box2D(15, 19)
            }
        })),
        *per_interp(({
            "L0": {
                "B0": Box2D(6, 23)
            }
        })),
        *per_interp(({
            "L0": {
                "B0": Box2D(2, 12),
                "B1": Box2D(13, 25)
            }
        })),
        *per_interp(({
            "L0": {
                "B0": Box2D(5, 20)
            },
            "L1": {
                "B0": Box2D(15, 19)
            }
        })),
        *per_interp(({
            "L0": {
                "B0": Box2D(5, 20)
            },
            "L1": {
                "B0": Box2D(12, 38)
            },
            "L2": {
                "B0": Box2D(30, 52)
            }
        })),
    )
    @unpack
    def test_field_coarsening_via_subcycles(self, interp_order,
                                            refinement_boxes):
        print(f"{self._testMethodName}_{ndim}d")
        self._test_field_coarsening_via_subcycles(ndim,
                                                  interp_order,
                                                  refinement_boxes,
                                                  dl=.3)

    @data(  # only supports a hierarchy with 2 levels
        # *per_interp(({"L0": [Box2D(0, 4)]})),   # fails?
        *per_interp(({
            "L0": [Box2D(10, 14)]
        })),
        *per_interp(({
            "L0": [Box2D(0, 4), Box2D(10, 14)]
        })),
        *per_interp(({
            "L0": [Box2D(0, 4), Box2D(5, 9),
                   Box2D(10, 14)]
        })),
        *per_interp(({
            "L0": [Box2D(20, 24)]
        })),
        # *per_interp(({"L0": [Box2D(30, 34)]})), # fails?
    )
    @unpack
    def test_field_level_ghosts_via_subcycles_and_coarser_interpolation(
            self, interp_order, refinement_boxes):
        self._test_field_level_ghosts_via_subcycles_and_coarser_interpolation(
            ndim, interp_order, refinement_boxes)
Example #5
0
class SimulatorValidation(unittest.TestCase):
    def __init__(self, *args, **kwargs):
        super(SimulatorValidation, self).__init__(*args, **kwargs)
        self.simulator = None

    def tearDown(self):
        if self.simulator is not None:
            self.simulator.reset()

    def _do_dim(self, dim, input, valid: bool = False):
        for interp in range(1, 4):

            try:
                self.simulator = Simulator(
                    populate_simulation(dim, interp, **input))
                self.simulator.initialize()
                self.assertTrue(valid)
                self.simulator = None
            except ValueError as e:
                self.assertTrue(not valid)

    """
      The first set of boxes "B0": [(10,), (14,)]
      Are configured to force there to be a single patch on L0
      This creates a case with MPI that there are an unequal number of
      Patches across MPI domains. This case must be handled and not hang due
      to collective calls not being handled properly.
    """
    valid1D = [
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": {
                    "B0": [(10, ), (14, )]
                }
            }
        }),
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": {
                    "B0": [(5, ), (55, )]
                }
            }
        }),
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": {
                    "B0": Box(5, 55)
                }
            }
        }),
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 55)]
            }
        }),
        dup({
            "cells": [65],
            "refinement_boxes": {
                0: [Box(5, 55)]
            }
        }),
        dup({
            "cells": [65],
            "refinement_boxes": {
                0: [Box(0, 55)]
            }
        }),
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 14), Box(15, 25)]
            }
        }),
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 25)],
                "L1": [Box(12, 48)],
                "L2": [Box(60, 64)]
            }
        }),
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 25)],
                "L1": [Box(12, 48)]
            }
        }),
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 25)],
                "L1": [Box(20, 30)]
            }
        }),
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 25)],
                "L1": [Box(11, 49)]
            },
            "nesting_buffer": 1
        }),
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 25)],
                "L1": [Box(10, 50)]
            }
        }),
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 25)],
                "L1": [Box(15, 49)]
            }
        }),
        dup({
            "cells": [65],
            "refinement_boxes": None,
            "smallest_patch_size": 20,
            "largest_patch_size": 20,
            "nesting_buffer": 10
        }),
        # finer box is within set of coarser boxes
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 9), Box(10, 15)],
                "L1": [Box(11, 29)]
            }
        }),
    ]

    invalid1D = [
        # finer box outside lower
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 24)],
                "L1": [Box(9, 30)]
            }
        }),
        # finer box outside upper
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 24)],
                "L1": [Box(15, 50)]
            }
        }),
        # overlapping boxes
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 15), Box(15, 25)]
            }
        }),
        # box.upper outside domain
        dup({
            "cells": [55],
            "refinement_boxes": {
                "L0": {
                    "B0": [(5, ), (65, )]
                }
            }
        }),
        # largest_patch_size > smallest_patch_size
        dup({
            "smallest_patch_size": 100,
            "largest_patch_size": 64,
        }),
        # refined_particle_nbr doesn't exist
        dup({"refined_particle_nbr": 1}),
        # L2 box incompatible with L1 box due to nesting buffer
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 25)],
                "L1": [Box(11, 49)]
            },
            "nesting_buffer": 2
        }),
        # negative nesting buffer
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 25)],
                "L1": [Box(11, 49)]
            },
            "nesting_buffer": -1
        }),
        # too large nesting buffer
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 25)],
                "L1": [Box(11, 49)]
            },
            "nesting_buffer": 33
        }),
        dup({
            "cells": [65],
            "refinement_boxes": None,
            "largest_patch_size": 20,
            "nesting_buffer": 46
        }),
        # finer box is not within set of coarser boxes
        dup({
            "cells": [65],
            "refinement_boxes": {
                "L0": [Box(5, 9), Box(11, 15)],
                "L1": [Box(11, 29)]
            }
        }),
    ]

    @data(*valid1D)
    def test_1d_valid(self, input):
        self._do_dim(1, input, True)

    @data(*invalid1D)
    def test_1d_invalid(self, input):
        self._do_dim(1, input)

    valid2D = [
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 55)]
            }
        }),
        dup({
            "smallest_patch_size": None,
            "largest_patch_size": None
        }),
        dup({
            "smallest_patch_size": (10, 10),
            "largest_patch_size": (20, 20)
        }),
        dup({
            "smallest_patch_size": [10, 10],
            "largest_patch_size": [20, 20]
        }),
        dup({
            "smallest_patch_size": (10, 10),
            "largest_patch_size": None
        }),
        dup({
            "smallest_patch_size": None,
            "largest_patch_size": (20, 20)
        }),
        dup({"smallest_patch_size": (10, 10)}),
        dup({"largest_patch_size": (20, 20)}),
        dup({
            "smallest_patch_size": 10,
            "largest_patch_size": (20, 20)
        }),
        dup({
            "smallest_patch_size": (10, 10),
            "largest_patch_size": 20
        }),
        dup({
            "smallest_patch_size": [10, 10],
            "largest_patch_size": (20, 20)
        }),
        dup({
            "smallest_patch_size": (10, 10),
            "largest_patch_size": [20, 20]
        }),
        dup({
            "cells": [65, 65],
            "refinement_boxes": None,
            "smallest_patch_size": 20,
            "largest_patch_size": 20,
            "nesting_buffer": 10
        }),
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": {
                    "B0": Box2D(5, 55)
                }
            }
        }),
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 55)]
            }
        }),
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                0: [Box2D(5, 55)]
            }
        }),
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                0: [Box2D(0, 55)]
            }
        }),
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 14), Box2D(15, 25)]
            }
        }),
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 25)],
                "L1": [Box2D(12, 48)],
                "L2": [Box2D(60, 64)]
            }
        }),
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 25)],
                "L1": [Box2D(12, 48)]
            }
        }),
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 25)],
                "L1": [Box2D(20, 30)]
            }
        }),
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 25)],
                "L1": [Box2D(11, 49)]
            },
            "nesting_buffer": 1
        }),
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 25)],
                "L1": [Box2D(10, 50)]
            }
        }),
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 25)],
                "L1": [Box2D(15, 49)]
            }
        }),
    ]

    invalid2D = [
        # finer box outside lower
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 24)],
                "L1": [Box2D(9, 30)]
            }
        }),
        # finer box outside lower
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 24)],
                "L1": [Box2D(9, 30)]
            }
        }),
        # finer box outside upper
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 24)],
                "L1": [Box2D(15, 50)]
            }
        }),
        # overlapping boxes
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 15), Box2D(15, 25)]
            }
        }),
        # box.upper outside domain
        dup({
            "cells": [55, 55],
            "refinement_boxes": {
                "L0": {
                    "B0": Box2D(
                        5,
                        65,
                    )
                }
            }
        }),
        # largest_patch_size > smallest_patch_size
        dup({
            "smallest_patch_size": 100,
            "largest_patch_size": 64,
        }),
        # refined_particle_nbr doesn't exist
        dup({"refined_particle_nbr": 1}),
        # L2 box incompatible with L1 box due to nesting buffer
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 25)],
                "L1": [Box2D(11, 49)]
            },
            "nesting_buffer": 2
        }),
        # negative nesting buffer
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 25)],
                "L1": [Box2D(11, 49)]
            },
            "nesting_buffer": -1
        }),
        # too large nesting buffer
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 25)],
                "L1": [Box2D(11, 49)]
            },
            "nesting_buffer": 33
        }),
        dup({
            "cells": [65, 65],
            "refinement_boxes": None,
            "largest_patch_size": 20,
            "nesting_buffer": 46
        }),
        # finer box is not within set of coarser boxes
        dup({
            "cells": [65, 65],
            "refinement_boxes": {
                "L0": [Box2D(5, 9), Box2D(11, 15)],
                "L1": [Box2D(11, 29)]
            }
        }),
    ]

    @data(*valid2D)
    def test_2d_valid(self, input):
        self._do_dim(2, input, True)

    @data(*invalid2D)
    def test_2d_invalid(self, input):
        self._do_dim(2, input)
Example #6
0
class GeometryTest(AGeometryTest):
    @data(
        (
            {
                # no level 1
            },
            {
                0: [
                    {
                        "box": Box([5, 5], [15, 14]),
                        "offset": ([0, 0], [0, 0])
                    },
                    {
                        "box": Box([-5, 5], [15, 14]),
                        "offset": ([0, 0], [0, 0])
                    },
                    {
                        "box": Box([5, -5], [15, 14]),
                        "offset": ([0, 0], [0, 0])
                    },
                    {
                        "box": Box([5, 5], [15, 24]),
                        "offset": ([0, 0], [0, 0])
                    },
                    {
                        "box": Box([5, 5], [25, 14]),
                        "offset": ([0, 0], [0, 0])
                    },
                    {
                        "box": Box([5, 5], [15, 14]),
                        "offset": ([0, 0], [0, 0])
                    },
                    {
                        "box": Box([-5, 5], [5, 14]),
                        "offset": ([0, 0], [-20, 0])
                    },
                    {
                        "box": Box([15, 5], [25, 14]),
                        "offset": ([20, 0], [0, 0])
                    },
                    {
                        "box": Box([-5, -5], [5, 14]),
                        "offset": ([0, 0], [-20, 0])
                    },
                    {
                        "box": Box([15, -5], [25, 14]),
                        "offset": ([20, 0], [0, 0])
                    },
                    {
                        "box": Box([5, -5], [15, 4]),
                        "offset": ([0, 0], [0, -20])
                    },
                    {
                        "box": Box([5, 15], [15, 24]),
                        "offset": ([0, 20], [0, 0])
                    },
                    {
                        "box": Box([-5, -5], [15, 4]),
                        "offset": ([0, 0], [0, -20])
                    },
                    {
                        "box": Box([-5, 15], [15, 24]),
                        "offset": ([0, 20], [0, 0])
                    },
                    {
                        "box": Box([-5, -5], [5, 4]),
                        "offset": ([0, 0], [-20, -20])
                    },
                    {
                        "box": Box([15, 15], [25, 24]),
                        "offset": ([20, 20], [0, 0])
                    },
                    {
                        "box": Box([15, 5], [25, 24]),
                        "offset": ([0, 0], [20, 0])
                    },
                    {
                        "box": Box([-5, 5], [5, 24]),
                        "offset": ([-20, 0], [0, 0])
                    },
                    {
                        "box": Box([5, 15], [25, 24]),
                        "offset": ([0, 0], [0, 20])
                    },
                    {
                        "box": Box([5, -5], [25, 4]),
                        "offset": ([0, -20], [0, 0])
                    },
                    {
                        "box": Box([-5, 5], [5, 14]),
                        "offset": ([0, 0], [-20, 0])
                    },
                    {
                        "box": Box([15, 5], [25, 14]),
                        "offset": ([20, 0], [0, 0])
                    },
                    {
                        "box": Box([5, 15], [15, 24]),
                        "offset": ([0, 0], [0, 20])
                    },
                    {
                        "box": Box([5, -5], [15, 4]),
                        "offset": ([0, -20], [0, 0])
                    },
                    {
                        "box": Box([-5, 15], [5, 24]),
                        "offset": ([0, 0], [-20, 20])
                    },
                    {
                        "box": Box([15, -5], [25, 4]),
                        "offset": ([20, -20], [0, 0])
                    },
                ]
            },
        ),
        (
            {
                "L0": [
                    Box2D(0, 4),
                    Box([0, 15], [4, 19]),
                    Box([15, 0], [19, 4]),
                    Box2D(15, 19),
                ]
            },
            {
                1: [  # level 0 same as previous
                    {
                        "box": Box([-5, -5], [5, 14]),
                        "offset": ([0, 0], [-40, 0])
                    },
                    {
                        "box": Box([35, -5], [45, 14]),
                        "offset": ([40, 0], [0, 0])
                    },
                    {
                        "box": Box([-5, -5], [15, 4]),
                        "offset": ([0, 0], [0, -40])
                    },
                    {
                        "box": Box([-5, 35], [15, 44]),
                        "offset": ([0, 40], [0, 0])
                    },
                    {
                        "box": Box([-5, -5], [5, 4]),
                        "offset": ([0, 0], [-40, -40])
                    },
                    {
                        "box": Box([35, 35], [45, 44]),
                        "offset": ([40, 40], [0, 0])
                    },
                    {
                        "box": Box([-5, 25], [5, 44]),
                        "offset": ([0, 0], [-40, 0])
                    },
                    {
                        "box": Box([35, 25], [45, 44]),
                        "offset": ([40, 0], [0, 0])
                    },
                    {
                        "box": Box([-5, 35], [5, 44]),
                        "offset": ([0, 0], [-40, 40])
                    },
                    {
                        "box": Box([35, -5], [45, 4]),
                        "offset": ([40, -40], [0, 0])
                    },
                    {
                        "box": Box([25, -5], [45, 4]),
                        "offset": ([0, 0], [0, -40])
                    },
                    {
                        "box": Box([25, 35], [45, 44]),
                        "offset": ([0, 40], [0, 0])
                    },
                ]
            },
        ),
    )
    @unpack
    def test_overlaps(self, refinement_boxes, expected):
        print("GeometryTest.test_overlaps")
        test_id = self._testMethodName.split("_")[-1]
        dim, interp_order, nbr_cells = (2, 1, [20] * 2)
        hierarchy = self.setup_hierarchy(dim,
                                         interp_order,
                                         nbr_cells,
                                         refinement_boxes,
                                         quantities="Bx")

        level_overlaps = hierarchy_overlaps(hierarchy)
        for ilvl, lvl in enumerate(hierarchy.patch_levels):
            if ilvl not in expected:
                continue
            self.assertEqual(len(expected[ilvl]), len(level_overlaps[ilvl]))
            for exp, actual in zip(expected[ilvl], level_overlaps[ilvl]):
                self.assertEqual(actual["box"], exp["box"])
                self.assertTrue((np.asarray(actual["offset"]) == np.asarray(
                    exp["offset"])).all())

        if 1 in level_overlaps:
            fig = hierarchy.plot_2d_patches(
                1, [p.box for p in hierarchy.level(1).patches])
            fig.savefig("hierarchy_2d_lvl_" + str(1) + "_simple_test_" +
                        str(test_id) + ".png")

    @data([
        {
            "box": Box([-5, -5], [6, 25]),
            "offset": ([0, 0], [-20, 0])
        },
        {
            "box": Box([15, -5], [26, 25]),
            "offset": ([20, 0], [0, 0])
        },
        {
            "box": Box([-5, -5], [26, 5]),
            "offset": ([0, 0], [0, -20])
        },
        {
            "box": Box([-5, 15], [26, 25]),
            "offset": ([0, 20], [0, 0])
        },
        {
            "box": Box([-5, -5], [6, 5]),
            "offset": ([0, 0], [-20, -20])
        },
        {
            "box": Box([15, 15], [26, 25]),
            "offset": ([20, 20], [0, 0])
        },
        {
            "box": Box([15, -5], [26, 25]),
            "offset": ([0, 0], [20, 0])
        },
        {
            "box": Box([-5, -5], [6, 25]),
            "offset": ([-20, 0], [0, 0])
        },
        {
            "box": Box([-5, 15], [26, 25]),
            "offset": ([0, 0], [0, 20])
        },
        {
            "box": Box([-5, -5], [26, 5]),
            "offset": ([0, -20], [0, 0])
        },
        {
            "box": Box([15, 15], [26, 25]),
            "offset": ([0, 0], [20, 20])
        },
        {
            "box": Box([-5, -5], [6, 5]),
            "offset": ([-20, -20], [0, 0])
        },
        {
            "box": Box([15, -5], [26, 5]),
            "offset": ([0, 0], [20, -20])
        },
        {
            "box": Box([-5, 15], [6, 25]),
            "offset": ([-20, 20], [0, 0])
        },
        {
            "box": Box([-5, 15], [6, 25]),
            "offset": ([0, 0], [-20, 20])
        },
        {
            "box": Box([15, -5], [26, 5]),
            "offset": ([20, -20], [0, 0])
        },
    ])
    def test_large_patchoverlaps(self, expected):
        print(f"GeometryTest.{self._testMethodName}")
        test_id = self._testMethodName.split("_")[-1]
        dim, interp_order, nbr_cells = (2, 1, [20] * 2)
        hierarchy = self.setup_hierarchy(dim,
                                         interp_order,
                                         nbr_cells, {},
                                         quantities="Bx",
                                         largest_patch_size=20)

        level_overlaps = hierarchy_overlaps(hierarchy)
        ilvl = 0
        lvl = hierarchy.level(ilvl)
        overlap_boxes = []

        self.assertEqual(len(expected), len(level_overlaps[ilvl]))
        for exp, actual in zip(expected, level_overlaps[ilvl]):
            self.assertEqual(actual["box"], exp["box"])
            self.assertTrue((np.asarray(actual["offset"]) == np.asarray(
                exp["offset"])).all())
            overlap_boxes += [actual["box"]]

        fig = hierarchy.plot_2d_patches(
            ilvl,
            collections=[
                {
                    "boxes": overlap_boxes,
                    "facecolor": "yellow",
                },
                {
                    "boxes": [p.box for p in hierarchy.level(ilvl).patches],
                    "facecolor": "grey",
                },
            ],
        )
        fig.savefig(f"hierarchy_2d_lvl_0_large_patch_test_{test_id}.png")

    def test_touch_border(self):
        print("GeometryTest.test_touch_border")
        hierarchy = super().basic_hierarchy()

        domain_box = hierarchy.domain_box
        self.assertFalse(
            touch_domain_border(Box2D(10, 14), domain_box, "upper"))
        self.assertFalse(
            touch_domain_border(Box2D(10, 14), domain_box, "lower"))
        self.assertTrue(touch_domain_border(Box2D(0, 14), domain_box, "lower"))
        self.assertTrue(touch_domain_border(Box2D(-5, 14), domain_box,
                                            "lower"))
        self.assertTrue(touch_domain_border(Box2D(-5, 10), domain_box,
                                            "lower"))
        self.assertTrue(touch_domain_border(Box2D(-5, 30), domain_box,
                                            "upper"))
        self.assertTrue(touch_domain_border(Box2D(10, 30), domain_box,
                                            "upper"))
        self.assertTrue(touch_domain_border(Box2D(10, 24), domain_box,
                                            "upper"))

    def test_particle_ghost_area_boxes(self):
        print("GeometryTest.test_particle_ghost_area_boxes")
        hierarchy = super().basic_hierarchy()

        expected = {
            0: [
                {
                    "boxes": [
                        Box([-1, -1], [-1, 10]),
                        Box([10, -1], [10, 10]),
                        Box([0, -1], [9, -1]),
                        Box([0, 10], [9, 10]),
                    ]
                },
                {
                    "boxes": [
                        Box([9, 9], [9, 20]),
                        Box([20, 9], [20, 20]),
                        Box([10, 9], [19, 9]),
                        Box([10, 20], [19, 20]),
                    ]
                },
                {
                    "boxes": [
                        Box([-1, 9], [-1, 20]),
                        Box([10, 9], [10, 20]),
                        Box([0, 9], [9, 9]),
                        Box([0, 20], [9, 20]),
                    ]
                },
                {
                    "boxes": [
                        Box([9, -1], [9, 10]),
                        Box([20, -1], [20, 10]),
                        Box([10, -1], [19, -1]),
                        Box([10, 10], [19, 10]),
                    ]
                },
            ],
            1: [
                {
                    "boxes": [
                        Box([9, 9], [9, 20]),
                        Box([20, 9], [20, 20]),
                        Box([10, 9], [19, 9]),
                        Box([10, 20], [19, 20]),
                    ]
                },
                {
                    "boxes": [
                        Box([27, 27], [27, 40]),
                        Box([40, 27], [40, 40]),
                        Box([28, 27], [39, 27]),
                        Box([28, 40], [39, 40]),
                    ]
                },
            ],
        }

        gaboxes = ghost_area_boxes(hierarchy, "particles")
        particles = "particles"

        self.assertEqual(len(expected), len(gaboxes))

        for ilvl, lvl in enumerate(hierarchy.patch_levels):
            self.assertEqual(len(gaboxes[ilvl][particles]),
                             len(expected[ilvl]))
            for act_pdata, exp_pdata in zip(gaboxes[ilvl][particles],
                                            expected[ilvl]):
                self.assertEqual(len(exp_pdata["boxes"]),
                                 len(act_pdata["boxes"]))
                for exp_box in exp_pdata["boxes"]:
                    self.assertTrue(exp_box in act_pdata["boxes"])

    def test_particle_level_ghost_boxes_do_not_overlap_patch_interiors(self):
        print(
            "GeometryTest.test_particle_level_ghost_boxes_do_not_overlap_patch_interiors"
        )
        hierarchy = super().basic_hierarchy()

        lvl_gboxes = level_ghost_boxes(hierarchy, "particles")

        assert len(lvl_gboxes) > 0
        for ilvl, pdatainfos in lvl_gboxes.items():
            assert len(pdatainfos) > 0
            for particles_id, gaboxes_list in pdatainfos.items():
                assert len(gaboxes_list) > 0
                for pdatainfo in gaboxes_list:
                    for box in pdatainfo["boxes"]:
                        for patch in hierarchy.patch_levels[ilvl].patches:
                            self.assertIsNone(patch.box * box)
Example #7
0
class ParticleLevelGhostGeometryTest(AGeometryTest):
    @data(
        (  # no patch ghost on level 1
            {
                "L0": [Box2D(5, 9), Box2D(14, 19)]
            },
            {
                1: [
                    Box([9, 9], [9, 20]),
                    Box([20, 9], [20, 20]),
                    Box([10, 9], [19, 9]),
                    Box([10, 20], [19, 20]),
                    Box([27, 27], [27, 40]),
                    Box([40, 27], [40, 40]),
                    Box([28, 27], [39, 27]),
                    Box([28, 40], [39, 40]),
                ]
            },
        ),
        (  # top right of gabox0 overlaps bottom left gabox1
            {
                "L0": [Box2D(5, 9), Box2D(10, 11)]
            },
            {
                1: [
                    Box([9, 9], [9, 20]),
                    Box([20, 9], [20, 19]),
                    Box([10, 9], [19, 9]),
                    Box([10, 20], [19, 20]),
                    Box([19, 20], [19, 24]),
                    Box([24, 19], [24, 24]),
                    Box([20, 19], [23, 19]),
                    Box([20, 24], [23, 24]),
                ]
            },
        ),
        (  # right side of gabox0 overlaps left side of gabox1
            {
                "L0": [Box2D(2, 9), Box([10, 1], [14, 10])]
            },
            {
                1: [
                    Box([3, 3], [3, 20]),
                    Box([4, 3], [19, 3]),
                    Box([4, 20], [19, 20]),
                    Box([19, 1], [19, 3]),
                    Box([19, 20], [19, 22]),
                    Box([30, 1], [30, 22]),
                    Box([20, 1], [29, 1]),
                    Box([20, 22], [29, 22]),
                ]
            },
        ),
        (
            {  # right side of gabox0 overlaps left of gabox1/gabox2
                # left side of gabox3 overlaps right of gabox1/gabox2
                "L0": [
                    Box([0, 0], [4, 19]),
                    Box([10, 0], [14, 19]),
                    Box([5, 2], [9, 6]),
                    Box([5, 12], [9, 16]),
                ]
            },
            {
                1: [
                    Box([-1, -1], [-1, 40]),
                    Box([10, -1], [10, 3]),
                    Box([10, 14], [10, 23]),
                    Box([10, 34], [10, 40]),
                    Box([0, -1], [9, -1]),
                    Box([0, 40], [9, 40]),
                    Box([19, -1], [19, 3]),
                    Box([19, 14], [19, 23]),
                    Box([19, 34], [19, 40]),
                    Box([30, -1], [30, 40]),
                    Box([20, -1], [29, -1]),
                    Box([20, 40], [29, 40]),
                    Box([10, 3], [19, 3]),
                    Box([10, 14], [19, 14]),
                    Box([10, 23], [19, 23]),
                    Box([10, 34], [19, 34]),
                ]
            },
        ),
    )
    @unpack
    def test_level_ghost_boxes(self, refinement_boxes, expected):
        print("ParticleLevelGhostGeometryTest.test_level_ghost_boxes")
        dim, interp_order, nbr_cells = (2, 1, [20] * 2)
        hierarchy = self.setup_hierarchy(dim,
                                         interp_order,
                                         nbr_cells,
                                         refinement_boxes,
                                         quantities="particles")
        lvl_gaboxes = level_ghost_boxes(hierarchy, "particles")

        for ilvl in range(1, len(hierarchy.patch_levels)):
            self.assertEqual(len(lvl_gaboxes[ilvl].keys()), 1)

            key = list(lvl_gaboxes[ilvl].keys())[0]

            ghost_area_box_list = sum(  # aggregate to single list
                [actual["boxes"] for actual in lvl_gaboxes[ilvl][key]], [])

            self.assertEqual(expected[ilvl], ghost_area_box_list)

            fig = hierarchy.plot_2d_patches(
                ilvl,
                collections=[
                    {
                        "boxes": ghost_area_box_list,
                        "facecolor": "yellow",
                    },
                    {
                        "boxes":
                        [p.box for p in hierarchy.level(ilvl).patches],
                        "facecolor": "grey",
                    },
                ],
                title="".join([
                    str(box) + ","
                    for box in refinement_boxes["L" + str(ilvl - 1)]
                ]),
            )
            fig.savefig(
                f"{type(self).__name__}_lvl_{ilvl}_{self._testMethodName}.png")

    @data(
        (
            {
                # no level 1
            },
            {
                0: [
                    Box([0, 0], [9, 9]),
                    Box([0, 10], [9, 19]),
                    Box([10, 0], [19, 9]),
                    Box([10, 10], [19, 19]),
                    Box([20, 0], [29, 9]),
                    Box([0, 20], [9, 29]),
                    Box([20, 20], [29, 29]),
                    Box([-10, 10], [-1, 19]),
                    Box([10, -10], [19, -1]),
                    Box([-10, -10], [-1, -1]),
                    Box([20, 10], [29, 19]),
                    Box([0, -10], [9, -1]),
                    Box([20, -10], [29, -1]),
                    Box([-10, 0], [-1, 9]),
                    Box([10, 20], [19, 29]),
                    Box([-10, 20], [-1, 29]),
                ]
            },
        ),
        (
            {
                "L0": [
                    Box([0, 0], [4, 4]),
                    Box([15, 15], [19, 19]),
                    Box([15, 0], [19, 4]),
                    Box([0, 15], [4, 19]),
                ]
            },
            {
                1: [
                    Box([0, 0], [9, 9]),
                    Box([30, 0], [39, 9]),
                    Box([0, 30], [9, 39]),
                    Box([30, 30], [39, 39]),
                    Box([40, 0], [49, 9]),
                    Box([0, 40], [9, 49]),
                    Box([40, 40], [49, 49]),
                    Box([-10, 30], [-1, 39]),
                    Box([30, -10], [39, -1]),
                    Box([-10, -10], [-1, -1]),
                    Box([-10, 0], [-1, 9]),
                    Box([30, 40], [39, 49]),
                    Box([-10, 40], [-1, 49]),
                    Box([40, 30], [49, 39]),
                    Box([0, -10], [9, -1]),
                    Box([40, -10], [49, -1]),
                ]
            },
        ),
        (
            {
                "L0": [
                    Box([1, 1], [5, 5]),
                    Box([14, 14], [18, 18]),
                    Box([14, 1], [18, 5]),
                    Box([1, 14], [5, 18]),
                ]
            },
            {
                # NO lvl 1 PERIODIC PARTICLE GHOST BOX
            },
        ),
    )
    @unpack
    def test_patch_periodicity_copy(self, refinement_boxes, expected):
        print("ParticleLevelGhostGeometryTest.test_patch_periodicity_copy")
        dim, interp_order, nbr_cells = (2, 1, [20] * 2)
        hierarchy = self.setup_hierarchy(dim,
                                         interp_order,
                                         nbr_cells,
                                         refinement_boxes,
                                         quantities="particles")

        for ilvl, lvl in hierarchy.levels().items():
            domain_box = hierarchy.level_domain_box(ilvl)

            qtyNbr = len(lvl.patches[0].patch_datas.keys())
            self.assertEqual(qtyNbr, 1)
            pop_name = list(lvl.patches[0].patch_datas.keys())[0]
            n_ghosts = lvl.patches[0].patch_datas[pop_name].ghosts_nbr

            periodic_list = get_periodic_list(lvl.patches, domain_box,
                                              n_ghosts)

            box_list = [p.box for p in periodic_list]

            if ilvl in expected:
                self.assertEqual(expected[ilvl], box_list)

            fig = hierarchy.plot_2d_patches(
                ilvl,
                collections=[
                    {
                        "boxes": [p.box for p in periodic_list],
                        "facecolor": "grey",
                    },
                ],
            )
            fig.savefig(
                f"{type(self).__name__}_lvl_{ilvl}_{self._testMethodName}.png")
Example #8
0
 def basic_hierarchy(self):
     dim, interp_order, nbr_cells = (2, 1, [20] * 2)
     refinement_boxes = {"L0": {"B0": Box2D(5, 9), "B1": Box2D(14, 19)}}
     return self.setup_hierarchy(dim, interp_order, nbr_cells,
                                 refinement_boxes)
Example #9
0
class InitializationTest(InitializationTest):
    @data(*interp_orders)
    def test_nbr_particles_per_cell_is_as_provided(self, interp_order):
        print(f"{self._testMethodName}_{ndim}d")
        self._test_nbr_particles_per_cell_is_as_provided(ndim, interp_order)

    @data(
        *per_interp(({
            "L0": {
                "B0": Box2D(10, 14)
            }
        })),
        *per_interp(({
            "L0": {
                "B0": Box2D(10, 14)
            },
            "L1": {
                "B0": Box2D(22, 26)
            }
        })),
        *per_interp(({
            "L0": {
                "B0": Box2D(2, 6),
                "B1": Box2D(7, 11)
            }
        })),
    )
    @unpack
    def test_levelghostparticles_have_correct_split_from_coarser_particle(
            self, interp_order, refinement_boxes):
        print(f"\n{self._testMethodName}_{ndim}d")
        now = self.datetime_now()
        self._test_levelghostparticles_have_correct_split_from_coarser_particle(
            self.getHierarchy(
                interp_order,
                refinement_boxes,
                "particles",
                ndim=ndim,
                cells=30,
                nbr_part_per_cell=ppc,
                diag_outputs=
                f"phare_outputs/test_levelghost/{ndim}/{interp_order}/{self.ddt_test_id()}",
            ))
        print(
            f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds"
        )

    @data(
        *per_interp(({
            "L0": {
                "B0": Box2D(10, 14)
            }
        })),
        *per_interp(({
            "L0": {
                "B0": Box2D(5, 20)
            },
            "L1": {
                "B0": Box2D(15, 35)
            }
        })),
        *per_interp(({
            "L0": {
                "B0": Box2D(2, 12),
                "B1": Box2D(13, 25)
            }
        })),
    )
    @unpack
    def test_domainparticles_have_correct_split_from_coarser_particle(
            self, interp_order, refinement_boxes):
        print(f"\n{self._testMethodName}_{ndim}d")
        now = self.datetime_now()
        self._test_domainparticles_have_correct_split_from_coarser_particle(
            ndim, interp_order, refinement_boxes, nbr_part_per_cell=ppc)
        print(
            f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds"
        )

    @data({
        "cells": 40,
        "smallest_patch_size": 20,
        "largest_patch_size": 20,
        "nbr_part_per_cell": ppc
    })
    def test_no_patch_ghost_on_refined_level_case(self, simInput):
        print(f"\n{self._testMethodName}_{ndim}d")
        now = self.datetime_now()
        self._test_patch_ghost_on_refined_level_case(ndim, False, **simInput)
        print(
            f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds"
        )

    @data({"cells": 40, "interp_order": 1, "nbr_part_per_cell": ppc})
    def test_has_patch_ghost_on_refined_level_case(self, simInput):
        print(f"\n{self._testMethodName}_{ndim}d")
        from pyphare.pharein.simulation import check_patch_size
        diag_outputs = f"phare_overlaped_fields_are_equal_with_min_max_patch_size_of_max_ghosts_{ndim}_{self.ddt_test_id()}"
        _, smallest_patch_size = check_patch_size(ndim, **simInput)
        simInput["smallest_patch_size"] = smallest_patch_size
        simInput["largest_patch_size"] = smallest_patch_size
        now = self.datetime_now()
        self._test_patch_ghost_on_refined_level_case(ndim, True, **simInput)
        print(
            f"\n{self._testMethodName}_{ndim}d took {self.datetime_diff(now)} seconds"
        )