Beispiel #1
0
    def solve(self):
        # consturct the matrices
        self.assembler.discretize()

        # in the case the fractures are scaled modify the problem
        if self.data.get("length_ratio", None) is not None:
            for g, d in self.gb:
                if g.dim == 1:
                    ratio = self.data["length_ratio"][g.frac_num]
                    d[pp.DISCRETIZATION_MATRICES][self.model]["flux"] *= ratio
                    d[pp.DISCRETIZATION_MATRICES][self.model]["bound_flux"] *= ratio
                    d[pp.DISCRETIZATION_MATRICES][self.model]["bound_pressure_face"] *= ratio
                    d[pp.DISCRETIZATION_MATRICES][self.model]["bound_pressure_cell"] *= ratio

        A, b = self.assembler.assemble_matrix_rhs()

        # solve the problem
        p = sps.linalg.spsolve(A, b)

        # distribute the variables
        self.assembler.distribute_variable(p)

        # split the variables
        for g, d in self.gb:
            d[pp.STATE][self.pressure] = d[pp.STATE][self.variable]
            d[pp.STATE][self.P0_flux] = np.zeros(g.num_cells)
            d[pp.PARAMETERS][self.model][self.flux] = np.zeros(g.num_faces)

        # reconstruct the Darcy flux
        pp.fvutils.compute_darcy_flux(self.gb, keyword=self.model, d_name=self.flux,
                                      p_name=self.pressure, lam_name=self.mortar)

        # split the darcy flux on each grid-bucket grid
        for _, d in self.gb:
            d[pp.STATE][self.flux] = d[pp.PARAMETERS][self.model][self.flux]

        for e, d in self.gb.edges():
            _, g_master = self.gb.nodes_of_edge(e)
            if g_master.dim == 1:
                ratio = self.data["length_ratio"][g_master.frac_num]
                d[pp.PARAMETERS][self.model][self.flux] *= ratio
            d[pp.STATE][self.mortar] = d[pp.PARAMETERS][self.model][self.flux]

        # export the P0 flux reconstruction
        pp.project_flux(self.gb, pp.MVEM(self.model), self.flux, self.P0_flux, self.mortar)

        # compute the module of the flow velocity and the azimuth
        for g, d in self.gb:
            P0_flux = d[pp.STATE][self.P0_flux]

            norm = np.sqrt(np.einsum("ij,ij->j", P0_flux, P0_flux))
            d[pp.STATE][self.norm_flux] = norm

            north = self.data["north"] / np.linalg.norm(self.data["north"])
            P0_flux_dir = np.divide(P0_flux, norm)

            azimuth = np.arctan2(P0_flux_dir[1, :], P0_flux_dir[0, :]) - \
                      np.arctan2(north[1], north[0]);

            d[pp.STATE][self.azimuth] = azimuth
    def extract(self, x):
        self.assembler.distribute_variable(x)

        discr = self.discr(self.model)
        for g, d in self.gb:
            var = d[pp.STATE][self.variable]
            d[pp.STATE][self.pressure] = discr.extract_pressure(g, var, d)
            d[pp.STATE][self.flux] = discr.extract_flux(g, var, d)

        # export the P0 flux reconstruction
        pp.project_flux(self.gb, discr, self.flux, self.P0_flux, self.mortar)
    def extract(self, x, block_dof, full_dof):

        logger.info("Variable post-process")
        self.assembler.distribute_variable(x)
        for g, d in self.gb:
            d[self.pressure] = self.discr.extract_pressure(
                g, d[self.variable], d)
            d[self.flux] = self.discr.extract_flux(g, d[self.variable], d)

        # export the P0 flux reconstruction
        pp.project_flux(self.gb, self.discr, self.flux, self.P0_flux,
                        self.mortar)
        logger.info("done")
Beispiel #4
0
    def extract(self, x):
        self.assembler.distribute_variable(x)

        discr = self.discr(self.model)
        for g, d in self.gb:
            var = d[pp.STATE][self.variable]
            d[pp.STATE][self.pressure] = discr.extract_pressure(g, var, d)
            d[pp.STATE][self.flux] = discr.extract_flux(g, var, d)
            if "original_id" in g.tags:
                d[pp.STATE]["original_id"] = g.tags["original_id"] * np.ones(
                    g.num_cells)
            if "condition" in g.tags:
                d[pp.STATE]["condition"] = g.tags["condition"] * np.ones(
                    g.num_cells)

        # export the P0 flux reconstruction
        pp.project_flux(self.gb, discr, self.flux, self.P0_flux, self.mortar)
