def test_scale(self): factor = [1, 1, 0.5] vo.scale(network=self.net, scale_factor=factor, linear_scaling=[True, False, False], preserve_vol=False)
def compress_geometry(self, factor=None, preserve_fibres=False): r""" Adjust the vertices and recalculate geometry. Save fibre voxels before and after then put them back into the image to preserve fibre volume. Shape will not be conserved. Also make adjustments to the pore and throat properties given an approximate volume change from adding the missing fibre voxels back in Parameters ---------- factor : array_like List of 3 values, [x,y,z], 2 must be one and the other must be between zero and one representing the fraction of the domain height to compress to. preserve_fibres : boolean If the fibre image has been generated and used to calculate pore volumes then preserve fibre volume artificially by adjusting pore and throat sizes """ if factor is None: logger.warning('Please supply a compression factor in the form ' + '[1,1,CR], with CR < 1') return if sp.any(sp.asarray(factor) > 1): logger.warning( 'The supplied compression factor is greater than 1, ' + 'the method is not tested for stretching') return # uncompressed number of fibre voxels in each pore fvu = self["pore.fibre_voxels"] r1 = self["pore.diameter"] / 2 # Most likely boundary pores - prevents divide by zero (vol change zero) r1[r1 == 0] = 1 vo.scale(network=self._net, scale_factor=factor, preserve_vol=False) self.models.regenerate() if preserve_fibres and self._voxel_vol: # compressed number of fibre voxels in each pore fvc = self["pore.fibre_voxels"] # amount to adjust pore volumes by # (based on 1 micron cubed voxels for volume calc) vol_diff = (fvu - fvc) * 1e-18 # don't account for positive volume changes vol_diff[vol_diff < 0] = 0 pv1 = self["pore.volume"].copy() self["pore.volume"] -= vol_diff self["pore.volume"][self["pore.volume"] < 0.0] = 0.0 pv2 = self["pore.volume"].copy() "Now need to adjust the pore diameters" from scipy.special import cbrt rdiff = cbrt(3 * np.abs(vol_diff) / (4 * sp.pi)) self["pore.diameter"] -= 2 * rdiff * sp.sign(vol_diff) "Now as a crude approximation adjust all the throat areas and diameters" "by the same ratio as the increase in a spherical pore surface area" spd = np.ones(len(fvu)) spd[fvu > 0] = (pv2[fvu > 0] / pv1[fvu > 0])**(2 / 3) spd[spd > 1.0] = 1.0 tconns = self._net["throat.conns"][self.map_throats( self._net, self.throats())] # Need to work out the average volume change for the two pores # connected by each throat Boundary pores will be connected to a # throat outside this geometry if there are multiple geoms so get mapping mapping = self._net.map_pores(self, self._net.pores(), return_mapping=True) source = list(mapping['source']) target = list(mapping['target']) ta_diff_avg = np.ones(len(tconns)) for i in np.arange(len(tconns)): np1, np2 = tconns[i] if np1 in source and np2 in source: gp1 = target[source.index(np1)] gp2 = target[source.index(np2)] ta_diff_avg[i] = (spd[gp1] + spd[gp2]) / 2 elif np1 in source: gp1 = target[source.index(np1)] ta_diff_avg[i] = spd[gp1] elif np2 in source: gp2 = target[source.index(np2)] ta_diff_avg[i] = spd[gp2] self["throat.area"] *= ta_diff_avg self["throat.area"][self["throat.area"] < 0] = 0 self["throat.diameter"] = 2 * sp.sqrt(self["throat.area"] / sp.pi) self["throat.indiameter"] *= sp.sqrt(ta_diff_avg) else: logger.warning( 'Fibre volume is not be conserved under compression') # Remove pores with zero throats topo.trim_occluded_throats(self._net)
def compress_geometry(self, factor=None, preserve_fibres=False): r""" Adjust the vertices and recalculate geometry. Save fibre voxels before and after then put them back into the image to preserve fibre volume. Shape will not be conserved. Also make adjustments to the pore and throat properties given an approximate volume change from adding the missing fibre voxels back in Parameters ---------- factor : array_like List of 3 values, [x,y,z], 2 must be one and the other must be between zero and one representing the fraction of the domain height to compress to. preserve_fibres : boolean If the fibre image has been generated and used to calculate pore volumes then preserve fibre volume artificially by adjusting pore and throat sizes """ if factor is None: logger.warning('Please supply a compression factor in the form ' + '[1,1,CR], with CR < 1') return if sp.any(sp.asarray(factor) > 1): logger.warning('The supplied compression factor is greater than 1, ' + 'the method is not tested for stretching') return # uncompressed number of fibre voxels in each pore fvu = self["pore.fibre_voxels"] r1 = self["pore.diameter"]/2 # Most likely boundary pores - prevents divide by zero (vol change zero) r1[r1 == 0] = 1 vo.scale(network=self._net, scale_factor=factor, preserve_vol=False) self.models.regenerate() self.adjust_volumes() if preserve_fibres and self._voxel_vol: # compressed number of fibre voxels in each pore fvc = self["pore.fibre_voxels"] # amount to adjust pore volumes by # (based on 1 micron cubed voxels for volume calc) vol_diff = (fvu-fvc)*1e-18 # don't account for positive volume changes vol_diff[vol_diff < 0] = 0 pv1 = self["pore.volume"].copy() self["pore.volume"] -= vol_diff self["pore.volume"][self["pore.volume"] < 0.0] = 0.0 pv2 = self["pore.volume"].copy() "Now need to adjust the pore diameters" from scipy.special import cbrt rdiff = cbrt(3*np.abs(vol_diff)/(4*sp.pi)) self["pore.diameter"] -= 2*rdiff*sp.sign(vol_diff) "Now as a crude approximation adjust all the throat areas and diameters" "by the same ratio as the increase in a spherical pore surface area" spd = np.ones(len(fvu)) spd[fvu > 0] = (pv2[fvu > 0]/pv1[fvu > 0])**(2/3) spd[spd > 1.0] = 1.0 tconns = self._net["throat.conns"][self.map_throats(self._net, self.throats())] # Need to work out the average volume change for the two pores # connected by each throat Boundary pores will be connected to a # throat outside this geometry if there are multiple geoms so get mapping mapping = self._net.map_pores(self, self._net.pores(), return_mapping=True) source = list(mapping['source']) target = list(mapping['target']) ta_diff_avg = np.ones(len(tconns)) for i in np.arange(len(tconns)): np1, np2 = tconns[i] if np1 in source and np2 in source: gp1 = target[source.index(np1)] gp2 = target[source.index(np2)] ta_diff_avg[i] = (spd[gp1] + spd[gp2]) / 2 elif np1 in source: gp1 = target[source.index(np1)] ta_diff_avg[i] = spd[gp1] elif np2 in source: gp2 = target[source.index(np2)] ta_diff_avg[i] = spd[gp2] self["throat.area"] *= ta_diff_avg self["throat.area"][self["throat.area"] < 0] = 0 self["throat.diameter"] = 2*sp.sqrt(self["throat.area"]/sp.pi) self["throat.indiameter"] *= sp.sqrt(ta_diff_avg) else: logger.warning('Fibre volume is not be conserved under compression') # Remove pores with zero throats topo.trim_occluded_throats(self._net)