PlasCom2  1.0
XPACC Multi-physics simluation application
RK4Advancer.H
Go to the documentation of this file.
1 #include "Advancer.H"
2 #include "PCPPTypes.H"
3 #include "StateOperators.H"
4 #include "State.H"
5 #include "OperatorKernels.H"
6 #include "RKKernels.H"
7 #include <limits>
8 //#include "RKUtil.H"
9 #ifdef USE_OMP
10 #include <omp.h>
11 #endif
12 
13 //#define USE_PAPI 1
14 #ifdef USE_PAPI
15 #include <papi.h>
16 int papiEventSet = PAPI_NULL;
17 int numCounters;
18 #define MAXCOUNTERS 8
19 
20 inline void AccumulateCounters(long long *tick,long long *tock,long long *clock)
21 {
22  for(int iCounter = 0;iCounter < numCounters;iCounter++)
23  clock[iCounter] += (tock[iCounter] - tick[iCounter]);
24 };
25 
26 #endif
27 
28 #ifndef _ADVANCER_TIMERS_
29 #define _ADVANCER_TIMERS_
30 static const char *timerNames[] = { "ZAXPY","RKSUM" };
31 #endif
32 
33 namespace error {
34  static const int INIT = 1;
35  static const int RHS = 2;
36  static const int IGX = 4;
37  static const int FINAL = 8;
38 }
39 
40 
41 //template<typename DomainType,typename RHSType>
42 template<typename DomainType>
43 class rk4advancer : public simulation::advancer::base<DomainType> {
44 
45 public:
46 
47  enum {ZAXPYKERNEL=0,RKSUMKERNEL,NUMTIMERS};
48 
49 
51 
52  using DomainAdvancerType::messageStreamPtr;
53  using DomainAdvancerType::domainPtr;
54  using DomainAdvancerType::advancerConfig;
55 
56  // using typename DomainType::GridType;
57 
58  typedef typename DomainType::GridType GridType;
59  typedef typename DomainType::StateType StateType;
60  typedef typename DomainType::HaloType HaloType;
61  typedef typename DomainType::OperatorType OperatorType;
62  typedef typename DomainType::RHSType RHSType;
63 
64  bool errCheck;
65 
66  rk4advancer() : DomainAdvancerType(), // rkStage(0),
67  numStages(4), rkH(0.0)
68  {
69  stageWeights.resize(4,0.5);
70  stageWeights[2] = 1.0;
71  stageWeights[3] = 1.0/6.0;
72  updateWeights.resize(4,1.0/3.0);
73  updateWeights[0] = 1.0/6.0;
74  updateWeights[3] = 1.0/6.0;
75  timersOn = false;
76  communicateState = false;
77  };
78 
79  rk4advancer(DomainType &inDomain) : DomainAdvancerType(inDomain), // rkStage(0),
80  numStages(4), rkH(0.0)
81  {
82  stageWeights.resize(4,0.5);
83  stageWeights[2] = 1.0;
84  stageWeights[3] = 1.0/6.0;
85  updateWeights.resize(4,1.0/3.0);
86  updateWeights[0] = 1.0/6.0;
87  updateWeights[3] = 1.0/6.0;
88  InitilializeAdvancer(inDomain,std::cout);
89  timersOn = false;
90  communicateState = false;
91  };
92 
94  DomainType &inDomain) : DomainAdvancerType(inDomain), // rkStage(0),
95  numStages(4), rkH(0.0)
96  {
97  stageWeights.resize(4,0.5);
98  stageWeights[2] = 1.0;
99  stageWeights[3] = 1.0/6.0;
100  updateWeights.resize(4,1.0/3.0);
101  updateWeights[0] = 1.0/6.0;
102  updateWeights[3] = 1.0/6.0;
103  timersOn = false;
104  communicateState = false;
105  Configure(inConfig);
106  InitilializeAdvancer(inDomain,std::cout);
107  };
108 
109  void SetCommunication(bool onoff)
110  { communicateState = onoff; };
111  void SetTimers(bool onoff)
112  { timersOn = onoff; };
113 
114  virtual int Configure(fixtures::ConfigurationType &inConfig){
115  advancerFields = inConfig.GetValueVector<std::string>("AdvancerFields");
116  // spatialOrder = inConfig.GetValue<int>("SpatialOrder");
117  return(0);
118  };
119 
120  // virtual int Configure(fixtures::ConfigurationType &inConfig) { return(0); };
121 
122 
133  virtual int InitializeAdvance() {
134  rkH = domainPtr->TimeStep();
135  return(0);
136  }
137 
138  virtual void SetRHS(RHSType &inRHS)
139  { rhsHandlerPtr = &inRHS; };
140 
141  // pcpp::IndexIntervalType &ThreadInterval(int threadID)
142  // { return(threadIntervals[threadID]); };
143 
144  // pcpp::IndexIntervalType &ThreadPartitionInterval(int threadID)
145  // { return(threadPartitionIntervals[threadID]); };
146 
147 
148  void SetMessageStream(std::ostream &inStream)
149  {
150  messageStreamPtr = &inStream;
151  };
152 
168  virtual int InitializeAdvancer(DomainType &inDomain,pcpp::ParallelGlobalType &inGlobal,std::ostream &inStream) {
169 
170  // FC_GLOBAL(fd1load,FD1LOAD)();
171 
172  SetRHS(inDomain.RHS());
173  SetGlobal(inGlobal);
174  SetMessageStream(inStream);
175 
176  domainPtr = &inDomain;
177  numGrids = inDomain.NumberOfLocalGrids();
178 
179  if(numGrids <= 0){
180  inStream << "rk4advancer:Error: No grids found for domain." << std::endl;
181  return(1);
182  }
183 
184  // Grid Data
185  rhsHandlers.resize(numGrids,NULL);
186  gridSizes.resize(numGrids);
187  numPointsGrids.resize(numGrids);
188  stateMessageIds.resize(numGrids);
189  gridFortranIntervals.resize(numGrids);
190  gridTimes.resize(numGrids,NULL);
191 
192  inStream << "rk4advancer:Status: Found " << numGrids << " grids in domain." << std::endl;
193 
194  for(int i = 0;i < NUMTIMERS;i++){
195  advancerTimers[i] = 0.0;
196 #ifdef USE_PAPI
197  advancerCounters[i] = new long long [numCounters];
198  for(int iCount = 0;iCount < numCounters;iCount++){
199  advancerCounters[i][iCount] = 0;
200  }
201 #endif
202  }
203 
204 
205  int numThreads = 1;
206 
207 #ifdef USE_OMP
208  numThreads = omp_get_max_threads();
209 #endif
210 
211  inStream << "rk4advancer:Status: Setting up for " << numThreads << " threads." << std::endl;
212 
213  threadStage.resize(numThreads);
214  threadGrid.resize(numThreads);
215 
216  stageStates.resize(numGrids);
217  stageKs.resize(numGrids);
218  gridNeighbors.resize(numGrids);
219 
220  for(int iLocalGrid = 0;iLocalGrid < numGrids;iLocalGrid++){
221 
222  int iGrid = inDomain.LocalGridIndex(iLocalGrid);
223 
224  rhsHandlers[iLocalGrid] = &inDomain.RHS(iGrid);
225 
226  GridType &domainGrid(inDomain.Grid(iGrid));
227  HaloType &gridHalo(inDomain.Grid(iGrid).Halo());
228  StateType &gridState(inDomain.State(iGrid));
229  StateType dummyParams;
230  StateType *paramPtr = &dummyParams;
231 
232  std::vector<StateType *> &gridParamVec(inDomain.Params());
233  if(gridParamVec.size() == numGrids){
234  if(gridParamVec[iGrid] != NULL)
235  paramPtr = gridParamVec[iGrid];
236  }
237  StateType &gridParams(*paramPtr);
238 
239 
240  gridFortranIntervals[iLocalGrid].resize(numThreads);
241 
242  fixtures::CommunicatorType &gridComm(inDomain.Grid(iGrid).Communicator());
243 
244  int numDim = domainGrid.Dimension();
245  const std::vector<double> &dX(domainGrid.DX());
246 
247  const std::vector<size_t> &bufferSizes(domainGrid.BufferSizes());
248  size_t numPoints = domainGrid.BufferSize();
249 
250 
251  gridSizes[iLocalGrid] = bufferSizes;
252  numPointsGrids[iLocalGrid] = numPoints;
253 
254  int timeHandle = gridState.GetDataIndex("simTime");
255 
256  if(timeHandle >= 0){
257  pcpp::field::dataset::DataBufferType &timeData(gridState.Field("simTime"));
258  gridTimes[iLocalGrid] = timeData.Data<double>();
259  inStream << "rk4advancer:Status: Using state-supplied time ("
260  << gridTimes[iLocalGrid] << ")" << std::endl;
261  } else {
262  inStream << "rk4advancer:Warning: Time data not supplied in state! Using dummy time."
263  << std::endl;
264  gridTimes[iLocalGrid] = &myTime;
265  *gridTimes[iLocalGrid] = 0.0;
266  }
267  myTime = inDomain.Time();
268  *gridTimes[iLocalGrid] = myTime;
269 
270  rkH = domainPtr->TimeStep();
271  if(rkH < 0.0){
272  inStream << "rk4advancer:Error: Received negative timestep (" << rkH << ") from "
273  << "RHS object. Aborting initialization." << std::endl;
274  return(1);
275  } else if (rkH == 0.0){
276  inStream << "rk4advancer:Warning: Received ZERO timestep at setup. Advancer will not update time."
277  << std::endl;
278  }
279 
280  numStateFields = gridState.NumStateFields();
281  inStream << "rk4advancer:Status: Number of state fields = "
282  << numStateFields << std::endl;
283  // Only need one intermediate state - reused for every stage
284  stageStates[iLocalGrid].resize(1);
285  stageKs[iLocalGrid].resize(numStages);
286  stageStates[iLocalGrid][0].CopyStateData(gridState);
287  for(int iStage = 0;iStage < numStages;iStage++){
288  // Multiple states will be back for adjoint "revancing"
289  // stageStates[iGrid][iStage].Copy(gridState);
290  stageKs[iLocalGrid][iStage].CopyStateData(gridState);
291  }
292 
293  gridComm.CartNeighbors(gridNeighbors[iLocalGrid]);
294 
295  // Set up the state message
296  if(communicateState){
297  inStream << "rk4advancer: Setting up message for state communication."
298  << std::endl;
299  stateMessageIds[iLocalGrid] = SetupStateMessage(gridState,gridHalo);
300  if(stateMessageIds[iLocalGrid] < 0){
301  inStream
302  << "rk4advancer:Error: Could not set up state message for Grid("
303  << iLocalGrid+1 << "," << iGrid+1 << ")."
304  << std::endl;
305  return(1);
306  }
307  }
308 
309  }
310  inStream << "rk4advancer:Status: Initialized advancer at time = "
311  << myTime << std::endl;
312  return(0);
313  };
314 
315  int SetupStateMessage(StateType &inState,HaloType &inHalo)
316  {
317  int numVar = inState.NumStateVar();
318  return(inHalo.CreateMessageBuffers(numVar));
319  };
320 
321  int PackStateMessage(StateType &inState,HaloType &inHalo,
322  int messageId,int threadId)
323  {
324  if(threadId == 0) {
325  int iVar = 0;
326  for(int iField = 0;iField < numStateFields;iField++){
327  int numComponents = inState.NumStateFieldComponents(iField);
328  double *fieldData = inState.GetStateFieldData(iField);
330  inHalo.PackMessageBuffers(messageId,iVar,numComponents,fieldData);
331  iVar += numComponents;
332  }
333  }
334  return(0);
335  };
336 
337  int UnpackStateMessage(StateType &inState,HaloType &inHalo,
338  int messageId,int threadId)
339  {
340 
341  if(threadId == 0){
342  int iVar = 0;
343  for(int iField = 0;iField < numStateFields;iField++){
344  int numComponents = inState.NumStateFieldComponents(iField);
345  double *fieldData = inState.GetStateFieldData(iField);
347  inHalo.UnPackMessageBuffers(messageId,iVar,numComponents,fieldData);
348  iVar += numComponents;
349  }
350  }
351  return(0);
352  };
353 
354  int SyncStates()
355  {
356 
357  int myThreadId = 0;
358 
359 #ifdef USE_OMP
360  myThreadId = omp_get_thread_num();
361 #endif
362 
363  DomainType &inDomain(*domainPtr);
364 
365  for(int iLocalGrid = 0;iLocalGrid < numGrids;iLocalGrid++){
366 
367  int iGrid = inDomain.LocalGridIndex(iLocalGrid);
368 
369  GridType &domainGrid(inDomain.Grid(iGrid));
370  HaloType &gridHalo(domainGrid.Halo());
371  StateType &gridState(inDomain.State(iGrid));
372  fixtures::CommunicatorType &gridComm(domainGrid.Communicator());
373  std::vector<int> &cartNeighbors(gridNeighbors[iLocalGrid]);
374  int stateMessageId = stateMessageIds[iLocalGrid];
375 
376  if(communicateState){
377  if(PackStateMessage(gridState,gridHalo,stateMessageId,myThreadId)){
378  SetError("PackStateMessage",gridComm);
379  }
380 
381 
382 #pragma omp barrier
383  // if(ErrorCheck(gridComm))
384  // return(1);
385 #pragma omp master
386  {
387  gridHalo.SendMessage(stateMessageId,cartNeighbors,gridComm);
388  gridHalo.ReceiveMessage(stateMessageId,cartNeighbors,gridComm);
389  }
390 #pragma omp barrier
391  if(UnpackStateMessage(gridState,gridHalo,stateMessageId,myThreadId)){
392  SetError("UnpackStateMessage",gridComm);
393  }
394  }
395  }
396  return(0);
397  };
398 
405  virtual int FinalizeAdvance()
406  {
407  // Update Time
408 #pragma omp master
409  {
410  myErrorCode = 0;
411  myTime = myTime + rkH;
412  for(int iGrid = 0;iGrid < numGrids;iGrid++)
413  *gridTimes[iGrid] = *gridTimes[iGrid] + rkH;
414  if(domainPtr->FinalizeAdvance(myTime))
415  myErrorCode = 1;
416  }
417 #pragma omp barrier
418  return(myErrorCode);
419  }
420 
421  virtual int GetStateUpdate(GridType &inGrid,StateType &inState,
422  StateType &stateUpdate)
423  { return(0); };
424 
425  virtual int InterGridExchange() { return(0); };
426 
427  virtual void SetError(const std::string &errorMessage,
429 
430  int myThreadId = 0;
431 #ifdef USE_OMP
432  myThreadId = omp_get_thread_num();
433 #endif
434  int &rkStage(threadStage[myThreadId]);
435 
436  std::ostringstream errOut;
437 
438  errOut << errorMessage << " for RKstage = " << rkStage;
439  DomainAdvancerType::SetError(errOut.str(),inComm);
440 
441  };
442 
444  { return(DomainAdvancerType::ErrorCheck(inComm)); };
445 
446 
455  virtual int AdvanceDomain()
456  {
457 
458  int myThreadId = 0;
459  myErrorCode = 0;
460  pcpp::ParallelGlobalType &myGlobal(*myGlobalPtr);
461 
462 #ifdef USE_OMP
463  myThreadId = omp_get_thread_num();
464 #endif
465 
466 
467  DomainType &simulationDomain(*domainPtr);
468 
469  std::vector<GridType *> &domainGrids(simulationDomain.Grids());
470  std::vector<StateType *> &domainStates(simulationDomain.States());
471  std::vector<int> &globalGridIndices(simulationDomain.LocalGridIndices());
472 
473 #pragma omp master
474  {
475  myGlobal.FunctionEntry("InitializeAdvance");
476  }
477 
478  if(InitializeAdvance()){
479  return(error::INIT);
480  }
481 
482 #pragma omp master
483  {
484  myGlobal.FunctionExit("InitializeAdvance");
485  }
486 #pragma omp barrier
487 
488  int &rkStage(threadStage[myThreadId]);
489  int &rkGrid(threadGrid[myThreadId]);
490 
491  for(rkStage = 0;rkStage < numStages;rkStage++){
492 
493  for(rkGrid = 0;rkGrid < numGrids;rkGrid++){
494 
495  double tick = 0.0;
496  double tock = 0.0;
497  int domainGridIndex = globalGridIndices[rkGrid];
498 
499 #ifdef USE_PAPI
500  long long counterTicks[MAXCOUNTERS];
501  long long counterTocks[MAXCOUNTERS];
502 #endif
503 
504  StateType &baseState(*domainStates[domainGridIndex]);
505  GridType &domainGrid(*domainGrids[domainGridIndex]);
506 
507  fixtures::CommunicatorType &gridComm(domainGrid.Communicator());
508  HaloType &gridHalo(domainGrid.Halo());
509  StateType &stageK(stageKs[rkGrid][rkStage]);
510 
511  // Perform a pointer jig...
512  // Sets up the input state (rkInputState) and
513  // the output state (rkNextState) for the current
514  // RK substep.
515  StateType *rkNextStatePtr = NULL;
516  StateType *rkInputStatePtr = NULL;
517  if(rkStage < 3) {
518  rkNextStatePtr = &stageStates[rkGrid][0];
519  if(rkStage == 0) {
520  rkInputStatePtr = domainStates[domainGridIndex];
521  } else {
522  rkInputStatePtr = &stageStates[rkGrid][0];
523  }
524  } else {
525  rkNextStatePtr = domainStates[domainGridIndex];
526  rkInputStatePtr = &stageStates[rkGrid][0];
527  }
528  StateType &rkNextState(*rkNextStatePtr);
529  StateType &rkInputState(*rkInputStatePtr);
530 
531  std::vector<int> &cartNeighbors(gridNeighbors[rkGrid]);
532  int stateMessageId = stateMessageIds[rkGrid];
533 
534 
535 #pragma omp barrier
536 #pragma omp master
537  {
538  rhsHandlerPtr = rhsHandlers[rkGrid];
539  myGlobal.FunctionEntry("GetRHS");
540  }
541 #pragma omp barrier
542 
543 
544  // std::cout << "INPUT STATE: " << std::endl;
545  // rkInputState.Report(std::cout);
546  // std::cout << "K: " << std::endl;
547  // stageK.Report(std::cout);
548  if(GetRHS(domainGrid,gridHalo,rkInputState,stageK,myThreadId)){
549  myErrorCode = 1;
550  }
551 
552  // std::cout << "RHS: " << std::endl;
553  // stageK.Report(std::cout);
554 
555 #pragma omp barrier
556 
557  if(myErrorCode){
558  return(error::RHS);
559  }
560 
561 #pragma omp master
562  {
563  myGlobal.FunctionExit("GetRHS");
564  }
565 
566  if(rkStage < 3){
567 #pragma omp barrier
568 #pragma omp master
569  {
570  myGlobal.FunctionEntry("ZAXPY");
571  }
572 
573  AXPY(stageWeights[rkStage]*rkH,stageK,baseState,rkNextState,rkGrid,myThreadId);
574 
575 #pragma omp barrier
576 #pragma omp master
577  {
578  myGlobal.FunctionExit("ZAXPY");
579  }
580  } else {
581 #pragma omp barrier
582 #pragma omp master
583  {
584  myGlobal.FunctionEntry("RKSum");
585  }
586 
587  RKSum(rkGrid,myThreadId);
588 
589 #pragma omp barrier
590 #pragma omp master
591  {
592  myGlobal.FunctionExit("RKSum");
593  }
594  }
595 
596  if(communicateState){
597 
598 #pragma omp master
599  {
600  myGlobal.FunctionEntry("StateComm");
601  myGlobal.FunctionEntry("PackMessage");
602  }
603  if(PackStateMessage(rkNextState,gridHalo,stateMessageId,myThreadId)){
604  SetError("PackStateMessage",gridComm);
605  }
606 #pragma omp barrier
607 #pragma omp master
608  {
609  myGlobal.FunctionExit("PackMessage");
610  }
611 #pragma omp barrier
612  // if(ErrorCheck(gridComm))
613  // return(1);
614 #pragma omp master
615  {
616  myGlobal.FunctionEntry("StateComm");
617  gridHalo.SendMessage(stateMessageId,cartNeighbors,gridComm);
618  gridHalo.ReceiveMessage(stateMessageId,cartNeighbors,gridComm);
619  myGlobal.FunctionExit("StateComm");
620  }
621 
622 #pragma omp barrier
623 #pragma omp master
624  {
625  myGlobal.FunctionEntry("UnpackMessage");
626  }
627 
628  if(UnpackStateMessage(rkNextState,gridHalo,stateMessageId,myThreadId)){
629  SetError("UnpackStateMessage",gridComm);
630  }
631 #pragma omp barrier
632 #pragma omp master
633  {
634  myGlobal.FunctionExit("UnpackMessage");
635  myGlobal.FunctionExit("StateComm");
636  }
637  // if(ErrorCheck(gridComm))
638  // return(1);
639  }
640  }
641  // Intergrid exchange of substate
642  if(InterGridExchange()){
643  return(error::IGX); // igx does its own error handling
644  // std::cout << "rk step done" << std::endl;
645  }
646  }
647 #pragma omp master
648  {
649  myGlobal.FunctionEntry("FinalizeAdvance");
650  }
652  if(FinalizeAdvance())
653  return(error::FINAL);
654 #pragma omp master
655  {
656  myGlobal.FunctionExit("FinalizeAdvance");
657  }
658 
659  return(0);
660 
661  };
662 
663 
664 
665 
666  int GetRHS(GridType &currentGrid,HaloType &gridHalo,StateType &inState,
667  StateType &stateRHS,int myThreadId)
668  {
669  int &rkStage(threadStage[myThreadId]);
670 
671 #pragma omp master
672  {
673  myGlobalPtr->FunctionEntry("SetupRHS");
674  }
675 
676  if(rhsHandlerPtr->SetupRHS(currentGrid,inState,stateRHS,myThreadId)){
677  if(messageStreamPtr)
678  *messageStreamPtr << "rhsHandler::SetupRHS failed in rk stage " << rkStage
679  << std::endl;
680  return(1);
681  }
682 
683 #pragma omp barrier
684 #pragma omp master
685  {
686  myGlobalPtr->FunctionExit("SetupRHS");
687  myGlobalPtr->FunctionEntry("RHS");
688  }
689  int rhsErrorCode = rhsHandlerPtr->RHS(myThreadId);
690  if(rhsErrorCode){
691  if(messageStreamPtr)
692  *messageStreamPtr << "rhsHandler::RHS failed in rk stage " << rkStage
693  << " with error code (" << rhsErrorCode << ")" << std::endl;
694  return(1);
695  }
696 
697 #pragma omp barrier
698 #pragma omp master
699  {
700  myGlobalPtr->FunctionExit("RHS");
701  }
702 
703  return(0);
704  };
705 
706 
707  int AXPY(double a,StateType &xState,StateType &yState,StateType &outState,
708  int localGridIndex,int myThreadId)
709  {
710 
711 #ifdef USE_PAPI
712  long long counterTicks[MAXCOUNTERS];
713  long long counterTocks[MAXCOUNTERS];
714 #endif
715 
716  DomainType &simulationDomain(*domainPtr);
717  std::vector<GridType *> &domainGrids(simulationDomain.Grids());
718  std::vector<int> &globalGridIndices(simulationDomain.LocalGridIndices());
719  int gridIndex = globalGridIndices[localGridIndex];
720 
721  GridType &opGrid(*domainGrids[gridIndex]);
722  size_t numPoints = opGrid.BufferSize();
723 
724  //#if 0
725  if(numPoints == 1){ // this case is needed by testing
728  StateType tempState1(yState);
729  StateType tempState2(xState*a);
730  StateType tempState3(tempState1 + tempState2);
731  outState.Copy(tempState3);
732  // outState.CopyStateData(xState*a + yState);
733  // operators::AXPY<StateType>(a,xState,outState);
734  pcpp::field::dataset::DataBufferType &timeData(outState.Field("simTime"));
735  double *nextTime = timeData.Data<double>();
736  myTime += a;
737  *nextTime = *nextTime + a;
738  return(0);
739  }
740  //#endif
741 
742  double tick = 0.0;
743  std::vector<size_t> &myInterval(gridFortranIntervals[localGridIndex][myThreadId]);
744  int numDim = opGrid.Dimension();
745  std::vector<size_t> &numPointsX(opGrid.BufferSizes());
746 
747  for(int iField = 0;iField < numStateFields;iField++){
748 
749  double *xData = xState.GetStateFieldData(iField);
750  double *yData = yState.GetStateFieldData(iField);
751  double *outData = outState.GetStateFieldData(iField);
752 
753  int numComponents = xState.NumStateFieldComponents(iField);
754 
755  for(int iComponent = 0;iComponent < numComponents;iComponent++){
756 
757  size_t compIndex = iComponent*numPoints;
758 
759  double *xBuffer = &xData[compIndex];
760  double *yBuffer = &yData[compIndex];
761  double *zBuffer = &outData[compIndex];
762 
763 
764 #pragma omp master
765  {
766  if(timersOn){
767  tick = ix::profiler::Time();
768 #ifdef USE_PAPI
769  PAPI_read(papiEventSet,counterTicks);
770 #endif
771  }
772  }
773 
775  (&numDim,&numPoints,&numPointsX[0],&myInterval[0],
776  &a,xBuffer,yBuffer,zBuffer);
777 
778 #pragma omp master
779  {
780  if(timersOn){
781  // if((myThreadId == 0) && timersOn){
782 #ifdef USE_PAPI
783  PAPI_read(papiEventSet,counterTocks);
784  AccumulateCounters(counterTicks,counterTocks,advancerCounters[ZAXPYKERNEL]);
785 #endif
786  advancerTimers[ZAXPYKERNEL] += (ix::profiler::Time() - tick);
787  }
788  }
789  }
790  }
791  return(0);
792  };
793 
794 
795  int RKSum(int localGridIndex,int myThreadId)
796  {
797 
798 #ifdef USE_PAPI
799  long long counterTicks[MAXCOUNTERS];
800  long long counterTocks[MAXCOUNTERS];
801 #endif
802 
803  DomainType &simulationDomain(*domainPtr);
804  std::vector<GridType *> &domainGrids(simulationDomain.Grids());
805  std::vector<int> &globalGridIndices(simulationDomain.LocalGridIndices());
806 
807  int gridIndex = globalGridIndices[localGridIndex];
808 
809  GridType &opGrid(*domainGrids[gridIndex]);
810  std::vector<StateType *> &domainStates(simulationDomain.States());
811  StateType &baseState(*domainStates[gridIndex]);
812  std::vector<StateType> &gridKs(stageKs[localGridIndex]);
813 
814  size_t numPoints = opGrid.BufferSize();
815  double h = rkH;
816 
817  //#if 0
818  if(numPoints == 1){
819  baseState += (((gridKs[0] + gridKs[3])*(1.0/6.0) + (gridKs[1] + gridKs[2])*(1.0/3.0))*h);
820  return(0);
821  }
822  //#endif
823 
824  double tick = 0.0;
825  std::vector<size_t> &myInterval(gridFortranIntervals[localGridIndex][myThreadId]);
826  std::vector<size_t> &numPointsX(opGrid.BufferSizes());
827  int numDim = opGrid.Dimension();
828 
829 
830  for(int iField = 0;iField < numStateFields;iField++){
831 
832  double *k1Data = gridKs[0].GetStateFieldData(iField);
833  double *k2Data = gridKs[1].GetStateFieldData(iField);
834  double *k3Data = gridKs[2].GetStateFieldData(iField);
835  double *k4Data = gridKs[3].GetStateFieldData(iField);
836  double *baseData = baseState.GetStateFieldData(iField);
837 
838  int numComponents = baseState.NumStateFieldComponents(iField);
839 
840  for(int iComponent = 0;iComponent < numComponents;iComponent++){
841 
842  size_t compIndex = iComponent*numPoints;
843  double *k1Buffer = &k1Data[compIndex];
844  double *k2Buffer = &k2Data[compIndex];
845  double *k3Buffer = &k3Data[compIndex];
846  double *k4Buffer = &k4Data[compIndex];
847  double *stateBuffer = &baseData[compIndex];
848 
849 #pragma omp master
850  {
851  if(timersOn){
852  tick = ix::profiler::Time();
853 #ifdef USE_PAPI
854  PAPI_read(papiEventSet,counterTicks);
855 #endif
856  }
857 
858  }
859 
860  FC_MODULE(rungekutta,rk4sum,RUNGEKUTTA,RK4SUM)
861  (&numDim,&numPoints,&numPointsX[0],&myInterval[0],
862  &h,k1Buffer,k2Buffer,k3Buffer,k4Buffer,stateBuffer);
863 
864 #pragma omp master
865  {
866  if(timersOn){
867 #ifdef USE_PAPI
868  PAPI_read(papiEventSet,counterTocks);
869  AccumulateCounters(counterTicks,counterTocks,advancerCounters[RKSUMKERNEL]);
870 #endif
871  advancerTimers[RKSUMKERNEL] += (ix::profiler::Time() - tick);
872  }
873  }
874  }
875  }
876  return(0);
877  };
878 
879  void GetTimers(double **timersPtr,const char ***namesPtr,unsigned int *numTimers)
880  {
881  *timersPtr = advancerTimers;
882  *namesPtr = timerNames;
883  *numTimers = NUMTIMERS;
884  };
885 
886  void GetCounters(long long ***countersPtr)
887  {
888  *countersPtr = advancerCounters;
889  };
890 
892  {
893  myGlobalPtr = &inGlobal;
894  };
895 
897  {
898 
899  int myThreadId = 0;
900  int numThreads = 1;
901 
902  DomainType &simulationDomain(*domainPtr);
903 
904 #ifdef USE_OMP
905  myThreadId = omp_get_thread_num();
906  // numThreads = omp_get_num_threads();
907 #endif
908 
909 #pragma omp barrier
910 
911  for(int iLocalGrid = 0;iLocalGrid < numGrids;iLocalGrid++){
912 
913  int iGrid = simulationDomain.LocalGridIndex(iLocalGrid);
914 
915  GridType &inGrid(simulationDomain.Grid(iGrid));
916 
917  std::vector<pcpp::IndexIntervalType> &threadPartitionIntervals(inGrid.ThreadPartitionBufferIntervals());
918  std::vector< std::vector<size_t> > &threadFortranIntervals(gridFortranIntervals[iGrid]);
919  pcpp::IndexIntervalType &threadInterval(threadPartitionIntervals[myThreadId]);
920  std::vector<size_t> &threadFortranInterval(threadFortranIntervals[myThreadId]);
921  threadInterval.Flatten(threadFortranInterval);
922  std::vector<size_t>::iterator tfIt = threadFortranInterval.begin();
923  while(tfIt != threadFortranInterval.end()){
924  *tfIt += 1;
925  tfIt++;
926  }
927  }
928 
929  };
930 
931 protected:
932 
934  bool timersOn;
936 
937  double advancerTimers[NUMTIMERS];
938  long long *advancerCounters[NUMTIMERS];
939 
940  // bool haveBCs;
941  // bool haveHalos;
942 
945  std::vector<int> threadStage;
946  std::vector<int> threadGrid;
947 
948  int numGrids;
949 
951 
952  double rkH;
953 
954  double *timePtr;
955  double *timeStepPtr;
956 
957  std::vector<RHSType *> rhsHandlers;
958  RHSType *rhsHandlerPtr;
959 
960  // int spatialOrder;
961  std::vector<std::string> advancerFields;
962 
963  // std::vector<bool> haveBoundary;
964  std::vector<double> stageWeights;
965  std::vector<double> updateWeights;
966 
967  std::vector<std::vector<StateType> > stageStates;
968  std::vector<std::vector<StateType> > stageKs;
969 
970  // Grid data
971  std::vector<size_t> numPointsGrids;
972  std::vector<std::vector<size_t> > gridSizes;
973  std::vector<int> stateMessageIds;
974  std::vector<double *> gridTimes;
975  // std::vector< std::vector<pcpp::IndexIntervalType> > gridPartitionIntervals;
976  std::vector< std::vector< std::vector<size_t> > > gridFortranIntervals;
977 
978  // StateType stateUpdate;
979 
980  // std::vector<pcpp::IndexIntervalType> threadPartitionIntervals; // local
981  // std::vector<pcpp::IndexIntervalType> threadIntervals; // global
982  // std::vector<std::vector<size_t> > fortranIntervals; // local
983 
984  std::vector<std::vector<int> > gridNeighbors;
985 
986  // Just in case the user does not provide data for these
987  double myTime;
988  double myTimeStep;
989 
990 };
991 
std::vector< std::vector< StateType > > stageKs
Definition: RK4Advancer.H:968
std::vector< std::string > advancerFields
Definition: RK4Advancer.H:961
int UnpackStateMessage(StateType &inState, HaloType &inHalo, int messageId, int threadId)
Definition: RK4Advancer.H:337
std::vector< int > stateMessageIds
Definition: RK4Advancer.H:973
double rkH
Definition: RK4Advancer.H:952
pcpp::ParallelGlobalType * myGlobalPtr
Definition: RK4Advancer.H:929
void Flatten(ContainerType &output) const
Definition: IndexUtil.H:274
void const size_t * numPoints
Definition: EulerKernels.H:10
void SetMessageStream(std::ostream &inStream)
Definition: RK4Advancer.H:148
subroutine zaxpy(N1, N2, N3, localInterval, a, X, Y, Z)
Definition: RKUtil.f90:79
void AXPY(double a, StateType &X, StateType &Y)
RHSType * rhsHandlerPtr
Definition: RK4Advancer.H:958
void SetCommunication(bool onoff)
Definition: RK4Advancer.H:109
double * timeStepPtr
Definition: RK4Advancer.H:955
static const int RHS
Definition: RK4Advancer.H:35
virtual void FunctionExit(const StackType &stackentry)
FunctionExit updates the Stack as well as the Profiler.
Definition: Global.H:609
double * timePtr
Definition: RK4Advancer.H:954
void GetCounters(long long ***countersPtr)
Definition: RK4Advancer.H:886
void const size_t const size_t * gridSizes
Definition: EulerKernels.H:10
rk4advancer(fixtures::ConfigurationType &inConfig, DomainType &inDomain)
Definition: RK4Advancer.H:93
static const int INIT
Definition: RK4Advancer.H:34
int AXPY(double a, StateType &xState, StateType &yState, StateType &outState, int localGridIndex, int myThreadId)
Definition: RK4Advancer.H:707
virtual int AdvanceDomain()
Advances domain, grid, and state by one step.
Definition: RK4Advancer.H:455
std::vector< double * > gridTimes
Definition: RK4Advancer.H:974
subroutine rk4sum(numDim, numPoints, bufferSize, bufferInterval, h, K1, K2, K3, K4, stateData)
Definition: RungeKutta.f90:8
DomainType::GridType GridType
Definition: RK4Advancer.H:58
int GetRHS(GridType &currentGrid, HaloType &gridHalo, StateType &inState, StateType &stateRHS, int myThreadId)
Definition: RK4Advancer.H:666
virtual void SetRHS(RHSType &inRHS)
Definition: RK4Advancer.H:138
std::vector< std::vector< size_t > > gridSizes
Definition: RK4Advancer.H:972
virtual int Configure(fixtures::ConfigurationType &inConfig)
Definition: RK4Advancer.H:114
std::vector< size_t > numPointsGrids
Definition: RK4Advancer.H:971
virtual int GetStateUpdate(GridType &inGrid, StateType &inState, StateType &stateUpdate)
Definition: RK4Advancer.H:421
static double Time()
Simple timer.
Definition: Profiler.H:347
virtual void FunctionEntry(const StackType &stackentry)
FunctionEntry updates the Stack as well as the Profiler.
Definition: Global.H:604
int SetupStateMessage(StateType &inState, HaloType &inHalo)
Definition: RK4Advancer.H:315
bool communicateState
Definition: RK4Advancer.H:935
std::vector< std::vector< StateType > > stageStates
Definition: RK4Advancer.H:967
std::vector< RHSType * > rhsHandlers
Definition: RK4Advancer.H:957
std::vector< int > threadStage
Definition: RK4Advancer.H:945
bool errCheck
Definition: RK4Advancer.H:64
DomainType::StateType StateType
Definition: RK4Advancer.H:59
DomainType::RHSType RHSType
Definition: RK4Advancer.H:62
simulation::advancer::base< DomainType > DomainAdvancerType
Definition: RK4Advancer.H:50
Main encapsulation of MPI.
Definition: COMM.H:62
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 * a
virtual int ErrorCheck(fixtures::CommunicatorType &inComm)
Definition: RK4Advancer.H:443
std::vector< std::string > GetValueVector(const std::string &key) const
Definition: Parameters.C:36
virtual int InterGridExchange()
Definition: RK4Advancer.H:425
std::vector< std::vector< int > > gridNeighbors
Definition: RK4Advancer.H:984
std::vector< double > stageWeights
Definition: RK4Advancer.H:964
std::vector< std::vector< std::vector< size_t > > > gridFortranIntervals
Definition: RK4Advancer.H:976
static const int IGX
Definition: RK4Advancer.H:36
double myTimeStep
Definition: RK4Advancer.H:988
void const size_t const size_t * bufferSizes
Definition: MetricKernels.H:19
static const char * timerNames[]
Definition: RK4Advancer.H:30
void GetTimers(double **timersPtr, const char ***namesPtr, unsigned int *numTimers)
Definition: RK4Advancer.H:879
int RKSum(int localGridIndex, int myThreadId)
Definition: RK4Advancer.H:795
rk4advancer(DomainType &inDomain)
Definition: RK4Advancer.H:79
Definition: EulerRHS.H:33
virtual void SetError(const std::string &errorMessage, fixtures::CommunicatorType &inComm)
Definition: RK4Advancer.H:427
virtual int InitializeAdvance()
Initialize advance called every time step.
Definition: RK4Advancer.H:133
virtual int InitializeAdvancer(DomainType &inDomain, pcpp::ParallelGlobalType &inGlobal, std::ostream &inStream)
Initializes the advancer object.
Definition: RK4Advancer.H:168
static const int FINAL
Definition: RK4Advancer.H:37
DomainType::HaloType HaloType
Definition: RK4Advancer.H:60
void SetGlobal(pcpp::ParallelGlobalType &inGlobal)
Definition: RK4Advancer.H:891
DomainType::OperatorType OperatorType
Definition: RK4Advancer.H:61
int SyncStates()
Definition: RK4Advancer.H:354
double myTime
Definition: RK4Advancer.H:987
Simple Block Structured Mesh object.
Definition: IndexUtil.H:21
void size_t int * numComponents
virtual int FinalizeAdvance()
Last call after 1 advance step.
Definition: RK4Advancer.H:405
int PackStateMessage(StateType &inState, HaloType &inHalo, int messageId, int threadId)
Definition: RK4Advancer.H:321
std::vector< double > updateWeights
Definition: RK4Advancer.H:965
void SyncIntervals()
Definition: RK4Advancer.H:896
void FC_MODULE(euler, flux1d, EULER, FLUX1D)(const int *numDim
std::vector< int > threadGrid
Definition: RK4Advancer.H:946
void SetTimers(bool onoff)
Definition: RK4Advancer.H:111
int numStateFields
Definition: RK4Advancer.H:943