@@ -240,3 +240,113 @@ def s_value(
240
240
kappa = kappa_min + (kappa_max - kappa_min ) * step ** order
241
241
sigma = sigma_max * avg_speed / (ETA_0 * dl ) * step ** order
242
242
return kappa + 1j * sigma / (omega * EPSILON_0 )
243
+
244
+
245
+ def make_cxf (dls , shape , pmc ):
246
+ """Forward colocation in x."""
247
+ import scipy .sparse as sp
248
+
249
+ Nx , Ny = shape
250
+ if Nx == 1 :
251
+ return sp .csr_matrix ((Ny , Ny ))
252
+ # Create matrix with [1,1,0,...,0], [0,1,1,...,0], etc pattern
253
+ cxf = 0.5 * sp .csr_matrix (sp .diags ([1 , 1 ], [0 , 1 ], shape = (Nx , Nx )))
254
+
255
+ # Apply boundary conditions before Kronecker product
256
+ if not pmc :
257
+ cxf [0 , 0 ] = 0
258
+
259
+ return sp .kron (cxf , sp .eye (Ny ))
260
+
261
+
262
+ def make_cxb (dls , shape , pmc ):
263
+ """Backward colocation in x."""
264
+ import scipy .sparse as sp
265
+
266
+ Nx , Ny = shape
267
+ if Nx == 1 :
268
+ return sp .csr_matrix ((Ny , Ny ))
269
+
270
+ # Calculate weights for each position
271
+ p1 = dls [:- 1 ] # First grid spacing
272
+ p2 = dls [1 :] # Second grid spacing
273
+
274
+ weights_curr = np .ones (Nx )
275
+ weights_curr [1 :] = p1 / (p1 + p2 )
276
+
277
+ weights_prev = np .zeros (Nx )
278
+ weights_prev [:- 1 ] = p2 / (p1 + p2 )
279
+
280
+ # Create the matrix using diagonals
281
+ cxb = sp .diags ([weights_curr , weights_prev ], [0 , - 1 ], shape = (Nx , Nx ))
282
+
283
+ # Apply boundary conditions before Kronecker product
284
+ # The matrix is already set up for PEC (cxb[0, 0] = 1)
285
+ if pmc :
286
+ cxb [0 , 0 ] = 0
287
+
288
+ return sp .kron (cxb , sp .eye (Ny ))
289
+
290
+
291
+ def make_cyf (dls , shape , pmc ):
292
+ """Forward colocation in y."""
293
+ import scipy .sparse as sp
294
+
295
+ Nx , Ny = shape
296
+ if Ny == 1 :
297
+ return sp .csr_matrix ((Nx , Nx ))
298
+ # Create matrix with [1,1,0,...,0], [0,1,1,...,0], etc pattern
299
+ cyf = 0.5 * sp .csr_matrix (sp .diags ([1 , 1 ], [0 , 1 ], shape = (Ny , Ny )))
300
+
301
+ # Apply boundary conditions before Kronecker product
302
+ if not pmc :
303
+ cyf [0 , 0 ] = 0
304
+
305
+ return sp .kron (sp .eye (Nx ), cyf )
306
+
307
+
308
+ def make_cyb (dls , shape , pmc ):
309
+ """Backward colocation in y."""
310
+ import scipy .sparse as sp
311
+
312
+ Nx , Ny = shape
313
+ if Ny == 1 :
314
+ return sp .csr_matrix ((Nx , Nx ))
315
+
316
+ # Calculate weights for each position
317
+ p1 = dls [:- 1 ] # First grid spacing
318
+ p2 = dls [1 :] # Second grid spacing
319
+
320
+ weights_curr = np .ones (Ny )
321
+ weights_curr [1 :] = p1 / (p1 + p2 )
322
+
323
+ weights_prev = np .zeros (Ny )
324
+ weights_prev [:- 1 ] = p2 / (p1 + p2 )
325
+
326
+ # Create the matrix using diagonals
327
+ cyb = sp .diags ([weights_curr , weights_prev ], [0 , - 1 ], shape = (Ny , Ny ))
328
+
329
+ # Apply boundary conditions before Kronecker product
330
+ # The matrix is already set up for PEC (cyb[0, 0] = 1)
331
+ if pmc :
332
+ cyb [0 , 0 ] = 0
333
+
334
+ return sp .kron (sp .eye (Nx ), cyb )
335
+
336
+
337
+ def create_c_matrices (shape , dls , dmin_pmc = (False , False )):
338
+ """Make the colocation matrices. If dmin_pmc is True, the matrices will be modified
339
+ to implement PMC boundary conditions, otherwise they will implement PEC."""
340
+
341
+ dlf , _ = dls
342
+ cxf = make_cxf (dlf [0 ], shape , dmin_pmc [0 ])
343
+ cxb = make_cxb (dlf [0 ], shape , dmin_pmc [0 ]) # Note: uses primal grid spacings
344
+ cyf = make_cyf (dlf [1 ], shape , dmin_pmc [1 ])
345
+ cyb = make_cyb (dlf [1 ], shape , dmin_pmc [1 ]) # Note: uses primal grid spacings
346
+
347
+ # cxf = sp.eye(shape[0] * shape[1])
348
+ # cxb = sp.eye(shape[0] * shape[1])
349
+ # cyf = sp.eye(shape[0] * shape[1])
350
+ # cyb = sp.eye(shape[0] * shape[1])
351
+
352
+ return (cxf , cxb , cyf , cyb )
0 commit comments