Coverage for pySDC / projects / Monodomain / problem_classes / TestODE.py: 91%
76 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-11 14:50 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-11 14:50 +0000
1import logging
2import numpy as np
3from pySDC.core.problem import Problem
4from pySDC.core.common import RegisterParams
5from pySDC.implementations.datatype_classes.mesh import mesh
6from pySDC.projects.Monodomain.datatype_classes.my_mesh import imexexp_mesh
8"""
9Here we define the problems classes for the multirate Dahlquist test equation y'=lambda_I*y + lambda_E*y + lambda_e*y
10Things are done so that it is compatible witht the sweepers.
11"""
14class Parabolic(RegisterParams):
15 def __init__(self, **problem_params):
16 self._makeAttributeAndRegister(*problem_params.keys(), localVars=problem_params, readOnly=True)
17 self.shape = (1,)
18 self.init = ((1,), None, np.dtype("float64"))
21class TestODE(Problem):
22 def __init__(self, **problem_params):
23 self.logger = logging.getLogger("step")
25 self.parabolic = Parabolic(**problem_params)
26 self.size = 1 # one state variable
27 self.init = ((self.size, *self.parabolic.init[0]), self.parabolic.init[1], self.parabolic.init[2])
29 # invoke super init
30 super(TestODE, self).__init__(self.init)
31 # store all problem params dictionary values as attributes
32 self._makeAttributeAndRegister(*problem_params.keys(), localVars=problem_params, readOnly=True)
34 # initial and end time
35 self.t0 = 0.0
36 self.Tend = 1.0 if self.end_time < 0.0 else self.end_time
38 # set lambdas, if not provided by user
39 if not hasattr(self, 'lmbda_laplacian'):
40 self.lmbda_laplacian = -5.0
41 if not hasattr(self, 'lmbda_gating'):
42 self.lmbda_gating = -10.0
43 if not hasattr(self, 'lmbda_others'):
44 self.lmbda_others = -1.0
46 self.dtype_u = mesh
47 self.dtype_f = mesh
49 def init_exp_extruded(self, new_dim_shape):
50 return ((*new_dim_shape, 1, self.init[0][1]), self.init[1], self.init[2])
52 def initial_value(self):
53 u0 = self.dtype_u(self.init, val=1.0)
55 return u0
57 def eval_f(self, u, t, fh=None):
58 if fh is None:
59 fh = self.dtype_f(init=self.init, val=0.0)
61 fh[0] = (self.lmbda_laplacian + self.lmbda_gating + self.lmbda_others) * u[0]
63 return fh
66class MultiscaleTestODE(TestODE):
67 def __init__(self, **problem_params):
68 super(MultiscaleTestODE, self).__init__(**problem_params)
70 self.dtype_f = imexexp_mesh
72 self.rhs_stiff_indeces = [0]
73 self.rhs_stiff_args = [0]
74 self.rhs_nonstiff_indeces = [0]
75 self.rhs_nonstiff_args = [0]
76 self.rhs_exp_args = [0]
77 self.rhs_exp_indeces = [0]
78 self.rhs_non_exp_indeces = []
80 self.constant_lambda_and_phi = True
82 self.one = self.dtype_u(init=self.init, val=1.0)
84 def solve_system(self, rhs, factor, u0, t, u_sol=None):
85 if u_sol is None:
86 u_sol = self.dtype_u(init=self.init, val=0.0)
88 u_sol[0] = rhs[0] / (1 - factor * self.lmbda_laplacian)
90 return u_sol
92 def eval_f(self, u, t, eval_impl=True, eval_expl=True, eval_exp=True, fh=None, zero_untouched_indeces=True):
94 if fh is None:
95 fh = self.dtype_f(init=self.init, val=0.0)
97 if eval_expl:
98 fh.expl[0] = self.lmbda_others * u[0]
100 if eval_impl:
101 fh.impl[0] = self.lmbda_laplacian * u[0]
103 if eval_exp:
104 fh.exp[0] = self.lmbda_gating * u[0]
106 return fh
108 def eval_lmbda_yinf_exp(self, u, lmbda, yinf):
109 lmbda[0] = self.lmbda_gating
110 yinf[0] = 0.0
112 def lmbda_eval(self, u, t, lmbda=None):
113 if lmbda is None:
114 lmbda = self.dtype_u(init=self.init, val=0.0)
116 lmbda[0] = self.lmbda_gating
118 return lmbda