Beispiel #1
0
    def test_import_single_grid(self):
        folder = "../../geometry/mesh_test_porepy/mesh_senzafrattura/"
        fname = "_bulk"
        g = import_grid(folder, fname, 2)
        pp.Exporter(g, "grid").write_vtk()

        pp.plot_grid(g, info="c", alpha=0)
        print(g)
Beispiel #2
0
def main():
    # example in 2d
    file_name = "network.csv"
    write_network(file_name)

    # load the network and split it, we assume 2d
    domain = {"xmin": 0, "xmax": 1, "ymin": 0, "ymax": 1}
    global_network = pp.fracture_importer.network_2d_from_csv(file_name,
                                                              domain=domain)
    global_network = global_network.split_intersections()

    # select a subsample of the fractures
    macro_network, micro_network = split_network(global_network,
                                                 Criterion.every)
    # NOTE: the explicit network is empty so far

    # create the macroscopic grid
    mesh_size = 2
    mesh_kwargs = {
        "mesh_size_frac": mesh_size,
        "mesh_size_min": mesh_size / 20
    }
    gb = macro_network.mesh(mesh_kwargs)

    # plot the suff
    pp.plot_fractures(micro_network.pts, micro_network.edges,
                      micro_network.domain)
    pp.plot_grid(gb, info="c", alpha=0)

    # construct the solver
    tpfa_dfm = Tpfa_DFM()

    # Set data for the upscaling problem
    g = gb.grids_of_dimension(gb.dim_max())[0]
    d = gb.node_props(g)

    # store the
    # EK: We probably need to initialize some of the nested dictionaries
    d[pp.PARAMETERS][tpfa_dfm.keyword][
        tpfa_dfm.network_keyword] = micro_network

    # set parameters and discretization variables
    # EK: This must be done in this run-script - it is not the responsibility of the
    # discretization. We may want to construct a model for this.
    # tpfa_dfm.set_parameters(gb)
    # tpfa_dfm.set_variables_discretizations(gb)

    # discretize with the assembler
    assembler = pp.Assembler(gb)
    assembler.discretize()

    A, b = assembler.assemble_matrix_rhs()

    # Solve and distribute
    x = spsolve(A, b)
    assembler.distribute_variable(x)
Beispiel #3
0
def import_gb(folder, max_dim, **kwargs):

    index_names = kwargs.get("index_names", 1)
    index_shift = kwargs.get("index_shift", 1)

    # bulk grid
    fname_bulk = kwargs.get("bulk", "_bulk")
    grid_bulk = [import_grid(folder, fname_bulk, max_dim, **kwargs)]

    # fracture grids
    fname_fracture = kwargs.get("fracture", "_fracture_")
    grid_fracture = []

    # check the number of fractures
    fname = "/" + kwargs.get("nodes", "points") + fname_fracture + "*.txt"
    num_frac = len(glob.glob(folder + fname))
    print("there are " + str(num_frac) + " fractures")

    for idx in np.arange(num_frac):
        fname = fname_fracture + str(idx + index_names)
        g = import_grid(folder, fname, max_dim - 1, **kwargs)
        grid_fracture.append(g)

    # intersection grids
    fname_intersection = kwargs.get("intersection", "_")
    grid_intersection = []

    # check the number of intersections
    fname = "/" + kwargs.get("nodes",
                             "InterCellsCoord") + fname_intersection + "*.txt"
    num_int = len(glob.glob(folder + fname))
    print("there are " + str(num_int) + " intersections")

    for idx in np.arange(num_int):
        fname = fname_intersection + str(idx + index_names)
        g = import_grid_0d(folder, fname, **kwargs)
        grid_intersection.append(g)

    grids = [grid_bulk, grid_fracture, grid_intersection]
    #grids = [[], grid_fracture, []]#, grid_intersection]
    gb = pp.meshing.grid_list_to_grid_bucket(grids)
    pp.plot_grid(gb, alpha=0)

    for _, d in gb:
        d[pp.PRIMARY_VARIABLES] = {}
        d[pp.DISCRETIZATION] = {}
        d[pp.DISCRETIZATION_MATRICES] = {}

    for _, d in gb.edges():
        d[pp.PRIMARY_VARIABLES] = {}
        d[pp.COUPLING_DISCRETIZATION] = {}
        d[pp.DISCRETIZATION_MATRICES] = {}

    return gb
