Coverage for /usr/local/lib/python3.8/site-packages/spam/mesh/structured.py: 100%
32 statements
« prev ^ index » next coverage.py v7.2.3, created at 2023-11-22 13:26 +0000
« prev ^ index » next coverage.py v7.2.3, created at 2023-11-22 13:26 +0000
1# Library of SPAM functions for dealing with structured meshes
2# Copyright (C) 2020 SPAM Contributors
3#
4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU General Public License as published by the Free
6# Software Foundation, either version 3 of the License, or (at your option)
7# any later version.
8#
9# This program is distributed in the hope that it will be useful, but WITHOUT
10# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12# more details.
13#
14# You should have received a copy of the GNU General Public License along with
15# this program. If not, see <http://www.gnu.org/licenses/>.
17"""
18This module offers a set of tools in order to manipulate structured meshes.
20>>> # import module
21>>> import spam.mesh
24The strucutred VTK files used to save the data have the form:
26.. code-block:: text
28 # vtk DataFile Version 2.0
29 VTK file from spam: spam.vtk
30 ASCII
32 DATASET STRUCTURED_POINTS
33 DIMENSIONS nx ny nz
34 ASPECT_RATIO lx ly lz
35 ORIGIN ox oy oz
37 POINT_DATA nx x ny x nz
39 SCALARS myNodalField1 float
40 LOOKUP_TABLE default
41 nodalValue_1
42 nodalValue_2
43 nodalValue_3
44 ...
46 VECTORS myNodalField2 float
47 LOOKUP_TABLE default
48 nodalValue_1_X nodalValue_1_Y nodalValue_1_Z
49 nodalValue_2_X nodalValue_2_Y nodalValue_2_Z
50 nodalValue_3_X nodalValue_3_Y nodalValue_3_Z
51 ...
53 CELL_DATA (nx-1) x (ny-1) x (nz-1)
55 SCALARS myCellField1 float
56 LOOKUP_TABLE default
57 cellValue_1
58 cellValue_2
59 cellValue_3
60 ...
62where nx, ny and nz are the number of nodes in each axis, lx, ly, lz, the mesh length in each axis and ox, oy, oz the spatial postiion of the origin.
63"""
66def createCylindricalMask(shape, radius, voxSize=1.0, centre=None):
67 """
68 Create a image mask of a cylinder in the z direction.
70 Parameters
71 ----------
72 shape: array, int
73 The shape of the array the where the cylinder is saved
75 radius: float
76 The radius of the cylinder
78 voxSize: float (default=1.0)
79 The physical size of a voxel
81 centre: array of floats of size 2, (default None)
82 The center [y,x] of the axis of rotation of the cylinder.
83 If None it is taken to be the centre of the array.
85 Returns
86 -------
87 cyl: array, bool
88 The cylinder
90 """
91 import numpy
93 cyl = numpy.zeros(shape).astype(bool)
95 if centre is None:
96 centre = [float(shape[1]) / 2.0, float(shape[2]) / 2.0]
98 for iy in range(cyl.shape[1]):
99 y = (float(iy) + 0.5) * float(voxSize)
100 for ix in range(cyl.shape[2]):
101 x = (float(ix) + 0.5) * float(voxSize)
102 dist = numpy.sqrt((x - centre[1]) ** 2 + (y - centre[0]) ** 2)
103 if dist < radius:
104 cyl[:, iy, ix] = True
106 return cyl
109def structuringElement(radius=1, order=2, margin=0, dim=3):
110 """
111 This function construct a structural element.
113 Parameters
114 -----------
115 radius : int, default=1
116 The `radius` of the structural element
118 .. code-block:: text
120 radius = 1 gives 3x3x3 arrays
121 radius = 2 gives 5x5x5 arrays
122 ...
123 radius = n gives (2n+1)x(2n+1)x(2n+1) arrays
125 order : int, default=2
126 Defines the shape of the structuring element by setting the order of the norm
127 used to compute the distance between the centre and the border.
129 A representation for the slices of a 5x5x5 element (size=2) from the center to on corner (1/8 of the cube)
131 .. code-block:: text
133 order=numpy.inf: the cube
134 1 1 1 1 1 1 1 1 1
135 1 1 1 1 1 1 1 1 1
136 1 1 1 1 1 1 1 1 1
138 order=2: the sphere
139 1 0 0 0 0 0 0 0 0
140 1 1 0 1 1 0 0 0 0
141 1 1 1 1 1 0 1 0 0
143 order=1: the diamond
144 1 0 0 0 0 0 0 0 0
145 1 1 0 1 0 0 0 0 0
146 1 1 1 1 1 0 1 0 0
148 margin : int, default=0
149 Gives a 0 valued margin of size margin.
151 dim : int, default=3
152 Spatial dimension (2 or 3).
154 Returns
155 --------
156 array
157 The structural element
158 """
159 import numpy
161 tb = tuple([2 * radius + 2 * margin + 1 for _ in range(dim)])
162 ts = tuple([2 * radius + 1 for _ in range(dim)])
163 c = numpy.abs(numpy.indices(ts) - radius)
164 d = numpy.zeros(tb)
165 s = tuple([slice(margin, margin + 2 * radius + 1) for _ in range(dim)])
166 d[s] = numpy.power(numpy.sum(numpy.power(c, order), axis=0), 1.0 / float(order)) <= radius
167 return d.astype("<u1")
170def createLexicoCoordinates(lengths, nNodes, origin=(0, 0, 0)):
171 """
172 Create a list of coordinates following the lexicographical order.
174 Parameters
175 ----------
176 lengths : array of floats
177 The length of the cuboids in every directions.
178 nNodes : array of int
179 The number of nodes of the mesh in every directions.
180 origin : array of floats
181 The coordinates of the origin of the mesh.
183 Returns
184 -------
185 array
186 The list of coordinates. ``shape=(nx*ny*nz, 3)``
188 """
189 import numpy
191 x = numpy.linspace(origin[0], lengths[0] + origin[0], nNodes[0])
192 y = numpy.linspace(origin[1], lengths[1] + origin[1], nNodes[1])
193 z = numpy.linspace(origin[2], lengths[2] + origin[2], nNodes[2])
194 cx = numpy.tile(x, (1, nNodes[1] * nNodes[2]))
195 cy = numpy.tile(numpy.sort(numpy.tile(y, (1, nNodes[0]))), (1, nNodes[2]))
196 cz = numpy.sort(numpy.tile(z, (1, nNodes[0] * nNodes[1])))
197 return numpy.transpose([cx[0], cy[0], cz[0]])