# Library of SPAM functions for projecting morphological field onto tetrahedral
# meshes
# Copyright (C) 2020 SPAM Contributors
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
"""
The ``objects`` module offers functions that enables to generate and manipulates geometrical objects in order to represent various phases of materials.
>>> import spam.mesh
>>> spam.mesh.packSpheres()
>>> spam.mesh.packSpheresFromList()
NOTE
----
Objects array conventions:
- Sphere: ``[radius, centerX, centerY, centerZ, phase]``
- Cylinder: ``[radius, centerX, centerY, centerZ, directionX, directionY, directionZ, phase]``
WARNING
-------
This submodule will move to a different module in the near future.
"""
import numpy
from spam.mesh.meshToolkit import crpacking
[docs]
def packSpheres(
totalVolumeFraction,
rejectionLength,
phases,
origin=[0.0] * 3,
lengths=[1.0] * 3,
inside=True,
domain="cube",
vtk=None,
):
"""This function packs one or several sets (phase) of spheres of different
radii and create the corresponding distance fields (one per set).
`The packing algorithm is an iterative process based collective
rearrangement.`
Parameters
----------
totalVolumeFraction: float
The total volume fraction of all the phases
rejectionLength: float
The minimal distance between two sphere surfaces
phases: (nPhase x 3) array
A 2D array containing the phases parameteres.
A line corresponds to a phase and a column to a parameter:
.. code-block:: text
column 0: the minimal ray of the spheres of the phase
column 1: the maximal ray of the spheres of the phase
column 2: the relative volume fraction of the phase
inside: bool, default=True
Defines whether or not the spheres have to be completly inside the domain or if they can intersect it (centres always remain inside).
lengths: array, default=[1, 1, 1]
The size of the domain the spheres are packed into.
origin: array, default=[0, 0, 0]
The origin of the domain.
domain: string, default='cube'
The domain type the spheres are packed into. Options are:
- `cube``: which corresponds to a cuboid. ``lengths`` is then
the length of the cuboids.
- ``cylinder``: which corresponds to a cylinder of diameter ``lengths[0]`` and height ``lengths[2]``.
vtk: string, default=None
Save vtk files of the spheres for each iterations of the packing
algorithm under base name `vtk`.
Returns
-------
(nSpheres x 4) array
For each sphere: ``[radius, ox, oy, oz, phase]``
>>> import spam.mesh
>>> volumeFraction = 0.1
>>> rejectionLength = 1.0
>>> # phase 1: rmin = 5, rmax = 6.5, volume fraction = 0.6 (of total volume fraction)
>>> # phase 2: rmin = 6.5, rmax = 8, volume fraction = 0.4 (of total volume fraction)
>>> phases = [[5.0, 6.5, 0.6], [6.5, 8.0, 0.4]]
>>> # cylinder going from -5 to 135 in z
>>> # with a base radius 50 and center [50, 60
>>> domain = "cylinder"
>>> lengths = [100, 0, 140]
>>> origin = [0, 10, -5]
>>> # generate and pack spheres
>>> spheres = spam.mesh.packSpheres(volumeFraction, rejectionLength, phases, domain=domain, origin=origin, lengths=lengths, vtk="packing-1")
NOTE
----
The output of this function can directly be used by the function ``spam.mesh.projectObjects``.
"""
# if simple table (one phase) convert to table of table anyway
param = [totalVolumeFraction, rejectionLength]
for iPhase, phase in enumerate(phases):
if len(phase) not in [3, 4]:
raise ValueError("Each phase should have at least 3 parameters: [radius, ox, oy, oz]")
if len(phase) == 3:
phase.append(iPhase + 1)
param += phase
# fileName
fileName = vtk if vtk else "crpacking"
cr = crpacking(param, lengths, origin, int(inside), fileName, domain)
cr.createSpheres()
spheres = cr.packSpheres()
if fileName:
cr.writeSpheresVTK()
return spheres
[docs]
def packObjectsFromList(
objects,
rejectionLength,
origin=[0.0] * 3,
lengths=[1.0] * 3,
inside=True,
domain="cube",
vtk=None,
):
"""This function packs a set of predefine spheres.
`The packing algorithm is an iterative process based collective
rearrangement.`
Parameters
----------
objects: (nSpheres x nPram) array
The list of objects. Each line corresponds to:
- for spheres: `[radius, ox, oy, oz, phase]`
rejectionLength: float
The minimal distance between two spheres surfaces
inside: bool, default=True
Defines whether or not the spheres have to be completly inside the domain or if they can intersect it (centres always remain inside).
lengths: array, default=[1.0, 1.0, 1.0]
The size of the domain the spheres are packed into.
origin: array, default=[0.0, 0.0, 0.0]
The origin of the domain.
domain: string, default='cube'
The domain type the spheres are packed into. Options are:
- `cube``: which corresponds to a cuboid. ``lengths`` is then
the length of the cuboids.
- ``cylinder``: which corresponds to a cylinder of diameter ``lengths[0]`` and height ``lengths[2]``.
vtk: string, default=None
Save vtk files of the spheres for each iterations of the packing
algorithm under base name `vtk`.
Returns
-------
(nSpheres x 4) array
For each sphere: ``[radius, ox, oy, oz, phase]``
NOTE
----
The output of this function can directly be used by the function ``spam.mesh.projectObjects``.
"""
# condition inputs for crPacking c++ constructor
param = [0.0, rejectionLength, 1.0, 1.0, 1.0, 1.0]
# test objects size
objects = numpy.array(objects)
if objects.shape[1] not in [5]:
raise NotImplementedError("Objects with {objects.shape[1]} parameters are not implemented.")
# fileName
fileName = vtk if vtk else "crpacking"
cr = crpacking(param, lengths, origin, int(inside), fileName, domain)
cr.setObjects(objects)
spheres = cr.packSpheres()
if fileName:
cr.writeSpheresVTK()
return spheres