def make_grid(mesh_size=0.1, grid_type="cartesian", plot_grid=False):
    
    if grid_type == "cartesian":
        n = int(1/mesh_size)
        gb = pp.meshing.cart_grid([], nx=[n, n], physdims=[1.0, 1.0])
    elif grid_type == "triangular":
        domain = {"xmin": 0.0, "xmax": 1.0, "ymin": 0.0, "ymax": 1.0}
        network_2d = pp.FractureNetwork2d(None, None, domain)
        mesh_args = {"mesh_size_bound": mesh_size, "mesh_size_frac": mesh_size}
        gb = network_2d.mesh(mesh_args)
    else:
        raise ValueError("Grid type not available.")

    if plot_grid:
        pp.plot_grid(g, plot_2d=True)

    return gb
def make_mesh(mesh_size, plot=False):

    # define the domain
    domain = {"xmin": 0, "xmax": 1, "ymin": 0, "ymax": 2}

    # Point coordinates, as a 2xn array
    p = np.array([[0, 1], [1, 1]])

    # Point connections as a 2 x num_frac array
    e = np.array([[0], [1]])

    # Define a fracture network in 2d
    network_2d = pp.FractureNetwork2d(p, e, domain)

    # Generate a mixed-dimensional mesh
    gb = network_2d.mesh({"mesh_size_frac": mesh_size})

    if plot:
        pp.plot_grid(gb, alpha=0, info="all")

    return gb
        x_new = x + x_prev

        # Distribute the solution, in an additive manner
        dof_manager.distribute_variable(values=x_new,
                                        additive=False,
                                        to_iterate=True)

        # Rediscretize the equations.
        # Mainly to update the Darcy flux
        equation_manager = equation(gb, dof_manager, equation_manager, True)

        A, b = equation_manager.assemble_matrix_rhs()

        res = np.linalg.norm(b)
        iter += 1

    # end while

    # Distribute the solution to the next time step
    x_new = dof_manager.assemble_variable(from_iterate=True)
    dof_manager.distribute_variable(x_new.copy(),
                                    to_iterate=False,
                                    additive=False)

    pp.plot_grid(gb, pressure_variable, figsize=(15, 12))
    print(res)

    print(f"time step {i}")
    print(f"newton iters {iter}")
# end i-loop
    [0.4, 0.2]
]).T

e = np.array([
    [0, 1],
    [2, 3],
    [4, 5],
]).T

domain = {"xmin": 0, "xmax": 2, "ymin": 0, "ymax": 1}  # domain is 0<x<2,0<y<1
network_2d = pp.FractureNetwork2d(pts, e, domain)

mesh_args = {"mesh_size_frac": 0.2, "mesh_size_bound": 0.2}
gb = network_2d.mesh(mesh_args)

pp.plot_grid(gb, figsize=(15, 12))

# g = pp.CartGrid([5,5])
# g.compute_geometry()
# gb = pp.GridBucket()
# gb.add_nodes(g)

# Keywords
kw_f = "flow"
kw_t = "transport"

