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")
Exemple #2
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")
Exemple #3
0
    def test_overlaps(self):
        hierarchy = self.basic_hierarchy()

        expected = {0 :
                        # Middle overlap, for all quantities
                        [  {"box":Box(28, 38),'offset':(0,0)},

                        {"box": Box(28, 37),"offset":(0,0)},
                        {"box": Box(28, 37),"offset":(0,0)},
                        {"box": Box(28, 37),'offset': (0,0)},
                        {"box": Box(28, 38),"offset":(0,0)},
                        {"box": Box(28, 38),"offset":(0,0)},
                        {"box": Box(32,33),"offset":(0,0)},

                        # left side overlap with periodicity, for all quantities
                          {"box": Box(-5, 5),"offset":(0,-65)},
                        # right side overlap with periodicity, for all quantities
                        {"box": Box(60, 70),"offset": (65,0)},
                        {"box": Box(-5, 4),"offset":(0,-65)},
                        {"box": Box(60, 69),"offset": (65,0 )},
                        {"box": Box(-5, 4),"offset":(0,-65)},
                        {"box": Box(60, 69),"offset": (65,0)},
                        {"box": Box(-5, 4),"offset":(0,-65)},
                        {"box": Box(60, 69),"offset":(65, 0)},
                        {"box": Box(-5, 5),"offset":(0,-65)},
                        {"box": Box(60, 70),"offset":(65, 0)},
                        {"box": Box(-5, 5),"offset":(0,-65)},
                        {"box": Box(60, 70),"offset":(65, 0)},
                        {"box": Box(-1,0),"offset":(0,-65)},
                        {"box": Box(64, 65),"offset":(65 ,0)}
                    ],

            1:  # level 1
                [
                    {"box": Box(59, 65),'offset': (0, 0)},
                    {"box": Box(59, 64),"offset": (0, 0)},
                    {"box": Box(59, 64),"offset": (0, 0)},
                    {"box": Box(59, 64),'offset': (0, 0)},
                    {"box": Box(59, 65),"offset": (0, 0)},
                    {"box": Box(59, 65),"offset": (0, 0)}
                ]


        }

        overlaps = hierarchy_overlaps(hierarchy)

        for ilvl, lvl in enumerate(hierarchy.patch_levels):
            self.assertEqual(len(expected[ilvl]), len(overlaps[ilvl]))

            for exp, actual in zip(expected[ilvl], overlaps[ilvl]):

                act_box = actual["box"]
                act_offset = actual["offset"]
                exp_box = exp["box"]
                exp_offset = exp["offset"]

                self.assertEqual(act_box, exp_box)
                self.assertEqual(act_offset, exp_offset)
Exemple #4
0
    def _test_overlapped_particledatas_have_identical_particles(self, dim, interp_order, refinement_boxes):
        print("test_overlapped_particledatas_have_identical_particles")
        print("interporder : {}".format(interp_order))
        from copy import copy

        time_step_nbr=3
        time_step=0.001
        diag_outputs=f"phare_overlapped_particledatas_have_identical_particles_{self.ddt_test_id()}"
        datahier = self.getHierarchy(interp_order, refinement_boxes, "particles", diag_outputs=diag_outputs,
                                      time_step=time_step, time_step_nbr=time_step_nbr)

        for time_step_idx in range(time_step_nbr + 1):
            coarsest_time =  time_step_idx * time_step

            overlaps = hierarchy_overlaps(datahier, coarsest_time)

            for ilvl, lvl in datahier.patch_levels.items():

                print("testing level {}".format(ilvl))
                for overlap in overlaps[ilvl]:

                    pd1, pd2 = overlap["pdatas"]
                    box      = overlap["box"]
                    offsets  = overlap["offset"]

                    self.assertEqual(pd1.quantity, pd2.quantity)

                    if "particles" in pd1.quantity:

                        # the following uses 'offset', we need to remember that offset
                        # is the quantity by which a patch has been moved to detect
                        # overlap with the other one.
                        # so shift by +offset when evaluating patch data in overlap box
                        # index space, and by -offset when we want to shift box indexes
                        # to the associated patch index space.

                        # overlap box must be shifted by -offset to select data in the patches
                        part1 = copy(pd1.dataset.select(boxm.shift(box, -offsets[0])))
                        part2 = copy(pd2.dataset.select(boxm.shift(box, -offsets[1])))

                        idx1 = np.argsort(part1.iCells + part1.deltas)
                        idx2 = np.argsort(part2.iCells + part2.deltas)

                        # if there is an overlap, there should be particles
                        # in these cells
                        assert(len(idx1) >0)
                        assert(len(idx2) >0)

                        print("respectively {} and {} in overlaped patchdatas".format(len(idx1), len(idx2)))

                        # particle iCells are in their patch AMR space
                        # so we need to shift them by +offset to move them to the box space
                        np.testing.assert_array_equal(part1.iCells[idx1]+offsets[0], part2.iCells[idx2]+offsets[1])

                        self.assertTrue(np.allclose(part1.deltas[idx1], part2.deltas[idx2], atol=1e-12))
                        self.assertTrue(np.allclose(part1.v[idx1,0], part2.v[idx2,0], atol=1e-12))
                        self.assertTrue(np.allclose(part1.v[idx1,1], part2.v[idx2,1], atol=1e-12))
                        self.assertTrue(np.allclose(part1.v[idx1,2], part2.v[idx2,2], atol=1e-12))
