CG  Version 25
pcMacros.h
Go to the documentation of this file.
1 // This file contains some macros that are shared amongst the different predictor-corrector methods
2 
3 
4 // ==================================================================================================
5 // MACRO: This macro saves past values of the pressure and values of the velocity on the ghost lines
6 // For use with the fourth-order accurate INS solver.
7 //
8 // tp (input) : past value of time
9 // nab (input) : save results in fn[nab] (NOTE: use the grid from gf[mOld] not the one with fn[nab] !)
10 // ==================================================================================================
11 #beginMacro savePressureAndGhostVelocity(tp,nab)
13 {
14  const int uc = parameters.dbase.get<int >("uc");
15  const int pc = parameters.dbase.get<int >("pc");
16  OGFunction & e = *(parameters.dbase.get<OGFunction* >("exactSolution"));
17 
18  const int numberOfDimensions=cg.numberOfDimensions();
19  const int numberOfGhostLines=2;
20  Range V(uc,uc+numberOfDimensions-1);
21 
22  for( int grid=0; grid<gf[mOld].cg.numberOfComponentGrids(); grid++ )
23  {
24  MappedGrid & c = gf[mOld].cg[grid];
25 
26  realArray & fng = fn[nab][grid];
27  realArray & uOld = gf[mOld].u[grid];
28 #ifdef USE_PPP
29  realSerialArray fnLocal; getLocalArrayWithGhostBoundaries(fng,fnLocal);
30  realSerialArray uOldLocal; getLocalArrayWithGhostBoundaries(uOld,uOldLocal);
31 #else
32  realSerialArray & fnLocal = fng;
33  realSerialArray & uOldLocal = uOld;
34 #endif
35  OV_GET_SERIAL_ARRAY_CONST(real,c.vertex(),xLocal);
36  const int isRectangular=false; // for e.gd(..)
37 
38  const IntegerArray & gridIndexRange = c.gridIndexRange();
39  getIndex(c.dimension(),I1,I2,I3);
40 
41 
42  // save p for use when extrapolating in time
43  // ua(.,.,.,pc)= p(t-2*dt) (for 2nd/4th order)
44  // ub(.,.,.,pc)= p(t-3*dt) (for 4th order)
45  // uc(.,.,.,pc)= p(t-4*dt) (for 4th order)
46  if( parameters.dbase.get<bool >("twilightZoneFlow") )
47  {
48  // *wdh* 050416 fn[nab][grid](I1,I2,I3,pc)=e(c,I1,I2,I3,pc,tp);
49  // fn[nab][grid](I1,I2,I3,pc)=e(c,I1,I2,I3,pc,tp);
50  // e.gd(fn[nab][grid],0,0,0,0,I1,I2,I3,pc,tp);
51  e.gd(fnLocal,xLocal,numberOfDimensions,isRectangular,0,0,0,0,I1,I2,I3,pc,tp);
52  // display(fn[nab][grid],"fn[nab][grid] after assigning for fourth order",debugFile,"%5.2f ");
53  fprintf(debugFile,"savePressureAndGhostVelocity: Set p at old time for fourth-order: nab=%i, t=%9.3e\n",nab,tp);
54 
55  if( debug() & 4 )
56  {
57  display(xLocal,"savePressureAndGhostVelocity: xLocal from gf[mOld] ",debugFile,"%6.3f ");
58  display(fn[nab][grid],"savePressureAndGhostVelocity: fn[nab][grid] after assigning p for fourth order",debugFile,"%6.3f ");
59  }
60 
61 
62  }
63  else
64  {
65  bool ok = ParallelUtility::getLocalArrayBounds(fng,fnLocal,I1,I2,I3);
66  if( ok )
67  fnLocal(I1,I2,I3,pc)=uOldLocal(I1,I2,I3,pc); // *** fix this ****
68  }
69 
70  // We also extrapolate, in time, the ghost values of u -- used in the BC's
71  getIndex(gridIndexRange,I1,I2,I3,numberOfGhostLines);
72  for( int axis=0; axis<c.numberOfDimensions(); axis++ )
73  {
74  for( int side=0; side<=1; side++ )
75  {
76  const int is=1-2*side;
77  if( c.boundaryCondition(side,axis)>0 )
78  {
79  // set values on the two ghost lines
80  if( side==0 )
81  Iv[axis]=Range(gridIndexRange(side,axis)-2,gridIndexRange(side,axis)-1);
82  else
83  Iv[axis]=Range(gridIndexRange(side,axis)+1,gridIndexRange(side,axis)+2);
84 
85  if( parameters.dbase.get<bool >("twilightZoneFlow") )
86  {
87  // *wdh* 050416 fn[nab][grid](I1,I2,I3,V)=e(c,I1,I2,I3,V,tp);
88  // fn[nab][grid](I1,I2,I3,V)=e(c,I1,I2,I3,V,tp);
89  // display(fn[nab][grid],"fn[nab][grid] before assign V on ghost",debugFile,"%5.2f ");
90  // e.gd(fn[nab][grid],0,0,0,0,I1,I2,I3,V,tp);
91  e.gd(fnLocal,xLocal,numberOfDimensions,isRectangular,0,0,0,0,I1,I2,I3,V,tp);
92  // display(fn[nab][grid],"fn[nab][grid] after assign V on ghost",debugFile,"%5.2f ");
93 
94  }
95  else
96  {
97  bool ok = ParallelUtility::getLocalArrayBounds(fng,fnLocal,I1,I2,I3);
98  if( ok )
99  fnLocal(I1,I2,I3,V)=uOldLocal(I1,I2,I3,V); // ***** fix this ****
100  }
101  }
102  }
103  // set back to gridIndexRange to avoid re-doing corners: *** is this ok for 3D ???
104  Iv[axis]=Range(gridIndexRange(0,axis),gridIndexRange(1,axis));
105  }
106 
107  } // end for grid
108 }
109 #endMacro
110 
111 
112 
113 // ===============================================================================
114 // MACRO: Perform the initialization step for the PC method
115 //
116 // /METHOD (input) : name of the method: adamsPC or implicitPC
117 // ===============================================================================
118 #beginMacro initializePredictorCorrector(METHOD,utImplicit)
119 
120 const int orderOfPredictorCorrector = parameters.dbase.get<int >("orderOfPredictorCorrector");
121 const int orderOfAccuracy = parameters.dbase.get<int >("orderOfAccuracy");
122 const int orderOfTimeExtrapolationForPressure = parameters.dbase.get<int >("orderOfTimeExtrapolationForPressure");
123 
124 
125 if( movingGridProblem() )
126 {
127 
128  getGridVelocity( gf[mCur],t0 );
129 }
130 
131 
132 if( orderOfTimeExtrapolationForPressure!=-1 )
133 {
134  if( orderOfPredictorCorrector==2 && orderOfTimeExtrapolationForPressure>1 &&
135  poisson!=NULL && poisson->isSolverIterative() )
136  {
137  // orderOfTimeExtrapolationForPressure==1 : p(t+dt) = 2*p(t) - p(t-dt)
138  // 2 : p(t+dt) = 3*p(t) - 3*p(t-dt) + p(t-2*dt)
139  assert( previousPressure==NULL );
140  assert( !parameters.isMovingGridProblem() ); // fix for this case
141 
142  numberOfExtraPressureTimeLevels = orderOfTimeExtrapolationForPressure - 1;
143  printf(" ***initPC: allocate %i extra grid functions to store the pressure at previous times ****\n",
144  numberOfExtraPressureTimeLevels);
145 
146  previousPressure = new realCompositeGridFunction [numberOfExtraPressureTimeLevels];
147  for( int i=0; i<numberOfExtraPressureTimeLevels; i++ )
148  {
149  previousPressure[i].updateToMatchGrid(gf[mCur].cg);
150  }
151  }
152 
153 }
154 
155 fn[nab0]=0.;
156 fn[nab1]=0.;
157 
158 
159 if( parameters.dbase.get<bool >("twilightZoneFlow") )
160 {
161  OGFunction & e = *(parameters.dbase.get<OGFunction* >("exactSolution"));
162 
163  if( orderOfAccuracy==4 )
164  {
165  // For the fourth-order PC method, first compute u.t(t-2*dt) and u.t(t-3*dt)
166  // Even for 2nd-order in time methods -- save p and u-ghost at t-2*dt
167  const int numberOfPreviousValuesOfPressureToSave= orderOfPredictorCorrector==2 ? 1 : 2;
168 
169  int grid;
170  for( int m=0; m<numberOfPreviousValuesOfPressureToSave; m++ )
171  {
172 
173  const int nab=(nab2+m) % 4; // save du/dt in fn[nab]
174  real tp=t0-(m+2)*dt0; // move grid to this previous time
175 
176  if( movingGridProblem() )
177  {
178  // move gf[mOld] to t-(m+2)*dt
179  moveGrids( t0,t0,tp,dt0,gf[mCur],gf[mCur],gf[mOld] ); // Is this correct? dt0?
180 
181  gf[mOld].u.updateToMatchGrid(gf[mOld].cg); // *wdh* 040826
182 
183  // *wdh* 111125: the vertex is used below for error checking
184  fn[nab].updateToMatchGrid(gf[mOld].cg);
185 
186 
187  // *wdh* 090806
188  real cpu0=getCPU();
189  gf[mOld].u.getOperators()->updateToMatchGrid(gf[mOld].cg);
190  parameters.dbase.get<RealArray>("timing")(parameters.dbase.get<int>("timeForUpdateOperators"))+=getCPU()-cpu0;
191 
192 
193  }
194  gf[mOld].t=tp;
195 
196  e.assignGridFunction( gf[mOld].u,tp );
197 
198  updateStateVariables(gf[mOld]); // *wdh* 080204
199 
200  if( parameters.useConservativeVariables() )
201  gf[mOld].primitiveToConservative();
202 
203  if( orderOfPredictorCorrector==4 )
204  { // we only need du/dt at old times for pc4
205  for( grid=0; grid<gf[mCur].cg.numberOfComponentGrids(); grid++ )
206  {
207  rparam[0]=gf[mOld].t;
208  rparam[1]=gf[mOld].t; // tforce
209  rparam[2]=gf[mCur].t-gf[mOld].t; // tImplicit *************** check me 111124 **********************
210  iparam[0]=grid;
211  iparam[1]=gf[mOld].cg.refinementLevelNumber(grid);
212  iparam[2]=numberOfStepsTaken;
213 
214  getUt(gf[mOld].u[grid],gf[mOld].getGridVelocity(grid),fn[nab][grid],iparam,rparam,
215  utImplicit[grid],&gf[mOld].cg[grid]);
216  }
217  }
218 
219  // save past time values of p and ghost u for the 4th order method
220  // NOTE: PAST time values are saved in a funny place:
221  // save p for use when extrapolating in time
222  // ua(.,.,.,pc)= p(t-2*dt) (for 2nd/4th order)
223  // ub(.,.,.,pc)= p(t-3*dt) (for 4th order)
224  // uc(.,.,.,pc)= p(t-4*dt) (for 4th order)
225  assert( nab0==0 );
226  const int nabPastTime=(nab0+m);
227  savePressureAndGhostVelocity(tp,nabPastTime);
228 
229  if( debug() & 4 )
230  {
231  // determineErrors( gf[mOld].u,gf[mOld].gridVelocity, tp, 0, error,
232  // sPrintF(" adams:startup: errors in u at t=%e \n",nab,tp) );
233 
234  if( movingGridProblem() && debug() & 64 )
235  {
236  CompositeGrid & cg = *fn[nab].getCompositeGrid();
237 
238  for( grid=0; grid<cg.numberOfComponentGrids(); grid++ )
239  {
240  if( parameters.gridIsMoving(grid) )
241  {
242  display(cg[grid].vertex()(I1,I2,I3,0),sPrintF("\n *** PC: AFTER moveGrids: fn[nab] "
243  "grid=%i vertex after move back t=%e",grid,gf[mOld].t),debugFile,"%8.5f ");
244  }
245  }
246 
247  }
248  determineErrors( fn[nab],gf[mOld].gridVelocity, tp, 1, error,
249  sPrintF(" adams:startup: errors in ut (nab=%i) at t=%e \n",nab,tp) );
250  }
251 
252  }
253  }
254 
255 
256  // get solution and derivative at t-dt
257  if( movingGridProblem() )
258  {
259  // move gf[mOld] to t-dt
260  if( debug() & 2 )
261  fPrintF(debugFile,"METHOD: take an initial step backwards\n");
262 
263  // display(gf[mOld].cg[0].vertex()(I1,I2,I3,0),sPrintF(" gf[mOld] vertex before move back at t=%e",gf[mOld].t),
264  // debugFile,"%5.2f ");
265 
266  moveGrids( t0,t0,t0-dt0,dt0,gf[mCur],gf[mCur],gf[mOld] ); // this will set gf[mOld].t=t-dt
267 
268  // *wdh* 090806
269  if( parameters.isAdaptiveGridProblem() )
270  { // both moving and AMR
271  parameters.dbase.get<Ogen* >("gridGenerator")->updateRefinement(gf[mOld].cg);
272  }
273  // *wdh* 090806
274  real cpu0=getCPU();
275  gf[mOld].u.getOperators()->updateToMatchGrid(gf[mOld].cg);
276  parameters.dbase.get<RealArray>("timing")(parameters.dbase.get<int>("timeForUpdateOperators"))+=getCPU()-cpu0;
277 
278  if( debug() & 64 )
279  {
280  for( grid=0; grid<gf[mOld].cg.numberOfComponentGrids(); grid++ )
281  {
282  if( parameters.gridIsMoving(grid) )
283  {
284  display(gf[mOld].cg[grid].vertex()(I1,I2,I3,0),sPrintF("\n *** PC: AFTER moveGrids: gf[mOld] grid=%i vertex after move back t=%e",grid,gf[mOld].t),
285  debugFile,"%10.7f ");
286  }
287  }
288 
289  }
290 
291 
292  gf[mOld].u.updateToMatchGrid(gf[mOld].cg); // make sure the grid is correct, vertex used in TZ *wdh* 040826
293 
294  // *wdh* 111125: the vertex is used below for error checking and computing ghost values of u
295  fn[nab1].updateToMatchGrid(gf[mOld].cg);
296 
297  }
298  else
299  gf[mOld].t=t0-dt0;
300 
301  // assign u(t-dt) with the TZ solution:
302  e.assignGridFunction( gf[mOld].u,t0-dt0 );
303  updateStateVariables(gf[mOld]); // *wdh* 080204
304 
305  if( parameters.useConservativeVariables() )
306  gf[mOld].primitiveToConservative();
307 
308  // -- evaluate du/dt(t-dt) --
309  for( int grid=0; grid<gf[mCur].cg.numberOfComponentGrids(); grid++ )
310  {
311  rparam[0]=gf[mOld].t;
312  rparam[1]=gf[mOld].t; // tforce
313  rparam[2]=gf[mCur].t-gf[mOld].t; // tImplicit *************** check me 090806 **********************
314  iparam[0]=grid;
315  iparam[1]=gf[mOld].cg.refinementLevelNumber(grid);
316  iparam[2]=numberOfStepsTaken;
317  getUt(gf[mOld].u[grid],gf[mOld].getGridVelocity(grid),fn[nab1][grid],iparam,rparam,
318  utImplicit[grid],&gf[mOld].cg[grid]);
319  }
320 
321  // display(fn[nab1][0],sPrintF("ut(t-dt) from getUt at t=%e\n",gf[mOld].t),debugFile,"%5.2f ");
322 
323  if( false ) // for testing assign du/dt(t-dt) from TZ directly
324  {
325  for( grid=0; grid<gf[mOld].cg.numberOfComponentGrids(); grid++ )
326  {
327  MappedGrid & c = gf[mOld].cg[grid];
328  getIndex(c.dimension(),I1,I2,I3);
329  Range Na(0,parameters.dbase.get<int >("numberOfComponents")-1);
330  fn[nab1][grid](I1,I2,I3,Na)=e.t(c,I1,I2,I3,Na,t0-dt0);
331 
332  if( parameters.gridIsMoving(grid) )
333  { // add on gDot.grad(u)
334  const realArray & gridVelocity = gf[mOld].getGridVelocity(grid);
335  const int na=parameters.dbase.get<int >("uc"), nb=na+c.numberOfDimensions()-1; // ***** watch out ***
336  for( int n=na; n<=nb; n++ )
337  {
338  fn[nab1][grid](I1,I2,I3,n)+=gridVelocity(I1,I2,I3,0)*e.x(c,I1,I2,I3,n,t0-dt0)+
339  gridVelocity(I1,I2,I3,1)*e.y(c,I1,I2,I3,n,t0-dt0);
340  if( c.numberOfDimensions()>2 )
341  fn[nab1][grid](I1,I2,I3,n)+=gridVelocity(I1,I2,I3,2)*e.z(c,I1,I2,I3,n,t0-dt0);
342  }
343 
344  display(fn[nab1][grid],sPrintF("METHOD:init: ut(t-dt) grid=%i from TZ at t=%e\n",grid,gf[mOld].t),debugFile,"%5.2f ");
345 
346  }
347  }
348  }
349 
350 
351  if( numberOfExtraPressureTimeLevels>0 )
352  {
353  // get extra time levels for extrapolating the pressure in time (as an initial guess for iterative solvers)
354  for( int i=0; i<numberOfExtraPressureTimeLevels; i++ )
355  {
356  // if orderOfPC==2 : we need p(t-2*dt), p(t-3*dt) ...
357  // ==4 : we need p(t-5*dt), ... **check**
358  const real tp = t0-dt0*(i+orderOfPredictorCorrector);
359  realCompositeGridFunction & pp = previousPressure[i];
360  Range all;
361  for( grid=0; grid<gf[mCur].cg.numberOfComponentGrids(); grid++ )
362  {
363  e.gd( pp[grid],0,0,0,0,all,all,all,parameters.dbase.get<int >("pc"),tp);
364  }
365  }
366  }
367 
368 
369  if( debug() & 4 || debug() & 64 )
370  {
371  for( grid=0; grid<gf[mCur].cg.numberOfComponentGrids(); grid++ )
372  {
373  aString buff;
374  display(gf[mOld].u[grid],sPrintF(buff,"\n ****METHOD: Init:gf[mOld].u grid=%i : du/dt(t) t=%9.3e",grid,gf[mOld].t),
375  debugFile,"%9.3e ");
376  display(fn[nab1][grid],sPrintF(buff,"\n ****METHOD: Init:fn[nab1] grid=%i : du/dt(t) t=%9.3e",grid,gf[mOld].t),
377  debugFile,"%9.3e ");
378  if( parameters.isMovingGridProblem() )
379  {
380  display(gf[mOld].getGridVelocity(grid),sPrintF("adams:init: t=-dt: gridVelocity[%i] at t=%9.3e\n",grid,gf[mOld].t),debugFile,"%5.2f ");
381  display(gf[mCur].getGridVelocity(grid),sPrintF("adams:init: t=0 : gridVelocity[%i] at t=%9.3e\n",grid,gf[mCur].t),debugFile,"%5.2f ");
382  }
383  if( debug() & 64 && parameters.isMovingGridProblem() )
384  {
385  display(gf[mOld].cg[grid].vertex(),sPrintF("adams:init: gf[mOld].cg[%i].vertex at t=%9.3e\n",grid,gf[mOld].t),debugFile,"%7.4f ");
386  display(gf[mCur].cg[grid].vertex(),sPrintF("adams:init: gf[mCur].cg[%i].vertex at t=%9.3e\n",grid,gf[mCur].t),debugFile,"%7.4f ");
387  }
388 
389  }
390 
391  }
392  if( debug() & 4 )
393  {
394  if( parameters.isMovingGridProblem() )
395  {
396  determineErrors( gf[mOld].u,gf[mOld].gridVelocity, gf[mOld].t, 0, error,
397  sPrintF(" adams:init: errors in u at t=%9.3e (t0-dt0=%9.3e)\n",gf[mOld].t,t0-dt0) );
398  fn[nab1].updateToMatchGrid(gf[mOld].cg); // for moving grid TZ to get errors correct
399  determineErrors( fn[nab1],gf[mOld].gridVelocity, gf[mOld].t, 1, error,
400  sPrintF(" adams:init: errors in ut (fn[nab1]) at t=%9.3e (t0-dt0=%9.3e)\n",gf[mOld].t,t0-dt0) );
401  }
402 
403  }
404 
405 
406 }
407 else
408 {
409  // ****** Initialize for NOT twilightZoneFlow ***********
410 
411  printF(" **************** METHOD: still need correct initial values for du/dt(t-dt) ****** \n");
412  printF(" **************** use values from du/dt(t) ****** \n");
413 
414  if( parameters.useConservativeVariables() )
415  gf[mCur].primitiveToConservative();
416 
417  // if( parameters.isAdaptiveGridProblem() )
418  // gf[mOld].u.updateToMatchGrid(gf[mOld].cg); // 040928 -- why is this needed here ?
419 
420  if( debug() & 8 )
421  {
422  printF(" PC: init: gf[mOld].u.numberOfGrids=%i \n",gf[mOld].u.numberOfGrids());
423  printF(" PC: init: gf[mOld].cg.numberOfComponentGrids=%i \n",gf[mOld].cg.numberOfComponentGrids());
424 
425  printF(" PC: init: gf[mCur].u.numberOfGrids=%i \n",gf[mCur].u.numberOfGrids());
426  printF(" PC: init: gf[mCur].cg.numberOfComponentGrids=%i \n",gf[mCur].cg.numberOfComponentGrids());
427  }
428 
429  assign(gf[mOld].u,gf[mCur].u); // 990903 give initial values to avoid NAN's at ghost points for CNS
430 
431  gf[mOld].form=gf[mCur].form;
432 
433  for( grid=0; grid<gf[mCur].cg.numberOfComponentGrids(); grid++ )
434  {
435  rparam[0]=gf[mOld].t;
436  rparam[1]=gf[mOld].t; // tforce
437  // *wdh* 090806 : what was this? rparam[2]=gf[mCur].t-gf[mOld].t; // tImplicit
438  rparam[2]=gf[mCur].t; // tImplicit = apply forcing for implicit time stepping at this time
439  iparam[0]=grid;
440  iparam[1]=gf[mOld].cg.refinementLevelNumber(grid);
441  iparam[2]=numberOfStepsTaken;
442  getUt(gf[mOld].u[grid],gf[mOld].getGridVelocity(grid),fn[nab1][grid],iparam,rparam,
443  utImplicit[grid],&gf[mOld].cg[grid]);
444  }
445  for( grid=0; grid<gf[mOld].cg.numberOfComponentGrids(); grid++ )
446  {
447  MappedGrid & c = gf[mOld].cg[grid];
448  getIndex(c.dimension(),I1,I2,I3);
449  // fn[nab1][grid](I1,I2,I3,N)=fn[nab0][grid](I1,I2,I3,N);
450  if( orderOfPredictorCorrector==4 )
451  {
452  for( int m=0; m<=1; m++ )
453  {
454  const int nab=(mOld+m+1) % 4;
455  // *wdh* 050319 fn[nab][grid](I1,I2,I3,N)=fn[nab0][grid](I1,I2,I3,N);
456  assign(fn[nab][grid],fn[nab0][grid],I1,I2,I3,N);
457  }
458  }
459  }
460 
461 }
462 
463 
464 if( false && orderOfAccuracy==4 ) // now done above
465 {
466  const int uc = parameters.dbase.get<int >("uc");
467  const int pc = parameters.dbase.get<int >("pc");
468  OGFunction & e = *(parameters.dbase.get<OGFunction* >("exactSolution"));
469 
470  const int numberOfGhostLines=2;
471  Range V(uc,uc+gf[mOld].cg.numberOfDimensions()-1);
472  const int numberOfPreviousValuesOfPressureToSave= orderOfPredictorCorrector==2 ? 1 : 3;
473  for( int m=0; m<numberOfPreviousValuesOfPressureToSave; m++ )
474  {
475  real tp=t0-(m+2)*dt0;
476  assert( nab0==0 );
477  const int nab=(nab0+m);
478  for( grid=0; grid<gf[mOld].cg.numberOfComponentGrids(); grid++ )
479  {
480  MappedGrid & c = gf[mOld].cg[grid];
481 
482  realArray & fng = fn[nab][grid];
483  realArray & uOld = gf[mOld].u[grid];
484  #ifdef USE_PPP
485  realSerialArray fnLocal; getLocalArrayWithGhostBoundaries(fng,fnLocal);
486  realSerialArray uOldLocal; getLocalArrayWithGhostBoundaries(uOld,uOldLocal);
487  #else
488  realSerialArray & fnLocal = fng;
489  realSerialArray & uOldLocal = uOld;
490  #endif
491 
492  const IntegerArray & gridIndexRange = c.gridIndexRange();
493  getIndex(c.dimension(),I1,I2,I3);
494 
495 
496 
497  // save p for use when extrapolating in time
498  // ua(.,.,.,pc)= p(t-2*dt) (for 2nd/4th order)
499  // ub(.,.,.,pc)= p(t-3*dt) (for 4th order)
500  // uc(.,.,.,pc)= p(t-4*dt) (for 4th order)
501  if( parameters.dbase.get<bool >("twilightZoneFlow") )
502  {
503  // *wdh* 050416 fn[nab][grid](I1,I2,I3,pc)=e(c,I1,I2,I3,pc,tp);
504  // fn[nab][grid](I1,I2,I3,pc)=e(c,I1,I2,I3,pc,tp);
505  fprintf(debugFile," Set p at old time for fourth-order: nab=%i, t=%9.3e\n",nab,tp);
506  display(fn[nab][grid],"fn[nab][grid] before assigning p for fourth order",debugFile,"%5.2f ");
507  e.gd(fn[nab][grid],0,0,0,0,I1,I2,I3,pc,tp);
508  display(fn[nab][grid],"fn[nab][grid] after assigning p for fourth order",debugFile,"%5.2f ");
509 
510  }
511  else
512  {
513  bool ok = ParallelUtility::getLocalArrayBounds(fng,fnLocal,I1,I2,I3);
514  if( ok )
515  fnLocal(I1,I2,I3,pc)=uOldLocal(I1,I2,I3,pc); // *** fix this ****
516  }
517 
518  // We also extrapolate, in time, the ghost values of u -- used in the BC's
519  getIndex(gridIndexRange,I1,I2,I3,numberOfGhostLines);
520  int side,axis;
521  for( axis=0; axis<c.numberOfDimensions(); axis++ )
522  {
523  for( side=0; side<=1; side++ )
524  {
525  const int is=1-2*side;
526  if( c.boundaryCondition(side,axis)>0 )
527  {
528  // set values on the two ghost lines
529  if( side==0 )
530  Iv[axis]=Range(gridIndexRange(side,axis)-2,gridIndexRange(side,axis)-1);
531  else
532  Iv[axis]=Range(gridIndexRange(side,axis)+1,gridIndexRange(side,axis)+2);
533 
534  if( parameters.dbase.get<bool >("twilightZoneFlow") )
535  {
536  // *wdh* 050416 fn[nab][grid](I1,I2,I3,V)=e(c,I1,I2,I3,V,tp);
537  // fn[nab][grid](I1,I2,I3,V)=e(c,I1,I2,I3,V,tp);
538  // display(fn[nab][grid],"fn[nab][grid] before assign V on ghost",debugFile,"%5.2f ");
539  e.gd(fn[nab][grid],0,0,0,0,I1,I2,I3,V,tp);
540  // display(fn[nab][grid],"fn[nab][grid] after assign V on ghost",debugFile,"%5.2f ");
541  }
542  else
543  {
544  bool ok = ParallelUtility::getLocalArrayBounds(fng,fnLocal,I1,I2,I3);
545  if( ok )
546  fnLocal(I1,I2,I3,V)=uOldLocal(I1,I2,I3,V); // ***** fix this ****
547  }
548  }
549  }
550  // set back to gridIndexRange to avoid re-doing corners: *** is this ok for 3D ???
551  Iv[axis]=Range(gridIndexRange(0,axis),gridIndexRange(1,axis));
552  }
553 
554  }
555  }
556 } // end if( parameters.dbase.get< >("orderOfAccuracyInSpace")==4 )
557 
558 
559 
560 
561 dtb=dt0; // delta t to go from ub to ua
562 
563 dtp[0]=dt0;
564 dtp[1]=dt0;
565 dtp[2]=dt0;
566 dtp[3]=dt0;
567 dtp[4]=dt0;
568 
569 // if( debug() & 8 )
570 // {
571 // fprintf(debugFile," advance Adams PC: ut at t0=%e\n",t0);
572 // outputSolution( fn[nab0],t0 );
573 // fprintf(debugFile," advance Adams PC: Errors in ut at t0=%e\n",t0);
574 // determineErrors( fn[1],t0-dt0 );
575 // }
576 
577 init=false;
578 
579 
580 #endMacro
581 
582 
583 // =======================================================================================================
584 // Macro to move the grids at the start of a PC time step.
585 // Arguments:
586 // METHOD : name of the calling function (for debug output)
587 // utImplicit : name of the grid function that holds the explicit part of the implicit operator.
588 //
589 // predictorOrder : order of the predictor corrector
590 // ub,uc,ud : grid functions that hold du/dt at times tb, tc, td
591 // If predictorOrder==2 then explosed points are filled in on ub.
592 // If predictorOrder==3 then explosed points are filled in on ub and uc.
593 // If predictorOrder==4 then explosed points are filled in on ub, uc and ud.
594 // =======================================================================================================
595 #beginMacro moveTheGridsMacro(METHOD,utImplicit,predictorOrder,tb,ub,tc,uc,td,ud)
596 
597 if( movingGridProblem() )
598 {
599  checkArrays(" METHOD : before move grids");
600 
601  if( debug() & 8 )
602  printf(" METHOD: before moveTheGridsMacro: t0=%9.3e, gf[mNew].t=%9.3e, gf[mNew].gridVelocityTime=%9.3e\n",
603  t0,gf[mNew].t,gf[mNew].gridVelocityTime);
604 
605  // generate gf[mNew] from gf[mCur] (compute grid velocity on gf[mCur] and gf[mNew]
606  moveGrids( t0,t0,t0+dt0,dt0,gf[mCur],gf[mCur],gf[mNew] );
607 
608  checkArrayIDs(sPrintF(" METHOD : after move grids t=%9.3e",gf[mCur].t));
609 
610  if( parameters.isAdaptiveGridProblem() )
611  {
612  // both moving and AMR
613  parameters.dbase.get<Ogen* >("gridGenerator")->updateRefinement(gf[mNew].cg);
614  }
615 
616  if( debug() & 16 )
617  {
618  if( twilightZoneFlow() )
619  {
620  fprintf(debugFile,"\n ---> METHOD : Errors in u after moveGrids t=%e \n",gf[mCur].t);
621  determineErrors( gf[mCur] );
622  }
623  }
624 
625 
626  real cpu0=getCPU();
627  gf[mNew].cg.rcData->interpolant->updateToMatchGrid( gf[mNew].cg );
628  parameters.dbase.get<RealArray>("timing")(parameters.dbase.get<int>("timeForUpdateInterpolant"))+=getCPU()-cpu0;
629 
630  cpu0=getCPU();
631  gf[mNew].u.getOperators()->updateToMatchGrid(gf[mNew].cg);
632  parameters.dbase.get<RealArray>("timing")(parameters.dbase.get<int>("timeForUpdateOperators"))+=getCPU()-cpu0;
633 
634  if( debug() & 4 ) printf("METHOD : step: update gf[mNew] for moving grids, gf[mNew].t=%9.3e,...\n",gf[mNew].t);
635 
636  if( debug() & 16 )
637  {
638  if( twilightZoneFlow() )
639  {
640  fprintf(debugFile,"\n ---> METHOD: Errors in u before updateForMovingGrids t=%e \n",gf[mCur].t);
641  fprintf(debugFile,"*** mCur=%i mNew=%i numberOfGridFunctions=%i *** \n",
642  mCur,mNew,numberOfGridFunctions);
643 
644  determineErrors( gf[mCur] );
645  }
646  }
647 
648  updateForMovingGrids(gf[mNew]);
649  // **** gf[mNew].u.updateToMatchGrid( gf[mNew].cg );
650 
651  checkArrayIDs(sPrintF(" METHOD : after updateForMovingGrids t=%9.3e",gf[mCur].t));
652 
653  if( debug() & 16 )
654  {
655  if( twilightZoneFlow() )
656  {
657  fprintf(debugFile,"\n ---> METHOD: Errors in u after updateForMovingGrids t=%e \n",gf[mCur].t);
658  determineErrors( gf[mCur] );
659  }
660  }
661 
662  // get values for exposed points on gf[mCur]
663  if( parameters.useConservativeVariables() )
664  gf[mCur].primitiveToConservative(); // *wdh* 010318
665 
666  cpu0=getCPU();
667  if( useNewExposedPoints && parameters.dbase.get<int>("simulateGridMotion")==0 )
668  {
670  checkSolution(gf[mCur].u,"Before interp exposed points",true);
671 
672  if( debug() & 16 )
673  {
674  if( twilightZoneFlow() )
675  {
676  fprintf(debugFile,"\n ---> METHOD: Errors in u BEFORE interp exposed t=%e \n",gf[mCur].t);
677  determineErrors( gf[mCur] );
678  }
679  }
680 
681 
682  // parameters.dbase.get<int >("stencilWidthForExposedPoints")=5; // ****************** TEMP *****
683 
684 
685  ExposedPoints exposedPoints;
686  exposedPoints.setAssumeInterpolationNeighboursAreAssigned(parameters.dbase.get<int >("extrapolateInterpolationNeighbours"));
687  exposedPoints.initialize(gf[mCur].cg,gf[mNew].cg,parameters.dbase.get<int >("stencilWidthForExposedPoints"));
688  exposedPoints.interpolate(gf[mCur].u,(twilightZoneFlow() ? parameters.dbase.get<OGFunction* >("exactSolution") : NULL),t0);
689 
690  if( debug() & 16 )
691  {
692  if( twilightZoneFlow() )
693  {
694  fprintf(debugFile,"\n ---> METHOD: Errors in u AFTER interp exposed t=%e \n",gf[mCur].t);
695  determineErrors( gf[mCur] );
696  }
697  }
698 
699  if( predictorOrder==0 )
700  {
701  OV_ABORT("METHOD: moveTheGrids: ERROR: predictorOrder=0");
702  }
703 
704  if( predictorOrder>=2 )
705  {
706  // -------------------------
707  // --- fixup du/dt(t-dt) ---
708  // -------------------------
709 
710  // NOTE: we CANNOT directly interpolate points on du/dt since for moving grids
711  // du/dt includes the -gDot.grad(u) term
712 
713  // Current procedure:
714  // 1. Interpolate exposed points on u(t-dt)
715  // 2. Recompute du/dt(t-dt)
716 
717  // Optimizations:
718  // - only recompute du/dt(t-dt) on grids with exposed points
719  // - could only compute du/dt(t-dt) on those points where is not already known.
720 
721  if( gf[mCur].t<=0. || debug() & 4 )
722  {
723  printF(" --- INFO: Fixup exposed points of u(t-dt) and recompute du/dt(t-dt) t=%9.3e, tb=%9.3e ----- \n"
724  " The extra work involved in recomputing du/dt(t-dt) can be avoided by using "
725  "the option 'first order predictor'.\n",gf[mCur].t,tb);
726  }
727 
728  ExposedPoints exposedPoints;
729 
730  //
731  // exposedPoints.setExposedPointType(ExposedPoints::exposedDiscretization);
732 
733  exposedPoints.setAssumeInterpolationNeighboursAreAssigned(parameters.dbase.get<int >("extrapolateInterpolationNeighbours"));
734 
735  exposedPoints.initialize(gf[mOld].cg,gf[mNew].cg,parameters.dbase.get<int >("stencilWidthForExposedPoints"));
736  exposedPoints.interpolate(gf[mOld].u,(twilightZoneFlow() ? parameters.dbase.get<OGFunction* >("exactSolution") : NULL),gf[mOld].t);
737 
738  // For now recompute du/dt(t-dt) using the mask values from cg(t+dt)
739  for( grid=0; grid<gf[mOld].cg.numberOfComponentGrids(); grid++ )
740  {
741 
742  if( gridWasAdapted || exposedPoints.getNumberOfExposedPoints(grid)>0 )
743  {
744  if( debug() & 2 )
745  printf(" ---- METHOD: recompute du/dt(t-dt) for grid=%i t-dt = %9.3e (%i exposed)-----\n",grid,gf[mOld].t,
746  exposedPoints.getNumberOfExposedPoints(grid));
747 
748  // This is only necesssary if there are exposed points on this grid
749  rparam[0]=gf[mOld].t;
750  rparam[1]=gf[mOld].t;
751  rparam[2]=gf[mCur].t; // tImplicit
752  iparam[0]=grid;
753  iparam[1]=gf[mOld].cg.refinementLevelNumber(grid);
754  iparam[2]=numberOfStepsTaken;
755 
756  getUt(gf[mOld].u[grid],gf[mOld].getGridVelocity(grid),ub[grid],iparam,rparam,
757  utImplicit[grid],&gf[mNew].cg[grid]);
758 
759  }
760  }
761  if( debug() & 4 )
762  {
763  if( twilightZoneFlow() )
764  {
765  fprintf(debugFile," ***METHOD: gf[mOld] after interp exposed, gf[mOld].t=%e",gf[mOld].t);
766  for( grid=0; grid<gf[mOld].cg.numberOfComponentGrids(); grid++ )
767  {
768  display(gf[mOld].u[grid],sPrintF("\n ****gf[mOld].u[grid=%i]",grid),debugFile,"%7.1e ");
769  }
770  determineErrors( gf[mOld] );
771 
772  fprintf(debugFile," ***METHOD: du/dt(t-dt) after interp exposed, gf[mOld].t=%e",gf[mOld].t);
773  for( grid=0; grid<gf[mOld].cg.numberOfComponentGrids(); grid++ )
774  {
775  display(ub[grid],sPrintF("\n ****ub[grid=%i]: du/dt(t-dt)",grid),debugFile,"%7.1e ");
776  }
777  determineErrors( ub,gf[mOld].gridVelocity, gf[mOld].t, 1, error );
778  }
779  }
780 
781 
782  if( predictorOrder>=3 )
783  {
784  OV_ABORT("METHOD: moveTheGridsMacro:Error: finish me for predictorOrder>=3");
785  }
786 
787  } // end if predictorOrder>=2
788 
790  checkSolution(gf[mCur].u,"METHOD: After interp exposed points",true);
791 
792  }
793  else if( parameters.dbase.get<int>("simulateGridMotion")==0 )
794  {
795  // *old way*
796  interpolateExposedPoints(gf[mCur].cg,gf[mNew].cg,gf[mCur].u,
797  (twilightZoneFlow() ? parameters.dbase.get<OGFunction* >("exactSolution") : NULL),t0,
798  false,Overture::nullIntArray(),Overture::nullIntegerDistributedArray(),
799  parameters.dbase.get<int >("stencilWidthForExposedPoints") );
800  }
801 
802 
803  if( twilightZoneFlow() && false ) // **** wdh ****
804  {
805  // for testing ***
806  OGFunction & e = *(parameters.dbase.get<OGFunction* >("exactSolution"));
807 
808  int grid=0;
809  MappedGrid & c = gf[mNew].cg[grid];
810  getIndex(c.dimension(),I1,I2,I3);
811 
812  ub[grid](I1,I2,I3,N)=e.t(c,I1,I2,I3,N,t0-dt0);
813 
814  }
815 
816 
817 
818  parameters.dbase.get<RealArray>("timing")(parameters.dbase.get<int>("timeForInterpolateExposedPoints"))+=getCPU()-cpu0;
819  // compute dudt now -- after exposed points have been computed!
820 
821  checkArrayIDs(sPrintF(" METHOD : after moving grids update t=%9.3e",gf[mCur].t));
822 
823 
824  if( debug() & 16 )
825  {
826  if( twilightZoneFlow() )
827  {
828  fprintf(debugFile,"\n ---> METHOD: Errors in u after move grids t=%e \n",gf[mCur].t);
829  determineErrors( gf[mCur] );
830  }
831  }
832 
833  if( debug() & 16 )
834  printf(" METHOD: AFTER moveTheGridsMacro: t0=%9.3e, gf[mNew].t=%9.3e, gf[mNew].gridVelocityTime=%9.3e\n",
835  t0,gf[mNew].t,gf[mNew].gridVelocityTime);
836 }
837 
838 
839 #endMacro