Exemplo n.º 1
0
    def assign_mechanics_variables(self) -> None:
        """ Assign variables to the nodes and edges of the grid bucket.
        """
        gb = self.gb
        primary_vars = pp.PRIMARY_VARIABLES
        var_m = self.displacement_variable
        var_contact = self.contact_traction_variable
        var_mortar = self.mortar_displacement_variable

        for g, d in gb:
            add_nonpresent_dictionary(d, primary_vars)
            if g.dim == self.Nd:
                d[primary_vars].update(
                    {var_m: {"cells": self.Nd},}
                )

            elif g.dim == self.Nd - 1:
                d[primary_vars].update(
                    {var_contact: {"cells": self.Nd},}
                )

        for e, d in gb.edges():
            add_nonpresent_dictionary(d, primary_vars)

            g_l, g_h = gb.nodes_of_edge(e)
            if g_h.dim == self.Nd:
                d[primary_vars].update(
                    {var_mortar: {"cells": self.Nd},}
                )
Exemplo n.º 2
0
    def assign_scalar_variables(self) -> None:
        """
        Assign primary variables to the nodes and edges of the grid bucket.
        """
        gb = self.gb
        primary_vars = pp.PRIMARY_VARIABLES

        # First for the nodes
        for _, d in gb:
            add_nonpresent_dictionary(d, primary_vars)

            d[primary_vars].update({
                self.scalar_variable: {
                    "cells": 1
                },
            }  # noqa: E231
                                   )

        # Then for the edges
        for _, d in gb.edges():
            add_nonpresent_dictionary(d, primary_vars)

            d[primary_vars].update({
                self.mortar_scalar_variable: {
                    "cells": 1
                },
            })
Exemplo n.º 3
0
    def assign_mechanics_discretizations(self) -> None:
        """
        Assign discretizations to the nodes and edges of the grid bucket.
        """
        gb = self.gb
        nd = self.Nd
        # Shorthand
        key_m, var_m = self.mechanics_parameter_key, self.displacement_variable
        var_contact = self.contact_traction_variable
        var_mortar = self.mortar_displacement_variable
        discr_key, coupling_discr_key = pp.DISCRETIZATION, pp.COUPLING_DISCRETIZATION

        # For the Nd domain we solve linear elasticity with mpsa.
        mpsa = pp.Mpsa(key_m)

        # We need a void discretization for the contact traction variable defined on
        # the fractures.
        empty_discr = pp.VoidDiscretization(key_m, ndof_cell=nd)

        # Assign node discretizations
        for g, d in gb:
            add_nonpresent_dictionary(d, discr_key)

            if g.dim == nd:
                d[discr_key].update(
                    {var_m: {"mpsa": mpsa},}
                )

            elif g.dim == nd - 1:
                d[discr_key].update(
                    {var_contact: {"empty": empty_discr},}
                )

        # Define the contact condition on the mortar grid
        coloumb = pp.ColoumbContact(key_m, nd, mpsa)
        contact = pp.PrimalContactCoupling(key_m, mpsa, coloumb)

        for e, d in gb.edges():
            g_l, g_h = gb.nodes_of_edge(e)
            add_nonpresent_dictionary(d, coupling_discr_key)
            if g_h.dim == nd:
                d[coupling_discr_key].update(
                    {
                        self.friction_coupling_term: {
                            g_h: (var_m, "mpsa"),
                            g_l: (var_contact, "empty"),
                            e: (var_mortar, contact),
                        },
                    }
                )
Exemplo n.º 4
0
    def initial_mechanics_condition(self) -> None:
        """ Set initial guess for the variables.

        The displacement is set to zero in the Nd-domain, and at the fracture interfaces
        The displacement jump is thereby also zero.

        The contact pressure is set to zero in the tangential direction,
        and -1 (that is, in contact) in the normal direction.

        We initialize pp.ITERATE for the contact traction and
        mortar displacement since they are to be updated every Newton
        iteration.

        """
        gb = self.gb
        var_m = self.displacement_variable
        var_contact = self.contact_traction_variable
        var_mortar = self.mortar_displacement_variable
        state, iterate = pp.STATE, pp.ITERATE

        for g, d in gb:
            add_nonpresent_dictionary(d, state)
            if g.dim == self.Nd:
                # Initialize displacement variable
                initial_displacement_value = np.zeros(g.num_cells * self.Nd)
                d[state].update(
                    {var_m: initial_displacement_value,}
                )

            elif g.dim == self.Nd - 1:
                # Initialize contact variable
                traction = np.vstack(
                    (np.zeros((g.dim, g.num_cells)), -1 * np.ones(g.num_cells))
                ).ravel(order="F")
                d[state].update(
                    {iterate: {var_contact: traction}, var_contact: traction,}
                )

        for e, d in self.gb.edges():
            add_nonpresent_dictionary(d, state)

            mg: pp.MortarGrid = d["mortar_grid"]
            if mg.dim == self.Nd - 1:
                size = mg.num_cells * self.Nd
                d[state].update(
                    {var_mortar: np.zeros(size), iterate: {var_mortar: np.zeros(size)},}
                )
Exemplo n.º 5
0
    def assign_scalar_discretizations(self) -> None:
        """
        Assign discretizations to the nodes and edges of the grid bucket.

        Note the attribute subtract_fracture_pressure: Indicates whether or not to
        subtract the fracture pressure contribution for the contact traction. This
        should not be done if the scalar variable is temperature.
        """
        gb = self.gb
        # Shorthand
        key_s = self.scalar_parameter_key
        var_s = self.scalar_variable
        discr_key, coupling_discr_key = pp.DISCRETIZATION, pp.COUPLING_DISCRETIZATION

        # Scalar discretizations (all dimensions)
        diff_disc_s = implicit_euler.ImplicitMpfa(key_s)
        mass_disc_s = implicit_euler.ImplicitMassMatrix(key_s, var_s)
        source_disc_s = pp.ScalarSource(key_s)

        # Assign node discretizations
        for _, d in gb:
            add_nonpresent_dictionary(d, discr_key)

            d[discr_key].update({
                var_s: {
                    "diffusion": diff_disc_s,
                    "mass": mass_disc_s,
                    "source": source_disc_s,
                },
            })

        # Assign edge discretizations
        for e, d in gb.edges():
            g_l, g_h = gb.nodes_of_edge(e)
            add_nonpresent_dictionary(d, coupling_discr_key)

            d[coupling_discr_key].update({
                self.scalar_coupling_term: {
                    g_h: (var_s, "diffusion"),
                    g_l: (var_s, "diffusion"),
                    e: (
                        self.mortar_scalar_variable,
                        pp.RobinCoupling(key_s, diff_disc_s),
                    ),
                },
            })
Exemplo n.º 6
0
    def initial_scalar_condition(self) -> None:
        """
        Initial guess for Newton iteration, scalar variable and bc_values (for time
        discretization).
        """
        gb = self.gb

        for g, d in gb:
            add_nonpresent_dictionary(d, pp.STATE)
            # Initial value for the scalar variable.
            initial_scalar_value = np.zeros(g.num_cells)
            d[pp.STATE].update({self.scalar_variable: initial_scalar_value})

        for _, d in gb.edges():
            add_nonpresent_dictionary(d, pp.STATE)
            mg = d["mortar_grid"]
            initial_scalar_value = np.zeros(mg.num_cells)
            d[pp.STATE][self.mortar_scalar_variable] = initial_scalar_value