Beispiel #1
0
 def __init__(self, filename, interpolation_method):
     self.mesh = MeshManager(filename, dim=3)
     self.mesh.set_boundary_condition(
         "Dirichlet", {101: 0.0}, dim_target=2, set_nodes=True
     )
     self.mesh.set_global_id()
     self.mesh.get_redefine_centre()
     self.mpfad = MpfaD3D(self.mesh)
     self.im = interpolation_method(self.mesh)
Beispiel #2
0
 def setUp(self):
     self.mesh = MeshManager("meshes/mesh_test_conservative.msh", dim=3)
     sw = 0.2
     so_i = 0.9
     self.mesh.set_media_property("Water_Sat_i", {1: sw}, dim_target=3)
     self.mesh.set_media_property("Oil_Sat_i", {1: so_i}, dim_target=3)
     self.mesh.set_media_property("Water_Sat", {1: sw}, dim_target=3)
     self.mesh.set_boundary_condition(
         "SW_BC", {102: 1.0}, dim_target=2, set_nodes=True
     )
Beispiel #3
0
    def __init__(self, filename):
        self.mesh = MeshManager(filename, dim=3)
        self.mesh.set_boundary_condition("Dirichlet", {101: None},
                                         dim_target=2,
                                         set_nodes=True)
        self.mesh.set_boundary_condition("Neumann", {201: 0.0},
                                         dim_target=2,
                                         set_nodes=True)

        bed_perm = [
            0.965384615384615,
            0.173076923076923,
            0.0,
            0.173076923076923,
            0.134615384615385,
            0.0,
            0.0,
            0.0,
            1.0,
        ]
        drain_perm = [
            96.538461538461530,
            17.307692307692307,
            0.0,
            17.307692307692307,
            13.461538461538462,
            0.0,
            0.0,
            0.0,
            1.0,
        ]
        self.mesh.set_media_property(
            "Permeability",
            {
                1: bed_perm,
                2: drain_perm,
                3: bed_perm
            },
            dim_target=3,
        )
        self.mesh.set_global_id()
        self.mesh.get_redefine_centre()
        self.mpfad = MpfaD3D(self.mesh)
    def setUp(self):

        K_1 = np.array([1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0])
        K_2 = np.array([2.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 2.0])

        self.mesh_1 = MeshManager("meshes/mesh_test_1.msh")

        self.mesh_2 = MeshManager("meshes/mesh_test_2.msh", dim=3)
        self.mesh_2.set_media_property("Permeability", {1: K_1}, dim_target=3)
        self.mesh_2.set_boundary_condition(
            "Dirichlet", {102: 1.0, 101: 0.0}, dim_target=2, set_nodes=True
        )
        self.mesh_2.set_boundary_condition(
            "Neumann", {201: 0.0}, dim_target=2, set_nodes=True
        )
        self.mesh_2.set_global_id()
        self.mesh_2.get_redefine_centre()
        self.mpfad_2 = MpfaD3D(self.mesh_2)

        self.mesh_3 = MeshManager(
            "meshes/geometry_two_regions_test.msh", dim=3
        )
        self.mesh_3.set_media_property(
            "Permeability", {1: K_1, 2: K_2}, dim_target=3
        )
        self.mesh_3.set_boundary_condition(
            "Dirichlet", {102: 1.0, 101: 0.0}, dim_target=2, set_nodes=True
        )
        self.mesh_3.set_boundary_condition(
            "Neumann", {201: 0.0}, dim_target=2, set_nodes=True
        )
        self.mesh_3.get_redefine_centre()
        self.mpfad_3 = MpfaD3D(self.mesh_3)

        self.mesh_4 = MeshManager("meshes/mesh_darlan.msh")
        self.mesh_4.set_global_id()
        self.mesh_4.get_redefine_centre()
Beispiel #5
0
class TestFoumTags(unittest.TestCase):
    def setUp(self):
        self.mesh = MeshManager("meshes/mesh_test_conservative.msh", dim=3)
        sw = 0.2
        so_i = 0.9
        self.mesh.set_media_property("Water_Sat_i", {1: sw}, dim_target=3)
        self.mesh.set_media_property("Oil_Sat_i", {1: so_i}, dim_target=3)
        self.mesh.set_media_property("Water_Sat", {1: sw}, dim_target=3)
        self.mesh.set_boundary_condition("SW_BC", {102: 1.0},
                                         dim_target=2,
                                         set_nodes=True)
        self.foum = Foum(self.mesh, 1.0, 0.9, 1.0, 1.3, 0.5)

    def test_foum_is_instanciated(self):
        """Test that foum is initiated successfuly."""
        self.assertIsNotNone(self.foum)

    def test_mount_mobility(self):
        self.foum.init()
        for face in self.mesh.all_faces:
            face_mobility = self.mesh.mb.tag_get_data(
                self.mesh.face_mobility_tag, face)
            self.assertTrue(face_mobility)
Beispiel #6
0
class TestMeshManagerFoum(unittest.TestCase):
    """Test integration of mesh manager with the two phase solver."""

    def setUp(self):
        self.mesh = MeshManager("meshes/mesh_test_conservative.msh", dim=3)
        sw = 0.2
        so_i = 0.9
        self.mesh.set_media_property("Water_Sat_i", {1: sw}, dim_target=3)
        self.mesh.set_media_property("Oil_Sat_i", {1: so_i}, dim_target=3)
        self.mesh.set_media_property("Water_Sat", {1: sw}, dim_target=3)
        self.mesh.set_boundary_condition(
            "SW_BC", {102: 1.0}, dim_target=2, set_nodes=True
        )

    def test_reading_mesh_return_moab_mesh_instance(self):
        """Test that MeshManager return a moab object containing the mesh."""
        volumes = self.mesh.all_volumes

        self.assertTrue(self.mesh)
        self.assertEqual(len(volumes), 96)

    def test_water_saturation_initial_cond(self):
        """Test setting water saturation Initial Cond at the volumes"""
        water_saturation_tag = self.mesh.water_sat_tag
        volumes = self.mesh.all_volumes
        for volume in volumes:
            water_saturation = self.mesh.mb.tag_get_data(
                water_saturation_tag, volume
            )[0]
            self.assertEqual(water_saturation, 0.2)

    def test_add_water_saturation_BC(self):
        """Test that boundary conditions to the saturation problem is set."""
        water_saturation_bc_tag = self.mesh.water_sat_bc_tag
        for face in self.mesh.sat_BC_faces:
            sw = self.mesh.mb.tag_get_data(water_saturation_bc_tag, face)[0]
            self.assertEqual(sw, 1.0)
