8
8
#include " fdtd.hpp"
9
9
#include " matrixTypeDef.hpp"
10
10
#include " mapIndex.hpp"
11
+ // #define DEBUG_SOLVE_REORDERED_S // debug mode: directly solve the entire reordered S (growZ, rmPEC)
11
12
12
13
// Compute y = alpha * A * x + beta * y and store computed dense matrix in y
13
14
int csrMultiplyDense (const sparse_matrix_t &csrA_mklHandle, // mkl handle of csr A
@@ -56,11 +57,11 @@ int eliminateVolumE(const vector<BlockType> &layerS, myint N_surfE, myint N_volE
56
57
Inputs:
57
58
layerS: a vector containing 9 blocks of the whole matrix S, ~ within one layer
58
59
N_surfE: number of {e}_surface at one surface, e.g. 0s
59
- N_volE: number of {e}_volumn at one layer, e.g. 0v
60
+ N_volE: number of {e}_volume at one layer, e.g. 0v
60
61
Output:
61
62
preducedS: pointing to memory of a vector storing 4 reduced dense blocks as {C11, C12, C21, C22}
62
63
63
- Each isolated layer here contains 2 surfaces and 1 middle volumn e, namely 0s-0v-1s.
64
+ Each isolated layer here contains 2 surfaces and 1 middle volume e, namely 0s-0v-1s.
64
65
A symbolic form is (each number represents the blockId in vector<BlockType>):
65
66
66
67
0s 0v 1s 0s 1s
@@ -219,21 +220,32 @@ vector<myint> findSurfLocationOfPort(fdtdMesh *psys) {
219
220
returned surfLocationOfPort = { 0, 2 } */
220
221
221
222
vector<myint> surfLocationOfPort;
223
+ double dyErrorUpperBound = (psys->yn [1 ] - psys->yn [0 ]) * MINDISFRACY; // used to compare two equal y coordinates
222
224
223
225
for (myint sourcePort = 0 ; sourcePort < psys->numPorts ; sourcePort++) {
224
226
double y_thisPort = psys->portCoor [sourcePort].y1 [0 ];
225
227
for (myint indy = 0 ; indy < psys->N_cell_y + 1 ; indy++) { // search over all y nodes
226
- if (y_thisPort == psys->yn [indy]) {
228
+ if (fabs ( y_thisPort - psys->yn [indy]) < dyErrorUpperBound ) {
227
229
surfLocationOfPort.push_back (indy);
228
230
break ;
229
231
}
230
232
}
231
233
}
232
234
235
+ if (surfLocationOfPort.size () != psys->numPorts ) {
236
+ cout << " ERROR! Missed some ports." << endl;
237
+ exit (2 );
238
+ }
239
+
233
240
// Sort vector and erase duplicated surface index
234
241
sort (surfLocationOfPort.begin (), surfLocationOfPort.end ());
235
242
surfLocationOfPort.erase ( unique (surfLocationOfPort.begin (), surfLocationOfPort.end ()), surfLocationOfPort.end () );
236
243
244
+ if (surfLocationOfPort.size () != psys->numPorts ) {
245
+ cout << " ERROR! Unsupported port setting! Ports should not locate at the same surface" << endl;
246
+ exit (2 );
247
+ }
248
+
237
249
return surfLocationOfPort;
238
250
}
239
251
@@ -248,14 +260,46 @@ denseFormatOfMatrix cascadeMatrixS(fdtdMesh *psys, double omegaHz, const mapInde
248
260
Return:
249
261
- cascadedS: matrix "(-w^2*D_eps+iw*D_sig+ShSe/mu)" with only {e}_portSurf left */
250
262
251
-
252
-
253
263
// Num of {e} at each surface or each layer, index mode (growY, removed PEC)
254
264
myint n_surfExEz = indexMap.N_surfExEz_rmPEC ;
255
265
myint n_volEy = indexMap.N_volEy_rmPEC ;
256
266
myint n_layerE_growY = n_surfExEz + n_volEy;
257
267
myint N_layers = psys->N_cell_y ; // num of layers
258
268
269
+ #ifdef DEBUG_SOLVE_REORDERED_S
270
+ BlockType coo_reorderedS (psys->leng_S );
271
+ for (myint i_nnz = 0 ; i_nnz < psys->leng_S ; i_nnz++) {
272
+ // (rowId, colId, val) of this nnz element in ShSe/mu, index mode (growZ, removed PEC)
273
+ myint nnzS_rowId_rmPECz = psys->SRowId [i_nnz];
274
+ myint nnzS_colId_rmPECz = psys->SColId [i_nnz];
275
+ complex<double > cascadedS_val = psys->Sval [i_nnz];
276
+
277
+ // Map row and col index from (growZ, removed PEC) to (growY, removed PEC)
278
+ myint nnzS_rowId = indexMap.eInd_map_rmPEC_z2y [nnzS_rowId_rmPECz];
279
+ myint nnzS_colId = indexMap.eInd_map_rmPEC_z2y [nnzS_colId_rmPECz];
280
+
281
+ // For diagonal nnz, add "-w^2*eps+iw*sig" to psys->Sval (ShSe/mu)
282
+ if (nnzS_rowId == nnzS_colId) { // if at diagonal
283
+ myint nnzS_rowId_growZ = psys->mapEdgeR [nnzS_rowId_rmPECz];
284
+ myint layerInd_alongZ = (nnzS_rowId_growZ + psys->N_edge_v ) / (psys->N_edge_s + psys->N_edge_v );
285
+ double epsi_thisnnz = psys->stackEpsn [layerInd_alongZ] * EPSILON0;
286
+ double sigma_thisnnz = 0 ;
287
+ if (psys->markEdge [nnzS_rowId_growZ] != 0 ) {
288
+ sigma_thisnnz = SIGMA;
289
+ } // if inside a conductor
290
+
291
+ complex<double > epsi_sigma = { -omegaHz*omegaHz*epsi_thisnnz, omegaHz*sigma_thisnnz };
292
+ cascadedS_val += epsi_sigma; // -w^2*D_eps+iw*D_sig+ShSe/mu
293
+ }
294
+ coo_reorderedS.push_back ({ nnzS_rowId, nnzS_colId, cascadedS_val });
295
+ }
296
+
297
+ denseFormatOfMatrix denseS_reordered (indexMap.N_totEdges_rmPEC , indexMap.N_totEdges_rmPEC );
298
+ denseS_reordered.convertBlockTypeToDense (coo_reorderedS);
299
+ return denseS_reordered;
300
+
301
+ #endif
302
+
259
303
// Determine the block id of each nnz element of S and store in corresponding block matrix
260
304
vector< BlockType > Blocks (8 * N_layers + 1 ); // store all bolck matrices of S in a 2D vector
261
305
for (myint i_nnz = 0 ; i_nnz < psys->leng_S ; i_nnz++) {
@@ -320,7 +364,7 @@ denseFormatOfMatrix cascadeMatrixS(fdtdMesh *psys, double omegaHz, const mapInde
320
364
}
321
365
}
322
366
323
- // Eliminate e_volumn at each layer and store 4 reduced dense blocks of each layer
367
+ // Eliminate e_volume at each layer and store 4 reduced dense blocks of each layer
324
368
vector<vector<denseFormatOfMatrix>> surfSurfBlocks (N_layers); // N_layers*4 dense blocks
325
369
for (myint i_layer = 0 ; i_layer < N_layers; i_layer++) {
326
370
// Init and allocate memory for 4 dense blocks of each layer
@@ -465,9 +509,13 @@ denseFormatOfMatrix assignRhsJForAllPorts(fdtdMesh *psys, double omegaHz, const
465
509
}
466
510
}
467
511
512
+ #ifdef DEBUG_SOLVE_REORDERED_S
513
+ return RhsJ_SI;
514
+ #endif
515
+
468
516
// Only keep -iw{j} at port surfaces (cascading)
469
517
myint N_surfExEz = indexMap.N_surfExEz_rmPEC ; // number of edges at one surface
470
- myint n_volEy = indexMap.N_volEy_rmPEC ; // number of volumn edges in one layer
518
+ myint n_volEy = indexMap.N_volEy_rmPEC ; // number of volume edges in one layer
471
519
myint N_allCascadedEdges = psys->numPorts * N_surfExEz; // number of all edges in kept surfaces
472
520
denseFormatOfMatrix cascadedRhsJ_SI (N_allCascadedEdges, psys->numPorts ); // -iw{j} only at port surfaces
473
521
vector<myint> surfLocationOfPort = findSurfLocationOfPort (psys);
@@ -500,7 +548,7 @@ denseFormatOfMatrix reconstruct_e(fdtdMesh *psys, const mapIndex &indexMap, cons
500
548
- eField_oneExcit: of size (psys->N_edge - psys->bden) * 1, mode (growZ, removed PEC) */
501
549
502
550
myint N_surfExEz = indexMap.N_surfExEz_rmPEC ; // number of edges at one surface
503
- myint n_volEy = indexMap.N_volEy_rmPEC ; // number of volumn edges in one layer
551
+ myint n_volEy = indexMap.N_volEy_rmPEC ; // number of volume edges in one layer
504
552
myint N_allCascadedEdges = psys->numPorts * N_surfExEz; // number of all edges in kept surfaces
505
553
myint N_edgesNotAtPEC = psys->N_edge - psys->bden ; // num of all edges after removing PEC
506
554
vector<myint> surfLocationOfPort = findSurfLocationOfPort (psys); // surf index of the port's location
@@ -524,6 +572,19 @@ denseFormatOfMatrix reconstruct_e(fdtdMesh *psys, const mapIndex &indexMap, cons
524
572
}
525
573
}
526
574
575
+ #ifdef DEBUG_SOLVE_REORDERED_S
576
+ for (myint e_ind = 0 ; e_ind < N_allCascadedEdges; e_ind++) {
577
+ myint eInd_cascaded = e_ind + excitedPort * N_allCascadedEdges;
578
+
579
+ myint eInd_growY = indexMap.eInd_map_rmPEC2y [e_ind]; // Step 1: -> index at (growY, no PEC removal)
580
+ myint eInd_growZ = indexMap.eInd_map_y2z [eInd_growY]; // Step 2: map (growY, no PEC removal) to (growZ, no PEC removal)
581
+ myint eInd_growZrmPEC = psys->mapEdge [eInd_growZ]; // Step 3: map (growZ, no PEC removal) to (growZ, removed PEC)
582
+
583
+ eField_oneExcit.vals [eInd_growZrmPEC] = cascadedeField_SI.vals [eInd_cascaded];
584
+ }
585
+ return eField_oneExcit;
586
+ #endif
587
+
527
588
return eField_oneExcit;
528
589
}
529
590
0 commit comments