Exemple #1
0
 def lambda_lpew3(self, node, aux_node, face):
     # Should include tao parameter in order to change interpolation region
     adj_vols = self.mtu.get_bridge_adjacencies(face, 2, 3)
     face_nodes = self.mtu.get_bridge_adjacencies(face, 2, 0)
     ref_node = list(set(face_nodes) - (set([node]) | set([aux_node])))
     face_nodes_crds = self.mb.get_coords(face_nodes)
     face_nodes_crds = np.reshape(face_nodes_crds, (3, 3))
     ref_node = self.mb.get_coords(ref_node)
     aux_node = self.mb.get_coords([aux_node])
     node = self.mb.get_coords([node])
     lambda_l = 0.0
     for a_vol in adj_vols:
         vol_perm = self.mb.tag_get_data(self.perm_tag, a_vol)
         vol_perm = np.reshape(vol_perm, (3, 3))
         vol_cent = self.mesh_data.mb.tag_get_data(
             self.mesh_data.volume_centre_tag, a_vol)[0]
         vol_nodes = self.mb.get_adjacencies(a_vol, 0)
         sub_vol = np.append(face_nodes_crds, vol_cent)
         sub_vol = np.reshape(sub_vol, (4, 3))
         tetra_vol = self.mesh_data.get_tetra_volume(sub_vol)
         ref_node_i = list(set(vol_nodes) - set(face_nodes))
         ref_node_i = self.mb.get_coords(ref_node_i)
         N_int = geo._area_vector([node, aux_node, vol_cent], ref_node)[0]
         N_i = geo._area_vector(face_nodes_crds, ref_node_i)[0]
         lambda_l += self.flux_term(N_i, vol_perm, N_int) / tetra_vol
     return lambda_l
    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)
Exemple #3
0
 def sigma_lpew3(self, node, vol):
     node_crds = self.mb.get_coords([node])
     adj_faces = set(self.mtu.get_bridge_adjacencies(node, 0, 2))
     vol_faces = set(self.mtu.get_bridge_adjacencies(vol, 3, 2))
     in_faces = list(adj_faces & vol_faces)
     vol_cent = self.mesh_data.mb.tag_get_data(
         self.mesh_data.volume_centre_tag, vol)[0]
     clockwise = 1.0
     counter_clockwise = 1.0
     for a_face in in_faces:
         aux_nodes = set(self.mtu.get_bridge_adjacencies(a_face, 2, 0))
         aux_nodes.remove(node)
         aux_nodes = list(aux_nodes)
         aux_nodes_crds = self.mb.get_coords(aux_nodes)
         aux_nodes_crds = np.reshape(aux_nodes_crds, (2, 3))
         aux_vect = [node_crds, aux_nodes_crds[0], aux_nodes_crds[1]]
         spin = geo._area_vector(aux_vect, vol_cent)[1]
         if spin < 0:
             aux_nodes[0], aux_nodes[1] = aux_nodes[1], aux_nodes[0]
         count = self.lambda_lpew3(node, aux_nodes[0], a_face)
         counter_clockwise = counter_clockwise * count
         clock = self.lambda_lpew3(node, aux_nodes[1], a_face)
         clockwise = clockwise * clock
     sigma = clockwise + counter_clockwise
     return sigma
Exemple #4
0
 def neta_lpew3(self, node, vol, face):
     vol_perm = self.mb.tag_get_data(self.perm_tag, vol)
     vol_perm = np.reshape(vol_perm, (3, 3))
     vol_nodes = self.mb.get_adjacencies(vol, 0)
     face_nodes = self.mtu.get_bridge_adjacencies(face, 2, 0)
     face_nodes_crds = self.mb.get_coords(face_nodes)
     face_nodes_crds = np.reshape(face_nodes_crds, (3, 3))
     ref_node = list(set(vol_nodes) - set(face_nodes))
     ref_node = self.mb.get_coords(ref_node)
     vol_nodes_crds = self.mb.get_coords(list(vol_nodes))
     vol_nodes_crds = np.reshape(vol_nodes_crds, (4, 3))
     tetra_vol = self.mesh_data.get_tetra_volume(vol_nodes_crds)
     vol_nodes = set(vol_nodes)
     vol_nodes.remove(node)
     face_nodes_i = self.mb.get_coords(list(vol_nodes))
     face_nodes_i = np.reshape(face_nodes_i, (3, 3))
     node = self.mb.get_coords([node])
     N_out = geo._area_vector(face_nodes_i, node)[0]
     N_i = geo._area_vector(face_nodes_crds, ref_node)[0]
     neta = self.flux_term(N_out, vol_perm, N_i) / tetra_vol
     return neta
