PlasCom2  1.0
XPACC Multi-physics simluation application
TestMaxwellSolver.C
Go to the documentation of this file.
1 #include "Testing.H"
2 #include "Simulation.H"
3 #include "OperatorKernels.H"
4 #include "MaxwellSolver.H"
5 #include "RK4Advancer.H"
6 #include "EulerUtil.H"
7 #include "MaxwellUtil.H"
8 #include "MaxwellBC.H"
9 #include "PC2IO.H"
10 
11 #define MACHINE_EPS 1e-12
12 
13 #define EPS0 8.85418782e-12 // permittivity of free space [F/m]
14 #define MU0 1.25663706e-6 // permeability of free space [H/m]
15 
16 
17 
18 void CreateLinearScalarField(int numDim, size_t *numX, double *deltaX, double *field, double *coeff)
19 {
20 
21  if (numDim == 3) {
22 
23  coeff[0] = 1.0;
24  coeff[1] = 2.0;
25  coeff[2] = 3.0;
26  coeff[3] = 4.0;
27 
28  for (int k=0; k<numX[2]; k++) {
29  for (int j=0; j<numX[1]; j++) {
30  for (int i=0; i<numX[0]; i++) {
31  field[i+j*numX[0]+k*numX[0]*numX[1]] = coeff[0]*(i*deltaX[0]) + coeff[1]*(j*deltaX[1]) + coeff[2]*(k*deltaX[2]) + coeff[3];
32  }
33  }
34  }
35 
36  } else if (numDim == 2) {
37 
38  coeff[0] = 1.0;
39  coeff[1] = 2.0;
40  coeff[2] = 3.0;
41 
42  for (int j=0; j<numX[1]; j++) {
43  for (int i=0; i<numX[0]; i++) {
44  field[i+j*numX[0]] = coeff[0]*(i*deltaX[0]) + coeff[1]*(j*deltaX[1]) + coeff[2];
45  }
46  }
47 
48  } else if (numDim == 1) {
49 
50  coeff[0] = 1.0;
51  coeff[1] = 2.0;
52 
53  for (int i=0; i<numX[0]; i++) {
54  field[i] = coeff[0]*(i*deltaX[0]) + coeff[1];
55  }
56 
57  } else {
58  std::cout << "Invalid no. of dimensions. No. of dimensions = " << numDim << std::endl;
59  }
60 
61 }
62 
63 
64 void CreateConstantVectorField(int numDim, size_t *numX, double *value, double *inputField)
65 {
66 
67  if (numDim==3) {
68 
69  size_t numPoints = numX[0]*numX[1]*numX[2];
70 
71  for (int iDim=0; iDim<numDim; iDim++) {
72  size_t iDimxnumPoints = iDim*numPoints;
73 
74  for (size_t iPoint=0; iPoint<numPoints; iPoint++) {
75  inputField[iDimxnumPoints+iPoint] = value[iDim];
76  }
77  }
78 
79  } else {
80  std::cout << "Invalid no. of dimensions. Only 3-D is allowed." << std::endl;
81  }
82 
83 }
84 
85 
86 void CreateCurlFreeVectorFieldNonzeroDDx1(int numDim, size_t *numX, double *deltaX, double *inputField)
87 /******************************************************************************************************
88 
89  Create curl-free vector field with non-zero derivatives.
90  Vector field is derived from the gradient of the potential:
91  phi(x,y,z) = coeff*x*y*z
92 
93  ******************************************************************************************************/
94 {
95 
96  if (numDim==3) {
97 
98  double coeff = 3.0;
99  double X, Y, Z;
100 
101  size_t numPoints = numX[0]*numX[1]*numX[2];
102  size_t numX0xnumX1 = numX[0]*numX[1];
103  size_t XYZIndex, XYIndex;
104 
105  // Calculate x-component
106  for (size_t iZ=0; iZ<numX[2]; iZ++) {
107  XYZIndex = iZ*numX0xnumX1;
108  Z = iZ*deltaX[2];
109 
110  for (size_t iY=0; iY<numX[1]; iY++) {
111  XYIndex = iY*numX[0];
112  Y = iY*deltaX[1];
113 
114  for (size_t iX=0; iX<numX[0]; iX++) {
115  inputField[XYZIndex+XYIndex+iX] = coeff*Y*Z;
116  }
117  }
118  }
119 
120  // Calculate y-component
121  for (size_t iZ=0; iZ<numX[2]; iZ++) {
122  XYZIndex = iZ*numX0xnumX1;
123  Z = iZ*deltaX[2];
124 
125  for (size_t iY=0; iY<numX[1]; iY++) {
126  XYIndex = iY*numX[0];
127 
128  for (size_t iX=0; iX<numX[0]; iX++) {
129  X = iX*deltaX[0];
130  inputField[numPoints+XYZIndex+XYIndex+iX] = coeff*X*Z;
131  }
132  }
133  }
134 
135  // Calculate z-component
136  size_t twoxnumPoints = 2*numPoints;
137  for (size_t iZ=0; iZ<numX[2]; iZ++) {
138  XYZIndex = iZ*numX0xnumX1;
139 
140  for (size_t iY=0; iY<numX[1]; iY++) {
141  XYIndex = iY*numX[0];
142  Y = iY*deltaX[1];
143 
144  for (size_t iX=0; iX<numX[0]; iX++) {
145  X = iX*deltaX[0];
146  inputField[twoxnumPoints+XYZIndex+XYIndex+iX] = coeff*X*Y;
147  }
148  }
149  }
150 
151  } else {
152  std::cout << "Invalid no. of dimensions. Only 3-D is allowed." << std::endl;
153  }
154 
155 }
156 
157 
158 void CreateCurlFreeVectorFieldNonzeroDDx2(int numDim, size_t *numX, double *deltaX, double *inputField)
159 /******************************************************************************************************
160 
161  Create curl-free vector field with non-zero derivatives.
162  Vector field is derived from the gradient of the potential:
163  phi(x,y,z) = coeff*(x*y*z)^2
164 
165  ******************************************************************************************************/
166 {
167 
168  if (numDim==3) {
169 
170  double coeff = 3.0;
171  double Y, Z;
172  double Xsq, Ysq, Zsq;
173 
174  size_t numPoints = numX[0]*numX[1]*numX[2];
175  size_t numX0xnumX1 = numX[0]*numX[1];
176  size_t XYZIndex, XYIndex;
177 
178  // Calculate squares of grid size in each dim.
179  double deltaXsq[3];
180  for (int iDim=0; iDim<numDim; iDim++) {
181  deltaXsq[iDim] = deltaX[iDim]*deltaX[iDim];
182  }
183 
184  // Calculate x-component
185  for (size_t iZ=0; iZ<numX[2]; iZ++) {
186  XYZIndex = iZ*numX0xnumX1;
187  Zsq = iZ*iZ*deltaXsq[2];
188 
189  for (size_t iY=0; iY<numX[1]; iY++) {
190  XYIndex = iY*numX[0];
191  Ysq = iY*iY*deltaXsq[1];
192 
193  for (size_t iX=0; iX<numX[0]; iX++) {
194  inputField[XYZIndex+XYIndex+iX] = coeff*iX*deltaX[0]*Ysq*Zsq;
195  }
196  }
197  }
198 
199  // Calculate y-component
200  for (size_t iZ=0; iZ<numX[2]; iZ++) {
201  XYZIndex = iZ*numX0xnumX1;
202  Zsq = iZ*iZ*deltaXsq[2];
203 
204  for (size_t iY=0; iY<numX[1]; iY++) {
205  XYIndex = iY*numX[0];
206  Y = iY*deltaX[1];
207 
208  for (size_t iX=0; iX<numX[0]; iX++) {
209  Xsq = iX*iX*deltaXsq[0];
210  inputField[numPoints+XYZIndex+XYIndex+iX] = coeff*Xsq*Y*Zsq;
211  }
212  }
213  }
214 
215  // Calculate z-component
216  size_t twoxnumPoints = 2*numPoints;
217  for (size_t iZ=0; iZ<numX[2]; iZ++) {
218  XYZIndex = iZ*numX0xnumX1;
219  Z = iZ*deltaX[2];
220 
221  for (size_t iY=0; iY<numX[1]; iY++) {
222  XYIndex = iY*numX[0];
223  Ysq = iY*iY*deltaXsq[1];
224 
225  for (size_t iX=0; iX<numX[0]; iX++) {
226  Xsq = iX*iX*deltaXsq[0];
227  inputField[twoxnumPoints+XYZIndex+XYIndex+iX] = coeff*Xsq*Ysq*Z;
228  }
229  }
230  }
231 
232  } else {
233  std::cout << "Invalid no. of dimensions. Only 3-D is allowed." << std::endl;
234  }
235 
236 }
237 
238 
239 void CreateConstCurlVectorField(int numDim, size_t *numX, double *deltaX, double *inputField, double *curlComp)
240 /**************************************************************************************************************
241 
242  Create a vector field with a constant curl everywhere.
243  Vector field is given by:
244  V(x,y,z) = (C00*x+C01*y+C02*z, C10*x+C11*y+C12*z, C20*x+C21*y+C22*z)
245 
246  **************************************************************************************************************/
247 {
248 
249  if (numDim==3) {
250 
251  double X, Y, Z;
252 
253  double C0[3] = { 3.0, -7.0, 1.0};
254  double C1[3] = {-4.0, 9.0, 6.0};
255  double C2[3] = { 5.0, 8.0, 2.0};
256 
257  size_t numPoints = numX[0]*numX[1]*numX[2];
258  size_t numX0xnumX1 = numX[0]*numX[1];
259  size_t XYZIndex, XYIndex;
260 
261  // Calculate expected curl components
262  curlComp[0] = C2[1]-C1[2];
263  curlComp[1] = C0[2]-C2[0];
264  curlComp[2] = C1[0]-C0[1];
265 
266  // Calculate x-component
267  for (size_t iZ=0; iZ<numX[2]; iZ++) {
268  XYZIndex = iZ*numX0xnumX1;
269  Z = iZ*deltaX[2];
270 
271  for (size_t iY=0; iY<numX[1]; iY++) {
272  XYIndex = iY*numX[0];
273  Y = iY*deltaX[1];
274 
275  for (size_t iX=0; iX<numX[0]; iX++) {
276  X = iX*deltaX[0];
277  inputField[XYZIndex+XYIndex+iX] = C0[0]*X+C0[1]*Y+C0[2]*Z;
278  }
279  }
280  }
281 
282  // Calculate y-component
283  for (size_t iZ=0; iZ<numX[2]; iZ++) {
284  XYZIndex = iZ*numX0xnumX1;
285  Z = iZ*deltaX[2];
286 
287  for (size_t iY=0; iY<numX[1]; iY++) {
288  XYIndex = iY*numX[0];
289  Y = iY*deltaX[1];
290 
291  for (size_t iX=0; iX<numX[0]; iX++) {
292  X = iX*deltaX[0];
293  inputField[numPoints+XYZIndex+XYIndex+iX] = C1[0]*X+C1[1]*Y+C1[2]*Z;
294  }
295  }
296  }
297 
298  // Calculate z-component
299  size_t twoxnumPoints = 2*numPoints;
300  for (size_t iZ=0; iZ<numX[2]; iZ++) {
301  XYZIndex = iZ*numX0xnumX1;
302  Z = iZ*deltaX[2];
303 
304  for (size_t iY=0; iY<numX[1]; iY++) {
305  XYIndex = iY*numX[0];
306  Y = iY*deltaX[1];
307 
308  for (size_t iX=0; iX<numX[0]; iX++) {
309  X = iX*deltaX[0];
310  inputField[twoxnumPoints+XYZIndex+XYIndex+iX] = C2[0]*X+C2[1]*Y+C2[2]*Z;
311  }
312  }
313  }
314 
315  } else {
316  std::cout << "Invalid no. of dimensions. Only 3-D is allowed." << std::endl;
317  }
318 
319 }
320 
321 
322 void CreateLinearIncreasingField(size_t numPoints, double coeff, double *inputField)
323 {
324 
325  for (size_t iPoint=0; iPoint<numPoints; iPoint++) {
326  inputField[iPoint] = coeff*(1.0+static_cast<double>(iPoint));
327  }
328 
329 }
330 
331 
332 void TestApplyOperatorAppl(ix::test::results &serialUnitResults)
333 /****************************************************************
334 
335  Test if ApplyOperator is applied correctly.
336 
337  ****************************************************************/
338 {
339 
340  int interiorOrder = 2;
342  plascom2::operators::sbp::Initialize(sbpXX, interiorOrder);
343 
344  // Forticate the stencil starts
345  for (int iStencil=0; iStencil<sbpXX.numStencils; iStencil++)
346  sbpXX.stencilStarts[iStencil]++;
347 
348  // Initialize test boolean operator
349  bool MaxwellApplyOperator = true;
350 
351  int numDim = 3; // no. of dims.
352  int numComponents = 1; // some variable - currently unused
353  int boundaryDepth = (sbpXX.numStencils-1)/2; // no. of pts. near boundaries that must use boundary stencils
354  size_t numPoints = 1; // total no. of pts.
355 
356  size_t *numX = new size_t [numDim]; // no. of pts. in each dim.
357  double *lengthX = new double [numDim]; // length in each dim.
358  double *deltaX = new double [numDim]; // grid size in each dim.
359  double *recipDeltaX = new double [numDim]; // reciprocal of grid size in each dim.
360  size_t *opInterval = new size_t [2*numDim]; // start and end indices in each dim.
361 
362  double *inputData = NULL; // input field
363  double *opData = NULL; // operator output field
364  int *stencilID = NULL; // stencil ID for each pt. in each dim.
365 
366  // Set and calculate domain parameters
367  for (int iDim=0; iDim<numDim; iDim++) {
368  numX[iDim] = std::pow(2,static_cast<double>(iDim))*2*boundaryDepth+20;
369  lengthX[iDim] = 1.0;
370  deltaX[iDim] = lengthX[iDim]/(numX[iDim]-1);
371  recipDeltaX[iDim] = 1.0/deltaX[iDim];
372  numPoints *= numX[iDim];
373 
374  opInterval[2*iDim] = 1;
375  opInterval[2*iDim+1] = numX[iDim];
376  }
377 
378  inputData = new double [numPoints];
379  opData = new double [numDim*numPoints];
380  stencilID = new int [numDim*numPoints];
381 
382  // Create connectivity for stencil - set stencil ID
383  plascom2::operators::sbp::CreateStencilConnectivity(numDim, numX, opInterval, boundaryDepth, stencilID, true);
384 
385  // Create linear scalar field: f = coeff*[x 1]'
386  double *coeff = new double [numDim+1];
387  CreateLinearScalarField(numDim, numX, deltaX, inputData, coeff);
388 
389  // Apply ApplyOperator to obtain df
390  for (int opDir=1; opDir<=numDim; opDir++) {
391  FC_MODULE(operators,applyoperator,OPERATORS,APPLYOPERATOR)(&numDim, numX, &numComponents, &numPoints,
392  &opDir, opInterval, &(sbpXX.numStencils), sbpXX.stencilSizes,
393  sbpXX.stencilStarts, &(sbpXX.numValues),
394  sbpXX.stencilWeights, sbpXX.stencilOffsets,
395  &stencilID[(opDir-1)*numPoints], inputData, &opData[(opDir-1)*numPoints]);
396  }
397 
398  // Run test
399  for (int iDim=0; iDim<numDim && MaxwellApplyOperator; iDim++) {
400  size_t iDimxnumPoints = iDim*numPoints;
401 
402  for (int iPoints=0; iPoints<numPoints && MaxwellApplyOperator; iPoints++) {
403  if (std::fabs(recipDeltaX[iDim]*opData[iPoints+iDimxnumPoints]-coeff[iDim]) > MACHINE_EPS) {
404  MaxwellApplyOperator = false;
405 // break;
406  }
407  }
408  }
409 
410  serialUnitResults.UpdateResult("Maxwell:TestApplyOperatorAppl", MaxwellApplyOperator);
411 
412  // Free memory
413  delete [] numX;
414  delete [] lengthX;
415  delete [] deltaX;
416  delete [] recipDeltaX;
417  delete [] opInterval;
418 
419  delete [] inputData;
420  delete [] opData;
421  delete [] stencilID;
422 
423  delete [] coeff;
424 
425 }
426 
427 
428 void TestCurlOperator(ix::test::results &serialUnitResults)
429 /***********************************************************
430 
431  Test curl operator function.
432 
433  ***********************************************************/
434 {
435 
436  int interiorOrder = 4;
438  plascom2::operators::sbp::Initialize(sbpXX, interiorOrder);
439 
440  // Forticate the stencil starts
441  for (int iStencil=0; iStencil<sbpXX.numStencils; iStencil++)
442  sbpXX.stencilStarts[iStencil]++;
443 
444  // Initialize Boolean operator
445  int numTests = 3;
446  std::vector<bool> MaxwellCurlOperator(numTests, true);
447 
448  int numDim = 3; // no. of dims.
449  int numComponents = 1; // some variable - currently unused
450  int boundaryDepth = (sbpXX.numStencils-1)/2; // no. of pts. near boundaries that must use boundary stencils
451  size_t numPoints = 1; // total no. of pts.
452 
453  size_t *numX = new size_t [numDim]; // no. of pts. in each dim.
454  double *lengthX = new double [numDim]; // length in each dim.
455  double *deltaX = new double [numDim]; // grid size in each dim.
456  double *recipDeltaX = new double [numDim]; // reciprocal of grid size in each dim.
457  size_t *opInterval = new size_t [2*numDim]; // start and end indices in each dim.
458 
459  double *inputField = NULL; // input field
460  double *outputField = NULL; // operator output field
461  int *stencilID = NULL; // stencil ID for each pt. in each dim.
462 
463  double *recipDeltaXField = NULL; // field of reciprocal of grid size in each dim.
464 
465  // Set and calculate domain parameters
466  for (int iDim=0; iDim<numDim; iDim++) {
467  numX[iDim] = std::pow(2,static_cast<double>(iDim))*2*boundaryDepth+20;
468  lengthX[iDim] = 1.0;
469  deltaX[iDim] = lengthX[iDim]/(numX[iDim]-1);
470  recipDeltaX[iDim] = 1.0/deltaX[iDim];
471  numPoints *= numX[iDim];
472 
473  opInterval[2*iDim] = 1;
474  opInterval[2*iDim+1] = numX[iDim];
475  }
476 
477  recipDeltaXField = new double [numDim*numPoints];
478  for (int iDim=0; iDim<numDim; iDim++) {
479  size_t iDimxnumPoints = iDim*numPoints;
480 
481  for (size_t iPoint=0; iPoint<numPoints; iPoint++) {
482  recipDeltaXField[iDimxnumPoints+iPoint] = recipDeltaX[iDim];
483  }
484  }
485 
486  // Create connectivity for stencil - set stencil ID
487  stencilID = new int [numDim*numPoints];
488  plascom2::operators::sbp::CreateStencilConnectivity(numDim, numX, opInterval, boundaryDepth, stencilID, true);
489 
490 
491  /* ======== CASE 1: Constant field ======== */
492  inputField = new double [numDim*numPoints];
493  outputField = new double [numDim*numPoints];
494 
495  // Populate field
496  double constComp[3] = {0.0, 1.0, 2.0};
497  CreateConstantVectorField(numDim, numX, constComp, inputField);
498 
499  // Compute curl of field
500  Maxwell::ComputeCurl(numDim, numX, numComponents,
501  numPoints, opInterval, stencilID,
502  sbpXX, recipDeltaXField, inputField, outputField);
503 
504  // Execute test
505  for (int iDim=0; iDim<numDim && MaxwellCurlOperator[0]; iDim++) {
506  size_t iDimxnumPoints = iDim*numPoints;
507 
508  for (size_t iPoint=0; iPoint<numPoints && MaxwellCurlOperator[0]; iPoint++) {
509  if (std::fabs(outputField[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
510  MaxwellCurlOperator[0] = false;
511  }
512  }
513  }
514 
515  serialUnitResults.UpdateResult("Maxwell:TestCurlOperator:Case1", MaxwellCurlOperator[0]);
516 
517  delete [] inputField;
518  delete [] outputField;
519 
520 
521 // /* ======== CASE 1: Curl-free field (zero partial derivatives) ======== */
522 // inputField = new double [numDim*numPoints];
523 //
524 // // Populate field
525 // CreateCurlFreeVectorFieldZeroDDx();
526 //
527 // // Compute curl of field
528 //
529 // // Run test
530 //
531 // serialUnitResults.UpdateResult("Maxwell:TestCurlOperator:Case1", MaxwellCurlOperator[0]);
532 //
533 // delete [] inputField;
534 
535 
536  /* ======== CASE 2: Curl-free field (non-zero partial derivatives) ======== */
537  inputField = new double [numDim*numPoints];
538  outputField = new double [numDim*numPoints];
539 
540  // Populate field
541  CreateCurlFreeVectorFieldNonzeroDDx1(numDim, numX, deltaX, inputField);
542 
543  // Compute curl of field
544  Maxwell::ComputeCurl(numDim, numX, numComponents,
545  numPoints, opInterval, stencilID,
546  sbpXX, recipDeltaXField, inputField, outputField);
547 
548  // Execute test
549  for (int iDim=0; iDim<numDim && MaxwellCurlOperator[1]; iDim++) {
550  size_t iDimxnumPoints = iDim*numPoints;
551 
552  for (size_t iPoint=0; iPoint<numPoints && MaxwellCurlOperator[1]; iPoint++) {
553  if (std::fabs(outputField[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
554  MaxwellCurlOperator[1] = false;
555  }
556  }
557  }
558 
559  serialUnitResults.UpdateResult("Maxwell:TestCurlOperator:Case2", MaxwellCurlOperator[1]);
560 
561  delete [] inputField;
562  delete [] outputField;
563 
564 
565  /* ======== CASE 3: Constant-curl field ======== */
566  double curlComp[3];
567  inputField = new double [numDim*numPoints];
568  outputField = new double [numDim*numPoints];
569 
570  // Populate field
571  CreateConstCurlVectorField(numDim, numX, deltaX, inputField, curlComp);
572 
573  // Compute curl of field
574  Maxwell::ComputeCurl(numDim, numX, numComponents,
575  numPoints, opInterval, stencilID,
576  sbpXX, recipDeltaXField, inputField, outputField);
577 
578  // Execute test
579  for (int iDim=0; iDim<numDim && MaxwellCurlOperator[2]; iDim++) {
580  size_t iDimxnumPoints = iDim*numPoints;
581 
582  for (size_t iPoint=0; iPoint<numPoints && MaxwellCurlOperator[2]; iPoint++) {
583  if (std::fabs(outputField[iDimxnumPoints+iPoint]-curlComp[iDim]) > MACHINE_EPS) {
584  MaxwellCurlOperator[2] = false;
585  }
586  }
587  }
588 
589  serialUnitResults.UpdateResult("Maxwell:TestCurlOperator:Case3", MaxwellCurlOperator[2]);
590 
591  delete [] inputField;
592  delete [] outputField;
593 
594 
595  // Free memory
596  delete [] numX;
597  delete [] lengthX;
598  delete [] deltaX;
599  delete [] recipDeltaX;
600  delete [] opInterval;
601 
602  delete [] stencilID;
603  delete [] recipDeltaXField;
604 
605 }
606 
607 
608 void TestMaxwellRHS_Bfield(ix::test::results &serialUnitResults)
609 /***************************************************************
610 
611  Test RHS function for B-field (Faraday's law):
612  dBdt = -curl(E)
613 
614  ***************************************************************/
615 {
616 
617  int interiorOrder = 4;
619  plascom2::operators::sbp::Initialize(sbpXX, interiorOrder);
620 
621  // Forticate the stencil starts
622  for (int iStencil=0; iStencil<sbpXX.numStencils; iStencil++)
623  sbpXX.stencilStarts[iStencil]++;
624 
625  // Initialize Boolean operator
626  int numTests = 3;
627  std::vector<bool> MaxwellRHS_Bfield(numTests, true);
628 
629  int numDim = 3; // no. of dims.
630  int numComponents = 1; // some variable - currently unused
631  int boundaryDepth = (sbpXX.numStencils-1)/2; // no. of pts. near boundaries that must use boundary stencils
632  size_t numPoints = 1; // total no. of pts.
633 
634  size_t *numX = new size_t [numDim]; // no. of pts. in each dim.
635  double *lengthX = new double [numDim]; // length in each dim.
636  double *deltaX = new double [numDim]; // grid size in each dim.
637  double *recipDeltaX = new double [numDim]; // reciprocal of grid size in each dim.
638  size_t *opInterval = new size_t [2*numDim]; // start and end indices in each dim.
639 
640  double *inputField = NULL; // input field
641  double *outputField = NULL; // operator output field
642  int *stencilID = NULL; // stencil ID for each pt. in each dim.
643 
644  double *recipDeltaXField = NULL; // field of reciprocal of grid size in each dim.
645 
646  // Set and calculate domain parameters
647  for (int iDim=0; iDim<numDim; iDim++) {
648  numX[iDim] = std::pow(2,static_cast<double>(iDim))*2*boundaryDepth+20;
649  lengthX[iDim] = 1.0;
650  deltaX[iDim] = lengthX[iDim]/(numX[iDim]-1);
651  recipDeltaX[iDim] = 1.0/deltaX[iDim];
652  numPoints *= numX[iDim];
653 
654  opInterval[2*iDim] = 1;
655  opInterval[2*iDim+1] = numX[iDim];
656  }
657 
658  recipDeltaXField = new double [numDim*numPoints];
659  for (int iDim=0; iDim<numDim; iDim++) {
660  size_t iDimxnumPoints = iDim*numPoints;
661 
662  for (size_t iPoint=0; iPoint<numPoints; iPoint++) {
663  recipDeltaXField[iDimxnumPoints+iPoint] = recipDeltaX[iDim];
664  }
665  }
666 
667  // Create connectivity for stencil - set stencil ID
668  stencilID = new int [numDim*numPoints];
669  plascom2::operators::sbp::CreateStencilConnectivity(numDim, numX, opInterval, boundaryDepth, stencilID, true);
670 
671 
672  /* ======== CASE 1: Constant field ======== */
673  inputField = new double [numDim*numPoints];
674  outputField = new double [numDim*numPoints];
675 
676  // Populate field
677  double constComp[3] = {0.0, 1.0, 2.0};
678  CreateConstantVectorField(numDim, numX, constComp, inputField);
679 
680  // Compute RHS for B-field
681  Maxwell::ComputeMaxwellRHS_Bfield(numDim, numX, numComponents,
682  numPoints, opInterval, stencilID,
683  sbpXX, recipDeltaXField, inputField, outputField);
684 
685  // Execute test
686  for (int iDim=0; iDim<numDim && MaxwellRHS_Bfield[0]; iDim++) {
687  size_t iDimxnumPoints = iDim*numPoints;
688 
689  for (size_t iPoint=0; iPoint<numPoints && MaxwellRHS_Bfield[0]; iPoint++) {
690  if (std::fabs(outputField[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
691  MaxwellRHS_Bfield[0] = false;
692  }
693  }
694  }
695 
696  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS_Bfield:Case1", MaxwellRHS_Bfield[0]);
697 
698  delete [] inputField;
699  delete [] outputField;
700 
701 
702 // /* ======== CASE 1: Curl-free field (zero partial derivatives) ======== */
703 // inputField = new double [numDim*numPoints];
704 //
705 // // Populate field
706 // CreateCurlFreeVectorFieldZeroDDx();
707 //
708 // // Compute curl of field
709 //
710 // // Run test
711 //
712 // serialUnitResults.UpdateResult("Maxwell:TestCurlOperator:Case1", MaxwellCurlOperator[0]);
713 //
714 // delete [] inputField;
715 
716 
717  /* ======== CASE 2: Curl-free field (non-zero partial derivatives) ======== */
718  inputField = new double [numDim*numPoints];
719  outputField = new double [numDim*numPoints];
720 
721  // Populate field
722  CreateCurlFreeVectorFieldNonzeroDDx1(numDim, numX, deltaX, inputField);
723 
724  // Compute RHS for B-field
725  Maxwell::ComputeMaxwellRHS_Bfield(numDim, numX, numComponents,
726  numPoints, opInterval, stencilID,
727  sbpXX, recipDeltaXField, inputField, outputField);
728 
729  // Execute test
730  for (int iDim=0; iDim<numDim && MaxwellRHS_Bfield[1]; iDim++) {
731  size_t iDimxnumPoints = iDim*numPoints;
732 
733  for (size_t iPoint=0; iPoint<numPoints && MaxwellRHS_Bfield[1]; iPoint++) {
734  if (std::fabs(outputField[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
735  MaxwellRHS_Bfield[1] = false;
736  }
737  }
738  }
739 
740  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS_Bfield:Case2", MaxwellRHS_Bfield[1]);
741 
742  delete [] inputField;
743  delete [] outputField;
744 
745 
746  /* ======== CASE 3: Constant-curl field ======== */
747  double curlComp[3];
748  inputField = new double [numDim*numPoints];
749  outputField = new double [numDim*numPoints];
750 
751  // Populate field
752  CreateConstCurlVectorField(numDim, numX, deltaX, inputField, curlComp);
753 
754  // Compute RHS for B-field
755  Maxwell::ComputeMaxwellRHS_Bfield(numDim, numX, numComponents,
756  numPoints, opInterval, stencilID,
757  sbpXX, recipDeltaXField, inputField, outputField);
758 
759  // Execute test
760  for (int iDim=0; iDim<numDim && MaxwellRHS_Bfield[2]; iDim++) {
761  size_t iDimxnumPoints = iDim*numPoints;
762 
763  for (size_t iPoint=0; iPoint<numPoints && MaxwellRHS_Bfield[2]; iPoint++) {
764  if (std::fabs(outputField[iDimxnumPoints+iPoint]+curlComp[iDim]) > MACHINE_EPS) {
765  MaxwellRHS_Bfield[2] = false;
766  }
767  }
768  }
769 
770  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS_Bfield:Case3", MaxwellRHS_Bfield[2]);
771 
772  delete [] inputField;
773  delete [] outputField;
774 
775 
776  // Free memory
777  delete [] numX;
778  delete [] lengthX;
779  delete [] deltaX;
780  delete [] recipDeltaX;
781  delete [] opInterval;
782 
783  delete [] stencilID;
784  delete [] recipDeltaXField;
785 
786 }
787 
788 
789 void TestMaxwellRHS_Dfield(ix::test::results &serialUnitResults)
790 /***************************************************************
791 
792  Test RHS function for D-field (Ampere's law):
793  dDdt = curl(H)-J
794 
795  ***************************************************************/
796 {
797 
798  int interiorOrder = 4;
800  plascom2::operators::sbp::Initialize(sbpXX, interiorOrder);
801 
802  // Forticate the stencil starts
803  for (int iStencil=0; iStencil<sbpXX.numStencils; iStencil++)
804  sbpXX.stencilStarts[iStencil]++;
805 
806  // Initialize Boolean operator
807  int numTests = 5;
808  std::vector<bool> MaxwellRHS_Dfield(numTests, true);
809 
810  int numDim = 3; // no. of dims.
811  int numComponents = 1; // some variable - currently unused
812  int boundaryDepth = (sbpXX.numStencils-1)/2; // no. of pts. near boundaries that must use boundary stencils
813  size_t numPoints = 1; // total no. of pts.
814 
815  size_t *numX = new size_t [numDim]; // no. of pts. in each dim.
816  double *lengthX = new double [numDim]; // length in each dim.
817  double *deltaX = new double [numDim]; // grid size in each dim.
818  double *recipDeltaX = new double [numDim]; // reciprocal of grid size in each dim.
819  size_t *opInterval = new size_t [2*numDim]; // start and end indices in each dim.
820 
821  double *inputField = NULL; // input field
822  double *J = NULL; // current density field
823  double *outputField = NULL; // operator output field
824  int *stencilID = NULL; // stencil ID for each pt. in each dim.
825 
826  double *recipDeltaXField = NULL; // field of reciprocal of grid size in each dim.
827 
828  // Set and calculate domain parameters
829  for (int iDim=0; iDim<numDim; iDim++) {
830  numX[iDim] = std::pow(2,static_cast<double>(iDim))*2*boundaryDepth+20;
831  lengthX[iDim] = 1.0;
832  deltaX[iDim] = lengthX[iDim]/(numX[iDim]-1);
833  recipDeltaX[iDim] = 1.0/deltaX[iDim];
834  numPoints *= numX[iDim];
835 
836  opInterval[2*iDim] = 1;
837  opInterval[2*iDim+1] = numX[iDim];
838  }
839 
840  recipDeltaXField = new double [numDim*numPoints];
841  for (int iDim=0; iDim<numDim; iDim++) {
842  size_t iDimxnumPoints = iDim*numPoints;
843 
844  for (size_t iPoint=0; iPoint<numPoints; iPoint++) {
845  recipDeltaXField[iDimxnumPoints+iPoint] = recipDeltaX[iDim];
846  }
847  }
848 
849  // Create connectivity for stencil - set stencil ID
850  stencilID = new int [numDim*numPoints];
851  plascom2::operators::sbp::CreateStencilConnectivity(numDim, numX, opInterval, boundaryDepth, stencilID, true);
852 
853 
854  /* ======== CASE 1: Constant field and J=0 ======== */
855  inputField = new double [numDim*numPoints];
856  J = new double [numDim*numPoints];
857  outputField = new double [numDim*numPoints];
858 
859  // Populate fields
860  double constComp1[3] = {0.0, 1.0, 2.0};
861  CreateConstantVectorField(numDim, numX, constComp1, inputField);
862 
863  double constCompJ1[3] = {0.0, 0.0, 0.0};
864  CreateConstantVectorField(numDim, numX, constCompJ1, J);
865 
866  // Compute RHS for D-field
867  Maxwell::ComputeMaxwellRHS_Dfield(numDim, numX, numComponents,
868  numPoints, opInterval, stencilID,
869  sbpXX, recipDeltaXField, inputField, J, outputField);
870 
871  // Execute test
872  for (int iDim=0; iDim<numDim && MaxwellRHS_Dfield[0]; iDim++) {
873  size_t iDimxnumPoints = iDim*numPoints;
874 
875  for (size_t iPoint=0; iPoint<numPoints && MaxwellRHS_Dfield[0]; iPoint++) {
876  if (std::fabs(outputField[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
877  MaxwellRHS_Dfield[0] = false;
878  }
879  }
880  }
881 
882  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS_Dfield:Case1", MaxwellRHS_Dfield[0]);
883 
884  delete [] inputField;
885  delete [] J;
886  delete [] outputField;
887 
888 
889 // /* ======== CASE 1: Curl-free field (zero partial derivatives) ======== */
890 // inputField = new double [numDim*numPoints];
891 //
892 // // Populate field
893 // CreateCurlFreeVectorFieldZeroDDx();
894 //
895 // // Compute curl of field
896 //
897 // // Run test
898 //
899 // serialUnitResults.UpdateResult("Maxwell:TestCurlOperator:Case1", MaxwellCurlOperator[0]);
900 //
901 // delete [] inputField;
902 
903 
904  /* ======== CASE 2: Curl-free field (non-zero partial derivatives) and J=0 ======== */
905  inputField = new double [numDim*numPoints];
906  J = new double [numDim*numPoints];
907  outputField = new double [numDim*numPoints];
908 
909  // Populate fields
910  CreateCurlFreeVectorFieldNonzeroDDx1(numDim, numX, deltaX, inputField);
911 
912  double constCompJ2[3] = {0.0, 0.0, 0.0};
913  CreateConstantVectorField(numDim, numX, constCompJ2, J);
914 
915  // Compute RHS for D-field
916  Maxwell::ComputeMaxwellRHS_Dfield(numDim, numX, numComponents,
917  numPoints, opInterval, stencilID,
918  sbpXX, recipDeltaXField, inputField, J, outputField);
919 
920  // Execute test
921  for (int iDim=0; iDim<numDim && MaxwellRHS_Dfield[1]; iDim++) {
922  size_t iDimxnumPoints = iDim*numPoints;
923 
924  for (size_t iPoint=0; iPoint<numPoints && MaxwellRHS_Dfield[1]; iPoint++) {
925  if (std::fabs(outputField[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
926  MaxwellRHS_Dfield[1] = false;
927  }
928  }
929  }
930 
931  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS_Dfield:Case2", MaxwellRHS_Dfield[1]);
932 
933  delete [] inputField;
934  delete [] J;
935  delete [] outputField;
936 
937 
938  /* ======== CASE 3: Constant-curl field and J=0 ======== */
939  double curlComp3[3];
940  inputField = new double [numDim*numPoints];
941  J = new double [numDim*numPoints];
942  outputField = new double [numDim*numPoints];
943 
944  // Populate fields
945  CreateConstCurlVectorField(numDim, numX, deltaX, inputField, curlComp3);
946 
947  double constCompJ3[3] = {0.0, 0.0, 0.0};
948  CreateConstantVectorField(numDim, numX, constCompJ3, J);
949 
950  // Compute RHS for D-field
951  Maxwell::ComputeMaxwellRHS_Dfield(numDim, numX, numComponents,
952  numPoints, opInterval, stencilID,
953  sbpXX, recipDeltaXField, inputField, J, outputField);
954 
955  // Execute test
956  for (int iDim=0; iDim<numDim && MaxwellRHS_Dfield[2]; iDim++) {
957  size_t iDimxnumPoints = iDim*numPoints;
958 
959  for (size_t iPoint=0; iPoint<numPoints && MaxwellRHS_Dfield[2]; iPoint++) {
960  if (std::fabs(outputField[iDimxnumPoints+iPoint]-curlComp3[iDim]) > MACHINE_EPS) {
961  MaxwellRHS_Dfield[2] = false;
962  }
963  }
964  }
965 
966  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS_Dfield:Case3", MaxwellRHS_Dfield[2]);
967 
968  delete [] inputField;
969  delete [] J;
970  delete [] outputField;
971 
972 
973  /* ======== CASE 4: Curl-free field (non-zero partial derivatives) and J=J(x,y,z) ======== */
974  inputField = new double [numDim*numPoints];
975  J = new double [numDim*numPoints];
976  outputField = new double [numDim*numPoints];
977 
978  // Populate fields
979  CreateCurlFreeVectorFieldNonzeroDDx1(numDim, numX, deltaX, inputField);
980  CreateCurlFreeVectorFieldNonzeroDDx1(numDim, numX, deltaX, J);
981 
982  // Compute RHS for D-field
983  Maxwell::ComputeMaxwellRHS_Dfield(numDim, numX, numComponents,
984  numPoints, opInterval, stencilID,
985  sbpXX, recipDeltaXField, inputField, J, outputField);
986 
987  // Execute test
988  for (int iDim=0; iDim<numDim && MaxwellRHS_Dfield[3]; iDim++) {
989  size_t iDimxnumPoints = iDim*numPoints;
990 
991  for (size_t iPoint=0; iPoint<numPoints && MaxwellRHS_Dfield[3]; iPoint++) {
992  if (std::fabs(outputField[iDimxnumPoints+iPoint]+J[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
993  MaxwellRHS_Dfield[3] = false;
994  }
995  }
996  }
997 
998  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS_Dfield:Case4", MaxwellRHS_Dfield[3]);
999 
1000  delete [] inputField;
1001  delete [] J;
1002  delete [] outputField;
1003 
1004 
1005  /* ======== CASE 5: Constant-curl field and J=(c1,c2,c3) ======== */
1006  double curlComp5[3];
1007  inputField = new double [numDim*numPoints];
1008  J = new double [numDim*numPoints];
1009  outputField = new double [numDim*numPoints];
1010 
1011  // Populate fields
1012  CreateConstCurlVectorField(numDim, numX, deltaX, inputField, curlComp5);
1013 
1014  double constCompJ5[3] = {-1.0, -2.0, 3.0};
1015  CreateConstantVectorField(numDim, numX, constCompJ5, J);
1016 
1017  // Compute RHS for D-field
1018  Maxwell::ComputeMaxwellRHS_Dfield(numDim, numX, numComponents,
1019  numPoints, opInterval, stencilID,
1020  sbpXX, recipDeltaXField, inputField, J, outputField);
1021 
1022  // Execute test
1023  for (int iDim=0; iDim<numDim && MaxwellRHS_Dfield[4]; iDim++) {
1024  size_t iDimxnumPoints = iDim*numPoints;
1025 
1026  for (size_t iPoint=0; iPoint<numPoints && MaxwellRHS_Dfield[4]; iPoint++) {
1027  if (std::fabs(outputField[iDimxnumPoints+iPoint]-curlComp5[iDim]+J[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
1028  MaxwellRHS_Dfield[4] = false;
1029  }
1030  }
1031  }
1032 
1033  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS_Dfield:Case5", MaxwellRHS_Dfield[4]);
1034 
1035  delete [] inputField;
1036  delete [] J;
1037  delete [] outputField;
1038 
1039 
1040  // Free memory
1041  delete [] numX;
1042  delete [] lengthX;
1043  delete [] deltaX;
1044  delete [] recipDeltaX;
1045  delete [] opInterval;
1046 
1047  delete [] stencilID;
1048  delete [] recipDeltaXField;
1049 
1050 }
1051 
1052 
1054 /****************************************************************
1055 
1056  Test function computing reciprocals
1057  of epsilon and mu.
1058 
1059  ****************************************************************/
1060 {
1061 
1062  double eps0 = EPS0;
1063  double mu0 = MU0;
1064 
1065  int numDim = 3; // no. of dims.
1066  size_t numPoints = 1; // total no. of pts.
1067  size_t *numX = new size_t [numDim]; // no. of pts. in each dim.
1068  size_t *opInterval = new size_t [2*numDim]; // start and end indices in each dim.
1069 
1070  double *epsMu = NULL;
1071  double *recipEpsMu = NULL;
1072 
1073  // Initialize Boolean operator
1074  int numTests = 2;
1075  std::vector<bool> MaxwellComputeRecipEpsMu(numTests, true);
1076 
1077  // Set and calculate domain parameters
1078  for (int iDim=0; iDim<numDim; iDim++) {
1079  numX[iDim] = 3+iDim;
1080  numPoints *= numX[iDim];
1081 
1082  opInterval[2*iDim] = 1;
1083  opInterval[2*iDim+1] = numX[iDim];
1084  }
1085 
1086  size_t twoxnumPoints = 2*numPoints;
1087 
1088 
1089  /* ======== CASE 1: Constant eps, mu ======== */
1090  epsMu = new double [2*numPoints];
1091  recipEpsMu = new double [2*numPoints];
1092 
1093  // Populate fields
1094  FC_MODULE(operators,assignmentxa,OPERATORS,ASSIGNMENTXA)(&numDim, &numPoints, numX, opInterval, &eps0, &epsMu[0]);
1095  FC_MODULE(operators,assignmentxa,OPERATORS,ASSIGNMENTXA)(&numDim, &numPoints, numX, opInterval, &mu0, &epsMu[numPoints]);
1096 
1097  // Compute reciprocals
1098  Maxwell::ComputeRecipEpsMu(numDim, numPoints, numX, opInterval, epsMu, recipEpsMu);
1099 
1100  // Execute test
1101  for (size_t iPoint=0; iPoint<twoxnumPoints && MaxwellComputeRecipEpsMu[0]; iPoint++) {
1102  if (std::fabs(epsMu[iPoint]*recipEpsMu[iPoint]-1.0) > MACHINE_EPS) {
1103  MaxwellComputeRecipEpsMu[0] = false;
1104  }
1105  }
1106 
1107  serialUnitResults.UpdateResult("Maxwell:TestComputeRecipEpsMu:Case1", MaxwellComputeRecipEpsMu[0]);
1108 
1109  delete [] epsMu;
1110  delete [] recipEpsMu;
1111 
1112 
1113  /* ======== CASE 2: Spatially-varying eps, mu ======== */
1114  epsMu = new double [2*numPoints];
1115  recipEpsMu = new double [2*numPoints];
1116 
1117  // Populate fields
1118  CreateLinearIncreasingField(numPoints, eps0, &epsMu[0]);
1119  CreateLinearIncreasingField(numPoints, mu0, &epsMu[numPoints]);
1120 
1121  // Compute reciprocals
1122  Maxwell::ComputeRecipEpsMu(numDim, numPoints, numX, opInterval, epsMu, recipEpsMu);
1123 
1124  // Execute test
1125  for (size_t iPoint=0; iPoint<twoxnumPoints && MaxwellComputeRecipEpsMu[1]; iPoint++) {
1126  if (std::fabs(epsMu[iPoint]*recipEpsMu[iPoint]-1.0) > MACHINE_EPS) {
1127  MaxwellComputeRecipEpsMu[1] = false;
1128  }
1129  }
1130 
1131  serialUnitResults.UpdateResult("Maxwell:TestComputeRecipEpsMu:Case2", MaxwellComputeRecipEpsMu[1]);
1132 
1133  delete [] epsMu;
1134  delete [] recipEpsMu;
1135 
1136 
1137  // Free memory
1138  delete [] numX;
1139  delete [] opInterval;
1140 
1141 }
1142 
1143 
1144 void TestConvertFields(ix::test::results &serialUnitResults)
1145 /***********************************************************
1146 
1147  Test functions converting between fields:
1148  E->D, D->E, B->H and H->B
1149 
1150  ***********************************************************/
1151 {
1152 
1153  double eps0 = EPS0;
1154  double mu0 = MU0;
1155 
1156  int numDim = 3; // no. of dims.
1157  size_t numPoints = 1; // total no. of pts.
1158  size_t *numX = new size_t [numDim]; // no. of pts. in each dim.
1159  size_t *opInterval = new size_t [2*numDim]; // start and end indices in each dim.
1160 
1161  double *epsMu = NULL;
1162  double *recipEpsMu = NULL;
1163 
1164  double *Efield_i = NULL;
1165  double *Dfield = NULL;
1166  double *Efield_f = NULL;
1167 
1168  double *Bfield_i = NULL;
1169  double *Hfield = NULL;
1170  double *Bfield_f = NULL;
1171 
1172  // Initialize Boolean operator
1173  int numTests = 12;
1174  std::vector<bool> MaxwellConvertFields(numTests, true);
1175 
1176  // Set and calculate domain parameters
1177  for (int iDim=0; iDim<numDim; iDim++) {
1178  numX[iDim] = 3+iDim;
1179  numPoints *= numX[iDim];
1180 
1181  opInterval[2*iDim] = 1;
1182  opInterval[2*iDim+1] = numX[iDim];
1183  }
1184 
1185 
1186  /* ======== CASES 1-4: Constant eps, mu and fields ======== */
1187  epsMu = new double [2*numPoints];
1188  recipEpsMu = new double [2*numPoints];
1189 
1190  Efield_i = new double [numDim*numPoints];
1191  Dfield = new double [numDim*numPoints];
1192  Efield_f = new double [numDim*numPoints];
1193 
1194  Bfield_i = new double [numDim*numPoints];
1195  Hfield = new double [numDim*numPoints];
1196  Bfield_f = new double [numDim*numPoints];
1197 
1198  // Populate fields
1199  FC_MODULE(operators,assignmentxa,OPERATORS,ASSIGNMENTXA)(&numDim, &numPoints, numX, opInterval, &eps0, &epsMu[0]);
1200  FC_MODULE(operators,assignmentxa,OPERATORS,ASSIGNMENTXA)(&numDim, &numPoints, numX, opInterval, &mu0, &epsMu[numPoints]);
1201 
1202  Maxwell::ComputeRecipEpsMu(numDim, numPoints, numX, opInterval, epsMu, recipEpsMu);
1203 
1204  double constCompEi[3] = {1.2, 2.6, 3.8};
1205  CreateConstantVectorField(numDim, numX, constCompEi, Efield_i);
1206 
1207  double constCompBi[3] = {0.6, 4.4, 8.9};
1208  CreateConstantVectorField(numDim, numX, constCompBi, Bfield_i);
1209 
1210  /* == CASE 1: Test conversion E->D == */
1211  Maxwell::ConvertEfieldtoDfield(numDim, numPoints, numX, opInterval, epsMu, Efield_i, Dfield);
1212 
1213  // Execute test
1214  for (int iDim=0; iDim<numDim && MaxwellConvertFields[0]; iDim++) {
1215  size_t iDimxnumPoints = iDim*numPoints;
1216 
1217  for (size_t iPoint=0; iPoint<numPoints && MaxwellConvertFields[0]; iPoint++) {
1218  if (std::fabs(Dfield[iDimxnumPoints+iPoint]-epsMu[iPoint]*Efield_i[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
1219  MaxwellConvertFields[0] = false;
1220  }
1221  }
1222  }
1223 
1224  serialUnitResults.UpdateResult("Maxwell:TestConvertFields:Case1", MaxwellConvertFields[0]);
1225 
1226  /* == CASE 2: Test conversion D->E == */
1227  Maxwell::ConvertDfieldtoEfield(numDim, numPoints, numX, opInterval, recipEpsMu, Dfield, Efield_f);
1228 
1229  // Execute test
1230  for (int iDim=0; iDim<numDim && MaxwellConvertFields[1]; iDim++) {
1231  size_t iDimxnumPoints = iDim*numPoints;
1232 
1233  for (size_t iPoint=0; iPoint<numPoints && MaxwellConvertFields[1]; iPoint++) {
1234  if (std::fabs(Efield_f[iDimxnumPoints+iPoint]-recipEpsMu[iPoint]*Dfield[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
1235  MaxwellConvertFields[1] = false;
1236  }
1237  }
1238  }
1239 
1240  serialUnitResults.UpdateResult("Maxwell:TestConvertFields:Case2", MaxwellConvertFields[1]);
1241 
1242  /* == CASE 1/2: Is Efield_f == Efield_i? == */
1243  for (int iDim=0; iDim<numDim && MaxwellConvertFields[2]; iDim++) {
1244  size_t iDimxnumPoints = iDim*numPoints;
1245 
1246  for (size_t iPoint=0; iPoint<numPoints && MaxwellConvertFields[2]; iPoint++) {
1247  if (std::fabs(Efield_f[iDimxnumPoints+iPoint]-Efield_i[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
1248  MaxwellConvertFields[2] = false;
1249  }
1250  }
1251  }
1252 
1253  serialUnitResults.UpdateResult("Maxwell:TestConvertFields:Case1/2", MaxwellConvertFields[2]);
1254 
1255  /* == CASE 3: Test conversion B->H == */
1256  Maxwell::ConvertBfieldtoHfield(numDim, numPoints, numX, opInterval, recipEpsMu, Bfield_i, Hfield);
1257 
1258  // Execute test
1259  for (int iDim=0; iDim<numDim && MaxwellConvertFields[3]; iDim++) {
1260  size_t iDimxnumPoints = iDim*numPoints;
1261 
1262  for (size_t iPoint=0; iPoint<numPoints && MaxwellConvertFields[3]; iPoint++) {
1263  if (std::fabs(Hfield[iDimxnumPoints+iPoint]-recipEpsMu[numPoints+iPoint]*Bfield_i[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
1264  MaxwellConvertFields[3] = false;
1265  }
1266  }
1267  }
1268 
1269  serialUnitResults.UpdateResult("Maxwell:TestConvertFields:Case3", MaxwellConvertFields[3]);
1270 
1271  /* == CASE 4: Test conversion H->B == */
1272  Maxwell::ConvertHfieldtoBfield(numDim, numPoints, numX, opInterval, epsMu, Hfield, Bfield_f);
1273 
1274  // Execute test
1275  for (int iDim=0; iDim<numDim && MaxwellConvertFields[4]; iDim++) {
1276  size_t iDimxnumPoints = iDim*numPoints;
1277 
1278  for (size_t iPoint=0; iPoint<numPoints && MaxwellConvertFields[4]; iPoint++) {
1279  if (std::fabs(Bfield_f[iDimxnumPoints+iPoint]-epsMu[numPoints+iPoint]*Hfield[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
1280  MaxwellConvertFields[4] = false;
1281  }
1282  }
1283  }
1284 
1285  serialUnitResults.UpdateResult("Maxwell:TestConvertFields:Case4", MaxwellConvertFields[4]);
1286 
1287  /* == CASE 3/4: Is Bfield_f == Bfield_i? == */
1288  for (int iDim=0; iDim<numDim && MaxwellConvertFields[5]; iDim++) {
1289  size_t iDimxnumPoints = iDim*numPoints;
1290 
1291  for (size_t iPoint=0; iPoint<numPoints && MaxwellConvertFields[5]; iPoint++) {
1292  if (std::fabs(Bfield_f[iDimxnumPoints+iPoint]-Bfield_i[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
1293  MaxwellConvertFields[5] = false;
1294  }
1295  }
1296  }
1297 
1298  serialUnitResults.UpdateResult("Maxwell:TestConvertFields:Case3/4", MaxwellConvertFields[5]);
1299 
1300  delete [] epsMu;
1301  delete [] recipEpsMu;
1302 
1303  delete [] Efield_i;
1304  delete [] Dfield;
1305  delete [] Efield_f;
1306 
1307  delete [] Bfield_i;
1308  delete [] Hfield;
1309  delete [] Bfield_f;
1310 
1311 
1312  /* ======== CASES 5-8: Spatially-varying eps, mu and fields ======== */
1313  epsMu = new double [2*numPoints];
1314  recipEpsMu = new double [2*numPoints];
1315 
1316  Efield_i = new double [numDim*numPoints];
1317  Dfield = new double [numDim*numPoints];
1318  Efield_f = new double [numDim*numPoints];
1319 
1320  Bfield_i = new double [numDim*numPoints];
1321  Hfield = new double [numDim*numPoints];
1322  Bfield_f = new double [numDim*numPoints];
1323 
1324  // Populate fields
1325  CreateLinearIncreasingField(numPoints, eps0, &epsMu[0]);
1326  CreateLinearIncreasingField(numPoints, mu0, &epsMu[numPoints]);
1327 
1328  Maxwell::ComputeRecipEpsMu(numDim, numPoints, numX, opInterval, epsMu, recipEpsMu);
1329 
1330  double *deltaX = new double [numDim];
1331  for (int iDim=0; iDim<numDim; iDim++) {
1332  deltaX[iDim] = 0.1*(1.0+static_cast<double>(iDim));
1333  }
1334  CreateCurlFreeVectorFieldNonzeroDDx1(numDim, numX, deltaX, Efield_i);
1335  CreateCurlFreeVectorFieldNonzeroDDx1(numDim, numX, deltaX, Bfield_i);
1336  delete [] deltaX;
1337 
1338  /* == CASE 5: Test conversion E->D == */
1339  Maxwell::ConvertEfieldtoDfield(numDim, numPoints, numX, opInterval, epsMu, Efield_i, Dfield);
1340 
1341  // Execute test
1342  for (int iDim=0; iDim<numDim && MaxwellConvertFields[6]; iDim++) {
1343  size_t iDimxnumPoints = iDim*numPoints;
1344 
1345  for (size_t iPoint=0; iPoint<numPoints && MaxwellConvertFields[6]; iPoint++) {
1346  if (std::fabs(Dfield[iDimxnumPoints+iPoint]-epsMu[iPoint]*Efield_i[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
1347  MaxwellConvertFields[6] = false;
1348  }
1349  }
1350  }
1351 
1352  serialUnitResults.UpdateResult("Maxwell:TestConvertFields:Case5", MaxwellConvertFields[6]);
1353 
1354  /* == CASE 6: Test conversion D->E == */
1355  Maxwell::ConvertDfieldtoEfield(numDim, numPoints, numX, opInterval, recipEpsMu, Dfield, Efield_f);
1356 
1357  // Execute test
1358  for (int iDim=0; iDim<numDim && MaxwellConvertFields[7]; iDim++) {
1359  size_t iDimxnumPoints = iDim*numPoints;
1360 
1361  for (size_t iPoint=0; iPoint<numPoints && MaxwellConvertFields[7]; iPoint++) {
1362  if (std::fabs(Efield_f[iDimxnumPoints+iPoint]-recipEpsMu[iPoint]*Dfield[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
1363  MaxwellConvertFields[7] = false;
1364  }
1365  }
1366  }
1367 
1368  serialUnitResults.UpdateResult("Maxwell:TestConvertFields:Case6", MaxwellConvertFields[7]);
1369 
1370  /* == CASE 5/6: Is Efield_f == Efield_i? == */
1371  for (int iDim=0; iDim<numDim && MaxwellConvertFields[8]; iDim++) {
1372  size_t iDimxnumPoints = iDim*numPoints;
1373 
1374  for (size_t iPoint=0; iPoint<numPoints && MaxwellConvertFields[8]; iPoint++) {
1375  if (std::fabs(Efield_f[iDimxnumPoints+iPoint]-Efield_i[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
1376  MaxwellConvertFields[8] = false;
1377  }
1378  }
1379  }
1380 
1381  serialUnitResults.UpdateResult("Maxwell:TestConvertFields:Case5/6", MaxwellConvertFields[8]);
1382 
1383  /* == CASE 7: Test conversion B->H == */
1384  Maxwell::ConvertBfieldtoHfield(numDim, numPoints, numX, opInterval, recipEpsMu, Bfield_i, Hfield);
1385 
1386  // Execute test
1387  for (int iDim=0; iDim<numDim && MaxwellConvertFields[9]; iDim++) {
1388  size_t iDimxnumPoints = iDim*numPoints;
1389 
1390  for (size_t iPoint=0; iPoint<numPoints && MaxwellConvertFields[9]; iPoint++) {
1391  if (std::fabs(Hfield[iDimxnumPoints+iPoint]-recipEpsMu[numPoints+iPoint]*Bfield_i[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
1392  MaxwellConvertFields[9] = false;
1393  }
1394  }
1395  }
1396 
1397  serialUnitResults.UpdateResult("Maxwell:TestConvertFields:Case7", MaxwellConvertFields[9]);
1398 
1399  /* == CASE 8: Test conversion H->B == */
1400  Maxwell::ConvertHfieldtoBfield(numDim, numPoints, numX, opInterval, epsMu, Hfield, Bfield_f);
1401 
1402  // Execute test
1403  for (int iDim=0; iDim<numDim && MaxwellConvertFields[10]; iDim++) {
1404  size_t iDimxnumPoints = iDim*numPoints;
1405 
1406  for (size_t iPoint=0; iPoint<numPoints && MaxwellConvertFields[10]; iPoint++) {
1407  if (std::fabs(Bfield_f[iDimxnumPoints+iPoint]-epsMu[numPoints+iPoint]*Hfield[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
1408  MaxwellConvertFields[10] = false;
1409  }
1410  }
1411  }
1412 
1413  serialUnitResults.UpdateResult("Maxwell:TestConvertFields:Case8", MaxwellConvertFields[10]);
1414 
1415  /* == CASE 7/8: Is Bfield_f == Bfield_i? == */
1416  for (int iDim=0; iDim<numDim && MaxwellConvertFields[11]; iDim++) {
1417  size_t iDimxnumPoints = iDim*numPoints;
1418 
1419  for (size_t iPoint=0; iPoint<numPoints && MaxwellConvertFields[11]; iPoint++) {
1420  if (std::fabs(Bfield_f[iDimxnumPoints+iPoint]-Bfield_i[iDimxnumPoints+iPoint]) > MACHINE_EPS) {
1421  MaxwellConvertFields[11] = false;
1422  }
1423  }
1424  }
1425 
1426  serialUnitResults.UpdateResult("Maxwell:TestConvertFields:Case7/8", MaxwellConvertFields[11]);
1427 
1428  delete [] epsMu;
1429  delete [] recipEpsMu;
1430 
1431  delete [] Efield_i;
1432  delete [] Dfield;
1433  delete [] Efield_f;
1434 
1435  delete [] Bfield_i;
1436  delete [] Hfield;
1437  delete [] Bfield_f;
1438 
1439 }
1440 
1441 
1442 void TestDirichletBC(ix::test::results &serialUnitResults)
1443 /**********************************************************
1444 
1445  Test Dirichlet boundary condition.
1446 
1447  **********************************************************/
1448 {
1449 
1450  int numDim = 3;
1451  size_t numPointsBuffer, numPointsIndices;
1452  double *bufferVar = NULL;
1453  double *value = NULL;
1454 
1455  // Initialize Boolean operator
1456  int numTests = 2;
1457  std::vector<bool> MaxwellDirichletBC(numTests, true);
1458 
1459 
1460  /* ==== CASE 1: Set 2nd half only ==== */
1461  numPointsBuffer = 120; // = 4 x 5 x 6
1462  numPointsIndices = 60;
1463  std::vector<size_t> bufferIndices1(numPointsIndices, 0);
1464  bufferVar = new double [numDim*numPointsBuffer];
1465  value = new double [numDim];
1466 
1467  // Initialize buffer variables to zero
1468  size_t numDimxnumPointsBuffer = numDim*numPointsBuffer;
1469  for(size_t iPoint=0; iPoint<numDimxnumPointsBuffer; iPoint++) {
1470  bufferVar[iPoint] = 0.0;
1471  }
1472 
1473  // Assign buffer indices
1474  for(size_t iPoint=0; iPoint<numPointsIndices; iPoint++) {
1475  bufferIndices1[iPoint] = 60+iPoint;
1476  }
1477 
1478  // Set values
1479  for(int iDim=0; iDim<numDim; iDim++) {
1480  value[iDim] = 1.0+static_cast<double>(iDim);
1481  }
1482 
1483  // Compute Dirichlet boundary condition
1484  for(int iDim=0; iDim<numDim; iDim++) {
1485  double *bufferPtr = bufferVar + iDim*numPointsBuffer;
1486  if(Maxwell::bc::ComputeDirichletBC(bufferIndices1, bufferPtr, value[iDim]))
1487  MaxwellDirichletBC[0] = false;
1488  }
1489 
1490  // Execute test
1491  for(int iDim=0; iDim<numDim; iDim++) {
1492  size_t iDimxnumPointsBuffer = iDim*numPointsBuffer;
1493 
1494  for(size_t iPoint=0; iPoint<numPointsBuffer; iPoint++) {
1495  if(iPoint<60 && bufferVar[iPoint+iDimxnumPointsBuffer]!=0.0)
1496  MaxwellDirichletBC[0] = false;
1497 
1498  if(iPoint>=60 && bufferVar[iPoint+iDimxnumPointsBuffer]!=value[iDim])
1499  MaxwellDirichletBC[0] = false;
1500  }
1501  }
1502 
1503  serialUnitResults.UpdateResult("Maxwell:TestDirichletBC:Case1", MaxwellDirichletBC[0]);
1504 
1505  delete [] bufferVar;
1506  delete [] value;
1507 
1508 
1509  /* ==== CASE 2: Set every other element ==== */
1510  numPointsBuffer = 120; // = 4 x 5 x 6
1511  numPointsIndices = 60;
1512  std::vector<size_t> bufferIndices2(numPointsIndices, 0);
1513  bufferVar = new double [numDim*numPointsBuffer];
1514  value = new double [numDim];
1515 
1516  // Initialize buffer variables to zero
1517  numDimxnumPointsBuffer = numDim*numPointsBuffer;
1518  for(size_t iPoint=0; iPoint<numDimxnumPointsBuffer; iPoint++) {
1519  bufferVar[iPoint] = 0.0;
1520  }
1521 
1522  // Assign buffer indices
1523  for(size_t iPoint=0; iPoint<numPointsIndices; iPoint++) {
1524  bufferIndices2[iPoint] = 2*iPoint+1;
1525  }
1526 
1527  // Set values
1528  for(int iDim=0; iDim<numDim; iDim++) {
1529  value[iDim] = 1.0+static_cast<double>(iDim);
1530  }
1531 
1532  // Compute Dirichlet boundary condition
1533  for(int iDim=0; iDim<numDim; iDim++) {
1534  double *bufferPtr = bufferVar + iDim*numPointsBuffer;
1535  if(Maxwell::bc::ComputeDirichletBC(bufferIndices2, bufferPtr, value[iDim]))
1536  MaxwellDirichletBC[1] = false;
1537  }
1538 
1539  // Execute test
1540  for(int iDim=0; iDim<numDim; iDim++) {
1541  size_t iDimxnumPointsBuffer = iDim*numPointsBuffer;
1542 
1543  for(size_t iPoint=0; iPoint<numPointsBuffer; iPoint++) {
1544  if(iPoint%2) {
1545  if(bufferVar[iPoint+iDimxnumPointsBuffer]!=value[iDim])
1546  MaxwellDirichletBC[1] = false;
1547  } else {
1548  if(bufferVar[iPoint+iDimxnumPointsBuffer]!=0.0)
1549  MaxwellDirichletBC[1] = false;
1550  }
1551  }
1552  }
1553 
1554  serialUnitResults.UpdateResult("Maxwell:TestDirichletBC:Case2", MaxwellDirichletBC[1]);
1555 
1556  delete [] bufferVar;
1557  delete [] value;
1558 
1559 }
1560 
1561 
1563 
1570 
1571 void TestMaxwellRHS(ix::test::results &serialUnitResults)
1572 /********************************************************
1573 
1574  Test individual components that form
1575  the RHS API for time integration.
1576 
1577  ********************************************************/
1578 {
1579 
1580  int myThreadID = 0; // thread ID
1581 
1582  // basic types for the advection problem
1586 
1587  // -- Set up the RHS --
1588  rhs_t testRHS;
1589 
1590  // -- Set up the grid --
1591  grid_t testGrid;
1592 
1593  // -- Set up the halo --
1594  halo_t &testHalo(testGrid.Halo());
1595 
1596  int numDim = 3;
1597  int interiorOrder = 2;
1598  operator_t sbpXX;
1599 
1600  plascom2::operators::sbp::Initialize(sbpXX, interiorOrder);
1601  int boundaryDepth = (sbpXX.numStencils-1)/2;
1602  std::vector<int> haloDepths(2*numDim,boundaryDepth);
1603  std::vector<int> boundaryDepths(2*numDim,boundaryDepth);
1604 
1605  // // Forticate the stencil starts
1606  // for (int iStencil=0; iStencil<sbpXX.numStencils; iStencil++)
1607  // sbpXX.stencilStarts[iStencil]++;
1608 
1609  std::vector<double> realGridExtent;
1610  realGridExtent.resize(6,0.0);
1611  realGridExtent[1] = 1.0;
1612  realGridExtent[3] = 1.0;
1613  realGridExtent[5] = 1.0;
1614 
1615  std::vector<size_t> numNodes;
1616  numNodes.resize(3);
1617  numNodes[0] = 5;
1618  numNodes[1] = 6;
1619  numNodes[2] = 9;
1620  testGrid.SetGridSizes(numNodes);
1621 
1622  std::vector<double> dX;
1623  dX.resize(3);
1624  for(int iDim = 0;iDim < 3;iDim++)
1625  dX[iDim] = (realGridExtent[2*iDim+1] - realGridExtent[2*iDim])/static_cast<double>(numNodes[iDim] - 1);
1626 
1627  testGrid.SetGridSpacings(dX);
1628 
1629  interval_t &partitionInterval(testGrid.PartitionInterval());
1630  partitionInterval.InitSimple(numNodes);
1631 
1632  // Set up buffers for periodic boundaries
1633  std::vector<size_t> extendGrid(2*numDim,0);
1634 // std::vector<bool> isPeriodic(numDim,true); // periodic true here
1635  std::vector<bool> isPeriodic(numDim,false); // periodic false here
1636  std::vector<int> periodicDirs(numDim,0);
1637  size_t numPointsPart = partitionInterval.NNodes();
1638  for(int iDim = 0;iDim < numDim; iDim++){
1639  if(isPeriodic[iDim]){
1640  extendGrid[2*iDim] = haloDepths[2*iDim];
1641  extendGrid[2*iDim+1] = haloDepths[2*iDim+1];
1642  } else {
1643  if(partitionInterval[iDim].first != 0)
1644  extendGrid[2*iDim] = haloDepths[2*iDim];
1645  if(partitionInterval[iDim].second != (numNodes[iDim]-1))
1646  extendGrid[2*iDim + 1] = haloDepths[2*iDim+1];
1647  }
1648  }
1649  std::cout << "Dimension Extensions: (";
1650  pcpp::io::DumpContents(std::cout,extendGrid,",");
1651  std::cout << ")" << std::endl;
1652  testGrid.SetDimensionExtensions(extendGrid);
1653  testGrid.Finalize();
1654  testHalo.SetPeriodicDirs(periodicDirs);
1655 
1656 
1657  size_t numPointsBuffer = testGrid.BufferSize();
1658  const interval_t &partitionBufferInterval(testGrid.PartitionBufferInterval());
1659 
1660  // set up the state
1661  state_t paramState;
1662  state_t testState;
1663 
1664  Maxwell::util::SetupMaxwellStateAndParameters(testGrid, testState, paramState);
1665  testState.InitializeFieldHandles();
1666 
1667  // set up another state by copying
1668  state_t testState2(testState);
1669 
1670 // std::ostringstream OutStream;
1671 // testState.Report(OutStream);
1672 
1673 
1674  // Populate the state
1675  std::vector<double> constE(3, 1.0);
1676  std::vector<double> constB(3, 1.0);
1677  std::vector<double> constJ(3, 1.0);
1678  double constEps = EPS0*1e12;
1679  double constMu = MU0*1e6;
1680 
1681  Maxwell::util::InitializeMaxwellStateConstFields(testGrid, testState, &constE[0], &constB[0],
1682  &constJ[0], constEps, constMu, false);
1683 
1684  // Populate the parameters
1685  double CFLValue = 1.0;
1686  Maxwell::util::InitializeMaxwellParameters(testGrid, paramState, CFLValue);
1687 
1688 
1689  /* ======== Test RHS initialization routine ======== */
1690  bool MaxwellRHSInitialize = true;
1691  if(testRHS.Initialize(testGrid,testState,paramState,sbpXX))
1692  {
1693  MaxwellRHSInitialize = false;
1694  }
1695  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:Initialize", MaxwellRHSInitialize);
1696 
1697 
1698  /* ======== Test SetParamState() function ======== */
1699  // bool MaxwellRHSSetParamState = true;
1700  // if(testRHS.SetParamState(paramState))
1701  // {
1702  // MaxwellRHSSetParamState = false;
1703  // }
1704  // serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:SetParamState", MaxwellRHSSetParamState);
1705 
1706 
1707  /* ======== Test RHS setup routine ======== */
1708  const std::vector<double *> &stateBuffers(testRHS.StateBuffers());
1709  const std::vector<double *> &rhsBuffers(testRHS.RHSBuffers());
1710 
1711  /**** CALL 1 ****/
1712  bool MaxwellRHSSetup = true;
1713  if(testRHS.SetupRHS(testGrid,testState,testState2,myThreadID))
1714  {
1715  MaxwellRHSSetup = false;
1716  }
1717  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:Setup:Call1", MaxwellRHSSetup);
1718 
1719  // Check state buffers
1720  std::vector<std::string> stateFieldNames;
1721  stateFieldNames.push_back("Efield");
1722  stateFieldNames.push_back("Bfield");
1723  stateFieldNames.push_back("Dfield");
1724  stateFieldNames.push_back("Hfield");
1725  stateFieldNames.push_back("J");
1726  stateFieldNames.push_back("epsilonMu");
1727 
1728  bool MaxwellRHSSetupStateBuffers = true;
1729  if(stateBuffers.size() != stateFieldNames.size())
1730  {
1731  MaxwellRHSSetupStateBuffers = false;
1732  }
1733 
1734  std::vector<double *>::const_iterator stateBuffersIt = stateBuffers.begin();
1735  std::vector<std::string>::iterator stateFieldNamesIt = stateFieldNames.begin();
1736  while(stateBuffersIt != stateBuffers.end()) {
1737  double *stateBuffer = *stateBuffersIt++;
1738  std::string &stateFieldName(*stateFieldNamesIt++);
1739 
1740  if(stateFieldName.compare("Efield")==0 || stateFieldName.compare("Hfield")==0) {
1741  if(testState.GetFieldBuffer<double>(stateFieldName) != stateBuffer) {
1742  MaxwellRHSSetupStateBuffers = false;
1743  }
1744  }
1745  }
1746  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:Setup:Call1:CheckStateBuffers", MaxwellRHSSetupStateBuffers);
1747 
1748  // Check RHS buffers
1749  std::vector<std::string> rhsFieldNames;
1750  rhsFieldNames.push_back("Efield");
1751  rhsFieldNames.push_back("Hfield");
1752 
1753  bool MaxwellRHSSetupRHSBuffers = true;
1754  if(rhsBuffers.size() != rhsFieldNames.size())
1755  {
1756  MaxwellRHSSetupRHSBuffers = false;
1757  }
1758 
1759  std::vector<double *>::const_iterator rhsBuffersIt = rhsBuffers.begin();
1760  std::vector<std::string>::iterator rhsFieldNamesIt = rhsFieldNames.begin();
1761  while(rhsBuffersIt != rhsBuffers.end()) {
1762  double *rhsBuffer = *rhsBuffersIt++;
1763  std::string &rhsFieldName(*rhsFieldNamesIt++);
1764 
1765  if(testState2.GetFieldBuffer<double>(rhsFieldName) != rhsBuffer)
1766  MaxwellRHSSetupRHSBuffers = false;
1767  }
1768  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:Setup:Call1:CheckRHSBuffers", MaxwellRHSSetupRHSBuffers);
1769 
1770  /**** CALL 2 (switch input and output buffers) ****/
1771  bool MaxwellRHSSetup2 = true;
1772  if(testRHS.SetupRHS(testGrid,testState2,testState,myThreadID))
1773  {
1774  MaxwellRHSSetup2 = false;
1775  }
1776  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:Setup:Call2", MaxwellRHSSetup2);
1777 
1778  // Check state buffers
1779  std::vector<std::string> stateFieldNames2;
1780  stateFieldNames2.push_back("Efield");
1781  stateFieldNames2.push_back("Bfield");
1782  stateFieldNames2.push_back("Dfield");
1783  stateFieldNames2.push_back("Hfield");
1784  stateFieldNames2.push_back("J");
1785  stateFieldNames2.push_back("epsilonMu");
1786 
1787  bool MaxwellRHSSetupStateBuffers2 = true;
1788  if(stateBuffers.size() != stateFieldNames2.size())
1789  {
1790  MaxwellRHSSetupStateBuffers2 = false;
1791  }
1792 
1793  std::vector<double *>::const_iterator stateBuffersIt2 = stateBuffers.begin();
1794  std::vector<std::string>::iterator stateFieldNamesIt2 = stateFieldNames2.begin();
1795  while(stateBuffersIt2 != stateBuffers.end()) {
1796  double *stateBuffer2 = *stateBuffersIt2++;
1797  std::string &stateFieldName2(*stateFieldNamesIt2++);
1798 
1799  if(stateFieldName2.compare("Efield")==0 || stateFieldName2.compare("Hfield")==0) {
1800  if(testState2.GetFieldBuffer<double>(stateFieldName2) != stateBuffer2) {
1801  MaxwellRHSSetupStateBuffers2 = false;
1802  }
1803  }
1804  }
1805  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:Setup:Call2:CheckStateBuffers", MaxwellRHSSetupStateBuffers2);
1806 
1807  // Check RHS buffers
1808  std::vector<std::string> rhsFieldNames2;
1809  rhsFieldNames2.push_back("Efield");
1810  rhsFieldNames2.push_back("Hfield");
1811 
1812  bool MaxwellRHSSetupRHSBuffers2 = true;
1813  if(rhsBuffers.size() != rhsFieldNames2.size())
1814  {
1815  MaxwellRHSSetupRHSBuffers2 = false;
1816  }
1817 
1818  std::vector<double *>::const_iterator rhsBuffersIt2 = rhsBuffers.begin();
1819  std::vector<std::string>::iterator rhsFieldNamesIt2 = rhsFieldNames2.begin();
1820  while(rhsBuffersIt2 != rhsBuffers.end()) {
1821  double *rhsBuffer2 = *rhsBuffersIt2++;
1822  std::string &rhsFieldName2(*rhsFieldNamesIt2++);
1823 
1824  if(testState.GetFieldBuffer<double>(rhsFieldName2) != rhsBuffer2)
1825  MaxwellRHSSetupRHSBuffers2 = false;
1826  }
1827  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:Setup:Call2:CheckRHSBuffers", MaxwellRHSSetupRHSBuffers2);
1828 
1829 
1830  /* ======== Test MaxwellRHS() function ======== */
1831  int numTests = 2;
1832  std::vector<bool> MaxwellRHSMaxwellRHS(numTests, true);
1833 
1834  /**** CASE 1: Constant epsilon, mu, E, B and J ****/
1835 
1836  // Set up RHS
1837  if(testRHS.SetupRHS(testGrid,testState,testState2,myThreadID))
1838  {
1839  std::cout << "SetupRHS failed." << std::endl;
1840  MaxwellRHSMaxwellRHS[0] = false;
1841  }
1842 
1843  std::vector<double *>::const_iterator rhsIt = rhsBuffers.begin();
1844  while(rhsIt != rhsBuffers.end()) {
1845  double *rhsBuffer = *rhsIt++;
1846  for(size_t iPoint = 0;iPoint < numDim*numPointsBuffer;iPoint++)
1847  rhsBuffer[iPoint] = 0.0;
1848  }
1849 
1850  // Compute Maxwell RHS
1851  if(testRHS.MaxwellRHS(myThreadID))
1852  {
1853  std::cout << "MaxwellRHS failed." << std::endl;
1854  MaxwellRHSMaxwellRHS[0] = false;
1855  }
1856 
1857  // Execute test
1858  size_t nFailE = 0;
1859  size_t nFailH = 0;
1860  double *dE = rhsBuffers[0];
1861  double *dH = rhsBuffers[1];
1862  double *J = testState.GetFieldBuffer<double>("J");
1863  double *epsMu = testState.GetFieldBuffer<double>("epsilonMu");
1864  for(int iDim=0; iDim<numDim; iDim++) {
1865  size_t iDimxnumPointsBuffer = iDim*numPointsBuffer;
1866  for(size_t iPoint=0; iPoint<numPointsBuffer; iPoint++) {
1867  if(std::fabs(dH[iDimxnumPointsBuffer+iPoint]) > MACHINE_EPS) {
1868  nFailH++;
1869  MaxwellRHSMaxwellRHS[0] = false;
1870  std::cout << "H(" << iDim << "):" << dH[iDimxnumPointsBuffer+iPoint] << std::endl;
1871  }
1872 
1873  if(std::fabs(dE[iDimxnumPointsBuffer+iPoint]+J[iDimxnumPointsBuffer+iPoint]/epsMu[iPoint]) > MACHINE_EPS) {
1874  nFailE++;
1875  MaxwellRHSMaxwellRHS[0] = false;
1876  std::cout << "E(" << iDim << "):" << dE[iDimxnumPointsBuffer+iPoint] << std::endl;
1877  }
1878  }
1879  if(nFailE > 0) {
1880  std::cout << nFailE << "/" << numPointsBuffer << " E failures in dimension " << iDim << std::endl;
1881  }
1882  if(nFailH > 0) {
1883  std::cout << nFailH << "/" << numPointsBuffer << " H failures in dimension " << iDim << std::endl;
1884  }
1885  nFailE = 0;
1886  nFailH = 0;
1887  }
1888 
1889  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:Execution:MaxwellRHS:Case1", MaxwellRHSMaxwellRHS[0]);
1890 
1891  /**** CASE 2: Constant epsilon, mu and spatially-varying E, B and J ****/
1892 
1893  // Re-populate fields
1894  double *E = testState.GetFieldBuffer<double>("Efield");
1895  double *D = testState.GetFieldBuffer<double>("Dfield");
1896  double curlCompE2[3];
1897  CreateConstCurlVectorField(numDim, &numNodes[0], &dX[0], &E[0], curlCompE2);
1898 
1899  double *B = testState.GetFieldBuffer<double>("Bfield");
1900  double *H = testState.GetFieldBuffer<double>("Hfield");
1901  double curlCompB2[3];
1902  CreateConstCurlVectorField(numDim, &numNodes[0], &dX[0], &B[0], curlCompB2);
1903 
1904  double curlCompJ2[3];
1905  CreateConstCurlVectorField(numDim, &numNodes[0], &dX[0], &J[0], curlCompJ2);
1906 
1907  size_t twoxnumPointsBuffer = 2*numPointsBuffer;
1908  for(size_t iPoint=0; iPoint<numPointsBuffer; iPoint++) {
1909  D[iPoint] = epsMu[iPoint]*E[iPoint];
1910  D[iPoint+numPointsBuffer] = epsMu[iPoint]*E[iPoint+numPointsBuffer];
1911  D[iPoint+twoxnumPointsBuffer] = epsMu[iPoint]*E[iPoint+twoxnumPointsBuffer];
1912 
1913  H[iPoint] = B[iPoint]/epsMu[iPoint+numPointsBuffer];
1914  H[iPoint+numPointsBuffer] = B[iPoint+numPointsBuffer]/epsMu[iPoint+numPointsBuffer];
1915  H[iPoint+twoxnumPointsBuffer] = B[iPoint+twoxnumPointsBuffer]/epsMu[iPoint+numPointsBuffer];
1916  }
1917 
1918  // Set up RHS
1919  if(testRHS.SetupRHS(testGrid,testState,testState2,myThreadID))
1920  {
1921  MaxwellRHSMaxwellRHS[1] = false;
1922  }
1923 
1924  // Compute Maxwell RHS
1925  if(testRHS.MaxwellRHS(myThreadID))
1926  {
1927  MaxwellRHSMaxwellRHS[1] = false;
1928  }
1929 
1930  // Execute test
1931  for(int iDim=0; iDim<numDim; iDim++) {
1932  size_t iDimxnumPointsBuffer = iDim*numPointsBuffer;
1933  for(size_t iPoint=0; iPoint<numPointsBuffer; iPoint++) {
1934  if(std::fabs(dH[iDimxnumPointsBuffer+iPoint]+curlCompE2[iDim]/epsMu[iPoint+numPointsBuffer]) > MACHINE_EPS)
1935  MaxwellRHSMaxwellRHS[1] = false;
1936 
1937  double epsxMu = epsMu[iPoint]*epsMu[numPointsBuffer+iPoint];
1938  if(std::fabs(dE[iDimxnumPointsBuffer+iPoint]+J[iDimxnumPointsBuffer+iPoint]/epsMu[iPoint]-curlCompB2[iDim]/epsxMu) > MACHINE_EPS)
1939  MaxwellRHSMaxwellRHS[1] = false;
1940  }
1941  }
1942 
1943  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:Execution:MaxwellRHS:Case2", MaxwellRHSMaxwellRHS[1]);
1944 
1945 
1946  /* ======== Test RHS routine ======== */
1947  bool MaxwellRHSRHS = true;
1948  if(testRHS.RHS(myThreadID))
1949  {
1950  MaxwellRHSRHS = false;
1951  }
1952  serialUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:Execution:RHS", MaxwellRHSRHS);
1953 
1954 }
1955 
1956 
1958 /*********************************************************************************************************
1959 
1960  Test functions that set up the simulation for time integration,
1961  including initialization of the states.
1962 
1963  *********************************************************************************************************/
1964 {
1965 
1966  /* ======== Set up global type ======== */
1967  global_t testGlobal;
1968 
1969  const std::string testName("TestMaxwellRHSTimeIntegrate");
1970  testGlobal.Init(testName, testComm);
1971  testGlobal.StdOut("Entering "+testName+"\n");
1972 
1973  /* ======== Set up grid, halo and operator ======== */
1974  grid_t testGrid;
1975  halo_t &testHalo(testGrid.Halo());
1976  operator_t testOperator;
1977 
1978  std::ostringstream messageStream;
1979 
1980  int opInteriorOrder = 4;
1981  std::vector<size_t> gridSizes(3, 21);
1982  testGrid.SetGridSizes(gridSizes);
1983  std::vector<double> physicalExtent(6,0.2);
1984  physicalExtent[0] = 0.0;
1985  physicalExtent[2] = 0.0;
1986  physicalExtent[4] = 0.0;
1987  testGrid.SetPhysicalExtent(physicalExtent);
1988 
1989  bool MaxwellRHSTimeIntegrateGridHaloOpSetup = true;
1990  if(euler::util::InitializeSimulationFixtures(testGrid, testOperator, opInteriorOrder,
1991  testComm, &messageStream))
1992  {
1993  MaxwellRHSTimeIntegrateGridHaloOpSetup = false;
1994  }
1995 
1996  MaxwellRHSTimeIntegrateGridHaloOpSetup = CheckResult(MaxwellRHSTimeIntegrateGridHaloOpSetup,
1997  testComm);
1998  parallelUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:TimeIntegration:GridHaloOpSetup", MaxwellRHSTimeIntegrateGridHaloOpSetup);
1999 
2000  testGlobal.StdOut(messageStream.str());
2001  pcpp::io::RenewStream(messageStream);
2002 
2003  /* ======== Set up states and parameters ======== */
2004  state_t paramState;
2005  state_t testState;
2006 
2007  bool MaxwellRHSTimeIntegrateStateParamsSetup = true;
2008  if(Maxwell::util::SetupMaxwellStateAndParameters(testGrid, testState, paramState))
2009  {
2010  MaxwellRHSTimeIntegrateStateParamsSetup = false;
2011  }
2012  testState.InitializeFieldHandles();
2013  MaxwellRHSTimeIntegrateStateParamsSetup = CheckResult(MaxwellRHSTimeIntegrateStateParamsSetup, testComm);
2014  parallelUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:TimeIntegration:StateParamsSetup", MaxwellRHSTimeIntegrateStateParamsSetup);
2015 
2016  testGlobal.StdOut("Creating states...\n");
2017 
2018  state_t testRHSState(testState);
2019 
2020  /* ======== Initialize states - constant fields ======== */
2021  size_t numPointsBuffer = testGrid.BufferSize();
2022 // const std::vector<size_t> &gridSizes(testGrid.GridSizes());
2023  const std::vector<size_t> &bufferSizes(testGrid.BufferSizes());
2024  const pcpp::IndexIntervalType &partitionInterval(testGrid.PartitionInterval());
2025  const pcpp::IndexIntervalType &partitionBufferInterval(testGrid.PartitionBufferInterval());
2026  int numDim = bufferSizes.size();
2027 
2028  // Get state buffers
2029  double *timePtr = testState.GetFieldBuffer<double>("simTime");
2030  double *EfieldPtr = testState.GetFieldBuffer<double>("Efield");
2031  double *BfieldPtr = testState.GetFieldBuffer<double>("Bfield");
2032  double *DfieldPtr = testState.GetFieldBuffer<double>("Dfield");
2033  double *HfieldPtr = testState.GetFieldBuffer<double>("Hfield");
2034  double *JPtr = testState.GetFieldBuffer<double>("J");
2035  double *epsilonMuPtr = testState.GetFieldBuffer<double>("epsilonMu");
2036 
2037  /**** Initialize in entire buffer ****/
2038  std::vector<double> EfieldAll(3, 0.0);
2039  std::vector<double> BfieldAll(3, 0.0);
2040  std::vector<double> JAll(3, 0.0);
2041  double epsilonAll = -1.0;
2042  double muAll = -1.0;
2043 
2044  testGlobal.StdOut("Initializing states...\n");
2045  bool MaxwellRHSTimeIntegrateStateInitEverywhere = true;
2046  if(Maxwell::util::InitializeMaxwellStateConstFields(testGrid, testState, &EfieldAll[0], &BfieldAll[0], &JAll[0], epsilonAll, muAll, true))
2047  {
2048  MaxwellRHSTimeIntegrateStateInitEverywhere = false;
2049  }
2050  MaxwellRHSTimeIntegrateStateInitEverywhere = CheckResult(MaxwellRHSTimeIntegrateStateInitEverywhere, testComm);
2051  parallelUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:TimeIntegration:StateInit:Everywhere", MaxwellRHSTimeIntegrateStateInitEverywhere);
2052 
2053  // Test initialization
2054  size_t twoxnumPointsBuffer = 2*numPointsBuffer;
2055  for(size_t iPoint=0; iPoint<numPointsBuffer; iPoint++) {
2056  if(std::fabs(EfieldPtr[iPoint] -EfieldAll[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2057  if(std::fabs(EfieldPtr[iPoint+numPointsBuffer] -EfieldAll[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2058  if(std::fabs(EfieldPtr[iPoint+twoxnumPointsBuffer]-EfieldAll[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2059 
2060  if(std::fabs(BfieldPtr[iPoint] -BfieldAll[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2061  if(std::fabs(BfieldPtr[iPoint+numPointsBuffer] -BfieldAll[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2062  if(std::fabs(BfieldPtr[iPoint+twoxnumPointsBuffer]-BfieldAll[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2063 
2064  if(std::fabs(DfieldPtr[iPoint] -epsilonAll*EfieldAll[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2065  if(std::fabs(DfieldPtr[iPoint+numPointsBuffer] -epsilonAll*EfieldAll[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2066  if(std::fabs(DfieldPtr[iPoint+twoxnumPointsBuffer]-epsilonAll*EfieldAll[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2067 
2068  if(std::fabs(HfieldPtr[iPoint] -BfieldAll[0]/muAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2069  if(std::fabs(HfieldPtr[iPoint+numPointsBuffer] -BfieldAll[1]/muAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2070  if(std::fabs(HfieldPtr[iPoint+twoxnumPointsBuffer]-BfieldAll[2]/muAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2071 
2072  if(std::fabs(JPtr[iPoint] -JAll[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2073  if(std::fabs(JPtr[iPoint+numPointsBuffer] -JAll[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2074  if(std::fabs(JPtr[iPoint+twoxnumPointsBuffer]-JAll[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2075 
2076  if(std::fabs(epsilonMuPtr[iPoint]-epsilonAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2077  if(std::fabs(epsilonMuPtr[iPoint+numPointsBuffer]-muAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitEverywhere = false; }
2078  }
2079  MaxwellRHSTimeIntegrateStateInitEverywhere = CheckResult(MaxwellRHSTimeIntegrateStateInitEverywhere, testComm);
2080  parallelUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:TimeIntegration:StateInit:Everywhere:CheckBuffers", MaxwellRHSTimeIntegrateStateInitEverywhere);
2081 
2082  /**** Initialize only in local partition ****/
2083  std::vector<double> Efield(3, 1.0); Efield[1] = -2.0; Efield[2] = 3.0;
2084  std::vector<double> Bfield(3, -1.0); Bfield[1] = 2.0; Bfield[2] = -3.0;
2085  std::vector<double> J(3, 4.0); J[1] = -5.0; J[2] = 6.0;
2086  double epsilon = EPS0;
2087  double mu = MU0;
2088 
2089  bool MaxwellRHSTimeIntegrateStateInitLocalPart = true;
2090  if(Maxwell::util::InitializeMaxwellStateConstFields(testGrid, testState, &Efield[0], &Bfield[0], &J[0], epsilon, mu, false))
2091  {
2092  MaxwellRHSTimeIntegrateStateInitLocalPart = false;
2093  }
2094  MaxwellRHSTimeIntegrateStateInitLocalPart = CheckResult(MaxwellRHSTimeIntegrateStateInitLocalPart, testComm);
2095  parallelUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:TimeIntegration:StateInit:LocalPartition", MaxwellRHSTimeIntegrateStateInitLocalPart);
2096 
2097  // Test initialization
2098  size_t iStart = partitionBufferInterval[0].first;
2099  size_t iEnd = partitionBufferInterval[0].second;
2100  size_t jStart = partitionBufferInterval[1].first;
2101  size_t jEnd = partitionBufferInterval[1].second;
2102  size_t kStart = partitionBufferInterval[2].first;
2103  size_t kEnd = partitionBufferInterval[2].second;
2104 
2105  size_t nPlane = bufferSizes[0]*bufferSizes[1];
2106 
2107  for(size_t iPoint=0; iPoint<numPointsBuffer; iPoint++) {
2108  size_t iIndex = static_cast<size_t>((iPoint%nPlane)%bufferSizes[0]);
2109  size_t jIndex = static_cast<size_t>(((iPoint%nPlane)-iIndex)/bufferSizes[0]);
2110  size_t kIndex = static_cast<size_t>((iPoint-jIndex*bufferSizes[0]-iIndex)/nPlane);
2111 
2112  if(iIndex<iStart || iIndex>iEnd || jIndex<jStart || jIndex>jEnd || kIndex<kStart || kIndex>kEnd) {
2113  // Halo buffers
2114  if(std::fabs(EfieldPtr[iPoint] -EfieldAll[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2115  if(std::fabs(EfieldPtr[iPoint+numPointsBuffer] -EfieldAll[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2116  if(std::fabs(EfieldPtr[iPoint+twoxnumPointsBuffer]-EfieldAll[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2117 
2118  if(std::fabs(BfieldPtr[iPoint] -BfieldAll[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2119  if(std::fabs(BfieldPtr[iPoint+numPointsBuffer] -BfieldAll[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2120  if(std::fabs(BfieldPtr[iPoint+twoxnumPointsBuffer]-BfieldAll[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2121 
2122  if(std::fabs(DfieldPtr[iPoint] -epsilonAll*EfieldAll[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2123  if(std::fabs(DfieldPtr[iPoint+numPointsBuffer] -epsilonAll*EfieldAll[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2124  if(std::fabs(DfieldPtr[iPoint+twoxnumPointsBuffer]-epsilonAll*EfieldAll[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2125 
2126  if(std::fabs(HfieldPtr[iPoint] -BfieldAll[0]/muAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2127  if(std::fabs(HfieldPtr[iPoint+numPointsBuffer] -BfieldAll[1]/muAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2128  if(std::fabs(HfieldPtr[iPoint+twoxnumPointsBuffer]-BfieldAll[2]/muAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2129 
2130  if(std::fabs(JPtr[iPoint] -JAll[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2131  if(std::fabs(JPtr[iPoint+numPointsBuffer] -JAll[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2132  if(std::fabs(JPtr[iPoint+twoxnumPointsBuffer]-JAll[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2133 
2134  if(std::fabs(epsilonMuPtr[iPoint]-epsilonAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2135  if(std::fabs(epsilonMuPtr[iPoint+numPointsBuffer]-muAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2136  } else {
2137  // Partition buffers
2138  if(std::fabs(EfieldPtr[iPoint] -Efield[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2139  if(std::fabs(EfieldPtr[iPoint+numPointsBuffer] -Efield[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2140  if(std::fabs(EfieldPtr[iPoint+twoxnumPointsBuffer]-Efield[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2141 
2142  if(std::fabs(BfieldPtr[iPoint] -Bfield[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2143  if(std::fabs(BfieldPtr[iPoint+numPointsBuffer] -Bfield[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2144  if(std::fabs(BfieldPtr[iPoint+twoxnumPointsBuffer]-Bfield[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2145 
2146  if(std::fabs(DfieldPtr[iPoint] -epsilon*Efield[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2147  if(std::fabs(DfieldPtr[iPoint+numPointsBuffer] -epsilon*Efield[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2148  if(std::fabs(DfieldPtr[iPoint+twoxnumPointsBuffer]-epsilon*Efield[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2149 
2150  if(std::fabs(HfieldPtr[iPoint] -Bfield[0]/mu) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2151  if(std::fabs(HfieldPtr[iPoint+numPointsBuffer] -Bfield[1]/mu) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2152  if(std::fabs(HfieldPtr[iPoint+twoxnumPointsBuffer]-Bfield[2]/mu) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2153 
2154  if(std::fabs(JPtr[iPoint] -J[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2155  if(std::fabs(JPtr[iPoint+numPointsBuffer] -J[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2156  if(std::fabs(JPtr[iPoint+twoxnumPointsBuffer]-J[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2157 
2158  if(std::fabs(epsilonMuPtr[iPoint]-epsilon) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2159  if(std::fabs(epsilonMuPtr[iPoint+numPointsBuffer]-mu) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart = false; }
2160  }
2161  }
2162  MaxwellRHSTimeIntegrateStateInitLocalPart = CheckResult(MaxwellRHSTimeIntegrateStateInitLocalPart, testComm);
2163  parallelUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:TimeIntegration:StateInit:LocalPartition:CheckBuffers", MaxwellRHSTimeIntegrateStateInitLocalPart);
2164 
2165 // /* ======== Re-initialize states - using grid indices ======== */
2166 //
2167 // /**** Initialize only in local partition ****/
2168 // bool MaxwellRHSTimeIntegrateStateInitLocalPart2 = true;
2169 // if(Maxwell::util::InitializeMaxwellStateGridIndices(testGrid, testState))
2170 // {
2171 // MaxwellRHSTimeIntegrateStateInitLocalPart2 = false;
2172 // }
2173 // MaxwellRHSTimeIntegrateStateInitLocalPart2 = CheckResult(MaxwellRHSTimeIntegrateStateInitLocalPart2, testComm);
2174 // parallelUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:TimeIntegration:StateInit:LocalPartition2", MaxwellRHSTimeIntegrateStateInitLocalPart2);
2175 //
2176 // // Test initialization
2177 // size_t iStartG = partitionInterval[0].first;
2178 // size_t iEndG = partitionInterval[0].second;
2179 // size_t jStartG = partitionInterval[1].first;
2180 // size_t jEndG = partitionInterval[1].second;
2181 // size_t kStartG = partitionInterval[2].first;
2182 // size_t kEndG = partitionInterval[2].second;
2183 //
2184 // size_t nPlaneG = gridSizes[0]*gridSizes[1];
2185 //
2186 // for(size_t iPoint=0; iPoint<numPointsBuffer; iPoint++) {
2187 // size_t iIndex = static_cast<size_t>((iPoint%nPlane)%bufferSizes[0]);
2188 // size_t jIndex = static_cast<size_t>(((iPoint%nPlane)-iIndex)/bufferSizes[0]);
2189 // size_t kIndex = static_cast<size_t>((iPoint-jIndex*bufferSizes[0]-iIndex)/nPlane);
2190 //
2191 // if(iIndex<iStart || iIndex>iEnd || jIndex<jStart || jIndex>jEnd || kIndex<kStart || kIndex>kEnd) {
2192 // // Halo buffers
2193 // if(std::fabs(EfieldPtr[iPoint] -EfieldAll[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2194 // if(std::fabs(EfieldPtr[iPoint+numPointsBuffer] -EfieldAll[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2195 // if(std::fabs(EfieldPtr[iPoint+twoxnumPointsBuffer]-EfieldAll[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2196 //
2197 // if(std::fabs(BfieldPtr[iPoint] -BfieldAll[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2198 // if(std::fabs(BfieldPtr[iPoint+numPointsBuffer] -BfieldAll[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2199 // if(std::fabs(BfieldPtr[iPoint+twoxnumPointsBuffer]-BfieldAll[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2200 //
2201 // if(std::fabs(DfieldPtr[iPoint] -epsilonAll*EfieldAll[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2202 // if(std::fabs(DfieldPtr[iPoint+numPointsBuffer] -epsilonAll*EfieldAll[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2203 // if(std::fabs(DfieldPtr[iPoint+twoxnumPointsBuffer]-epsilonAll*EfieldAll[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2204 //
2205 // if(std::fabs(HfieldPtr[iPoint] -BfieldAll[0]/muAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2206 // if(std::fabs(HfieldPtr[iPoint+numPointsBuffer] -BfieldAll[1]/muAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2207 // if(std::fabs(HfieldPtr[iPoint+twoxnumPointsBuffer]-BfieldAll[2]/muAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2208 //
2209 // if(std::fabs(JPtr[iPoint] -JAll[0]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2210 // if(std::fabs(JPtr[iPoint+numPointsBuffer] -JAll[1]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2211 // if(std::fabs(JPtr[iPoint+twoxnumPointsBuffer]-JAll[2]) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2212 //
2213 // if(std::fabs(epsilonMuPtr[iPoint]-epsilonAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2214 // if(std::fabs(epsilonMuPtr[iPoint+numPointsBuffer]-muAll) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2215 // } else {
2216 // // Partition buffers
2217 // size_t gridIndex = (kStartG+kIndex-kStart)*nPlaneG + (jStartG+jIndex-jStart)*gridSizes[0] + (iStartG+iIndex-iStart+1);
2218 //
2219 // if(std::fabs(EfieldPtr[iPoint] -gridIndex) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2220 // if(std::fabs(EfieldPtr[iPoint+numPointsBuffer] -gridIndex) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2221 // if(std::fabs(EfieldPtr[iPoint+twoxnumPointsBuffer]-gridIndex) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2222 //
2223 // if(std::fabs(BfieldPtr[iPoint] -gridIndex) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2224 // if(std::fabs(BfieldPtr[iPoint+numPointsBuffer] -gridIndex) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2225 // if(std::fabs(BfieldPtr[iPoint+twoxnumPointsBuffer]-gridIndex) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2226 //
2227 // if(std::fabs(DfieldPtr[iPoint] -gridIndex*gridIndex) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2228 // if(std::fabs(DfieldPtr[iPoint+numPointsBuffer] -gridIndex*gridIndex) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2229 // if(std::fabs(DfieldPtr[iPoint+twoxnumPointsBuffer]-gridIndex*gridIndex) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2230 //
2231 // if(std::fabs(HfieldPtr[iPoint] -1.0) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2232 // if(std::fabs(HfieldPtr[iPoint+numPointsBuffer] -1.0) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2233 // if(std::fabs(HfieldPtr[iPoint+twoxnumPointsBuffer]-1.0) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2234 //
2235 // if(std::fabs(JPtr[iPoint] -gridIndex) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2236 // if(std::fabs(JPtr[iPoint+numPointsBuffer] -gridIndex) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2237 // if(std::fabs(JPtr[iPoint+twoxnumPointsBuffer]-gridIndex) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2238 //
2239 // if(std::fabs(epsilonMuPtr[iPoint]-gridIndex) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2240 // if(std::fabs(epsilonMuPtr[iPoint+numPointsBuffer]-gridIndex) > MACHINE_EPS) { MaxwellRHSTimeIntegrateStateInitLocalPart2 = false; }
2241 // }
2242 // }
2243 // MaxwellRHSTimeIntegrateStateInitLocalPart2 = CheckResult(MaxwellRHSTimeIntegrateStateInitLocalPart2, testComm);
2244 // parallelUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:TimeIntegration:StateInit:LocalPartition2:CheckBuffers", MaxwellRHSTimeIntegrateStateInitLocalPart2);
2245 
2246  /* ======== Initialize parameters ======== */
2247  double CFLValue = 1.0;
2248 
2249  bool MaxwellRHSTimeIntegrateParamsInit = true;
2250  if(Maxwell::util::InitializeMaxwellParameters(testGrid, paramState, CFLValue))
2251  {
2252  MaxwellRHSTimeIntegrateParamsInit = false;
2253  }
2254  MaxwellRHSTimeIntegrateParamsInit = CheckResult(MaxwellRHSTimeIntegrateParamsInit, testComm);
2255  parallelUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:TimeIntegration:ParamsInit", MaxwellRHSTimeIntegrateParamsInit);
2256 
2257  /* ======== Set up domain and RHS ======== */
2261 
2262  domain_t testDomain;
2263  rhs_t testRHS;
2264 
2265  testDomain.SetNumGrids(1);
2266  testDomain.SetGrid(0,testGrid);
2267  testDomain.SetGridState(0,testState);
2268  testDomain.SetGridParams(0,paramState);
2269  testDomain.PartitionDomain(0);
2270  testDomain.SetRHS(testRHS);
2271 
2272  bool MaxwellRHSTimeIntegrateInitialize = true;
2273  if(testRHS.Initialize(testGrid,testState,paramState,testOperator))
2274  {
2275  MaxwellRHSTimeIntegrateInitialize = false;
2276  }
2277  MaxwellRHSTimeIntegrateInitialize = CheckResult(MaxwellRHSTimeIntegrateInitialize, testComm);
2278  parallelUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:TimeIntegration:Initialize", MaxwellRHSTimeIntegrateInitialize);
2279 
2280  /* ======== Set up time advancer ======== */
2281  rk4advancer<domain_t> testAdvancer;
2282  testAdvancer.SetCommunication(true);
2283  testAdvancer.InitializeAdvancer(testDomain,testGlobal,messageStream);
2284 
2285  std::cout << "Initialization done." << std::endl;
2286 
2287  testGlobal.StdOut(messageStream.str());
2288  pcpp::io::RenewStream(messageStream);
2289 
2290  int myThreadID = 0;
2291  int numThreads = 1;
2292  int masterThread = 1;
2293 
2294 #ifdef USE_OMP
2295  myThreadID = omp_get_thread_num();
2296  numThreads = omp_get_max_threads();
2297  masterThread = (myThreadID == 0);
2298 #endif
2299 
2300  testAdvancer.SyncIntervals();
2301  // testAdvancer.SyncStates();
2302 
2303 
2304  /* ======== Set up I/O ======== */
2305 #ifdef ENABLE_HDF5
2306  fixtures::ConfigurationType testConfig;
2307  std::ostringstream outputFileNameOut;
2308  std::string outputFileNameRoot("TestMaxwellRHSTimeIntegrate");
2309  std::string domainName("TestDomain");
2310  std::string geometryName("TestGeom");
2311  std::string gridName("TestGrid");
2312 
2313  // Create directory to store test output files
2314  std::string outputFileDirName("OutputFiles_TestMaxwellRHSTimeIntegrate");
2315  if(!ix::sys::FILEEXISTS(outputFileDirName)){
2316  if(ix::sys::CreateDirectory(outputFileDirName))
2317  testGlobal.ErrOut("ix::sys::CreateDirectory failed.\n");
2318  }
2319 #endif
2320 
2321  /* ======== Advance in time ======== */
2322  size_t iStep;
2323  size_t numStepsMax = 100;
2324  size_t numStepsStatus = 1;
2325  size_t numStepsIO = 1;
2326  bool MaxwellRHSTimeIntegrateTimeAdvance = true;
2327 
2328  for(iStep=0; iStep<numStepsMax; iStep++) {
2329 
2330  if(!(iStep%numStepsStatus)) {
2331  if(masterThread) {
2332  messageStream << "MaxwellSolver:TestMaxwellRHS:TimeIntegration:TimeAdvance - Step = "
2333  << iStep << std::endl;
2334  testGlobal.StdOut(messageStream.str(),2);
2335  pcpp::io::RenewStream(messageStream);
2336  }
2337  }
2338 
2339  // Perform I/O operations at every numStepsIO
2340  if(!(iStep%numStepsIO)) {
2341 #ifdef ENABLE_HDF5
2342  outputFileNameOut.str("");
2343  outputFileNameOut << outputFileDirName << "/" << outputFileNameRoot << "_tstep" << iStep << ".h5";
2344 
2345  std::string outputFileName(outputFileNameOut.str());
2346  if(plascom2::io::hdf5::OutputSingle(outputFileName,domainName,geometryName,gridName,
2347  testGrid,testState,paramState,testConfig,messageStream)) {
2348  testGlobal.ErrOut("Maxwell:TestMaxwellRHS:TimeIntegration:TimeAdvance - plascom2::io::hdf5::OutputSingle() failed.\n");
2349  }
2350  testGlobal.StdOut(messageStream.str(),3);
2351  pcpp::io::RenewStream(messageStream);
2352 #else
2353  testGlobal.ErrOut("Maxwell:TestMaxwellRHS:TimeIntegration:TimeAdvance - WARNING! > HDF5 not enabled. Cannot perform I/O.\n");
2354 #endif
2355  }
2356 
2357  testComm.Barrier();
2358  testGlobal.StdOut("Advancing domain.\n");
2359 
2360  if(testAdvancer.AdvanceDomain()) {
2361  MaxwellRHSTimeIntegrateTimeAdvance = false;
2362  }
2363 
2364  testComm.Barrier();
2365  testGlobal.StdOut("Advance done.\nComputing DV.");
2366 
2367  if(!MaxwellRHSTimeIntegrateTimeAdvance)
2368  break;
2369 
2370  if(testRHS.ComputeDV(myThreadID))
2371  testGlobal.ErrOut("Maxwell:TestMaxwellRHS:TimeIntegration:TimeAdvance - ComputeDV() failed.\n");
2372 
2373  testComm.Barrier();
2374  testGlobal.StdOut("Compute DV done.\n");
2375 
2376  if(iStep == 1)
2377  testAdvancer.SetTimers(true);
2378 
2379  }
2380  MaxwellRHSTimeIntegrateTimeAdvance = CheckResult(MaxwellRHSTimeIntegrateTimeAdvance, testComm);
2381  parallelUnitResults.UpdateResult("Maxwell:TestMaxwellRHS:TimeIntegration:TimeAdvance", MaxwellRHSTimeIntegrateTimeAdvance);
2382 
2383  testComm.Barrier();
2384  testGlobal.StdOut("Performing final I/O.\n");
2385 
2386  // Perform final I/O dump
2387  if(masterThread) {
2388 #ifdef ENABLE_HDF5
2389  outputFileNameOut.str("");
2390  outputFileNameOut << outputFileDirName << "/" << outputFileNameRoot << "_tstep" << iStep << ".h5";
2391 
2392  std::string outputFileName(outputFileNameOut.str());
2393  if(plascom2::io::hdf5::OutputSingle(outputFileName,domainName,geometryName,gridName,
2394  testGrid,testState,paramState,testConfig,messageStream)) {
2395  testGlobal.ErrOut("Maxwell:TestMaxwellRHS:TimeIntegration:TimeAdvance - plascom2::io::hdf5::OutputSingle() failed.\n");
2396  }
2397  testGlobal.StdOut(messageStream.str(),3);
2398  pcpp::io::RenewStream(messageStream);
2399 #else
2400  testGlobal.ErrOut("Maxwell:TestMaxwellRHS:TimeIntegration:TimeAdvance - WARNING! > HDF5 not enabled. Cannot perform I/O.\n");
2401 #endif
2402  }
2403 
2404  if(masterThread) {
2405  messageStream << "Maxwell:TestMaxwellRHS:TimeIntegration:TimeAdvance - Ending at step " << iStep << std::endl;
2406  testGlobal.StdOut(messageStream.str(),1);
2407  pcpp::io::RenewStream(messageStream);
2408  }
2409 
2410 }
int InitializeMaxwellParameters(const GridType &inGrid, StateType &inParams, double CFLValue)
Definition: MaxwellUtil.H:354
#define MU0
int ComputeMaxwellRHS_Bfield(int numDim, size_t *numX, int numComponents, size_t numPoints, size_t *opInterval, int *stencilID, plascom2::operators::sbp::base &inOperator, double *recipDeltaX, double *Efield, double *dBdt)
Definition: MaxwellSolver.C:82
void CreateCurlFreeVectorFieldNonzeroDDx2(int numDim, size_t *numX, double *deltaX, double *inputField)
void TestConvertFields(ix::test::results &serialUnitResults)
void TestMaxwellRHS_Dfield(ix::test::results &serialUnitResults)
int ConvertBfieldtoHfield(int numDim, size_t numPoints, size_t *numX, size_t *opInterval, double *recipEpsMu, double *Bfield, double *Hfield)
int * stencilSizes
The number of weights for each stencil.
Definition: Stencil.H:102
void size_t int size_t int size_t int int int int double int int double double *void size_t int size_t int int int int int double int size_t size_t size_t double double *void size_t int size_t int size_t size_t int double int double double *void size_t size_t size_t double double * X
int InitializeMaxwellStateConstFields(const GridType &inGrid, StateType &inState, double *constE, double *constB, double *constJ, double &constEps, double &constMu, bool everyWhere=false)
Definition: MaxwellUtil.H:49
void const size_t * numPoints
Definition: EulerKernels.H:10
virtual int ErrOut(const std::string &outstr)
Definition: Global.H:456
void TestMaxwellRHS_Bfield(ix::test::results &serialUnitResults)
int ComputeMaxwellRHS_Dfield(int numDim, size_t *numX, int numComponents, size_t numPoints, size_t *opInterval, int *stencilID, plascom2::operators::sbp::base &inOperator, double *recipDeltaX, double *Hfield, double *J, double *dDdt)
void size_t int size_t int * opDir
void CreateLinearIncreasingField(size_t numPoints, double coeff, double *inputField)
subroutine applyoperator(numDim, dimSizes, numComponents, numPoints, opDir, opInterval, numStencils, stencilSizes, stencilStarts, numValues, stencilWeights, stencilOffsets, stencilID, U, dU)
applyoperator applies an operator specified as a stencil set to the provided state data ...
Definition: Operators.f90:36
int ComputeCurl(int numDim, size_t *numX, int numComponents, size_t numPoints, size_t *opInterval, int *stencilID, plascom2::operators::sbp::base &inOperator, double *recipDeltaX, double *inputField, double *outputField)
Definition: MaxwellSolver.C:18
void SetCommunication(bool onoff)
Definition: RK4Advancer.H:109
plascom2::operators::sbp::base operator_t
#define MACHINE_EPS
pcpp::IndexIntervalType & PartitionInterval()
Definition: Grid.H:500
void CreateLinearScalarField(int numDim, size_t *numX, double *deltaX, double *field, double *coeff)
void const size_t const size_t * gridSizes
Definition: EulerKernels.H:10
void RenewStream(std::ostringstream &outStream)
bool CheckResult(bool &localResult, pcpp::CommunicatorType &testComm)
Definition: PCPPCommUtil.C:176
Definition: FieldData.C:3
void SetDimensionExtensions(const std::vector< size_t > &inExtensions)
Definition: Grid.H:492
int * stencilStarts
The starting index into the stencilWeight and stencilOffset arrays for each stencil.
Definition: Stencil.H:104
int * stencilOffsets
The offsets wrt the grid point at which the stencil is being applied.
Definition: Stencil.H:106
void TestMaxwellRHSTimeIntegrate(ix::test::results &parallelUnitResults, pcpp::CommunicatorType &testComm)
void const size_t const size_t const size_t * opInterval
Definition: EulerKernels.H:10
virtual int AdvanceDomain()
Advances domain, grid, and state by one step.
Definition: RK4Advancer.H:455
pcpp::IndexIntervalType interval_t
subroutine assignmentxa(numDim, numPoints, bufferSize, bufferInterval, a, X)
ASSIGNMENTXA point-wise operator performing X = scalar a.
Definition: Operators.f90:1222
void SetGridSizes(const std::vector< size_t > &inSize)
Definition: Grid.H:452
void CreateConstantVectorField(int numDim, size_t *numX, double *value, double *inputField)
virtual int Init(const std::string &name, CommunicatorType &incomm)
Definition: Global.H:578
void CreateCurlFreeVectorFieldNonzeroDDx1(int numDim, size_t *numX, double *deltaX, double *inputField)
int OutputSingle(const std::string &fileName, const GridType &inGrid, const StateType &inState, const ConfigType &simConfig, const ConfigType &gridConfig, const ConfigType &stateConfig)
Definition: PlasCom2IO.C:12
const std::vector< size_t > & BufferSizes() const
Definition: Grid.H:459
Encapsulating class for collections of test results.
Definition: Testing.H:18
void TestMaxwellRHS(ix::test::results &serialUnitResults)
simulation::domain::base< grid_t, state_t > domain_t
Definition: PlasCom2.H:19
int CreateDirectory(const std::string &fname)
Definition: UnixUtils.C:217
pcpp::IndexIntervalType & PartitionBufferInterval()
Definition: Grid.H:519
simulation::grid::halo halo_t
void size_t int size_t int size_t int int int int double int int * stencilID
void SetGridSpacings(const std::vector< double > &inSpacing)
Definition: Grid.H:540
void TestApplyOperatorAppl(ix::test::results &serialUnitResults)
int SetupMaxwellStateAndParameters(const GridType &inGrid, StateType &inState, StateType &inParams)
Definition: MaxwellUtil.H:10
virtual int StdOut(const std::string &outstr, unsigned char inlev=1)
Definition: Global.H:439
int InitializeSimulationFixtures(GridType &inGrid, plascom2::operators::sbp::base &inOperator, int interiorOrder, pcpp::CommunicatorType &inComm, std::ostream *messageStreamPtr=NULL)
Definition: EulerUtil.H:218
int ConvertHfieldtoBfield(int numDim, size_t numPoints, size_t *numX, size_t *opInterval, double *epsMu, double *Hfield, double *Bfield)
bool FILEEXISTS(const std::string &fname)
Definition: UnixUtils.C:189
pcpp::ParallelGlobalType global_t
Main encapsulation of MPI.
Definition: COMM.H:62
int CreateStencilConnectivity(int numDim, size_t *dimSizes, size_t *opInterval, int boundaryDepth, int *stencilID, bool fortranInterval=false)
Creates simple stencil connectivity assuming all domain boundaries are physical boundaries.
Definition: Stencil.C:840
Testing constructs for unit testing.
Encapsulation for a collection of operator stencils.
Definition: Stencil.H:26
BufferDataType * GetFieldBuffer(const std::string &fieldName)
int numValues
The total number of weights for all stencils (reqd for Fortran)
Definition: Stencil.H:98
void size_t size_t size_t double double double double *void size_t size_t size_t double double double double double *void size_t size_t size_t double double double double *void size_t size_t size_t double double double *void const size_t const size_t const size_t const int const double const double double * Z
void CreateConstCurlVectorField(int numDim, size_t *numX, double *deltaX, double *inputField, double *curlComp)
void DumpContents(std::ostream &Ostr, const ContainerType &c, std::string del="\)
Dump container contents.
Definition: AppTools.H:117
simulation::state::base state_t
void const size_t const size_t * bufferSizes
Definition: MetricKernels.H:19
int SetGrid(GridType &inGrid)
void size_t int size_t int size_t int int int int double int int double double *void size_t int size_t int int int int int double int size_t size_t size_t double double *void size_t int size_t int size_t size_t int double int double double *void size_t size_t size_t double double double * Y
void UpdateResult(const std::string &name, const ValueType &result)
Updates an existing test result.
Definition: Testing.H:55
int ConvertEfieldtoDfield(int numDim, size_t numPoints, size_t *numX, size_t *opInterval, double *epsMu, double *Efield, double *Dfield)
void TestCurlOperator(ix::test::results &serialUnitResults)
int ComputeRecipEpsMu(int numDim, size_t numPoints, size_t *numX, size_t *opInterval, double *epsMu, double *recipEpsMu)
double * stencilWeights
The stencil weights.
Definition: Stencil.H:108
virtual int InitializeAdvancer(DomainType &inDomain, pcpp::ParallelGlobalType &inGlobal, std::ostream &inStream)
Initializes the advancer object.
Definition: RK4Advancer.H:168
int numStencils
The number of stencils (e.g. interior + boundary)
Definition: Stencil.H:93
#define EPS0
int Initialize(base &stencilSet, int interiorOrder)
Initialize the sbp::base stencilset with the SBP operator of given order.
Definition: Stencil.C:360
int ConvertDfieldtoEfield(int numDim, size_t numPoints, size_t *numX, size_t *opInterval, double *recipEpsMu, double *Dfield, double *Efield)
void TestComputeRecipEpsMu(ix::test::results &serialUnitResults)
Simple Block Structured Mesh object.
Definition: IndexUtil.H:21
void size_t int * numComponents
void SetPhysicalExtent(const std::vector< double > &inExtent)
Definition: Grid.H:535
simulation::grid::parallel_blockstructured grid_t
int Finalize(bool allocateCoordinateData=false)
Definition: Grid.C:2318
void InitSimple(const ContainerType &inSize)
Definition: IndexUtil.H:169
void const size_t * numPointsBuffer
Definition: MetricKernels.H:19
void SyncIntervals()
Definition: RK4Advancer.H:896
void TestDirichletBC(ix::test::results &serialUnitResults)
void FC_MODULE(euler, flux1d, EULER, FLUX1D)(const int *numDim
void SetTimers(bool onoff)
Definition: RK4Advancer.H:111
int ComputeDirichletBC(const std::vector< size_t > &bufferIndices, double *variable, const double &value)
Definition: MaxwellBC.C:11