Skip to content

Reaction-Diffusion Scenarios in physical Mode¤

apebench.scenarios.physical.FisherKPP ¤

Bases: Polynomial

Source code in apebench/scenarios/physical/_polynomial.py
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class FisherKPP(Polynomial):
    drag_coef: float = 20.0
    diffusion_coef: float = 0.004
    quadratic_coef: float = -20.0

    ic_config: str = "clamp;0.0;1.0;fourier;5;false;false"  # Overwrite

    def __post_init__(self):
        self.a_coefs = (self.drag_coef, 0.0, self.diffusion_coef, 0.0, 0.0)
        self.poly_coefs = (0.0, 0.0, self.quadratic_coef)

        super().__post_init__()

    def get_scenario_name(self) -> str:
        return f"{self.num_spatial_dims}d_phy_fisher"
quadratic_coef class-attribute instance-attribute ¤
quadratic_coef: float = -20.0
drag_coef class-attribute instance-attribute ¤
drag_coef: float = 20.0
diffusion_coef class-attribute instance-attribute ¤
diffusion_coef: float = 0.004
ic_config class-attribute instance-attribute ¤
ic_config: str = 'clamp;0.0;1.0;fourier;5;false;false'
__post_init__ ¤
__post_init__()
Source code in apebench/scenarios/physical/_polynomial.py
63
64
65
66
67
def __post_init__(self):
    self.a_coefs = (self.drag_coef, 0.0, self.diffusion_coef, 0.0, 0.0)
    self.poly_coefs = (0.0, 0.0, self.quadratic_coef)

    super().__post_init__()
get_scenario_name ¤
get_scenario_name() -> str
Source code in apebench/scenarios/physical/_polynomial.py
69
70
def get_scenario_name(self) -> str:
    return f"{self.num_spatial_dims}d_phy_fisher"

apebench.scenarios.physical.GrayScott ¤

Bases: BaseScenario

Source code in apebench/scenarios/physical/_gray_scott.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
class GrayScott(BaseScenario):
    domain_extent: float = 1.0
    dt: float = 10.0
    num_channels: int = 2  # Overwrite

    num_substeps: int = 10

    ic_config: str = "gray_scott_blobs"  # Overwrite

    feed_rate: float = 0.04
    kill_rate: float = 0.06
    diffusivity_1: float = 2e-5
    diffusivity_2: float = 1e-5

    coarse_proportion: float = 0.5

    def __post_init__(self):
        if self.num_spatial_dims == 1:
            raise ValueError("GrayScott is only supported for 2D and 3D")
        if self.num_channels != 2:
            raise ValueError("Number of channels must be 2 for GrayScott")

    def get_ic_generator(self) -> BaseRandomICGenerator:
        return ex.ic.RandomMultiChannelICGenerator(
            [
                ex.ic.RandomGaussianBlobs(self.num_spatial_dims, one_complement=True),
                ex.ic.RandomGaussianBlobs(self.num_spatial_dims),
            ]
        )

    def _build_stepper(self, dt):
        substepped_stepper = ex.stepper.reaction.GrayScott(
            num_spatial_dims=self.num_spatial_dims,
            domain_extent=self.domain_extent,
            num_points=self.num_points,
            dt=dt / self.num_substeps,
            feed_rate=self.feed_rate,
            kill_rate=self.kill_rate,
            diffusivity_1=self.diffusivity_1,
            diffusivity_2=self.diffusivity_2,
        )

        if self.num_substeps == 1:
            stepper = substepped_stepper
        else:
            stepper = ex.RepeatedStepper(substepped_stepper, self.num_substeps)

        return stepper

    def get_ref_stepper(self):
        return self._build_stepper(self.dt)

    def get_coarse_stepper(self):
        return self._build_stepper(self.dt * self.coarse_proportion)

    def get_scenario_name(self) -> str:
        return f"{self.num_spatial_dims}d_phy_gs"
domain_extent class-attribute instance-attribute ¤
domain_extent: float = 1.0
dt class-attribute instance-attribute ¤
dt: float = 10.0
num_channels class-attribute instance-attribute ¤
num_channels: int = 2
num_substeps class-attribute instance-attribute ¤
num_substeps: int = 10
feed_rate class-attribute instance-attribute ¤
feed_rate: float = 0.04
kill_rate class-attribute instance-attribute ¤
kill_rate: float = 0.06
diffusivity_1 class-attribute instance-attribute ¤
diffusivity_1: float = 2e-05
diffusivity_2 class-attribute instance-attribute ¤
diffusivity_2: float = 1e-05
coarse_proportion class-attribute instance-attribute ¤
coarse_proportion: float = 0.5
ic_config class-attribute instance-attribute ¤
ic_config: str = 'gray_scott_blobs'
__post_init__ ¤
__post_init__()
Source code in apebench/scenarios/physical/_gray_scott.py
25
26
27
28
29
def __post_init__(self):
    if self.num_spatial_dims == 1:
        raise ValueError("GrayScott is only supported for 2D and 3D")
    if self.num_channels != 2:
        raise ValueError("Number of channels must be 2 for GrayScott")
