|
2 | 2 | import scipy.sparse as nsp
|
3 | 3 |
|
4 | 4 | from pySDC.core.problem import Problem, WorkCounter
|
5 |
| -from pySDC.implementations.datatype_classes.mesh import mesh |
| 5 | +from pySDC.implementations.datatype_classes.mesh import mesh, imex_mesh |
6 | 6 |
|
7 | 7 |
|
8 | 8 | class testequation0d(Problem):
|
@@ -145,3 +145,118 @@ def u_exact(self, t, u_init=None, t_init=None):
|
145 | 145 | me = self.dtype_u(self.init)
|
146 | 146 | me[:] = u_init * self.xp.exp((t - t_init) * self.lambdas)
|
147 | 147 | return me
|
| 148 | + |
| 149 | + |
| 150 | +class test_equation_IMEX(Problem): |
| 151 | + dtype_f = imex_mesh |
| 152 | + dtype_u = mesh |
| 153 | + xp = np |
| 154 | + xsp = nsp |
| 155 | + |
| 156 | + def __init__(self, lambdas_implicit=None, lambdas_explicit=None, u0=0.0): |
| 157 | + """Initialization routine""" |
| 158 | + |
| 159 | + if lambdas_implicit is None: |
| 160 | + re = self.xp.linspace(-30, 19, 50) |
| 161 | + im = self.xp.linspace(-50, 49, 50) |
| 162 | + lambdas_implicit = self.xp.array( |
| 163 | + [[complex(re[i], im[j]) for i in range(len(re))] for j in range(len(im))] |
| 164 | + ).reshape((len(re) * len(im))) |
| 165 | + if lambdas_explicit is None: |
| 166 | + re = self.xp.linspace(-30, 19, 50) |
| 167 | + im = self.xp.linspace(-50, 49, 50) |
| 168 | + lambdas_implicit = self.xp.array( |
| 169 | + [[complex(re[i], im[j]) for i in range(len(re))] for j in range(len(im))] |
| 170 | + ).reshape((len(re) * len(im))) |
| 171 | + lambdas_implicit = self.xp.asarray(lambdas_implicit) |
| 172 | + lambdas_explicit = self.xp.asarray(lambdas_explicit) |
| 173 | + |
| 174 | + assert lambdas_implicit.ndim == 1, f'expect flat list here, got {lambdas_implicit}' |
| 175 | + assert lambdas_explicit.shape == lambdas_implicit.shape |
| 176 | + nvars = lambdas_implicit.size |
| 177 | + assert nvars > 0, 'expect at least one lambda parameter here' |
| 178 | + |
| 179 | + # invoke super init, passing number of dofs, dtype_u and dtype_f |
| 180 | + super().__init__(init=(nvars, None, self.xp.dtype('complex128'))) |
| 181 | + |
| 182 | + self.A = self.xsp.diags(lambdas_implicit) |
| 183 | + self._makeAttributeAndRegister( |
| 184 | + 'nvars', 'lambdas_implicit', 'lambdas_explicit', 'u0', localVars=locals(), readOnly=True |
| 185 | + ) |
| 186 | + self.work_counters['rhs'] = WorkCounter() |
| 187 | + |
| 188 | + def eval_f(self, u, t): |
| 189 | + """ |
| 190 | + Routine to evaluate the right-hand side of the problem. |
| 191 | +
|
| 192 | + Parameters |
| 193 | + ---------- |
| 194 | + u : dtype_u |
| 195 | + Current values of the numerical solution. |
| 196 | + t : float |
| 197 | + Current time of the numerical solution is computed. |
| 198 | +
|
| 199 | + Returns |
| 200 | + ------- |
| 201 | + f : dtype_f |
| 202 | + The right-hand side of the problem. |
| 203 | + """ |
| 204 | + |
| 205 | + f = self.dtype_f(self.init) |
| 206 | + f.impl[:] = u * self.lambdas_implicit |
| 207 | + f.expl[:] = u * self.lambdas_explicit |
| 208 | + self.work_counters['rhs']() |
| 209 | + return f |
| 210 | + |
| 211 | + def solve_system(self, rhs, factor, u0, t): |
| 212 | + r""" |
| 213 | + Simple linear solver for :math:`(I-factor\cdot A)\vec{u}=\vec{rhs}`. |
| 214 | +
|
| 215 | + Parameters |
| 216 | + ---------- |
| 217 | + rhs : dtype_f |
| 218 | + Right-hand side for the linear system. |
| 219 | + factor : float |
| 220 | + Abbrev. for the local stepsize (or any other factor required). |
| 221 | + u0 : dtype_u |
| 222 | + Initial guess for the iterative solver. |
| 223 | + t : float |
| 224 | + Current time (e.g. for time-dependent BCs). |
| 225 | +
|
| 226 | + Returns |
| 227 | + ------- |
| 228 | + me : dtype_u |
| 229 | + The solution as mesh. |
| 230 | + """ |
| 231 | + me = self.dtype_u(self.init) |
| 232 | + L = 1 - factor * self.lambdas_implicit |
| 233 | + L[L == 0] = 1 # to avoid potential divisions by zeros |
| 234 | + me[:] = rhs |
| 235 | + me /= L |
| 236 | + return me |
| 237 | + |
| 238 | + def u_exact(self, t, u_init=None, t_init=None): |
| 239 | + """ |
| 240 | + Routine to compute the exact solution at time t. |
| 241 | +
|
| 242 | + Parameters |
| 243 | + ---------- |
| 244 | + t : float |
| 245 | + Time of the exact solution. |
| 246 | + u_init : pySDC.problem.testequation0d.dtype_u |
| 247 | + Initial solution. |
| 248 | + t_init : float |
| 249 | + The initial time. |
| 250 | +
|
| 251 | + Returns |
| 252 | + ------- |
| 253 | + me : dtype_u |
| 254 | + The exact solution. |
| 255 | + """ |
| 256 | + |
| 257 | + u_init = (self.u0 if u_init is None else u_init) * 1.0 |
| 258 | + t_init = 0.0 if t_init is None else t_init * 1.0 |
| 259 | + |
| 260 | + me = self.dtype_u(self.init) |
| 261 | + me[:] = u_init * self.xp.exp((t - t_init) * (self.lambdas_implicit + self.lambdas_explicit)) |
| 262 | + return me |
0 commit comments