Exemple #5
0
    def _test_overlapped_particledatas_have_identical_particles(
            self, ndim, interp_order, refinement_boxes, ppc=100, **kwargs):
        print(
            "test_overlapped_particledatas_have_identical_particles, interporder : {}"
            .format(interp_order))
        from copy import copy

        time_step_nbr = 3
        time_step = 0.001
        diag_outputs = f"phare_overlapped_particledatas_have_identical_particles/{ndim}/{interp_order}/{self.ddt_test_id()}"
        datahier = self.getHierarchy(interp_order,
                                     refinement_boxes,
                                     "particles",
                                     diag_outputs=diag_outputs,
                                     ndim=ndim,
                                     time_step=time_step,
                                     time_step_nbr=time_step_nbr,
                                     nbr_part_per_cell=ppc,
                                     **kwargs)

        for time_step_idx in range(time_step_nbr + 1):
            coarsest_time = time_step_idx * time_step

            overlaps = hierarchy_overlaps(datahier, coarsest_time)

            for ilvl, lvl in datahier.patch_levels.items():

                print("testing level {}".format(ilvl))
                for overlap in overlaps[ilvl]:
                    pd1, pd2 = overlap["pdatas"]
                    box = overlap["box"]
                    offsets = overlap["offset"]

                    self.assertEqual(pd1.quantity, pd2.quantity)

                    if "particles" in pd1.quantity:

                        # the following uses 'offset', we need to remember that offset
                        # is the quantity by which a patch has been moved to detect
                        # overlap with the other one.
                        # so shift by +offset when evaluating patch data in overlap box
                        # index space, and by -offset when we want to shift box indexes
                        # to the associated patch index space.

                        # overlap box must be shifted by -offset to select data in the patches
                        part1 = copy(
                            pd1.dataset.select(
                                boxm.shift(box, -np.asarray(offsets[0]))))
                        part2 = copy(
                            pd2.dataset.select(
                                boxm.shift(box, -np.asarray(offsets[1]))))

                        # periodic icell overlaps need shifting to be the same
                        part1.iCells = part1.iCells + offsets[0]
                        part2.iCells = part2.iCells + offsets[1]
                        self.assertEqual(part1, part2)
Exemple #6
0
    def base_test_overlaped_fields_are_equal(self, datahier, coarsest_time):
        checks = 0
        for ilvl, overlaps in hierarchy_overlaps(datahier,
                                                 coarsest_time).items():
            for overlap in overlaps:
                pd1, pd2 = overlap["pdatas"]
                box = overlap["box"]
                offsets = overlap["offset"]

                self.assertEqual(pd1.quantity, pd2.quantity)

                if pd1.quantity == 'field':

                    # we need to transform the AMR overlap box, which is thus
                    # (because AMR) common to both pd1 and pd2 into local index
                    # boxes that will allow to slice the data

                    # the patchData ghost box that serves as a reference box
                    # to transfrom AMR to local indexes first needs to be
                    # shifted by the overlap offset associated to it
                    # this is because the overlap box has been calculated from
                    # the intersection of possibly shifted patch data ghost boxes

                    loc_b1 = boxm.amr_to_local(
                        box, boxm.shift(pd1.ghost_box, offsets[0]))
                    loc_b2 = boxm.amr_to_local(
                        box, boxm.shift(pd2.ghost_box, offsets[1]))

                    data1 = pd1.dataset
                    data2 = pd2.dataset

                    if box.ndim == 1:
                        slice1 = data1[loc_b1.lower[0]:loc_b1.upper[0] + 1]
                        slice2 = data2[loc_b2.lower[0]:loc_b2.upper[0] + 1]

                    if box.ndim == 2:
                        slice1 = data1[loc_b1.lower[0]:loc_b1.upper[0] + 1,
                                       loc_b1.lower[1]:loc_b1.upper[1] + 1]
                        slice2 = data2[loc_b2.lower[0]:loc_b2.upper[0] + 1,
                                       loc_b2.lower[1]:loc_b2.upper[1] + 1]

                    try:
                        assert slice1.dtype == np.float64
                        np.testing.assert_equal(slice1, slice2)
                        checks += 1
                    except AssertionError as e:
                        print("AssertionError", pd1.name, e)
                        if self.rethrow_:
                            raise e
                        return diff_boxes(slice1, slice2, box)

        return checks
