1212from scipy .spatial import Delaunay
1313from scipy .special import comb
1414from copy import copy
15+ import cdd
1516
1617from .material import cached_property
1718
1819from ..utils .math import independent_row_indices
1920
20- try :
21- cdd = importlib .import_module ("cdd" )
22- except ImportError as err :
23- print (
24- f"Warning: { err } . "
25- "For full functionality of BurnMan, please install pycddlib."
26- )
21+ cdd_number_type = "float"
2722
2823
2924class SimplexGrid (object ):
@@ -142,21 +137,21 @@ def __init__(
142137 :param return_fractions: Choose whether the generated polytope object
143138 should return fractions or floats.
144139 :type return_fractions: bool
145- :param independent_endmember_occupancies: If specified, this array provides
146- the independent endmember set against which the dependent endmembers
147- are defined.
140+ :param independent_endmember_occupancies: If specified, this array
141+ provides the independent endmember set against which the
142+ dependent endmembers are defined.
148143 :type independent_endmember_occupancies: numpy.array (2D) or None
149144 """
150145 self .set_return_type (return_fractions )
151146 self .equality_matrix = equalities [:, 1 :]
152147 self .equality_vector = - equalities [:, 0 ]
153148
154- self .polytope_matrix = cdd .Matrix (
155- equalities , linear = True , number_type = number_type
156- )
149+ self .polytope_matrix = cdd .matrix_from_array (equalities )
150+ self .polytope_matrix .lin_set = set (range (len (equalities )))
157151 self .polytope_matrix .rep_type = cdd .RepType .INEQUALITY
158- self .polytope_matrix .extend (inequalities , linear = False )
159- self .polytope = cdd .Polyhedron (self .polytope_matrix )
152+
153+ cdd .matrix_append_to (self .polytope_matrix , cdd .matrix_from_array (inequalities ))
154+ self .polytope = cdd .polyhedron_from_matrix (self .polytope_matrix )
160155
161156 if independent_endmember_occupancies is not None :
162157 self .independent_endmember_occupancies = independent_endmember_occupancies
@@ -182,14 +177,14 @@ def raw_vertices(self):
182177 Returns a list of the vertices of the polytope without any
183178 postprocessing. See also endmember_occupancies.
184179 """
185- return self .polytope . get_generators ()[:]
180+ return cdd . copy_generators ( self .polytope ). array
186181
187182 @cached_property
188183 def limits (self ):
189184 """
190185 Return the limits of the polytope (the set of bounding inequalities).
191186 """
192- return np .array (self .polytope . get_inequalities () , dtype = float )
187+ return np .array (cdd . copy_inequalities ( self .polytope ). array , dtype = float )
193188
194189 @cached_property
195190 def n_endmembers (self ):
@@ -206,7 +201,7 @@ def endmember_occupancies(self):
206201 (a processed list of all of the vertex locations).
207202 """
208203 if self .return_fractions :
209- if self . polytope . number_type == "fraction" :
204+ if cdd_number_type == "fraction" :
210205 v = np .array (
211206 [[Fraction (value ) for value in v ] for v in self .raw_vertices ]
212207 )
@@ -225,7 +220,6 @@ def endmember_occupancies(self):
225220 "The combined equality and positivity "
226221 "constraints result in a null polytope."
227222 )
228-
229223 return v [:, 1 :] / v [:, 0 , np .newaxis ]
230224
231225 @cached_property
@@ -281,37 +275,38 @@ def independent_endmember_polytope(self):
281275 """
282276 arr = self .endmembers_as_independent_endmember_amounts
283277 arr = np .hstack ((np .ones ((len (arr ), 1 )), arr [:, :- 1 ]))
284- M = cdd .Matrix (arr , number_type = "fraction" )
278+ M = cdd .matrix_from_array (arr )
285279 M .rep_type = cdd .RepType .GENERATOR
286- return cdd .Polyhedron (M )
280+ return cdd .polyhedron_from_matrix (M )
287281
288282 @cached_property
289283 def independent_endmember_limits (self ):
290284 """
291285 Gets the limits of the polytope as a function of the independent
292286 endmembers.
293287 """
294- return np . array (
295- self . independent_endmember_polytope . get_inequalities (), dtype = float
296- )
288+ ind_poly = self . independent_endmember_polytope
289+ inequalities = cdd . copy_inequalities ( ind_poly ). array
290+ return np . array ( inequalities , dtype = float )
297291
298292 def subpolytope_from_independent_endmember_limits (self , limits ):
299293 """
300294 Returns a smaller polytope by applying additional limits to the amounts
301295 of the independent endmembers.
302296 """
303- modified_limits = self .independent_endmember_polytope .get_inequalities ().copy ()
304- modified_limits .extend (limits , linear = False )
305- return cdd .Polyhedron (modified_limits )
297+ ind_poly = self .independent_endmember_polytope
298+ modified_limits = cdd .copy_inequalities (ind_poly )
299+ cdd .matrix_append_to (modified_limits , cdd .matrix_from_array (limits ))
300+ return cdd .polyhedron_from_matrix (modified_limits )
306301
307302 def subpolytope_from_site_occupancy_limits (self , limits ):
308303 """
309304 Returns a smaller polytope by applying additional limits to the
310305 individual site occupancies.
311306 """
312- modified_limits = self .polytope_matrix . copy ( )
313- modified_limits . extend ( limits , linear = False )
314- return cdd .Polyhedron (modified_limits )
307+ modified_limits = copy ( self .polytope_matrix )
308+ cdd . matrix_append_to ( modified_limits , cdd . matrix_from_array ( limits ) )
309+ return cdd .polyhedron_from_matrix (modified_limits )
315310
316311 def grid (
317312 self ,
@@ -325,15 +320,16 @@ def grid(
325320
326321 :param points_per_edge: Number of points per edge of the polytope.
327322 :type points_per_edge: int
328- :param unique_sorted: The gridding is done by splitting the polytope into
329- a set of simplices. This means that points will be duplicated along
330- vertices, faces etc. If unique_sorted is True, this function
323+ :param unique_sorted: The gridding is done by splitting the polytope
324+ into a set of simplices. This means that points will be duplicated
325+ along vertices, faces etc. If unique_sorted is True, this function
331326 will sort and make the points unique. This is an expensive
332327 operation for large polytopes, and may not always be necessary.
333328 :type unique_sorted: bool
334329 :param grid_type: Whether to grid the polytope in terms of
335330 independent endmember proportions or site occupancies.
336- Choices are 'independent endmember proportions' or 'site occupancies'
331+ Choices are 'independent endmember proportions' or
332+ 'site occupancies'
337333 :type grid_type: str
338334 :param limits: Additional inequalities restricting the
339335 gridded area of the polytope.
@@ -361,11 +357,8 @@ def grid(
361357 )
362358 else :
363359 if grid_type == "independent endmember proportions" :
364- ppns = np .array (
365- self .subpolytope_from_independent_endmember_limits (
366- limits
367- ).get_generators ()[:]
368- )[:, 1 :]
360+ plims = self .subpolytope_from_site_occupancy_limits (limits )
361+ ppns = np .array (cdd .copy_generators (plims ).array )[:, 1 :]
369362 last_ppn = np .array ([1.0 - sum (p ) for p in ppns ]).reshape (
370363 (len (ppns ), 1 )
371364 )
@@ -377,11 +370,8 @@ def grid(
377370 )
378371
379372 elif grid_type == "site occupancies" :
380- occ = np .array (
381- self .subpolytope_from_site_occupancy_limits (
382- limits
383- ).get_generators ()[:]
384- )[:, 1 :]
373+ plims = self .subpolytope_from_site_occupancy_limits (limits )
374+ occ = np .array (cdd .copy_generators (plims ).array )[:, 1 :]
385375 f_occ = occ / (points_per_edge - 1 )
386376
387377 ind = self .independent_endmember_occupancies
0 commit comments