Parameter Distributions

By default a realization obtained by an instance of Model will have degenerate distributions of all blob parameters. For any interesting application this is not enough. In order to provide the highest possible flexibility for setting blob parameters this is done by a separate class, which should implement BlobFactory. An implementation is provided by DefaultBlobFactory which allows to easily set independent distributions of any blob parameters to a wide range of distribution families.

DefaultBlobFactory

We can use DefaultBlobFactory class in order to change the distribution functions of the following blob parameters:

  • Amplitudes

  • widths in x and y

  • velocities in x and y

  • pulse shape in x and y

  • blob alignment and tilt

The distributions for these parameters are set with the *_dist arguments. The following distribution functions are implemented:

“exp”

exponential distribution with mean 1

“gamma”

gamma distribution with free_parameter as shape parameter and mean 1

“normal”

normal distribution with zero mean and free_parameter as scale parameter

“uniform”

uniform distribution with mean 1 and free_parameter as width

“ray”

Rayleight distribution with mean 1

“deg”

degenerate distribution at free_parameter

“zeros”

array of zeros

As you can see, some of these distributions require an additional free_parameter to specify the distribution. This is done by the *_parameter arguments.

Let’s take a look at an example. Let’s assume we want to sample the blob amplitudes from normal distribution with 5 as the scale parameter. We chose the defualt distributions for all other blob parameters. We would set up the Model as follows:

    from blobmodel import DefaultBlobFactory, DistributionEnum, Model

    my_blob_factory = DefaultBlobFactory(A_dist=DistributionEnum.normal, A_parameter=5)

    bm = Model(
        Nx=10,
        Ny=10,
        Lx=10,
        Ly=10,
        dt=0.1,
        T=20,
        blob_factory=my_blob_factory,
        t_drain=100,
        num_blobs=100,
    )

    ds = bm.make_realization()

CustomBlobFactory

But what if you want to use a distribution function that is not implemented? Or maybe you even want to change the initial position and arrival time of each blob? In this case you can use the CustomBlobFactory class to define all blob parameters individually. An example could look like this:

    from blobmodel import BlobFactory, AbstractBlobShape, Blob, Model
    import numpy as np

    class CustomBlobFactory(BlobFactory):
        def __init__(self) -> None:
            pass

        def sample_blobs(
            self,
            Ly: float,
            T: float,
            num_blobs: int,
            blob_shape: AbstractBlobShape,
            t_drain: float,
        ) -> list[Blob]:

            # set custom parameter distributions
            amp = np.linspace(0.01, 1, num=num_blobs)
            width = np.linspace(0.01, 1, num=num_blobs)
            vx = np.linspace(0.01, 1, num=num_blobs)
            vy = np.linspace(0.01, 1, num=num_blobs)

            posx = np.zeros(num_blobs)
            posy = np.random.uniform(low=0.0, high=Ly, size=num_blobs)
            t_init = np.random.uniform(low=0, high=T, size=num_blobs)

            # sort blobs by _t_init
            t_init = np.sort(t_init)

            return [
                Blob(
                    blob_id=i,
                    blob_shape=blob_shape,
                    amplitude=amp[i],
                    width_prop=width[i],
                    width_perp=width[i],
                    v_x=vx[i],
                    v_y=vy[i],
                    pos_x=posx[i],
                    pos_y=posy[i],
                    t_init=t_init[i],
                    t_drain=t_drain,
                )
                for i in range(num_blobs)
            ]

        def is_one_dimensional(self) -> bool:
            return False

    bf = CustomBlobFactory()
    tmp = Model(
        Nx=10,
        Ny=10,
        Lx=2,
        Ly=2,
        dt=0.1,
        T=10,
        t_drain=2,
        periodic_y=True,
        num_blobs=10,
        blob_factory=bf,
    )

    ds = tmp.make_realization()

By assigning an array like to the variables amp, width, vx, vy, posx, posy and t_init we can exactly define every single blob parameter of every single blob.

Note

When using CustomBlobFactory it is your responsibility to make sure all blob variables have the correct dimensions. Also, if you wish to normalize the parameters you have to do this manually.