Exemple #5
0
 def csi_lpew3(self, face, vol):
     vol_perm = self.mb.tag_get_data(self.perm_tag, vol)
     vol_perm = np.reshape(vol_perm, (3, 3))
     vol_cent = self.mesh_data.mb.tag_get_data(
         self.mesh_data.volume_centre_tag, vol)[0]
     face_nodes = self.mtu.get_bridge_adjacencies(face, 2, 0)
     face_nodes = self.mb.get_coords(face_nodes)
     face_nodes = np.reshape(face_nodes, (3, 3))
     N_i = geo._area_vector(face_nodes, vol_cent)[0]
     sub_vol = np.append(face_nodes, vol_cent)
     sub_vol = np.reshape(sub_vol, (4, 3))
     tetra_vol = self.mesh_data.get_tetra_volume(sub_vol)
     csi = self.flux_term(N_i, vol_perm, N_i) / tetra_vol
     return csi
Exemple #6
0
 def neumann_treatment(self, node):
     adj_faces = self.mtu.get_bridge_adjacencies(node, 0, 2)
     N_term_sum = 0.0
     for face in adj_faces:
         if face not in self.neumann_faces:
             continue
         face_flux = self.mb.tag_get_data(self.neumann_tag, face)[0][0]
         face_nodes = self.mb.get_adjacencies(face, 0)
         nodes_crds = self.mb.get_coords(face_nodes)
         nodes_crds = np.reshape(nodes_crds, (len(face_nodes), 3))
         face_area = geo._area_vector(nodes_crds,
                                      np.array([0.0, 0.0, 0.0]),
                                      norma=True)
         # store face_area
         vol_N = tuple(self.mtu.get_bridge_adjacencies(face, 2, 3))
         psi_N = self.psi_sum_lpew3(node, vol_N, face)
         phi_N = self.phi_lpew3(node, vol_N, face)
         N_term = -3.0 * (1 + (psi_N - phi_N)) * face_flux * face_area
         N_term_sum += N_term
     return N_term_sum
