Skip to content

Commit ff52b4e

Browse files
committed
[mesh motion] RBF Gaussian 3d order convergence
1 parent 6d970a0 commit ff52b4e

File tree

2 files changed

+61
-9
lines changed

2 files changed

+61
-9
lines changed

src/displacementSmartSimMotionSolver/pytorchApproximationModels/rbf_network.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ def rbf(self, x):
4343
r = torch.cdist(x, self.centers) / self.r_max
4444
return torch.exp(-r**2) # Infinitely smooth Gaussian RBF
4545

46+
#def rbf(self, x):
47+
# """
48+
# Compute Gaussian RBF with enforced compact support.
49+
# """
50+
# r = torch.cdist(x, self.centers) / self.r_max
51+
# mask = (r < 1).float() # Ensure compact support
52+
# return mask * torch.exp(-r**2) # Compactly supported Gaussian
4653

4754
def forward(self, x):
4855
"""

src/displacementSmartSimMotionSolver/pytorchApproximationModels/test_rbf_network_stream_function.py

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import torch.nn as nn
55
import torch.optim as optim
66
import csv
7+
import pandas as pd
78
import os
89

910
from rbf_network import WendlandLinearNetwork
@@ -60,6 +61,48 @@ def generate_centers(num_centers):
6061
centers = np.vstack([X.ravel(), Y.ravel()]).T
6162
return torch.tensor(centers, dtype=torch.float32)
6263

64+
def estimate_convergence_order(csv_filename):
65+
"""
66+
Opens a CSV file containing numerical convergence results and estimates the
67+
convergence order for each row using log-log error reduction.
68+
69+
The last row's convergence order is set equal to the second-to-last row.
70+
71+
Parameters:
72+
csv_filename (str): The path to the CSV file to process.
73+
"""
74+
# Load the CSV file
75+
df = pd.read_csv(csv_filename)
76+
77+
# Ensure required columns exist
78+
required_columns = {"point_dist", "err_validation"}
79+
if not required_columns.issubset(df.columns):
80+
raise ValueError(f"Missing required columns in CSV: {required_columns - set(df.columns)}")
81+
82+
# Compute convergence order using log-log slope formula
83+
convergence_orders = []
84+
85+
for i in range(len(df) - 1): # Iterate up to the second-to-last row
86+
h_coarse, h_fine = df.iloc[i]["point_dist"], df.iloc[i + 1]["point_dist"]
87+
err_coarse, err_fine = df.iloc[i]["err_validation"], df.iloc[i + 1]["err_validation"]
88+
89+
if err_coarse > 0 and err_fine > 0: # Avoid log errors due to zero or negative values
90+
p = np.log(err_coarse / err_fine) / np.log(h_coarse / h_fine)
91+
convergence_orders.append(p)
92+
else:
93+
convergence_orders.append(np.nan)
94+
95+
# Ensure last row gets the same convergence order as the previous row
96+
convergence_orders.append(convergence_orders[-1] if len(convergence_orders) > 0 else np.nan)
97+
98+
# Add convergence order column
99+
df["error_convergence_order"] = convergence_orders
100+
101+
# Save the updated CSV file
102+
df.to_csv(csv_filename, index=False)
103+
104+
print(f"Updated {csv_filename} with convergence orders.")
105+
63106
def main(num_points):
64107
# Generate training data
65108
x = np.linspace(0, 1, num_points)
@@ -76,7 +119,7 @@ def main(num_points):
76119
# centers = generate_centers(32).clone().detach()
77120
centers = x_train
78121
print(centers.shape)
79-
r_max = 3.0 / num_points
122+
r_max = 2.5 / num_points
80123
smoothness = 4 # C^4 smoothness
81124

82125
# Initialize model
@@ -87,7 +130,7 @@ def main(num_points):
87130
criterion = nn.MSELoss()
88131

89132
# Training loop
90-
epochs = 2000
133+
epochs = 4000
91134
for epoch in range(epochs):
92135
model.train()
93136
optimizer.zero_grad()
@@ -119,15 +162,14 @@ def main(num_points):
119162

120163
# Reshape for visualization
121164
psi_pred = pred.reshape(X_val.shape)
122-
#psi_actual = psi(X_val, Y_val)
123165

124166
# Visualize actual and predicted stream functions
125167
visualize_psi(X_val, Y_val, psi_val, centers, title="Actual Stream Function")
126168
visualize_psi(X_val, Y_val, psi_pred, centers, title="Predicted Stream Function")
127169

128-
err_val = np.abs(psi_pred - psi_val)
170+
err_val = np.abs(psi_pred - psi_val) / np.max(psi_val)
129171
visualize_psi(X_val, Y_val, err_val, centers,
130-
title="Stream Function Approximation Error")
172+
title="Stream Function Relative Approximation Error")
131173

132174
# Define the filename
133175
csv_filename = "stream_function_validation.csv"
@@ -162,7 +204,10 @@ def main(num_points):
162204
title="Predicted Velocity Field")
163205

164206
if __name__ == "__main__":
165-
main(num_points=4)
166-
main(num_points=8)
167-
main(num_points=16)
168-
main(num_points=32)
207+
208+
# Run mesh convergence study
209+
for num_points in [4,8,16,32]:
210+
main(num_points)
211+
212+
# Estimate convergence order
213+
estimate_convergence_order("stream_function_validation.csv")

0 commit comments

Comments
 (0)