Showing 1 of 3 files from the diff.

@@ -914,9 +914,13 @@
Loading
914 914
    return im
915 915
916 916
917 -
def cylinders(shape: List[int], radius: int, ncylinders: int,
918 -
              phi_max: float = 0, theta_max: float = 90, length: float = None,
919 -
              verbose: bool = True):
917 +
def _cylinders(shape: List[int],
918 +
               radius: int,
919 +
               ncylinders: int,
920 +
               phi_max: float = 0,
921 +
               theta_max: float = 90,
922 +
               length: float = None,
923 +
               verbose: bool = True):
920 924
    r"""
921 925
    Generates a binary image of overlapping cylinders.
922 926
@@ -999,38 +1003,20 @@
Loading
999 1003
    return ~dt
1000 1004
1001 1005
1002 -
def cylinders_porosity(shape: list,
1003 -
                       radius: int,
1004 -
                       porosity: float,
1005 -
                       phi_max: float = 0,
1006 -
                       theta_max: float = 90,
1007 -
                       length: float = None,
1008 -
                       max_iter: int = 3,
1009 -
                       return_fiber_number: bool = False,
1010 -
                       verbose: bool = True):
1006 +
def cylinders(shape: List[int],
1007 +
              radius: int,
1008 +
              ncylinders: int = None,
1009 +
              porosity: float = None,
1010 +
              phi_max: float = 0,
1011 +
              theta_max: float = 90,
1012 +
              length: float = None,
1013 +
              max_iter: int = 3):
1011 1014
    r"""
1012 -
    Generates a binary image of overlapping cylinders, with a target
1013 -
    porosity input. Delegates cylinder creation to generators.cylinders.
1015 +
    Generates a binary image of overlapping cylinders given porosity OR number
1016 +
    of cylinders.
1014 1017
1015 1018
    This is a good approximation of a fibrous mat.
1016 1019
1017 -
    The cylinders_porosity function works by estimating the number of
1018 -
    cylinders needed to be inserted into the domain by estimating
1019 -
    cylinder length, and exploiting the fact that, when inserting any
1020 -
    potentially overlapping objects randomly into a volume v_total (which
1021 -
    has units of pixels and is equal to dimx x dimy x dimz, for example),
1022 -
    such that the total volume of objects added to the volume is v_added
1023 -
    (and includes any volume that was inserted but overlapped with already
1024 -
    occupied space), the resulting porosity will be equal to
1025 -
    exp(-v_added/v_total).
1026 -
1027 -
    After intially estimating the cylinder number and inserting a small
1028 -
    fraction of the estimated number, the true cylinder volume is
1029 -
    calculated, the estimate refined, and a larger fraction of cylinders
1030 -
    inserted. This is repeated a number of times according to the
1031 -
    'iterations' argument, yielding an image with a porosity close to
1032 -
    the goal.
1033 -
1034 1020
    Parameters
1035 1021
    ----------
1036 1022
    shape : list
@@ -1038,6 +1024,10 @@
Loading
1038 1024
        number of voxels. 2D images are not permitted.
1039 1025
    radius : scalar
1040 1026
        The radius of the cylinders in voxels
1027 +
    ncylinders : scalar
1028 +
        The number of cylinders to add to the domain. Adjust this value to
1029 +
        control the final porosity, which is not easily specified since
1030 +
        cylinders overlap and intersect different fractions of the domain.
1041 1031
    porosity : scalar
1042 1032
        The targeted value for the porosity of the generated mat. The
1043 1033
        function uses an algorithm for predicted the number of required
@@ -1073,10 +1063,41 @@
Loading
1073 1063
    -------
1074 1064
    image : ND-array
1075 1065
        A boolean array with ``True`` values denoting the pore space
1076 -
    fiber_number : scalar
1077 -
        The number of fibers added to the image. This is optional, and whether
1078 -
        it is returned is determined by 'return_fiber_number'