Exemple #7
0
    def run_solver(self, interpolation_method):
        """Run solver."""
        self.interpolation_method = interpolation_method
        t0 = time.time()
        n_vertex = len(set(self.mesh_data.all_nodes) - self.dirichlet_nodes)
        print("interpolation runing...")
        self.get_nodes_weights(interpolation_method)
        print(
            "done interpolation...",
            "took {0} seconds to interpolate over {1} verts".format(
                time.time() - t0, n_vertex
            ),
        )
        print("filling the transmissibility matrix...")
        begin = time.time()

        try:
            for volume in self.volumes:
                volume_id = self.mb.tag_get_data(self.global_id_tag, volume)[
                    0
                ][0]
                RHS = self.mb.tag_get_data(self.source_tag, volume)[0][0]
                self.Q[volume_id] += RHS
                # self.Q[volume_id, 0] += RHS
        except Exception:
            pass

        for face in self.neumann_faces:
            face_flow = self.mb.tag_get_data(self.neumann_tag, face)[0][0]
            volume = self.mtu.get_bridge_adjacencies(face, 2, 3)
            volume = np.asarray(volume, dtype="uint64")
            id_volume = self.mb.tag_get_data(self.global_id_tag, volume)[0][0]
            face_nodes = self.mtu.get_bridge_adjacencies(face, 0, 0)
            node_crds = self.mb.get_coords(face_nodes).reshape([3, 3])
            face_area = geo._area_vector(node_crds, norma=True)
            RHS = face_flow * face_area
            self.Q[id_volume] += -RHS
            # self.Q[id_volume, 0] += - RHS

        id_volumes = []
        all_LHS = []
        for face in self.dirichlet_faces:
            # '2' argument was initially '0' but it's incorrect
            I, J, K = self.mtu.get_bridge_adjacencies(face, 2, 0)

            left_volume = np.asarray(
                self.mtu.get_bridge_adjacencies(face, 2, 3), dtype="uint64"
            )
            id_volume = self.mb.tag_get_data(self.global_id_tag, left_volume)[
                0
            ][0]
            id_volumes.append(id_volume)

            JI = self.mb.get_coords([I]) - self.mb.get_coords([J])
            JK = self.mb.get_coords([K]) - self.mb.get_coords([J])
            LJ = (
                self.mb.get_coords([J])
                - self.mesh_data.mb.tag_get_data(
                    self.volume_centre_tag, left_volume
                )[0]
            )
            N_IJK = np.cross(JI, JK) / 2.0
            _test = np.dot(LJ, N_IJK)
            if _test < 0.0:
                I, K = K, I
                JI = self.mb.get_coords([I]) - self.mb.get_coords([J])
                JK = self.mb.get_coords([K]) - self.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)
            self.mb.tag_set_data(self.normal_tag, face, N_IJK)

            face_area = np.sqrt(np.dot(N_IJK, N_IJK))
            h_L = geo.get_height(N_IJK, LJ)

            g_I = self.get_boundary_node_pressure(I)
            g_J = self.get_boundary_node_pressure(J)
            g_K = self.get_boundary_node_pressure(K)

            K_L = self.mb.tag_get_data(self.perm_tag, left_volume).reshape(
                [3, 3]
            )
            K_n_L = self.vmv_multiply(N_IJK, K_L, N_IJK)
            K_L_JI = self.vmv_multiply(N_IJK, K_L, tan_JI)
            K_L_JK = self.vmv_multiply(N_IJK, K_L, tan_JK)

            D_JK = self.get_cross_diffusion_term(
                tan_JK, LJ, face_area, h_L, K_n_L, K_L_JK, boundary=True
            )
            D_JI = self.get_cross_diffusion_term(
                tan_JI, LJ, face_area, h_L, K_n_L, K_L_JI, boundary=True
            )
            K_eq = (1 / h_L) * (face_area * K_n_L)

            RHS = D_JK * (g_I - g_J) - K_eq * g_J + D_JI * (g_J - g_K)
            LHS = K_eq
            all_LHS.append(LHS)

            self.Q[id_volume] += -RHS
            # self.Q[id_volume, 0] += - RHS
            # self.mb.tag_set_data(self.flux_info_tag, face,
            #                      [D_JK, D_JI, K_eq, I, J, K, face_area])

        all_cols = []
        all_rows = []
        all_values = []
        self.ids = []
        self.v_ids = []
        self.ivalues = []
        for face in self.intern_faces:
            left_volume, right_volume = self.mtu.get_bridge_adjacencies(
                face, 2, 3
            )
            L = self.mesh_data.mb.tag_get_data(
                self.volume_centre_tag, left_volume
            )[0]
            R = self.mesh_data.mb.tag_get_data(
                self.volume_centre_tag, right_volume
            )[0]
            dist_LR = R - L
            I, J, K = self.mtu.get_bridge_adjacencies(face, 0, 0)
            JI = self.mb.get_coords([I]) - self.mb.get_coords([J])
            JK = self.mb.get_coords([K]) - self.mb.get_coords([J])

            N_IJK = np.cross(JI, JK) / 2.0
            test = np.dot(N_IJK, dist_LR)

            if test < 0:
                left_volume, right_volume = right_volume, left_volume
                L = self.mesh_data.mb.tag_get_data(
                    self.volume_centre_tag, left_volume
                )[0]
                R = self.mesh_data.mb.tag_get_data(
                    self.volume_centre_tag, right_volume
                )[0]
                dist_LR = R - L

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

            K_R = self.mb.tag_get_data(self.perm_tag, right_volume).reshape(
                [3, 3]
            )
            RJ = R - self.mb.get_coords([J])
            h_R = geo.get_height(N_IJK, RJ)

            K_R_n = self.vmv_multiply(N_IJK, K_R, N_IJK)
            K_R_JI = self.vmv_multiply(N_IJK, K_R, tan_JI)
            K_R_JK = self.vmv_multiply(N_IJK, K_R, tan_JK)

            K_L = self.mb.tag_get_data(self.perm_tag, left_volume).reshape(
                [3, 3]
            )

            LJ = L - self.mb.get_coords([J])
            h_L = geo.get_height(N_IJK, LJ)

            K_L_n = self.vmv_multiply(N_IJK, K_L, N_IJK)
            K_L_JI = self.vmv_multiply(N_IJK, K_L, tan_JI)
            K_L_JK = self.vmv_multiply(N_IJK, K_L, tan_JK)

            D_JI = self.get_cross_diffusion_term(
                tan_JI,
                dist_LR,
                face_area,
                h_L,
                K_L_n,
                K_L_JI,
                h_R,
                K_R_JI,
                K_R_n,
            )
            D_JK = self.get_cross_diffusion_term(
                tan_JK,
                dist_LR,
                face_area,
                h_L,
                K_L_n,
                K_L_JK,
                h_R,
                K_R_JK,
                K_R_n,
            )

            K_eq = (K_R_n * K_L_n) / (K_R_n * h_L + K_L_n * h_R) * face_area

            id_right = self.mb.tag_get_data(self.global_id_tag, right_volume)
            id_left = self.mb.tag_get_data(self.global_id_tag, left_volume)

            col_ids = [id_right, id_right, id_left, id_left]
            row_ids = [id_right, id_left, id_left, id_right]
            values = [K_eq, -K_eq, K_eq, -K_eq]
            all_cols.append(col_ids)
            all_rows.append(row_ids)
            all_values.append(values)
            # wait for interpolation to be done
            self._node_treatment(I, id_left, id_right, K_eq, D_JK=D_JK)
            self._node_treatment(
                J, id_left, id_right, K_eq, D_JI=D_JI, D_JK=-D_JK
            )
            self._node_treatment(K, id_left, id_right, K_eq, D_JI=-D_JI)
            # self.mb.tag_set_data(self.flux_info_tag, face,
            #                      [D_JK, D_JI, K_eq, I, J, K, face_area])

        self.T.InsertGlobalValues(self.ids, self.v_ids, self.ivalues)
        # self.T[
        #     np.asarray(self.ids)[:, :, 0, 0], np.asarray(self.v_ids)
        # ] = np.asarray(self.ivalues)
        self.T.InsertGlobalValues(id_volumes, id_volumes, all_LHS)
        # self.T[
        #     np.asarray(id_volumes), np.asarray(id_volumes)
        # ] = np.asarray(all_LHS)
        self.T.InsertGlobalValues(all_cols, all_rows, all_values)
        # self.T[
        #     np.asarray(all_cols)[:, 0, 0, 0],
        #     np.asarray(all_rows)[:, 0, 0, 0]
        # ] = np.asarray(all_values)[:, 0]
        self.T.FillComplete()
        mat_fill_time = time.time() - begin
        print("matrix fill took {0} seconds...".format(mat_fill_time))
        mesh_size = len(self.volumes)
        print("running solver...")
        USE_DIRECT_SOLVER = False
        linearProblem = Epetra.LinearProblem(self.T, self.x, self.Q)
        if USE_DIRECT_SOLVER:
            solver = Amesos.Lapack(linearProblem)
            print("1) Performing symbolic factorizations...")
            solver.SymbolicFactorization()
            print("2) Performing numeric factorizations...")
            solver.NumericFactorization()
            print("3) Solving the linear system...")
            solver.Solve()
            t = time.time() - t0
            print(
                "Solver took {0} seconds to run over {1} volumes".format(
                    t, mesh_size
                )
            )
        else:
            solver = AztecOO.AztecOO(linearProblem)
            solver.SetAztecOption(AztecOO.AZ_solver, AztecOO.AZ_gmres)
            solver.SetAztecOption(AztecOO.AZ_output, AztecOO.AZ_none)
            # solver.SetAztecOption(AztecOO.AZ_precond, AztecOO.AZ_Jacobi)
            # solver.SetAztecOption(AztecOO.AZ_kspace, 1251)
            # solver.SetAztecOption(AztecOO.AZ_orthog, AztecOO.AZ_modified)
            # solver.SetAztecOption(AztecOO.AZ_conv, AztecOO.AZ_Anorm)
            solver.Iterate(8000, 1e-10)
            t = time.time() - t0
            its = solver.GetAztecStatus()[0]
            solver_time = solver.GetAztecStatus()[6]
            print(
                "Solver took {0} seconds to run over {1} volumes".format(
                    t, mesh_size
                )
            )
            print(
                "Solver converged at %.dth iteration in %3f seconds."
                % (int(its), solver_time)
            )
        # self.T = self.T.tocsc()
        # self.Q = self.Q.tocsc()
        # self.x = spsolve(self.T, self.Q)
        # print(np.sum(self.T[50]), self.Q[50])
        self.mb.tag_set_data(self.pressure_tag, self.volumes, self.x)
