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

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/>. 

17 

18""" 

19 The ``objects`` module offers functions that enables to generate and manipulates geometrical objects in order to represent various phases of materials. 

20 

21 >>> import spam.mesh 

22 >>> spam.mesh.packSpheres() 

23 >>> spam.mesh.packSpheresFromList() 

24 

25 NOTE 

26 ---- 

27 

28 Objects array conventions: 

29 

30 - Sphere: ``[radius, centerX, centerY, centerZ, phase]`` 

31 - Cylinder: ``[radius, centerX, centerY, centerZ, directionX, directionY, directionZ, phase]`` 

32 

33 WARNING 

34 ------- 

35 

36 This submodule will move to a different module in the near future. 

37 

38""" 

39 

40import numpy 

41from spam.mesh.meshToolkit import crpacking 

42 

43 

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). 

56 

57 `The packing algorithm is an iterative process based collective 

58 rearrangement.` 

59 

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: 

69 

70 .. code-block:: text 

71 

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 

75 

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: 

84 

85 - `cube``: which corresponds to a cuboid. ``lengths`` is then 

86 the length of the cuboids. 

87 

88 - ``cylinder``: which corresponds to a cylinder of diameter ``lengths[0]`` and height ``lengths[2]``. 

89 

90 vtk: string, default=None 

91 Save vtk files of the spheres for each iterations of the packing 

92 algorithm under base name `vtk`. 

93 

94 Returns 

95 ------- 

96 (nSpheres x 4) array 

97 For each sphere: ``[radius, ox, oy, oz, phase]`` 

98 

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") 

112 

113 NOTE 

114 ---- 

115 The output of this function can directly be used by the function ``spam.mesh.projectObjects``. 

116 

117 """ 

118 

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]") 

124 

125 if len(phase) == 3: 

126 phase.append(iPhase + 1) 

127 

128 param += phase 

129 

130 # fileName 

131 fileName = vtk if vtk else "crpacking" 

132 cr = crpacking(param, lengths, origin, int(inside), fileName, domain) 

133 

134 cr.createSpheres() 

135 spheres = cr.packSpheres() 

136 if fileName: 

137 cr.writeSpheresVTK() 

138 

139 return spheres 

140 

141 

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. 

152 

153 `The packing algorithm is an iterative process based collective 

154 rearrangement.` 

155 

156 Parameters 

157 ---------- 

158 objects: (nSpheres x nPram) array 

159 The list of objects. Each line corresponds to: 

160 

161 - for spheres: `[radius, ox, oy, oz, phase]` 

162 

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: 

173 

174 - `cube``: which corresponds to a cuboid. ``lengths`` is then 

175 the length of the cuboids. 

176 

177 - ``cylinder``: which corresponds to a cylinder of diameter ``lengths[0]`` and height ``lengths[2]``. 

178 

179 vtk: string, default=None 

180 Save vtk files of the spheres for each iterations of the packing 

181 algorithm under base name `vtk`. 

182 

183 Returns 

184 ------- 

185 (nSpheres x 4) array 

186 For each sphere: ``[radius, ox, oy, oz, phase]`` 

187 

188 NOTE 

189 ---- 

190 The output of this function can directly be used by the function ``spam.mesh.projectObjects``. 

191 

192 """ 

193 # condition inputs for crPacking c++ constructor 

194 param = [0.0, rejectionLength, 1.0, 1.0, 1.0, 1.0] 

195 

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.") 

200 

201 # fileName 

202 fileName = vtk if vtk else "crpacking" 

203 cr = crpacking(param, lengths, origin, int(inside), fileName, domain) 

204 

205 cr.setObjects(objects) 

206 spheres = cr.packSpheres() 

207 if fileName: 

208 cr.writeSpheresVTK() 

209 

210 return spheres