Exemple #7
0
    def test_periodic_overlaps(self, refinement_boxes, expected):
        dim, interp_order, nbr_cells = (1, 1, 20)
        hierarchy = self.setup_hierarchy(
            dim, interp_order, nbr_cells, refinement_boxes, quantities="Bx"
        )

        overlaps = hierarchy_overlaps(hierarchy)
        for ilvl, lvl in enumerate(hierarchy.patch_levels):
            if ilvl not in expected:
                continue
            self.assertEqual(len(expected[ilvl]), len(overlaps[ilvl]))
            for exp, actual in zip(expected[ilvl], overlaps[ilvl]):
                self.assertEqual(actual["box"], exp["box"])
                self.assertEqual(actual["offset"], exp["offset"])
Exemple #8
0
    def _test_overlaped_fields_are_equal(self, time_step, time_step_nbr, datahier):
        check=0
        for time_step_idx in range(time_step_nbr + 1):
            coarsest_time =  time_step_idx * time_step

            for ilvl, overlaps in hierarchy_overlaps(datahier, coarsest_time).items():

                for overlap in overlaps:

                    pd1, pd2 = overlap["pdatas"]
                    box      = overlap["box"]
                    offsets  = overlap["offset"]

                    self.assertEqual(pd1.quantity, pd2.quantity)

                    if pd1.quantity == 'field':
                        check+=1

                        # we need to transform the AMR overlap box, which is thus
                        # (because AMR) common to both pd1 and pd2 into local index
                        # boxes that will allow to slice the data

                        # the patchData ghost box that serves as a reference box
                        # to transfrom AMR to local indexes first needs to be
                        # shifted by the overlap offset associated to it
                        # this is because the overlap box has been calculated from
                        # the intersection of possibly shifted patch data ghost boxes

                        loc_b1 = boxm.amr_to_local(box, boxm.shift(pd1.ghost_box, offsets[0]))
                        loc_b2 = boxm.amr_to_local(box, boxm.shift(pd2.ghost_box, offsets[1]))

                        data1 = pd1.dataset
                        data2 = pd2.dataset

                        slice1 = data1[loc_b1.lower[0]:loc_b1.upper[0] + 1]
                        slice2 = data2[loc_b2.lower[0]:loc_b2.upper[0] + 1]

                        try:
                            np.testing.assert_allclose(slice1, slice2, atol=1e-6)
                        except AssertionError as e:
                            print("error", coarsest_time, overlap)
                            raise e

        self.assertGreater(check, time_step_nbr)
        self.assertEqual(check % time_step_nbr, 0)
Exemple #9
0
    def test_overlaped_fields_are_equal(self, interp_order, refinement_boxes):
        print("test_overlaped_fields_are_equal")
        hier = self.getHierarchy(interp_order, refinement_boxes, "b")

        overlaps = hierarchy_overlaps(hier)
        check = 0
        for ilvl, lvl in hier.levels().items():

            for overlap in overlaps[ilvl]:
                pd1, pd2 = overlap["pdatas"]
                box = overlap["box"]
                offsets = overlap["offset"]

                self.assertEqual(pd1.quantity, pd2.quantity)

                if pd1.quantity == 'field':
                    check += 1

                    # we need to transform the AMR overlap box, which is thus
                    # (because AMR) common to both pd1 and pd2 into local index
                    # boxes that will allow to slice the data

                    # the patchData ghost box that serves as a reference box
                    # to transfrom AMR to local indexes first needs to be
                    # shifted by the overlap offset associated to it
                    # this is because the overlap box has been calculated from
                    # the intersection of possibly shifted patch data ghost boxes

                    loc_b1 = boxm.amr_to_local(
                        box, boxm.shift(pd1.ghost_box, offsets[0]))
                    loc_b2 = boxm.amr_to_local(
                        box, boxm.shift(pd2.ghost_box, offsets[1]))

                    data1 = pd1.dataset
                    data2 = pd2.dataset

                    slice1 = data1[loc_b1.lower[0]:loc_b1.upper[0] + 1]
                    slice2 = data2[loc_b2.lower[0]:loc_b2.upper[0] + 1]

                    self.assertTrue(np.allclose(slice1, slice2, atol=1e-12))

        self.assertTrue(check > 0)