Exemple #8
0
    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 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))
Exemple #10
0
    def tag_velocity(self):
        self.tag_verts_pressure()
        velocities = []
        for face in self.neumann_faces:
            face_mobility = self.mb.tag_get_data(self.face_mobility_tag,
                                                 face)[0][0]
            face_flow = self.mb.tag_get_data(self.neumann_tag, face)[0][0]
            volume = self.mtu.get_bridge_adjacencies(face, 2, 3)
            volume = np.asarray(volume, dtype="uint64")
            face_nodes = self.mtu.get_bridge_adjacencies(face, 0, 0)
            node_crds = self.mb.get_coords(face_nodes).reshape([3, 3])
            face_area = geo._area_vector(node_crds, norma=True)
            velocity = face_mobility * face_flow * face_area
            velocities.append(velocity)
        self.mb.tag_set_data(self.velocity_tag, self.neumann_faces, velocities)

        velocities = []
        dirichlet_faces = list(self.dirichlet_faces)
        for face in dirichlet_faces:
            face_mobility = self.mb.tag_get_data(self.face_mobility_tag,
                                                 face)[0][0]
            # '2' argument was initially '0' but it's incorrect
            I, J, K = self.mtu.get_bridge_adjacencies(face, 2, 0)

            left_volume = np.asarray(self.mtu.get_bridge_adjacencies(
                face, 2, 3),
                                     dtype="uint64")

            JI = self.mb.get_coords([I]) - self.mb.get_coords([J])
            JK = self.mb.get_coords([K]) - self.mb.get_coords([J])
            LJ = (self.mb.get_coords([J]) - self.mesh_data.mb.tag_get_data(
                self.volume_centre_tag, left_volume)[0])
            N_IJK = np.cross(JI, JK) / 2.0
            _test = np.dot(LJ, N_IJK)
            if _test < 0.0:
                I, K = K, I
                JI = self.mb.get_coords([I]) - self.mb.get_coords([J])
                JK = self.mb.get_coords([K]) - self.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)
            self.mb.tag_set_data(self.normal_tag, face, N_IJK)

            face_area = np.sqrt(np.dot(N_IJK, N_IJK))
            h_L = geo.get_height(N_IJK, LJ)

            g_I = self.mb.tag_get_data(self.node_pressure_tag, I)
            g_J = self.mb.tag_get_data(self.node_pressure_tag, J)
            g_K = self.mb.tag_get_data(self.node_pressure_tag, K)

            K_L = self.mb.tag_get_data(self.perm_tag,
                                       left_volume).reshape([3, 3])
            K_n_L = self.vmv_multiply(N_IJK, face_mobility * K_L, N_IJK)
            K_L_JI = self.vmv_multiply(N_IJK, face_mobility * K_L, tan_JI)
            K_L_JK = self.vmv_multiply(N_IJK, face_mobility * K_L, tan_JK)

            D_JK = self.get_cross_diffusion_term(tan_JK,
                                                 LJ,
                                                 face_area,
                                                 h_L,
                                                 K_n_L,
                                                 K_L_JK,
                                                 boundary=True)
            D_JI = self.get_cross_diffusion_term(tan_JI,
                                                 LJ,
                                                 face_area,
                                                 h_L,
                                                 K_n_L,
                                                 K_L_JI,
                                                 boundary=True)
            K_eq = (1 / h_L) * (face_area * K_n_L)
            p_vol = self.mb.tag_get_data(self.pressure_tag, left_volume)
            velocity = (D_JK * (g_I - g_J) - K_eq * (p_vol - g_J) + D_JI *
                        (g_J - g_K))
            velocities.append(velocity)
        vels = np.asarray(velocities).flatten()
        self.mb.tag_set_data(self.velocity_tag, dirichlet_faces, vels)
        velocities = []
        left_vols = []
        intern_faces = list(self.intern_faces)
        for face in intern_faces:
            face_mobility = self.mb.tag_get_data(self.face_mobility_tag,
                                                 face)[0][0]
            left_volume, right_volume = self.mtu.get_bridge_adjacencies(
                face, 2, 3)
            L = self.mesh_data.mb.tag_get_data(self.volume_centre_tag,
                                               left_volume)[0]
            R = self.mesh_data.mb.tag_get_data(self.volume_centre_tag,
                                               right_volume)[0]
            dist_LR = R - L
            I, J, K = self.mtu.get_bridge_adjacencies(face, 0, 0)
            JI = self.mb.get_coords([I]) - self.mb.get_coords([J])
            JK = self.mb.get_coords([K]) - self.mb.get_coords([J])

            N_IJK = np.cross(JI, JK) / 2.0
            test = np.dot(N_IJK, dist_LR)

            if test < 0:
                left_volume, right_volume = right_volume, left_volume
                L = self.mesh_data.mb.tag_get_data(self.volume_centre_tag,
                                                   left_volume)[0]
                R = self.mesh_data.mb.tag_get_data(self.volume_centre_tag,
                                                   right_volume)[0]
                dist_LR = R - L

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

            K_R = self.mb.tag_get_data(self.perm_tag,
                                       right_volume).reshape([3, 3])
            RJ = R - self.mb.get_coords([J])
            h_R = geo.get_height(N_IJK, RJ)

            K_R_n = self.vmv_multiply(N_IJK, face_mobility * K_R, N_IJK)
            K_R_JI = self.vmv_multiply(N_IJK, face_mobility * K_R, tan_JI)
            K_R_JK = self.vmv_multiply(N_IJK, face_mobility * K_R, tan_JK)

            K_L = self.mb.tag_get_data(self.perm_tag,
                                       left_volume).reshape([3, 3])

            LJ = L - self.mb.get_coords([J])
            h_L = geo.get_height(N_IJK, LJ)

            K_L_n = self.vmv_multiply(N_IJK, face_mobility * K_L, N_IJK)
            K_L_JI = self.vmv_multiply(N_IJK, face_mobility * K_L, tan_JI)
            K_L_JK = self.vmv_multiply(N_IJK, face_mobility * K_L, tan_JK)

            D_JI = self.get_cross_diffusion_term(
                tan_JI,
                dist_LR,
                face_area,
                h_L,
                K_L_n,
                K_L_JI,
                h_R,
                K_R_JI,
                K_R_n,
            )
            D_JK = self.get_cross_diffusion_term(
                tan_JK,
                dist_LR,
                face_area,
                h_L,
                K_L_n,
                K_L_JK,
                h_R,
                K_R_JK,
                K_R_n,
            )

            K_eq = (K_R_n * K_L_n) / (K_R_n * h_L + K_L_n * h_R) * face_area
            p_r = self.mb.tag_get_data(self.pressure_tag, right_volume)
            p_l = self.mb.tag_get_data(self.pressure_tag, left_volume)
            p_I = self.mb.tag_get_data(self.node_pressure_tag, I)
            p_J = self.mb.tag_get_data(self.node_pressure_tag, J)
            p_K = self.mb.tag_get_data(self.node_pressure_tag, K)
            velocity = K_eq * (p_r - p_l - D_JI * (p_I - p_J) - D_JK *
                               (p_K - p_J))
            velocities.append(velocity)
            left_vols.append(left_volume)
        velocities = np.asarray(velocities).flatten()
        self.mb.tag_set_data(self.velocity_tag, intern_faces, velocities)
        self.mb.tag_set_data(self.left_volume_tag, left_vols,
                             np.repeat(1, len(left_vols)))
