PlasCom2  1.0
XPACC Multi-physics simluation application
MaxwellSolver.H
Go to the documentation of this file.
1 #ifndef __MAXWELL_SOLVER_H__
2 #define __MAXWELL_SOLVER_H__
3 
4 #include "Simulation.H"
5 #include "Stencil.H"
6 #include "MaxwellBC.H"
7 
8 
9 
10 namespace Maxwell {
11 
12  int ComputeCurl(int numDim, size_t *numX, int numComponents,
13  size_t numPoints, size_t *opInterval, int *stencilID,
15  double *recipDeltaX, double *inputField, double *outputField);
16 
17  int ComputeMaxwellRHS_Bfield(int numDim, size_t *numX, int numComponents, size_t numPoints,
18  size_t *opInterval, int *stencilID,
20  double *recipDeltaX, double *Efield, double *dBdt);
21 
22  int ComputeMaxwellRHS_Dfield(int numDim, size_t *numX, int numComponents, size_t numPoints,
23  size_t *opInterval, int *stencilID,
25  double *recipDeltaX, double *Hfield, double *J, double *dDdt);
26 
27  int ComputeRecipEpsMu(int numDim, size_t numPoints, size_t *numX, size_t *opInterval,
28  double *epsMu, double *recipEpsMu);
29 
30  int ConvertEfieldtoDfield(int numDim, size_t numPoints, size_t *numX, size_t *opInterval,
31  double *epsMu, double *Efield, double *Dfield);
32 
33  int ConvertDfieldtoEfield(int numDim, size_t numPoints, size_t *numX, size_t *opInterval,
34  double *recipEpsMu, double *Dfield, double *Efield);
35 
36  int ConvertBfieldtoHfield(int numDim, size_t numPoints, size_t *numX, size_t *opInterval,
37  double *recipEpsMu, double *Bfield, double *Hfield);
38 
39  int ConvertHfieldtoBfield(int numDim, size_t numPoints, size_t *numX, size_t *opInterval,
40  double *epsMu, double *Hfield, double *Bfield);
41 
43 
44  template<typename GridT, typename StateT, typename OperatorT>
45  class rhs : public simulation::rhs::domain_base<GridT,StateT,OperatorT> {
46 
47  public:
48  typedef GridT GridType;
49  typedef StateT StateType;
50  typedef OperatorT OperatorType;
54  typedef typename rhs_base_t::BCType BCType;
55 
56 
57  public:
58  // - First thing to call from outside, sets up grid, halo, state and operator
59  // Only called once ever
60  int Initialize(GridType &inGrid, StateType &inState, const StateType &paramState, OperatorType &inOperator)
61  {
62 
63  if(Init())
64  return(1);
65 
66  if(SetParamState(paramState))
67  return(7);
68 
69  if(SetGrid(inGrid))
70  return(2);
71 
72  if(InitializeState(inState))
73  return(3);
74 
75  if(HaloSetup(inGrid.Halo()))
76  return(4);
77 
78  if(SetupOperator(inOperator))
79  return(5);
80 
81  if(SetupTempBuffers())
82  return(6);
83 
84  return(0);
85 
86  };
87 
88 
89  // - Called any time the state/rhs are different, for RK, that's
90  // every substep as each stage has separate storage
91  int SetupRHS(GridType &inGrid, StateType &inState, StateType &rhsState, int myThreadID = 0)
92  {
93 
94  int masterThread = (myThreadID == 0);
95 
96  if(SetGrid(inGrid))
97  return(1);
98 
99  errorCode = 0;
100 
101  if(masterThread)
102  errorCode = SetHalo(inGrid.Halo());
103 
104 #pragma omp barrier
105  if(errorCode > 0)
106  return(errorCode);
107 
108  if(masterThread)
109  errorCode = SetState(inState);
110 
111 #pragma omp barrier
112  if(errorCode > 0)
113  return(errorCode);
114 
115  if(masterThread)
116  errorCode = SetRHSState(rhsState);
117 
118 #pragma omp barrier
119  if(errorCode > 0)
120  return(errorCode);
121 
122  return(0);
123 
124  };
125 
126 
127  int HandleBoundaryConditions(int threadID)
128  {
129 
130  if(!domainBCsPtr)
131  return(0);
132  else if (!subRegionsPtr || !domainBoundariesPtr)
133  return(1);
134 
135  bool masterThread = (threadID == 0);
136 
137  std::vector<BoundaryType> &domainBoundaries(*domainBoundariesPtr);
138  std::vector<BCType> &domainBCs(*domainBCsPtr);
139  std::vector<GridRegionType> &gridRegions(*subRegionsPtr);
140 
141  int numBCs = domainBCs.size();
142  int numGridRegions = gridRegions.size();
143  int numDomainBoundaries = domainBoundaries.size();
144 
145  if(numBCs == 0)
146  return(0);
147  if(numDomainBoundaries == 0)
148  return(0);
149 
150  typename std::vector<BoundaryType>::iterator dbIt = domainBoundaries.begin();
151 
152 // std::vector<double> gasParams(4,0.0);
153 // gasParams[0] = cRef;
154 // gasParams[1] = gamma;
155 // gasParams[2] = cpRef;
156 // gasParams[3] = reRef;
157 
158  while(dbIt != domainBoundaries.end()) {
159 
160  BoundaryType &domainBoundary(*dbIt++);
161  GridRegionType &gridRegion(gridRegions[domainBoundary.GridRegionID()]);
162  std::vector<size_t> &threadPartBufferIndices(gridRegion.threadPartitionBufferIndices[threadID]);
163  size_t numBoundaryPoints = threadPartBufferIndices.size();
164 
165  if(numBoundaryPoints > 0) { // this rank/thread owns part of the boundary
166 
167  BCType &boundaryCondition(domainBoundary.BC());
168  // unique int id for bc
169  int bcType = boundaryCondition.BCType();
170 
172  continue;
173 
174  int normalDir = gridRegion.normalDirection;
175  std::vector<size_t> regionSizes(gridRegion.regionInterval.Sizes());
176  size_t numPointsRegion = gridRegion.regionInterval.NNodes();
177 
178 
179  // bc-associated parameters from input file
180  // ///@todo get handle on BC-associated numbers/flags to avoid search
181  StateType &bcParamState(boundaryCondition.Params());
182  double *bcParams = bcParamState.template GetFieldBuffer<double>("Numbers");
183  int *bcFlags = bcParamState.template GetFieldBuffer<int>("Flags");
184 
185  // useful for debugging
186  const std::string &bcName(boundaryCondition.BCName());
187  // const std::string &regionName(gridRegion.regionName);
188  // const std::string &boundaryName(domainBoundary.Name());
189 
190 
191  // gasParams = (sndspdref,gamma,Cp,1/Re)
192  // bcParams = (sigma1,sigma2,sbpBoundaryStencilWeight)
193  // bcFlags = unused currently (soon to be part of BC API)
194 
195  switch(bcType) {
196 
198 // bcParams[2] = boundaryWeight;
199 // // Call SAT Farfield kernel
200 // FC_MODULE(satutil,farfield,SATUTIL,FARFIELD)
201 // ( &numDim,&bufferSizes[0],&numPointsBuffer,&normalDir,&regionSizes[0],
202 // &numPointsRegion,&numBoundaryPoints,&threadPartBufferIndices[0],&gridMetric[0],
203 // &gridJacobian,bcParams,&gasParams[0],myStateBuffers[0],myStateBuffers[1],
204 // myStateBuffers[2],&numScalar,myStateBuffers[3],myRHSBuffers[0],myRHSBuffers[1],
205 // myRHSBuffers[numDim+1],myRHSBuffers[numDim+2],targetStateBuffers[0],
206 // targetStateBuffers[1],targetStateBuffers[2],targetStateBuffers[3]);
207 //
208 // break;
209  std::cout << "MaxwellRHS:HandleBoundaryConditions: Error: SAT_FARFIELD"
210  << " has not been implemented (yet)." << std::endl;
211  return(1);
212 
214 // std::cout << "EulerRHS:HandleBoundaryConditions: Error: SAT_NOSLIP_ISOTHERMAL"
215 // << " has not been implemented (yet)." << std::endl;
216 // return(1);
217  /* Set E-field components */
218  for(int iComp=0; iComp<3; iComp++) {
219  double *rhsPtr = myRHSBuffers[0]+iComp*numPointsBuffer;
220  double *statePtr = myStateBuffers[0]+iComp*numPointsBuffer;
221 // bc::ComputeDirichletBC(threadPartBufferIndices, rhsPtr, bcParams[iComp]);
222  bc::ComputeSATDirichletBC(threadPartBufferIndices, rhsPtr, statePtr, bcParams[iComp], bcParams[6]);
223  }
224 
225  /* Set H-field components */
226  for(int iComp=0; iComp<3; iComp++) {
227  double *rhsPtr = myRHSBuffers[1]+iComp*numPointsBuffer;
228  double *statePtr = myStateBuffers[3]+iComp*numPointsBuffer;
229 // bc::ComputeDirichletBC(threadPartBufferIndices, rhsPtr, bcParams[iComp+3]);
230  bc::ComputeSATDirichletBC(threadPartBufferIndices, rhsPtr, statePtr, bcParams[iComp+3], bcParams[7]);
231  }
232 
233  break;
234 
236  std::cout << "MaxwellRHS:HandleBoundaryConditions: Error: SAT_SLIPWALL_ADIABATIC"
237  << " has not been implemented (yet)." << std::endl;
238  return(1);
239 // bcParams[1] = boundaryWeight;
240 // FC_MODULE(satutil,slip_adiabatic,SATUTIL,SLIP_ADIABATIC)
241 // ( &numDim,&bufferSizes[0],&numPointsBuffer,&normalDir,&regionSizes[0],
242 // &numPointsRegion,&numBoundaryPoints,&threadPartBufferIndices[0],&gridMetric[0],
243 // &gridJacobian,bcParams,&gasParams[0],myStateBuffers[0],myStateBuffers[1],
244 // myStateBuffers[2],&numScalar,myStateBuffers[3],myRHSBuffers[0],myRHSBuffers[1],
245 // myRHSBuffers[numDim+1],myRHSBuffers[numDim+2],targetStateBuffers[0],
246 // targetStateBuffers[1],targetStateBuffers[2],targetStateBuffers[3]);
247 //
248 // break;
249 
250  default:
251  std::cout << "ERROR! MaxwellRHS:Could not resolve BC("
252  << bcName << ") = " << bcType << std::endl;
253  return(1);
254  break;
255 
256  }
257 
258  }
259 
260  }
261 
262  return(0);
263 
264  };
265 
266 
267  // No sources (yet)
268  int HandleSources(int threadID)
269  {
270  return(0);
271  };
272 
273 
274  // main call to get RHS (SetupRHS needs to have been called first)
275  int RHS(int threadID)
276  {
277 
278  // Call Maxwell RHS
279  if(MaxwellRHS(threadID))
280  return(1);
281 
282  // Apply boundary terms
283  if(HandleBoundaryConditions(threadID))
284  return(2);
285 
286  // Apply additional/external source terms
287  if(HandleSources(threadID))
288  return(3);
289 
290  // Compute dependent variables
291 // if(ComputeDV(threadID))
292 // return(4);
293 
294  return(0);
295 
296  };
297 
298 
299  // =============== Modify below at your own risk =============
300 
301  int ComputeDV(int threadID)
302  {
303 
304  // Get intervals
305  std::vector<size_t> &fortranBufferInterval(fortranBufferIntervals[threadID]);
306  std::vector<size_t> &fortranOpInterval(fortranPartitionBufferIntervals[threadID]);
307 
308  if(ConvertHfieldtoBfield(numDim, numPointsBuffer, &bufferSizes[0], &fortranOpInterval[0],
310  {
311  std::cout << "ComputeDV - Compute B-field from H-field failed." << std::endl;
312  return(1);
313  }
314 
315  if(ConvertEfieldtoDfield(numDim, numPointsBuffer, &bufferSizes[0], &fortranOpInterval[0],
317  {
318  std::cout << "ComputeDV - Compute D-field from E-field failed." << std::endl;
319  return(2);
320  }
321 
322  return(0);
323 
324  };
325 
326 
327  int MaxwellRHS(int threadID)
328  {
329 
330  // Get intervals
331  std::vector<size_t> &fortranBufferInterval(fortranBufferIntervals[threadID]);
332  std::vector<size_t> &fortranOpInterval(fortranPartitionBufferIntervals[threadID]);
333 
334  // std::cout << "Buffer Sizes: (";
335  // pcpp::io::DumpContents(std::cout,bufferSizes,",");
336  // std::cout << ")" << std::endl;
337  // std::cout << "Fortran Buffer Interval: (";
338  // pcpp::io::DumpContents(std::cout,fortranBufferInterval,",");
339  // std::cout << ")" << std::endl;
340  // std::cout << "Fortran OpInterval: (";
341  // pcpp::io::DumpContents(std::cout,fortranOpInterval,",");
342  // std::cout << ")" << std::endl;
343  // std::cout << "BField(before):" << std::endl;
344  // for(size_t iPoint = 0;iPoint < numDim*numPointsBuffer;iPoint++)
345  // std::cout << bFieldPtr[iPoint] << " ";
346  // std::cout << std::endl;
347  // std::cout << "dBdt(BEFORE):" << std::endl;
348  // for(size_t iPoint = 0;iPoint < numDim*numPointsBuffer;iPoint++)
349  // std::cout << myRHSBuffers[1][iPoint] << " ";
350  // std::cout << std::endl;
351  // size_t iPoint = 0;
352  // for(int iDim = 0;iDim < numDim;iDim++){
353  // std::cout << "StencilID[" << iDim << "]:" << std::endl;
354  // for(size_t iZ = 0;iZ < bufferSizes[2];iZ++){
355  // for(size_t iY = 0;iY < bufferSizes[1];iY++){
356  // for(size_t iX = 0;iX < bufferSizes[0];iX++){
357  // std::cout << stencilID[iPoint++] << " ";
358  // }
359  // }
360  // }
361  // }
362 
363  // Compute RHS for B-field
365  &fortranOpInterval[0], stencilID, myOperator, &recipDX[0],
367  {
368  return(1);
369  }
370 
371  // std::cout << "dBdt(AFTER):" << std::endl;
372  // for(size_t iPoint = 0;iPoint < numDim*numPointsBuffer;iPoint++)
373  // std::cout << myRHSBuffers[1][iPoint] << " ";
374  // std::cout << std::endl;
375 
376  // Convert dB/dt to dH/dt
377  if(ConvertBfieldtoHfield(numDim, numPointsBuffer, &bufferSizes[0], &fortranOpInterval[0],
378  &recipEpsMu[0], myRHSBuffers[1], myRHSBuffers[1]))
379  {
380  return(2);
381  }
382 
383  // std::cout << "dHdt:" << std::endl;
384  // for(size_t iPoint = 0;iPoint < numDim*numPointsBuffer;iPoint++)
385  // std::cout << myRHSBuffers[1][iPoint] << " ";
386  // std::cout << std::endl;
387 
388  // Compute RHS for D-field
390  &fortranOpInterval[0], stencilID, myOperator, &recipDX[0],
392  {
393  return(3);
394  }
395 
396  // Convert dD/dt to dE/dt
397  if(ConvertDfieldtoEfield(numDim, numPointsBuffer, &bufferSizes[0], &fortranOpInterval[0],
398  &recipEpsMu[0], myRHSBuffers[0], myRHSBuffers[0]))
399  {
400  return(4);
401  }
402 
403  return(0);
404 
405  };
406 
407 
408  std::vector<double *> &StateBuffers()
409  {
410  return(myStateBuffers);
411  };
412 
413 
414  std::vector<double *> &RHSBuffers()
415  {
416  return(myRHSBuffers);
417  };
418 
419 
420  int SetParamState(const StateType &paramState)
421  {
422 
423  int myThreadID = 0;
424  int numThreads = 1;
425  int masterThread = 1;
426 
427 #ifdef USE_OMP
428  myThreadID = omp_get_thread_num();
429  masterThread = (myThreadID == 0);
430 #endif
431 
432  if(masterThread) {
433  epsilon0Handle = paramState.GetDataIndex("epsilon0");
434  if(epsilon0Handle < 0)
435  return(1);
436  const pcpp::field::dataset::DataBufferType &epsilon0Data(paramState.Field(epsilon0Handle));
437  epsilon0Ptr = epsilon0Data.Data<double>();
438  if(!epsilon0Ptr)
439  return(1);
441 
442  mu0Handle = paramState.GetDataIndex("mu0");
443  if(mu0Handle < 0)
444  return(2);
445  const pcpp::field::dataset::DataBufferType &mu0Data(paramState.Field(mu0Handle));
446  mu0Ptr = mu0Data.Data<double>();
447  if(!mu0Ptr)
448  return(2);
449  mu0 = *mu0Ptr;
450 
451  cflHandle = paramState.GetDataIndex("inputCFL");
452  if(cflHandle < 0)
453  return(3);
454  const pcpp::field::dataset::DataBufferType &cflData(paramState.Field(cflHandle));
455  cflPtr = cflData.Data<double>();
456  if(!cflPtr)
457  return(3);
458  cfl = *cflPtr;
459 
460  deltaTHandle = paramState.GetDataIndex("inputDT");
461  if(deltaTHandle < 0)
462  return(4);
463  const pcpp::field::dataset::DataBufferType &deltaTData(paramState.Field(deltaTHandle));
464  deltaTPtr = deltaTData.Data<double>();
465  if(!deltaTPtr)
466  return(4);
467  deltaT = *deltaTPtr;
468 
469  cRefHandle = paramState.GetDataIndex("refC");
470  if(cRefHandle < 0)
471  return(5);
472  const pcpp::field::dataset::DataBufferType &cRefData(paramState.Field(cRefHandle));
473  cRefPtr = cRefData.Data<double>();
474  if(!cRefPtr)
475  return(5);
476  cRef = *cRefPtr;
477  }
478 #pragma omp barrier
479 
480  return(0);
481 
482  };
483 
484 
485  int InitializeState(StateType &inState)
486  {
487 
488  if(!gridInitialized)
489  return(1);
490 
491  int myThreadID = 0;
492  int numThreads = 1;
493  int masterThread = 1;
494 
495 #ifdef USE_OMP
496  myThreadID = omp_get_thread_num();
497  masterThread = (myThreadID == 0);
498 #endif
499 
500  if(masterThread) {
501  timeHandle = inState.GetDataIndex("simTime");
502  if(timeHandle < 0)
503  return(1);
504  pcpp::field::dataset::DataBufferType &timeData(inState.Field(timeHandle));
505  timePtr = timeData.Data<double>();
506  if(!timePtr)
507  return(1);
508  time = *timePtr;
509 
510  eFieldHandle = inState.GetFieldHandle("Efield");
511  if(eFieldHandle < 0)
512  return(1);
513  pcpp::field::dataset::DataBufferType &eFieldData(inState.GetFieldDataByHandle(eFieldHandle));
514  eFieldPtr = eFieldData.Data<double>();
515  if(!eFieldPtr)
516  return(1);
517 
518  bFieldHandle = inState.GetFieldHandle("Bfield");
519  if(bFieldHandle < 0)
520  return(1);
521  pcpp::field::dataset::DataBufferType &bFieldData(inState.GetFieldDataByHandle(bFieldHandle));
522  bFieldPtr = bFieldData.Data<double>();
523  if(!bFieldPtr)
524  return(1);
525 
526  dFieldHandle = inState.GetDataIndex("Dfield");
527  if(dFieldHandle < 0)
528  return(1);
529  pcpp::field::dataset::DataBufferType &dFieldData(inState.Field(dFieldHandle));
530  dFieldPtr = dFieldData.Data<double>();
531  if(!dFieldPtr)
532  return(1);
533 
534  hFieldHandle = inState.GetDataIndex("Hfield");
535  if(hFieldHandle < 0)
536  return(1);
537  pcpp::field::dataset::DataBufferType &hFieldData(inState.Field(hFieldHandle));
538  hFieldPtr = hFieldData.Data<double>();
539  if(!hFieldPtr)
540  return(1);
541 
542  jHandle = inState.GetDataIndex("J");
543  if(jHandle < 0)
544  return(1);
545  pcpp::field::dataset::DataBufferType &jData(inState.Field(jHandle));
546  jPtr = jData.Data<double>();
547  if(!jPtr)
548  return(1);
549 
550  epsilonMuHandle = inState.GetDataIndex("epsilonMu");
551  if(epsilonMuHandle < 0)
552  return(1);
553  pcpp::field::dataset::DataBufferType &epsilonMuData(inState.Field(epsilonMuHandle));
554  epsilonMuPtr = epsilonMuData.Data<double>();
555  if(!epsilonMuPtr)
556  return(1);
557 #if 0
558  epsilonHandle = inState.GetDataIndex("epsilon");
559  if(epsilonHandle < 0)
560  return(1);
561  pcpp::field::dataset::DataBufferType &epsilonData(inState.Field(epsilonHandle));
562  epsilonPtr = epsilonData.Data<double>();
563  if(!epsilonPtr)
564  return(1);
565 
566  muHandle = inState.GetDataIndex("mu");
567  if(muHandle < 0)
568  return(1);
569  pcpp::field::dataset::DataBufferType &muData(inState.Field(muHandle));
570  muPtr = muData.Data<double>();
571  if(!muPtr)
572  return(1);
573 #endif
574  myStateBuffers.resize(6,NULL);
579  myStateBuffers[4] = jPtr;
581 // myStateBuffers[3] = epsilonPtr;
582 // myStateBuffers[4] = muPtr;
583  myRHSBuffers.resize(2,NULL);
584 
585  stateInitialized = true;
586  }
587 #pragma omp barrier
588 
589  return(0);
590 
591  };
592 
593 
595  {
596 
598  return(1);
599 
600  int myThreadID = 0;
601  int numThreads = 1;
602  int masterThread = 1;
603 
604 #ifdef USE_OMP
605  myThreadID = omp_get_thread_num();
606  numThreads = omp_get_num_threads();
607  masterThread = (myThreadID == 0);
608 #endif
609 
610  if(masterThread) {
611  stencilID = new int [numDim*numPointsBuffer];
612  }
613 
614 #pragma omp barrier
615 
616  // Create stencil connectivity
617  if(numThreads == 1) {
619  &periodicDirs[0],stencilID,true))
620  {
621  std::cout << "CreateStencilConnectivity failed." << std::endl;
622  return(1);
623  }
624  } else {
627  {
628  std::cout << "CreateStencilConnectivity failed." << std::endl;
629  return(1);
630  }
631  }
632 
633 
634  // plascom2::operators::sbp::CreateStencilConnectivity(numDim,&gridSize[0],opInterval,boundaryDepth,stencilID,true);
635 
636  // bug! unlike stencilID, these need to be thread-aware
637  // @todo Thread-aware dual stencil connectivities in RHS
638  // Invert the connectivity
639  // plascom2::operators::InvertStencilConnectivity(numDim,opInterval,stencilID,dualStencilConn,true);
640  // dualStencilConn = new size_t [numDim*numPointsBuffer]; // [DIM1[stencil1Points,stencil2Points....stencil(numStencils)Points]...]
641  // numPointsStencil = new size_t [numDim*numStencils]; // [DIM1[numPoints1,numPoints2....numPoints(numStencils)]...]
642 
643 // if(plascom2::operators::sbp::InvertStencilConnectivity(numDim,&bufferSizes[0],&opInterval[0],numStencils,
644 // stencilID,dualStencilConn,numPointsStencil,true))
645 // {
646 // std::cout << "InvertStencilConnectivity failed." << std::endl;
647 // return(1);
648 // }
649 
650  return(0);
651 
652  };
653 
654 
655  int SetupOperator(OperatorType &inOperator)
656  {
657 
658  int myThreadID = 0;
659  int numThreads = 1;
660  int masterThread = 1;
661 
662 #ifdef USE_OMP
663  myThreadID = omp_get_thread_num();
664  masterThread = (myThreadID == 0);
665 #endif
666 
667  if(masterThread && !operatorInitialized) {
668  myOperator.Copy(inOperator);
669 
670  // plascom2::operators::sbp::Initialize(myOperator,interiorSpatialOrder);
671  numStencils = myOperator.numStencils;
672  stencilStarts = myOperator.stencilStarts;
673  stencilOffsets = myOperator.stencilOffsets;
674  stencilSizes = myOperator.stencilSizes;
675  stencilWeights = myOperator.stencilWeights;
676  boundaryDepth = myOperator.boundaryDepth; // (numStencils - 1)/2;
677  boundaryWeight = myOperator.boundaryWeight;
678  numComponents = 1;
679  // std::cout << "NumStencils: " << numStencils << std::endl
680  // << "StencilStarts/sizes: (";
681  // for(int iStencil = 0;iStencil < numStencils;iStencil++){
682  // std::cout << stencilStarts[iStencil] << "/" << stencilSizes[iStencil];
683  // if(iStencil != (numStencils - 1)) std::cout << ",";
684  // }
685  // std::cout << ") " << std::endl;
686  // Forticate the stencil starts
687  for(int iStencil=0; iStencil<numStencils; iStencil++)
688  stencilStarts[iStencil]++;
689 
690  operatorInitialized = true;
691  }
692 #pragma omp barrier
693 
695  return(1);
696 
697  return(0);
698 
699  };
700 
701  int SetState(StateType &inState)
702  {
703 
704  if(!stateInitialized)
705  return(1);
706 
707  eFieldPtr = inState.GetRealFieldBufferByHandle(eFieldHandle);
708 // bFieldPtr = inState.GetRealFieldBuffer(bFieldHandle);
709 // dFieldPtr = inState.GetRealFieldBuffer(dFieldHandle);
710  hFieldPtr = inState.GetRealFieldBufferByHandle(hFieldHandle);
711 // jPtr = inState.GetRealFieldBuffer(jHandle);
712 // epsilonMuPtr = inState.GetRealFieldBuffer(epsilonMuHandle);
713 // epsilonPtr = inState.GetRealFieldBuffer(epsilonHandle);
714 // muPtr = inState.GetRealFieldBuffer(muHandle);
715 
717 // myStateBuffers[1] = bFieldPtr;
718 // myStateBuffers[2] = dFieldPtr;
720 // myStateBuffers[4] = jPtr;
721 // myStateBuffers[5] = epsilonMuPtr;
722 // myStateBuffers[3] = epsilonPtr;
723 // myStateBuffers[4] = muPtr;
724 
725  // Compute reciprocals of epsilon and mu
726  if(dynamicEpsMu || recipEpsMu.empty()) {
727  recipEpsMu.resize(2*numPointsBuffer);
729  myStateBuffers[5], &recipEpsMu[0]))
730  {
731  return(1);
732  }
733  }
734 
735 #pragma omp barrier
736 
737  return(0);
738 
739  };
740 
741 
743  {
744 
745  int myThreadId = 0;
746  int numThreads = 1;
747  int masterThread = 1;
748 
749 #ifdef USE_OMP
750  myThreadId = omp_get_thread_num();
751  numThreads = omp_get_max_threads();
752  masterThread = (myThreadId == 0);
753 #endif
754 
755  if(masterThread) {
756  fortranBufferIntervals.resize(numThreads);
757  fortranPartitionBufferIntervals.resize(numThreads);
758  }
759 
760 #pragma omp barrier
761 
762  std::vector<pcpp::IndexIntervalType> &threadPartitionBufferIntervals(gridPtr->ThreadPartitionBufferIntervals());
763  if(threadPartitionBufferIntervals.size() != numThreads)
764  return(1);
765  threadPartitionBufferIntervals[myThreadId].Flatten(fortranPartitionBufferIntervals[myThreadId]);
766 
767  std::vector<pcpp::IndexIntervalType> &threadBufferIntervals(gridPtr->ThreadBufferIntervals());
768  if(threadBufferIntervals.size() != numThreads)
769  return(1);
770  threadBufferIntervals[myThreadId].Flatten(fortranBufferIntervals[myThreadId]);
771 
772  // Forticate the thread intervals
773  std::vector<size_t>::iterator opIt = fortranPartitionBufferIntervals[myThreadId].begin();
774  while(opIt != fortranPartitionBufferIntervals[myThreadId].end()) {
775  *opIt += 1;
776  opIt++;
777  }
778 
779  std::vector<size_t>::iterator bufIt = fortranBufferIntervals[myThreadId].begin();
780  while(bufIt != fortranBufferIntervals[myThreadId].end()) {
781  *bufIt += 1;
782  bufIt++;
783  }
784 
785  return(0);
786 
787  };
788 
789 
790  int SetGrid(GridType &inGrid)
791  {
792 
793  int numThreads = 1;
794 #ifdef USE_OMP
795  numThreads = omp_get_num_threads();
796 #endif
797 
798  if(gridPtr != &inGrid) {
799  int myThreadID = 0;
800  int masterThread = 1;
801 
802 #ifdef USE_OMP
803  myThreadID = omp_get_thread_num();
804  masterThread = (myThreadID == 0);
805 #endif
806 
807  if(masterThread) {
808  gridPtr = &inGrid;
809  gridSizes = gridPtr->GridSizes();
810  bufferSizes = gridPtr->BufferSizes();
811  partitionInterval = gridPtr->PartitionInterval();
812  partitionBufferInterval = gridPtr->PartitionBufferInterval();
814  numDim = gridSizes.size();
815  numPointsBuffer = gridPtr->BufferSize();
816  gridCommPtr = &gridPtr->Communicator();
817  subRegionsPtr = &gridPtr->SubRegions();
819  gridInitialized = true;
820  if(partitionBufferInterval.empty()) {
821  return(1);
822  }
824 
825  // Get dX
826  dX = gridPtr->DX();
827 
828  // Allocate memory for reciprocal of dX
830 
831  // Compute reciprocal of dX
833  {
834  return(2);
835  }
836 
837  // Forticate the opInterval
838  std::vector<size_t>::iterator opIt = opInterval.begin();
839  while(opIt != opInterval.end()) {
840  *opIt += 1;
841  opIt++;
842  }
843  }
844 
845  // Reset the thread intervals for this grid
847  }
848 
849  return(0);
850 
851  };
852 
853 
854  int SetRHSState(StateType &rhsState)
855  {
856 
857  if(dEHandle < 0) {
858  dEHandle = rhsState.GetFieldHandle("Efield");
859  dHHandle = rhsState.GetFieldHandle("Hfield");
860  // dJHandle = rhsState.GetDataIndex("J");
861  }
862 
863  eFieldRHSPtr = rhsState.GetRealFieldBufferByHandle(dEHandle);
864  hFieldRHSPtr = rhsState.GetRealFieldBufferByHandle(dHHandle);
865 
868 #if 0
872  myRHSBuffers[3] = bFieldRHSPtr;
873  myRHSBuffers[4] = &bFieldRHSPtr[numPoints];
874  myRHSBuffers[5] = &bFieldRHSPtr[2*numPoints];
875 #endif
876  return(0);
877 
878  };
879 
880 
881  int HaloSetup(HaloType &inHalo)
882  {
883 
884  int myThreadID = 0;
885  int numThreads = 1;
886  int masterThread = 1;
887 
888 #ifdef USE_OMP
889  myThreadID = omp_get_thread_num();
890  masterThread = (myThreadID == 0);
891 #endif
892 
893  if(masterThread) {
894  SetHalo(inHalo);
895  periodicDirs = inHalo.PeriodicDirs();
896  if(periodicDirs.empty()) {
897  std::cout << "WARNING: Defaulting to periodic domain in RHS object." << std::endl;
898  periodicDirs.resize(numDim,1);
899  }
900  }
901 #pragma omp barrier
902 
903  return(0);
904 
905  };
906 
907 
908  int SetHalo(HaloType &inHalo)
909  {
910 
911  haloPtr = &inHalo;
912 
913  return(0);
914 
915  };
916 
917 
918  // This function sets the domainBoundaries data structure *and* goes
919  // through the stencilConnectivity to assign boundary stencils. It is
920  // redundant for the actual grid/domain boundaries, but boundary stencils
921  // for internal boundaries are set here.
922  void SetDomainBoundaries(std::vector<BoundaryType> &domainBoundaries)
923  {
924 
925  domainBoundariesPtr = &domainBoundaries;
926 
927  assert(subRegionsPtr != NULL);
928 
929  std::vector<GridRegionType> &gridRegions(*subRegionsPtr);
930  int numDomainBoundaries = domainBoundaries.size();
931  int numGridRegions = gridRegions.size();
932  int holeStencil = myOperator.numStencils;
933 
934  typename std::vector<BoundaryType>::iterator dbIt = domainBoundaries.begin();
935 
936  while(dbIt != domainBoundaries.end()) {
937 
938  BoundaryType &domainBoundary(*dbIt++);
939  GridRegionType &gridRegion(gridRegions[domainBoundary.GridRegionID()]);
940 
941  int boundaryNormalDirection = gridRegion.normalDirection;
942  pcpp::IndexIntervalType &boundaryPartitionInterval(gridRegion.regionPartitionInterval);
943 
944  int returnCode = 0;
945  if(boundaryNormalDirection != 0) {
949  boundaryPartitionInterval,
951  boundaryNormalDirection,
952  stencilID);
953  } else {
957  boundaryPartitionInterval,
958  holeStencil,
959  stencilID);
960  }
961 
962  assert(returnCode == 0);
963 
964  }
965 
966  };
967 
968 
969  void SetDomainBCs(std::vector<BCType> &domainBCs)
970  { domainBCsPtr = &domainBCs; };
971 
972 
973  int InitStep(GridType &inGrid,StateType &inState)
974  {
975  return(0);
976  };
977 
978 
980  {
981  return(0);
982  };
983 
984 
986  {
987 
988  size_t iDimxnumPointsBuffer;
989  double oneOverDX;
990 
991  if (numDim != 3) return(1);
992 
993  for (int iDim=0; iDim<numDim; iDim++) {
994  iDimxnumPointsBuffer = iDim*numPointsBuffer;
995  oneOverDX = 1.0/dX[iDim];
996  for (size_t iPoint=0; iPoint<numPointsBuffer; iPoint++) {
997  recipDX[iPoint+iDimxnumPointsBuffer] = oneOverDX;
998  }
999  }
1000 
1001  return(0);
1002 
1003  };
1004  double TimeStep(double *outCFL = NULL)
1005  {
1006  return(deltaT);
1007  };
1008 
1009  private:
1010  int Init()
1011  {
1012 
1013  int myThreadID = 0;
1014  int numThreads = 1;
1015  int masterThread = 1;
1016 
1017 #ifdef USE_OMP
1018  myThreadID = omp_get_thread_num();
1019  numThreads = omp_get_num_threads();
1020  masterThread = (myThreadID == 0);
1021 #endif
1022 
1023  if(masterThread) {
1024  // Dynamic material properties
1025  dynamicEpsMu = false;
1026 
1027  // Conserved state
1028  eFieldHandle = -1;
1029  bFieldHandle = -1;
1030  dFieldHandle = -1;
1031  hFieldHandle = -1;
1032  jHandle = -1;
1033  dEHandle = -1;
1034  dHHandle = -1;
1035 
1036  // Parameters
1037  timeHandle = -1;
1038  epsilonMuHandle = -1;
1039  gridSpacingHandle = -1;
1040  epsilon0Handle = -1;
1041  mu0Handle = -1;
1042  cflHandle = -1;
1043  deltaTHandle = -1;
1044  cRefHandle = -1;
1045 
1046  // Misc
1047  numPointsPartition = 0;
1048  numPointsBuffer = 0;
1049  numDim = 0;
1050  numStateFields = 3;
1051  numStateVar = 9;
1052 
1053  // Pointers
1054  gridPtr = NULL;
1055  timePtr = NULL;
1056  eFieldPtr = NULL;
1057  bFieldPtr = NULL;
1058  dFieldPtr = NULL;
1059  hFieldPtr = NULL;
1060  jPtr = NULL;
1061  epsilonMuPtr = NULL;
1062  eFieldRHSPtr = NULL;
1063  hFieldRHSPtr = NULL;
1064  rhsHaloPtr = NULL;
1065  epsilon0Ptr = NULL;
1066  mu0Ptr = NULL;
1067  cflPtr = NULL;
1068  deltaTPtr = NULL;
1069  cRefPtr = NULL;
1070  domainBoundariesPtr = NULL;
1071  subRegionsPtr = NULL;
1072  domainBCsPtr = NULL;
1073 
1074  stateInitialized = false;
1075  gridInitialized = false;
1076  operatorInitialized = false;
1077  errorCode = 0;
1078  }
1079 
1080  return(0);
1081 
1082  };
1083 
1084 
1085  protected:
1086  // Data handles
1087  int eFieldHandle;
1091  int jHandle;
1102 
1103  // Parameters
1104  double time;
1105  double epsilon0;
1106  double mu0;
1107  double cfl;
1108  double deltaT;
1109  double cRef;
1112 
1113  // Grid data
1114  GridType *gridPtr;
1116  std::vector<int> gridNeighbors;
1117  int numDim;
1118  std::vector<size_t> gridSizes;
1119  std::vector<size_t> bufferSizes;
1124  std::vector<double> gridMetric;
1126  std::vector<double> dX;
1127  std::vector<int> periodicDirs;
1128  std::vector<size_t> opInterval;
1129  HaloType *haloPtr;
1130  std::vector<std::vector<size_t> > fortranBufferIntervals;
1131  std::vector<std::vector<size_t> > fortranPartitionBufferIntervals;
1132 
1133  // Parameter information
1134  const double *epsilon0Ptr;
1135  const double *mu0Ptr;
1136  const double *cflPtr;
1137  const double *deltaTPtr;
1138  const double *cRefPtr;
1139 
1140  // Input state information
1141  double *eFieldPtr;
1142  double *bFieldPtr;
1143  double *dFieldPtr;
1144  double *hFieldPtr;
1145  double *jPtr;
1146  double *epsilonMuPtr;
1147  double *timePtr;
1148 
1149  // RHS state information
1150  // double *rhsTimePtr;
1151  double *eFieldRHSPtr;
1152  double *hFieldRHSPtr;
1153 
1154  // My storage
1155  std::vector<double *> myStateBuffers;
1156  std::vector<double *> myRHSBuffers;
1157 
1158  // Operator
1159  OperatorType myOperator;
1171 // std::vector<size_t> opInterval; // forticated, flat partition buffer interval
1172 
1173  // Bookkeeping
1177  std::vector<bool> haveHalo;
1179 
1180  // Halo
1181  HaloType *rhsHaloPtr;
1182 
1183  // Boundary condition support
1184  std::vector<BoundaryType> *domainBoundariesPtr;
1185  std::vector<GridRegionType> *subRegionsPtr;
1186  std::vector<BCType> *domainBCsPtr;
1188 
1189  // Temporary buffers
1190  std::vector<double> recipEpsMu;
1191  std::vector<double> recipDX;
1193 
1194  };
1195 
1196 }
1197 #endif
int SetParamState(const StateType &paramState)
const double * cflPtr
std::vector< size_t > gridSizes
int Initialize(GridType &inGrid, StateType &inState, const StateType &paramState, OperatorType &inOperator)
Definition: MaxwellSolver.H:60
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
OperatorT OperatorType
Definition: MaxwellSolver.H:50
pcpp::IndexIntervalType partitionInterval
rhs_base_t::BoundaryType BoundaryType
Definition: MaxwellSolver.H:53
void SetDomainBoundaries(std::vector< BoundaryType > &domainBoundaries)
double * eFieldPtr
std::vector< int > & PeriodicDirs()
Definition: Grid.H:160
int ConvertBfieldtoHfield(int numDim, size_t numPoints, size_t *numX, size_t *opInterval, double *recipEpsMu, double *Bfield, double *Hfield)
void Flatten(ContainerType &output) const
Definition: IndexUtil.H:274
void const size_t * numPoints
Definition: EulerKernels.H:10
HaloType * rhsHaloPtr
int CartNeighbors(std::vector< int > &neighborRanks)
Definition: COMM.C:173
double * bFieldPtr
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)
int HaloSetup(HaloType &inHalo)
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
rhs_base_t::BCType BCType
Definition: MaxwellSolver.H:54
size_t * dualStencilConn
pcpp::IndexIntervalType partitionBufferInterval
int BoundaryStencilConnectivity(std::vector< size_t > &bufferSizes, pcpp::IndexIntervalType &partitionInterval, pcpp::IndexIntervalType &partitionBufferInterval, pcpp::IndexIntervalType &boundaryInterval, int boundaryDepth, int boundaryDirection, int *stencilConnectivity)
Update a stencil connectivity with a boundary.
Definition: Stencil.C:1114
int InitStep(GridType &inGrid, StateType &inState)
OperatorType myOperator
std::vector< double > gridMetric
void SetDomainBCs(std::vector< BCType > &domainBCs)
std::vector< double * > & RHSBuffers()
int SetHalo(HaloType &inHalo)
const double * cRefPtr
int InitializeState(StateType &inState)
std::vector< double > recipEpsMu
size_t * numPointsStencil
void const size_t const size_t const size_t * opInterval
Definition: EulerKernels.H:10
size_t numPointsPartition
std::vector< size_t > bufferSizes
simulation::rhs::domain_base< GridType, StateType, OperatorType > rhs_base_t
Definition: MaxwellSolver.H:52
const double * epsilon0Ptr
int SetupStencilConnectivities()
std::vector< size_t > opInterval
std::vector< double > recipDX
std::vector< bool > haveHalo
size_t NNodes() const
Definition: IndexUtil.H:254
double TimeStep(double *outCFL=NULL)
std::vector< double * > myStateBuffers
int ComputeDV(int threadID)
StateT StateType
Definition: MaxwellSolver.H:49
std::vector< double * > & StateBuffers()
double * epsilonMuPtr
int HoleStencilConnectivity(std::vector< size_t > &bufferSizes, pcpp::IndexIntervalType &partitionInterval, pcpp::IndexIntervalType &partitionBufferInterval, pcpp::IndexIntervalType &holeInterval, int holeStencil, int *stencilConnectivity)
Update a stencil connectivity with a hole.
Definition: Stencil.C:1230
std::vector< GridRegionType > * subRegionsPtr
int SetupOperator(OperatorType &inOperator)
size_t numPointsBuffer
double * stencilWeights
void size_t int size_t int size_t int int int int double int int * stencilID
double * hFieldRHSPtr
int MaxwellRHS(int threadID)
int ConvertHfieldtoBfield(int numDim, size_t numPoints, size_t *numX, size_t *opInterval, double *epsMu, double *Hfield, double *Bfield)
int RHS(int threadID)
const double * deltaTPtr
int SetRHSState(StateType &rhsState)
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
int ComputeSATDirichletBC(const std::vector< size_t > &bufferIndices, double *rhsVar, double *stateVar, const double &value, const double &weight)
Definition: MaxwellBC.C:25
Encapsulation for a collection of operator stencils.
Definition: Stencil.H:26
double * hFieldPtr
int ComputeRecipDXUniformGrid()
fixtures::CommunicatorType * gridCommPtr
int SetupRHS(GridType &inGrid, StateType &inState, StateType &rhsState, int myThreadID=0)
Definition: MaxwellSolver.H:91
std::vector< BoundaryType > * domainBoundariesPtr
int * stencilOffsets
int SetGrid(GridType &inGrid)
int InitThreadIntervals()
double gridJacobian
int HandleBoundaryConditions(int threadID)
int ConvertEfieldtoDfield(int numDim, size_t numPoints, size_t *numX, size_t *opInterval, double *epsMu, double *Efield, double *Dfield)
std::vector< std::vector< size_t > > fortranBufferIntervals
simulation::grid::subregion GridRegionType
Definition: MaxwellSolver.H:42
int ComputeRecipEpsMu(int numDim, size_t numPoints, size_t *numX, size_t *opInterval, double *epsMu, double *recipEpsMu)
std::vector< double > dX
std::vector< int > periodicDirs
int SetupTempBuffers()
double * dFieldPtr
std::vector< std::vector< size_t > > fortranPartitionBufferIntervals
double * timePtr
int HandleSources(int threadID)
int ConvertDfieldtoEfield(int numDim, size_t numPoints, size_t *numX, size_t *opInterval, double *recipEpsMu, double *Dfield, double *Efield)
simulation::grid::halo HaloType
Definition: MaxwellSolver.H:51
Simple Block Structured Mesh object.
Definition: IndexUtil.H:21
HaloType * haloPtr
void size_t int * numComponents
std::vector< double * > myRHSBuffers
const double * mu0Ptr
double boundaryWeight
GridType * gridPtr
bool operatorInitialized
void const size_t const size_t const int const size_t const size_t const size_t const size_t const int const double const double const double * bcParams
Definition: SATKernels.H:10
std::vector< BCType > * domainBCsPtr
std::vector< int > gridNeighbors
int SetState(StateType &inState)
double * eFieldRHSPtr