get_scenario_name ¤
get_scenario_name() -> str
Source code in apebench/scenarios/physical/_gray_scott.py
64
65
def get_scenario_name(self) -> str:
    return f"{self.num_spatial_dims}d_phy_gs"

apebench.scenarios.physical.GrayScottType ¤

Bases: BaseScenario

Source code in apebench/scenarios/physical/_gray_scott.py
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
class GrayScottType(BaseScenario):
    domain_extent: float = 2.5
    dt: float = 20.0
    num_channels: int = 2  # Overwrite

    coarse_proportion: float = 0.5

    num_substeps: int = 20

    ic_config: str = "gray_scott_blobs"  # Overwrite

    diffusivity_1: float = 2e-5
    diffusivity_2: float = 1e-5
    pattern_type: Literal[
        "alpha",
        "beta",
        "gamma",
        "delta",
        "epsilon",
        "zeta",
        "eta",
        "theta",
        "iota",
        "kappa",
        "lambda",
        "mu",
    ] = "theta"

    def __post_init__(self):
        if not (self.num_spatial_dims in [2, 3]):
            raise ValueError(
                "Only 2 and 3 spatial dimensions are supported for GrayScott"
            )
        if self.num_channels != 2:
            raise ValueError("Number of channels must be 2 for GrayScott")

    def get_feed_and_kill_rate(
        self,
        pattern_type: Literal[
            "alpha",
            "beta",
            "gamma",
            "delta",
            "epsilon",
            "zeta",
            "eta",
            "theta",
            "iota",
            "kappa",
            "lambda",
            "mu",
        ],
    ):
        if pattern_type == "alpha":
            feed_rate = 0.008
            kill_rate = 0.046
        elif pattern_type == "beta":
            feed_rate = 0.020
            kill_rate = 0.046
        elif pattern_type == "gamma":
            feed_rate = 0.024
            kill_rate = 0.056
        elif pattern_type == "delta":
            feed_rate = 0.028
            kill_rate = 0.056
        elif pattern_type == "epsilon":
            feed_rate = 0.02
            kill_rate = 0.056
        elif pattern_type == "zeta":
            # Does not seem to work
            feed_rate = 0.024
            kill_rate = 0.06
        elif pattern_type == "eta":
            # Does not seem to work
            feed_rate = 0.036
            kill_rate = 0.063
        elif pattern_type == "theta":
            feed_rate = 0.04
            kill_rate = 0.06
        elif pattern_type == "iota":
            feed_rate = 0.05
            kill_rate = 0.0605
        elif pattern_type == "kappa":
            feed_rate = 0.052
            kill_rate = 0.063
        elif pattern_type == "lambda":
            # Does not seem to work
            feed_rate = 0.036
            kill_rate = 0.0655
        elif pattern_type == "mu":
            # Does not seem to work
            feed_rate = 0.044
            kill_rate = 0.066
        else:
            raise ValueError("Invalid pattern type")

        return feed_rate, kill_rate

    def get_ic_generator(self) -> BaseRandomICGenerator:
        return ex.ic.RandomMultiChannelICGenerator(
            [
                ex.ic.RandomGaussianBlobs(self.num_spatial_dims, one_complement=True),
                ex.ic.RandomGaussianBlobs(self.num_spatial_dims),
            ]
        )

    def _build_stepper(self, dt):
        feed_rate, kill_rate = self.get_feed_and_kill_rate(self.pattern_type)
        substepped_stepper = ex.stepper.reaction.GrayScott(
            num_spatial_dims=self.num_spatial_dims,
            domain_extent=self.domain_extent,
            num_points=self.num_points,
            dt=dt / self.num_substeps,
            feed_rate=feed_rate,
            kill_rate=kill_rate,
            diffusivity_1=self.diffusivity_1,
            diffusivity_2=self.diffusivity_2,
        )

        if self.num_substeps == 1:
            stepper = substepped_stepper
        else:
            stepper = ex.RepeatedStepper(substepped_stepper, self.num_substeps)

        return stepper

    def get_ref_stepper(self) -> ex.BaseStepper:
        return self._build_stepper(self.dt)

    def get_coarse_stepper(self) -> ex.BaseStepper:
        return self._build_stepper(self.dt * self.coarse_proportion)

    def get_scenario_name(self) -> str:
        return f"{self.num_spatial_dims}d_phy_gs_{self.pattern_type}"