Exemple #11
0
    def run_solver(self, interpolation_method):
        """Run solver."""
        self.get_mobility()
        self.interpolation_method = interpolation_method
        t0 = time.time()
        n_vertex = len(set(self.mesh_data.all_nodes) - self.dirichlet_nodes)
        print("interpolation runing...")
        self.get_nodes_weights(interpolation_method)
        print(
            "done interpolation...",
            "took {0} seconds to interpolate over {1} verts".format(
                time.time() - t0, n_vertex
            ),
        )
        print("filling the transmissibility matrix...")
        # begin = time.time()

        try:
            for volume in self.volumes:
                volume_id = self.mb.tag_get_data(self.global_id_tag, volume)[
                    0
                ][0]
                RHS = self.mb.tag_get_data(self.source_tag, volume)[0][0]
                # self.Q[volume_id] += RHS
                self.Q[volume_id, 0] += RHS
        except Exception:
            pass

        for face in self.neumann_faces:
            face_mobility = self.mb.tag_get_data(self.face_mobility_tag, face)[
                0
            ][0]
            face_flow = self.mb.tag_get_data(self.neumann_tag, face)[0][0]
            volume = self.mtu.get_bridge_adjacencies(face, 2, 3)
            volume = np.asarray(volume, dtype="uint64")
            id_volume = self.mb.tag_get_data(self.global_id_tag, volume)[0][0]
            face_nodes = self.mtu.get_bridge_adjacencies(face, 0, 0)
            node_crds = self.mb.get_coords(face_nodes).reshape([3, 3])
            face_area = geo._area_vector(node_crds, norma=True)
            RHS = face_mobility * face_flow * face_area
            # self.Q[id_volume] += -RHS
            self.Q[id_volume, 0] += -RHS

        id_volumes = []
        all_LHS = []
        antidiffusive_flux = {}
        for face in self.dirichlet_faces:
            face_mobility = self.mb.tag_get_data(
                self.face_mobility_tag, face
            )[0][0]
            # '2' argument was initially '0' but it's incorrect
            I, J, K = self.mtu.get_bridge_adjacencies(face, 2, 0)

            left_volume = np.asarray(
                self.mtu.get_bridge_adjacencies(face, 2, 3), dtype="uint64"
            )
            id_volume = self.mb.tag_get_data(
                self.global_id_tag, left_volume
            )[0][0]
            id_volumes.append(id_volume)

            JI = self.mb.get_coords([I]) - self.mb.get_coords([J])
            JK = self.mb.get_coords([K]) - self.mb.get_coords([J])
            LJ = (
                self.mb.get_coords([J])
                - self.mesh_data.mb.tag_get_data(
                    self.volume_centre_tag, left_volume
                )[0]
            )
            N_IJK = np.cross(JI, JK) / 2.0
            _test = np.dot(LJ, N_IJK)
            if _test < 0.0:
                I, K = K, I
                JI = self.mb.get_coords([I]) - self.mb.get_coords([J])
                JK = self.mb.get_coords([K]) - self.mb.get_coords([J])
                N_IJK = np.cross(JI, JK) / 2.0
            #  calc_grad(I, J, K, vol_left, vol_right=none)
            tan_JI = np.cross(N_IJK, JI)
            tan_JK = np.cross(N_IJK, JK)
            self.mb.tag_set_data(self.normal_tag, face, N_IJK)

            face_area = np.sqrt(np.dot(N_IJK, N_IJK))
            h_L = geo.get_height(N_IJK, LJ)

            g_I = self.get_boundary_node_pressure(I)
            g_J = self.get_boundary_node_pressure(J)
            g_K = self.get_boundary_node_pressure(K)

            K_L = self.mb.tag_get_data(self.perm_tag, left_volume).reshape(
                [3, 3]
            )
            K_n_L = self.vmv_multiply(N_IJK, face_mobility * K_L, N_IJK)
            K_L_JI = self.vmv_multiply(N_IJK, face_mobility * K_L, tan_JI)
            K_L_JK = self.vmv_multiply(N_IJK, face_mobility * K_L, tan_JK)

            D_JK = self.get_cross_diffusion_term(
                tan_JK, LJ, face_area, h_L, K_n_L, K_L_JK, boundary=True
            )
            D_JI = self.get_cross_diffusion_term(
                tan_JI, LJ, face_area, h_L, K_n_L, K_L_JI, boundary=True
            )
            K_eq = (1 / h_L) * (face_area * K_n_L)

            RHS = D_JK * (g_I - g_J) - K_eq * g_J + D_JI * (g_J - g_K)
            LHS = K_eq
            all_LHS.append(LHS)
            if id_volume not in antidiffusive_flux.keys():
                antidiffusive_flux[id_volume] = []
            fluxes = OrderedDict(
                {
                    I: [g_I, D_JK],
                    J: [g_J, -D_JK + D_JI - K_eq],
                    K: [g_K, -D_JI],
                }
            )
            antidiffusive_flux[id_volume].append(fluxes)
            # self.Q[id_volume] += -RHS
            self.Q[id_volume, 0] += -RHS
            # self.T_expanded[:len(self.volumes), len(self.volumes):len(self.u)] * self.u[len(self.volumes):]
            # self.mb.tag_set_data(self.flux_info_tag, face,
            #                      [D_JK, D_JI, K_eq, I, J, K, face_area])
            i_id = self.expanded_matrix_node_ids[I]
            j_id = self.expanded_matrix_node_ids[J]
            k_id = self.expanded_matrix_node_ids[K]
            # self.T_expanded[i_id, id_volume] = D_JK
            self.T_expanded[id_volume, i_id] = D_JK
            # self.T_expanded[j_id, id_volume] = -D_JK + D_JI - K_eq
            self.T_expanded[id_volume, j_id] = -D_JK + D_JI - K_eq
            # self.T_expanded[k_id, id_volume] = -D_JI
            self.T_expanded[id_volume, k_id] = -D_JI
            self.T_expanded[i_id, i_id] = 1.0
            self.T_expanded[j_id, j_id] = 1.0
            self.T_expanded[k_id, k_id] = 1.0

        all_cols = []
        all_rows = []
        all_values = []
        self.ids = []
        self.v_ids = []
        self.ivalues = []
        for face in self.intern_faces:
            face_mobility = self.mb.tag_get_data(self.face_mobility_tag, face)[
                0
            ][0]
            left_volume, right_volume = self.mtu.get_bridge_adjacencies(
                face, 2, 3
            )
            L = self.mesh_data.mb.tag_get_data(
                self.volume_centre_tag, left_volume
            )[0]
            R = self.mesh_data.mb.tag_get_data(
                self.volume_centre_tag, right_volume
            )[0]
            dist_LR = R - L
            I, J, K = self.mtu.get_bridge_adjacencies(face, 0, 0)
            JI = self.mb.get_coords([I]) - self.mb.get_coords([J])
            JK = self.mb.get_coords([K]) - self.mb.get_coords([J])

            N_IJK = np.cross(JI, JK) / 2.0
            test = np.dot(N_IJK, dist_LR)

            if test < 0:
                left_volume, right_volume = right_volume, left_volume
                L = self.mesh_data.mb.tag_get_data(
                    self.volume_centre_tag, left_volume
                )[0]
                R = self.mesh_data.mb.tag_get_data(
                    self.volume_centre_tag, right_volume
                )[0]
                dist_LR = R - L

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

            K_R = self.mb.tag_get_data(self.perm_tag, right_volume).reshape(
                [3, 3]
            )
            RJ = R - self.mb.get_coords([J])
            h_R = geo.get_height(N_IJK, RJ)

            K_R_n = self.vmv_multiply(N_IJK, face_mobility * K_R, N_IJK)
            K_R_JI = self.vmv_multiply(N_IJK, face_mobility * K_R, tan_JI)
            K_R_JK = self.vmv_multiply(N_IJK, face_mobility * K_R, tan_JK)

            K_L = self.mb.tag_get_data(self.perm_tag, left_volume).reshape(
                [3, 3]
            )

            LJ = L - self.mb.get_coords([J])
            h_L = geo.get_height(N_IJK, LJ)

            K_L_n = self.vmv_multiply(N_IJK, face_mobility * K_L, N_IJK)
            K_L_JI = self.vmv_multiply(N_IJK, face_mobility * K_L, tan_JI)
            K_L_JK = self.vmv_multiply(N_IJK, face_mobility * K_L, tan_JK)

            D_JI = self.get_cross_diffusion_term(
                tan_JI,
                dist_LR,
                face_area,
                h_L,
                K_L_n,
                K_L_JI,
                h_R,
                K_R_JI,
                K_R_n,
            )
            D_JK = self.get_cross_diffusion_term(
                tan_JK,
                dist_LR,
                face_area,
                h_L,
                K_L_n,
                K_L_JK,
                h_R,
                K_R_JK,
                K_R_n,
            )

            K_eq = (K_R_n * K_L_n) / (K_R_n * h_L + K_L_n * h_R) * face_area

            id_right = self.mb.tag_get_data(self.global_id_tag, right_volume)
            id_left = self.mb.tag_get_data(self.global_id_tag, left_volume)

            col_ids = [id_right, id_right, id_left, id_left]
            row_ids = [id_right, id_left, id_left, id_right]
            values = [K_eq, -K_eq, K_eq, -K_eq]
            all_cols.append(col_ids)
            all_rows.append(row_ids)
            all_values.append(values)
            self._node_treatment(I, id_left, id_right, K_eq, D_JK=D_JK)
            self._node_treatment(
                J, id_left, id_right, K_eq, D_JI=D_JI, D_JK=-D_JK
            )
            self._node_treatment(K, id_left, id_right, K_eq, D_JI=-D_JI)

        self.T.InsertGlobalValues(self.ids, self.v_ids, self.ivalues)
        self.T.InsertGlobalValues(id_volumes, id_volumes, all_LHS)
        self.T.InsertGlobalValues(all_cols, all_rows, all_values)
        self.T.FillComplete()
        for i in range(len(self.volumes)):
            for j in range(len(self.volumes)):
                if self.T[i][j]:
                    self.T_expanded[i, j] = self.T[i][j]
        _is, js, values = find(self.T_expanded)
        self.T_plus[
            [i for i, j in zip(_is, js) if i != j],
            [j for i, j in zip(_is, js) if i != j],
        ] = np.asarray(
            [max(0, value) for i, j, value in zip(_is, js, values) if i != j]
        )
        self.T_plus[_is, _is] = -self.T_plus[_is].sum(axis=1).transpose()
        self.T_minus = self.T_expanded - self.T_plus
        self.q = self.Q.tocsc()
        self.u[: len(self.volumes)] = spsolve(self.T_expanded[0: len(self.volumes), 0: len(self.volumes)], self.q)

        nodes_pressure = self.mb.tag_get_data(
            self.dirichlet_tag, self.dirichlet_nodes | self.neumann_nodes
        )
        self.u[len(self.volumes):] = nodes_pressure[:, 0]
        residual = -self.T_minus * self.u
        self.T_plus_aux = self.T_plus
        _is, js, _ = find(self.T_plus)
        print("vai entrar no calculo do residuo")
        n = 0
        self.mb.tag_set_data(
            self.pressure_tag, self.volumes, self.u[:len(self.volumes)]
        )
        vols = [
            self.vol_volumes.get(vol[0]) for vol in self.mb.tag_get_data(
                self.global_id_tag, self.volumes
            )
        ]
        tol = np.dot(vols, abs(residual[:len(self.volumes)]))
        # while np.average(abs(residual[:len(self.volumes)])) > 1e-3:

        while tol > 1e-3:
            self.tag_verts_pressure()
            # its = list(
            #     map(self.compute_vert_pressure, self.nodes_ws.keys())
            # )
            # import pdb; pdb.set_trace()
            # bs = {}
            # for item in its:
            #     for key, value in item.items():
            #         if bs.get(key):
            #             bs[key] = min(bs.get(key), value)
            #         else:
            #             pass
            # limiter = {key}
            # limiters = {
            #     key: value for key, value in list(
            #         map(self.compute_vert_pressure, self.nodes_ws.keys())
            #     )
            # }
            self.grads = {}
            for volume in self.volumes:
                vol_id = self.mb.tag_get_data(self.global_id_tag, volume)[0][0]
                grad = self.get_grad(volume)
                self.grads.update({vol_id: {"grad": grad, "vol": volume}})
            n += 1
            # print("u_i max")
            self.u_maxs = {}
            [
                self.u_maxs.update({
                    i: max(
                            0,
                            self.u[i]
                            + max(
                                [
                                    self.u[j] - self.u[i]
                                    for j in self.mb.tag_get_data(
                                        self.global_id_tag,
                                        self.mtu.get_bridge_adjacencies(
                                            self.volumes[i], 0, 3
                                        )
                                    )
                                    if j != i
                                ]
                            ),
                        )
                    }) for i in range(len(self.volumes))
            ]
            # print("u_i min")
            self.u_mins = {}
            [
                self.u_mins.update({
                    i: min(
                            0,
                            self.u[i]
                            + min(
                                [
                                    self.u[j] - self.u[i]
                                    for j in self.mb.tag_get_data(
                                        self.global_id_tag,
                                        self.mtu.get_bridge_adjacencies(
                                            self.volumes[i], 0, 3))
                                    if j != i
                                ]
                            ),
                        )
                    }) for i in range(len(self.volumes))
            ]
            # print("u_j max")
            # print(f"Solution: u_max: \
            #       {max(self.u[:len(self.volumes)])} \
            #       u_min: {min(self.u[:len(self.volumes)])}")
            # print("calculo de slope limiter")
            rows = []
            cols = []
            alpha_ijs = []
            [
                (
                    rows.append(i),
                    cols.append(j),
                    alpha_ijs.append(
                        self.compute_alpha(i, j)
                    ),
                ) for i, j in zip(_is, js) if i != j
            ]
            # print(f"max alpha: {max(alpha_ijs)} min alpha: {min(alpha_ijs)}")
            # print("vai recalcular T_plus")
            t0 = time.time()
            new_vals = [
                self.T_plus[i, j] * alpha for i, j, alpha in zip(
                    rows, cols, alpha_ijs
                )
            ]
            self.T_plus[rows, cols] = new_vals
            self.T_plus[
                range(len(self.u)), range(len(self.u))
            ] = self.T_plus.sum(axis=1).transpose() - self.T_plus.diagonal()
            # print("Refaz o assembly da matry com novos fluxos")
            self.T_expanded = self.T_minus + self.T_plus
            # print("calculo do termo fonte")
            _q = (
                -self.T_expanded[: len(self.volumes), len(self.volumes):]
                * nodes_pressure
            )
            # print("calculo de pressao u")
            self.u[: len(self.volumes)] = spsolve(
                self.T_expanded[: len(self.volumes), : len(self.volumes)], _q
            )
            f = self.T_plus * self.u
            a_omega_u = - self.T_minus * self.u
            residual = a_omega_u + f
            tol = np.dot(vols, abs(residual[:len(self.volumes)]))
            # print(f"res: {np.average(abs(residual[:len(self.volumes)]))}")
            print(f"res: {tol}")
            self.mb.tag_set_data(
                self.pressure_tag, self.volumes, self.u[:len(self.volumes)]
            )
            self.record_data(f'results_crr2.vtk')
        print("DONE!!!")
        import pdb; pdb.set_trace()