Beispiel #5
0
    def extract(self, x):
        self.assembler.distribute_variable(x)

        for g, d in self.gb:
            d[pp.STATE][self.pressure] = d[pp.STATE][self.variable]
            d[pp.STATE]["cell_volumes"] = g.cell_volumes

        pp.fvutils.compute_darcy_flux(self.gb,
                                      keyword=self.model,
                                      d_name=self.flux,
                                      p_name=self.pressure,
                                      lam_name=self.mortar)

        for _, d in self.gb:
            d[pp.STATE][self.flux] = d[pp.PARAMETERS][self.model][self.flux]

        # export the P0 flux reconstruction
        pp.project_flux(self.gb, pp.MVEM(self.model), self.flux, self.P0_flux,
                        self.mortar)
def flow(gb, param):

    model = "flow"

    model_data = data.flow(gb, model, param)

    # discretization operator name
    flux_id = "flux"

    # master variable name
    variable = "flux_pressure"
    mortar = "lambda_" + variable

    # post process variables
    pressure = "pressure"
    flux = "darcy_flux"  # it has to be this one
    P0_flux = "P0_flux"

    # save variable name for the advection-diffusion problem
    param["pressure"] = pressure
    param["flux"] = flux
    param["P0_flux"] = P0_flux
    param["mortar_flux"] = mortar

    # discretization operators
    discr = pp.MVEM(model_data)
    coupling = pp.RobinCoupling(model_data, discr)

    # define the dof and discretization for the grids
    for g, d in gb:
        d[pp.PRIMARY_VARIABLES] = {variable: {"cells": 1, "faces": 1}}
        d[pp.DISCRETIZATION] = {variable: {flux_id: discr}}

    # define the interface terms to couple the grids
    for e, d in gb.edges():
        g_slave, g_master = gb.nodes_of_edge(e)
        d[pp.PRIMARY_VARIABLES] = {mortar: {"cells": 1}}
        d[pp.COUPLING_DISCRETIZATION] = {
            variable: {
                g_slave: (variable, flux_id),
                g_master: (variable, flux_id),
                e: (mortar, coupling)
            }
        }

    # solution of the darcy problem
    assembler = pp.Assembler()

    logger.info("Assemble the flow problem")
    A, b, block_dof, full_dof = assembler.assemble_matrix_rhs(gb)
    logger.info("done")

    logger.info("Solve the linear system")
    up = sps.linalg.spsolve(A, b)
    logger.info("done")

    logger.info("Variable post-process")
    assembler.distribute_variable(gb, up, block_dof, full_dof)
    for g, d in gb:
        d[pressure] = discr.extract_pressure(g, d[variable])
        d[flux] = discr.extract_flux(g, d[variable])

    pp.project_flux(gb, discr, flux, P0_flux, mortar)
    logger.info("done")

    return model_data
Beispiel #7
0
def flow(gb, param, bc_flag):

    model = "flow"

    model_data = data_flow(gb, model, param, bc_flag)

    # discretization operator name
    flux_id = "flux"

    # master variable name
    variable = "flow_variable"
    mortar = "lambda_" + variable

    # post process variables
    pressure = "pressure"
    flux = "darcy_flux"  # it has to be this one

    # save variable name for the advection-diffusion problem
    param["pressure"] = pressure
    param["flux"] = flux
    param["mortar_flux"] = mortar

    # define the dof and discretization for the grids
    for g, d in gb:
        d[pp.PRIMARY_VARIABLES] = {variable: {"cells": 1, "faces": 1}}
        if g.dim == gb.dim_max():
            discr = pp.RT0(model_data)
        else:
            discr = RT0Multilayer(model_data)
        d[pp.DISCRETIZATION] = {variable: {flux_id: discr}}

    # define the interface terms to couple the grids
    for e, d in gb.edges():
        g_slave, g_master = gb.nodes_of_edge(e)
        d[pp.PRIMARY_VARIABLES] = {mortar: {"cells": 1}}

        # retrive the discretization of the master and slave grids
        discr_master = gb.node_props(g_master,
                                     pp.DISCRETIZATION)[variable][flux_id]
        discr_slave = gb.node_props(g_slave,
                                    pp.DISCRETIZATION)[variable][flux_id]

        if g_master.dim == gb.dim_max():
            # classical 2d-1d/3d-2d coupling condition
            coupling = pp.RobinCoupling(model_data, discr_master, discr_slave)

            d[pp.COUPLING_DISCRETIZATION] = {
                flux: {
                    g_slave: (variable, flux_id),
                    g_master: (variable, flux_id),
                    e: (mortar, coupling),
                }
            }
        elif g_master.dim < gb.dim_max():
            # the multilayer coupling condition
            coupling = RobinCouplingMultiLayer(model_data, discr_master,
                                               discr_slave)

            d[pp.COUPLING_DISCRETIZATION] = {
                flux: {
                    g_slave: (variable, flux_id),
                    g_master: (variable, flux_id),
                    e: (mortar, coupling),
                }
            }

    # solution of the darcy problem
    assembler = pp.Assembler()

    logger.info("Assemble the flow problem")
    A, b, block_dof, full_dof = assembler.assemble_matrix_rhs(gb)
    logger.info("done")

    logger.info("Solve the linear system")
    x = sps.linalg.spsolve(A, b)
    logger.info("done")

    logger.info("Variable post-process")
    assembler.distribute_variable(gb, x, block_dof, full_dof)
    for g, d in gb:
        d[pressure] = discr.extract_pressure(g, d[variable], d)
        d[flux] = discr.extract_flux(g, d[variable], d)

    # export the P0 flux reconstruction
    P0_flux = "P0_flux"
    param["P0_flux"] = P0_flux
    pp.project_flux(gb, discr, flux, P0_flux, mortar)

    # identification of layer and fault
    for g, d in gb:
        # save the identification of the fault
        if "fault" in g.name:
            d["fault"] = np.ones(g.num_cells)
            d["layer"] = np.zeros(g.num_cells)
        # save the identification of the layer
        elif "layer" in g.name:
            d["fault"] = np.zeros(g.num_cells)
            half_cells = int(g.num_cells / 2)
            d["layer"] = np.hstack(
                (np.ones(half_cells), 2 * np.ones(half_cells)))
        # save zero for the other cases
        else:
            d["fault"] = np.zeros(g.num_cells)
            d["layer"] = np.zeros(g.num_cells)

    save = pp.Exporter(gb, "solution", folder=param["folder"])
    save.write_vtk([pressure, P0_flux, "fault", "layer"])

    logger.info("done")
