diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 15bf778..a6fc069 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -10,13 +10,13 @@ jobs: - uses: actions/checkout@v2 - name: Setup Mambaforge - uses: conda-incubator/setup-miniconda@v2 + uses: conda-incubator/setup-miniconda@v3 with: use-mamba: true - miniforge-variant: Mambaforge + miniforge-variant: Miniforge3 miniforge-version: latest activate-environment: anaconda-client-env - + - name: Install conda packages shell: bash -l {0} run: | @@ -27,9 +27,9 @@ jobs: shell: bash -l {0} run: | git clone --branch 3.4.0 https://gitlab.com/libeigen/eigen.git - cd eigen + cd eigen mkdir build - cd build + cd build cmake -DBUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DINCLUDE_INSTALL_DIR=$CONDA_PREFIX/include .. make install cd ../.. @@ -57,16 +57,13 @@ jobs: - name: Install Marmot shell: bash -l {0} run: | - git clone --recurse-submodules https://github.com/MAteRialMOdelingToolbox/Marmot/ - cd Marmot - cd modules/core - git clone ${{secrets.MARMOT_MPMCORE_TOKEN}} - cd ../../ - mkdir build - cd build + git clone "https://github.com/MAteRialMOdelingToolbox/Marmot.git" + git clone "https://github.com/BOKU-CMP-MEC-MAT/MarmotMeshfreeCore.git" ./Marmot/modules/core/MarmotMeshfreeCore + mkdir ./Marmot/build + cd ./Marmot/build cmake -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX .. make install - cd ../../ + cd ../.. - name: Install EdelweissFE shell: bash -l {0} diff --git a/README.md b/README.md index e687380..889dfe7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) # EdelweissMPM: A light-weight, platform-independent, parallel material point module for EdelweissFE. @@ -14,7 +14,7 @@ Some features are: * Python for non performance-critical routines * Cython for performance-critical routines - * Parallelization + * Parallelization * Modular system, which is easy to extend * Output to Paraview, Ensight, CSV, matplotlib * Interfaces to powerful direct and iterative linear solvers diff --git a/doc/source/documentation/material_point_managers.rst b/doc/source/documentation/mpm/material_point_managers.rst similarity index 98% rename from doc/source/documentation/material_point_managers.rst rename to doc/source/documentation/mpm/material_point_managers.rst index 0d85d62..1c4ab89 100644 --- a/doc/source/documentation/material_point_managers.rst +++ b/doc/source/documentation/mpm/material_point_managers.rst @@ -18,5 +18,5 @@ Smart Material Point Manager .. automodule:: edelweissmpm.mpmmanagers.smartmpmmanager :private-members: :members: - - + + diff --git a/doc/source/documentation/material_points.rst b/doc/source/documentation/mpm/material_points.rst similarity index 100% rename from doc/source/documentation/material_points.rst rename to doc/source/documentation/mpm/material_points.rst diff --git a/doc/source/index.rst b/doc/source/index.rst index c6248dc..f306d08 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -9,7 +9,7 @@ EdelweissMPM aims to be... - ... a development and learning environment for constitutive models and the material point method, - ... an easy to use tool for coupled problems, - - ... a very flexible tool for implementing and employing special techniques (e.g., the indirect displacement control technique), + - ... a very flexible tool for implementing and employing special techniques (e.g., the indirect displacement control technique), which are often more difficult and time consuming to implement in mature, MPI-parallelized codes, - ... an efficient tool for nonlinear simulations up to medium sized problems (~ :math:`10^5` degrees of freedom). diff --git a/edelweissmpm/cells/base/cell.py b/edelweissmpm/cells/base/cell.py index 2896b15..3fcf229 100644 --- a/edelweissmpm/cells/base/cell.py +++ b/edelweissmpm/cells/base/cell.py @@ -30,7 +30,7 @@ to the material points. Cells are used to compute the residual and stiffness matrices for the global system of equations. -Implementing your own cells can be done easily by subclassing from +Implementing your own cells can be done easily by subclassing from the abstract base class :class:`~CellBase`. """ diff --git a/edelweissmpm/cells/marmotcell/bsplinemarmotcell.pyx b/edelweissmpm/cells/marmotcell/bsplinemarmotcell.pyx index 366fb37..eeca22b 100644 --- a/edelweissmpm/cells/marmotcell/bsplinemarmotcell.pyx +++ b/edelweissmpm/cells/marmotcell/bsplinemarmotcell.pyx @@ -90,7 +90,7 @@ cdef class BSplineMarmotCellWrapper(MarmotCellWrapper): &knotVectorsView[0,0], knotVectorsView.size) - except IndexError: + except ValueError: raise NotImplementedError("Marmot cell {:} not found in library.".format(cellType)) def __dealloc__(self): diff --git a/edelweissmpm/cells/marmotcell/lagrangianmarmotcell.pyx b/edelweissmpm/cells/marmotcell/lagrangianmarmotcell.pyx index 71b68d8..011eaec 100644 --- a/edelweissmpm/cells/marmotcell/lagrangianmarmotcell.pyx +++ b/edelweissmpm/cells/marmotcell/lagrangianmarmotcell.pyx @@ -87,7 +87,7 @@ cdef class LagrangianMarmotCellWrapper(MarmotCellWrapper): try: self._marmotCell = MarmotCellFactory.createCell( cellType.encode('utf-8'), self._cellNumber, &self._nodeCoordinates[0,0], self._nodeCoordinates.size) - except IndexError: + except ValueError: raise NotImplementedError("Marmot cell {:} not found in library.".format(cellType)) def __dealloc__(self): diff --git a/edelweissmpm/cells/test/cell.py b/edelweissmpm/cells/test/cell.py index fd64ca8..0212b16 100644 --- a/edelweissmpm/cells/test/cell.py +++ b/edelweissmpm/cells/test/cell.py @@ -25,7 +25,7 @@ # the top level directory of EdelweissMPM. # --------------------------------------------------------------------- """ -Implementing your own cells can be done easily by subclassing from +Implementing your own cells can be done easily by subclassing from the abstract base class :class:`~CellBase`. """ diff --git a/edelweissmpm/constraints/particlepenaltyweakdirichtlet.py b/edelweissmpm/constraints/particlepenaltyweakdirichtlet.py index c4a5a02..879aaf6 100644 --- a/edelweissmpm/constraints/particlepenaltyweakdirichtlet.py +++ b/edelweissmpm/constraints/particlepenaltyweakdirichtlet.py @@ -41,7 +41,7 @@ def __init__( prescribedStepDelta: dict, penaltyParameter: float, constrain: str | list[int] = "center", - **kwargs + **kwargs, ): self._name = name self._model = model diff --git a/edelweissmpm/fieldoutput/mpresultcollector.pyx b/edelweissmpm/fieldoutput/mpresultcollector.pyx index 5585f36..d10d82f 100644 --- a/edelweissmpm/fieldoutput/mpresultcollector.pyx +++ b/edelweissmpm/fieldoutput/mpresultcollector.pyx @@ -1,32 +1,30 @@ -#!/usr/bin/env python3 # -*- coding: utf-8 -*- # --------------------------------------------------------------------- # -# _____ _ _ _ _____ _____ -# | ____|__| | ___| |_ _____(_)___ ___| ___| ____| -# | _| / _` |/ _ \ \ \ /\ / / _ \ / __/ __| |_ | _| -# | |__| (_| | __/ |\ V V / __/ \__ \__ \ _| | |___ -# |_____\__,_|\___|_| \_/\_/ \___|_|___/___/_| |_____| -# -# +# _____ _ _ _ __ __ ____ __ __ +# | ____|__| | ___| |_ _____(_)___ ___| \/ | _ \| \/ | +# | _| / _` |/ _ \ \ \ /\ / / _ \ / __/ __| |\/| | |_) | |\/| | +# | |__| (_| | __/ |\ V V / __/ \__ \__ \ | | | __/| | | | +# |_____\__,_|\___|_| \_/\_/ \___|_|___/___/_| |_|_| |_| |_| +# +# # Unit of Strength of Materials and Structural Analysis # University of Innsbruck, -# 2017 - today -# +# 2023 - today +# # Matthias Neuner matthias.neuner@uibk.ac.at -# -# This file is part of EdelweissFE. -# +# +# This file is part of EdelweissMPM. +# # 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. +# the top level directory of EdelweissMPM. # --------------------------------------------------------------------- - cimport numpy as np import numpy as np @@ -35,30 +33,30 @@ from libc.stdlib cimport free, malloc cdef class MaterialPointResultCollector: - + cdef public resultsTable - - cdef int nMPs, nSize + + cdef int nMPs, nSize cdef double[:, ::1] res_ cdef double** resultPointers - + def __init__(self, materialPoints:list, result:str): """ - A cdef class for collecting materialPoint results (by using the permanent results pointer (i.e., a numpy array) + A cdef class for collecting materialPoint results (by using the permanent results pointer (i.e., a numpy array) in large array of all materialPoints and all quadrature points. Collecting materialPointal results may be a performance critical part. This cdef class allows for the efficient gathering. A 3D array is assembled if multiple quadrature points are requested (shape ``[materialPoints, quadraturePoints, resultVector]`` ) or a 2D array for one quadrature point ( shape ``[materialPoints, resultVector]`` ). - + Method :func:`~edelweissfe.utils.materialPointresultcollector.MaterialPointResultCollector.getCurrentResults` updates the assembly array and passes it back. - + The caller is responsible to make a copy of it, if persistent results are needed! Parameters ---------- - materialPoints + materialPoints The list of materialPoints for which the results should be collected. result The name of the requested result. @@ -67,17 +65,17 @@ cdef class MaterialPointResultCollector: # hotfix for cython compile error associated with 'range' typing of argument quadraturePoints # this is due to a bug in in cython 0.29.xx and should be fixed in cython 3.x.x # https://github.com/cython/cython/issues/4002 - + self.nMPs = len(materialPoints) # assemble a 2d list of all permanent result arrays (=continously updated np arrays) resultsPointerList = [ el.getResultArray(result, getPersistentView=True) for el in materialPoints ] self.nSize = resultsPointerList[0].shape[0] - + # allocate an equivalent 2D C-array for the pointers to each materialPoints results self.resultPointers = malloc ( sizeof(double*) * self.nMPs ) - + cdef double* ptr cdef double[::1] res # fill the 2D C-array of pointers by accessing the materialPoints' resultArrays memoryviews @@ -86,13 +84,13 @@ cdef class MaterialPointResultCollector: res = el ptr = &res[0] self.resultPointers[ i ] = ptr - + # initialize the large assembly array self.resultsTable = np.empty([self.nMPs, self.nSize] ) - + # an internal use only memoryview is created for accesing the assembly self.res_ = self.resultsTable - + def update(self, ): """Update all results.""" @@ -102,7 +100,7 @@ cdef class MaterialPointResultCollector: # most inner loop: could also be handled by copying the complete vector at once, # but this version turned out to be faster! self.res_[i,k] = self.resultPointers[i][k] - + def getCurrentResults(self,) -> np.ndarray: """Update and get current results. @@ -114,7 +112,7 @@ cdef class MaterialPointResultCollector: self.update() return self.resultsTable - + def __dealloc__(self): free ( self.resultPointers ) diff --git a/edelweissmpm/generators/cooksmembranekernelfunctiongridgenerator.py b/edelweissmpm/generators/cooksmembranekernelfunctiongridgenerator.py index 922d19f..f49a561 100644 --- a/edelweissmpm/generators/cooksmembranekernelfunctiongridgenerator.py +++ b/edelweissmpm/generators/cooksmembranekernelfunctiongridgenerator.py @@ -61,11 +61,10 @@ def generateCooksMembraneKernelFunctionGrid( """ x_coords = np.linspace(x0, x0 + l, nX + 1) vertices = np.zeros((nX + 1, nY + 1, 2)) # (x, y) coordinates - dx = l / nX for i, x in enumerate(x_coords): - y_top = y0 + h0 + h1/l * (x - x0) - y_bottom = y0 + h0/l * (x - x0) + y_top = y0 + h0 + h1 / l * (x - x0) + y_bottom = y0 + h0 / l * (x - x0) y_coords = np.linspace(y_bottom, y_top, nY + 1) @@ -77,22 +76,24 @@ def generateCooksMembraneKernelFunctionGrid( for i in range(nX): for j in range(nY): - quad = np.array([ - vertices[i, j], - vertices[i + 1, j], - vertices[i + 1, j + 1], - vertices[i, j + 1], - ]) + quad = np.array( + [ + vertices[i, j], + vertices[i + 1, j], + vertices[i + 1, j + 1], + vertices[i, j + 1], + ] + ) pCoordinates = np.mean(quad, axis=0) # centroid of the quad - + kf = kernelFunctionFactoryCallback(Node(currentKernelFunctionNumber, pCoordinates)) model.meshfreeKernelFunctions[currentKernelFunctionNumber] = kf currentKernelFunctionNumber += 1 nodes.append(kf.node) - + nG = np.asarray(nodes).reshape(nX, nY) - #for x in range(nX): + # for x in range(nX): # for y in range(nY): # pCoordinates = grid[:, x, y].flatten() @@ -102,7 +103,7 @@ def generateCooksMembraneKernelFunctionGrid( # currentKernelFunctionNumber += 1 # nodes.append(kf.node) - #nG = np.asarray(nodes).reshape(nX, nY) + # nG = np.asarray(nodes).reshape(nX, nY) model.nodes.update({n.label: n for n in nodes}) model.nodeSets["{:}_left".format(name)] = NodeSet("{:}_left".format(name), [n for n in nG[0, :]]) diff --git a/edelweissmpm/generators/cooksmembranequadparticlegridgenerator.py b/edelweissmpm/generators/cooksmembranequadparticlegridgenerator.py index 13f64ed..c05f6fd 100644 --- a/edelweissmpm/generators/cooksmembranequadparticlegridgenerator.py +++ b/edelweissmpm/generators/cooksmembranequadparticlegridgenerator.py @@ -34,6 +34,7 @@ from edelweissmpm.particles.base.baseparticle import BaseParticle from edelweissmpm.sets.particleset import ParticleSet + def generateCooksMembraneParticleGrid( model: MPMModel, journal: Journal, @@ -62,8 +63,8 @@ def generateCooksMembraneParticleGrid( dx = l / nX for i, x in enumerate(x_coords): - y_top = y0 + h0 + h1/l * (x - x0) - y_bottom = y0 + h0/l * (x - x0) + y_top = y0 + h0 + h1 / l * (x - x0) + y_bottom = y0 + h0 / l * (x - x0) y_coords = np.linspace(y_bottom, y_top, nY + 1) @@ -76,12 +77,14 @@ def generateCooksMembraneParticleGrid( for i in range(nX): for j in range(nY): - quad = np.array([ - vertices[i, j], - vertices[i + 1, j], - vertices[i + 1, j + 1], - vertices[i, j + 1], - ]) + quad = np.array( + [ + vertices[i, j], + vertices[i + 1, j], + vertices[i + 1, j + 1], + vertices[i, j + 1], + ] + ) quad_h1 = vertices[i, j + 1][1] - vertices[i, j][1] quad_h2 = vertices[i + 1, j + 1][1] - vertices[i + 1, j][1] pVolume = 0.5 * (quad_h1 + quad_h2) * dx * thickness @@ -118,4 +121,3 @@ def generateCooksMembraneParticleGrid( model.surfaces[f"{name}_left"] = {4: np.ravel(particleGrid[0, :])} return model - diff --git a/edelweissmpm/generators/rectangularbsplinegridgenerator.py b/edelweissmpm/generators/rectangularbsplinegridgenerator.py index c642a70..5289140 100644 --- a/edelweissmpm/generators/rectangularbsplinegridgenerator.py +++ b/edelweissmpm/generators/rectangularbsplinegridgenerator.py @@ -24,40 +24,6 @@ # The full text of the license can be found in the file LICENSE.md at # the top level directory of EdelweissMPM. # --------------------------------------------------------------------- -""" - -A mesh generator, for rectangular geometries and structured quad meshes: - - -.. code-block:: console - - <-----l-----> - nX elements - __ __ __ __ - |__|__|__|__| A - |__|__|__|__| | - |__|__|__|__| | h - |__|__|__|__| | nY elements - | |__|__|__|__| | - | |__|__|__|__| V - x0|_____ - y0 - -nSets, elSets, surface : 'name'_top, _bottom, _left, _right, ... -are automatically generated - -Datalines: -""" - -documentation = { - "x0": "(optional) origin at x axis", - "y0": "(optional) origin at y axis", - "h": "(optional) height of the body", - "l": "(optional) length of the body", - "nX": "(optional) number of elements along x", - "nY": "(optional) number of elements along y", - "elType": "type of element", -} import numpy as np from edelweissfe.points.node import Node @@ -67,12 +33,36 @@ def generateModelData(model, journal, **kwargs): + """ + + A mesh generator, for rectangular geometries and structured quad meshes: + + + .. code-block:: console + + <-----l-----> + nX elements + __ __ __ __ + |__|__|__|__| A + |__|__|__|__| | + |__|__|__|__| | h + |__|__|__|__| | nY elements + | |__|__|__|__| | + | |__|__|__|__| V + x0|_____ + y0 + + nSets, elSets, surface : 'name'_top, _bottom, _left, _right, ... + are automatically generated + + Datalines: + """ name = kwargs.get("name", "rectangular_grid") x0 = float(kwargs.get("x0", 0.0)) y0 = float(kwargs.get("y0", 0.0)) - h = float(kwargs.get("h", 1.0)) - l = float(kwargs.get("l", 1.0)) + hght = float(kwargs.get("h", 1.0)) + lgth = float(kwargs.get("l", 1.0)) nX = int(kwargs.get("nX", 10)) nY = int(kwargs.get("nY", 10)) order = int(kwargs["order"]) @@ -94,13 +84,13 @@ def generateModelData(model, journal, **kwargs): nKnotsY = nKnotsPerCellDirection + (nY - 1) nodeGrid = np.mgrid[ - x0 : x0 + l : nNodesX * 1j, - y0 : y0 + h : nNodesY * 1j, + x0 : x0 + lgth : nNodesX * 1j, + y0 : y0 + hght : nNodesY * 1j, ] - knotsX = np.hstack((np.full(order, x0), np.linspace(x0, x0 + l, nKnotsX - 2 * order), np.full(order, x0 + l))) + knotsX = np.hstack((np.full(order, x0), np.linspace(x0, x0 + lgth, nKnotsX - 2 * order), np.full(order, x0 + lgth))) - knotsY = np.hstack((np.full(order, y0), np.linspace(y0, y0 + h, nKnotsY - 2 * order), np.full(order, y0 + h))) + knotsY = np.hstack((np.full(order, y0), np.linspace(y0, y0 + hght, nKnotsY - 2 * order), np.full(order, y0 + hght))) nodes = [] currentNodeNumber = firstNodeNumber @@ -116,7 +106,6 @@ def generateModelData(model, journal, **kwargs): currentCellNumber = firstCellNumber - cells = [] for x in range(nX): for y in range(nY): cellNodes = [] diff --git a/edelweissmpm/materialpoints/base/mp.py b/edelweissmpm/materialpoints/base/mp.py index 6260b91..58f1545 100644 --- a/edelweissmpm/materialpoints/base/mp.py +++ b/edelweissmpm/materialpoints/base/mp.py @@ -28,7 +28,7 @@ Material points are the basic building blocks of the material point method. They are used to represent the material properties of a continuum. Furthermore, material points are used to store the material properties and state variables of a continuum at a specific location in space and time. Material points are used to compute the material response of the continuum -and to transfer the material properties to the grid. +and to transfer the material properties to the grid. """ from abc import ABC, abstractmethod diff --git a/edelweissmpm/materialpoints/marmotmaterialpoint/mp.pyx b/edelweissmpm/materialpoints/marmotmaterialpoint/mp.pyx index 1669a76..6cfd11f 100644 --- a/edelweissmpm/materialpoints/marmotmaterialpoint/mp.pyx +++ b/edelweissmpm/materialpoints/marmotmaterialpoint/mp.pyx @@ -45,9 +45,9 @@ cdef class MarmotMaterialPointWrapper: # cdef classes cannot subclass. Hence we do not subclass from the BaseMaterialPoint, # but still we follow the interface for compatiblity. - def __cinit__(self, materialPointType, - int materialPointNumber, - np.ndarray vertexCoordinates, + def __cinit__(self, materialPointType, + int materialPointNumber, + np.ndarray vertexCoordinates, double volume, material ): @@ -55,7 +55,7 @@ cdef class MarmotMaterialPointWrapper: Parameters ---------- - materialPointType + materialPointType The MarmotMaterialPoint which should be represented. materialPointNumber The unique number of the MaterialPoint.""" @@ -65,13 +65,13 @@ cdef class MarmotMaterialPointWrapper: self._vertexCoordinatesView = self._vertexCoordinates try: - self._marmotMaterialPoint = MarmotMaterialPointFactory.createMaterialPoint(materialPointType.encode('utf-8'), + self._marmotMaterialPoint = MarmotMaterialPointFactory.createMaterialPoint(materialPointType.encode('utf-8'), materialPointNumber, &self._vertexCoordinatesView[0,0], self._vertexCoordinates.size, volume ) - except IndexError: + except ValueError: raise NotImplementedError("Failed to create instance of MarmotMaterialPoint {:}.".format(materialPointType)) self._number = materialPointNumber @@ -102,7 +102,7 @@ cdef class MarmotMaterialPointWrapper: def assignCells(self, list cells): """The list of currently attached cells.""" self._assignedCells = cells - + @property def materialPointType(self): return self._materialPointType @@ -119,7 +119,7 @@ cdef class MarmotMaterialPointWrapper: self._stateVarsTemp[:] = self._stateVars self._marmotMaterialPoint.initializeYourself() self.acceptStateAndPosition() - + def prepareYourself(self, timeTotal: float, dTime: float): self._stateVarsTemp[:] = self._stateVars self._marmotMaterialPoint.prepareYourself(timeTotal, dTime) @@ -127,13 +127,13 @@ cdef class MarmotMaterialPointWrapper: cpdef void _initializeStateVarsTemp(self, ) nogil: self._stateVarsTemp[:] = self._stateVars - def getResultArray(self, result:str, getPersistentView:bool=True): + def getResultArray(self, result:str, getPersistentView:bool=True): """Get the array of a result, possibly as a persistent view which is continiously updated by the underlying MarmotMaterialPoint.""" cdef string result_ = result.encode('UTF-8') return np.array( self.getStateView(result_ ), copy= not getPersistentView) - + cdef double[::1] getStateView(self, string result ): """Directly access the state vars of the underlying MarmotElement""" @@ -144,19 +144,19 @@ cdef class MarmotMaterialPointWrapper: def getVertexCoordinates(self): """Get the underlying MarmotMaterialPoint vertex coordinates.""" - self._marmotMaterialPoint.getVertexCoordinates(&self._vertexCoordinatesView[0,0]) - + self._marmotMaterialPoint.getVertexCoordinates(&self._vertexCoordinatesView[0,0]) + return self._vertexCoordinates def getCenterCoordinates(self): """Compute the underlying MarmotMaterialPoint center of mass coordinates.""" - self._marmotMaterialPoint.getVertexCoordinates(&self._centerCoordinatesView[0]) + self._marmotMaterialPoint.getVertexCoordinates(&self._centerCoordinatesView[0]) return self._centerCoordinates - cpdef void computeYourself(self, - double timeNew, + cpdef void computeYourself(self, + double timeNew, double dTime, ) except * nogil: """Evaluate residual and stiffness for given time, field, and field increment.""" @@ -179,18 +179,18 @@ cdef class MarmotMaterialPointWrapper: self._marmotMaterialPoint.assignMaterial( MarmotMaterialSection( MarmotMaterialFactory.getMaterialCodeFromName( - materialName.upper().encode('UTF-8')), + materialName.upper().encode('UTF-8')), &self._materialProperties[0], self._materialProperties.shape[0] ) ) except IndexError: raise NotImplementedError("Marmot material {:} not found in library.".format(materialName)) - + self._nStateVars = self._marmotMaterialPoint.getNumberOfRequiredStateVars() - + self._stateVars = np.zeros(self._nStateVars) self._stateVarsTemp = np.zeros(self._nStateVars) - + self._marmotMaterialPoint.assignStateVars(&self._stateVarsTemp[0], self._nStateVars) - + def __dealloc__(self): del self._marmotMaterialPoint diff --git a/edelweissmpm/meshfree/approximations/base/basemeshfreeapproximation.py b/edelweissmpm/meshfree/approximations/base/basemeshfreeapproximation.py index 7146354..d3cfb73 100644 --- a/edelweissmpm/meshfree/approximations/base/basemeshfreeapproximation.py +++ b/edelweissmpm/meshfree/approximations/base/basemeshfreeapproximation.py @@ -24,9 +24,7 @@ # The full text of the license can be found in the file LICENSE.md at # the top level directory of EdelweissMPM. # --------------------------------------------------------------------- -""" - -""" +""" """ from abc import ABC, abstractmethod diff --git a/edelweissmpm/mpmmanagers/utils.pyx b/edelweissmpm/mpmmanagers/utils.pyx index 623debf..58a207a 100644 --- a/edelweissmpm/mpmmanagers/utils.pyx +++ b/edelweissmpm/mpmmanagers/utils.pyx @@ -39,7 +39,7 @@ cdef int _2pow (int exp) nogil: cdef class BoundingBox: """This class represents a bounding box. - + It is constructed from two points A and B, representing 2 opposing vertices of the box. @@ -67,7 +67,7 @@ cdef class BoundingBox: return False return True - + cdef double[::1] getCenterCoordinates(self): return (np.asarray(self.maxCoords) + np.asarray(self.minCoords)) / 2.0 @@ -78,7 +78,7 @@ cdef class BoundingBox: for i in range( _2pow( self.dim )): for j in range(self.dim): - vertices[i, j] = self.minCoords[j] if (i & (1 << j) ) else self.maxCoords[j] + vertices[i, j] = self.minCoords[j] if (i & (1 << j) ) else self.maxCoords[j] return vertices @@ -107,7 +107,7 @@ def buildBoundingBoxFromCells(materialPointCells, int dimension): return BoundingBox(boundingBoxMin, boundingBoxMax) cdef class BoundedCell: - """This classs represents a tuple of a + """This classs represents a tuple of a cell and its bounding box. @@ -195,7 +195,7 @@ cdef class _KDTreeImpl: childDomain = BoundingBox(vertice, self._centerCoordinates) self._children[self.getChildIDForCoordinates(vertice)] = _KDTreeImpl( - childDomain, self._level - 1, + childDomain, self._level - 1, filterCellsInBoundingBox( self._boundedCellsInDomain, childDomain ), self ) @@ -203,7 +203,7 @@ cdef class _KDTreeImpl: self.linkBoundedCellsToChild(self._boundedCellsInDomain, self) cdef getCellForCoordinatesUpwards(self, double[::1] coordinates): - """Search for a recursively cell by first going levels upwards until + """Search for a recursively cell by first going levels upwards until the domain covers the coordinate, followed by a downward search. Parameters @@ -223,8 +223,8 @@ cdef class _KDTreeImpl: return self._parent.getCellForCoordinatesUpwards(coordinates) cdef getCellForCoordinatesDownwards(self, double[::1] coordinates): - """Search for a recursively cell by first going levels down until - until the lowest level is reached. Then, all covered cells are asked for + """Search for a recursively cell by first going levels down until + until the lowest level is reached. Then, all covered cells are asked for the requested coordinates. Parameters @@ -263,7 +263,7 @@ cdef class _KDTreeImpl: """ cdef int num = 0 - cdef int i + cdef int i for i in range(self._domain.dim): if coordinates[i] < self._centerCoordinates[i]: num += _2pow(i) @@ -281,18 +281,18 @@ cdef class _KDTreeImpl: child The lowest level KDTree instance covering those cells. """ - + if self._parent: - return self._parent.linkBoundedCellsToChild(cells, child) + return self._parent.linkBoundedCellsToChild(cells, child) - for cell in cells: + for cell in cells: self.cellsToChild[cell.cell] = child cdef class KDTree: - """This is an efficient Kd tree implementation for searching + """This is an efficient Kd tree implementation for searching the correct cell for a given (material point) coordinate. - + Parameters ---------- domain @@ -304,7 +304,7 @@ cdef class KDTree: """ cdef BoundingBox _domain - cdef _KDTreeImpl _tree + cdef _KDTreeImpl _tree cdef _cellsInDomain def __init__(self, domain , int level, cellsInDomain): @@ -334,12 +334,12 @@ cdef class KDTree: if not self._domain.containsCoordinates(coordinates): raise Exception("requested coordinate {:} outside domain".format(np.asarray(coordinates))) - + if initialGuess: for cell in initialGuess: if cell.isCoordinateInCell(np.asarray(coordinates)): return cell - + # that failed, but let's check the parent KDTree of the first initial guess cell. return (<_KDTreeImpl>self._tree.cellsToChild[initialGuess[0]]).getCellForCoordinatesUpwards(coordinates) diff --git a/edelweissmpm/particles/marmot/marmotparticlewrapper.pyx b/edelweissmpm/particles/marmot/marmotparticlewrapper.pyx index f911a2d..cec7dd6 100644 --- a/edelweissmpm/particles/marmot/marmotparticlewrapper.pyx +++ b/edelweissmpm/particles/marmot/marmotparticlewrapper.pyx @@ -107,7 +107,7 @@ cdef class MarmotParticleWrapper: nMaterialProperties, self._marmotMeshfreeApproximation[0], ) - except IndexError: + except ValueError: raise NotImplementedError("Failed to create instance of MarmotParticle {:}.".format(particleType)) self._nStateVars = self._marmotParticle.getNumberOfRequiredStateVars() diff --git a/edelweissmpm/stepactions/base/mpmbodyloadbase.py b/edelweissmpm/stepactions/base/mpmbodyloadbase.py index 52e9572..939bd3e 100644 --- a/edelweissmpm/stepactions/base/mpmbodyloadbase.py +++ b/edelweissmpm/stepactions/base/mpmbodyloadbase.py @@ -24,8 +24,7 @@ # The full text of the license can be found in the file LICENSE.md at # the top level directory of EdelweissMPM. # --------------------------------------------------------------------- -"""Body loads are loads that act on the entire body of the model. -""" +"""Body loads are loads that act on the entire body of the model.""" from abc import abstractmethod diff --git a/edelweissmpm/stepactions/particledistributedload.py b/edelweissmpm/stepactions/particledistributedload.py index 1d1b642..a73e52b 100644 --- a/edelweissmpm/stepactions/particledistributedload.py +++ b/edelweissmpm/stepactions/particledistributedload.py @@ -66,7 +66,7 @@ def __init__( particles: ParticleSet, distributedLoadType: str, loadVector: np.ndarray, - **kwargs + **kwargs, ): self.name = name diff --git a/examples/003_motion_test_marmot/motion_marmot_test.py b/examples/003_motion_test_marmot/motion_marmot_test.py index 27cd6e7..4412db3 100644 --- a/examples/003_motion_test_marmot/motion_marmot_test.py +++ b/examples/003_motion_test_marmot/motion_marmot_test.py @@ -208,7 +208,7 @@ def change_test_dir(request, monkeypatch): def test_sim(): try: mpmModel = run_sim() - except ValueError as e: + except NotImplementedError as e: pytest.skip(str(e)) return diff --git a/examples/004_dirichlet_test/dirichlet_test.py b/examples/004_dirichlet_test/dirichlet_test.py index bb49a9b..cf24b90 100644 --- a/examples/004_dirichlet_test/dirichlet_test.py +++ b/examples/004_dirichlet_test/dirichlet_test.py @@ -241,7 +241,11 @@ def change_test_dir(request, monkeypatch): def test_sim(): - mpmModel = run_sim() + try: + mpmModel = run_sim() + except NotImplementedError as e: + pytest.skip(str(e)) + return res = mpmModel.nodeFields["displacement"]["dU"] diff --git a/examples/005_simple_column_collapse/simple_column_test.py b/examples/005_simple_column_collapse/simple_column_test.py index 41c7243..a66ffc7 100644 --- a/examples/005_simple_column_collapse/simple_column_test.py +++ b/examples/005_simple_column_collapse/simple_column_test.py @@ -207,7 +207,7 @@ def change_test_dir(request, monkeypatch): def test_sim(): try: mpmModel = run_sim() - except ValueError as e: + except NotImplementedError as e: pytest.skip(str(e)) return diff --git a/examples/006_dirichlet_load/dirichlet_load_test.py b/examples/006_dirichlet_load/dirichlet_load_test.py index 8952d0f..db07546 100644 --- a/examples/006_dirichlet_load/dirichlet_load_test.py +++ b/examples/006_dirichlet_load/dirichlet_load_test.py @@ -194,7 +194,7 @@ def change_test_dir(request, monkeypatch): def test_sim(): try: mpmModel = run_sim() - except ValueError as e: + except NotImplementedError as e: pytest.skip(str(e)) return