1066 +
1067 +
    Notes
1068 +
    -----
1069 +
    The cylinders_porosity function works by estimating the number of
1070 +
    cylinders needed to be inserted into the domain by estimating
1071 +
    cylinder length, and exploiting the fact that, when inserting any
1072 +
    potentially overlapping objects randomly into a volume v_total (which
1073 +
    has units of pixels and is equal to dimx x dimy x dimz, for example),
1074 +
    such that the total volume of objects added to the volume is v_added
1075 +
    (and includes any volume that was inserted but overlapped with already
1076 +
    occupied space), the resulting porosity will be equal to
1077 +
    exp(-v_added/v_total).
1078 +
1079 +
    After intially estimating the cylinder number and inserting a small
1080 +
    fraction of the estimated number, the true cylinder volume is
1081 +
    calculated, the estimate refined, and a larger fraction of cylinders
1082 +
    inserted. This is repeated a number of times according to the
1083 +
    'max_iter' argument, yielding an image with a porosity close to
1084 +
    the goal.
1085 +
1079 1086
    """
1087 +
    if ncylinders is not None:
1088 +
        im = _cylinders(
1089 +
            shape=shape,
1090 +
            radius=radius,
1091 +
            ncylinders=ncylinders,
1092 +
            phi_max=phi_max,
1093 +
            theta_max=theta_max,
1094 +
            length=length,
1095 +
        )
1096 +
        return im
1097 +
1098 +
    if porosity is None:
1099 +
        raise Exception("'ncylinders' and 'porosity' can't be both None")
1100 +
1080 1101
    if max_iter < 3:
1081 1102
        raise Exception("Iterations must be greater than or equal to 3")
1082 1103
@@ -1104,12 +1125,11 @@
Loading
1104 1125
        fractions.append(fractions[i - 1] + (max_iter - i) ** 2 * subdif)
1105 1126
1106 1127
    im = np.ones(shape, dtype=bool)
1107 -
    for frac in tqdm(fractions, disable=not verbose, file=sys.stdout,
1108 -
                     desc="Adding fibers"):
1128 +
    for frac in tqdm(fractions, file=sys.stdout, desc="Adding fibers"):
1109 1129
        n_fibers_total = n_pixels_to_add / vol_fiber
1110 1130
        n_fibers = int(np.ceil(frac * n_fibers_total) - n_fibers_added)
1111 1131
        if n_fibers > 0:
1112 -
            im = im & ps.generators.cylinders(
1132 +
            im = im & _cylinders(
1113 1133
                shape, radius, n_fibers, phi_max, theta_max, length, verbose=False
1114 1134
            )
1115 1135
        n_fibers_added += n_fibers
@@ -1118,11 +1138,8 @@
Loading
1118 1138
        vol_added = get_num_pixels(porosity)
1119 1139
        vol_fiber = vol_added / n_fibers_added
1120 1140
1121 -
    if verbose:
1122 -
        print(f"{n_fibers_added} fibers were added to reach the target porosity.\n")
1141 +
    print(f"{n_fibers_added} fibers were added to reach the target porosity.\n")
1123 1142
1124 -
    if return_fiber_number:
1125 -
        return im, n_fibers_added
1126 1143
    return im
1127 1144
1128 1145
Files Coverage
porespy 88.1%
Project Totals (16 files) 88.1%
codecov-umbrella
Build #311426196 -
unittests
1
codecov:
2
  branch: dev
3

4
coverage:
5
  precision: 1
6
  round: down
7
  range: "50...100"
8

9
  status:
10
    project:
11
      default:
12
        target: auto
13
        threshold: 0.5%
14
        branches: null
15

16
    patch:
17
      default:
18
        target: auto
19
        threshold: 0.5%
20
        branches: null
21

22
comment:
23
  layout: "header, diff, changes, sunburst, uncovered"
24
  branches: null
25
  behavior: default
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading