Source code for edelweissfe.elements.marmotsingleqpelement.element

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#  ---------------------------------------------------------------------
#
#  _____    _      _              _         _____ _____
# | ____|__| | ___| |_      _____(_)___ ___|  ___| ____|
# |  _| / _` |/ _ \ \ \ /\ / / _ \ / __/ __| |_  |  _|
# | |__| (_| |  __/ |\ V  V /  __/ \__ \__ \  _| | |___
# |_____\__,_|\___|_| \_/\_/ \___|_|___/___/_|   |_____|
#
#
#  Unit of Strength of Materials and Structural Analysis
#  University of Innsbruck,
#  2017 - today
#
#  Matthias Neuner matthias.neuner@uibk.ac.at
#
#  This file is part of EdelweissFE.
#
#  This library is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public
#  License as published by the Free Software Foundation; either
#  version 2.1 of the License, or (at your option) any later version.
#
#  The full text of the license can be found in the file LICENSE.md at
#  the top level directory of EdelweissFE.
#  ---------------------------------------------------------------------
# Created on Wed Aug 31 08:35:06 2022
# @author: matthias

import numpy as np

from edelweissfe.elements.base.baseelement import BaseElement
from edelweissfe.elements.marmotsingleqpelement.marmotmaterialgradientenhancedhypoelasticwrapper import (
    MarmotMaterialGradientEnhancedHypoElasticWrapper,
)
from edelweissfe.elements.marmotsingleqpelement.marmotmaterialhypoelasticwrapper import (
    MarmotMaterialHypoElasticWrapper,
)
from edelweissfe.points.node import Node

marmotMaterialWrappers = {
    "MarmotMaterialHypoElastic": MarmotMaterialHypoElasticWrapper,
    "MarmotMaterialGradientEnhancedHypoElastic": MarmotMaterialGradientEnhancedHypoElasticWrapper,
}


[docs]class MarmotMaterialWrappingElement(BaseElement): def __init__(self, materialType: str, elNumber: int): """This element serves as a wrapper for MarmotMaterials, cf. `Marmot <https://github.com/MAteRialMOdelingToolbox/Marmot/>`_. It has a single quadrature point, and one (dummy) node. For interfacing with specific Marmot materials, specialized material wrappers are used. The element allows to run quadrature point simulations investigating materials for development purposes. Parameters ---------- materialType The Marmot material class which should be represented, e.g., MarmotMaterialHypoElastic. elNumber The number of the element.""" self._elNumber = elNumber self._materialType = materialType self._nNodes = 1 self._nSpatialDimensions = 0 self._ensightType = "point" self._hasMaterial = False self._marmotMaterialWrapper = marmotMaterialWrappers[self._materialType]() self._fields = [ self._marmotMaterialWrapper.fields, ] self._nDof = self._marmotMaterialWrapper.nU self._dofIndicesPermutation = np.arange(0, self._nDof, 1, dtype=int) @property def elNumber(self): return self._elNumber @property def nNodes(self): return self._nNodes @property def nSpatialDimensions(self): return self._nSpatialDimensions @property def nodes(self): return self._nodes @property def nDof(self): return self._nDof @property def fields(self): return self._fields @property def dofIndicesPermutation(self): return self._dofIndicesPermutation @property def ensightType(self): return self._ensightType @property def hasMaterial(self): return self._hasMaterial
[docs] def setNodes(self, nodes: list): """Assign the nodes. Only the first node is considered. Parameters ---------- nodes The list of node instances. """ self._nodes = nodes self._nodeCoordinates = nodes[0].coordinates self._qpCoordinates = nodes[0].coordinates
[docs] def setProperties(self, elementProperties): """ Not used by this wrapper""" raise ValueError("This should not be called for this material wrapper!")
[docs] def initializeElement( self, ): """ Not used by this wrapper"""
[docs] def setMaterial(self, materialName: str, materialProperties: np.ndarray): """Assign a material and material properties to the underlying Wrapper. Furthermore, create two sets of state vars: * the actual set, * and a temporary set for backup in nonlinear iteration schemes Parameters ---------- materialName The name of the requested material. materialProperties The properties for he requested material. """ self._materialProperties = materialProperties self._marmotMaterialWrapper.createMaterial(materialName, materialProperties) self._nStateVars = self._marmotMaterialWrapper.getNumberOfRequiredStateVars() self._stateVars = np.zeros(self._nStateVars) self._stateVarsTemp = np.zeros(self._nStateVars) self._marmotMaterialWrapper.assignStateVars(self._stateVarsTemp) self._hasMaterial = True
def _initializeStateVarsTemp( self, ): self._stateVarsTemp[:] = self._stateVars
[docs] def setInitialCondition(self, stateType, values): self._initializeStateVarsTemp() if stateType == "initialize material": self._marmotMaterialWrapper.initializeYourself() if stateType == "characteristic element length": self._marmotMaterialWrapper.setCharacteristicElementLength(values) self.acceptLastState()
[docs] def computeYourself( self, Ke, Pe, U, dU, time, dTime, ): self._initializeStateVarsTemp() self._marmotMaterialWrapper.computeYourself(Ke, Pe, U, dU, time, dTime) Pe *= -1
[docs] def computeDistributedLoad(self, loadType, P, K, faceID, load, U, time, dTime): """Not implemented for this wrapper.""" raise ValueError("This should not be called for this wrapper.")
[docs] def computeBodyForce(self, P, K, load, U, time, dTime): """Not implemented for this wrapper.""" raise ValueError("This should not be called for this wrapper.")
[docs] def acceptLastState( self, ): """Accept the computed state.""" self._stateVars[:] = self._stateVarsTemp
[docs] def resetToLastValidState( self, ): pass
[docs] def getResultArray(self, result: str, quadraturePoint: int, getPersistentView: bool = True) -> np.ndarray: return self._marmotMaterialWrapper.getResultArray(result, getPersistentView)
[docs] def getCoordinatesAtCenter(self) -> np.ndarray: """Return the only node's coordinates. Returns ------- np.ndarray The node's coordinates.""" return self._nodeCoordinates
[docs] def getCoordinatesAtQuadraturePoints(self) -> np.ndarray: """Return the only qp's coordinates. Returns ------- np.ndarray The qp's coordinates.""" return self._qpCoordinates
[docs] def getNumberOfQuadraturePoints(self) -> int: """Return the only qp's coordinates. Returns ------- np.ndarray The qp's coordinates.""" return 1
@property def visualizationNodes(self) -> list[Node]: """The nodes for visualization. Commonly, these are the same as the nodes of the entity. However, in some cases, the visualization nodes are different from the nodes of the entity, e.g., in case of mixed formulations. """ return self._nodes