Beispiel #7
0
class BenchmarkFVCA:
    def __init__(self, filename, interpolation_method):
        self.mesh = MeshManager(filename, dim=3)
        self.mesh.set_boundary_condition(
            "Dirichlet", {101: 0.0}, dim_target=2, set_nodes=True
        )
        self.mesh.set_global_id()
        self.mesh.get_redefine_centre()
        self.mpfad = MpfaD3D(self.mesh)
        self.im = interpolation_method(self.mesh)

    def get_velocity(self, bmk):
        self.node_pressure_tag = self.mpfad.mb.tag_get_handle(
            "Node Pressure", 1, types.MB_TYPE_DOUBLE, types.MB_TAG_SPARSE, True
        )
        p_verts = []
        for node in self.mesh.all_nodes:
            try:
                p_vert = self.mpfad.mb.tag_get_data(
                    self.mpfad.dirichlet_tag, node
                )
                p_verts.append(p_vert[0])
            except Exception:
                p_vert = 0.0
                p_tag = self.mpfad.pressure_tag
                nd_weights = self.mpfad.nodes_ws[node]
                for volume, wt in nd_weights.items():
                    p_vol = self.mpfad.mb.tag_get_data(p_tag, volume)
                    p_vert += p_vol * wt
                p_verts.append(p_vert[0])
        self.mpfad.mb.tag_set_data(
            self.node_pressure_tag, self.mesh.all_nodes, p_verts
        )
        err = []
        err_grad = []
        grads_p = []
        all_vels = []
        areas = []
        vols = []
        for a_volume in self.mesh.all_volumes:
            vol_faces = self.mesh.mtu.get_bridge_adjacencies(a_volume, 2, 2)
            vol_nodes = self.mesh.mtu.get_bridge_adjacencies(a_volume, 0, 0)
            vol_crds = self.mesh.mb.get_coords(vol_nodes)
            vol_crds = np.reshape(vol_crds, ([4, 3]))
            vol_volume = self.mesh.get_tetra_volume(vol_crds)
            vols.append(vol_volume)
            I, J, K = self.mesh.mtu.get_bridge_adjacencies(vol_faces[0], 2, 0)
            L = list(
                set(vol_nodes).difference(
                    set(
                        self.mesh.mtu.get_bridge_adjacencies(
                            vol_faces[0], 2, 0
                        )
                    )
                )
            )
            JI = self.mesh.mb.get_coords([I]) - self.mesh.mb.get_coords([J])
            JK = self.mesh.mb.get_coords([K]) - self.mesh.mb.get_coords([J])
            LJ = self.mesh.mb.get_coords([J]) - self.mesh.mb.get_coords(L)
            N_IJK = np.cross(JI, JK) / 2.0

            test = np.dot(LJ, N_IJK)
            if test < 0.0:
                I, K = K, I
                JI = self.mesh.mb.get_coords([I]) - self.mesh.mb.get_coords(
                    [J]
                )
                JK = self.mesh.mb.get_coords([K]) - self.mesh.mb.get_coords(
                    [J]
                )
                N_IJK = np.cross(JI, JK) / 2.0

            tan_JI = np.cross(N_IJK, JI)
            tan_JK = np.cross(N_IJK, JK)
            face_area = np.sqrt(np.dot(N_IJK, N_IJK))

            h_L = geo.get_height(N_IJK, LJ)

            p_I = self.mpfad.mb.tag_get_data(self.node_pressure_tag, I)
            p_J = self.mpfad.mb.tag_get_data(self.node_pressure_tag, J)
            p_K = self.mpfad.mb.tag_get_data(self.node_pressure_tag, K)
            p_L = self.mpfad.mb.tag_get_data(self.node_pressure_tag, L)
            grad_normal = -2 * (p_J - p_L) * N_IJK

            grad_cross_I = (p_J - p_I) * (
                (np.dot(tan_JK, LJ) / face_area ** 2) * N_IJK
                - (h_L / (face_area)) * tan_JK
            )
            grad_cross_K = (p_K - p_J) * (
                (np.dot(tan_JI, LJ) / face_area ** 2) * N_IJK
                - (h_L / (face_area)) * tan_JI
            )

            grad_p = -(1 / (6 * vol_volume)) * (
                grad_normal + grad_cross_I + grad_cross_K
            )
            vol_centroid = np.asarray(
                self.mesh.mb.tag_get_data(
                    self.mesh.volume_centre_tag, a_volume
                )[0]
            )
            vol_perm = self.mesh.mb.tag_get_data(
                self.mesh.perm_tag, a_volume
            ).reshape([3, 3])
            x, y, z = vol_centroid
            grad_p_bar = self.calculate_gradient(x, y, z, bmk)
            grads_p.append(np.dot(grad_p_bar, grad_p_bar))
            # print(grad_p, grad_p_bar, grad_p - grad_p_bar)
            e = grad_p[0] - grad_p_bar
            err_norm = np.sqrt(np.dot(e, e))
            # print(err_norm)
            err_grad.append(err_norm ** 2)

            for face in vol_faces:
                # x, y, z = self.mesh.mb.get_coords([face])
                face_nodes = self.mesh.mtu.get_bridge_adjacencies(face, 2, 0)
                face_nodes_crds = self.mesh.mb.get_coords(face_nodes)
                area_vect = geo._area_vector(
                    face_nodes_crds.reshape([3, 3]), vol_centroid
                )[0]
                unit_area_vec = area_vect / np.sqrt(
                    np.dot(area_vect, area_vect)
                )
                k_grad_p = np.dot(vol_perm, grad_p[0])
                vel = -np.dot(k_grad_p, unit_area_vec)
                calc_vel = -np.dot(
                    self.calculate_K_gradient(x, y, z, bmk), unit_area_vec
                )
                err.append(abs(vel - calc_vel) ** 2)
                areas.append(np.sqrt(np.dot(area_vect, area_vect)))
                all_vels.append(calc_vel ** 2)
        norm_vel = np.sqrt(np.dot(err, areas) / np.dot(all_vels, areas))
        norm_grad = np.sqrt(np.dot(err_grad, vols) / np.dot(grads_p, vols))
        return norm_vel, norm_grad

    def norms_calculator(self, error_vector, volumes_vector, u_vector):
        error_vector = np.array(error_vector)
        volumes_vector = np.array(volumes_vector)
        u_vector = np.array(u_vector)
        l2_norm = np.dot(error_vector, error_vector) ** (1 / 2)
        l2_volume_norm = np.dot(error_vector ** 2, volumes_vector) ** (1 / 2)
        erl2 = (
            np.dot(error_vector ** 2, volumes_vector)
            / np.dot(u_vector ** 2, volumes_vector)
        ) ** (1 / 2)
        avr_error = l2_norm / len(volumes_vector)
        max_error = max(error_vector)
        min_error = min(error_vector)
        results = [
            l2_norm,
            l2_volume_norm,
            erl2,
            avr_error,
            max_error,
            min_error,
        ]
        return results

    def calculate_gradient(self, x, y, z, benchmark, delta=0.00001):
        grad_x = (
            benchmark(x + delta, y, z)[1] - benchmark(x, y, z)[1]
        ) / delta
        grad_y = (
            benchmark(x, y + delta, z)[1] - benchmark(x, y, z)[1]
        ) / delta
        grad_z = (
            benchmark(x, y, z + delta)[1] - benchmark(x, y, z)[1]
        ) / delta
        grad = np.array([grad_x, grad_y, grad_z])
        return grad

    def calculate_K_gradient(self, x, y, z, benchmark):
        perm = np.array(benchmark(x, y, z)[0]).reshape([3, 3])
        grad = self.calculate_gradient(x, y, z, benchmark)
        return np.dot(perm, grad)

    def calculate_divergent(self, x, y, z, benchmark, delta=0.00001):
        k_grad_x = (
            self.calculate_K_gradient(x + delta, y, z, benchmark)[0]
            - self.calculate_K_gradient(x, y, z, benchmark)[0]
        ) / delta
        k_grad_y = (
            self.calculate_K_gradient(x, y + delta, z, benchmark)[1]
            - self.calculate_K_gradient(x, y, z, benchmark)[1]
        ) / delta
        k_grad_z = (
            self.calculate_K_gradient(x, y, z + delta, benchmark)[2]
            - self.calculate_K_gradient(x, y, z, benchmark)[2]
        ) / delta
        return -np.sum(k_grad_x + k_grad_y + k_grad_z)

    def _benchmark_1(self, x, y, z):
        K = [1.0, 0.5, 0.0, 0.5, 1.0, 0.5, 0.0, 0.5, 1.0]
        u1 = 1 + np.sin(pi * x) * np.sin(pi * (y + 1 / 2.0)) * np.sin(
            pi * (z + 1 / 3.0)
        )
        source = pi ** 2 * (
            3.0 * np.sin(pi * x) * np.sin(pi * (z + 1 / 3.0)) * np.cos(pi * y)
            + np.sin(pi * y) * np.sin(pi * (x + z + 1 / 3.0))
        )

        return K, u1, source

    def _benchmark_2(self, x, y, z):
        k_xx = y ** 2 + z ** 2 + 1
        k_xy = -x * y
        k_xz = -x * z
        k_yx = -x * y
        k_yy = x ** 2 + z ** 2 + 1
        k_yz = -y * z
        k_zx = -x * z
        k_zy = -y * z
        k_zz = x ** 2 + y ** 2 + 1

        K = [k_xx, k_xy, k_xz, k_yx, k_yy, k_yz, k_zx, k_zy, k_zz]
        u2 = (x ** 3 * y ** 2 * z) + x * np.sin(2 * pi * x * z) * np.sin(
            2 * pi * x * y
        ) * np.sin(2 * pi * z)

        return K, u2

    def _bmk_5(self, x, y, z, alpha):
        """Return the Benchmark test case 5 analytical solution."""
        u5 = (
            alpha
            * np.sin(2 * pi * x)
            * np.sin(2 * pi * y)
            * np.sin(2 * pi * z)
        )
        return u5

    def _benchmark_3(self, x, y, z):
        K = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1000.0]
        u3 = np.sin(2 * pi * x) * np.sin(2 * pi * y) * np.sin(2 * pi * z)
        return K, u3

    def _benchmark_5(self, elems_in_set, material_set):
        # def set_props(self):
        #     # 1  2  3  4
        table = np.array(
            [
                [1.00, 1.00, 1.00, 1.00],  # ax^i
                [10.0, 0.10, 0.01, 100.0],  # ay^i
                [0.01, 100.0, 10.0, 0.100],
            ]  # az^i
        )
        count = material_set - 1
        k_xx = table[0][count]
        k_yy = table[1][count]
        k_zz = table[2][count]
        K = [k_xx, 0.0, 0.0, 0.0, k_yy, 0.0, 0.0, 0.0, k_zz]
        source_terms = []
        for volume in elems_in_set:
            x, y, z = self.mesh.mb.get_coords(volume)
            vol_nodes = self.mesh.mb.get_adjacencies(volume, 0)
            vol_nodes_crds = self.mesh.mb.get_coords(vol_nodes)
            vol_nodes_crds = np.reshape(vol_nodes_crds, (4, 3))
            tetra_vol = self.mesh.get_tetra_volume(vol_nodes_crds)
            material_set = self.mesh.mb.tag_get_handle("material")
            alpha = self.mesh.mb.tag_get_data(material_set, volume)[0][0]
            st = (
                4
                * pi ** 2
                * alpha
                * (k_xx + k_yy + k_zz)
                * np.sin(2 * pi * x)
                * np.sin(2 * pi * y)
                * np.sin(2 * pi * z)
            )
            source_terms.append(st * tetra_vol)
            self.mesh.mb.tag_set_data(self.mesh.perm_tag, volume, K)
        self.mesh.mb.tag_set_data(
            self.mesh.source_tag, elems_in_set, source_terms
        )

    def benchmark_case_1(self, log_name):
        """
        Call the Finite Volumes for Complex Applications Benchmark.

        Test case 1.
        """
        for node in self.mesh.get_boundary_nodes():
            x, y, z = self.mesh.mb.get_coords([node])
            g_D = self._benchmark_1(x, y, z)[1]
            self.mesh.mb.tag_set_data(self.mesh.dirichlet_tag, node, g_D)
        volumes = self.mesh.all_volumes
        vols = []
        for volume in volumes:
            x, y, z = self.mesh.mb.tag_get_data(
                self.mesh.volume_centre_tag, volume
            )[0]
            self.mesh.mb.tag_set_data(
                self.mesh.perm_tag, volume, self._benchmark_1(x, y, z)[0]
            )
            vol_nodes = self.mesh.mb.get_adjacencies(volume, 0)
            vol_nodes_crds = self.mesh.mb.get_coords(vol_nodes)
            vol_nodes_crds = np.reshape(vol_nodes_crds, (4, 3))
            tetra_vol = self.mesh.get_tetra_volume(vol_nodes_crds)
            vols.append(tetra_vol)
            source_term = self._benchmark_1(x, y, z)[2]
            self.mesh.mb.tag_set_data(
                self.mesh.source_tag, volume, source_term * tetra_vol
            )
        self.mpfad.run_solver(self.im.interpolate)
        u_err = []
        u = []
        for volume in volumes:
            x, y, z = self.mesh.mb.tag_get_data(
                self.mesh.volume_centre_tag, volume
            )[0]
            analytical_solution = self._benchmark_1(x, y, z)[1]
            calculated_solution = self.mpfad.mb.tag_get_data(
                self.mpfad.pressure_tag, volume
            )[0][0]
            u_err.append(
                np.absolute((analytical_solution - calculated_solution))
            )
            u.append(analytical_solution)
        u_max = max(
            self.mpfad.mb.tag_get_data(self.mpfad.pressure_tag, volumes)
        )
        u_min = min(
            self.mpfad.mb.tag_get_data(self.mpfad.pressure_tag, volumes)
        )
        results = self.norms_calculator(u_err, vols, u)
        non_zero_mat = self.mpfad.T.NumGlobalNonzeros()
        norm_vel, norm_grad = self.get_velocity(self._benchmark_1)
        path = (
            "paper_mpfad_tests/benchmark_fvca_cases/benchmark_case_1/"
            + log_name
            + "_log"
        )
        import pdb; pdb.set_trace()
        with open(path, "w") as f:
            f.write("TEST CASE 1\n\nUnknowns:\t %.0f\n" % (len(volumes)))
            # f.write('Interpolation Method: {}'.format(self.im.__name__))
            f.write("Non-zero matrix:\t %.0f\n" % (non_zero_mat))
            f.write("Umin:\t %.6f\n" % (u_min))
            f.write("Umax:\t %.6f\n" % (u_max))
            f.write("L2 norm:\t %.6g\n" % (results[0]))
            f.write("l2 norm volume weighted:\t %.6g\n" % (results[1]))
            f.write("Relative L2 norm:\t %.6g\n" % (results[2]))
            f.write("average error:\t %.6g\n" % (results[3]))
            f.write("maximum error:\t %.6g\n" % (results[4]))
            f.write("minimum error:\t %.6g\n" % (results[5]))
            f.write("velocity norm: \t %.6g\n" % norm_vel)
            f.write("gradient norm: \t %.6g\n" % norm_grad)

        print("max error: ", max(u_err), "l-2 relative norm: ", results[2])
        path = "paper_mpfad_tests/benchmark_fvca_cases/benchmark_case_1/"
        self.mpfad.record_data(path + log_name + ".vtk")
        print("END OF " + log_name + "!!!\n")

    def benchmark_case_2(self, log_name):
        """
        Call the Finite Volume for Complex Applications Benchmark.

        Test case 2.
        """
        for node in self.mesh.get_boundary_nodes():
            x, y, z = self.mesh.mb.get_coords([node])
            g_D = self._benchmark_2(x, y, z)[1]
            self.mesh.mb.tag_set_data(self.mesh.dirichlet_tag, node, g_D)
        volumes = self.mesh.all_volumes
        vols = []
        for volume in volumes:
            x, y, z = self.mesh.mb.tag_get_data(
                self.mesh.volume_centre_tag, volume
            )[0]
            self.mesh.mb.tag_set_data(
                self.mesh.perm_tag, volume, self._benchmark_2(x, y, z)[0]
            )
            vol_nodes = self.mesh.mb.get_adjacencies(volume, 0)
            vol_nodes_crds = self.mesh.mb.get_coords(vol_nodes)
            vol_nodes_crds = np.reshape(vol_nodes_crds, (4, 3))
            tetra_vol = self.mesh.get_tetra_volume(vol_nodes_crds)
            vols.append(tetra_vol)
            source_term = self.calculate_divergent(x, y, z, self._benchmark_2)
            self.mesh.mb.tag_set_data(
                self.mesh.source_tag, volume, source_term * tetra_vol
            )
        self.mpfad.run_solver(self.im.interpolate)
        err = []
        u = []
        for volume in volumes:
            x, y, z = self.mesh.mb.tag_get_data(
                self.mesh.volume_centre_tag, volume
            )[0]
            analytical_solution = self._benchmark_2(x, y, z)[1]
            calculated_solution = self.mpfad.mb.tag_get_data(
                self.mpfad.pressure_tag, volume
            )[0][0]
            err.append(
                np.absolute((analytical_solution - calculated_solution))
            )
            u.append(analytical_solution)
        u_max = max(
            self.mpfad.mb.tag_get_data(self.mpfad.pressure_tag, volumes)
        )
        u_min = min(
            self.mpfad.mb.tag_get_data(self.mpfad.pressure_tag, volumes)
        )
        results = self.norms_calculator(err, vols, u)
        non_zero_mat = self.mpfad.T.NumGlobalNonzeros()
        norm_vel, norm_grad = self.get_velocity(self._benchmark_2)
        path = (
            "paper_mpfad_tests/benchmark_fvca_cases/benchmark_case_2/"
            + log_name
            + "_log"
        )
        with open(path, "w") as f:
            f.write("TEST CASE 2\n\nUnknowns:\t %.6f\n" % (len(volumes)))
            f.write("Non-zero matrix:\t %.6f\n" % (non_zero_mat))
            f.write("Umin:\t %.6f\n" % (u_min))
            f.write("Umax:\t %.6f\n" % (u_max))
            f.write("L2 norm:\t %.6f\n" % (results[0]))
            f.write("l2 norm volume weighted:\t %.6f\n" % (results[1]))
            f.write("Relative L2 norm:\t %.6f\n" % (results[2]))
            f.write("average error:\t %.6f\n" % (results[3]))
            f.write("maximum error:\t %.6f\n" % (results[4]))
            f.write("minimum error:\t %.6f\n" % (results[5]))
            f.write("velocity norm: \t %.6g\n" % norm_vel)
            f.write("gradient norm: \t %.6g\n" % norm_grad)
        print("max error: ", max(err), "l-2 relative norm: ", results[2])
        path = "paper_mpfad_tests/benchmark_fvca_cases/benchmark_case_2/"
        self.mpfad.record_data(path + log_name + ".vtk")
        print("END OF " + log_name + "!!!\n")

    def benchmark_case_3(self, log_name):
        """
        Call the Finite Volume for Complex Applications Benchmark.

        Test case 2.
        """
        for node in self.mesh.get_boundary_nodes():
            x, y, z = self.mesh.mb.get_coords([node])
            g_D = self._benchmark_3(x, y, z)[1]
            self.mesh.mb.tag_set_data(self.mesh.dirichlet_tag, node, g_D)
        volumes = self.mesh.all_volumes
        vols = []
        for volume in volumes:
            x, y, z = self.mesh.mb.tag_get_data(
                self.mesh.volume_centre_tag, volume
            )[0]
            self.mesh.mb.tag_set_data(
                self.mesh.perm_tag, volume, self._benchmark_3(x, y, z)[0]
            )
            vol_nodes = self.mesh.mb.get_adjacencies(volume, 0)
            vol_nodes_crds = self.mesh.mb.get_coords(vol_nodes)
            vol_nodes_crds = np.reshape(vol_nodes_crds, (4, 3))
            tetra_vol = self.mesh.get_tetra_volume(vol_nodes_crds)
            vols.append(tetra_vol)
            source_term = self.calculate_divergent(x, y, z, self._benchmark_3)
            self.mesh.mb.tag_set_data(
                self.mesh.source_tag, volume, source_term * tetra_vol
            )
        self.mpfad.run_solver(self.im.interpolate)
        err = []
        u = []
        for volume in volumes:
            x, y, z = self.mesh.mb.tag_get_data(
                self.mesh.volume_centre_tag, volume
            )[0]
            analytical_solution = self._benchmark_3(x, y, z)[1]
            calculated_solution = self.mpfad.mb.tag_get_data(
                self.mpfad.pressure_tag, volume
            )[0][0]
            err.append(
                np.absolute((analytical_solution - calculated_solution))
            )
            u.append(analytical_solution)
        u_max = max(
            self.mpfad.mb.tag_get_data(self.mpfad.pressure_tag, volumes)
        )
        u_min = min(
            self.mpfad.mb.tag_get_data(self.mpfad.pressure_tag, volumes)
        )
        results = self.norms_calculator(err, vols, u)
        non_zero_mat = self.mpfad.T.NumGlobalNonzeros()
        norm_vel, norm_grad = self.get_velocity(self._benchmark_3)
        path = (
            "paper_mpfad_tests/benchmark_fvca_cases/benchmark_case_3/"
            + log_name
            + "_log"
        )
        with open(path, "w") as f:
            f.write("TEST CASE 2\n\nUnknowns:\t %.6f\n" % (len(volumes)))
            f.write("Non-zero matrix:\t %.6f\n" % (non_zero_mat))
            f.write("Umin:\t %.6f\n" % (u_min))
            f.write("Umax:\t %.6f\n" % (u_max))
            f.write("L2 norm:\t %.6f\n" % (results[0]))
            f.write("l2 norm volume weighted:\t %.6f\n" % (results[1]))
            f.write("Relative L2 norm:\t %.6f\n" % (results[2]))
            f.write("average error:\t %.6f\n" % (results[3]))
            f.write("maximum error:\t %.6f\n" % (results[4]))
            f.write("minimum error:\t %.6f\n" % (results[5]))
            f.write("velocity norm: \t %.6g\n" % norm_vel)
            f.write("gradient norm: \t %.6g\n" % norm_grad)
        print("max error: ", max(err), "l-2 relative norm: ", results[2])
        path = "paper_mpfad_tests/benchmark_fvca_cases/benchmark_case_3/"
        self.mpfad.record_data(path + log_name + ".vtk")
        print("END OF " + log_name + "!!!\n")

    def benchmark_case_5(self, log_name):
        """
        Call the Finite Volumes for Complex Applications Benchmark.

        Test case 5.
        """
        self.mesh.set_media_property(
            "material",
            {1: 0.1, 2: 10.0, 3: 100.0, 4: 0.01},
            dim_target=3,
            set_nodes=True,
        )
        sets = self.mesh.physical_sets[1:]
        for set in sets:
            volumes_in_set = self.mesh.mb.get_entities_by_dimension(set, 3)
            material_set = self.mesh.mb.tag_get_data(
                self.mesh.physical_tag, set
            )[0][0]
            self._benchmark_5(volumes_in_set, material_set)
        self.mpfad.run_solver(self.im.interpolate)
        volumes = self.mesh.all_volumes
        err = []
        u = []
        vols = []
        for set in sets:
            volumes_in_set = self.mesh.mb.get_entities_by_dimension(set, 3)
            for volume in volumes_in_set:
                x, y, z = self.mesh.mb.get_coords(volume)
                vol_nodes = self.mesh.mb.get_adjacencies(volume, 0)
                vol_nodes_crds = self.mesh.mb.get_coords(vol_nodes)
                vol_nodes_crds = np.reshape(vol_nodes_crds, (4, 3))
                tetra_vol = self.mesh.get_tetra_volume(vol_nodes_crds)
                vols.append(tetra_vol)
                material_set = self.mesh.mb.tag_get_handle("material")
                alpha = self.mesh.mb.tag_get_data(material_set, volume)[0][0]
                analytical_solution = self._bmk_5(x, y, z, alpha)
                calculated_solution = self.mpfad.mb.tag_get_data(
                    self.mpfad.pressure_tag, volume
                )[0][0]
                u.append(analytical_solution)
                err.append(
                    np.absolute((analytical_solution - calculated_solution))
                )
        u_max = max(
            self.mpfad.mb.tag_get_data(self.mpfad.pressure_tag, volumes)
        )
        u_min = min(
            self.mpfad.mb.tag_get_data(self.mpfad.pressure_tag, volumes)
        )
        results = self.norms_calculator(err, vols, u)
        # non_zero_mat = self.mpfad.T.NumGlobalNonzeros()
        path = (
            "results/benchmark_fvca_cases/benchmark_case_5/"
            + log_name
            + "_log"
        )
        with open(path, "w") as f:
            f.write("TEST CASE 2\n\nUnknowns:\t %.6f\n" % (len(volumes)))
            # f.write('Non-zero matrix:\t %.6f\n' % (non_zero_mat))
            f.write("Umin:\t %.6f\n" % (u_min))
            f.write("Umax:\t %.6f\n" % (u_max))
            f.write("L2 norm:\t %.6f\n" % (results[0]))
            f.write("l2 norm volume weighted:\t %.6f\n" % (results[1]))
            f.write("Relative L2 norm:\t %.6f\n" % (results[2]))
            f.write("average error:\t %.6f\n" % (results[3]))
            f.write("maximum error:\t %.6f\n" % (results[4]))
            f.write("minimum error:\t %.6f\n" % (results[5]))
            # f.write('velocity norm: \t %.6g\n' % norm_vel)
            # f.write('gradient norm: \t %.6g\n' % norm_grad)
        print(
            "max error: ",
            max(err),
            "l-2 relative norm: ",
            results[2],
            "u_min: ",
            u_min,
            "u_max: ",
            u_max,
        )
        path = "paper_mpfad_tests/benchmark_fvca_cases/benchmark_case_2/"
        self.mpfad.record_data(path + log_name + ".vtk")
        print("END OF " + log_name + "!!!\n")
Beispiel #8
0
class LinearityPreservingTests(unittest.TestCase):
    """Linear preserving test suite."""
    def setUp(self):
        """Init test suite."""
        self.K_1 = np.array([1.0, 0.50, 0.0, 0.50, 1.0, 0.50, 0.0, 0.50, 1.0])
        self.K_2 = np.array([10.0, 1.0, 0.0, 1.0, 10.0, 1.0, 0.0, 1.0, 10.0])
        self.K_3 = np.array([1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1e-3])
        self.K_4 = np.array([1.0, 0.0, 0.0, 0.0, 1e3, 0.0, 0.0, 0.0, 1.0])

        bed_perm_isotropic = [
            0.965384615384615,
            0.173076923076923,
            0.0,
            0.173076923076923,
            0.134615384615385,
            0.0,
            0.0,
            0.0,
            1.0,
        ]
        fracture_perm_isotropic = [
            96.538461538461530,
            17.307692307692307,
            0.0,
            17.307692307692307,
            13.461538461538462,
            0.0,
            0.0,
            0.0,
            1.0,
        ]

        self.mesh_homogeneous = MeshManager("meshes/test_mesh_5_vols.h5m",
                                            dim=3)
        self.mesh_homogeneous.set_boundary_condition("Dirichlet", {101: 0.0},
                                                     dim_target=2,
                                                     set_nodes=True)
        self.volumes = self.mesh_homogeneous.all_volumes
        self.mpfad_homogeneous = MpfaD3D(self.mesh_homogeneous)
        self.mesh_homogeneous.get_redefine_centre()
        self.mesh_homogeneous.set_global_id()

        self.mesh_heterogeneous = MeshManager(
            "meshes/geometry_two_regions_lp_test.msh", dim=3)
        self.mesh_heterogeneous.set_boundary_condition("Dirichlet", {101: 0.0},
                                                       dim_target=2,
                                                       set_nodes=True)
        self.mesh_heterogeneous.get_redefine_centre()
        self.mesh_heterogeneous.set_global_id()
        self.mpfad_heterogeneous = MpfaD3D(self.mesh_heterogeneous)
        self.hvolumes = self.mesh_heterogeneous.all_volumes

        self.slanted_mesh = MeshManager("meshes/mesh_slanted_mesh.h5m", dim=3)
        self.slanted_mesh.set_boundary_condition("Dirichlet", {101: None},
                                                 dim_target=2,
                                                 set_nodes=True)
        self.slanted_mesh.set_boundary_condition("Neumann", {201: 0.0},
                                                 dim_target=2,
                                                 set_nodes=True)

        self.slanted_mesh.set_media_property(
            "Permeability",
            {
                1: bed_perm_isotropic,
                2: fracture_perm_isotropic
            },
            dim_target=3,
        )
        self.slanted_mesh.get_redefine_centre()
        self.slanted_mesh.set_global_id()
        self.mpfad_slanted_mesh = MpfaD3D(self.slanted_mesh)

    def psol1(self, coords):
        """Return solution for test case 1."""
        x, y, z = coords

        return -x - 0.2 * y

    def lp_schneider_2018(self, coords, p_max, p_min, x_max, x_min, y_max,
                          y_min, z_max, z_min):
        """Return the solution for the Schineider (2018) example."""
        x, y, z = coords
        _max = ((1 / 3) * (((x_max - x) / (x_max - x_min)) +
                           ((y_max - y) / (y_max - y_min)) +
                           ((z_max - z) / (z_max - z_min))) * p_max)
        _min = ((1 / 3) * (((x - x_min) / (x_max - x_min)) +
                           ((y - y_min) / (y_max - y_min)) +
                           ((z - z_min) / (z_max - z_min))) * p_min)
        return _max + _min

    def test_case_1(self):
        """Run the test case 1."""
        mb = self.mesh_homogeneous.mb
        for volume in self.volumes:
            mb.tag_set_data(self.mesh_homogeneous.perm_tag, volume, self.K_1)
        allVolumes = self.mesh_homogeneous.all_volumes
        bcVerts = self.mesh_homogeneous.get_boundary_nodes()
        for bcVert in bcVerts:
            vertCoords = mb.get_coords([bcVert])
            bcVal = self.psol1(vertCoords)
            mb.tag_set_data(self.mesh_homogeneous.dirichlet_tag, bcVert, bcVal)
        self.mpfad_homogeneous.run_solver(
            LPEW3(self.mesh_homogeneous).interpolate)
        for volume in allVolumes:
            coords = mb.get_coords([volume])
            u = self.psol1(coords)
            u_calc = mb.tag_get_data(self.mpfad_homogeneous.pressure_tag,
                                     volume)
            self.assertAlmostEqual(u_calc, u, delta=1e-15)

    def test_case_2(self):
        """Test if mesh_homogeneous with tensor K_2 and solution 1."""
        mb = self.mesh_homogeneous.mb
        for volume in self.volumes:
            mb.tag_set_data(self.mesh_homogeneous.perm_tag, volume, self.K_2)
        allVolumes = self.mesh_homogeneous.all_volumes
        bcVerts = self.mesh_homogeneous.get_boundary_nodes()
        for bcVert in bcVerts:
            vertCoords = mb.get_coords([bcVert])
            bcVal = self.psol1(vertCoords)
            mb.tag_set_data(self.mesh_homogeneous.dirichlet_tag, bcVert, bcVal)
        self.mpfad_homogeneous.run_solver(
            LPEW3(self.mesh_homogeneous).interpolate)

        for volume in allVolumes:
            coords = mb.get_coords([volume])
            u = self.psol1(coords)
            u_calc = mb.tag_get_data(self.mpfad_homogeneous.pressure_tag,
                                     volume)
            self.assertAlmostEqual(u_calc, u, delta=1e-15)

    def test_case_3(self):
        """Test if mesh_homogeneous with tensor K_3 and solution 1."""
        mb = self.mesh_homogeneous.mb
        for volume in self.volumes:
            mb.tag_set_data(self.mesh_homogeneous.perm_tag, volume, self.K_3)
        allVolumes = self.mesh_homogeneous.all_volumes
        bcVerts = self.mesh_homogeneous.get_boundary_nodes()
        for bcVert in bcVerts:
            vertCoords = mb.get_coords([bcVert])
            bcVal = self.psol1(vertCoords)
            mb.tag_set_data(self.mesh_homogeneous.dirichlet_tag, bcVert, bcVal)
        self.mpfad_homogeneous.run_solver(
            LPEW3(self.mesh_homogeneous).interpolate)

        for volume in allVolumes:
            coords = mb.get_coords([volume])
            u = self.psol1(coords)
            u_calc = mb.tag_get_data(self.mpfad_homogeneous.pressure_tag,
                                     volume)
            self.assertAlmostEqual(u_calc, u, delta=1e-15)

    def test_case_4(self):
        """Test if mesh_heterogeneous with tensor K_1/K_2 and solution 1."""
        mb = self.mesh_heterogeneous.mb
        mtu = self.mesh_heterogeneous.mtu
        for volume in self.hvolumes:
            x, _, _ = mtu.get_average_position([volume])
            if x < 0.5:
                mb.tag_set_data(self.mesh_heterogeneous.perm_tag, volume,
                                self.K_3)
            else:
                mb.tag_set_data(self.mesh_heterogeneous.perm_tag, volume,
                                self.K_4)
        bcVerts = self.mesh_heterogeneous.get_boundary_nodes()
        for bcVert in bcVerts:
            vertCoords = mb.get_coords([bcVert])
            bcVal = self.psol1(vertCoords)
            mb.tag_set_data(self.mesh_heterogeneous.dirichlet_tag, bcVert,
                            bcVal)

        self.mpfad_heterogeneous.run_solver(
            LPEW3(self.mesh_heterogeneous).interpolate)

        for volume in self.hvolumes:
            coords = mb.get_coords([volume])
            u = self.psol1(coords)
            u_calc = mb.tag_get_data(self.mpfad_heterogeneous.pressure_tag,
                                     volume)

            self.assertAlmostEqual(u_calc, u, delta=1e-15)

    def test_schneider_linear_preserving(self):
        """Test if mesh_homogeneous with tensor K_3 and solution 1."""
        mb = self.mesh_homogeneous.mb
        for volume in self.volumes:
            mb.tag_set_data(self.mesh_homogeneous.perm_tag, volume, self.K_3)
        allVolumes = self.mesh_homogeneous.all_volumes
        bcVerts = self.mesh_homogeneous.get_boundary_nodes()
        for bcVert in bcVerts:
            vertCoords = mb.get_coords([bcVert])
            bcVal = self.lp_schneider_2018(vertCoords, 2e5, 1e5, 1.0, 0.0, 1.0,
                                           0.0, 1.0, 0.0)
            mb.tag_set_data(self.mesh_homogeneous.dirichlet_tag, bcVert, bcVal)
        self.mpfad_homogeneous.run_solver(
            LPEW3(self.mesh_homogeneous).interpolate)

        for volume in allVolumes:
            coords = mb.get_coords([volume])
            u = self.lp_schneider_2018(coords, 2e5, 1e5, 1.0, 0.0, 1.0, 0.0,
                                       1.0, 0.0)
            u_calc = mb.tag_get_data(self.mpfad_homogeneous.pressure_tag,
                                     volume)
            self.assertAlmostEqual(u_calc[0][0], u, delta=1e-10)

    def test_oblique_drain_contains_all_faces(self):
        """Test case: the Oblique Drain (linear solution)."""
        all_faces = self.slanted_mesh.all_faces
        self.assertEqual(len(all_faces), 44)

    def test_if_mesh_contains_all_dirichlet_faces(self):
        """Test if mesh contains all Dirichlet faces."""
        dirichlet_faces = self.slanted_mesh.dirichlet_faces
        self.assertEqual(len(dirichlet_faces), 16)

    def test_if_mesh_contains_all_neumann_faces(self):
        """Test if mesh contains all neumann faces."""
        neumann_faces = self.slanted_mesh.neumann_faces
        self.assertEqual(len(neumann_faces), 12)

    def test_if_neumann_bc_is_appplied(self):
        """Test if newmann BC is applied."""
        for face in self.slanted_mesh.neumann_faces:
            face_flow = self.slanted_mesh.mb.tag_get_data(
                self.slanted_mesh.neumann_tag, face)[0][0]
            self.assertEqual(face_flow, 0.0)

    def test_oblique_drain(self):
        """Test with slanted_mesh."""
        mb = self.slanted_mesh.mb
        allVolumes = self.slanted_mesh.all_volumes
        bcVerts = self.slanted_mesh.get_boundary_nodes()
        for bcVert in bcVerts:
            vertCoords = mb.get_coords([bcVert])
            bcVal = self.psol1(vertCoords)
            mb.tag_set_data(self.slanted_mesh.dirichlet_tag, bcVert, bcVal)

        self.mpfad_slanted_mesh.run_solver(
            LPEW3(self.slanted_mesh).interpolate)

        for volume in allVolumes:
            coords = mb.get_coords([volume])
            u = self.psol1(coords)
            u_calc = mb.tag_get_data(self.mpfad_slanted_mesh.pressure_tag,
                                     volume)
            self.assertAlmostEqual(u_calc[0][0], u, delta=1e-13)