# Set flow data
domain = {"xmin": 0, "xmax": 2, "ymin": 0, "ymax": 1}
gb = flow_in_gb(gb, domain)
# Set transport data
aq_components = np.array([0])
def solve_two_phase_flow_upwind(g):

    time = []
    sat_err = []
    pres_err = []
    maxflux = []
    
    xc = g.cell_centers

    # Permeability tensor
    k_xx = np.zeros(g.num_cells)
    k_xy = np.zeros(g.num_cells)
    k_yy = np.zeros(g.num_cells)

    k_xx[:] = perm_xx_f(xc[0], xc[1])
    k_yy[:] = perm_yy_f(xc[0], xc[1])
    k_xy[:] = perm_xy_f(xc[0], xc[1])

    perm = pp.SecondOrderTensor(k_xx, kyy=k_yy, kxy=k_xy)
    
    # Set type of boundary conditions
    xf = g.face_centers
    p_bound = np.zeros(g.num_faces)

    bnd_faces = g.get_all_boundary_faces()
    neu_faces = bnd_faces[:-1].copy()        
    dir_faces = np.array([g.num_faces-1])

    bot_faces = np.ravel(np.argwhere(g.face_centers[1] < 1e-10))
    top_faces = np.ravel(np.argwhere(g.face_centers[1] > domain[1] - 1e-10))
    left_faces = np.ravel(np.argwhere(g.face_centers[0] < 1e-10))
    right_faces = np.ravel(np.argwhere(g.face_centers[0] > domain[0] - 1e-10))
   
    bound_cond = pp.BoundaryCondition(g, dir_faces, ['dir'] * dir_faces.size)

    # set value of boundary condition
    p_bound[neu_faces] = 0
    p_bound[dir_faces] = p_f(xf[0, dir_faces], xf[1, dir_faces])

    # set rhs    
    rhs1 = np.zeros(g.num_cells)
    rhs2 = np.zeros(g.num_cells)

    specified_parameters = {"second_order_tensor": perm, "source": rhs1, "bc": bound_cond, "bc_values": p_bound}
    data = pp.initialize_default_data(g, {}, "flow", specified_parameters)
    
    # Set initial conditions
    s = np.zeros(g.num_cells)
    s = s_f(xc[0], xc[1])
    s_0 = s_f(xc[0], xc[1])
    #pp.plot_grid(g, s_0, figsize=(15, 12), alpha = 0.9, color_map=(0,1))
    V_start = np.sum(s*g.cell_volumes)

    fluxtot = np.zeros(g.num_faces)

    p_ex = p_f(xc[0], xc[1])
    s_ex = s_eq_f(xc[0], xc[1])

    time_steps_vec = []

    #save = pp.Exporter(g, 'twophase_gcmpfa8_time', folder='plots')
    #save.write_vtk({"s": s}, 0)

    # Gravity term
    # < K > * rho_alpha * g
    gforce = np.zeros((2, g.num_cells))
    gforce[0,:] = gx * np.ones(g.num_cells)
    gforce[1,:] = gy * np.ones(g.num_cells)
    gforce = gforce.ravel('F')

    g1 = rho1 * gforce
    g2 = rho2 * gforce

    flux_g1 = standard_discr(g, perm, g1)
    flux_g2 = standard_discr(g, perm, g2)
    
    # mpfa discretization
    flux, bound_flux, _, _  = pp.Mpfa("flow")._local_discr(
        g, perm, bound_cond, inverter="python"
    )
    div = pp.fvutils.scalar_divergence(g)

    # define iteration parameters
    t = .0
    k = 0
    i = 0

    time_steps_vec.append(t)
    time_step = 5  

    courant_max = 0.05
    
    while t < T:

        s_old = s.copy()

        # Increment time
        k += 1
        t += time_step

        # discretize gravity term
        kr1, kr2, f2, f1 = get_phase_mobility(g, s, fluxtot, flux_g1, flux_g2)
        fluxtot_g = kr1 * flux_g1 + kr2 * flux_g2
        p_bound[neu_faces] = fluxtot[neu_faces] - fluxtot_g[neu_faces]
        p_bound[bot_faces] *= -1
        p_bound[left_faces] *= -1

        a = div * (kr1 + kr2) * flux
        b = (rhs1 + rhs2) - div * bound_flux * p_bound - div * fluxtot_g

        p = sps.linalg.spsolve(a, b)
        
        fluxtot = (kr1 + kr2) * flux * p + bound_flux * p_bound + fluxtot_g
        assert np.all(abs(fluxtot[neu_faces]) < thresh)
        assert np.all(abs(fluxtot[dir_faces]) < 1.0e-16)

        if pert == 0:
            assert np.all(fluxtot < thresh)

        threshold_indices = abs(fluxtot) < thresh
        fluxtot[threshold_indices] = 0
        
        maxfluxtot = np.amax(np.absolute(fluxtot))
        maxflux.append(maxfluxtot)

        # update s
        q2 = f2 * (fluxtot + kr1 * (flux_g2 - flux_g1))
        q1 = f1 * (fluxtot + kr2 * (flux_g1 - flux_g2))
        q2[bnd_faces]=0
        q1[bnd_faces]=0
        assert np.allclose(q1+q2, fluxtot)

        # check courant number
        q2max = np.zeros(g.num_cells)
        q1max = np.zeros(g.num_cells)
        for j in range (0, g.num_cells):
            faces_of_cell = g.cell_faces.indices[g.cell_faces.indptr[j] : g.cell_faces.indptr[j+1]]
            for i in range (0, faces_of_cell.size):
                q2max[j] += np.absolute(q2[faces_of_cell[i]]) / g.cell_volumes[j]
                q1max[j] += np.absolute(q1[faces_of_cell[i]]) / g.cell_volumes[j]

        courant = 0.5 * max(np.amax(q2max), np.amax(q1max)) * time_step

        div_q2 = div * q2
        threshold_indices = abs(div_q2) < thresh
        div_q2[threshold_indices] = 0

        s = s + time_step / phi / g.cell_volumes * (rhs2 - div_q2)

        if not np.all(s >= 0.0):
            inds=np.argwhere(s<0.0)
            print(k, inds, s[inds])
            assert False
        if not np.all(s <= 1.0):
            inds=np.argwhere(s>1.0)
            #print(k, inds, s[inds])
            assert np.all(s[inds] < 1. + 1.0e-12)
            s[inds] = 1.
            #assert False
            

        mass_error = (np.sum(s*g.cell_volumes) - np.sum(s*g.cell_volumes)) / np.sum(s*g.cell_volumes)

        if abs(mass_error) > tol_mc:
            print('error in mass conservation')
            print(t, mass_error)
            break

        s_diff = s - s_ex
        s_err=np.sqrt(np.sum(g.cell_volumes * s_diff**2))/np.sqrt(np.sum(g.cell_volumes * s_ex**2))

        p_diff = p - p_ex
        p_err=np.sqrt(np.sum(g.cell_volumes * p_diff**2))/np.sqrt(np.sum(g.cell_volumes * p_ex**2))
        
        sat_err.append(s_err)
        pres_err.append(p_err)
        time.append(t)

        #time_steps.append(t)
        #save.write_vtk({"s": s}, time_step=k)

        if k % 100 == 0:
            print(t, mass_error, maxfluxtot, s_err, p_err)
            F = courant_max / courant
            if F > 1.:
                adjust_time_step = min(min(F, 1. + 0.1 * F), 1.2)
                time_step *= adjust_time_step
                print(time_step)

        #time_steps_vec.append(t)
        #i += 1
        """
        if k % 500 == 0 and t < 1.0e8:
            Q_n = fluxtot * g.face_normals
            solver_flow = pp.MVEM("flow")
            P0u = solver_flow.project_flux(g, fluxtot, data)
            #pp.plot_grid(g, p, P0u * 5e7, figsize=(15, 12))
            #pp.plot_grid(g, s_0, figsize=(15, 12), alpha = 0.9, color_map=(0,1))
            pp.plot_grid(g, s, vector_value=Q_n, figsize=(15, 12), vector_scale=1e7, alpha = 0.9, color_map=(0,1))
            #save.write_vtk({"s": s}, time_step=i)


        Q_n = fluxtot * g.face_normals
        pp.plot_grid(g, vector_value=Q_n, figsize=(15, 12), vector_scale=5e7)
        Q_1 = q1 * g.face_normals
        pp.plot_grid(g, vector_value=Q_1, figsize=(15, 12), vector_scale=5e7)
        Q_2 = q2 * g.face_normals
        pp.plot_grid(g, vector_value=Q_2, figsize=(15, 12), vector_scale=5e7)
        """

            
    #save.write_pvd(np.array(time_steps_vec))

    p_diff = p - p_ex
    s_diff = s - s_ex
    p_err=np.sqrt(np.sum(g.cell_volumes * p_diff**2))/np.sqrt(np.sum(g.cell_volumes * p_ex**2))
    s_err=np.sqrt(np.sum(g.cell_volumes * s_diff**2))/np.sqrt(np.sum(g.cell_volumes * s_ex**2))

    mass_error = (np.sum(s*g.cell_volumes) - np.sum(s*g.cell_volumes)) / np.sum(s*g.cell_volumes)
    print('error in mass conservation', mass_error)

    print('error in saturation ', s_err)
    print('error in pressure ', p_err)
    
    pp.plot_grid(g, s, figsize=(15, 12))
    pp.plot_grid(g, p, figsize=(15, 12))

    Q_n = fluxtot * g.face_normals
    solver_flow = pp.MVEM("flow")
    P0u = solver_flow.project_flux(g, fluxtot, data)
    #pp.plot_grid(g, p, P0u * 5e7, figsize=(15, 12))
    #pp.plot_grid(g, s_0, figsize=(15, 12), alpha = 0.9, color_map=(0,1))
    #pp.plot_grid(g, s, vector_value=Q_n, figsize=(15, 12), vector_scale=1e7, alpha = 0.9, color_map=(0,1))
    #save.write_vtk({"s": s}, time_step=i)

    #save.write_vtk({"p": p, 's_0' : s_0, 's_f' : s})

    return time, sat_err, pres_err, maxflux