Skip to content

Gradient-enhanced models interface #87

@srosenbu

Description

@srosenbu

We (or I) need an interface for gradient-enhanced models. I did some calculations, and I think it does not matter so much if we do gradient-plasticity or gradient damage. In the end, we have a local variable $\alpha$ and its nonlocal counterpart $\bar\alpha$ which is the solution of the PDE

$$ l^{2}\nabla^{2}\bar{\alpha}+\alpha-\bar{\alpha}=0. $$

For quasi-static calculations, we then need the tangents

$$ \frac{\partial\sigma}{\partial\varepsilon},\quad \frac{\partial\sigma}{\partial\bar\alpha}, \quad \frac{\partial\alpha}{\partial\varepsilon},\quad \frac{\partial\alpha}{\partial\bar\alpha}. $$

For dynamic simulations, the underlying PDE is

$$ l^{2}\nabla^{2}\bar{\alpha}+\alpha-\bar{\alpha}-\gamma\dot{\bar{\alpha}}=\zeta\ddot{\bar{\alpha}}. $$

for which we do not need any of these tangents if we use an explicit solver.

The proposed interface should therefore have the tangents as optional parameters:

class IncrSmallStrainNonlocalModel(ABC):
    """
    Interface for incremental small strain models.
    """

    @abstractmethod
    def evaluate(
        self,
        t: float,
        del_t: float,
        grad_del_u: np.ndarray,
        nonlocal_quantity: np.ndarray, #NEW parameter
        stress: np.ndarray,
        local_quantity: np.ndarray, #NEW parameter
        dsigma_deps: np.ndarray | None, #NEW parameter
        dsigma_dnonlocal: np.ndarray | None, #NEW parameter
        dlocal_deps: np.ndarray | None, #NEW parameter
        dlocal_dnonlocal: np.ndarray | None, #NEW parameter
        history: dict[str, np.ndarray] | None,
    ) -> None:

Or as a tuple

class IncrSmallStrainNonlocalModel(ABC):
    """
    Interface for incremental small strain models.
    """

    @abstractmethod
    def evaluate(
        self,
        t: float,
        del_t: float,
        grad_del_u: np.ndarray,
        nonlocal_quantity: np.ndarray, #NEW parameter
        stress: np.ndarray,
        local_quantity: np.ndarray, #NEW parameter
        tangents: tuple[np.ndarray] | None, #NEW parameter
        history: dict[str, np.ndarray] | None,
    ) -> None:

The first design could be annoying because we only want to handle the case where all tangents are either something or none. In the second approach, it is not obvious from the interface alone what the input for tangents is, but it should be somewhat easier to handle the two cases.

Another option could be a named tuple or a dataclass as input for the model

@dataclass
class NonlocalTangents:
    dsigma_deps: np.ndarray
    dsigma_dnonlocal: np.ndarray
    dlocal_deps: np.ndarray
    dlocal_dnonlocal: np.ndarray

class IncrSmallStrainNonlocalModel(ABC):
    """
    Interface for incremental small strain models.
    """

    @abstractmethod
    def evaluate(
        self,
        t: float,
        del_t: float,
        grad_del_u: np.ndarray,
        nonlocal_quantity: np.ndarray, #NEW parameter
        stress: np.ndarray,
        local_quantity: np.ndarray, #NEW parameter
        tangents: NonlocalTangents | None, #NEW parameter
        history: dict[str, np.ndarray] | None,
    ) -> None:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions