src/convection_diffusion.py

Fri, 08 May 2026 17:16:34 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Fri, 08 May 2026 17:16:34 -0500
changeset 4
49b062acace9
parent 3
c3a4f4bb87f7
permissions
-rw-r--r--

Do not directly depend on ndarray, but through numpy

1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1 import os
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
2 from dataclasses import dataclass
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
3 from posix import mkdir
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
4 from termios import B0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
5 from typing import Optional, Tuple, Union
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
6
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
7 import dolfinx.geometry as geo
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
8 import numpy as np
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
9 import ufl
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
10 from dolfinx import fem, mesh
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
11 from dolfinx.fem.petsc import (
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
12 apply_lifting,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
13 assemble_matrix,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
14 assemble_vector,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
15 create_vector,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
16 set_bc,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
17 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
18 from mpi4py import MPI
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
19 from petsc4py import PETSc
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
20
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
21 try:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
22 import pointsource_pde.dolfinx_extras as dx
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
23
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
24 from dolfinx_access import (
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25 cell_FunctionSpace_f64,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
26 max_Function_f64_p2,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
27 min_Function_f64_p2,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
28 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
29 except:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
30 import src.dolfinx_extras as dx
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
31
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
32
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
33 @dataclass
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
34 class XBound:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
35 # Parameter bounds for convection-diffusion operator estimates
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
36 mu_dual: float = 3.0 # ||μ||_M(Ω) bound
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
37 k_min: float = 0.1 # min diffusion > 0 (coercivity)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
38 k_max: float = 2.0 # max diffusion
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
39 c_Linf: float = 0.5 # max(|c1|,|c2|) L∞ bound
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
40 diam: float = 1.41 # domain diameter (√2 for unit square)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
41 T: float = 1.0 # final time
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
42
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
43 def __add__(self, other: "XBound") -> "XBound":
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
44 # Conservative combination: min(k_min), max(c_Linf) for energy bounds"""
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
45 other = XBound(
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
46 **{
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
47 k: getattr(other, k, getattr(self, k))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
48 for k in self.__dataclass_fields__
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
49 }
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
50 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
51 return XBound(
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
52 mu_dual=max(self.mu_dual, other.mu_dual),
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
53 k_min=min(self.k_min, other.k_min),
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
54 k_max=max(self.k_max, other.k_max),
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
55 c_Linf=max(self.c_Linf, other.c_Linf),
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
56 diam=max(self.diam, other.diam),
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
57 T=max(self.T, other.T),
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
58 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
59
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
60
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
61 class ConvectionDiffusion:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
62 def __init__(
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
63 self,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
64 u0,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
65 g,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
66 # w0,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
67 domain_size=[-2, 2, -2, 2],
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
68 nx=32,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
69 ny=32,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
70 degree=2,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71 t0=0.0,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
72 T=1.0,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
73 num_steps=50,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
74 p=None,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
75 Delta_t=None,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
76 C_stab=1.0,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77 alpha=1.0, # \alpha = k_m/2, k convective coefficient, k>=km
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
78 beta=1.0, # \beta = \| c \|_\infty^2 /k_m
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
79 C_emb=1.0,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
80 C_reg=1.0,
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
81 xbound=XBound,
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
82 override_lipschitz=None,
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
83 override_lipschitz_pair=None,
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
84 ):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
85 self.p = p # L^p, p=2
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
86 self.C_stab = C_stab # adjoint stability constant
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
87 self.alpha = alpha # coercivity lower bound for k
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
88 self.beta = beta # theoretical parameter
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
89 self.C_emb = C_emb # embedding constant
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
90 self.C_reg = C_reg
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
91 if Delta_t is None:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
92 self.Delta_t = T / num_steps # Matches your N=50 intent
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
93 else:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
94 self.Delta_t = Delta_t
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
95
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
96 self.domain_size = domain_size
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
97 self.nx = nx
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
98 self.ny = ny
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
99 self.degree = degree
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
100 self.T = T
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
101 self.xbound = xbound
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
102
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
103 self.num_steps = num_steps
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
104 self.dt = (T - t0) / num_steps
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
105 self.t0 = t0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
106
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
107 self.save_for_plot = False
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
108
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
109 self.override_lipschitz = override_lipschitz
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
110 self.override_lipschitz_pair = override_lipschitz_pair
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
111
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
112 domain = mesh.create_rectangle(
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
113 MPI.COMM_SELF,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
114 [
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
115 np.array([domain_size[0], domain_size[2]]),
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
116 np.array([domain_size[1], domain_size[3]]),
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
117 ],
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
118 [nx, ny],
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
119 mesh.CellType.triangle,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
120 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
121 self.domain = domain
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
122 # Compute the domain volume for the adjoint Lipschitz factor
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
123 self.domain_size = domain_size
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
124 # Domain diameter from your domain_size
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
125 self.diam = np.sqrt(
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
126 (domain_size[1] - domain_size[0]) ** 2
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
127 + (domain_size[3] - domain_size[2]) ** 2
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
128 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
129
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
130 V = fem.functionspace(domain, ("Lagrange", degree))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
131 self.V = V
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
132
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
133 self.u0 = fem.Function(V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
134 self.u0.name = "u0"
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
135 self.u0.interpolate(u0)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
136
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
137 self.g = fem.Function(V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
138 self.g.name = "g"
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
139 self.g.interpolate(g)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
140 self.bcs = [] # Initialize BCS as LIST
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
141 self.adjoint_bcs = [] # Initialize ADJOINT BCS as LIST (w = 0)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
142
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
143 # Identify boundary facets for Dirichlet BC location (e.g. left/right boundaries at x=domain_size[0] or x=domain_size[1])
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
144 fdim = domain.topology.dim - 1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
145 # Γ₁ facets: TOP/BOTTOM boundaries (y = ymin, ymax) - STATE Dirichlet u = g
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
146 gamma1_facets = mesh.locate_entities_boundary(
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
147 domain,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
148 fdim,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
149 lambda x: (
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
150 np.isclose(x[1], domain_size[2]) # x[1] = y = ymin
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
151 | np.isclose(x[1], domain_size[3])
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
152 ), # x[1] = y = ymax
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
153 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
154 # Γ₂ facets: LEFT/RIGHT boundaries (x = xmin, xmax) - ADJOINT Dirichlet w = 0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
155 gamma2_facets = mesh.locate_entities_boundary(
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
156 domain,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
157 fdim,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
158 lambda x: (
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
159 np.isclose(x[0], domain_size[0]) # x[0] = x = xmin
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
160 | np.isclose(x[0], domain_size[1])
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
161 ), # x[0] = x = xmax
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
162 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
163 # STATE BC: u = g on Γ₁ (top/bottom)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
164 dofs_gamma1 = fem.locate_dofs_topological(V, fdim, gamma1_facets)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
165 # Create BC and ADD TO LIST
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
166 bc = fem.dirichletbc(self.g, dofs_gamma1) # V inferred from self.g!
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
167 self.bcs.append(bc)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
168
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
169 # ADJOINT BC: w = 0 on Γ₁ (same facets, homogenized)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
170 zero = fem.Constant(domain, PETSc.ScalarType(0.0))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
171 dofs_gamma2 = fem.locate_dofs_topological(V, fdim, gamma2_facets)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
172 bc_adjoint = fem.dirichletbc(zero, dofs_gamma2, V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
173 self.adjoint_bcs.append(bc_adjoint)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
174
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
175 self.fdim = fdim
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
176 self.boundary_facets = np.unique(np.concatenate((gamma1_facets, gamma2_facets)))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
177
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
178 ux = fem.Function(V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
179 wpx = fem.Function(V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
180 self.ux = ux
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
181 self.wpx = wpx
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
182 dim = V.mesh.topology.dim
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
183 self.expr2_form = fem.form(ufl.inner(ufl.grad(ux), ufl.grad(wpx)) * ufl.dx)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
184 self.expr3_forms = tuple(
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
185 fem.form(wpx * ufl.grad(ux)[i] * ufl.dx) for i in range(dim)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
186 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
187
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
188 # Only scalar case
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
189 self.k = fem.Constant(domain, PETSc.ScalarType(0.0)) # c[0] scalar
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
190 self.c0 = fem.Constant(domain, PETSc.ScalarType(0.0)) # c[0] scalar
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
191 self.c1 = fem.Constant(domain, PETSc.ScalarType(0.0)) # c[1] scalar
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
192 u_n = fem.Function(V) # New copy!
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
193 u_n.name = "u_n"
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
194 self.u_n = u_n
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
195 u, w, v = ufl.TrialFunction(V), ufl.TrialFunction(V), ufl.TestFunction(V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
196 dt = self.dt
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
197 # Forward bilinear form (backward Euler)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
198 a = (
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
199 u * v * ufl.dx
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
200 + dt * ufl.dot(self.k * ufl.grad(u), ufl.grad(v)) * ufl.dx
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
201 + dt * (self.c0 * u.dx(0) + self.c1 * u.dx(1)) * v * ufl.dx
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
202 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
203 self.bilinear_form = fem.form(a)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
204 L = u_n * v * ufl.dx
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
205 self.linear_form = fem.form(L)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
206
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
207 # Adjoint bilinear form
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
208 w_n = fem.Function(V) # New copy!
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
209 w_n.name = "w_n"
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
210 self.w_n = w_n
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
211 j_u = fem.Function(V) # New copy!
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
212 j_u.name = "j_u"
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
213 self.j_u = j_u
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
214 a2 = (
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
215 w * v * ufl.dx
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
216 + dt
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
217 * (
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
218 ufl.dot(self.k * ufl.grad(w), ufl.grad(v))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
219 - (self.c0 * w.dx(0) * v + self.c1 * w.dx(1) * v)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
220 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
221 * ufl.dx
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
222 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
223 self.bilinear_form_w = fem.form(a2)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
224 # Step n=N-1: L2 uses w_n = w^N=0 → solves w^{N-1}. (∂t)_primal^*
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
225 # Step n=N-2: L2 uses w_n = w^{N-1} → solves w^{N-2}
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
226 # Replace your L2 with 2 simple forms (same notation)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
227
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
228 L2 = w_n * v * ufl.dx + dt * j_u * v * ufl.dx # kown w_n (previous step)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
229 self.linear_form_w = fem.form(L2)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
230
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
231 # Solving forward PDE
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
232 def apply(self, x):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
233 μ, (k, c) = x
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
234
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
235 domain = self.domain
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
236 V = self.V
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
237 dt = self.dt
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
238 bcs = self.bcs
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
239
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
240 # initial condition
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
241 u_n = self.u_n
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
242 u_n.x.array[:] = self.u0.x.array
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
243 u_n.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
244
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
245 # Linear form: only contains u_n * v (Dirichlet on Γ1 is handled via bc)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
246
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
247 # Assemble matrix WITH Dirichlet BCs applied
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
248 self.c0.value = c[0]
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
249 self.c1.value = c[1]
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
250 self.k.value = k
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
251 linear_form = self.linear_form
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
252 bilinear_form = self.bilinear_form
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
253 A = assemble_matrix(bilinear_form, bcs=bcs)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
254 A.assemble()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
255
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
256 # Create reusable RHS vector (will be filled each timestep)
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
257 b = create_vector(linear_form.function_spaces)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
258 b_ps = create_vector(linear_form.function_spaces)
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
259
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
260 # Prepare solver once
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
261 solver = PETSc.KSP().create(domain.comm)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
262 solver.setOperators(A)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
263 solver.setType(PETSc.KSP.Type.PREONLY)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
264 solver.getPC().setType(PETSc.PC.Type.LU)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
265
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
266 # Form point source contribution
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
267 mesh = V.mesh
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
268 element = V.element.basix_element
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
269 mesh_nodes = mesh.geometry.x
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
270 cmap = mesh.geometry.cmap
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
271
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
272 b_ps.assemblyBegin()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
273
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
274 with b_ps.localForm() as loc_b:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
275 loc_b.set(0)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
276
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
277 for point, alpha in μ.iter_padded():
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
278 cell_id = cell_FunctionSpace_f64(V._cpp_object, point)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
279
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
280 if cell_id < 0:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
281 print(f"Point {point} is outside the mesh.")
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
282 else:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
283 cell_dofs = V.dofmap.cell_dofs(cell_id)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
284
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
285 geom_dofs = mesh.geometry.dofmap[cell_id]
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
286 ref = cmap.pull_back(
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
287 np.array([[point[0], point[1]]]), mesh_nodes[geom_dofs]
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
288 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
289 phi = element.tabulate(0, ref)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
290
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
291 b_ps.setValuesLocal(
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
292 cell_dofs,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
293 alpha * phi,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
294 addv=PETSc.InsertMode.ADD_VALUES,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
295 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
296
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
297 b_ps.assemblyEnd()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
298
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
299 t = self.t0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
300 num_steps = self.num_steps
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
301 bcs = self.bcs
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
302
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
303 u_n_list = []
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
304 for i in range(num_steps):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
305 t += dt
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
306
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
307 # b.assemblyBegin()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
308
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
309 # zero-out and assemble RHS (M * u_n part)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
310 with b.localForm() as loc_b:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
311 loc_b.set(0)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
312 assemble_vector(b, linear_form) # b = (u^n, v)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
313
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
314 b.axpy(1.0, b_ps)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
315
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
316 # Apply homogeneous Dirichlet BC correction to RHS and finalize vector
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
317 apply_lifting(b, [bilinear_form], [bcs]) # [[bc1, bc2, ...]]
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
318 b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
319 set_bc(b, bcs) # list [bc1, bc2, ...]
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
320 # b.assemble()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
321 #
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
322 # b.assemblyEnd()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
323
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
324 # b.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
325
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
326 # Solve linear problem A * uh = b
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
327 uh = fem.Function(V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
328 uh.name = "uh"
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
329 solver.solve(b, uh.x.petsc_vec)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
330 uh.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
331
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
332 # Update u_n for next step, store uh
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
333 u_n.x.array[:] = uh.x.array
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
334 u_n.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
335 u_n_list.append(uh) # Unique objects
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
336
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
337 return u_n_list
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
338
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
339 # Solving the adjoint problem
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
340
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
341 def solve_adjoint_pde(self, j, x, u_n_list):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
342 μ, (k, c) = x
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
343
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
344 domain = self.domain
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
345 V = self.V
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
346 dt = self.dt
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
347 adjoint_bcs = self.adjoint_bcs
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
348
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
349 num_steps = len(u_n_list)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
350
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
351 assert len(j) == num_steps, f"MISMATCH: j({len(j)}) != u_n_list({num_steps})"
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
352 # Terminal condition: w(T) = 0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
353 w_n = self.w_n
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
354 w_n.x.array[:] = 0.0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
355 w_n.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
356
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
357 self.c0.value = c[0]
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
358 self.c1.value = c[1]
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
359 self.k.value = k
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
360 j_u = self.j_u
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
361 bilinear_form_w = self.bilinear_form_w
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
362 linear_form_w = self.linear_form_w
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
363
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
364 A2 = assemble_matrix(bilinear_form_w, bcs=adjoint_bcs) # Fixed bcs
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
365 A2.assemble()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
366
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
367 # Create vector for RHS to be updated each step
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
368 b2 = create_vector(linear_form_w.function_spaces)
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
369
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
370 solver = PETSc.KSP().create(domain.comm)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
371 solver.setOperators(A2)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
372 solver.setType(PETSc.KSP.Type.PREONLY)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
373 solver.getPC().setType(PETSc.PC.Type.LU)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
374
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
375 t = self.t0 + num_steps * dt # Start at time T
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
376
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
377 # N+1 adjoint values to match N PDE steps
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
378 w_n_list = [None] * (num_steps + 1)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
379 whT = fem.Function(V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
380 whT.x.array[:] = 0.0 # w^N = 0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
381 whT.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
382 w_n_list[num_steps] = whT # Store at FINAL index
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
383
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
384 # backward steps**: compute w^{N-1}, ..., w^0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
385
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
386 for i in range(num_steps - 1, -1, -1):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
387 t -= dt
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
388
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
389 # Source term at current time step: j(t_i)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
390
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
391 j_u.x.array[:] = j[i].x.array
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
392 j_u.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
393
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
394 # Update RHS
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
395 with b2.localForm() as loc_b2:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
396 loc_b2.set(0)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
397 assemble_vector(b2, linear_form_w)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
398
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
399 apply_lifting(b2, [bilinear_form_w], [adjoint_bcs]) # [forms] → [bcs]
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
400 b2.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
401 set_bc(b2, adjoint_bcs)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
402
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
403 # set_bc(b2, adjoint_bcs) # list BC object
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
404 # b2.assemble()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
405
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
406 wh = fem.Function(V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
407 wh.name = "wh"
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
408 solver.solve(b2, wh.x.petsc_vec)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
409 wh.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
410
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
411 # Update w_n for next iteration and store
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
412 w_n.x.array[:] = wh.x.array
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
413 w_n.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
414 w_n_list[i] = wh
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
415
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
416 return w_n_list
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
417
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
418 # Compute the differential operator
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
419 def diff_adjdir(self, j, x, apply_result=None):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
420 """
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
421 Returns dual space elements: (dual_μ, (dual_k, (dual_c1, dual_c2)))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
422 - scalar coeff → float sensitivity
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
423 - Function coeff → fem.Function sensitivity (Fréchet derivative)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
424 """
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
425 u_n_list = apply_result if apply_result is not None else self.apply(x)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
426 w_n_list = self.solve_adjoint_pde(j, x, u_n_list)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
427 dt = self.dt
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
428 V = self.V
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
429 dim = V.mesh.topology.dim
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
430
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
431 # Extract coefficients and check types
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
432 _mu, (k, c) = x
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
433 # is_scalar_mu = isinstance(mu, (int, float, np.number))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
434 is_scalar_k = isinstance(k, (int, float, np.number))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
435 is_scalar_c = all(isinstance(ci, (int, float, np.number)) for ci in c)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
436
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
437 # 1. expr1: dual sensitivity w.r.t. μ = ∫₀^T w_p dt (always Function)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
438 wp_bar = fem.Function(V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
439 wp_bar.x.array[:] = (
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
440 0.5
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
441 * dt
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
442 * (
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
443 w_n_list[0].x.array
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
444 + w_n_list[-1].x.array
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
445 + 2 * np.sum([w.x.array for w in w_n_list[1:-1]], axis=0)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
446 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
447 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
448
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
449 ux = self.ux
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
450 wpx = self.wpx
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
451
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
452 # 2. expr2: dual sensitivity w.r.t. k
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
453 if is_scalar_k:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
454 # k scalar → ⟨expr2, δk⟩ = δk ∫ ∇u·∇w_p → scalar
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
455 expr2 = 0.0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
456
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
457 form = self.expr2_form
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
458
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
459 for n, (u, wp) in enumerate(zip(u_n_list, w_n_list)):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
460 ux.x.array[:] = u.x.array[:]
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
461 ux.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
462 wpx.x.array[:] = wp.x.array[:]
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
463 wpx.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
464 v2 = fem.assemble_scalar(form)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
465 weight = 0.5 * dt if (n == 0 or n == len(u_n_list) - 1) else dt
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
466 expr2 -= weight * v2
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
467
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
468 else:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
469 raise Exception("Unimplemented - out of date")
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
470
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
471 # k Function → ⟨expr2, δk⟩ = ∫ expr2 δk → expr2 = ∇u·∇w_p (pointwise)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
472 expr2 = fem.Function(V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
473 expr2a = expr2.x.array
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
474
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
475 for n, (u, wp) in enumerate(zip(u_n_list, w_n_list)):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
476 form = ufl.inner(ufl.grad(u), ufl.grad(wp)) * ufl.dx
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
477 v2 = fem.assemble_scalar(fem.form(form))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
478 weight = 0.5 * dt if (n == 0 or n == len(u_n_list) - 1) else dt
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
479 expr2a -= weight * v2
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
480
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
481 # 3. expr3: dual sensitivity w.r.t. c = (c1, c2)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
482 if is_scalar_c:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
483 # Scalar c → return tuple of 2 floats
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
484
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
485 forms = self.expr3_forms
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
486
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
487 def val(i):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
488 expr3i = 0.0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
489 for n, (u, wp) in enumerate(zip(u_n_list, w_n_list)):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
490 ux.x.array[:] = u.x.array[:]
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
491 ux.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
492 wpx.x.array[:] = wp.x.array[:]
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
493 wpx.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
494 v3 = fem.assemble_scalar(forms[i])
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
495 weight = 0.5 * dt if (n == 0 or n == len(u_n_list) - 1) else dt
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
496 expr3i -= weight * v3
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
497 return expr3i
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
498
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
499 expr3 = tuple(val(i) for i in range(dim))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
500
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
501 else:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
502 raise Exception("Unimplemented - out of date")
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
503
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
504 # Function c → return tuple of 2 Functions (pointwise derivatives)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
505 def val(i):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
506 # expr3[i]. x.array[:] = 0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
507 expr3i = fem.Function(V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
508 expr3ia = expr3i.x.array[:]
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
509 for n, (u, wp) in enumerate(zip(u_n_list, w_n_list)):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
510 form = wp * ufl.grad(u)[i] * ufl.dx
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
511 v3 = fem.assemble_scalar(fem.form(form))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
512 weight = 0.5 * dt if (n == 0 or n == len(u_n_list) - 1) else dt
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
513 expr3ia -= weight * v3
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
514 return expr3i
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
515
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
516 expr3 = tuple(val(i) for i in range(dim))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
517
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
518 if self.save_for_plot:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
519 self.plot_wp_bar = wp_bar
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
520 self.plot_u_n_list = u_n_list
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
521 self.plot_w_n_list = w_n_list
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
522 self.plot_j_n_list = j
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
523 self.plot_aux = (k, c)
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
524
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
525 return wp_bar, (expr2, expr3)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
526
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
527 def do_plot(self, iter, μ, frames, prefix):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
528 n = self.num_steps
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
529 k, (c1, c2) = self.plot_aux
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
530 np.savez_compressed(
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
531 "%s/res_%d.npz" % (prefix, iter),
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
532 wp_bar_array=self.plot_wp_bar.x.array,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
533 u_n_list_array=[self.plot_u_n_list[i].x.array for i in frames],
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
534 w_n_list_array=[self.plot_w_n_list[i].x.array for i in frames],
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
535 j_n_list_array=[self.plot_j_n_list[i].x.array for i in frames],
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
536 k=k,
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
537 c1=c1,
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
538 c2=c2,
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
539 frames=frames,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
540 times=list(map(lambda i: self.T * i / (n - 1), frames)),
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
541 mu=[[point[0], point[1], alpha] for point, alpha in μ.iter_padded()],
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
542 )
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
543 # print("Aux variables: k: %f, c1: %f, c2: %f" % (k, c1, c2))
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
544
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
545 # def _stability_prefactor(
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
546 # self, *, C_stab=None, alpha=None, beta=None, T=None, C_emb=None, C_reg=None
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
547 # ):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
548 # """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
549 # Return the stability prefactor
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
550 # P := (C_stab/alpha) * (1 + sqrt(T)*(1 + sqrt(beta)/sqrt(alpha)))
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
551 # and the measure-to-functional constant L_e_mu := C_emb * C_reg * sqrt(T).
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
552 # Return (P, L_e_mu):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
553 # """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
554 # # self._stability_prefactor(alpha=0.5, T=2.0)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
555
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
556 # # Read from arguments or instance attributes
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
557 # C_stab = C_stab if C_stab is not None else self.C_stab
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
558 # alpha = alpha if alpha is not None else self.alpha
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
559 # beta = beta if beta is not None else self.beta
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
560 # T = T if T is not None else self.T
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
561 # C_emb = C_emb if C_emb is not None else self.C_emb
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
562 # C_reg = C_reg if C_reg is not None else self.C_reg
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
563
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
564 # # Stability factor P
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
565
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
566 # P = (C_stab / alpha) * (1 + np.sqrt(T) * (1 + np.sqrt(beta) / np.sqrt(alpha)))
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
567 # L_e_mu = C_emb * C_reg * np.sqrt(T)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
568
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
569 # return P, L_e_mu
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
570
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
571 # # Solution operator Lipschitz factor
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
572 # def lipschitz_factor(self, xbound=None):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
573 # """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
574 # Conservative Lipschitz factor for the forward solution operator mapping
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
575 # (k,c,mu) -> u. Returns a single scalar C_Lip such that
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
576 # ||u2 - u1|| <= C_Lip * (||k2-k1|| + ||c2-c1|| + ||mu2-mu1||_* )
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
577 # (we use a conservative form combining the measure and (k,c) pieces).
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
578 # """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
579 # P, L_e_mu = self._stability_prefactor()
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
580 # # Conservative combined choice: multiply P by max(1, L_e_mu)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
581 # C_Lip = P * max(1.0, L_e_mu)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
582 # return C_Lip
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
583 def diff_chain_lipschitz_factor(self, Delta_t=None):
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
584 """
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
585 Compute a Lipschitz factor C_tot^Lip using locally accumulated bounds
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
586 M_J = 1.
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
587 """
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
588
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
589 if self.override_lipschitz is not None:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
590 return self.override_lipschitz
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
591
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
592 # Use existing diff_bound3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
593 C_mu_adj, C_k_adj, C_c_adj = self.diff_bound3(Delta_t=Delta_t)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
594
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
595 if Delta_t is None:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
596 # fall back to the scheme used in diff_bound3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
597 Delta_t = self.dt
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
598
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
599 N = int(np.ceil(self.T / Delta_t))
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
600
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
601 # Use local per‑step bounds
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
602 C_adj_step = C_mu_adj / N
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
603 C_state_step = C_k_adj / N
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
604 C_c_step = C_c_adj / N
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
605
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
606 # Per‑step "Lipschitz"
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
607 l_e_local = C_adj_step + C_state_step + C_c_step
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
608
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
609 # Global Lipschitz constants
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
610 L_e = l_e_local * N
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
611 M_e = 1.2 * L_e
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
612 L_A = 0.5 * C_state_step * N
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
613
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
614 # PDE/coercivity
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
615 alpha = max(0.1, self.alpha) # guard α ≥ 0.1
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
616 M_J = 1.0
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
617
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
618 # C_tot^Lip
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
619 inv_alpha = 1.0 / alpha
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
620 inv_alpha_sq = inv_alpha * inv_alpha
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
621 C_tot = inv_alpha * (L_e + inv_alpha_sq * L_A * M_e) * M_J
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
622 return C_tot
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
623
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
624 def diff_chain_lipschitz_factor_pair(self, Delta_t=None):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
625 """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
626 Return (C^Lip_μ/M_J, C^Lip_aux/M_J)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
627 """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
628
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
629 if self.override_lipschitz_pair is not None:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
630 return self.override_lipschitz_pair
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
631
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
632 C_mu_adj, C_k_adj, C_c_adj = self.diff_bound3(Delta_t=Delta_t)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
633
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
634 if Delta_t is None:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
635 Delta_t = self.dt
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
636
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
637 N = int(np.ceil(self.T / Delta_t))
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
638
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
639 # Extract per-component per-step bounds (smaller scaling)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
640 C_mu_step = C_mu_adj / N
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
641 C_aux_step = max(C_k_adj, C_c_adj) / N
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
642
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
643 # TINY Lipschitz factors
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
644 C_Lip_mu = C_mu_step * N
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
645 C_Lip_aux = C_aux_step * N
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
646
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
647 # Light coercivity scaling
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
648 alpha = self.alpha
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
649 inv_alpha = 1.0 / alpha
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
650
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
651 C_mu_tot = C_Lip_mu * inv_alpha
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
652 C_aux_tot = C_Lip_aux * inv_alpha
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
653
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
654 return C_mu_tot, C_aux_tot
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
655
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
656 def diff_bound3(self, Delta_t=None):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
657 xbound = self.xbound
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
658 xb_combined = xbound # xbound[0] + xbound[1] if len(xbound) > 1 else xbound[0]
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
659
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
660 k_min = getattr(xb_combined, "k_min", self.alpha)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
661 c_Linf = getattr(xb_combined, "c_Linf", np.sqrt(self.beta * k_min))
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
662 diam = getattr(xb_combined, "diam", self.diam)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
663 T = getattr(xb_combined, "T", self.T)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
664
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
665 Pe = c_Linf * diam / k_min
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
666 gamma = c_Linf**2 / k_min
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
667 # adaptive time step size Delta_t (Delta_t = 0.01 in the test)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
668 if Delta_t is None:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
669 Delta_t = min(0.1, k_min / c_Linf**2, 0.01 * T) # CFL-like
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
670
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
671 # Accumulate N = T/Delta_t local steps
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
672 N = int(np.ceil(T / Delta_t))
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
673
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
674 # Per-step factors
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
675 exp_local = np.exp(0.5 * gamma * Delta_t)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
676 C_adj_step = np.sqrt(Delta_t * (exp_local + Delta_t / k_min))
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
677 C_state_step = np.sqrt(Delta_t) * np.sqrt(1 + Pe**2)
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
678
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
679 # Total accumulated bound (geometric sum <= N * max_step)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
680 C_adj_PDE = N * C_adj_step
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
681 C_state = N * C_state_step
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
682
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
683 # Use the embedding constant
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
684 C_mu_adj = self.C_emb * C_adj_PDE # ∫φ δμ
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
685 C_k_adj = C_state * C_adj_PDE # ∫∇u·∇φ δk
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
686 C_c_adj = C_state * C_adj_PDE * c_Linf # ∫∂x u φ δc1 and c2
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
687
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
688 return C_mu_adj, C_k_adj, C_c_adj
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
689
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
690 # ||S(x)||_Y→X ≤ C_state ||μ||_M(Ω) [time-independent μ]
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
691 def codomain_bound(self):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
692 xbound = self.xbound
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
693
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
694 # Extract parameters
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
695 if hasattr(xbound, "k_min"):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
696 xb = xbound
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
697 elif hasattr(xbound, "__len__") and len(xbound) > 0:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
698 xb = xbound[0] + xbound[1] if len(xbound) > 1 else xbound[0]
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
699 else:
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
700 xb = xbound
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
701
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
702 k_min = getattr(xb, "k_min", self.alpha)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
703 c_Linf = getattr(xb, "c_Linf", np.sqrt(self.beta * k_min))
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
704 mu_dual = getattr(xb, "mu_dual", 3.0)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
705 diam = getattr(xb, "diam", self.diam)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
706 T = getattr(xb, "T", self.T)
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
707
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
708 Pe = c_Linf * diam / k_min
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
709 if not hasattr(self, "Delta_t"):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
710 Delta_t = min(0.1, k_min / c_Linf**2, 0.01 * T)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
711 else:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
712 Delta_t = self.Delta_t
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
713
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
714 N = int(np.ceil(T / Delta_t))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
715 gamma = c_Linf**2 / k_min
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
716 exp_local = np.exp(0.25 * gamma * Delta_t)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
717
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
718 C_state_step = np.sqrt(Delta_t) * np.sqrt(1 + 0.5 * Pe**2) * exp_local
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
719 C_state = N * C_state_step
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
720
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
721 return C_state * mu_dual
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
722
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
723
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
724 def own(u):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
725 # """
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
726 # Return a version of u that is guaranteed to be uniquely owned.
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
727 # If u has other Python references, return a deep copy.
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
728 # """
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
729 # # sys.getrefcount(u) includes the temporary reference inside getrefcount,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
730 # # so '2' means exactly one external reference.
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
731 # if sys.getrefcount(u) <= 2:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
732 # return u # safe: no other references
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
733
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
734 # deep copy into a new Function
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
735 u_new = fem.Function(u.function_space)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
736 # Does not work
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
737 # u_new.x.petsc_vec.copy(u.x.petsc_vec)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
738 # u_new.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
739 np.copyto(u_new.x.array, u.x.array)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
740 return u_new
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
741
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
742
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
743 def nn2(x):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
744 return None if isinstance(x, float) else dx.norm2_squared(x)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
745
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
746
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
747 class PlotFactory:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
748 def __init__(self, pde, n_plots=5):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
749 self.pde = pde
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
750 self.n_plots = n_plots
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
751
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
752 m = n_plots
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
753 n = pde.num_steps
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
754 pde.save_for_plot = True
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
755 self.plot_frames = list(map(lambda i: i * (n - 1) // (m - 1), range(0, m)))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
756 self.pde = pde
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
757
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
758 def produce(self, prefix):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
759 return Plotter(self.pde, self.n_plots, prefix)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
760
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
761
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
762 class Plotter:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
763 def __init__(self, pde, n_plots, prefix):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
764 m = n_plots
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
765 n = pde.num_steps
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
766 pde.save_for_plot = True
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
767 self.plot_frames = list(map(lambda i: i * (n - 1) // (m - 1), range(0, m)))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
768 self.pde = pde
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
769 os.makedirs(prefix, exist_ok=True)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
770 self.prefix = prefix
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
771
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
772 def plot(self, iter, μ):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
773 self.pde.do_plot(iter, μ, self.plot_frames, self.prefix)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
774
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
775
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
776 class QuadraticRegularisation:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
777 """
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
778 Quadratic regularisation functional for the auxiliary variables
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
779 """
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
780
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
781 def _own(self, x):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
782 return x if isinstance(x, float) else own(x)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
783
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
784 def __init__(self, α, base=None):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
785 self.α = α
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
786 if base is not None:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
787 (k, (c1, c2)) = base
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
788 self.base = (self._own(k), (self._own(c1), self._own(c2)))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
789 self.base_norm_squared = (nn2(k), (nn2(c1), nn2(c2)))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
790 else:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
791 self.base = None
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
792
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
793 def _apply1(self, x, b, n):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
794 if isinstance(x, float):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
795 d = x if b is None else x - b
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
796 return d * d / 2.0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
797 else:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
798 if b is not None:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
799 return (dx.norm2_squared(x) + n) / 2.0 + dx.dot(x, b)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
800 return dx.norm2_squared(x) / 2.0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
801
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
802 def _get_base(self):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
803 return (None, (None, None)) if self.base is None else self.base
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
804
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
805 def apply(self, x):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
806 """
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
807 Apply the quadratic regularisation functional to `x`.
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
808 """
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
809 (k, (c1, c2)) = x
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
810 (kb, (c1b, c2b)) = self._get_base()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
811 (nkb, (nc1b, nc2b)) = self.base_norm_squared
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
812
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
813 if isinstance(self.α, float):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
814 αk, αc = self.α, self.α
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
815 else:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
816 αk, αc = self.α
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
817
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
818 return αk * self._apply1(k, kb, nkb) + αc * (
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
819 self._apply1(c1, c1b, nc1b) + self._apply1(c2, c2b, nc2b)
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
820 )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
821
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
822 def _prox1(self, γ, x, b):
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
823 β = 1.0 / (1.0 + γ)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
824 if isinstance(x, float):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
825 return β * (x if b is None else x + b * γ)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
826 else:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
827 # x = own(x)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
828 vx = x.x.array
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
829 if b is not None:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
830 vx += b.x.array * γ
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
831 vx *= β
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
832 return x
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
833
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
834 def prox(self, τ, x):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
835 """
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
836 Apply the proximal map of the quadratic regularisation functional to `x`.
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
837 WARNING: This function is unsafe. It may modify `x´.
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
838 That is ok for our purposes, as Rust, being a safe language, already needs to pass a
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
839 copied or owned instance to Python.
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
840 """
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
841 k, (c1, c2) = x
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
842 (kb, (c1b, c2b)) = self._get_base()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
843
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
844 if isinstance(self.α, float):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
845 αk, αc = self.α, self.α
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
846 else:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
847 αk, αc = self.α
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
848
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
849 return (
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
850 self._prox1(τ * αk, k, kb),
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
851 (self._prox1(τ * αc, c1, c1b), self._prox1(τ * αc, c2, c2b)),
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
852 )
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
853
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
854
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
855 class LogPowerRegularisation:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
856 """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
857 Logarithmic barrier + quadratic regularisation functional for the auxiliary variables;
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
858 $-α\\log(x) + ωx^2$.
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
859 """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
860
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
861 def _own(self, x):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
862 return x if isinstance(x, float) else own(x)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
863
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
864 def __init__(self, α, ω):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
865 self.α = α
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
866 self.ω = ω
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
867
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
868 def _apply1(self, x, α, ω):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
869 if isinstance(x, float):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
870 return -α * np.log(x) + ω * x**2
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
871 else:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
872 # Numpy is Matlab-grade junk. No reduce! Temporary arrays! In 2026! WTF?!?!?!?
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
873 return (-α * np.log(x) + ω * x**2).sum()
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
874
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
875 def apply(self, x):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
876 (k, (c1, c2)) = x
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
877
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
878 if isinstance(self.α, float):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
879 αk, αc = self.α, self.α
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
880 else:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
881 αk, αc = self.α
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
882 if isinstance(self.ω, float):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
883 ωk, ωc = self.ω, self.ω
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
884 else:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
885 ωk, ωc = self.ω
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
886
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
887 return (
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
888 self._apply1(k, αk, ωk)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
889 + self._apply1(c1, αc, ωc)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
890 + self._apply1(c2, αc, ωc)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
891 )
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
892
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
893 def _prox1(self, α, ω, x):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
894 # OC: 0 = -α/z + 2ωz + z-x ⟺ -α + (2ω+1)z^2 - xz = 0.
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
895 # ⟺ z = -x ± √(x^2 + 4α(2ω+1))/(2(2ω+1))
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
896 # Numpy is Matlab-grade junk. No reduce! Temporary arrays! In 2026! WTF?!?!?!?
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
897 return (x + np.sqrt(x**2 + 4 * α * (2 * ω + 1))) / (2 * (2 * ω + 1))
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
898
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
899 def prox(self, τ, x):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
900 """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
901 Apply the proximal map of the logarithmic regularisation functional to `x`.
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
902 WARNING: This function is unsafe. It may modify `x´.
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
903 That is ok for our purposes, as Rust, being a safe language, already needs to pass a
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
904 copied or owned instance to Python.
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
905 """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
906 k, (c1, c2) = x
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
907
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
908 if isinstance(self.α, float):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
909 αk, αc = self.α, self.α
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
910 else:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
911 αk, αc = self.α
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
912 if isinstance(self.ω, float):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
913 ωk, ωc = self.ω, self.ω
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
914 else:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
915 ωk, ωc = self.ω
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
916
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
917 return (
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
918 self._prox1(τ * αk, τ * ωk, k),
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
919 (self._prox1(τ * αc, τ * ωc, c1), self._prox1(τ * αc, τ * ωc, c2)),
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
920 )
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
921
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
922
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
923 class BoxConstraints:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
924 """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
925 Simple box constraints on the auxiliary variables
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
926 """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
927
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
928 def _own(self, x):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
929 return x if isinstance(x, float) else own(x)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
930
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
931 def __init__(self, α, ω):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
932 self.α = α
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
933 self.ω = ω
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
934
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
935 def _apply1(self, x, α, ω):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
936 if isinstance(x, float):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
937 if α <= x and x <= ω:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
938 return 0.0
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
939 else:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
940 return np.inf
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
941 else:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
942 raise Exception("Unimplemented")
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
943
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
944 def apply(self, x):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
945 (k, (c1, c2)) = x
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
946
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
947 if isinstance(self.α, float):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
948 αk, αc = self.α, self.α
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
949 else:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
950 αk, αc = self.α
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
951 if isinstance(self.ω, float):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
952 ωk, ωc = self.ω, self.ω
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
953 else:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
954 ωk, ωc = self.ω
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
955
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
956 return (
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
957 self._apply1(k, αk, ωk)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
958 + self._apply1(c1, αc, ωc)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
959 + self._apply1(c2, αc, ωc)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
960 )
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
961
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
962 def _prox1(self, α, ω, x):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
963 # OC: 0 = -α/z + 2ωz + z-x ⟺ -α + (2ω+1)z^2 - xz = 0.
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
964 # ⟺ z = -x ± √(x^2 + 4α(2ω+1))/(2(2ω+1))
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
965 # Numpy is Matlab-grade junk. No reduce! Temporary arrays! In 2026! WTF?!?!?!?
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
966 return max(min(ω, x), α)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
967
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
968 def prox(self, τ, x):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
969 """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
970 Apply the proximal map of the box constraints to `x`.
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
971 WARNING: This function is unsafe. It may modify `x´.
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
972 That is ok for our purposes, as Rust, being a safe language, already needs to pass a
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
973 copied or owned instance to Python.
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
974 """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
975 k, (c1, c2) = x
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
976
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
977 if isinstance(self.α, float):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
978 αk, αc = self.α, self.α
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
979 else:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
980 αk, αc = self.α
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
981 if isinstance(self.ω, float):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
982 ωk, ωc = self.ω, self.ω
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
983 else:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
984 ωk, ωc = self.ω
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
985
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
986 return (
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
987 self._prox1(αk, ωk, k),
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
988 (self._prox1(αc, ωc, c1), self._prox1(αc, ωc, c2)),
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
989 )
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
990
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
991
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
992 """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
993 Quadratic regularisation with box contraints
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
994 """
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
995
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
996
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
997 class BoxedQuadraticRegularisation:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
998 def __init__(self, ω0, ω1, α, base=None):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
999 self.box = BoxConstraints(ω0, ω1)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
1000 self.quadratic = QuadraticRegularisation(α, base)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
1001
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
1002 def apply(self, x):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
1003 return self.box.apply(x) + self.quadratic.apply(x)
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
1004
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
1005 def prox(self, τ, x):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
1006 return self.box.prox(1.0, self.quadratic.prox(τ, x))

mercurial