Skip to content

Commit 14f66c5

Browse files
EliEli
authored andcommitted
Documented laplace smoothers and got rid of buggy version 1 implementations (that were unused).
1 parent c30ab59 commit 14f66c5

1 file changed

Lines changed: 85 additions & 37 deletions

File tree

schimpy/laplace_smooth_data.py

Lines changed: 85 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,33 @@
11
import numpy as np
22

33

4-
def laplace_smooth_data(mesh, data, rate=0.05, iter_total=150):
5-
nodes = mesh.nodes
6-
edges = mesh.edges
7-
x = nodes[:, 0:2]
8-
iter = 0
9-
smooth_data = data.copy()
10-
while iter < iter_total:
11-
zz = smooth_data.copy()
12-
for ndx in range(nodes.shape[0]):
13-
nds = mesh.get_neighbor_nodes(ndx)
14-
vnode = data[ndx]
15-
vneighbor = [smooth_data[n] for n in nds]
16-
vave = np.mean(vneighbor)
17-
zz[ndx] = vnode + rate * (vave - vnode)
4+
def laplace_smooth_data2(mesh,data,kappa=0.05,dt=1.0,iter_total=150):
5+
"""
6+
Apply Laplacian smoothing to a scalar field on a mesh using explicit diffusion.
187
19-
iter += 1
20-
smooth_data = zz
21-
return smooth_data
8+
This function performs iterative smoothing by updating each node's value
9+
toward the average of its neighbors. It corresponds to forward Euler
10+
integration of the diffusion equation.
2211
12+
Parameters
13+
----------
14+
mesh : object
15+
A mesh object with a `nodes` array and a method `get_neighbor_nodes(ndx)`
16+
returning neighbor node indices for a given node.
17+
data : ndarray of shape (N,)
18+
Initial scalar field values at each mesh node.
19+
kappa : float, optional
20+
Diffusivity coefficient. Controls the rate of smoothing. Default is 0.05.
21+
dt : float, optional
22+
Timestep used for each smoothing iteration. Default is 1.0.
23+
iter_total : int, optional
24+
Number of smoothing iterations to perform. Default is 150.
2325
24-
def laplace_smooth_data2(mesh, data, kappa=0.05, dt=1.0, iter_total=150):
26+
Returns
27+
-------
28+
smooth_data : ndarray of shape (N,)
29+
The smoothed scalar field after `iter_total` iterations.
30+
"""
2531
nodes = mesh.nodes
2632
edges = mesh.edges
2733
rate = dt * kappa
@@ -42,27 +48,38 @@ def laplace_smooth_data2(mesh, data, kappa=0.05, dt=1.0, iter_total=150):
4248
return smooth_data
4349

4450

45-
def laplace_smooth_with_vel(mesh, data, vel, kappa=0.05, dt=1.0, iter_total=1):
46-
nodes = mesh.nodes
47-
edges = mesh.edges
48-
x = nodes[:, 0:2]
49-
iter = 0
50-
smooth_data = data.copy()
51-
while iter < iter_total:
52-
zz = smooth_data.copy()
53-
for ndx in range(nodes.shape[0]):
54-
nds = mesh.get_neighbor_nodes(ndx)
55-
vnode = data[ndx]
56-
vneighbor = [smooth_data[n] for n in nds]
57-
vave = np.mean(vneighbor)
58-
zz[ndx] = vnode + dt * kappa * (vave - vnode) + dt * vel[ndx]
51+
5952

60-
iter += 1
61-
smooth_data = zz
62-
return smooth_data
53+
def laplace_smooth_with_vel2(mesh,data,vel,kappa=0.05,dt=1.,iter_total=1):
54+
"""
55+
Apply Laplacian smoothing with additive forcing to a scalar field on a mesh.
56+
57+
This function performs iterative diffusion of `data` while incorporating
58+
a source or forcing term `vel` at each node. It evolves the field
59+
using explicit Euler integration of the PDE:
60+
∂u/∂t = κ ∇²u + vel
6361
62+
Parameters
63+
----------
64+
mesh : object
65+
A mesh object with a `nodes` array and a method `get_neighbor_nodes(ndx)`
66+
returning neighbor node indices for a given node.
67+
data : ndarray of shape (N,)
68+
Initial scalar field values at each mesh node.
69+
vel : ndarray of shape (N,)
70+
Additive source or forcing term to apply at each node.
71+
kappa : float, optional
72+
Diffusivity coefficient. Default is 0.05.
73+
dt : float, optional
74+
Timestep used for each smoothing iteration. Default is 1.0.
75+
iter_total : int, optional
76+
Number of smoothing iterations to perform. Default is 1.
6477
65-
def laplace_smooth_with_vel2(mesh, data, vel, kappa=0.05, dt=1.0, iter_total=1):
78+
Returns
79+
-------
80+
smooth_data : ndarray of shape (N,)
81+
The smoothed and forced scalar field after `iter_total` iterations.
82+
"""
6683
nodes = mesh.nodes
6784
# edges = mesh.edges
6885
# x =nodes[:,0:2]
@@ -83,7 +100,38 @@ def laplace_smooth_with_vel2(mesh, data, vel, kappa=0.05, dt=1.0, iter_total=1):
83100
return smooth_data
84101

85102

86-
def laplace_smooth_with_vel3(mesh, nlayer, data, vel, kappa=0.05, dt=1.0, iter_total=1):
103+
104+
def laplace_smooth_with_vel3(mesh,nlayer,data,vel,kappa=0.05,dt=1.,iter_total=1):
105+
"""
106+
Apply layer-aware Laplacian smoothing with forcing to a scalar field on a mesh.
107+
108+
This function diffuses values across mesh nodes but restricts neighbor contributions
109+
to those from the same or deeper layers. Shallower neighbors are excluded from
110+
smoothing influence, preserving stratification or flow directionality.
111+
112+
Parameters
113+
----------
114+
mesh : object
115+
A mesh object with a `nodes` array and a method `get_neighbor_nodes(ndx)`
116+
returning neighbor node indices for a given node.
117+
nlayer : ndarray of shape (N,)
118+
Integer layer index for each node. Smoothing ignores neighbors with shallower layer values.
119+
data : ndarray of shape (N,)
120+
Initial scalar field values at each mesh node (used as fallback for excluded neighbors).
121+
vel : ndarray of shape (N,)
122+
Additive source or forcing term applied at each node.
123+
kappa : float, optional
124+
Diffusivity coefficient. Default is 0.05.
125+
dt : float, optional
126+
Timestep used for each smoothing iteration. Default is 1.0.
127+
iter_total : int, optional
128+
Number of smoothing iterations to perform. Default is 1.
129+
130+
Returns
131+
-------
132+
smooth_data : ndarray of shape (N,)
133+
The smoothed scalar field after `iter_total` iterations with layer-aware filtering and forcing.
134+
"""
87135
nodes = mesh.nodes
88136
# edges = mesh.edges
89137
# x =nodes[:,0:2]

0 commit comments

Comments
 (0)