src/laser_sampling.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 numpy as np
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
2 from dolfinx import fem, geometry
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
3 from dolfinx_access import cell_FunctionSpace_f64
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
4 from mpi4py import MPI
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
5 from petsc4py import PETSc
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
6 from pointsource_pde.dolfinx_extras import get_mass_matrix
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
7 from scipy.sparse.linalg import svds
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
8 from slepc4py import SLEPc
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
9
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
10
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
11 class LaserSampling:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
12 """
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
13 A linear operator class for laser sampling of a concentration (fem.Function)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
14 """
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
15
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
16 def __init__(
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
17 self,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
18 V,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
19 domain,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
20 nx,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
21 ny,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
22 beams,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
23 num_segments=100,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
24 domain_size=[-2, 2, -2, 2],
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25 ):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
26 self.V = V
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
27 self.domain = domain
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
28 self.nx, self.ny = nx, ny
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
29 self.M = len(beams)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
30 self.domain_size = domain_size
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
31 self.num_segments = num_segments
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 # Build R matrix (single function does everything)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
34 self.R = self.matrix(beams)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
35
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
36 A = get_mass_matrix(V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
37 solver = PETSc.KSP().create(A.comm)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
38 solver.setOperators(A)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
39 solver.setType(PETSc.KSP.Type.PREONLY)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
40 solver.getPC().setType(PETSc.PC.Type.LU)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
41 self.solver = solver
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 # ‖x‖^2 = ‖Ax.array‖^2
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
44 # ‖Lx‖^2 = ‖Rx.array‖^2 = ‖RA^{-1}Ax.array‖^2 ≤ ‖RA^{-1}‖‖x‖^2 ≤ ‖R‖‖A^{-1}‖‖x‖^2,
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
45 # so we need the inverse of the minimal eigenvalue.
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
46 E = SLEPc.EPS().create(A.comm)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
47 E.setOperators(A)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
48 E.setProblemType(SLEPc.EPS.ProblemType.NHEP)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
49 E.setWhichEigenpairs(SLEPc.EPS.Which.SMALLEST_MAGNITUDE)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
50 # E.setWhichEigenpairs(SLEPc.EPS.Which.LARGEST_MAGNITUDE)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
51 E.setFromOptions()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
52 E.solve()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
53
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
54 # sigma = abs(E.getEigenvalue(0))
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
55 # self._opnorm = 1.0 / sigma
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
56 # print("Full sampling opnorm = %f" % self._opnorm)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
57
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
58 # SVD operator norm
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
59 _u, s, _v = svds(self.R, k=1)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
60 self._opnorm = s[0] # / sigma
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
61 # print(f"Laser sampling opnorm = {self._opnorm:.6f}")
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
62
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
63 def matrix(self, beams):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
64 """Combined: generate beams + segment + cell collision + dof weighting"""
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
65 dofmap = self.V.dofmap
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
66 tdim = self.domain.topology.dim
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
67
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
68 # Geometry trees
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
69
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
70 bb_tree = geometry.bb_tree(self.domain, tdim)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
72 n_dofs = self.V.dofmap.index_map.size_global
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
73 R = np.zeros((self.M, n_dofs))
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
74
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
75 xmin, xmax, ymin, ymax = self.domain_size
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
76
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77 for beam_idx, (start_pt, end_pt) in enumerate(beams):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
78 # Segment into midpoints
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
79 vec = end_pt - start_pt
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
80 total_len = np.linalg.norm(vec)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
81 seg_len = total_len / self.num_segments
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
82
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
83 midpoints = []
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
84 for i in range(self.num_segments):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
85 t = (i + 0.5) / self.num_segments
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
86 midpoint = start_pt + t * vec
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
87 midpoints.append(midpoint)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
88 # midpoints = np.array(midpoints, dtype=np.float64) # Force float64
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
89
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
90 # Ensure shape (N, 3), C-contiguous, read-only for DOLFINx
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
91 # assert midpoints.shape[1] == 2, (
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
92 # "Expected 2D points, got shape[1]=2 but need padding to 3D"
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
93 # )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
94 # midpoints = np.pad(
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
95 # midpoints, ((0, 0), (0, 1)), mode="constant"
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
96 # ) # (N, 3) with z=0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
97 # midpoints = np.ascontiguousarray(midpoints) # C-order
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
98 # midpoints.setflags(write=False) # Read-only requirement
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
99
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
100 # Find colliding cells
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
101 # cell_candidates = geometry.compute_collisions_points(bb_tree, midpoints)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
102 # colliding_cells = geometry.compute_colliding_cells(
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
103 # self.domain, cell_candidates, midpoints
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
104 # )
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
105
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
106 # Cell→DOFs→weight accumulation
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
107 # cell_lists = list(colliding_cells.array)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
108 # for seg_i, cell_idx_raw in enumerate(cell_lists):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
109 # cell_idx = int(cell_idx_raw) # Convert np.int32 → Python int
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
110 for point in midpoints:
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
111 pad_point = np.array([point[0], point[1], 0.0])
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
112 cell_idx = cell_FunctionSpace_f64(self.V._cpp_object, pad_point)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
113 if cell_idx >= 0: # Valid cell index
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
114 # Get global DOFs
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
115 cell_dofs_local = dofmap.cell_dofs(cell_idx)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
116 # Convert local dofs to numpy int32 array (DOLFINx requirement)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
117 # local_dofs_array = np.asarray(cell_dofs_local, dtype=np.int32)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
118 # local_dofs_array.setflags(write=False) # Read-only requirement
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
119
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
120 # Batch convert all local indices to global in one call
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
121 cell_dofs_global = dofmap.index_map.local_to_global(cell_dofs_local)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
122 cell_dofs = np.unique(cell_dofs_global)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
123
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
124 weight = seg_len / len(cell_dofs)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
125 R[beam_idx, cell_dofs] += weight # ADD for overlaps!
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
126
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
127 return R
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 def apply(self, x):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
130 """
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
131 This does not work with MPI
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 x.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
134 return self.R @ x.x.array
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
135
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
136 def diff_adjdir(self, j, _x):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
137 """
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
138 This does not work with MPI
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
139 """
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
140 # We need ⟨Rx,v⟩_{ℝ^n} = ⟨x,R^*v⟩_V
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
141 # We have ⟨x,R^*v⟩_V = ⟨Ax.array,[R^*v].array⟩_{ℝ^m}
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
142 # But Rx = R₀ x.array, so we need
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
143 # ⟨x.array,R₀^* v⟩_{ℝ^n} = ⟨Ax.array,[R^*v].array⟩_{ℝ^m}
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
144 # Taking [R^*v].array=A^{-1}R₀^* v, the conjugate works correctly.
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
145 tmp = fem.Function(self.V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
146 np.matmul(self.R.T, j, out=tmp.x.array)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
147 tmp.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
148 return tmp
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
149 # TODO: is convection_diffusion actualy based on norms in ℝ^n?
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
150 # res = fem.Function(self.V)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
151 # res.x.array[:] = 0.0
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
152 # self.solver.solve(tmp.x.petsc_vec, res.x.petsc_vec)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
153 # res.x.scatter_forward()
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
154 # return res
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
155
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
156 def opnorm(self, *args):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
157 # raise NotImplementedError("Need mesh weighting?")
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
158 return self._opnorm
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
159
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
160 def lipschitz_factor(self, *args):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
161 return self.opnorm(*args)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
162
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
163 def diff_chain_lipschitz_factor(self, *args):
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
164 return self.opnorm(*args)
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
165
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
166 def diff_bound(self, *args):
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
167 return self.opnorm(*args)
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 # Construct observation noise
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
170 def noise(self, noise_level, rng=None):
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
171 if rng is None:
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
172 rng = np.random.default_rng()
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
173 M = self.M
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
174 # Generate noise with shape (M, 1) using scalar standard deviation
3
c3a4f4bb87f7 Dolfin update, fixes, additional experiment, build instructions.
Tuomo Valkonen <tuomov@iki.fi>
parents: 1
diff changeset
175 noise = rng.normal(0, noise_level, size=(M,))
1
a4137aedcb3a Initial working version for known convectivity and diffusivity
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
176 return noise

mercurial