def flow(gb, discr, param, bc_flag):

    model = "flow"

    model_data = data_flow(gb, discr, model, param, bc_flag)

    # discretization operator name
    flux_id = "flux"

    # master variable name
    variable = "flow_variable"
    mortar = "lambda_" + variable

    # post process variables
    pressure = "pressure"
    flux = "darcy_flux"  # it has to be this one

    # save variable name for the advection-diffusion problem
    param["pressure"] = pressure
    param["flux"] = flux
    param["mortar_flux"] = mortar

    discr_scheme = discr["scheme"](model_data)
    discr_interface = pp.CellDofFaceDofMap(model_data)

    coupling = pp.FluxPressureContinuity(model_data, discr_scheme, discr_interface)

    # define the dof and discretization for the grids
    for g, d in gb:
        if g.dim == gb.dim_max():
            d[pp.PRIMARY_VARIABLES] = {variable: discr["dof"]}
            d[pp.DISCRETIZATION] = {variable: {flux_id: discr_scheme}}
        else:
            d[pp.PRIMARY_VARIABLES] = {variable: {"cells": 1}}
            d[pp.DISCRETIZATION] = {variable: {flux_id: discr_interface}}

    # define the interface terms to couple the grids
    for e, d in gb.edges():
        g_slave, g_master = gb.nodes_of_edge(e)
        d[pp.PRIMARY_VARIABLES] = {mortar: {"cells": 1}}
        d[pp.COUPLING_DISCRETIZATION] = {
            flux: {
                g_slave: (variable, flux_id),
                g_master: (variable, flux_id),
                e: (mortar, coupling),
            }
        }

    # solution of the darcy problem
    assembler = pp.Assembler(gb)

    logger.info("Assemble the flow problem")
    A, b = assembler.assemble_matrix_rhs()
    logger.info("done")

    logger.info("Solve the linear system")
    x = sps.linalg.spsolve(A, b)
    logger.info("done")

    logger.info("Variable post-process")
    assembler.distribute_variable(x)

    # extract the pressure from the solution
    for g, d in gb:
        if g.dim == 2:
            d[pp.STATE][pressure] = discr_scheme.extract_pressure(g, d[pp.STATE][variable], d)
            d[pp.STATE][flux] = discr_scheme.extract_flux(g, d[pp.STATE][variable], d)
        else:
            d[pp.STATE][pressure] = np.zeros(g.num_cells)
            d[pp.STATE][flux] = np.zeros(g.num_faces)

    # export the P0 flux reconstruction only for some scheme
    if discr["scheme"] is pp.MVEM or discr["scheme"] is pp.RT0:
        P0_flux = "P0_flux"
        param["P0_flux"] = P0_flux
        pp.project_flux(gb, discr_scheme, flux, P0_flux, mortar)

    logger.info("done")

    logger.info("Save dof on file")
    file_out = param["folder"] + "/dof_flow.csv"
    np.savetxt(file_out, get_dof(assembler), delimiter=",", fmt="%d")
    logger.info("done")