Coverage for /usr/local/lib/python3.8/site-packages/spam/mesh/objects.py: 97%
30 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 projecting morphological field onto tetrahedral
2# meshes
3# Copyright (C) 2020 SPAM Contributors
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation, either version 3 of the License, or (at your option)
8# any later version.
9#
10# This program is distributed in the hope that it will be useful, but WITHOUT
11# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13# more details.
14#
15# You should have received a copy of the GNU General Public License along with
16# this program. If not, see <http://www.gnu.org/licenses/>.
18"""
19 The ``objects`` module offers functions that enables to generate and manipulates geometrical objects in order to represent various phases of materials.
21 >>> import spam.mesh
22 >>> spam.mesh.packSpheres()
23 >>> spam.mesh.packSpheresFromList()
25 NOTE
26 ----
28 Objects array conventions:
30 - Sphere: ``[radius, centerX, centerY, centerZ, phase]``
31 - Cylinder: ``[radius, centerX, centerY, centerZ, directionX, directionY, directionZ, phase]``
33 WARNING
34 -------
36 This submodule will move to a different module in the near future.
38"""
40import numpy
41from spam.mesh.meshToolkit import crpacking
44def packSpheres(
45 totalVolumeFraction,
46 rejectionLength,
47 phases,
48 origin=[0.0] * 3,
49 lengths=[1.0] * 3,
50 inside=True,
51 domain="cube",
52 vtk=None,
53):
54 """This function packs one or several sets (phase) of spheres of different
55 radii and create the corresponding distance fields (one per set).
57 `The packing algorithm is an iterative process based collective
58 rearrangement.`
60 Parameters
61 ----------
62 totalVolumeFraction: float
63 The total volume fraction of all the phases
64 rejectionLength: float
65 The minimal distance between two sphere surfaces
66 phases: (nPhase x 3) array
67 A 2D array containing the phases parameteres.
68 A line corresponds to a phase and a column to a parameter:
70 .. code-block:: text
72 column 0: the minimal ray of the spheres of the phase
73 column 1: the maximal ray of the spheres of the phase
74 column 2: the relative volume fraction of the phase
76 inside: bool, default=True
77 Defines whether or not the spheres have to be completly inside the domain or if they can intersect it (centres always remain inside).
78 lengths: array, default=[1, 1, 1]
79 The size of the domain the spheres are packed into.
80 origin: array, default=[0, 0, 0]
81 The origin of the domain.
82 domain: string, default='cube'
83 The domain type the spheres are packed into. Options are:
85 - `cube``: which corresponds to a cuboid. ``lengths`` is then
86 the length of the cuboids.
88 - ``cylinder``: which corresponds to a cylinder of diameter ``lengths[0]`` and height ``lengths[2]``.
90 vtk: string, default=None
91 Save vtk files of the spheres for each iterations of the packing
92 algorithm under base name `vtk`.
94 Returns
95 -------
96 (nSpheres x 4) array
97 For each sphere: ``[radius, ox, oy, oz, phase]``
99 >>> import spam.mesh
100 >>> volumeFraction = 0.1
101 >>> rejectionLength = 1.0
102 >>> # phase 1: rmin = 5, rmax = 6.5, volume fraction = 0.6 (of total volume fraction)
103 >>> # phase 2: rmin = 6.5, rmax = 8, volume fraction = 0.4 (of total volume fraction)
104 >>> phases = [[5.0, 6.5, 0.6], [6.5, 8.0, 0.4]]
105 >>> # cylinder going from -5 to 135 in z
106 >>> # with a base radius 50 and center [50, 60
107 >>> domain = "cylinder"
108 >>> lengths = [100, 0, 140]
109 >>> origin = [0, 10, -5]
110 >>> # generate and pack spheres
111 >>> spheres = spam.mesh.packSpheres(volumeFraction, rejectionLength, phases, domain=domain, origin=origin, lengths=lengths, vtk="packing-1")
113 NOTE
114 ----
115 The output of this function can directly be used by the function ``spam.mesh.projectObjects``.
117 """
119 # if simple table (one phase) convert to table of table anyway
120 param = [totalVolumeFraction, rejectionLength]
121 for iPhase, phase in enumerate(phases):
122 if len(phase) not in [3, 4]:
123 raise ValueError("Each phase should have at least 3 parameters: [radius, ox, oy, oz]")
125 if len(phase) == 3:
126 phase.append(iPhase + 1)
128 param += phase
130 # fileName
131 fileName = vtk if vtk else "crpacking"
132 cr = crpacking(param, lengths, origin, int(inside), fileName, domain)
134 cr.createSpheres()
135 spheres = cr.packSpheres()
136 if fileName:
137 cr.writeSpheresVTK()
139 return spheres
142def packObjectsFromList(
143 objects,
144 rejectionLength,
145 origin=[0.0] * 3,
146 lengths=[1.0] * 3,
147 inside=True,
148 domain="cube",
149 vtk=None,
150):
151 """This function packs a set of predefine spheres.
153 `The packing algorithm is an iterative process based collective
154 rearrangement.`
156 Parameters
157 ----------
158 objects: (nSpheres x nPram) array
159 The list of objects. Each line corresponds to:
161 - for spheres: `[radius, ox, oy, oz, phase]`
163 rejectionLength: float
164 The minimal distance between two spheres surfaces
165 inside: bool, default=True
166 Defines whether or not the spheres have to be completly inside the domain or if they can intersect it (centres always remain inside).
167 lengths: array, default=[1.0, 1.0, 1.0]
168 The size of the domain the spheres are packed into.
169 origin: array, default=[0.0, 0.0, 0.0]
170 The origin of the domain.
171 domain: string, default='cube'
172 The domain type the spheres are packed into. Options are:
174 - `cube``: which corresponds to a cuboid. ``lengths`` is then
175 the length of the cuboids.
177 - ``cylinder``: which corresponds to a cylinder of diameter ``lengths[0]`` and height ``lengths[2]``.
179 vtk: string, default=None
180 Save vtk files of the spheres for each iterations of the packing
181 algorithm under base name `vtk`.
183 Returns
184 -------
185 (nSpheres x 4) array
186 For each sphere: ``[radius, ox, oy, oz, phase]``
188 NOTE
189 ----
190 The output of this function can directly be used by the function ``spam.mesh.projectObjects``.
192 """
193 # condition inputs for crPacking c++ constructor
194 param = [0.0, rejectionLength, 1.0, 1.0, 1.0, 1.0]
196 # test objects size
197 objects = numpy.array(objects)
198 if objects.shape[1] not in [5]:
199 raise NotImplementedError("Objects with {objects.shape[1]} parameters are not implemented.")
201 # fileName
202 fileName = vtk if vtk else "crpacking"
203 cr = crpacking(param, lengths, origin, int(inside), fileName, domain)
205 cr.setObjects(objects)
206 spheres = cr.packSpheres()
207 if fileName:
208 cr.writeSpheresVTK()
210 return spheres