domain_extent class-attribute instance-attribute ¤
domain_extent: float = 2.5
dt class-attribute instance-attribute ¤
dt: float = 20.0
num_channels class-attribute instance-attribute ¤
num_channels: int = 2
num_substeps class-attribute instance-attribute ¤
num_substeps: int = 20
pattern_type class-attribute instance-attribute ¤
pattern_type: Literal[
    "alpha",
    "beta",
    "gamma",
    "delta",
    "epsilon",
    "zeta",
    "eta",
    "theta",
    "iota",
    "kappa",
    "lambda",
    "mu",
] = "theta"
diffusivity_1 class-attribute instance-attribute ¤
diffusivity_1: float = 2e-05
diffusivity_2 class-attribute instance-attribute ¤
diffusivity_2: float = 1e-05
coarse_proportion class-attribute instance-attribute ¤
coarse_proportion: float = 0.5
ic_config class-attribute instance-attribute ¤
ic_config: str = 'gray_scott_blobs'
__post_init__ ¤
__post_init__()
Source code in apebench/scenarios/physical/_gray_scott.py
100
101
102
103
104
105
106
def __post_init__(self):
    if not (self.num_spatial_dims in [2, 3]):
        raise ValueError(
            "Only 2 and 3 spatial dimensions are supported for GrayScott"
        )
    if self.num_channels != 2:
        raise ValueError("Number of channels must be 2 for GrayScott")
get_scenario_name ¤
get_scenario_name() -> str
Source code in apebench/scenarios/physical/_gray_scott.py
204
205
def get_scenario_name(self) -> str:
    return f"{self.num_spatial_dims}d_phy_gs_{self.pattern_type}"

apebench.scenarios.physical.SwiftHohenberg ¤

Bases: BaseScenario

Source code in apebench/scenarios/physical/_swift_hohenberg.py
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class SwiftHohenberg(BaseScenario):
    domain_extent: float = 10.0 * pi
    dt: float = 0.1

    num_substeps: int = 5

    reactivity: float = 0.7
    critical_number: float = 1.0
    polynomial_coefficients: tuple[float, ...] = (0.0, 0.0, 1.0, -1.0)

    coarse_proportion: float = 0.5

    def __post_init__(self):
        if self.num_spatial_dims == 1:
            raise ValueError("Swift-Hohenberg is only supported for 2D and 3D")

    def _build_stepper(self, dt):
        substepped_stepper = ex.stepper.reaction.SwiftHohenberg(
            num_spatial_dims=self.num_spatial_dims,
            domain_extent=self.domain_extent,
            num_points=self.num_points,
            dt=dt / self.num_substeps,
            reactivity=self.reactivity,
            critical_number=self.critical_number,
            polynomial_coefficients=self.polynomial_coefficients,
        )

        if self.num_substeps == 1:
            stepper = substepped_stepper
        else:
            stepper = ex.RepeatedStepper(substepped_stepper, self.num_substeps)

        return stepper

    def get_ref_stepper(self):
        return self._build_stepper(self.dt)

    def get_coarse_stepper(self):
        return self._build_stepper(self.dt * self.coarse_proportion)

    def get_scenario_name(self) -> str:
        return f"{self.num_spatial_dims}d_phy_sh"
domain_extent class-attribute instance-attribute ¤
domain_extent: float = 10.0 * pi
dt class-attribute instance-attribute ¤
dt: float = 0.1
num_substeps class-attribute instance-attribute ¤
num_substeps: int = 5
reactivity class-attribute instance-attribute ¤
reactivity: float = 0.7
critical_number class-attribute instance-attribute ¤
critical_number: float = 1.0
coarse_proportion class-attribute instance-attribute ¤
coarse_proportion: float = 0.5
ic_config class-attribute instance-attribute ¤
ic_config: str = 'fourier;5;true;true'
__post_init__ ¤
__post_init__()
Source code in apebench/scenarios/physical/_swift_hohenberg.py
20
21
22
def __post_init__(self):
    if self.num_spatial_dims == 1:
        raise ValueError("Swift-Hohenberg is only supported for 2D and 3D")
get_scenario_name ¤
get_scenario_name() -> str
Source code in apebench/scenarios/physical/_swift_hohenberg.py
48
49
def get_scenario_name(self) -> str:
    return f"{self.num_spatial_dims}d_phy_sh"