Exemple #10
0
    def test_patch_ghost_particle_are_clone_of_overlaped_patch_domain_particles(
            self, interp_order, refinement_boxes):
        datahier = self.getHierarchy(interp_order, refinement_boxes,
                                     "particles")
        print(
            "test_patch_ghost_particle_are_clone_of_overlaped_patch_domain_particles"
        )
        print("interporder : {}".format(interp_order))
        overlaps = hierarchy_overlaps(datahier)
        for ilvl, lvl_overlaps in overlaps.items():
            print("level {}".format(ilvl))
            for overlap in lvl_overlaps:

                if ilvl != 0:  #only root level tested here
                    continue

                if "particles" not in overlap["pdatas"][0].quantity:
                    continue

                ref_pd, cmp_pd = overlap["pdatas"]

                box = overlap["box"]
                print(
                    "overlap box : {}, reference patchdata box : {}, ghostbox {},"
                    " comp. patchdata box : {} ghostbox {}".format(
                        box, ref_pd.box, ref_pd.ghost_box, cmp_pd.box,
                        cmp_pd.ghost_box))
                offsets = overlap["offset"]

                # first let's shift the overlap box over the AMR
                # indices of the patchdata. The box has been created
                # by shifting the patchdata ghost box by 'offset' so here
                # the box is shifted by -offset to get over patchdata
                shift_refbox, shift_cmpbox = [
                    boxm.shift(box, -off) for off in offsets
                ]

                # the overlap box overlaps both ghost and domain cells
                # we need to extract the domain ones to later select domain
                # particles
                ovlped_refdom = ref_pd.box * shift_refbox
                ovlped_cmpdom = cmp_pd.box * shift_cmpbox

                # on lvl 0 patches are adjacent
                # therefore the overlap box must overlap the
                # patchData box. 1 cell in interporder1, 2 cells for higher
                assert (ovlped_cmpdom is not None)
                assert (ovlped_refdom is not None)

                refdomain = ref_pd.dataset.select(ovlped_refdom)
                cmpdomain = cmp_pd.dataset.select(ovlped_cmpdom)

                # now get the ghost cells of each patch data overlaped by
                # the overlap box. To do this we need to intersect the shifted
                # overlap box with the patchdata ghost box, and remove interior cells
                # note that in 1D we don't expect remove to return more than 1 box, hence [0]
                ovlped_refghost = boxm.remove(ref_pd.ghost_box * shift_refbox,
                                              ref_pd.box)[0]
                ovlped_cmpghost = boxm.remove(cmp_pd.ghost_box * shift_cmpbox,
                                              cmp_pd.box)[0]

                refghost = ref_pd.dataset.select(ovlped_refghost)
                cmpghost = cmp_pd.dataset.select(ovlped_cmpghost)

                print("ghost box {} has {} particles".format(
                    ovlped_refghost, len(refghost.iCells)))
                print("ghost box {} has {} particles".format(
                    ovlped_cmpghost, len(cmpghost.iCells)))

                # before comparing the particles we need to be sure particles of both patchdatas
                # are sorted in the same order. We do that by sorting by x position
                sort_refdomain_idx = np.argsort(refdomain.iCells +
                                                refdomain.deltas)
                sort_cmpdomain_idx = np.argsort(cmpdomain.iCells +
                                                cmpdomain.deltas)
                sort_refghost_idx = np.argsort(refghost.iCells +
                                               refghost.deltas)
                sort_cmpghost_idx = np.argsort(cmpghost.iCells +
                                               cmpghost.deltas)

                assert (sort_refdomain_idx.size != 0)
                assert (sort_cmpdomain_idx.size != 0)
                assert (sort_refdomain_idx.size != 0)
                assert (sort_cmpghost_idx.size != 0)

                np.testing.assert_allclose(
                    refdomain.deltas[sort_refdomain_idx],
                    cmpghost.deltas[sort_cmpghost_idx],
                    atol=1e-12)
                np.testing.assert_allclose(
                    cmpdomain.deltas[sort_cmpdomain_idx],
                    refghost.deltas[sort_refghost_idx],
                    atol=1e-12)