Beispiel #9
0
    def setUp(self):
        """Init test suite."""
        self.K_1 = np.array([1.0, 0.50, 0.0, 0.50, 1.0, 0.50, 0.0, 0.50, 1.0])
        self.K_2 = np.array([10.0, 1.0, 0.0, 1.0, 10.0, 1.0, 0.0, 1.0, 10.0])
        self.K_3 = np.array([1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1e-3])
        self.K_4 = np.array([1.0, 0.0, 0.0, 0.0, 1e3, 0.0, 0.0, 0.0, 1.0])

        bed_perm_isotropic = [
            0.965384615384615,
            0.173076923076923,
            0.0,
            0.173076923076923,
            0.134615384615385,
            0.0,
            0.0,
            0.0,
            1.0,
        ]
        fracture_perm_isotropic = [
            96.538461538461530,
            17.307692307692307,
            0.0,
            17.307692307692307,
            13.461538461538462,
            0.0,
            0.0,
            0.0,
            1.0,
        ]

        self.mesh_homogeneous = MeshManager("meshes/test_mesh_5_vols.h5m",
                                            dim=3)
        self.mesh_homogeneous.set_boundary_condition("Dirichlet", {101: 0.0},
                                                     dim_target=2,
                                                     set_nodes=True)
        self.volumes = self.mesh_homogeneous.all_volumes
        self.mpfad_homogeneous = MpfaD3D(self.mesh_homogeneous)
        self.mesh_homogeneous.get_redefine_centre()
        self.mesh_homogeneous.set_global_id()

        self.mesh_heterogeneous = MeshManager(
            "meshes/geometry_two_regions_lp_test.msh", dim=3)
        self.mesh_heterogeneous.set_boundary_condition("Dirichlet", {101: 0.0},
                                                       dim_target=2,
                                                       set_nodes=True)
        self.mesh_heterogeneous.get_redefine_centre()
        self.mesh_heterogeneous.set_global_id()
        self.mpfad_heterogeneous = MpfaD3D(self.mesh_heterogeneous)
        self.hvolumes = self.mesh_heterogeneous.all_volumes

        self.slanted_mesh = MeshManager("meshes/mesh_slanted_mesh.h5m", dim=3)
        self.slanted_mesh.set_boundary_condition("Dirichlet", {101: None},
                                                 dim_target=2,
                                                 set_nodes=True)
        self.slanted_mesh.set_boundary_condition("Neumann", {201: 0.0},
                                                 dim_target=2,
                                                 set_nodes=True)

        self.slanted_mesh.set_media_property(
            "Permeability",
            {
                1: bed_perm_isotropic,
                2: fracture_perm_isotropic
            },
            dim_target=3,
        )
        self.slanted_mesh.get_redefine_centre()
        self.slanted_mesh.set_global_id()
        self.mpfad_slanted_mesh = MpfaD3D(self.slanted_mesh)
Beispiel #10
0
class MeshManagerTest(unittest.TestCase):

    """
    These tests are more MeshManager class related. We should rename
    this test suite.
    """

    def setUp(self):

        K_1 = np.array([1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0])
        K_2 = np.array([2.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 2.0])

        self.mesh_1 = MeshManager("meshes/mesh_test_1.msh")

        self.mesh_2 = MeshManager("meshes/mesh_test_2.msh", dim=3)
        self.mesh_2.set_media_property("Permeability", {1: K_1}, dim_target=3)
        self.mesh_2.set_boundary_condition(
            "Dirichlet", {102: 1.0, 101: 0.0}, dim_target=2, set_nodes=True
        )
        self.mesh_2.set_boundary_condition(
            "Neumann", {201: 0.0}, dim_target=2, set_nodes=True
        )
        self.mesh_2.set_global_id()
        self.mesh_2.get_redefine_centre()
        self.mpfad_2 = MpfaD3D(self.mesh_2)

        self.mesh_3 = MeshManager(
            "meshes/geometry_two_regions_test.msh", dim=3
        )
        self.mesh_3.set_media_property(
            "Permeability", {1: K_1, 2: K_2}, dim_target=3
        )
        self.mesh_3.set_boundary_condition(
            "Dirichlet", {102: 1.0, 101: 0.0}, dim_target=2, set_nodes=True
        )
        self.mesh_3.set_boundary_condition(
            "Neumann", {201: 0.0}, dim_target=2, set_nodes=True
        )
        self.mesh_3.get_redefine_centre()
        self.mpfad_3 = MpfaD3D(self.mesh_3)

        self.mesh_4 = MeshManager("meshes/mesh_darlan.msh")
        self.mesh_4.set_global_id()
        self.mesh_4.get_redefine_centre()

    def test_if_method_has_all_dirichlet_nodes(self):
        self.assertEqual(len(self.mpfad_3.dirichlet_nodes), 10)

    def test_if_method_has_all_neumann_nodes(self):
        self.assertEqual(len(self.mpfad_3.neumann_nodes), 12)

    def test_if_method_has_all_intern_nodes(self):
        self.assertEqual(len(self.mpfad_3.intern_nodes), 1)

    def test_if_method_has_all_dirichlet_faces(self):
        self.assertEqual(len(self.mpfad_2.dirichlet_faces), 4)

    def test_if_method_has_all_neumann_faces(self):
        self.assertEqual(len(self.mpfad_2.neumann_faces), 8)

    def test_if_method_has_all_intern_faces(self):
        self.assertEqual(len(self.mpfad_2.intern_faces), 18)

    def test_get_tetra_volume(self):
        a_tetra = self.mesh_1.all_volumes[0]
        tetra_nodes = self.mesh_1.mb.get_adjacencies(a_tetra, 0)
        tetra_nodes_coords = self.mesh_1.mb.get_coords(tetra_nodes)
        tetra_nodes_coords = np.reshape(tetra_nodes_coords, (4, 3))
        vol_eval = self.mesh_1.get_tetra_volume(tetra_nodes_coords)
        self.assertAlmostEqual(vol_eval, 1 / 12.0, delta=1e-15)
