# -*- coding: utf-8 -*-
# ---------------------------------------------------------------------
#
# _____ _ _ _
# | ____|__| | ___| |_ _____(_)___ ___
# | _| / _` |/ _ \ \ \ /\ / / _ \ / __/ __|
# | |__| (_| | __/ |\ V V / __/ \__ \__ \
# |_____\__,_|\___|_| \_/\_/_\___|_|___/___/
# | \/ | ___ ___| |__ / _|_ __ ___ ___
# | |\/| |/ _ \/ __| '_ \| |_| '__/ _ \/ _ \
# | | | | __/\__ \ | | | _| | | __/ __/
# |_| |_|\___||___/_| |_|_| |_| \___|\___|
#
#
# Unit of Strength of Materials and Structural Analysis
# University of Innsbruck,
#
# Research Group for Computational Mechanics of Materials
# Institute of Structural Engineering, BOKU University, Vienna
#
# 2023 - today
#
# Matthias Neuner | matthias.neuner@boku.ac.at
# Thomas Mader | thomas.mader@bokut.ac.at
#
# This file is part of EdelweissMeshfree.
#
# 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 EdelweissMeshfree.
# ---------------------------------------------------------------------
"""
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:
"""
import numpy as np
from edelweissfe.points.node import Node
from edelweissfe.sets.nodeset import NodeSet
from edelweissmeshfree.config.cellelementlibrary import getCellElementClass
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",
}
[docs]
def generateModelData(model, journal, **kwargs):
"""Generate a structured grid of nodes and cells.
Parameters
----------
model : FEModel
The model to which the grid should be added.
journal : Journal
The journal instance for logging purposes.
Other Parameters
----------------
name : str
The name of the grid.
x0 : float
The x-coordinate of the origin.
y0 : float
The y-coordinate of the origin.
h : float
The height of the grid.
l : float
The length of the grid.
nX : int
The number of elements along the x-axis.
nY : int
The number of elements along the y-axis.
firstNodeNumber : int
The first node number.
nodesPerCell : int
The number of nodes per cell.
mpType : str
The type of the material point.
mpClass : str
The name of the material point class.
thickness : float
The thickness of the material point.
mpNumberStart : int
The first material point number.
cellelementProvider : str
The name of the cell element provider class.
cellelementType : str
The type of the cell element.
material : dict
The material definition.
"""
name = kwargs.get("name", "rectangular_grid")
x0 = float(kwargs.get("x0", 0.0))
y0 = float(kwargs.get("y0", 0.0))
height = float(kwargs.get("h", 1.0))
length = float(kwargs.get("l", 1.0))
nX = int(kwargs.get("nX", 10))
nY = int(kwargs.get("nY", 10))
quadratureType = kwargs.get("quadratureType", "QGAUSS")
quadratureOrder = int(kwargs.get("quadratureOrder", 2))
firstCellElementNumber = int(kwargs.get("firstCellElementNumber", 1))
firstNodeNumber = int(kwargs.get("firstNodeNumber", 1))
cellClass = kwargs["cellelementProvider"]
cellType = kwargs["cellelementType"]
CellFactory = getCellElementClass(cellClass)
nodesPerCellElement = int(kwargs.get("nNodesPerCellElement", 4))
if nodesPerCellElement == 4:
nNodesX = nX + 1
nNodesY = nY + 1
elif nodesPerCellElement == 8:
nNodesX = 2 * nX + 1
nNodesY = 2 * nY + 1
else:
raise Exception("Invalid number of nodes per grid cell specified")
grid = np.mgrid[
x0 : x0 + length : nNodesX * 1j,
y0 : y0 + height : nNodesY * 1j,
]
nodes = []
currentNodeNumber = firstNodeNumber
for x in range(nNodesX):
for y in range(nNodesY):
node = Node(currentNodeNumber, grid[:, x, y])
model.nodes[currentNodeNumber] = node
nodes.append(node)
currentNodeNumber += 1
nG = np.asarray(nodes).reshape(nNodesX, nNodesY)
currentCellNumber = firstCellElementNumber
cellElements = []
for x in range(nX):
for y in range(nY):
if nodesPerCellElement == 4:
cellNodes = [nG[x, y], nG[x + 1, y], nG[x + 1, y + 1], nG[x, y + 1]]
elif nodesPerCellElement == 8:
cellNodes = [
nG[2 * x, 2 * y],
nG[2 * x + 2, 2 * y],
nG[2 * x + 2, 2 * y + 2],
nG[2 * x, 2 * y + 2],
nG[2 * x + 1, 2 * y],
nG[2 * x + 2, 2 * y + 1],
nG[2 * x + 1, 2 * y + 2],
nG[2 * x, 2 * y + 1],
]
newCellElement = CellFactory(cellType, currentCellNumber, cellNodes, quadratureType, quadratureOrder)
cellElements.append(newCellElement)
model.cellElements[currentCellNumber] = newCellElement
currentCellNumber += 1
model.nodeSets["{:}_all".format(name)] = NodeSet("{:}_all".format(name), nG.flatten())
model.nodeSets["{:}_left".format(name)] = NodeSet("{:}_left".format(name), [n for n in nG[0, :]])
model.nodeSets["{:}_right".format(name)] = NodeSet("{:}_right".format(name), [n for n in nG[-1, :]])
model.nodeSets["{:}_top".format(name)] = NodeSet("{:}_top".format(name), [n for n in nG[:, -1]])
model.nodeSets["{:}_bottom".format(name)] = NodeSet("{:}_bottom".format(name), [n for n in nG[:, 0]])
model.nodeSets["{:}_leftBottom".format(name)] = NodeSet("{:}_leftBottom".format(name), [nG[0, 0]])
model.nodeSets["{:}_leftTop".format(name)] = NodeSet("{:}_leftTop".format(name), [nG[0, -1]])
model.nodeSets["{:}_rightBottom".format(name)] = NodeSet("{:}_rightBottom".format(name), [nG[-1, 0]])
model.nodeSets["{:}_rightTop".format(name)] = NodeSet("{:}_rightTop".format(name), [nG[-1, -1]])
mpType = kwargs["mpType"]
MPClass = kwargs["mpClass"]
material = kwargs["material"]
# mpThickness = float(kwargs.get("thickness", 1.0))
currentMPNumber = int(kwargs.get("mpNumberStart", len(model.materialPoints) + 1))
for cell in cellElements:
# nMaterialPoints = cell.nMaterialPoints
mpCoords = cell.getRequestedMaterialPointCoordinates()
mpVolumes = cell.getRequestedMaterialPointVolumes()
cellMPs = []
for coord, vol in zip(mpCoords, mpVolumes):
while currentMPNumber in model.materialPoints:
currentMPNumber += 1
mp = MPClass(mpType, currentMPNumber, coord.reshape((1, 2)), vol, material)
model.materialPoints[currentMPNumber] = mp
cellMPs.append(mp)
currentMPNumber += 1
cell.assignMaterialPoints(cellMPs)
for mp in cellMPs:
mp.assignCells(
[
cell,
]
)
return model