ayda138000 commited on
Commit
ed3064e
·
verified ·
1 Parent(s): d32d52a

Upload models (2).py

Browse files
Files changed (1) hide show
  1. pinn_electromagnetics/models (2).py +117 -0
pinn_electromagnetics/models (2).py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import torch
3
+ import torch.nn as nn
4
+ import numpy as np
5
+
6
+ # --- Hash Grid Encoder (from v26) ---
7
+ class HashGridEncoder(nn.Module):
8
+ def __init__(self, n_levels=16, n_features_per_level=2,
9
+ log2_hashmap_size=19, base_resolution=16,
10
+ per_level_scale=1.5):
11
+ super(HashGridEncoder, self).__init__()
12
+ self.n_levels = n_levels
13
+ self.n_features_per_level = n_features_per_level
14
+ self.log2_hashmap_size = log2_hashmap_size
15
+ self.base_resolution = base_resolution
16
+ self.per_level_scale = per_level_scale
17
+ self.hashmap_size = 2**self.log2_hashmap_size
18
+ self.embeddings = nn.ModuleList([
19
+ nn.Embedding(self.hashmap_size, self.n_features_per_level)
20
+ for i in range(self.n_levels)
21
+ ])
22
+ for emb in self.embeddings: nn.init.uniform_(emb.weight, -1e-4, 1e-4)
23
+
24
+ def hash_fn(self, coords_int, level):
25
+ primes = torch.tensor([1, 2654435761, 805459861], dtype=torch.int64, device=coords_int.device)
26
+ hashed_indices = (coords_int * primes).sum(dim=-1) % self.hashmap_size
27
+ return hashed_indices
28
+
29
+ def trilinear_interp(self, x, v000, v001, v010, v011, v100, v101, v110, v111):
30
+ w0 = (1 - x[..., 0:1]); w1 = x[..., 0:1]
31
+ c00 = v000 * w0 + v100 * w1; c01 = v001 * w0 + v101 * w1
32
+ c10 = v010 * w0 + v110 * w1; c11 = v011 * w0 + v111 * w1
33
+ c0 = c00 * (1 - x[..., 1:2]) + c10 * x[..., 1:2]
34
+ c1 = c01 * (1 - x[..., 1:2]) + c11 * x[..., 1:2]
35
+ c = c0 * (1 - x[..., 2:3]) + c1 * x[..., 2:3]
36
+ return c
37
+
38
+ def forward(self, x_coords): # x_coords: [N, 3] in [0, 1]
39
+ all_features = []
40
+ for l in range(self.n_levels):
41
+ res = int(self.base_resolution * (self.per_level_scale ** l))
42
+ x_scaled = x_coords * res
43
+ x_floor = torch.floor(x_scaled).to(torch.int64)
44
+ x_local = (x_scaled - x_floor)
45
+ corners = torch.tensor([[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]], dtype=torch.int64, device=x_coords.device)
46
+ cell_corners_int = x_floor.unsqueeze(1) + corners.unsqueeze(0)
47
+ hashed_indices = self.hash_fn(cell_corners_int, l)
48
+ embedded_features = self.embeddings[l](hashed_indices)
49
+ interp_features = self.trilinear_interp(
50
+ x_local,
51
+ embedded_features[:, 0], embedded_features[:, 1],
52
+ embedded_features[:, 2], embedded_features[:, 3],
53
+ embedded_features[:, 4], embedded_features[:, 5],
54
+ embedded_features[:, 6], embedded_features[:, 7]
55
+ )
56
+ all_features.append(interp_features)
57
+ return torch.cat(all_features, dim=-1)
58
+
59
+ # --- GeoNetHash (for geometry, from v26) ---
60
+ class GeoNetHash(nn.Module):
61
+ def __init__(self, box_size_scale=1.0):
62
+ super(GeoNetHash, self).__init__()
63
+ self.box_size_scale = box_size_scale
64
+ self.encoder = HashGridEncoder(n_levels=16, n_features_per_level=2)
65
+ self.mlp = nn.Sequential(
66
+ nn.Linear(self.encoder.n_levels * self.encoder.n_features_per_level, 64),
67
+ nn.ReLU(),
68
+ nn.Linear(64, 1)
69
+ )
70
+ # Placeholder for min/max for normalization
71
+ self.min = None
72
+ self.max = None
73
+
74
+ def normalize_coords(self, coords):
75
+ # Stores min/max from the original dataset for consistent normalization
76
+ self.min = coords.min(dim=0, keepdim=True)[0]
77
+ self.max = coords.max(dim=0, keepdim=True)[0]
78
+ self.max[self.max == self.min] += 1e-6 # Avoid division by zero
79
+ return (coords - self.min) / (self.max - self.min)
80
+
81
+ def forward(self, coords_input_normalized): # input is already normalized [0, 1]
82
+ features = self.encoder(coords_input_normalized)
83
+ return self.mlp(features)
84
+
85
+ # --- Positional Encoder 4D (for MaxwellPINN, from v19/v22) ---
86
+ class PositionalEncoder4D(nn.Module):
87
+ def __init__(self, input_dims, num_freqs):
88
+ super(PositionalEncoder4D, self).__init__()
89
+ self.input_dims = input_dims
90
+ self.num_freqs = num_freqs
91
+ self.freq_bands = 2.**torch.linspace(0., num_freqs-1, num_freqs)
92
+ self.output_dims = self.input_dims * (2 * self.num_freqs + 1)
93
+
94
+ def forward(self, x): # x is [N, input_dims]
95
+ encoding = [x]
96
+ x_freq = x.unsqueeze(-1) * self.freq_bands.to(x.device)
97
+ encoding.append(torch.sin(x_freq).view(x.shape[0], -1))
98
+ encoding.append(torch.cos(x_freq).view(x.shape[0], -1))
99
+ return torch.cat(encoding, dim=1)
100
+
101
+ # --- MaxwellPINN (for electromagnetics, from v28) ---
102
+ class MaxwellPINN(nn.Module):
103
+ def __init__(self, num_freqs=8, hidden_dim=128):
104
+ super(MaxwellPINN, self).__init__()
105
+ self.encoder = PositionalEncoder4D(input_dims=4, num_freqs=num_freqs)
106
+ encoder_output_dims = self.encoder.output_dims
107
+ self.network = nn.Sequential(
108
+ nn.Linear(encoder_output_dims, hidden_dim), nn.Tanh(),
109
+ nn.Linear(hidden_dim, hidden_dim), nn.Tanh(),
110
+ nn.Linear(hidden_dim, hidden_dim), nn.Tanh(),
111
+ nn.Linear(hidden_dim, 6) # Outputs (Ex, Ey, Ez, Bx, By, Bz)
112
+ )
113
+
114
+ def forward(self, x, y, z, t):
115
+ coords = torch.cat([x, y, z, t], dim=1)
116
+ x_encoded = self.encoder(coords)
117
+ return self.network(x_encoded)