class InterpolationMethodTest(unittest.TestCase):
    """Test suite for interpolation."""
    def setUp(self):
        """Init test suite."""
        K_1 = np.array([1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0])

        K_2 = np.array([2.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 2.0])

        self.mesh_1 = MeshManager("meshes/mesh_test_1.msh", dim=3)
        self.mesh_1.set_media_property("Permeability", {1: K_1}, dim_target=3)
        self.mesh_1.set_boundary_condition("Dirichlet", {
            102: 1.0,
            101: 0.0
        },
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_1.set_boundary_condition("Neumann", {201: 0.0},
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_1.get_redefine_centre()
        self.mpfad_1 = MpfaD3D(self.mesh_1)

        self.mesh_2 = MeshManager("meshes/mesh_test_2.msh", dim=3)
        self.mesh_2.set_media_property("Permeability", {1: K_1}, dim_target=3)
        self.mesh_2.set_boundary_condition("Dirichlet", {
            102: 1.0,
            101: 0.0
        },
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_2.set_boundary_condition("Neumann", {201: 0.0},
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_2.set_global_id()
        self.mesh_2.get_redefine_centre()
        self.mpfad_2 = MpfaD3D(self.mesh_2)

        self.mesh_4 = MeshManager("meshes/mesh_test_7.msh", dim=3)
        self.mesh_4.set_media_property("Permeability", {1: K_1}, dim_target=3)
        self.mesh_4.set_boundary_condition("Dirichlet", {
            102: 1.0,
            101: 0.0
        },
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_4.set_boundary_condition("Neumann", {201: 0.0},
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_4.set_global_id()
        self.mesh_4.get_redefine_centre()
        self.mpfad_4 = MpfaD3D(self.mesh_4)

        self.mesh_5 = MeshManager("meshes/geometry_two_regions_test.msh",
                                  dim=3)
        self.mesh_5.set_media_property("Permeability", {
            1: K_2,
            2: K_1
        },
                                       dim_target=3)
        self.mesh_5.set_boundary_condition("Dirichlet", {
            102: 1.0,
            101: 0.0
        },
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_5.set_boundary_condition("Neumann", {201: 0.0},
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_5.get_redefine_centre()
        self.mesh_5.set_global_id()
        self.mpfad_5 = MpfaD3D(self.mesh_5)

        self.mesh_6 = MeshManager("meshes/mesh_test_6.msh", dim=3)
        self.mesh_6.set_media_property("Permeability", {1: K_1}, dim_target=3)
        self.mesh_6.set_boundary_condition("Dirichlet", {102: 1.0},
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_6.set_boundary_condition("Neumann", {
            202: 1.0,
            201: 0.0
        },
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_6.get_redefine_centre()
        self.mesh_6.set_global_id()
        self.mpfad_6 = MpfaD3D(self.mesh_6)

    def test_lpew3_yields_same_weight_for_equal_tetrahedra(self):
        """Test if lpew3 interpolation yields correct weights."""
        intern_node = self.mesh_1.all_nodes[-1]
        vols_ws_by_lpew3 = LPEW3(self.mesh_1).interpolate(intern_node)
        for vol, weight in vols_ws_by_lpew3.items():
            self.assertAlmostEqual(weight, 1.0 / 12.0, delta=1e-15)

    def test_linear_problem_with_lpew3_interpolation_mesh_2(self):
        """Test if linear solution is obtained for mesh 2 testcase."""
        self.mpfad_2.run_solver(LPEW3(self.mesh_2).interpolate)
        for a_volume in self.mesh_2.all_volumes:
            local_pressure = self.mesh_2.mb.tag_get_data(
                self.mpfad_2.pressure_tag, a_volume)
            coord_x = self.mesh_2.get_centroid(a_volume)[0]
            self.assertAlmostEqual(local_pressure[0][0],
                                   1 - coord_x,
                                   delta=1e-15)

    def test_linear_problem_with_neumann_lpew3_interpolation_mesh_4(self):
        """Test solution with Neumann BC lpew3 interpolation."""
        self.mpfad_4.run_solver(LPEW3(self.mesh_4).interpolate)
        for a_volume in self.mesh_4.all_volumes:
            local_pressure = self.mesh_4.mb.tag_get_data(
                self.mpfad_4.pressure_tag, a_volume)
            coord_x = self.mesh_4.get_centroid(a_volume)[0]
            self.assertAlmostEqual(local_pressure[0][0],
                                   1 - coord_x,
                                   delta=1e-15)

    def test_heterogeneous_mesh_lpew3_neumann_intern_nodes_mesh_5(self):
        """Test solution for Neumann BC lpew3 and heterogeneus mesh."""
        self.mpfad_4.run_solver(LPEW3(self.mesh_4).interpolate)
        self.mpfad_5.run_solver(LPEW3(self.mesh_5).interpolate)
        for a_volume in self.mesh_5.all_volumes:
            local_pressure = self.mesh_5.mb.tag_get_data(
                self.mpfad_5.pressure_tag, a_volume)
            coord_x = self.mesh_5.get_centroid(a_volume)[0]

            if coord_x < 0.5:
                self.assertAlmostEqual(local_pressure[0][0],
                                       (-2 / 3.0) * coord_x + 1,
                                       delta=1e-14)
            else:
                self.assertAlmostEqual(
                    local_pressure[0][0],
                    (4 / 3.0) * (1 - coord_x),
                    delta=1e-14,
                )

    def test_number_of_non_null_neumann_faces(self):
        """Test if len of neumann faces is not None."""
        neumann_faces = self.mpfad_6.neumann_faces
        count = 0

        for neumann_face in neumann_faces:
            flux = self.mesh_6.mb.tag_get_data(self.mpfad_6.neumann_tag,
                                               neumann_face)
            if flux == 1.0:
                count += 1
        self.assertEqual(count, 2)

    def test_linear_problem_with_non_null_neumann_condition_lpew3(self):
        """Test linear problem with non null neumann BC and lpew3."""
        self.mpfad_6.run_solver(LPEW3(self.mesh_6).interpolate)
        for a_volume in self.mesh_6.all_volumes:
            local_pressure = self.mesh_6.mb.tag_get_data(
                self.mpfad_6.pressure_tag, a_volume)
            coord_x = self.mesh_6.get_centroid(a_volume)[0]
            self.assertAlmostEqual(local_pressure[0][0],
                                   1 - coord_x,
                                   delta=1e-15)
Beispiel #12
0
class TestCasesMGE:
    def __init__(self, filename, interpolation_method):
        self.mesh = MeshManager(filename, dim=3)
        self.mesh.set_boundary_condition("Dirichlet", {101: 0.0},
                                         dim_target=2,
                                         set_nodes=True)
        self.mesh.set_global_id()
        self.mesh.get_redefine_centre()
        self.mpfad = MpfaD3D(self.mesh)
        self.im = interpolation_method(self.mesh)

    def get_velocity(self, bmk):
        self.node_pressure_tag = self.mpfad.mb.tag_get_handle(
            "Node Pressure", 1, types.MB_TYPE_DOUBLE, types.MB_TAG_SPARSE,
            True)
        p_verts = []
        for node in self.mesh.all_nodes:
            try:
                p_vert = self.mpfad.mb.tag_get_data(self.mpfad.dirichlet_tag,
                                                    node)
                p_verts.append(p_vert[0])
            except Exception:
                p_vert = 0.0
                p_tag = self.mpfad.pressure_tag
                nd_weights = self.mpfad.nodes_ws[node]
                for volume, wt in nd_weights.items():
                    p_vol = self.mpfad.mb.tag_get_data(p_tag, volume)
                    p_vert += p_vol * wt
                p_verts.append(p_vert[0])
        self.mpfad.mb.tag_set_data(self.node_pressure_tag, self.mesh.all_nodes,
                                   p_verts)
        err = []
        err_grad = []
        grads_p = []
        all_vels = []
        areas = []
        vols = []
        for a_volume in self.mesh.all_volumes:
            vol_faces = self.mesh.mtu.get_bridge_adjacencies(a_volume, 2, 2)
            vol_nodes = self.mesh.mtu.get_bridge_adjacencies(a_volume, 0, 0)
            vol_crds = self.mesh.mb.get_coords(vol_nodes)
            vol_crds = np.reshape(vol_crds, ([4, 3]))
            vol_volume = self.mesh.get_tetra_volume(vol_crds)
            vols.append(vol_volume)
            I, J, K = self.mesh.mtu.get_bridge_adjacencies(vol_faces[0], 2, 0)
            L = list(
                set(vol_nodes).difference(
                    set(
                        self.mesh.mtu.get_bridge_adjacencies(
                            vol_faces[0], 2, 0))))
            JI = self.mesh.mb.get_coords([I]) - self.mesh.mb.get_coords([J])
            JK = self.mesh.mb.get_coords([K]) - self.mesh.mb.get_coords([J])
            LJ = self.mesh.mb.get_coords([J]) - self.mesh.mb.get_coords(L)
            N_IJK = np.cross(JI, JK) / 2.0

            test = np.dot(LJ, N_IJK)
            if test < 0.0:
                I, K = K, I
                JI = self.mesh.mb.get_coords([I]) - self.mesh.mb.get_coords(
                    [J])
                JK = self.mesh.mb.get_coords([K]) - self.mesh.mb.get_coords(
                    [J])
                N_IJK = np.cross(JI, JK) / 2.0

            tan_JI = np.cross(N_IJK, JI)
            tan_JK = np.cross(N_IJK, JK)
            face_area = np.sqrt(np.dot(N_IJK, N_IJK))

            h_L = geo.get_height(N_IJK, LJ)

            p_I = self.mpfad.mb.tag_get_data(self.node_pressure_tag, I)
            p_J = self.mpfad.mb.tag_get_data(self.node_pressure_tag, J)
            p_K = self.mpfad.mb.tag_get_data(self.node_pressure_tag, K)
            p_L = self.mpfad.mb.tag_get_data(self.node_pressure_tag, L)
            grad_normal = -2 * (p_J - p_L) * N_IJK

            grad_cross_I = (p_J - p_I) * (
                (np.dot(tan_JK, LJ) / face_area**2) * N_IJK -
                (h_L / (face_area)) * tan_JK)
            grad_cross_K = (p_K - p_J) * (
                (np.dot(tan_JI, LJ) / face_area**2) * N_IJK -
                (h_L / (face_area)) * tan_JI)

            grad_p = -(1 / (6 * vol_volume)) * (grad_normal + grad_cross_I +
                                                grad_cross_K)
            vol_centroid = np.asarray(
                self.mesh.mb.tag_get_data(self.mesh.volume_centre_tag,
                                          a_volume)[0])
            vol_perm = self.mesh.mb.tag_get_data(self.mesh.perm_tag,
                                                 a_volume).reshape([3, 3])
            x, y, z = vol_centroid
            grad_p_bar = self.calculate_gradient(x, y, z, bmk)
            grads_p.append(np.dot(grad_p_bar, grad_p_bar))
            # print(grad_p, grad_p_bar, grad_p - grad_p_bar)
            e = grad_p[0] - grad_p_bar
            err_norm = np.sqrt(np.dot(e, e))
            # print(err_norm)
            err_grad.append(err_norm**2)

            for face in vol_faces:
                # x, y, z = self.mesh.mb.get_coords([face])
                face_nodes = self.mesh.mtu.get_bridge_adjacencies(face, 2, 0)
                face_nodes_crds = self.mesh.mb.get_coords(face_nodes)
                area_vect = geo._area_vector(face_nodes_crds.reshape([3, 3]),
                                             vol_centroid)[0]
                unit_area_vec = area_vect / np.sqrt(
                    np.dot(area_vect, area_vect))
                k_grad_p = np.dot(vol_perm, grad_p[0])
                vel = -np.dot(k_grad_p, unit_area_vec)
                calc_vel = -np.dot(self.calculate_K_gradient(x, y, z, bmk),
                                   unit_area_vec)
                err.append(abs(vel - calc_vel)**2)
                areas.append(np.sqrt(np.dot(area_vect, area_vect)))
                all_vels.append(calc_vel**2)
        norm_vel = np.sqrt(np.dot(err, areas) / np.dot(all_vels, areas))
        # print(len(err_norm), len(vols))
        norm_grad = np.sqrt(np.dot(err_grad, vols) / np.dot(grads_p, vols))
        # print(norm_grad)
        return norm_vel, norm_grad

    def norms_calculator(self, error_vector, volumes_vector, u_vector):
        error_vector = np.array(error_vector)
        volumes_vector = np.array(volumes_vector)
        u_vector = np.array(u_vector)
        l2_norm = np.dot(error_vector, error_vector)**(1 / 2)
        l2_volume_norm = np.dot(error_vector**2, volumes_vector)**(1 / 2)
        erl2 = (np.dot(error_vector**2, volumes_vector) /
                np.dot(u_vector**2, volumes_vector))**(1 / 2)
        avr_error = l2_norm / len(volumes_vector)
        max_error = max(error_vector)
        min_error = min(error_vector)
        results = [
            l2_norm,
            l2_volume_norm,
            erl2,
            avr_error,
            max_error,
            min_error,
        ]
        return results

    def calculate_gradient(self, x, y, z, benchmark, delta=0.00001):
        grad_x = (benchmark(x + delta, y, z)[1] -
                  benchmark(x, y, z)[1]) / delta
        grad_y = (benchmark(x, y + delta, z)[1] -
                  benchmark(x, y, z)[1]) / delta
        grad_z = (benchmark(x, y, z + delta)[1] -
                  benchmark(x, y, z)[1]) / delta
        grad = np.array([grad_x, grad_y, grad_z])
        return grad

    def calculate_K_gradient(self, x, y, z, benchmark):
        perm = np.array(benchmark(x, y, z)[0]).reshape([3, 3])
        grad = self.calculate_gradient(x, y, z, benchmark)
        return np.dot(perm, grad)

    def calculate_divergent(self, x, y, z, benchmark, delta=0.00001):
        k_grad_x = (self.calculate_K_gradient(x + delta, y, z, benchmark)[0] -
                    self.calculate_K_gradient(x, y, z, benchmark)[0]) / delta
        k_grad_y = (self.calculate_K_gradient(x, y + delta, z, benchmark)[1] -
                    self.calculate_K_gradient(x, y, z, benchmark)[1]) / delta
        k_grad_z = (self.calculate_K_gradient(x, y, z + delta, benchmark)[2] -
                    self.calculate_K_gradient(x, y, z, benchmark)[2]) / delta
        return -np.sum(k_grad_x + k_grad_y + k_grad_z)

    def mge_test_case_1(self, x, y, z):
        K = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
        u = np.sin(sqrt(2) * pi * x) * np.sinh(pi * y) * np.sinh(pi * z)

        return K, u

    def mge_test_case_2(self, x, y, z):
        if x <= 0.5:
            K = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
            u = (x - 0.5) * (2 * np.sin(y) + np.cos(y)) + np.sin(y) + z
        else:
            K = [2.0, 1.0, 0.0, 1.0, 2.0, 0.0, 0.0, 0.0, 1.0]
            u = np.exp(x) - 0.5 * np.sin(y) + z
        return K, u

    def mge_test_case_3(self, x, y, z):
        eps = 50
        K = [
            (1 + 10 * x**2 + y**2 + z**2),
            0.0,
            0.0,
            0.0,
            (1 + x**2 + 10 * y**2 + z**2),
            0.0,
            0.0,
            0.0,
            eps * (1 + x**2 + y**2 + 10 * z**2),
        ]
        u = x * (1 - x) * y * (1 - y) * z * (1 - z)
        return K, u

    def mge_test_case_4(self, x, y, z):
        eps1 = 0.1
        eps2 = 10
        K = [
            np.cos(pi * x)**2 + eps1 * np.sin(pi * x)**2,
            np.sin(pi * x) * np.cos(pi * x) -
            eps1 * np.sin(pi * x) * np.cos(pi * x),
            0.0,
            np.sin(pi * x) * np.cos(pi * x) -
            eps1 * np.sin(pi * x) * np.cos(pi * x),
            np.sin(pi * x)**2 + eps1 * np.cos(pi * x)**2,
            0.0,
            0.0,
            0.0,
            eps2 * (1 + x + y + z),
        ]
        u = np.sin(pi * x) * np.sin(pi * y) * np.sin(pi * z)

        return K, u

    def mge_test_case_5(self, x, y, z):
        epsx = 1
        epsy = 1e-3
        epsz = 10
        K = [
            (epsx * x**2 + epsy * y**2) / (x**2 + y**2),
            ((epsx - epsy) * x * y) / (x**2 + y**2),
            0.0,
            ((epsx - epsy) * x * y) / (x**2 + y**2),
            (epsy * x**2 + epsx * y**2) / (x**2 + y**2),
            0.0,
            0.0,
            0.0,
            epsz * (z + 1),
        ]
        u = np.sin(2 * pi * x) * np.sin(2 * pi * y) * np.sin(2 * pi * z)

        return K, u

    def run_case(self, log_name, test_case):
        """
        Call the Finite Volume for Complex Applications Benchmark.

        Test case 2.
        """
        func = {
            "mge_test_case_1": self.mge_test_case_1,
            "mge_test_case_2": self.mge_test_case_2,
            "mge_test_case_3": self.mge_test_case_3,
            "mge_test_case_4": self.mge_test_case_4,
            "mge_test_case_5": self.mge_test_case_5,
        }
        for node in self.mesh.get_boundary_nodes():
            x, y, z = self.mesh.mb.get_coords([node])
            g_D = func[test_case](x, y, z)[1]
            self.mesh.mb.tag_set_data(self.mesh.dirichlet_tag, node, g_D)
        volumes = self.mesh.all_volumes
        vols = []
        for volume in volumes:
            x, y, z = self.mesh.mb.tag_get_data(self.mesh.volume_centre_tag,
                                                volume)[0]
            self.mesh.mb.tag_set_data(self.mesh.perm_tag, volume,
                                      func[test_case](x, y, z)[0])
            vol_nodes = self.mesh.mb.get_adjacencies(volume, 0)
            vol_nodes_crds = self.mesh.mb.get_coords(vol_nodes)
            vol_nodes_crds = np.reshape(vol_nodes_crds, (4, 3))
            tetra_vol = self.mesh.get_tetra_volume(vol_nodes_crds)
            vols.append(tetra_vol)
            source_term = self.calculate_divergent(x, y, z, func[test_case])
            self.mesh.mb.tag_set_data(self.mesh.source_tag, volume,
                                      source_term * tetra_vol)

        self.mpfad.run_solver(self.im.interpolate)
        err = []
        u = []
        for volume in volumes:
            x, y, z = self.mesh.mb.tag_get_data(self.mesh.volume_centre_tag,
                                                volume)[0]
            analytical_solution = func[test_case](x, y, z)[1]
            calculated_solution = self.mpfad.mb.tag_get_data(
                self.mpfad.pressure_tag, volume)[0][0]
            err.append(np.absolute(
                (analytical_solution - calculated_solution)))
            u.append(analytical_solution)
        u_max = max(
            self.mpfad.mb.tag_get_data(self.mpfad.pressure_tag, volumes))
        u_min = min(
            self.mpfad.mb.tag_get_data(self.mpfad.pressure_tag, volumes))
        results = self.norms_calculator(err, vols, u)
        non_zero_mat = self.mpfad.T.NumGlobalNonzeros()
        norm_vel, norm_grad = self.get_velocity(func[test_case])
        path = (
            f"paper_mpfad_tests/mge_paper_cases/{func[test_case].__name__}/" +
            log_name + "_log")
        with open(path, "w") as f:
            f.write("TEST CASE 2\n\nUnknowns:\t %.6f\n" % (len(volumes)))
            f.write("Non-zero matrix:\t %.6f\n" % (non_zero_mat))
            f.write("Umin:\t %.6f\n" % (u_min))
            f.write("Umax:\t %.6f\n" % (u_max))
            f.write("L2 norm:\t %.6f\n" % (results[0]))
            f.write("l2 norm volume weighted:\t %.6f\n" % (results[1]))
            f.write("Relative L2 norm:\t %.6f\n" % (results[2]))
            f.write("average error:\t %.6f\n" % (results[3]))
            f.write("maximum error:\t %.6f\n" % (results[4]))
            f.write("minimum error:\t %.6f\n" % (results[5]))
            f.write("velocity norm: \t %.6g\n" % norm_vel)
            f.write("gradient norm: \t %.6g\n" % norm_grad)
        print("max error: ", max(err), "l-2 relative norm: ", results[2])
        path = (
            f"paper_mpfad_tests/mge_paper_cases/{func[test_case].__name__}/" +
            log_name)
        self.mpfad.record_data(path + ".vtk")
        print("END OF " + log_name + "!!!\n")
    def setUp(self):
        """Init test suite."""
        K_1 = np.array([1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0])
        self.mesh = MeshManager("meshes/mesh_test_conservative.msh", dim=3)
        self.mesh.set_media_property("Permeability", {1: K_1}, dim_target=3)
        self.mesh.set_boundary_condition("Dirichlet", {
            102: 1.0,
            101: 0.0
        },
                                         dim_target=2,
                                         set_nodes=True)
        self.mesh.set_boundary_condition("Neumann", {201: 0.0},
                                         dim_target=2,
                                         set_nodes=True)
        self.mesh.get_redefine_centre()
        self.mesh.set_global_id()
        self.mpfad = MpfaD3D(self.mesh)
        self.od = MeshManager("meshes/mesh_slanted_mesh.h5m", dim=3)
        bed_perm_isotropic = [
            0.965384615384615,
            0.173076923076923,
            0.0,
            0.173076923076923,
            0.134615384615385,
            0.0,
            0.0,
            0.0,
            1.0,
        ]
        fracture_perm_isotropic = [
            96.538461538461530,
            17.307692307692307,
            0.0,
            17.307692307692307,
            13.461538461538462,
            0.0,
            0.0,
            0.0,
            1.0,
        ]
        self.od.set_boundary_condition("Dirichlet", {101: None},
                                       dim_target=2,
                                       set_nodes=True)
        self.od.set_boundary_condition("Neumann", {201: 0.0},
                                       dim_target=2,
                                       set_nodes=True)

        self.od.set_media_property(
            "Permeability",
            {
                1: bed_perm_isotropic,
                2: fracture_perm_isotropic
            },
            dim_target=3,
        )
        self.od.get_redefine_centre()
        self.od.set_global_id()
        self.od_mpfad = MpfaD3D(self.od)

        self.perm = np.array([2.0, 1.0, 0.0, 1.0, 2.0, 1.0, 0.0, 1.0, 2.0])
        self.m = MeshManager("meshes/test_mesh_5_vols.h5m", dim=3)
        self.m.set_boundary_condition("Dirichlet", {101: None},
                                      dim_target=2,
                                      set_nodes=True)
        self.m.get_redefine_centre()
        self.m.set_global_id()
        self.m_mpfad = MpfaD3D(self.m)
class MeshManagerTest(unittest.TestCase):
    """Test MeshManager class."""
    def setUp(self):
        """Init test suite."""
        K_1 = np.array([1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0])
        self.mesh = MeshManager("meshes/mesh_test_conservative.msh", dim=3)
        self.mesh.set_media_property("Permeability", {1: K_1}, dim_target=3)
        self.mesh.set_boundary_condition("Dirichlet", {
            102: 1.0,
            101: 0.0
        },
                                         dim_target=2,
                                         set_nodes=True)
        self.mesh.set_boundary_condition("Neumann", {201: 0.0},
                                         dim_target=2,
                                         set_nodes=True)
        self.mesh.get_redefine_centre()
        self.mesh.set_global_id()
        self.mpfad = MpfaD3D(self.mesh)
        self.od = MeshManager("meshes/mesh_slanted_mesh.h5m", dim=3)
        bed_perm_isotropic = [
            0.965384615384615,
            0.173076923076923,
            0.0,
            0.173076923076923,
            0.134615384615385,
            0.0,
            0.0,
            0.0,
            1.0,
        ]
        fracture_perm_isotropic = [
            96.538461538461530,
            17.307692307692307,
            0.0,
            17.307692307692307,
            13.461538461538462,
            0.0,
            0.0,
            0.0,
            1.0,
        ]
        self.od.set_boundary_condition("Dirichlet", {101: None},
                                       dim_target=2,
                                       set_nodes=True)
        self.od.set_boundary_condition("Neumann", {201: 0.0},
                                       dim_target=2,
                                       set_nodes=True)

        self.od.set_media_property(
            "Permeability",
            {
                1: bed_perm_isotropic,
                2: fracture_perm_isotropic
            },
            dim_target=3,
        )
        self.od.get_redefine_centre()
        self.od.set_global_id()
        self.od_mpfad = MpfaD3D(self.od)

        self.perm = np.array([2.0, 1.0, 0.0, 1.0, 2.0, 1.0, 0.0, 1.0, 2.0])
        self.m = MeshManager("meshes/test_mesh_5_vols.h5m", dim=3)
        self.m.set_boundary_condition("Dirichlet", {101: None},
                                      dim_target=2,
                                      set_nodes=True)
        self.m.get_redefine_centre()
        self.m.set_global_id()
        self.m_mpfad = MpfaD3D(self.m)

    def psol1(self, coords):
        """Return solution to problem 1."""
        x, y, z = coords

        return -x - 0.2 * y

    def psol2(self, coords):
        """Return solution to problem 2."""
        x, y, z = coords

        return y**2

    def test_if_method_yields_exact_solution(self):
        """Test if method yields exact solution for a flow channel problem."""
        self.mtu = self.mesh.mtu
        self.mb = self.mesh.mb
        self.mpfad.run_solver(LPEW3(self.mesh).interpolate)
        for volume in self.mesh.all_volumes:
            c_solution = self.mb.tag_get_data(self.mpfad.pressure_tag, volume)
            a_solution = 1 - self.mb.get_coords([volume])[0]
            self.assertAlmostEqual(c_solution, a_solution, delta=1e-14)

    def test_if_inner_verts_weighted_calculation_yelds_exact_solution(self):
        """Test if inner verts weights match expected values."""
        self.mtu = self.mpfad.mtu
        self.mb = self.mpfad.mb
        self.mpfad.run_solver(LPEW3(self.mesh).interpolate)
        for node in self.mpfad.intern_nodes:
            analytical_solution = 1 - self.mb.get_coords([node])[0]
            nd_weights = self.mpfad.nodes_ws[node]
            p_vert = 0.0
            for volume, wt in nd_weights.items():
                p_vol = self.mpfad.mb.tag_get_data(self.mpfad.pressure_tag,
                                                   volume)
                p_vert += p_vol * wt
            self.assertAlmostEqual(p_vert, analytical_solution, delta=5e-15)

    @unittest.skip("later")
    def test_if_gradient_yields_correct_values(self):
        """Test if gradient yelds expeted values."""
        self.node_pressure_tag = self.mpfad.mb.tag_get_handle(
            "Node Pressure", 1, types.MB_TYPE_DOUBLE, types.MB_TAG_SPARSE,
            True)
        self.mpfad.run_solver(LPEW3(self.mesh).interpolate)
        p_verts = []
        for node in self.mesh.all_nodes:
            p_vert = self.mpfad.mb.tag_get_data(self.mpfad.dirichlet_tag, node)
            p_verts.append(p_vert[0])
        self.mpfad.mb.tag_set_data(self.node_pressure_tag, self.mesh.all_nodes,
                                   p_verts)
        for a_volume in self.mesh.all_volumes:
            vol_faces = self.mesh.mtu.get_bridge_adjacencies(a_volume, 2, 2)
            vol_nodes = self.mesh.mtu.get_bridge_adjacencies(a_volume, 0, 0)
            vol_crds = self.mesh.mb.get_coords(vol_nodes)
            vol_crds = np.reshape(vol_crds, ([4, 3]))
            vol_volume = self.mesh.get_tetra_volume(vol_crds)
            I, J, K = self.mesh.mtu.get_bridge_adjacencies(vol_faces[0], 2, 0)
            L = list(
                set(vol_nodes).difference(
                    set(
                        self.mesh.mtu.get_bridge_adjacencies(
                            vol_faces[0], 2, 0))))
            JI = self.mesh.mb.get_coords([I]) - self.mesh.mb.get_coords([J])
            JK = self.mesh.mb.get_coords([K]) - self.mesh.mb.get_coords([J])
            LJ = self.mesh.mb.get_coords([J]) - self.mesh.mb.get_coords(L)
            N_IJK = np.cross(JI, JK) / 2.0

            test = np.dot(LJ, N_IJK)
            if test < 0.0:
                I, K = K, I
                JI = self.mesh.mb.get_coords([I]) - self.mesh.mb.get_coords(
                    [J])
                JK = self.mesh.mb.get_coords([K]) - self.mesh.mb.get_coords(
                    [J])
                N_IJK = np.cross(JI, JK) / 2.0

            tan_JI = np.cross(N_IJK, JI)
            tan_JK = np.cross(N_IJK, JK)
            face_area = np.sqrt(np.dot(N_IJK, N_IJK))

            h_L = geo.get_height(N_IJK, LJ)

            p_I = self.mpfad.mb.tag_get_data(self.node_pressure_tag, I)
            p_J = self.mpfad.mb.tag_get_data(self.node_pressure_tag, J)
            p_K = self.mpfad.mb.tag_get_data(self.node_pressure_tag, K)
            p_L = self.mpfad.mb.tag_get_data(self.node_pressure_tag, L)
            grad_normal = -2 * (p_J - p_L) * N_IJK
            grad_cross_I = (p_J - p_I) * (
                (np.dot(tan_JK, LJ) / face_area**2) * N_IJK -
                (h_L / (face_area)) * tan_JK)
            grad_cross_K = (p_K - p_J) * (
                (np.dot(tan_JI, LJ) / face_area**2) * N_IJK -
                (h_L / (face_area)) * tan_JI)

            grad_p = -(1 / (6 * vol_volume)) * (grad_normal + grad_cross_I +
                                                grad_cross_K)
            vol_centroid = np.asarray(
                self.mesh.mb.tag_get_data(self.mesh.volume_centre_tag,
                                          a_volume)[0])
            vol_perm = self.mesh.mb.tag_get_data(self.mesh.perm_tag,
                                                 a_volume).reshape([3, 3])
            v = 0.0
            for face in vol_faces:
                face_nodes = self.mesh.mtu.get_bridge_adjacencies(face, 2, 0)
                face_nodes_crds = self.mesh.mb.get_coords(face_nodes)
                area_vect = geo._area_vector(face_nodes_crds.reshape([3, 3]),
                                             vol_centroid)[0]
                unit_area_vec = area_vect / np.sqrt(
                    np.dot(area_vect, area_vect))
                k_grad_p = np.dot(vol_perm, grad_p[0])
                vel = -np.dot(k_grad_p, unit_area_vec)
                v += vel * np.sqrt(np.dot(area_vect, area_vect))

    def test_if_flux_is_conservative_for_all_volumes(self):
        """Test if flux is conservative for all volumes in the test domain."""
        mb = self.od.mb
        bcVerts = self.od.get_boundary_nodes()
        for bcVert in bcVerts:
            vertCoords = mb.get_coords([bcVert])
            bcVal = self.psol1(vertCoords)
            mb.tag_set_data(self.od.dirichlet_tag, bcVert, bcVal)

        self.node_pressure_tag = self.od_mpfad.mb.tag_get_handle(
            "Node Pressure", 1, types.MB_TYPE_DOUBLE, types.MB_TAG_SPARSE,
            True)
        self.od_mpfad.run_solver(LPEW3(self.od).interpolate)
        p_verts = []
        for node in self.od.all_nodes:
            p_vert = self.od_mpfad.mb.tag_get_data(self.od_mpfad.dirichlet_tag,
                                                   node)
            p_verts.append(p_vert[0])
        self.od_mpfad.mb.tag_set_data(self.node_pressure_tag,
                                      self.od.all_nodes, p_verts)
        for a_volume in self.od.all_volumes:
            vol_centroid = self.od.mtu.get_average_position([a_volume])
            vol_faces = self.od.mtu.get_bridge_adjacencies(a_volume, 2, 2)
            vol_p = self.od.mb.tag_get_data(self.od_mpfad.pressure_tag,
                                            a_volume)[0][0]
            vol_nodes = self.od.mtu.get_bridge_adjacencies(a_volume, 0, 0)
            vol_crds = self.od.mb.get_coords(vol_nodes)
            vol_crds = np.reshape(vol_crds, ([4, 3]))
            vol_volume = self.od.get_tetra_volume(vol_crds)
            vol_perm = self.od.mb.tag_get_data(self.od_mpfad.perm_tag,
                                               a_volume).reshape([3, 3])
            fluxes = []
            for a_face in vol_faces:
                f_nodes = self.od.mtu.get_bridge_adjacencies(a_face, 0, 0)
                fc_nodes = self.od.mb.get_coords(f_nodes)
                fc_nodes = np.reshape(fc_nodes, ([3, 3]))
                grad = np.zeros(3)
                for i in range(len(fc_nodes)):
                    set_of_verts = np.array(
                        [fc_nodes[i], fc_nodes[i - 1], vol_centroid])
                    area_vect = geo._area_vector(set_of_verts,
                                                 fc_nodes[i - 2])[0]
                    p_node_op = self.od_mpfad.mb.tag_get_data(
                        self.node_pressure_tag, f_nodes[i - 2])[0][0]
                    grad += area_vect * p_node_op
                area_vect = geo._area_vector(fc_nodes, vol_centroid)[0]
                grad += area_vect * vol_p
                grad = grad / (3.0 * vol_volume)
                flux = -np.dot(np.dot(vol_perm, grad), area_vect)
                fluxes.append(flux)
            fluxes_sum = abs(sum(fluxes))
            self.assertAlmostEqual(fluxes_sum, 0.0, delta=1e-9)

    @unittest.skip("later")
    def test_if_method_yields_correct_T_matrix(self):
        """Test not well suited."""
        for node in self.m.get_boundary_nodes():
            coords = self.m.mb.get_coords([node])
            g_D = coords[1]**2
            self.m.mb.tag_set_data(self.m.dirichlet_tag, node, g_D)
        volumes = self.m.all_volumes
        source = [
            -0.666666721827,
            -0.666666721827,
            -0.666667091901,
            -0.666667091901,
            -1.33333307358,
        ]
        c = 0
        for volume in volumes:
            self.m.mb.tag_set_data(self.m.perm_tag, volume, self.perm)
            self.m.mb.tag_set_data(self.m.source_tag, volume, source[c])
            c += 1
        self.m_mpfad.run_solver(LPEW3(self.m).interpolate)
Beispiel #15
0
class ObliqueDrain:
    def __init__(self, filename):
        self.mesh = MeshManager(filename, dim=3)
        self.mesh.set_boundary_condition("Dirichlet", {101: None},
                                         dim_target=2,
                                         set_nodes=True)
        self.mesh.set_boundary_condition("Neumann", {201: 0.0},
                                         dim_target=2,
                                         set_nodes=True)

        bed_perm = [
            0.965384615384615,
            0.173076923076923,
            0.0,
            0.173076923076923,
            0.134615384615385,
            0.0,
            0.0,
            0.0,
            1.0,
        ]
        drain_perm = [
            96.538461538461530,
            17.307692307692307,
            0.0,
            17.307692307692307,
            13.461538461538462,
            0.0,
            0.0,
            0.0,
            1.0,
        ]
        self.mesh.set_media_property(
            "Permeability",
            {
                1: bed_perm,
                2: drain_perm,
                3: bed_perm
            },
            dim_target=3,
        )
        self.mesh.set_global_id()
        self.mesh.get_redefine_centre()
        self.mpfad = MpfaD3D(self.mesh)

    def norms_calculator(self, error_vector, volumes_vector, u_vector):
        error_vector = np.array(error_vector)
        volumes_vector = np.array(volumes_vector)
        u_vector = np.array(u_vector)
        l2_norm = np.dot(error_vector, error_vector)**(1 / 2)
        l2_volume_norm = np.dot(error_vector**2, volumes_vector)**(1 / 2)
        erl2 = (np.dot(error_vector**2, volumes_vector) /
                np.dot(u_vector**2, volumes_vector))**(1 / 2)
        avr_error = l2_norm / len(volumes_vector)
        max_error = max(error_vector)
        min_error = min(error_vector)
        results = [
            l2_norm,
            l2_volume_norm,
            erl2,
            avr_error,
            max_error,
            min_error,
        ]
        return results

    def _obliqueDrain(self, x, y):
        return -x - 0.2 * y

    def runCase(self, interpolation_method, log_name):
        for node in self.mesh.get_boundary_nodes():
            x, y, z = self.mesh.mb.get_coords([node])
            g_D = self._obliqueDrain(x, y)
            self.mesh.mb.tag_set_data(self.mesh.dirichlet_tag, node, g_D)
        volumes = self.mesh.all_volumes
        vols = []
        for volume in volumes:
            x, y, _ = self.mesh.mb.tag_get_data(self.mesh.volume_centre_tag,
                                                volume)[0]
            vol_nodes = self.mesh.mb.get_adjacencies(volume, 0)
            vol_nodes_crds = self.mesh.mb.get_coords(vol_nodes)
            vol_nodes_crds = np.reshape(vol_nodes_crds, (4, 3))
            tetra_vol = self.mesh.get_tetra_volume(vol_nodes_crds)
            vols.append(tetra_vol)
        self.mpfad.run_solver(interpolation_method(self.mesh).interpolate)

        for volume in volumes:
            x, y, _ = self.mesh.mb.tag_get_data(self.mesh.volume_centre_tag,
                                                volume)[0]
            analytical_solution = self._obliqueDrain(x, y)
            calculated_solution = self.mpfad.mb.tag_get_data(
                self.mpfad.pressure_tag, volume)[0][0]

        err = []
        u = []
        for volume in volumes:
            x_c, y_c, _ = self.mesh.mb.tag_get_data(
                self.mesh.volume_centre_tag, volume)[0]
            analytical_solution = self._obliqueDrain(x_c, y_c)
            calculated_solution = self.mpfad.mb.tag_get_data(
                self.mpfad.pressure_tag, volume)[0][0]
            err.append(np.absolute(
                (analytical_solution - calculated_solution)))
            u.append(analytical_solution)
        u_max = max(
            self.mpfad.mb.tag_get_data(self.mpfad.pressure_tag, volumes))
        u_min = min(
            self.mpfad.mb.tag_get_data(self.mpfad.pressure_tag, volumes))
        results = self.norms_calculator(err, vols, u)
        non_zero_mat = self.mpfad.T.NumGlobalNonzeros()
        path = ("paper_mpfad_tests/oblique_drain" + log_name + "_" +
                interpolation_method.__name__ + "_log")
        with open(path, "w") as f:
            f.write("TEST CASE 1\n\nUnknowns:\t %.0f\n" % (len(volumes)))
            f.write("Non-zero matrix:\t %.0f\n" % (non_zero_mat))
            f.write("Umin:\t %.6f\n" % (u_min))
            f.write("Umax:\t %.6f\n" % (u_max))
            f.write("L2 norm:\t %.6g\n" % ((results[0])))
            f.write("l2 norm volume weighted:\t %.6g\n" % (results[1]))
            f.write("Relative L2 norm:\t %.6g\n" % (results[2]))
            f.write("average error:\t %.6g\n" % (results[3]))
            f.write("maximum error:\t %.6g\n" % (results[4]))
            f.write("minimum error:\t %.6g\n" % (results[5]))

        print(
            "min u: ",
            u_min[0],
            "max u: ",
            u_max[0],
            "l-2 relative norm: ",
            results[2],
            "non-Zero mat",
            non_zero_mat,
            "ue min",
            min(u),
            "ue max",
            max(u),
        )
        path = "paper_mpfad_tests/oblique_drain/oblique_drain_"
        self.mpfad.record_data(path + log_name + "_" +
                               interpolation_method.__name__ + ".vtk")
        print("END OF " + log_name + "!!!\n")
Beispiel #16
0
class DiscreteMaxPrinciple:
    def __init__(self, filename, interpolation_method):
        self.mesh = MeshManager(filename, dim=3)
        self.mesh.set_global_id()
        self.mesh.get_redefine_centre()
        self.mx = 2.0
        self.mn = 0.0
        self.mesh.set_boundary_condition(
            "Dirichlet",
            {
                51: self.mx,
                10: self.mn
            },
            dim_target=2,
            set_nodes=True,
        )
        self.mpfad = MpfaD3D(self.mesh)
        self.im = interpolation_method(self.mesh)
        self.precond = LSW(self.mesh)

    def rotation_matrix(self, theta, axis=0):
        """
        Return the rotation matrix.

        Arguments:
        double theta = angle (in radians) for the rotation
        int axis = axis for rotation

        retuns a numpy array with shape [3, 3]
        """
        R_matrix = np.zeros([3, 3])
        cos = np.cos(theta)
        sin = np.sin(theta)

        if axis == 0:
            R_matrix = np.array([1, 0, 0, 0, cos, -sin, 0, sin, cos])
        if axis == 1:
            R_matrix = np.array([cos, 0, sin, 0, 1, 0, -sin, 0, cos])
        else:
            R_matrix = np.array([cos, -sin, 0, sin, cos, 0, 0, 0, 1])

        R_matrix = R_matrix.reshape([3, 3])
        return R_matrix

    def get_perm_tensor(self):
        R_x = self.rotation_matrix(-np.pi / 3, axis=0)
        R_y = self.rotation_matrix(-np.pi / 4, axis=1)
        R_z = self.rotation_matrix(-np.pi / 6, axis=2)
        R_xyz = np.matmul(np.matmul(R_z, R_y), R_x)
        perm = np.diag([300, 15, 1])
        perm = np.matmul(np.matmul(R_xyz, perm),
                         R_xyz.transpose()).reshape([1, 9])[0]

        perms = []
        for volume in self.mesh.all_volumes:
            perms.append(perm)
        self.mesh.mb.tag_set_data(self.mesh.perm_tag, self.mesh.all_volumes,
                                  perms)

    def run_dmp(self, log_name):
        self.get_perm_tensor()
        # precond = self.mpfad.run_solver(self.precond.interpolate)
        # x = self.mpfad.x
        self.mpfad = MpfaD3D(self.mesh)
        self.mpfad.run_solver(self.im.interpolate)
        max_p = max(self.mpfad.x)
        min_p = min(self.mpfad.x)
        volumes = self.mesh.all_volumes
        oversh = []
        undersh = []
        for volume in volumes:
            pressure = self.mesh.mb.tag_get_data(self.mesh.pressure_tag,
                                                 volume)[0][0]
            x, y, z = self.mesh.mb.tag_get_data(self.mesh.volume_centre_tag,
                                                volume)[0]
            vol_nodes = self.mesh.mb.get_adjacencies(volume, 0)
            vol_nodes_crds = self.mesh.mb.get_coords(vol_nodes)
            vol_nodes_crds = np.reshape(vol_nodes_crds, (4, 3))
            tetra_vol = self.mesh.get_tetra_volume(vol_nodes_crds)
            eps_mx = max(pressure - self.mx, 0.0)**2
            oversh.append(eps_mx * tetra_vol)
            eps_mn = min(pressure - self.mn, 0.0)**2
            undersh.append(eps_mn * tetra_vol)
        overshooting = sum(oversh)**(1 / 2.0)
        undershooting = sum(undersh)**(1 / 2.0)
        print(max_p, min_p, sum(oversh)**(1 / 2.0), sum(undersh)**(1 / 2.0))

        path = "paper_mpfad_tests/dmp_tests/" + log_name
        with open(path + "_log", "w") as f:
            f.write("\nUnknowns:\t %.0f\n" % (len(self.mesh.all_volumes)))
            f.write("Umin:\t %.6f\n" % (min_p))
            f.write("Umax:\t %.6f\n" % (max_p))
            f.write("Overshooting:\t %.6f\n" % (overshooting))
            f.write("Undershooting:\t %.6f\n" % (undershooting))
            f.write("Non-zero matrix:\t %.0f\n" %
                    (self.mpfad.T.NumGlobalNonzeros()))
        self.mpfad.record_data(path + ".vtk")

    def perm_tensor_lai(self, x, y, z):
        e = 5e-3

        k = np.asarray([
            y**2 + e * x**2,
            -(1 - e) * x * y,
            0,
            -(1 - e) * x * y,
            x**2 + e * y**2,
            0,
            0.0,
            0.0,
            1.0,
        ])
        return k

    def run_lai_sheng_dmp_test(self):
        all_volumes = self.mesh.all_volumes
        for volume in all_volumes:
            x, y, z = self.mesh.mb.get_coords(volume)
            perm = self.perm_tensor_lai(x, y, z)
            self.mesh.mb.tag_set_data(self.mesh.perm_tag, volume, perm)
            if x < 5 / 8 and x > 3 / 8 and y < 5 / 8 and y > 3 / 8:
                source_term = 1.0
                self.mesh.mb.tag_set_data(self.mesh.source_tag, volume,
                                          source_term)
            else:
                source_term = 0.0
                self.mesh.mb.tag_set_data(self.mesh.source_tag, volume,
                                          source_term)
        self.mpfad.run_solver(self.im.interpolate)
        solution = self.mesh.mb.tag_get_data(self.mesh.pressure_tag,
                                             all_volumes)
        print("min: ", min(solution), "max: ", max(solution))
    def setUp(self):
        """Init test suite."""
        K_1 = np.array([1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0])

        K_2 = np.array([2.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 2.0])

        self.mesh_1 = MeshManager("meshes/mesh_test_1.msh", dim=3)
        self.mesh_1.set_media_property("Permeability", {1: K_1}, dim_target=3)
        self.mesh_1.set_boundary_condition("Dirichlet", {
            102: 1.0,
            101: 0.0
        },
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_1.set_boundary_condition("Neumann", {201: 0.0},
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_1.get_redefine_centre()
        self.mpfad_1 = MpfaD3D(self.mesh_1)

        self.mesh_2 = MeshManager("meshes/mesh_test_2.msh", dim=3)
        self.mesh_2.set_media_property("Permeability", {1: K_1}, dim_target=3)
        self.mesh_2.set_boundary_condition("Dirichlet", {
            102: 1.0,
            101: 0.0
        },
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_2.set_boundary_condition("Neumann", {201: 0.0},
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_2.set_global_id()
        self.mesh_2.get_redefine_centre()
        self.mpfad_2 = MpfaD3D(self.mesh_2)

        self.mesh_4 = MeshManager("meshes/mesh_test_7.msh", dim=3)
        self.mesh_4.set_media_property("Permeability", {1: K_1}, dim_target=3)
        self.mesh_4.set_boundary_condition("Dirichlet", {
            102: 1.0,
            101: 0.0
        },
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_4.set_boundary_condition("Neumann", {201: 0.0},
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_4.set_global_id()
        self.mesh_4.get_redefine_centre()
        self.mpfad_4 = MpfaD3D(self.mesh_4)

        self.mesh_5 = MeshManager("meshes/geometry_two_regions_test.msh",
                                  dim=3)
        self.mesh_5.set_media_property("Permeability", {
            1: K_2,
            2: K_1
        },
                                       dim_target=3)
        self.mesh_5.set_boundary_condition("Dirichlet", {
            102: 1.0,
            101: 0.0
        },
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_5.set_boundary_condition("Neumann", {201: 0.0},
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_5.get_redefine_centre()
        self.mesh_5.set_global_id()
        self.mpfad_5 = MpfaD3D(self.mesh_5)

        self.mesh_6 = MeshManager("meshes/mesh_test_6.msh", dim=3)
        self.mesh_6.set_media_property("Permeability", {1: K_1}, dim_target=3)
        self.mesh_6.set_boundary_condition("Dirichlet", {102: 1.0},
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_6.set_boundary_condition("Neumann", {
            202: 1.0,
            201: 0.0
        },
                                           dim_target=2,
                                           set_nodes=True)
        self.mesh_6.get_redefine_centre()
        self.mesh_6.set_global_id()
        self.mpfad_6 = MpfaD3D(self.mesh_6)