HARM
harm and utilities
 All Data Structures Files Functions Variables Typedefs Macros Pages
initbase.c
Go to the documentation of this file.
1 
2 
16 #include "decs.h"
17 
18 
21 int init(int *argc, char **argv[])
22 {
23  extern int prepre_init(void);
24  extern int pre_init(int *argc, char **argv[]);
25  extern int init_defdefcoord(void);
26  extern int init_defgrid(void);
27  extern int init_defglobal(void);
28  extern int init_defconsts(void);
29  extern int init_arrays_before_set_pu(void);
30  extern void filterffde(int i, int j, int k, FTYPE *pr);
31  extern void filter_coldgrmhd(int i, int j, int k, FTYPE *pr);
32  void set_grid_all(FTYPE thetarot, int restartmode);
33  //
34  void init_all_conservatives(FTYPE (*prim)[NSTORE2][NSTORE3][NPR],FTYPE (*pstag)[NSTORE2][NSTORE3][NPR], FTYPE (*utemp)[NSTORE2][NSTORE3][NPR], FTYPE (*ucons)[NSTORE2][NSTORE3][NPR]);
35  int i,j,k;
36  int jj;
37  int pl,pliter;
38  int selfgraviter;
39  int gotnan;
40  int faketimeorder,fakenumtimeorders;
41 
42 
43 
44 
45 
46  stderrfprintf("Start init\n"); fflush(stderr);
47 
49  //
50  // Both normal and restart mode need all "pre_init" functions called
51  //
53 
54 
55  if(RESTARTMODE==0 || RESTARTMODE==1){
57  //
58  // prepre_init type functions should not assume anything done yet
59  //
61  prepre_init();
62  prepre_init_specific_init(); // user func
63 
65  //
66  // pre_init type functions initialize MPI and other things
67  //
69  pre_init(argc,argv);
70  pre_init_specific_init(); // user func
71  }
72 
73 
74 
76  //
77  // Always set parameters and coordinates as default in case restart file doesn't have this information. Properly, the restart file will overwrite if file contains those variables.
78  //
80  if(RESTARTMODE==0 || RESTARTMODE==1){
81  // define parameters
82  init_defglobal(); // init default global parameters
83  init_defconsts(); // init default physical constants
84  init_consts(); // init user constants
85  init_global(); // request choices for global parameters
86 
87  init_defdefcoord(); // choose defcoord
88  init_defcoord(); // user choose defcoord
89 
90  set_coord_parms_nodeps(defcoord); // requires only defcoord, no other grid parameters
91 
92  init_defgrid(); // init default grid
93  init_grid(); // request choices for grid/coordinate/metric parameters
94 
95 
96  set_coord_parms_deps(defcoord); // requires correct defcoord at least
97 
98  // MPI setup for core placement and boundary conditions
99  // requires special3dspc, periodicx?, and dofull2pi and other things defining grid type already be set
100  // after the below call, can then call boundary functions and MPI decomposition will be ready
101  init_placeongrid_griddecomposition();
102 
103 
104  // set certain arrays to zero for diagnostic purposes (must come after all basic init stuff that sets up grid parms and all other parms)
106 
107 
108 
109  }
110 
111 
113  //
114  // RESTART MODE
115  //
116  // Loads primitives and conserved quantities.
117  // Always assume conserved quantities are in the file, regardless of whether used. Only used if doing higher-order method
118  //
120  if(RESTARTMODE==1){
121  trifprintf("start restart_init: proc=%04d\n",myid);
122  if (restart_init(WHICHFILE) >= 1) {
123  dualfprintf(fail_file, "main:restart_init: failure\n");
124  return(1);
125  }
126  trifprintf("end restart_init: proc=%04d\n",myid);
127 
128  // don't bound read-in data yet since need grid and other things
129 
130  // if read-in dummy data that had meaningless radiation terms, then call below:
131  // extern int process_restart_toget_radiation(void);
132  // process_restart_toget_radiation();
133 
134  }
135 
136 
137 
138 
140  //
141  // Always write new coordparms file. Fresh start needs it, but also do in case user updated restart file but not coord file
142  // Default file name: coordparms.dat
143  //
145  if(RESTARTMODE==0 || RESTARTMODE==1){
146  write_coord_parms(defcoord); // output coordinate parameters to file
147  }
148 
149 
150 
152  //
153  // Both normal and restart mode need to setup grid
154  //
156  if(RESTARTMODE==0 || RESTARTMODE==1){
157  set_grid_all(THETAROTPRIMITIVES,RESTARTMODE); // use THETAROT=THETAROTPRIMITIVES
158  }
159 
160 
161 
162 
163 
164 
165 
167  //
168  // Normal fresh start need to get primitive and conserved quantities
169  //
171  if(RESTARTMODE==0){
172 
173 
174 #if(DOSELFGRAVVSR)
175 #define NUMSELFGRAVITER 3 // MINIMUM of 2 iterations should be done for metric to computed once
176  // further iterations will determine PRIMECOORD velocity and magnetic field using newly updated metric
177  // 3 iterations allows this new metric to be used once, and I suggest this as good minimum # of iterations
178 #else
179 #define NUMSELFGRAVITER 1 // NO CHOICE
180 #endif
181 
182 
183 
184  // iterations to get consistent/converged initial conditions
185  // assume user chooses primitive in final-to-be-metric so first primitive is correct final primitive
186  // conservatives adjusted with adjusting metric
187  for(selfgraviter=1;selfgraviter<=NUMSELFGRAVITER;selfgraviter++){
188 
189 
190  trifprintf("begin iteration over metric: selfgraviter=%d\n",selfgraviter);
191 
192 
193  if(selfgraviter>1){
194  if(DOSELFGRAVVSR){
195  trifprintf("new metric with self-gravity: selfgraviter=%d\n",selfgraviter);
196  // if box_grid needs to change, is done inside below function
197  compute_new_metric_and_prims(0,MBH, a, QBH, EP3, THETAROT, GLOBALPOINT(pglobal),GLOBALPOINT(pstagglobal),GLOBALPOINT(unewglobal),GLOBALPOINT(vpotarrayglobal),GLOBALPOINT(Bhatglobal),GLOBALPOINT(gp_l),GLOBALPOINT(gp_r),GLOBALPOINT(F1),GLOBALPOINT(F2),GLOBALPOINT(F3),GLOBALPOINT(emf),GLOBALPOINT(ulastglobal));
198  trifprintf("done with computing new metric with self-gravity dt=%21.15g selfgraviter=%d\n",dt,selfgraviter);
199  }
200  }
201 
202 
203 
204 
205 
206  // user function that should fill p with primitives
207  // assumes everyting computed by: compute_EOS_parms() is known by init_primitives without immediate reference to what's computed by compute_EOS_parms since this function depends upon primitives themselves
208  MYFUN(init_primitives(GLOBALPOINT(pglobal),GLOBALPOINT(pstagglobal),GLOBALPOINT(unewglobal),GLOBALPOINT(vpotarrayglobal),GLOBALPOINT(Bhatglobal),GLOBALPOINT(panalytic),GLOBALPOINT(pstaganalytic),GLOBALPOINT(vpotanalytic),GLOBALPOINT(Bhatanalytic),GLOBALPOINT(F1),GLOBALPOINT(F2),GLOBALPOINT(F3),GLOBALPOINT(emf)),"initbase.c:init()", "init_primitives()", 0);
209 
210 
211 
212 
213  // dump analytic solution
214  //GLOBALPOINT(pdump)=GLOBALPOINT(panalytic);
215  //if (dump(-9999) >= 1){
216  // dualfprintf(fail_file,"unable to print dump file\n");
217  // return (1);
218  //}
219 
220 
221  // assign memory for dumping primitives
222  GLOBALPOINT(pdump)=GLOBALPOINT(pglobal);
223 
224 
225 
226  // COMPLOOPF{
227  // MACP0A1(p,i,j,k,UU)=0.0;
228  // }
229 
230  // mandatory filters on user supplied primitives
231 
233  //
234  // Filter to get correct degenerate FFDE solution
235  //
237 
239  trifprintf("System filtered to FFDE\n");
240  // filter to get force-free
241  COMPFULLLOOP{
242  filterffde(i,j,k,GLOBALMAC(pglobal,i,j,k));
243  }
244  }
245 
246  if(EOMTYPE==EOMCOLDGRMHD){
247  trifprintf("System filtered to cold GRMHD\n");
248  // filter to get cold GRMHD
249  COMPFULLLOOP{
250  filter_coldgrmhd(i,j,k,GLOBALMAC(pglobal,i,j,k));
251  }
252  }
253 
254 
256  //
257  // Fixup and Bound variables since field may have changed
258  // Also setup pre_fixup() type quantities
259  //
261 
262  trifprintf("System Fixup and Bound\n");
263 
264 
265  if(pre_fixup(STAGEM1,GLOBALPOINT(pglobal))>=1) FAILSTATEMENT("initbase.c:init()", "pre_fixup()", 1);
266 
267 
268 #if(FIXUPAFTERINIT)
269  if(fixup(STAGEM1,GLOBALPOINT(pglobal),GLOBALPOINT(unewglobal),0)>=1)
270  FAILSTATEMENT("initbase.c:init()", "fixup()", 1);
271 #endif
272 
273 
274  {
275  int finalstep=1; // assume user wants to know if initial conserved quants changed
276  // in case pflag failure of utoprim call was hit during init, and user didn't do anything about it, then need to fixup now.
277  MYFUN(post_fixup(STAGEM1,finalstep, t, GLOBALPOINT(pglobal),GLOBALPOINT(pglobal),GLOBALPOINT(unewglobal)),"initbase.c:init()", "post_fixup()", 1);
278  }
279 
280 
281  {
282  int finalstep=1; // assume user wants to know if initial conserved quants changed
283  if (bound_allprim(STAGEM1,finalstep,t,GLOBALPOINT(pglobal),GLOBALPOINT(pstagglobal),GLOBALPOINT(unewglobal), USEMPI) >= 1)
284  FAILSTATEMENT("initbase.c:init()", "bound_allprim()", 1);
285  }
286 
287 
288  // now fully bounded, initialize interpolations in case interpolate using prim/pstag data
289  pre_interpolate_and_advance(GLOBALPOINT(pglobal));
290 
291 
292 
293 
294  if(DODIAGS && PRODUCTION==0){
296  // BEGIN DEBUG
297  // dump solution so far
298  if(selfgraviter==1){
299  GLOBALPOINT(pdump)=GLOBALPOINT(pglobal);
300  if (dump(9000) >= 1){
301  dualfprintf(fail_file,"unable to print dump file\n");
302  return (1);
303  }
304  }
305  else if(selfgraviter==2){
306  GLOBALPOINT(pdump)=GLOBALPOINT(pglobal);
307  if (dump(9001) >= 1){
308  dualfprintf(fail_file,"unable to print dump file\n");
309  return (1);
310  }
311  }
312  else if(selfgraviter==3){
313  GLOBALPOINT(pdump)=GLOBALPOINT(pglobal);
314  if (dump(9002) >= 1){
315  dualfprintf(fail_file,"unable to print dump file\n");
316  return (1);
317  }
318  }
319  // END DEBUG
321  }// end if doing diagnostics and production==0
322 
323 
324 
325  // after all parameters and primitives are set, then can set these items
326  post_init(GLOBALPOINT(pglobal),GLOBALPOINT(cfaraday));
327  // user post_init function
329 
330  // get all conserved quantities (volume averaged or otherwise)
331  init_all_conservatives(GLOBALPOINT(pglobal),GLOBALPOINT(pstagglobal),GLOBALPOINT(ulastglobal),GLOBALPOINT(unewglobal));
332 
333 
334  if(DODIAGS && PRODUCTION==0){
336  // BEGIN DEBUG
337  // dump solution so far
338  if(selfgraviter==1){
339  GLOBALPOINT(pdump)=GLOBALPOINT(pglobal);
340  if (dump(9100) >= 1){
341  dualfprintf(fail_file,"unable to print dump file\n");
342  return (1);
343  }
344  }
345  else if(selfgraviter==2){
346  GLOBALPOINT(pdump)=GLOBALPOINT(pglobal);
347  if (dump(9101) >= 1){
348  dualfprintf(fail_file,"unable to print dump file\n");
349  return (1);
350  }
351  }
352  else if(selfgraviter==3){
353  GLOBALPOINT(pdump)=GLOBALPOINT(pglobal);
354  if (dump(9102) >= 1){
355  dualfprintf(fail_file,"unable to print dump file\n");
356  return (1);
357  }
358  }
359  // END DEBUG
361  }
362 
363  trifprintf("end iteration over metric: selfgraviter=%d\n",selfgraviter);
364 
365  }// end loop to get metric and primitive setting consistent
366 
367 
368 
369 
370 
371  }// end if RESTARTMODE==0
373  //
374  // Restart and get primitive and conserved quantities
375  //
377  else if(RESTARTMODE==1){
378 
379 
380  // more restart checks
381  restart_init_simple_checks(2);
382 
383 
384 #if(FIXUPAFTERINIT)
385  trifprintf("before pre_fixup() during restart: proc=%04d\n",myid);
386  if(pre_fixup(STAGEM1,GLOBALPOINT(pglobal))>=1) FAILSTATEMENT("initbase.c:init()", "pre_fixup()", 1);
387  trifprintf("after pre_fixup() during restart: proc=%04d\n",myid);
388 
389 
390  trifprintf("before fixup() during restart: proc=%04d\n",myid);
391  if(fixup(STAGEM1,GLOBALPOINT(pglobal),GLOBALPOINT(unewglobal),0)>=1) FAILSTATEMENT("initbase.c:init()", "fixup()", 1);
392  trifprintf("after fixup() during restart: proc=%04d\n",myid);
393 
394 
395  // DEBUG: in case restart and need to fix-up things
396  //void debugfixup(void);
397  // debugfixup();
398 
399 
400  {
401  int finalstep=1; // assume user wants to know if initial conserved quants changed
402  // in case pflag failure of utoprim call was hit during init, and user didn't do anything about it, then need to fixup now.
403  MYFUN(post_fixup(STAGEM1,finalstep, t, GLOBALPOINT(pglobal),GLOBALPOINT(pglobal),GLOBALPOINT(unewglobal)),"initbase.c:init()", "post_fixup()", 1);
404  }
405 #endif
406 
407  trifprintf("before bound_prim() during restart: proc=%04d\n",myid);
408 
409  {
410  // pstag not computed from unewglobal yet, so don't bound it. It'll get self-consistently bounded when ucons2upointppoint() is called below
411  int finalstep=1; // assume user wants to know if initial conserved quants changed
412  if (bound_prim(STAGEM1,finalstep,t,GLOBALPOINT(pglobal),GLOBALPOINT(pstagglobal),GLOBALPOINT(unewglobal), USEMPI) >= 1) FAILSTATEMENT("initbase.c:init()", "bound_allprim()", 1);
413  }
414 
415  trifprintf("after bound_prim() during restart: proc=%04d\n",myid);
416 
417  // more restart checks
418  restart_init_simple_checks(3);
419 
420 
421  // before can interpolate inside ucons2upointppoint(), need to compute things needed by interpolation, including for STORESHOCKINDICATOR==1
422  if(STORESHOCKINDICATOR==1){
423  pre_interpolate_and_advance(GLOBALPOINT(pglobal));
424  }
425 
426 
428  //
429  // Note there is no need to convert average or quasi-deaveraged field to staggered field (see comments in ucons2upointppoint())
430  // However, divb diagnostics at first won't be right at t=0 since set to use primitive for lower-order method, but just assume diagnostic won't likely be immediately after restart
431  // For RESTARTMODE==0 the pstag quantity is set by user or during vector potential conversion to u and p, but during restart we only read-in p and unew while we need also pstagscratch
432  // so after ucons2upointppoint() call, pcent as in boundaries will not be updated but not required. And it will not be Nan since did bound above.
433  //
435  trifprintf("before ucons2upointppoint during restart: proc=%04d\n",myid);
436  ucons2upointppoint(t, GLOBALPOINT(pglobal),GLOBALPOINT(pstagglobal),GLOBALPOINT(unewglobal),GLOBALPOINT(ulastglobal),GLOBALPOINT(pglobal)); // this regenerates pcentered for B1,B2,B3
437  trifprintf("after ucons2upointppoint during restart: proc=%04d\n",myid);
438 
439 
440  // now bound unewglobal and vpot's
441  if(FLUXB==FLUXCTSTAG){
442  int boundvartype=BOUNDPRIMTYPE;
443  int finalstep=1; // assume user wants to know if initial conserved quants changed
444  int doboundmpi=1;
445  bound_anypstag(STAGEM1, finalstep, t, boundvartype, GLOBALPOINT(unewglobal), GLOBALPOINT(unewglobal), GLOBALPOINT(unewglobal), doboundmpi);
446  }
448  int boundvartype=BOUNDVPOTTYPE;
449  int finalstep=1; // assume user wants to know if initial conserved quants changed
450  int doboundmpi=1;
451  int doboundnonmpi=1;
452  bound_vpot(STAGEM1, finalstep, t, boundvartype, GLOBALPOINT(vpotarrayglobal),doboundmpi,doboundnonmpi);
453  }
454 
455 
456  // more restart checks
457  restart_init_simple_checks(4);
458 
459 
460  // after all parameters and primitives are set, then can set these items
461  trifprintf("before post_init and post_init_specific_init during restart: proc=%04d\n",myid);
462  post_init(GLOBALPOINT(pglobal),GLOBALPOINT(cfaraday));
463  // user post_init function
465  trifprintf("after post_init and post_init_specific_init during restart: proc=%04d\n",myid);
466 
467 
468  // more restart checks
469  restart_init_simple_checks(5);
470 
471 
472  // don't want conservatives or primitives to change, just compute metric
473  if(DOSELFGRAVVSR){
474  trifprintf("new metric with self-gravity\n");
475  compute_new_metric_and_prims(0,MBH, a, QBH, EP3, THETAROT, GLOBALPOINT(pglobal),GLOBALPOINT(pstagglobal),GLOBALPOINT(unewglobal),GLOBALPOINT(vpotarrayglobal),GLOBALPOINT(Bhatglobal),GLOBALPOINT(gp_l),GLOBALPOINT(gp_r),GLOBALPOINT(F1),GLOBALPOINT(F2),GLOBALPOINT(F3),GLOBALPOINT(emf),GLOBALPOINT(ulastglobal));
476  trifprintf("done with computing new metric with self-gravity dt=%21.15g\n",dt);
477  }
478 
479 
480  trifprintf("before restart_init_checks() during restart: proc=%04d\n",myid);
481  if (restart_init_checks(WHICHFILE, GLOBALPOINT(pglobal), GLOBALPOINT(pstagglobal), GLOBALPOINT(unewglobal)) >= 1) {
482  dualfprintf(fail_file, "main:restart_init_checks: failure\n");
483  return(1);
484  }
485  trifprintf("after restart_init_checks() during restart: proc=%04d\n",myid);
486 
487 
488  trifprintf( "proc: %d restart completed: failed=%d\n", myid, failed);
489 
490 
491 
492  }// done if RESTARTMODE==1
493 
494 
495 
496  if(THETAROTMETRIC!=THETAROTPRIMITIVES){ // Deal with initial tilt
497  // SUPERGODMARK: After changing metric, should really also do after below:
498  // 1) A_i or U -> Bstag for stag method *or* A_i -> B for Toth
499  // 2) Bstag -> B for stag method
500  // 3) Bstag,U -> Bhat for stag higher order method
501  // etc.
502  //
503  // Otherwise, gdet changes and t=0 Bstag and B won't be consistent with A_i and U for the new metric.
504 
505 
507  //
508  // Both normal and restart mode need to setup grid
509  //
511  if(RESTARTMODE==0 || RESTARTMODE==1){
512  set_grid_all(THETAROTMETRIC,RESTARTMODE); // now use THETAROT=THETAROTMETRIC
513  }
514 
515  }
516 
517 
519  //
520  // Final things done whether fresh run or restart run
521  //
523 #if(ANALYTICMEMORY)
524  // copy over initial solution as analytic solution
525  // NEEDED FOR BOUND in case uses panalytic
526  // Should be done before any changes in grid due to grid sectioning so that analytic variables set over all grid rather than limited range. Then expansion of grid uses those analytical values.
527  copy_prim2panalytic(GLOBALPOINT(pglobal),GLOBALPOINT(panalytic),GLOBALPOINT(pstagglobal),GLOBALPOINT(pstaganalytic),GLOBALPOINT(vpotarrayglobal),GLOBALPOINT(vpotanalytic),GLOBALPOINT(Bhatglobal),GLOBALPOINT(Bhatanalytic));
528 #endif
529 
530 
531  // redo grid positions using actual gridding (not full grid just because was doing inits before)
532  faketimeorder=1;
533  fakenumtimeorders=2;
534  recompute_fluxpositions(3,faketimeorder,fakenumtimeorders,nstep,t);
535 
536 
537  // must set dt after DOSELFGRAVVSR so have acceleration in case v=0 and c_s=0 initially
538  // set initial dt correctly rather than random choice
539  // actually compute_new_metric_and_prims() computes dt from set_dt()
540  MYFUN(set_dt(GLOBALPOINT(pglobal),&dt),"initbase.c:init()","set_dt()",1);
541  trifprintf("dt=%21.15g at t=%21.15g at nstep=%ld at realnstep=%ld\n",dt,t,nstep,realnstep);
542 
543 
544 
545 
547  //
548  // Some final diagnostics
549  //
551 
552 
553 #if(PRODUCTION==0)
554  // SUPERGODMARK: Should only be done for RESTARTMODE==1?
555  // final checks
556  restart_init_simple_checks(6);
557 
558 #endif
559 
560 
561 
562 
563  trifprintf("end init.c\n");
564  return (0);
565 
566 }
567 
568 
569 
570 // wrapper to do repeated set_grid when involving tilt
571 void set_grid_all(FTYPE thetarot, int restartmode)
572 {
573  int set_box_grid_parameters(void);
574  extern int post_par_set(void);
575 
576 
577  // sets global THETAROT
578  THETAROT = thetarot; // No, if restarting, then no need since not actually calling init_primitives // set so init rho,u,v,B are as if no rotation
579 
580  // once all interpolation parameters are set, now can set dependent items that may be used to set primitives or conservatives
581  // doesn't use metric parameters, so doesn't need to be in SELFGRAV loop
582  post_par_set();
583 
584  if(restartmode==1) trifprintf("proc: %d post_par_set completed: failed=%d\n", myid,failed);
585 
586  // get grid
587  // 0 tells set_grid that it's first call to set_grid() and so have to assume stationarity of the metric since have no time information yet
588  set_grid(0,0,0);
589 
590  if(restartmode==1) trifprintf("proc: %d grid restart completed: failed=%d\n", myid,failed);
591 
592  // set grid boundary parameters that uses metric parameters to determine loop ranges using enerregions and enerpos
594 
595  if(restartmode==1) trifprintf("proc: %d set_box_grid_parameters completed: failed=%d\n", myid,failed);
596 
597  // user post_set_grid function
598  init_grid_post_set_grid(GLOBALPOINT(pglobal),GLOBALPOINT(pstagglobal),GLOBALPOINT(unewglobal),GLOBALPOINT(vpotarrayglobal),GLOBALPOINT(Bhatglobal),GLOBALPOINT(panalytic),GLOBALPOINT(pstaganalytic),GLOBALPOINT(vpotanalytic),GLOBALPOINT(Bhatanalytic),GLOBALPOINT(F1),GLOBALPOINT(F2),GLOBALPOINT(F3),GLOBALPOINT(emf));
599 
600  if(restartmode==1) trifprintf("proc: %d init_grid_post_set_grid completed: failed=%d\n", myid,failed);
601 
602 
603  trifprintf("MCOORD=%d\n",MCOORD);
604  trifprintf("COMPDIM=%d\n",COMPDIM);
605  trifprintf("MAXBND=%d\n",MAXBND);
606  trifprintf("FLUXB=%d\n",FLUXB);
607 
608 }
609 
610 
611 
613 int copy_prim2panalytic(FTYPE (*prim)[NSTORE2][NSTORE3][NPR],FTYPE (*panalytic)[NSTORE2][NSTORE3][NPR],FTYPE (*pstag)[NSTORE2][NSTORE3][NPR],FTYPE (*pstaganalytic)[NSTORE2][NSTORE3][NPR], FTYPE (*vpot)[NSTORE1+SHIFTSTORE1][NSTORE2+SHIFTSTORE2][NSTORE3+SHIFTSTORE3], FTYPE (*vpotanalytic)[NSTORE1+SHIFTSTORE1][NSTORE2+SHIFTSTORE2][NSTORE3+SHIFTSTORE3], FTYPE (*Bhat)[NSTORE2][NSTORE3][NPR], FTYPE (*Bhatanalytic)[NSTORE2][NSTORE3][NPR])
614 {
615 
616 #if(ANALYTICMEMORY==0)
617  dualfprintf(fail_file,"Shouldn't be setting analytic with ANALYTICMEMORY==0\n");
618  myexit(ERRORCODEBELOWCLEANFINISH+35968346);
619 #endif
620 
621 
622 #pragma omp parallel
623  {
624  int i,j,k;
625  int pl,pliter;
626  int jj;
627 
629 
631 #pragma omp for schedule(OPENMPSCHEDULE(),OPENMPCHUNKSIZE(blocksize)) nowait // next vpot assignment does not depend upon this loop completing
633  OPENMP3DLOOPBLOCK2IJK(i,j,k);
635 
636  PLOOP(pliter,pl) MACP0A1(panalytic,i,j,k,pl)=MACP0A1(prim,i,j,k,pl);
637  if(FIELDSTAGMEM){
638  PLOOP(pliter,pl) MACP0A1(pstaganalytic,i,j,k,pl)=MACP0A1(pstag,i,j,k,pl);
639  }
640  if(HIGHERORDERMEM){
641  PLOOP(pliter,pl) MACP0A1(Bhatanalytic,i,j,k,pl)=MACP0A1(Bhat,i,j,k,pl);
642  }
643 
644  }
645 
646  if(TRACKVPOT){
649 #pragma omp for schedule(OPENMPSCHEDULE(),OPENMPCHUNKSIZE(blocksize)) nowait // next vpot assignment is independent
651  OPENMP3DLOOPBLOCK2IJK(i,j,k);
652 
653  DLOOPA(jj) MACP1A0(vpotanalytic,jj,i,j,k)=MACP1A0(vpot,jj,i,j,k);
654  }
655  }
656 
657  }// end parallel region (and implied barrier)
658 
659 
660  return(0);
661 }
662 
663 
666 void init_all_conservatives(FTYPE (*prim)[NSTORE2][NSTORE3][NPR], FTYPE (*pstag)[NSTORE2][NSTORE3][NPR], FTYPE (*utemp)[NSTORE2][NSTORE3][NPR], FTYPE (*ucons)[NSTORE2][NSTORE3][NPR])
667 {
668  int pl,pliter;
669  // below is user function that usually uses system function
670  extern int init_conservatives(FTYPE (*p)[NSTORE2][NSTORE3][NPR], FTYPE (*pstag)[NSTORE2][NSTORE3][NPR], FTYPE (*Utemp)[NSTORE2][NSTORE3][NPR], FTYPE (*U)[NSTORE2][NSTORE3][NPR]);
671 
672 
673  init_conservatives(prim, pstag, utemp, ucons);
674 
675  // bound_uavg(STAGEM1,ucons); DEBUG DEBUG
676 
677 }
678 
679 
680 
681 #include "initbase.defaultnprlists.c"
682 
684 int prepre_init(void)
685 {
686  int pl,pliter;
687 
688 
690 
691  NUMEPSILONPOW23=pow(NUMEPSILON,2.0/3.0);
692 
693  rancvaln=0; // for ranc.c
694 
695  // things initialized whether restarting or init fresh
696 
697  ranc(1,0); // power up random number generator in case used without init
698 
699 
700  // set default performance parameters
701  set_defaults_performance_checks_prepreinit();
702 
703 
704  // set file version numbers
705  set_file_versionnumbers();
706 
707 
709  //
710  // Setup Loop ranges for primitive/conserved/interpolated variables
711  //
713 
714  set_default_nprlists();
715 
716 
717  // setup NOGDET list
718  // defaults
719  PALLLOOP(pl) nogdetlist[pl]=NOGDETRHO;
720  // details
729  if(EOMRADTYPE!=EOMRADNONE){
730  nogdetlist[URAD0] =NOGDETURAD0;
731  nogdetlist[URAD1] =NOGDETURAD1;
732  nogdetlist[URAD2] =NOGDETURAD2;
733  nogdetlist[URAD3] =NOGDETURAD3;
734  }
735  if(DOENTROPY) nogdetlist[ENTROPY] =NOGDETENTROPY;
736  if(YFL1>=0) nogdetlist[YFL1] =NOGDETYFL1;
737  if(YFL2>=0) nogdetlist[YFL2] =NOGDETYFL2;
738  if(YFL3>=0) nogdetlist[YFL3] =NOGDETYFL3;
739  if(YFL4>=0) nogdetlist[YFL4] =NOGDETYFL4;
740  if(YFL5>=0) nogdetlist[YFL5] =NOGDETYFL5;
741  if(YL>=0) nogdetlist[YL] =NOGDETYL;
742  if(YNU>=0) nogdetlist[YNU] =NOGDETYNU;
743 
744 
745 
746 
747  advancepassnumber=-1; // by default assume all things done (should only matter if SPLITNPR==1 and debugging it)
748 
749  // still need to avoid conserved+flux calculations for other PL's in phys.c
750 
751 
752  // below 2 now determined at command line. See init_MPI_GRMHD() in init_mpi.c (myargs and init_MPI).
753  // RESTARTMODE=0;// whether restarting from rdump or not (0=no, 1=yes)
754  //WHICHFILE=0; // see diag.c for dump_cnt and image_cnt starts
755  // user defined parameter
756  restartonfail=0; // whether we are restarting on failure or not and want special diagnostics
757  specialstep=0; // normal step assumed
758  didstorepositiondata=0; // assume haven't stored position data (yet)
759  horizoni=-200;
760  horizoncpupos1=-1;
761 
762  // other global flags
763  failed=0;
765 
766  if(WHICHVEL==VEL3){
767  jonchecks=1; // whether to include jon's checks to make sure u^t real and some rho/u limits throughout code
768  jonchecks=0;
769  }
770  else jonchecks=0; // not relevant
771 
772  // choice// GODMARK: not convenient location, but needed for init_MPI_GRMHD()
773  periodicx1=0;
774  periodicx2=0;
775  periodicx3=0;// GODMARK: periodic in \phi for 3D spherical polar
776  dofull2pi=1;
777 
778  if(USEMPI&&USEROMIO){
779  binaryoutput=MIXEDOUTPUT; // choice: mixed or binary
780  sortedoutput=SORTED; // no choice
781  }
782  else{
783  // choice
784  // binaryoutput=TEXTOUTPUT;
785  binaryoutput=MIXEDOUTPUT; // choice: mixed or binary
787  }
788 
789 
791  //
792  // Initialize global EOS pointers and initial repeated array values (originally static)
793  //
795  initeos_eomtype();
796 
797 
798  return(0);
799 }
800 
801 
803 void set_defaults_performance_checks_prepreinit(void)
804 {
805 
806  // whether to log steps
807  // log the time step as per NDTCCHECK
808  DOLOGSTEP=1 ;
809  // log the performance as per NZCCHECK
810  DOLOGPERF=1;
811 
812  CHECKCONT=1; // 1: check if user wants to continue run 0: don't
813 
814  // initial guess for how often to check time per timestep
815  NTIMECHECK=1000;
816 
817  // how often in steps to output step/dt/t data (controlled by above if above are nonzero, else use below numbers)
818  // MARK 100 100 20 500
819  // MARK 10 10 1 100 for 1024x1024 vortex
820  // MARK 1D bondi: 10000 10000 1000 20000
821  // MARK 2D MHD Tori128128: 500 500 10 1000
822  NDTCCHECK=100;
823  // how often in steps to check speed in zonecycles/sec
824  NZCCHECK=100;
825  NDTDOTCCHECK=10;
826  NGOCHECK=1000; // how often in steps to check the go.go file to see if to continue running
827  NDTPERFDUMPCHECK=1000;
828 
829 
830 }
831 
832 
834 void set_defaults_performance_checks_preinit(void)
835 {
836  // must come after MPI is initialized
837  FTYPE secsperdump;
838 
839  // how often in REAL *seconds* to dump 0_logstep.out file (unless 0, which then uses below)
840  DTstep=10.0;
841  DTstepdot=1.0;
842  DTperf=DTstep;
843  DTgocheck=30.0;
844  DTtimecheck=60.0;
845  // below assumes shared disk space at 20MB/sec access
846  secsperdump=(100.0*8.0*(FTYPE)(totalsize[1]*totalsize[2]*totalsize[3])/(20.0*1024.0*1024.0*1024.0));
847  DTperfdump=3.0*secsperdump; // factor of 3 longer assumed so dumps don't hurt performance
848 
849 
850  // number of wallseconds per perf run(see: main.c)
851  PERFWALLTIME=30.0;
852  // 1 linux cluster cpu
853  // ZCPSESTIMATE (50000)
854  // 25 linux cluster cpu(550Mhz Xeon's connected via Myrinet)
855  // ZCPSESTIMATE (1250000)
856  // 36 linux cluster cpu(550Mhz Xeon's connected via Myrinet)
857  // ZCPSESTIMATE (1800000)
858  // 64 linux cluster cpu(550Mhz Xeon's connected via Myrinet)
859  // ZCPSESTIMATE (3200000)
860  // 121 linux cluster cpu(550Mhz Xeon's connected via Myrinet)
861  // ZCPSESTIMATE (6050000)
862  // photon MHD for one cpu alone
863  // ZCPSESTIMATE (265000)
864  // photon HD 1 cpu
865  // ZCPSESTIMATE (400000)
866  // rainman MHD for one cpu alone
867  // ZCPSESTIMATE (220000)
868  // ZCPSESTIMATE (100000)
869  // sgi r10000 for one cpu alone(195sMhz)
870  // ZCPSESTIMATE (80000)
871  // 4cpu mpigm
872  // ZCPSESTIMATE (800000)
873  // 4cpu r10000
874  // ZCPSESTIMATE (343000)
875  // 9cpu r10000
876  // ZCPSESTIMATE (745000)
877  // 16cpu r10000
878  // ZCPSESTIMATE (1325000)
879  // 25cpu r10000
880  // ZCPSESTIMATE (1200000)
881  // 36cpu r10000
882  // ZCPSESTIMATE (1700000)
883  // 49cpu r10000
884  // ZCPSESTIMATE (4021000)
885  // 64 r10000's 64x64 tile
886  // ZCPSESTIMATE (4309000)
887  // 121 r10000's
888  // ZCPSESTIMATE (10943000)
889  // 256 r10000's
890  // ZCPSESTIMATE (20000000)
891  // kerr 2DMHD
892  // ZCPSESTIMATE (50000)
893  // rainman 2DMHD
894  // ZCPSESTIMATE=(200000);
895 
896  // Latest HARM w/ lim=WENO5BND and FLUXCTSTAG on ki-rh42
897  // ZCPSESTIMATE=(5000);
898 
899  // Latest HARM w/ lim=PARA and FLUXCTSTAG on ki-rh42
900  // ZCPSESTIMATE=(10000);
901  // Latest HARM w/ lim=PARA and FLUXCTSTAG on 1 Orange CPU
902  // ZCPSESTIMATE=(7000);
903 
904  // Latest HARM w/ lim=WENO5BND and FLUXCTTOTH on 1 Orange CPU
905  ZCPSESTIMATE=(3200);
906 
907 
908 }
909 
910 
911 
912 
914 void set_file_versionnumbers(void)
915 {
916 
917  // file versions numbers(use sm for backwards compat)
918  PVER= 11;
919  GRIDVER= 3; // 3 is without cotangent
920  DVER= 1 ; // dumps same as for pdumps, adumps
921  FLVER= 2;
922  NPVER= 2;
923  AVG1DVER= 2;
924  AVG2DVER= 2;
925  ENERVER= 7; // 6 is without c/s mode amp in ener, 7 has new ang mom
926  MODEVER= 2; // 2 is all vars for 9 modes
927  LOSSVER= 7; // 6 has x3 losses, 5 doesn't, 7 has new ang mom losses
928  SPVER= 1;
929  TSVER= 1;
930  LOGDTVER= 1;
931  STEPVER= 1;
932  PERFVER= 3;
933  ADVER= DVER;
934  PDVER= DVER;
935  CALCVER= 1;
936  FLINEVER= 1;
937  // type designations for sm automagical read in correct format for similar things
938  PTYPE= 1; // global par file
939  GRIDTYPE= 2;
940  DTYPE= 3 ;// dump
941  FLTYPE= 4; // floor
942  NPTYPE= 5; // np
943  AVG2DTYPE= 6;
944  AVG1DTYPE= 7;
945  ENERTYPE= 8;
946  LOSSTYPE= 9;
947  SPTYPE= 10;
948  TSTYPE= 11;
949  LOGDTTYPE= 12 ;
950  STEPTYPE= 13;
951  PERFTYPE= 14;
952  ADTYPE= 15 ;// same as dump except filename
953  PDTYPE= 16; // same as dump except filename
954  CALCTYPE= 17; // arbitrary calcs during pp
955  FLINETYPE= 18; // field line during pp
956  MODETYPE= 19;
957  EXPANDTYPE= 50 ;// used to signify doing pp expansion
958  NPCOMPUTETYPE= 33; // used to signify want to compute np before output
959 
960 
961 }
962 
963 
964 
965 
966 
967 
970 void setup_nprlocalist(int whichprimtype, int *nprlocalstart, int *nprlocalend,int *nprlocallist, int *numprims)
971 {
972  int pl,pliter;
973 
974  // setup primitive loops
975  if(whichprimtype==ENOPRIMITIVE){
976  *nprlocalstart=npr2interpstart;
977  *nprlocalend=npr2interpend;
978  PMAXNPRLOOP(pl) nprlocallist[pl]=npr2interplist[pl];
979  *numprims=NPR2INTERP;
980  }
981  else{ // NPR type
982  *nprlocalstart=nprstart;
983  *nprlocalend=nprend;
984  PMAXNPRLOOP(pl) nprlocallist[pl]=nprlist[pl];
985  *numprims=NPR;
986  }
987 
988 }
989 
990 
991 
992 
995 int pre_init(int *argc, char **argv[])
996 {
997  int ii;
998  int dir,pl,pliter,sc,fl,floor,enerregion;
999  int jj;
1000  int tscale;
1001  int dissloop;
1002  int i,j,k;
1003  extern void set_arrays(void);
1004  int checki;
1005  int faketimeorder,fakenumtimeorders;
1006 
1007 
1008 
1009 
1010  // must do in MPI mode or not MPI mode
1011  init_MPI_GRMHD(argc, argv);
1012 
1013  // set default performance parameters
1014  set_defaults_performance_checks_preinit();
1015 
1016 
1017 #if(USEMPI)
1018  mpi_set_arrays();
1019 #endif
1020 
1021 
1022  // check starting go files (must be after init_mpi so all files know)
1023  gocheck(STARTTIME);
1024 
1025 
1026  report_systeminfo(stderr);
1027  if(log_file) report_systeminfo(log_file);
1028  if(myid==0&&logfull_file) report_systeminfo(logfull_file);
1029 
1031  //
1032  // setup files for writing and reading (must come after init_MPI_GRMHD())
1033  //
1034  makedirs();
1035 
1036 
1037  // init arrays
1038  set_arrays();
1039 
1040 
1041  // set default variable to dump (must come before init() where if failed or other reasons can dump output)
1042  GLOBALPOINT(udump) = GLOBALPOINT(unewglobal);
1043  // GLOBALPOINT(ubound) = GLOBALPOINT(unewglobal);
1044  GLOBALPOINT(pdump) = GLOBALPOINT(pglobal);
1045  GLOBALPOINT(pstagdump) = GLOBALPOINT(pstagglobal);
1046  GLOBALPOINT(Bhatdump) = GLOBALPOINT(Bhatglobal);
1047  GLOBALPOINT(vpotarraydump) = GLOBALPOINT(vpotarrayglobal);
1048  GLOBALPOINT(pl_ctdump) = GLOBALPOINT(gp_l);
1049  GLOBALPOINT(pr_ctdump) = GLOBALPOINT(gp_r);
1050 
1051 
1052 
1053 
1054 
1055  init_dumps();
1056 
1057  // compute default enerregion/section information and initialize ENERREGIONLOOP()
1058  // initial call is reason why (1)
1059  faketimeorder=-1;
1060  fakenumtimeorders=-1;
1061  recompute_fluxpositions(1,faketimeorder,fakenumtimeorders,nstep,t);
1062 
1063 
1064 
1065  // must go here b4 restart if restarting
1066  ENERREGIONLOOP(enerregion){
1067  // used for each region, related to global quantities
1068  // no need to initialize _tot quantities, they are overwritten during MPI sum in diag.c
1069  fladd=fladdreg[enerregion];
1070  fladdterms=fladdtermsreg[enerregion];
1071  U_init=Ureg_init[enerregion];
1072  pcum=pcumreg[enerregion];
1073  pdot=pdotreg[enerregion];
1074  pdotterms=pdottermsreg[enerregion];
1075  sourceaddterms=sourceaddtermsreg[enerregion];
1076  sourceadd=sourceaddreg[enerregion];
1077  diss=dissreg[enerregion];
1078 
1079  PLOOP(pliter,pl){
1080  fladd[pl] = 0;
1081  FLOORLOOP(floor) fladdterms[floor][pl]=0;
1082  U_init[pl] = 0;
1083  DIRLOOP(dir){
1084  pcum[dir][pl]=0;
1085  pdot[dir][pl]=0;
1086  FLLOOP(fl) pdotterms[dir][fl][pl]=0;
1087  if(enerregion==0) FLLOOP(fl) pdottermsjet2[dir][fl][pl]=0; // needed for other not-flux cpus!
1088  }
1089  sourceadd[pl] = 0;
1090  SCLOOP(sc) sourceaddterms[sc][pl] = 0;
1091  }
1092  for(dissloop=0;dissloop<NUMDISSVERSIONS;dissloop++) diss[dissloop] = 0;
1093 
1094  if(DOLUMVSR) if(enerregion==0) for(ii=0;ii<ncpux1*N1;ii++) lumvsr[ii]=0;
1095  if(DODISSVSR) if(enerregion==0) for(ii=0;ii<ncpux1*N1;ii++) for(dissloop=0;dissloop<NUMDISSVERSIONS;dissloop++) dissvsr[dissloop][ii]=0;
1096  if(DOSELFGRAVVSR) if(enerregion==0) for(ii=0;ii<ncpux1*N1;ii++) dMvsr[ii]=0;
1097 
1098  // below quantities have been subsumed into own full enerregion
1099  // if(DOEVOLVEMETRIC) if(enerregion==0) PLOOP(pliter,pl){
1100  // horizonflux[pl]=0;
1101  // horizoncum[pl]=0;
1102  // }
1103  }
1104 
1105 
1106 
1107  // start counter
1108  // full loop since user may choose to count something in boundary zones
1109  int indexfinalstep;
1110  if(DODEBUG) FULLLOOP FAILFLOORLOOP(indexfinalstep,tscale,floor) GLOBALMACP0A3(failfloorcount,i,j,k,indexfinalstep,tscale,floor)=0;
1111 
1112  // start du diag_fixup() sum
1113  // full loop since user may choose to count something in boundary zones
1114  if(DOFLOORDIAG){
1115  FULLLOOP{
1116  PALLLOOP(pl) GLOBALMACP0A1(failfloordu,i,j,k,pl)=0.0;
1117  }
1118  }
1119 
1120 #if(CALCFARADAYANDCURRENTS)
1121  // zero out jcon since outer boundaries not set ever since j^\mu involves spatial derivatives that don't exist outside a certain point
1122  for(pl=0;pl<NDIM;pl++) FULLLOOP GLOBALMACP0A1(jcon,i,j,k,pl)=0.0;
1123 #endif
1124 
1125 
1126 
1127 
1128  return(0);
1129 }
1130 
1133 {
1134  // set coordinates
1136 
1137  return(0);
1138 }
1139 
1141 int init_defgrid(void)
1142 {
1143  // sets metric
1144  // a=0.0;
1145  // sets parameters of coordinates, default changes
1146  R0 = 0.0;
1147  Rin = 0.98 * Rhor;
1148  Rout = 40.;
1149  hslope = 0.3;
1150 
1151  // default black hole parameters, and so length is in GMBH/c^2 and time in GMBH/c^3
1152  a=a0;
1153  MBH=MBH0;
1154  QBH=QBH0;
1155  EP3=EP30;
1157  THETAROTPRIMITIVES=0.0; // assume by default is zero
1158 
1159  return(0);
1160 }
1161 
1162 
1165 {
1166  int i;
1167  int pl,pliter;
1168  int dtloop;
1169 
1170 #if(PRODUCTION==0)
1171  debugfail=2; // CHANGINGMARK
1172 #else
1173  debugfail=0; // no messages in production -- assumes all utoprim-like failures need not be debugged
1174 #endif
1175  // whether to show debug into on failures. Desirable to turn off if don't care and just want code to burn away using given hacks/kludges
1176  // 0: no messages
1177  // 1: critical messages
1178  // 2: all failure messages
1179 
1180  // included in rdump
1181  defcon = 1.0;
1182  /* maximum increase in timestep */
1183  SAFE=1.3;
1184  FLUXDISSIPATION=(1.0); // normally full flux dissipation.
1185  EMFDISSIPATION=(1.0); // normally full emf dissipation.
1186  nstep = realnstep = 0;
1187  whichrestart = 0;
1188  restartsteps[0] = 0;
1189  restartsteps[1] = 0;
1191  fakesteps[0] = restartsteps[0];
1192  fakesteps[1] = restartsteps[1];
1193  failed = 0;
1194  cour = 0.5; // see init.tools.c for why >0.5 should *not* be used.
1195  doevolvemetricsubsteps=0; // default is to evolve on long steps (only applicable if DOEVOLVEMETRIC==1 && EVOLVEMETRICSUBSTEP==2)
1196  gravityskipstep=0; // default is no skipping
1197  gravitydtglobal = BIG;
1198  sourcedtglobal = BIG;
1199  wavedtglobal = BIG;
1200 
1201 
1202 
1203  // avgscheme=WENO5BND;
1205 
1207  PALLLOOP(pl) do_source_integration[pl] = 1;
1208  PALLLOOP(pl) do_conserved_integration[pl] = 1;
1209 
1213 
1215  MAX_AC_FRAC_CHANGE = 0.1;
1216 
1217  PARAMODWENO=0;
1218 
1220 
1221 
1222  if(DOEVOLVERHO){
1223  //lim = WENO5FLAT;
1224  //lim = WENO5BND;
1225  // lim = WENO3;
1226  //lim = DONOR;
1227  //lim = MINM;
1228  // lim = PARA;
1229  //lim = MC;
1230  lim[1]=lim[2]=lim[3]=MC;
1231  //lim = PARA;
1232  // lim = PARAFLAT;
1233  //lim = MC;
1234  TIMEORDER=4;
1236  // whether/which ENO used to interpolate fluxes
1238  //DOENOFLUX= NOENOFLUX;
1239  //DOENOFLUX=ENOFLUXRECON;
1240  // PALLLOOP(pl) fluxmethod[pl]=MUSTAFLUX;
1241  //PALLLOOP(pl) fluxmethod[pl]=FORCEFLUX;
1242  PALLLOOP(pl) fluxmethod[pl]=HLLFLUX;
1243  //PALLLOOP(pl) fluxmethod[pl]=HLLLAXF1FLUX;
1244  //PALLLOOP(pl) fluxmethod[pl]=LAXFFLUX;
1245  FLUXB = FLUXCTTOTH;
1246  UTOPRIMVERSION=UTOPRIM5D1; //UTOPRIM2DFINAL;
1247  //UTOPRIMVERSION=UTOPRIM5D2;
1248  // UTOPRIMVERSION=UTOPRIM2DFINAL;
1249  }
1250 
1251 
1253  // PARA and TO=4 and HLL not trustable in FFDE so far
1254  lim[1] = lim[2] = lim[3] = MC;
1255  TIMEORDER=2;
1257  PALLLOOP(pl) fluxmethod[pl]=LAXFFLUX;
1258  FLUXB = FLUXCTTOTH;
1260  // whether/which ENO used to interpolate fluxes
1261  //DOENOFLUX = ENOFINITEVOLUME;
1263  //DOENOFLUX=ENOFLUXRECON;
1264  }
1265 
1266 
1267  t = 0.;
1268  tstepparti = t;
1269  tsteppartf = t;
1270 
1271  tf = 1.0;
1272 
1273  for(dtloop=0;dtloop<NUMDUMPTYPES;dtloop++) DTdumpgen[dtloop]=1.0;
1274  // DTd = DTavg = DTdebug = 1.0;
1275  // DTener=1.0;
1276  // DTi=1.0;
1277  DTr=1;
1278  DTfake=MAX(1,DTr/10);
1279 
1280 
1281 
1282  GAMMIEDUMP=0;// whether in Gammie output types (sets filename with 3 numbers and doesn't output i,j)
1283  GAMMIEIMAGE=0; // Gammie filename and single density output
1284  GAMMIEENER=0; // currently doing gener as well as ener, but this would also output some messages in gammie form
1285 
1286  // DOCOLSPLIT
1287  //
1288  // 0: don't ..
1289  // 1: split dump files into 1 column per file with ending number being column number
1290  // works in MPI-mode as well. ROMIO+DOCOLSPLIT is useful for tungsten with low memory and small files to avoid diskspace and memory limits.
1291 
1292  // default
1293  for(i=0;i<NUMDUMPTYPES;i++){
1294  DOCOLSPLIT[i]=0;
1295  }
1296  // otherwise specify for each dump type
1297 
1298 
1299  DODIAGEVERYSUBSTEP = 0;
1301 
1302 
1303  DODIAGS=1; // whether to do diagnostics
1304  // specify individual diagnostics to be done
1305 
1306  if(PRODUCTION>=2){ // then disable things not really using
1307  DOENERDIAG=0;
1308  // still kinda use images to check if looks reasonable, and already limit images to 1 image file if PRODUCTION==1
1309  }
1310  else{
1311  // ener diag also does debug.out counts that could want even if not dumping debug dump itself that would give spatial information
1312  DOENERDIAG=1;
1313  }
1319 
1320  POSDEFMETRIC=0; // see metric.c, bounds.c, and coord.c
1321 
1322  rescaletype=1;
1323  // 0: normal
1324  // 1: extended b^2/rho in funnel
1325  // 2: conserve E and L along field lines
1326  // 1 or 2 required to conserve E and L along field line
1327 
1329  RHOMIN=1.e-4;
1330  UUMIN =1.e-6;
1331  SPECIFICENTROPYMIN=-sqrt(SMALL); // for ideal gas or other things so Newton steps in inversion and flux calculation for dissipation doesn't go wacky (see notes in utoprim_jon.c under Ss_Wp_utsq() calculation and Ss0 calculation).
1332  // 10* to avoid interaction with use of SMALL when avoiding singular expressions
1333  RHOMINLIMIT=10.0*sqrt(SMALL);
1334  UUMINLIMIT =10.0*sqrt(SMALL); // since u^2 used sometimes
1336 
1337  // limit of B^2/rho if using that flag
1338  BSQORHOLIMIT=1E2;
1339  BSQOULIMIT=1E3;
1340  UORHOLIMIT=1E3;
1341  GAMMADAMP=5.0;
1342 
1343  if(DOEVOLVERHO){
1344  // GODMARK -- unstable beyond about 25, but can sometimes get away with 1000
1345  GAMMAMAX=25.0; // when we think gamma is just too high and may cause unstable flow, but solution is probably accurate.
1346  }
1347  else{
1348  GAMMAMAX=2000.0;
1349  }
1350 
1351  GAMMAMAXRAD=1000.0; // maximum radiation frame lorentz factor
1352  GAMMAMAXRADFAIL=1000.0; // maximum radiation frame lorentz factor
1355 
1356 
1357  GAMMAFAIL=100.0*GAMMAMAX; // when we think gamma is rediculous as to mean failure and solution is not accurate.
1358  prMAX[RHO]=20.0;
1359  prMAX[UU]=20.0;
1360  prMAX[U1]=100.0;
1361  prMAX[U2]=100.0;
1362  prMAX[U3]=100.0;
1363  prMAX[B1]=100.0;
1364  prMAX[B2]=100.0;
1365  prMAX[B3]=100.0;
1366 
1367  // AKMARK: parameter: gam (adiabatic index)
1368  // some physics
1369  gam=4./3.; // ultrarelativistic gas, assumes pgas<prad and radiation
1370  gamideal=gam;
1371  zerouuperbaryon=0.0; // definition of zero-point energy per baryon (i.e. such that internal energy cannot be lower than this times baryon density)
1372 
1373  // doesn't escape
1374  // gam=5/3 for non-relativistic gas, such as neucleons in collapsar model
1376  // cooling: 0: no cooling 1: adhoc thin disk cooling 2: neutrino cooling for collapsar model
1377 
1378  // boundary conditions (default is for 3D spherical polar grid -- full r,pi,2pi)
1379  BCtype[X1UP]=OUTFLOW;
1380  BCtype[X1DN]=OUTFLOW;
1383  BCtype[X3UP]=PERIODIC;
1384  BCtype[X3DN]=PERIODIC;
1385 
1393 
1394 
1395 
1396  // special3dspc assignment must come after dofull2pi and periodicx? are set in prepre_init()
1397  // must come before any use of special3dspc such as by init_placeongrid_griddecomposition()
1398  special3dspc=dofull2pi && N3>1 && IF3DSPCTHENMPITRANSFERATPOLE&&periodicx3&&ISSPCMCOORDNATIVE(MCOORD);
1399  trifprintf("Using %s 3D polar boundary conditions\n", (special3dspc)?("full"):("limited") );
1400 
1401 
1402  return(0);
1403 }
1404 
1405 
1408 {
1409 
1410 
1411  // some constants that define neutrino cooling and spin evolution
1412  // cgs
1413  msun=1.989E33;
1414  lsun=3.89E33;
1415  rsun=695500.0*1E3*1E2;
1416  C=2.99792458E10;
1417  G=6.672E-8;
1418 
1419  // erg K^{-1} g^{-1}
1420  kb=1.3807E-16;
1421  // defs:
1422  C=2.99792458E10;
1423  amu=1.660538782E-24;
1424  qe=4.8032068E-10;
1425  Na=1/amu;
1426  // http://physics.nist.gov/cgi-bin/cuu/Convert?exp=0&num=1&From=ev&To=kg&Action=Convert+value+and+show+factor
1427  ergPmev = 1.782661758E-30*1.0E3*C*C;
1428  //
1429  // http://en.wikipedia.org/wiki/Proton
1430  // http://physics.nist.gov/cgi-bin/cuu/Value?mp
1431  mp=1.672621637E-24;
1432  // NIST:
1433  //me=9.10938188E-28
1434  me=9.10938215E-28;
1435  // http://physics.nist.gov/cgi-bin/cuu/Value?mn|search_for=atomnuc!
1436  mn=1.674927211E-24;
1437  //
1438  malpha=6.64465598E-24;
1439  // some constants
1440  //hpl=6.6262E-27
1441  //
1442  hpl=4.13566733E-15*1E-6*ergPmev;
1443  //
1444 
1445  // mn=1.67492716E-24;
1446  // mp=1.67262158E-24;
1447  // me=9.10938188E-28;
1448  kb=1.380658E-16; // erg K^{-1} g^{-1}
1449  Q=(mn-mp)*C*C;
1450  R=kb/mp;
1451  Re=kb/me;
1452  // hpl=6.6260755E-27;
1453  H=hpl;
1454  hbar=hpl/(2.0*M_PI);
1455  K=1.24E15;
1456  K2=9.9E12;
1457  //
1458  // compare below
1459  arad=8.*pow(M_PI,5.0)*pow(kb,4.0)/(15*C*C*C*H*H*H);
1460  // arad=5.6704E-5 * 4.0 / C;
1461  sigmasb=arad*C/4.0;
1462  sigmamat=6.652E-29*100*100;
1463  mevocsq=1.783E-27;
1464 
1465 
1466  // default for units is GM=C=1
1467  // GRB
1468  // mb=mn;
1469  // definition of baryon mass uses the below
1470  mb = amu;
1471 
1472  Mcgs=3.*msun;
1473  Mdot=0.1*msun;
1474  Mdotc=0.35; // approx code units mass accretion rate
1475 
1476  // units
1477  Lunit=G*Mcgs/(C*C);
1478  Tunit=G*Mcgs/(C*C*C);
1479  Vunit=Lunit/Tunit;
1480  Ccode=C/Vunit;
1481  rho0unittype=0; // mass is mass
1483  mbwithrhounit=mb;
1485  Munit=rhounit*pow(Lunit,3.0);
1489  Pressureunit=rhounit*Vunit*Vunit;
1491  Bunit=Vunit*sqrt(rhounit);
1493 
1494 
1495  // physics stuff
1496  ledd=4.*M_PI*C*G*Mcgs*mb/sigmamat;
1498 
1499  // normalizations and settings for metric changes
1500  a0=0.0;
1501  MBH0=1.0;
1502  QBH0=0.0;
1503  EP30=0.0;
1504  THETAROT0=0.0;
1505  Mfactor=1.0;
1506  Jfactor=1.0;
1507  rhofactor=1.0;
1508 
1509  dabh=0.0;
1510  dE=0.0;
1511  dJ=0.0;
1512 
1513 
1514  return(0);
1515 }
1516 
1517 
1518 
1519 
1520 
1521 
1523 int post_init(FTYPE (*prim)[NSTORE2][NSTORE3][NPR], FTYPE (*faraday)[NSTORE2][NSTORE3][NUMCURRENTSLOTS][3])
1524 {
1525  int compute_currents_t0(FTYPE (*prim)[NSTORE2][NSTORE3][NPR], FTYPE (*faraday)[NSTORE2][NSTORE3][NUMCURRENTSLOTS][3]);
1526 
1527 
1528  trifprintf("begin: post_init\n");
1529 
1530  // post-init checks
1531  if(
1532  ((BCtype[X1UP]==PERIODIC || BCtype[X1DN]==PERIODIC) && periodicx1==0 && N1>1)
1533  ||((BCtype[X1UP]!=PERIODIC || BCtype[X1DN]!=PERIODIC) && periodicx1==1 && N1>1)
1534  ||((BCtype[X2UP]==PERIODIC || BCtype[X2DN]==PERIODIC) && periodicx2==0 && N2>1)
1535  ||((BCtype[X2UP]!=PERIODIC || BCtype[X2DN]!=PERIODIC) && periodicx2==1 && N2>1)
1536  ||((BCtype[X3UP]==PERIODIC || BCtype[X3DN]==PERIODIC) && periodicx3==0 && N3>1)
1537  ||((BCtype[X3UP]!=PERIODIC || BCtype[X3DN]!=PERIODIC) && periodicx3==1 && N3>1)
1538  ){
1539  dualfprintf(fail_file,"inconsistent periodic settings\n");
1540  myexit(39472525);
1541  }
1542 
1543 
1544  // need to compute various things for EOS
1545  // also done per timestep in step_ch.c
1546  // GODMARK: Check that no EOS call is before this point
1547  compute_EOS_parms_full(WHICHEOS, GLOBALPOINT(EOSextraglobal),prim);
1548 
1549 
1550 
1551  // in synch always here
1552  if (error_check(3)) {
1553  dualfprintf(fail_file, "error_check detected failure at main:1\n");
1554  dualfprintf(fail_file, "Bad initial conditions\n");
1555  myexit(1);
1556  }
1557 
1558 
1559  // all calculations that do not change for any initial conditions or problem setup or restart conditions
1560 
1561 
1562  // don't recompute these things if doing metric evolution on substeps
1563  if(RESTARTMODE!=0){
1564  setfailresponse(restartonfail);
1565  }
1566 
1567 
1569  // current
1570  compute_currents_t0(prim,faraday);
1571 
1572 
1573 
1574 
1575  trifprintf("end: post_init\n");
1576 
1577 
1578  return(0);
1579 
1580 }
1581 
1582 
1585 {
1586  int faketimeorder,fakenumtimeorders;
1587 
1588  // need to recompute horizon-related quantities if horizon is growing due to accretion
1590  find_horizon(0);
1591  trifprintf("Rhor=%21.15g Risco=%21.15g MBH=%21.15g a=%21.15g QBH=%21.15g EP3=%21.15g THETAROT=%21.15g\n",Rhor,Risco,MBH,a,QBH,EP3,THETAROT);
1592  }
1593  else{
1595  }
1596 
1597  // not the initial call -- uses horizon information
1598  // By this point the code expects user to be able to specify ACTIVEREGION domain
1599  // however, if doing grid sectioning still need to have full COMP loops (hence 2 and not 1 below)
1600  faketimeorder=-1;
1601  fakenumtimeorders=-1;
1602  recompute_fluxpositions(2,faketimeorder,fakenumtimeorders,nstep,t);
1603 
1604 
1605 
1606  return(0);
1607 
1608 }
1609 
1611 int compute_currents_t0(FTYPE (*prim)[NSTORE2][NSTORE3][NPR], FTYPE (*faraday)[NSTORE2][NSTORE3][NUMCURRENTSLOTS][3])
1612 {
1613 
1614 #if(CALCFARADAYANDCURRENTS)
1615 
1616 #if(CURRENTST0)
1617  // setup faraday so t=0 dump has diagnostics
1618  // may want currents for dump=0 (time-derivative terms will be wrong)
1619  current_doprecalc(CURTYPET,prim);
1620  current_doprecalc(CURTYPEX,prim);
1621  current_doprecalc(CURTYPEY,prim);
1622  current_doprecalc(CURTYPEZ,prim);
1623  // compute current
1624  current_calc(faraday);
1625 
1626 #else
1627 
1628  // need to at least compute t=0 faraday so currents can start to be computed before reach step_ch.c (just an ordering issue with how step_ch.c does this case)
1629  if(WHICHCURRENTCALC==1){
1630  // compute faraday components needed for time centering of J
1631  current_doprecalc(CURTYPET,prim);
1632  }
1633 #endif
1634 
1635 #if(FARADAYT0)
1636  current_doprecalc(CURTYPEFARADAY,prim);
1637 #endif
1638 
1639 #endif
1640 
1641 
1642  return(0);
1643 
1644 }
1645 
1646 
1647 
1650 {
1651  int i,j,k,pliter,pl;
1652  int jj;
1653 
1655  // 0 out these things so dump files are readable by SM under any cases
1657  FULLLOOP{
1658 
1659  if(FLUXB==FLUXCTSTAG){
1660  // then pl=B1,B2,B3 actually should be correct (i.e. not NaN), so don't reset those so nan-check works
1661  PLOOP(pliter,pl){
1662  if(! (pl==B1 || pl==B2 || pl==B3) ){
1663  GLOBALMACP0A1(udump,i,j,k,pl)=0.0;
1664  }
1665  }
1666  }
1667  else if(DOENOFLUX != NOENOFLUX){
1668  // then all pl actually should be correct (i.e. not NaN), so don't reset those so nan-check works
1669  }
1670  else{
1671  PLOOP(pliter,pl) GLOBALMACP0A1(udump,i,j,k,pl)=0.0;
1672  }
1673 
1674 
1675 #if(CALCFARADAYANDCURRENTS)
1676  DLOOPA(jj) GLOBALMACP0A1(jcon,i,j,k,jj)=0.0;
1677  for(pl=0;pl<NUMFARADAY;pl++) GLOBALMACP0A1(fcon,i,j,k,pl)=0.0;
1678 #endif
1679 
1680  }
1681 
1682 
1683  return(0);
1684 
1685 }
1686 
1687 
1688 
1689 
1690 
1692 int post_par_set(void)
1693 {
1694  int interp_loop_set(void);
1695  int orders_set(void);
1696  void check_bnd_num(void);
1697 
1698 
1699 
1700 
1701 
1702  // if higher order, then set useghostplusactive to 1 since need that region in general
1703  if(HIGHERORDERMEM && (DOENOFLUX==ENOFINITEVOLUME || DOENOFLUX==ENOFLUXRECON) ){
1704 
1706  }
1707  else{
1709  }
1710 
1711 
1713  // no matter how this parameter is set, we reset it to
1714  extrazones4emf=1;
1715  }
1716  else extrazones4emf=0;
1717 
1718  if(SPLITMAEMMEM && HIGHERORDERMEM && DOENOFLUX == ENOFLUXRECON){
1719  splitmaem=1;
1720  }
1721  else splitmaem=0;
1722 
1724  // when not splitting MA/EM terms and doing FLUXRECON point field method, then need to still fix stencil for EMF terms
1725  emffixedstencil=1;
1726  }
1727 
1728 
1730  // no matter how this parameter is set, we reset it to
1731  unewisavg=1;
1732  }
1733  else unewisavg=0;
1734 
1735 
1736  trifprintf("useghostplusactive=%d extrazones4emf=%d\n",useghostplusactive,extrazones4emf);
1737 
1738 
1739  trifprintf("Setting orders\n");
1740  orders_set();
1741 
1742  trifprintf("Boundary number checks\n");
1743  check_bnd_num();
1744 
1745  trifprintf("Setting interp loop\n");
1746  interp_loop_set();
1747 
1748  trifprintf("Reporting bound loop\n");
1749  report_bound_loop();
1750 
1751 
1752  return(0);
1753 }
1754 
1755 
1756 
1757 
1758 
1760 void check_bnd_num(void)
1761 {
1762  int totalo;
1763  int get_num_bnd_zones_used(int dir);
1764  int dimen;
1765  int bndnum[NDIM];
1766  int doingdimen[NDIM];
1767  int pl,pliter;
1768  int doingenough;
1769 
1770 
1771  doingdimen[1]=N1NOT1;
1772  doingdimen[2]=N2NOT1;
1773  doingdimen[3]=N3NOT1;
1774 
1775 
1776  bndnum[1]=N1BND;
1777  bndnum[2]=N2BND;
1778  bndnum[3]=N3BND;
1779 
1780 
1781  DIMENLOOP(dimen){
1782 
1783  // first fix avgscheme and lim for case when not doing dimension
1784  if(!doingdimen[dimen]){
1785  avgscheme[dimen]=0;
1786  lim[dimen]=0;
1787  } // otherwise assume as wanted
1788 
1789  // get number of boundary zones needed
1790  totalo=get_num_bnd_zones_used(dimen);
1791 
1792 
1793  // bndnum[dimen] (MAXBND is maximum) is the number of boundary zones to be set by boundary routines and to be passed by MPI routines
1794  if(totalo==bndnum[dimen] || !doingdimen[dimen]){
1795  // then good
1796  }
1797  else if(totalo>bndnum[dimen]){
1798  dualfprintf(fail_file,"Not enough: dimen=%d totalo=%d MAXBND=%d bndnum=%d for avgscheme interporder[%d]=%d or lim interporder[%d]=%d extrazones4emf=%d\n",dimen,totalo,MAXBND,bndnum[dimen],avgscheme[dimen],interporder[avgscheme[dimen]],lim[dimen],interporder[lim[dimen]],extrazones4emf);
1799  failed=1; // so don't try to compute things in dump
1800  myexit(1);
1801  }
1802  else{
1803  // then MAXBND too large
1804  dualfprintf(fail_file,"WARNING: MAXBND excessive\n");
1805  dualfprintf(fail_file,"WARNING: dimen=%d totalo=%d MAXBND=%d and bndnum=%d for avgscheme interporder[%d]=%d or lim interporder[%d]=%d extrazones4emf=%d\n",dimen,totalo,MAXBND,bndnum[dimen],avgscheme[dimen],interporder[avgscheme[dimen]],lim[dimen],interporder[lim[dimen]],extrazones4emf);
1806  // not a failure, but user should be aware especially when doing MPI
1807  }
1808 
1809  }
1810 
1811 
1812  // see if need to be here at all
1813  if(interporder[avgscheme[1]]<3 && interporder[avgscheme[2]]<3 && interporder[avgscheme[3]]<3){
1815  PALLLOOP(pl) do_source_integration[pl] = 0;
1816  PALLLOOP(pl) do_conserved_integration[pl] = 0;
1817 
1818  trifprintf("Changed do_{conserved/source/transverse_flux}_integration to 0 since avgscheme[1]=%d avgscheme[2]=%d avgscheme[3]=%d\n",avgscheme[1],avgscheme[2],avgscheme[3]);
1819  }
1820 
1821 
1822 
1823  // checks on parameters so user doesn't do something stupid
1824  if(FULLOUTPUT&&USEMPI&&(numprocs>1 || mpicombine==1)){
1825  dualfprintf(fail_file,"Cannot use FULLOUTPUT!=0 when USEMPI=1 and (numprocs>1 || mpicombine==1)\n");
1826  myexit(ERRORCODEBELOWCLEANFINISH+200);
1827  }
1828 
1829  if(DOEVOLVEMETRIC&& (ANALYTICCONNECTION||ANALYTICSOURCE)){
1830  dualfprintf(fail_file,"Unlikely you have metric in time analytically\n");
1831  myexit(ERRORCODEBELOWCLEANFINISH+201);
1832  }
1833 
1834 
1835  if(DOSELFGRAVVSR && (ANALYTICCONNECTION||ANALYTICSOURCE||ANALYTICGCON)){
1836  dualfprintf(fail_file,"Unlikely you have metric analytically with self gravity\n");
1837  myexit(ERRORCODEBELOWCLEANFINISH+202);
1838  }
1839 
1840  if(GDETVOLDIFF){
1841  if(ISSPCMCOORDNATIVE(MCOORD)){
1842  // then fine
1843  }
1844  else{
1845  dualfprintf(fail_file,"GDETVOLDIFF==1 not setup for non-SPC metrics\n");
1846  myexit(ERRORCODEBELOWCLEANFINISH+203);
1847  }
1848  }
1849 
1850  if(DOSELFGRAVVSR==0 && (MCOORD==KS_BH_TOV_COORDS || MCOORD==KS_TOV_COORDS || MCOORD==BL_TOV_COORDS) ){
1851  dualfprintf(fail_file,"DOSELFGRAVVSR==0 with MCOORD=%d is not likely what you want\n",MCOORD);
1852  dualfprintf(fail_file,"Continuing....\n");
1853  }
1854 
1855 
1856 
1857 
1858  if(HIGHERORDERMEM==0 && DOENOFLUX != NOENOFLUX){
1859  dualfprintf(fail_file,"Need to turn on HIGHERORDERMEM when doing higher order methods (i.e. DOENOFLUX(=%d)!=NOENOFLUX)\n",DOENOFLUX);
1860  myexit(ERRORCODEBELOWCLEANFINISH+204);
1861  }
1862 
1863  if(COMPDIM!=3){
1864  dualfprintf(fail_file,"Code not setup for anything but COMPDIM==3\n");
1865  myexit(ERRORCODEBELOWCLEANFINISH+205);
1866  }
1867 
1868 
1869  if(FIELDSTAGMEM==0 && FLUXB==FLUXCTSTAG){
1870  dualfprintf(fail_file,"FIELDSTAGMEM should be 1 if FLUXB==FLUXCTSTAG\n");
1871  myexit(ERRORCODEBELOWCLEANFINISH+206);
1872  }
1873 
1874  if(FIELDSTAGMEM==1 && FLUXB!=FLUXCTSTAG){
1875  dualfprintf(fail_file,"WARNING: FIELDSTAGMEM==1 will be slower with non-stag method\n");
1876  }
1877 
1878  if(FIELDTOTHMEM==0 && FLUXB==FLUXCTTOTH){
1879  dualfprintf(fail_file,"FIELDTOTHMEM should be 1 if FLUXB==FLUXCTTOTH\n");
1880  myexit(ERRORCODEBELOWCLEANFINISH+207);
1881  }
1882 
1883 
1884  if(ISSPCMCOORDNATIVE(MCOORD)){
1885  // if( (N1%2>0 && N1>1) || (N2%2>0 && N2>1) || (N3%2>0 && N3>1) ){
1886  if( (N2%2>0 && N2>1) || (N3%2>0 && N3>1) ){
1887  dualfprintf(fail_file,"N1, N2, N3 should be even since some parts of code assume so for SPC.\n");
1888  myexit(ERRORCODEBELOWCLEANFINISH+208);
1889  }
1890  }
1891 
1892  // if(N1%2 && N1>1 || N2%2 && N2>1 || N3%2 && N3>1){
1893  // if(N2%2 && N2>1 || N3%2 && N3>1){
1894  // dualfprintf(fail_file,"Need even N1,N2,N3 AFAIK N1=%d N2=%d N3=%d\n",N1,N2,N3);
1895  // myexit(ERRORCODEBELOWCLEANFINISH+19846286);
1896  // }
1897 
1898 
1899 
1900  if(SUPERLONGDOUBLE){
1901  dualfprintf(fail_file,"If doing SUPERLONGDOUBLE, then should have compiled as such\n");
1902  }
1903 
1904  if(ROEAVERAGEDWAVESPEED || ATHENAROE){
1905  dualfprintf(fail_file,"ATHENA stuff only for non-rel setup and while was tested hasn't been used or kept up to date\n");
1906  myexit(ERRORCODEBELOWCLEANFINISH+209);
1907  }
1908 
1909  if(STOREWAVESPEEDS==0 && FLUXB==FLUXCTSTAG){
1910  dualfprintf(fail_file,"Must set STOREWAVESPEEDS==1 when doing FLUXCTSTAG\n");
1911  myexit(ERRORCODEBELOWCLEANFINISH+210);
1912  }
1913 
1914  if(LIMADJUST!=LIMITERFIXED){
1915  dualfprintf(fail_file,"LIMADJUST old code\n");
1916  myexit(ERRORCODEBELOWCLEANFINISH+211);
1917  }
1918 
1919 
1920  if(FLUXADJUST!=FLUXFIXED){
1921  dualfprintf(fail_file,"FLUXADJUST old code\n");
1922  myexit(ERRORCODEBELOWCLEANFINISH+212);
1923  }
1924 
1925  if(DOEVOLVEMETRIC&& (WHICHEOM!=WITHGDET )){
1926  dualfprintf(fail_file,"conn2 not computed for time-dependent metric yet\n");
1927  myexit(ERRORCODEBELOWCLEANFINISH+213);
1928  }
1929 
1930  if(CONNMACHINEBODY){
1931 
1932  if(WHICHEOM!=WITHGDET){
1933  dualfprintf(fail_file,"Not setup for body correction when f is not detg\n");
1934  myexit(ERRORCODEBELOWCLEANFINISH+215);
1935  }
1936  }
1937 
1938  if(CONNMACHINEBODY&&(DOENOFLUX!=NOENOFLUX || MERGEDC2EA2CMETHOD)){
1939  dualfprintf(fail_file,"WARNING: MACHINEBODY with higher order scheme makes no sense\n");
1940  }
1941 
1942 
1943 
1944  if(CONTACTINDICATOR!=0){
1945  dualfprintf(fail_file,"Contact not recommended\n");
1946  }
1947 
1948  if(FLUXDUMP==1){
1949  dualfprintf(fail_file,"FLUXDUMP ACTIVE -- lots of extra output\n");
1950  }
1951 
1952  if(NUMPOTHER!=0){
1953  dualfprintf(fail_file,"NUMPOTHER ACTIVE -- lots of extra memory used\n");
1954  }
1955 
1956  if(LIMIT_FLUXC2A_PRIM_CHANGE){
1957  dualfprintf(fail_file,"LIMIT_FLUXC2A_PRIM_CHANGE doesn't work according to Sasha, so don't use\n");
1958  myexit(ERRORCODEBELOWCLEANFINISH+216);
1959  }
1960 
1961  // check if
1962  doingenough=1;
1963  DIMENLOOP(dimen){
1964  doingenough *= (interporder[avgscheme[dimen]]>=interporder[WENO5BNDPLUSMIN] || doingdimen[dimen]==0);
1965  }
1966 
1967  if(WENO_EXTRA_A2C_MINIMIZATION==1 && doingenough==0){
1968  dualfprintf(fail_file,"WENO_EXTRA_A2C_MINIMIZATION==1 and interporder=%d %d %d invalid\n",interporder[avgscheme[1]],interporder[avgscheme[2]],interporder[avgscheme[3]]);
1969  myexit(ERRORCODEBELOWCLEANFINISH+217);
1970  }
1971 
1972 
1973 
1974  DIMENLOOP(dimen){
1975  if(avgscheme[dimen]!=DONOR){ // using DONOR just turns off and assume standard way to turn off so no need to message user
1976  if(avgscheme[dimen]<FIRSTWENO || avgscheme[dimen]>LASTWENO){
1977  dualfprintf(fail_file,"Choice of avgscheme[%d]=%d has no effect\n",dimen,avgscheme[dimen]);
1978  }
1979  }
1980  }
1981 
1982 
1983  // if( (FLUXB==FLUXCTHLL || FLUXB==FLUXCTTOTH || (FLUXB==FLUXCTSTAG && extrazones4emf==1 && )) && EVOLVEWITHVPOT){ // avoid complicated conditional
1984  if(EVOLVEWITHVPOT && !(FLUXB==FLUXCTSTAG && extrazones4emf==0) ){
1985  // Even with FV or FLUXRECON method that relies on updating non-point fields, can't evolve with A_i since truncation error different rather than just machine error different. This leads to large errors -- especially at boundaries? GODMARK -- not 100% sure this is the problem for test=1102 and EVOLVEWITHVPOT
1986  dualfprintf(fail_file,"Cannot evolve field using A_i for FLUXB==FLUXCTHLL or FLUXB==FLUXCTHLL since no single A_i evolved forward in time. And cannot use with non-point field method since while single A_i updated, the update diverges at truncation error between updating A_i and updating the non-point-field -- this is especially bad for periodic boundary conditions where one must have machine error correct behavior at boundaries\n");
1987  myexit(ERRORCODEBELOWCLEANFINISH+218);
1988  }
1989 
1990 
1991  if(splitmaem==0 && (SPLITPRESSURETERMINFLUXMA || SPLITPRESSURETERMINFLUXEM)){
1992  dualfprintf(fail_file,"To use SPLITPRESSURE must turn on splitmaem, which requires FLUXRECON\n");
1993  myexit(ERRORCODEBELOWCLEANFINISH+219);
1994  }
1995 
1996  if(splitmaem==1){
1997  dualfprintf(fail_file,"Noticed some tests are more accurate if don't split (splitmaem==0), like test=1102 in init.sasha.c when doing non-point field FLUXRECON method the density error is smaller by factor of 2 with splitmaem==0\n");
1998  }
1999 
2000  // when using FLUXRECON, WENO5BND lim/avg:
2001  // 32x16: splitmaem==1 (pressure split or not!): 5.164e-05 0.0005637 0.001195 0.001326 0.003499 0.0001439 0.0001438 0.000415
2002  // 32x16: splitmaem==0 (higherordersmooth or rough!): 8.369e-06 0.0005615 0.001208 0.001224 0.002977 0.0001433 0.0001431 0.0003529
2003 
2004 
2005  if(ISSPCMCOORD(MCOORD) && ACCURATESINCOS==0){
2006  dualfprintf(fail_file,"Warning: if polar axis or r=0 singularity don't have \\detg=0 you should force it -- normally ACCURATESINCOS==1 does a good job of this, but still should have code to check\n");
2007  }
2008 
2009 
2010  if(FULLOUTPUT!=0){
2011  // then ensure that boundary zones are off if necessary
2012 
2013  if(DOLUMVSR){
2014  dualfprintf(fail_file,"lumvsr requires no boundary zones outputted so dump and lumvsr file can be used together\n");
2015  myexit(ERRORCODEBELOWCLEANFINISH+195815983);
2016  }
2017  if(DODISSVSR){
2018  dualfprintf(fail_file,"dissvsr requires no boundary zones outputted so dump and dissvsr file can be used together\n");
2019  myexit(ERRORCODEBELOWCLEANFINISH+195815984);
2020  }
2021 
2022  }
2023 
2024 
2025 
2026  if(2*N1<N1BND || N1BND!=0 && N1==1 || periodicx1==1 && ncpux1>1 && N1<N1BND){
2027  dualfprintf(fail_file,"Code not setup to handle boundary cells N1BND=%d with only N1=%d\n",N1BND,N1);
2028  myexit(ERRORCODEBELOWCLEANFINISH+246872462);
2029  }
2030  if(2*N2<N2BND || N2BND!=0 && N2==1 || periodicx2==1 && ncpux2>1 && N2<N2BND){
2031  dualfprintf(fail_file,"Code not setup to handle boundary cells N2BND=%d with only N2=%d\n",N2BND,N2);
2032  myexit(ERRORCODEBELOWCLEANFINISH+246872463);
2033  }
2034  if(2*N3<N3BND || N3BND!=0 && N3==1 || periodicx3==1 && ncpux3>1 && N3<N3BND){
2035  dualfprintf(fail_file,"Code not setup to handle boundary cells N3BND=%d with only N3=%d\n",N3BND,N3);
2036  myexit(ERRORCODEBELOWCLEANFINISH+246872464);
2037  }
2038 
2039 
2040 
2042  dualfprintf(fail_file,"WARNING: With SENSITIVE!=LONGDOUBLETYPE you may have problems for some integral or counting quantities (e.g. DTd too small or many zones to integrate over)\n");
2043  }
2044 
2045 
2046 
2047 #if(MERGEDC2EA2CMETHOD==1)
2048  // if(splitmaem){
2049  // dualfprintf(fail_file,"MERGEDC2EA2CMETHOD==1 is not setup for splitmaem since it was assumed splitmaem only needed with old a2c method\n");
2050  // myexit(ERRORCODEBELOWCLEANFINISH+346897346);
2051  // }
2052 #endif
2053 
2054 #if(MERGEDC2EA2CMETHOD==1 && STOREFLUXSTATE==0)
2055  dualfprintf(fail_file,"Must store flux state (STOREFLUXSTATE 1) if doing merged method\n");
2056  myexit(9842511);
2057 #endif
2058 
2059 #if(STOREFLUXSTATE==0 && STORESHOCKINDICATOR==1)
2060  dualfprintf(fail_file,"Must store flux state (STOREFLUXSTATE 1) if storing shock indicator\n");
2061  myexit(9842512);
2062 #endif
2063 
2064 
2065 
2066  if(PRODUCTION>0){
2067  if(DOENOFLUX != NOENOFLUX && FLUXB==FLUXCTSTAG){
2068  dualfprintf(fail_file,"NOTE: With PRODUCTION>0, higher-order staggered field method won't compute ener file value of divB correctly because turned off diagnostic bounding to avoid excessive MPI calls to bound unew. dump file will still be correct for MPI boundaries but not for real boundaries since unew not defined to be bounded by user\n");
2069  }
2070  }
2071 
2072 
2073  if(PRODUCTION==0){
2074  dualfprintf(fail_file,"WARNING: PRODUCTION set to 0, code may be slower\n");
2075  }
2076 
2078  dualfprintf(fail_file,"WARNING: LIMITDTWITHSOURCETERM set to 1, code may be slower\n");
2079  }
2080 
2081  // if(LIMITDTWITHSOURCETERM){
2082  // dualfprintf(fail_file,"LIMITDTWITHSOURCETERM==1 doesn't work right now\n");
2083  // myexit(ERRORCODEBELOWCLEANFINISH+54986456);
2084  // }
2085 
2087  dualfprintf(fail_file,"WARNING: DODISS/DOLUMVSR/DODISSVSR/DOENTROPY!=DONOENTROPY set to 1, code may be slower\n");
2088  }
2089 
2090  if(CHECKONINVERSION){
2091  dualfprintf(fail_file,"WARNING: CHECKONINVERSION set to 1, code may be slower\n");
2092  }
2093 
2094 
2095  if(CHECKSOLUTION){
2096  dualfprintf(fail_file,"WARNING: CHECKSOLUTION set to 1, code may be slower\n");
2097  }
2098 
2099 
2100  DIMENLOOP(dimen){
2101  if(interporder[lim[dimen]]-1 > TIMEORDER){
2102  dualfprintf(fail_file,"WARNING: interporder[dimen=%d lim=%d]=%d -1 > TIMEORDER=%d is unstable in region where Courant condition setting dt\n",dimen,lim[dimen],interporder[lim[dimen]],TIMEORDER);
2103  }
2104  }
2105 
2106  if(DOINGLIAISON && USEMPI==0){
2107  dualfprintf(fail_file,"WARNING: DOINGLIAISON==1 but USEMPI==0\n");
2108  }
2109 
2110 
2111  // complain if b^2/rho b^2/u or u/rho too large for given resolution given experience with GRMHD torus problem
2112  DIMENLOOP(dimen){
2113  if(BSQORHOLIMIT/30.0>((FTYPE)totalsize[dimen])/64.0){
2114  dualfprintf(fail_file,"WARNING: BSQORHOLIMIT=%21.15g for totalsize[%d]=%d\n",BSQORHOLIMIT,dimen,totalsize[dimen]);
2115  }
2116  if(BSQOULIMIT/100.0>((FTYPE)totalsize[dimen])/64.0){
2117  dualfprintf(fail_file,"WARNING: BSQOULIMIT=%21.15g for totalsize[%d]=%d\n",BSQOULIMIT,dimen,totalsize[dimen]);
2118  }
2119  if(UORHOLIMIT/100.0>((FTYPE)totalsize[dimen])/64.0){
2120  dualfprintf(fail_file,"WARNING: UORHOLIMIT=%21.15g for totalsize[%d]=%d\n",UORHOLIMIT,dimen,totalsize[dimen]);
2121  }
2122  }
2123 
2125  dualfprintf(fail_file,"Cannot do merged method with older weno-type c2a/a2c methods\n");
2126  myexit(ERRORCODEBELOWCLEANFINISH+289754897);
2127  }
2128 
2130  dualfprintf(fail_file,"MERGEDC2EA2CMETHOD,MA,EM set inconsistently: %d %d %d\n",MERGEDC2EA2CMETHOD,MERGEDC2EA2CMETHODMA,MERGEDC2EA2CMETHODEM);
2131  myexit(ERRORCODEBELOWCLEANFINISH+289754898);
2132  }
2133 
2134 
2135 
2136  if(special3dspc && ncpux3==1 && (N3%2)){
2137  dualfprintf(fail_file,"Must have even N3 (N3=%d) if special3dspc==1 && ncpux3=1\n",N3);
2138  myexit(ERRORCODEBELOWCLEANFINISH+83746837);
2139  }
2140 
2141 
2142  if(DOENOFLUX == ENOFINITEVOLUME && (DODISS || DODISSVSR)){
2143  dualfprintf(fail_file,"WARNING: FV method does not allow accurate tracking of dissipation as code is currently written. Overestimates compared to actual dissipation.\n");
2144  }
2145 
2146 
2147  if(FLUXB==FLUXCTSTAG && special3dspc && (COORDSINGFIX==0 || SINGSMALL<=0.0)){
2148  dualfprintf(fail_file,"IF3DSPCTHENMPITRANSFERATPOLE==1 with N3>1 requires COORDSINGFIX>0 and SINGSMALL>0.0 in order for B2 to be evolved properly at the pole\n");
2149  myexit(ERRORCODEBELOWCLEANFINISH+978343943);
2150  }
2151 
2152  if(FLUXB!=FLUXCTSTAG && COORDSINGFIX==1 ){
2153  dualfprintf(fail_file,"WARNING: No need to have COORDSINGFIX==1 with non-staggered field\n");
2154  }
2155 
2156  if(COORDSINGFIX==1 && (N3==1) && ISSPCMCOORDNATIVE(MCOORD)){
2157  dualfprintf(fail_file,"WARNING: No need to have COORDSINGFIX==1 with 2D\n");
2158  }
2159 
2160  if(N1==1 && ncpux1>1 ||N2==1 && ncpux2>1 ||N3==1 && ncpux3>1){
2161  dualfprintf(fail_file,"Must have N?>1 if ncpux?>1 for code to recognize that dimension\n");
2162  myexit(ERRORCODEBELOWCLEANFINISH+28347525);
2163  }
2164 
2165 
2166  DIMENLOOP(dimen){
2167  if(WENOMEMORY==0 && ( WENOINTERPTYPE(lim[dimen])||WENOINTERPTYPE(avgscheme[dimen]))){
2168  dualfprintf(fail_file,"Need to turn on WENOMEMORY when lim or avgscheme = eno or weno\n");
2169  myexit(ERRORCODEBELOWCLEANFINISH+83763463);
2170  }
2171  }
2172 
2173 
2174  if(USEOPENMP){
2175  dualfprintf(fail_file,"WARNING: MYFUN function tracing for failures turned off because not allowed inside OpenMP constructs\n");
2176  }
2177 
2178  // GODMARK: No obvious way to check for ANALYTICMEMORY==0 since depends on user bounds. Depend upon user to check for this.
2179 
2180 
2181  if(ALLOWKAZEOS && USEOPENMP){
2182  dualfprintf(fail_file,"WARNING: If not using Kaz EOS, then setting ALLOWKAZEOS==1 will introduce more OpenMP overhead\n");
2183  }
2184 
2185  if(numopenmpthreads==1 && USEOPENMP==1){
2186  dualfprintf(fail_file,"WARNING: Using only 1 OpenMP thread: Excessive overhead due to pragma's: Recommend turning off USEOPENMP in makehead.inc.\n");
2187  }
2188 
2190  dualfprintf(fail_file,"******SUPERWARNING******: If reveal region with Toth method, then divb can't be preserved due to how fluxes are averaged.\n");
2191  }
2192 
2194  dualfprintf(fail_file,"******SUPERWARNING******: divb won't be zero for absorbed regions when using AVOIDADVANCESHIFTX???==1 as required since need those regions to inject solution with arbitrary velocity profile.\n");
2195  }
2196 
2197  if(ANALYTICGCON==0){
2198  dualfprintf(fail_file,"******SUPERWARNING******: If far from black hole, even with apparently g^{t\\phi}\\sim 0 at the 10^{-34} level, still leads to exponential spurious growth in u^3 u_3 and B^3 to catastrophic levels!! For KS metric with a\\neq 0, best to use analytical gcon that leads to exactly g^{t\\phi}=0 and so \\beta[\\phi]=0.\n");
2199  }
2200 
2201  if(CONNDERTYPE!=DIFFNUMREC){
2202  dualfprintf(fail_file,"WARNING: Using inaccurate CONNDERTYPE can lead to problems, such as force errors near poles can lead to secular errors growing.\n");
2203  }
2204  else{
2205  dualfprintf(fail_file,"WARNING: Using DIFFNUMREC can be very slow, but more accurate than DIFFGAMMIE.\n");
2206  }
2207 
2208  if(WHICHEOM==WITHGDET){
2209  dualfprintf(fail_file,"WARNING: WHICHEOM==WITHGDET is inferior to WHICHEOM==WITHNOGDET and setting NOGDETU1=NOGDETU2=1 near the poles where force balance is difficult to ensure. If pressure constant, then NOGDET method ensures force balance between flux and source terms.\n");
2210  }
2211 
2212  if(STOREWAVESPEEDS==1){
2213  dualfprintf(fail_file,"WARNING: STOREWAVESPEEDS==1 has been found to be unstable due to how Riemann solver uses max-averaged wavespeeds. You should use STOREWAVESPEEDS==2 or 0 .\n");
2214  }
2215 
2216 
2218  dualfprintf(fail_file,"ERROR: Must have DOENTROPY enabled to use EOMENTROPYGRMHD\n");
2219  myexit(34897562);
2220  }
2221 
2223  dualfprintf(fail_file,"ERROR: Must have DOENTROPY enabled to use HOT2ENTROPY\n");
2224  myexit(13892345);
2225  }
2226 
2227 
2229  dualfprintf(fail_file,"SUPERWARNING: Old 5D method often fails to find solution where solution to inversion does exist. This can readily lead to completely wrong solutions due to failure fixups.\n");
2230  myexit(3987634);
2231  }
2232 
2233 
2235  dualfprintf(fail_file,"For COLD GRMHD, turn off Kaz EOS\n");
2236  myexit(9782362);
2237  }
2238 
2240  dualfprintf(fail_file,"For COLD GRMHD with fake entropy tracking, ensure WHICHEOS==COLDEOS\n");
2241  myexit(872762211);
2242  }
2243 
2244 
2245  if(TRACKVPOT==0 && EVOLVEWITHVPOT==1){
2246  dualfprintf(fail_file,"Must turn on TRACKVPOT if EVOLVEWITHVPOT==1\n");
2247  myexit(38974632);
2248  }
2249 
2250 
2251  if(ALLOWMETRICROT==1 && (CONNAXISYMM==1 || DOMIXTHETAPHI==0)){
2252  dualfprintf(fail_file,"Generally must set CONNAXISYMM==0 and DOMIXTHETAPHI==1 if ALLOWMETRICROT==1 -- only special cases would override this.\n");
2253  myexit(2467346463);
2254  }
2255 
2256 
2257  if(EOMRADTYPE!=EOMRADNONE && URAD0<0){
2258  dualfprintf(fail_file,"You seem to have not turned on radiation, causing URAD0<0 and so not part of a normal evolved quantity\n");
2259  myexit(373472252);
2260  }
2261 
2262 
2263  if(RADSHOCKFLAT==0 && EOMRADTYPE!=EOMRADNONE && TIMEORDER<3 && (lim[1]>MC || lim[2]>MC || lim[3]>MC)){
2264  dualfprintf(fail_file,"With radiation, need to use shock flattener with para and TIMEORDER=3 to avoid unphysical oscillations that lead to bad evolution and no radiation inversion.\n");
2265  // example test is RADBEAMFLAT with cour=0.8 and lim=PARALINE and TIMEORDER=2 which generates problems at beginning of test. Also later in time generates consistent stripping and noise at much larger level compared to TIMEORDER=3.
2266  // generally want to have TIMEORDER\sim SPATIALORDER for consistent space-time errors. Too much high spatial order at low temporal order can mean dominant temporal errors that interact poorly with attempt at higher spatial accuracy.
2267  myexit(245834);
2268  }
2269 
2270 
2271  if(USEROMIO==1 && binaryoutput==TEXTOUTPUT){
2272  dualfprintf(fail_file,"Cannot use text output with ROMIO\n");
2273  myexit(98725235);
2274  }
2275 
2276 
2277 
2278  // external checks
2279  parainitchecks();
2280 
2281 
2282 
2283 }
2284 
2285 
2287 int get_num_bnd_zones_used(int dimen)
2288 {
2289  int avgo;
2290  int interpo;
2291  int totalo;
2292  int doingdimen[NDIM];
2293  int extraavgo;
2294 
2295 
2296 
2297  doingdimen[1]=N1NOT1;
2298  doingdimen[2]=N2NOT1;
2299  doingdimen[3]=N3NOT1;
2300 
2301 
2302  if(useghostplusactive){
2303 
2304  if(doingdimen[dimen]){
2305  // number of zones one way for finite volume scheme to convert Uavg -> Upoint
2306  avgo=(interporder[avgscheme[dimen]]-1)/2;
2307  }
2308  else avgo=0; // nothing done for this dimension, so no avg zones
2309  }
2310  else avgo=0; // no need for extra zones
2311 
2312  if(extrazones4emf){
2313  if(doingdimen[dimen]){
2314  // number of zones one way for finite volume scheme to convert Uavg -> Upoint
2315  extraavgo=(interporder[avgscheme[dimen]]-1)/2;
2316  }
2317  else extraavgo=0; // nothing done for this dimension, so no avg zones
2318  }
2319  else extraavgo=0; // no need for extra zones
2320 
2321 
2322  // number of zones one way to have for interpolation to get fluxes
2323  // need to get flux at i,j,k=-1 in any case, and need boundary zones from there, so 1 extra effective boundary zone for interpolation
2324  if(doingdimen[dimen]){
2325  interpo=(interporder[lim[dimen]]-1)/2+1;
2326  }
2327  else interpo=0; // then not doing this dimension
2328 
2329  totalo=avgo+interpo+extraavgo;
2330 
2331  return(totalo);
2332 }
2333 
2334 
2335 
2336 
2337 
2338 
2339 
2340 
2341 
2342 
2345 int interp_loop_set(void)
2346 {
2347  int avgo[NDIM];
2348  int doingdimen[NDIM];
2349  int dimen;
2350  int dir;
2351  int jj;
2352  int avgoperdir[NDIM][NDIM];
2353  int odimen1,odimen2;
2354 
2355 
2356 
2357 
2358  doingdimen[1]=N1NOT1;
2359  doingdimen[2]=N2NOT1;
2360  doingdimen[3]=N3NOT1;
2361 
2362 
2363  // the fluxloop[dir][FIJKDEL]'s can be used for general purpose to get idel, jdel, kdel
2364 
2365 
2366  DIMENLOOP(dimen){
2367 
2368  if(doingdimen[dimen]){
2369  // number of zones one way for finite volume scheme to convert Uavg -> Upoint
2370  avgo[dimen]=(interporder[avgscheme[dimen]]-1)/2;
2371  }
2372  else avgo[dimen]=0; // nothing done for this dimension, so no avg zones
2373  trifprintf("dimen=%d lim=%d avgo=%d\n",dimen,lim[dimen],avgo[dimen]);
2374  }
2375 
2376 
2377 
2378  // always need fluxes in ghost+active if doing higher order methods
2379  if(useghostplusactive){
2380 
2381  // (interporder[avgscheme]-1)/2 is the number of points to the left and the number of ponits to the right that are needed for the finite volume scheme
2382 
2383 
2384  // scheme used to convert Uavg -> Upoint requires extra zones
2385  // avgo=(interporder[avgscheme]-1)/2;
2386  // i.e. if avgscheme=WENO5, then interporder[WENO5]=5 and the Uconsloop goes from -2 .. N+1 inclusive and fluxes go from -2 to N+2 inclusive
2387  // same for WENO4
2388  // this is -avgo .. N-1+avgo for Uconsloop and -avgo .. N+avgo for fluxes
2389 
2390 
2391  // note that if doing FLUXCTSTAG (FIELDSTAGMEM) then cross directions already expanded
2392 
2393 
2394  // merged method needs to store/compute state for full cell. This is excessively computing final dissipative flux, but not major cost and this keeps loops simple
2395 
2396 
2397  // +SHIFT1/2/3 for fluxloop[dimen][F?E] is so flux computed on both lower and upper faces, which happens to only be required for IF3DSPCTHENMPITRANSFERATPOLE for upper pole
2398  // OUTM? already goes to upper face
2399 
2400  dimen=1;
2401  fluxloop[dimen][FIDEL]=SHIFT1;
2402  fluxloop[dimen][FJDEL]=0;
2403  fluxloop[dimen][FKDEL]=0;
2404  fluxloop[dimen][FFACE]=FACE1;
2405  fluxloop[dimen][FIS]=(-avgo[dimen]-MERGEDC2EA2CMETHOD)*N1NOT1;
2406  fluxloop[dimen][FIE]=N1-1 +SHIFT1 +(avgo[dimen]+1+MERGEDC2EA2CMETHOD)*N1NOT1;
2407  fluxloop[dimen][FJS]=INFULL2;
2408  fluxloop[dimen][FJE]=OUTFULL2;
2409  fluxloop[dimen][FKS]=INFULL3;
2410  fluxloop[dimen][FKE]=OUTFULL3;
2411 
2412  dimen=2;
2413  fluxloop[dimen][FIDEL]=0;
2414  fluxloop[dimen][FJDEL]=SHIFT2;
2415  fluxloop[dimen][FKDEL]=0;
2416  fluxloop[dimen][FFACE]=FACE2;
2417  fluxloop[dimen][FIS]=INFULL1;
2418  fluxloop[dimen][FIE]=OUTFULL1;
2419  fluxloop[dimen][FJS]=(-avgo[dimen]-MERGEDC2EA2CMETHOD)*N2NOT1;
2420  fluxloop[dimen][FJE]=N2-1 +SHIFT2 +(avgo[dimen]+1+MERGEDC2EA2CMETHOD)*N2NOT1;
2421  fluxloop[dimen][FKS]=INFULL3;
2422  fluxloop[dimen][FKE]=OUTFULL3;
2423 
2424  dimen=3;
2425  fluxloop[dimen][FIDEL]=0;
2426  fluxloop[dimen][FJDEL]=0;
2427  fluxloop[dimen][FKDEL]=SHIFT3;
2428  fluxloop[dimen][FFACE]=FACE3;
2429  fluxloop[dimen][FIS]=INFULL1;
2430  fluxloop[dimen][FIE]=OUTFULL1;
2431  fluxloop[dimen][FJS]=INFULL2;
2432  fluxloop[dimen][FJE]=OUTFULL2;
2433  fluxloop[dimen][FKS]=(-avgo[dimen]-MERGEDC2EA2CMETHOD)*N3NOT1;
2434  fluxloop[dimen][FKE]=N3-1 +SHIFT3 +(avgo[dimen]+1+MERGEDC2EA2CMETHOD)*N3NOT1;
2435 
2436  }
2437  else{
2438 
2439  // Uconsloop for these methods just involve normal CZLOOP
2440  // inversion for this method just involves CZLOOP
2441  dimen=1;
2442  fluxloop[dimen][FIDEL]=SHIFT1;
2443  fluxloop[dimen][FJDEL]=0;
2444  fluxloop[dimen][FKDEL]=0;
2445  fluxloop[dimen][FFACE]=FACE1;
2448  if(FLUXB==FLUXCTSTAG){
2449  fluxloop[dimen][FJS]=INFULL2;
2450  fluxloop[dimen][FJE]=OUTFULL2;
2451  fluxloop[dimen][FKS]=INFULL3;
2452  fluxloop[dimen][FKE]=OUTFULL3;
2453  }
2454  else{ // then only averaging for FLUXCT so only need 1 additional off-direction point
2455  fluxloop[dimen][FJS]=-SHIFT2; //atch: loop over additional row to provide enough fluxes for FLUXCT, etc. to operate near the boundary
2456  fluxloop[dimen][FJE]=N2-1+SHIFT2; // " "
2457  fluxloop[dimen][FKS]=-SHIFT3; // " "
2458  fluxloop[dimen][FKE]=N3-1+SHIFT3; // " "
2459  }
2460 
2461  dimen=2;
2462  fluxloop[dimen][FIDEL]=0;
2463  fluxloop[dimen][FJDEL]=SHIFT2;
2464  fluxloop[dimen][FKDEL]=0;
2465  fluxloop[dimen][FFACE]=FACE2;
2468  if(FLUXB==FLUXCTSTAG){
2469  fluxloop[dimen][FIS]=INFULL1;
2470  fluxloop[dimen][FIE]=OUTFULL1;
2471  fluxloop[dimen][FKS]=INFULL3;
2472  fluxloop[dimen][FKE]=OUTFULL3;
2473  }
2474  else{
2475  fluxloop[dimen][FIS]=-SHIFT1; //atch: loop over additional row to provide enough fluxes for FLUXCT, etc. to operate near the boundary
2476  fluxloop[dimen][FIE]=N1-1+SHIFT1; // " "
2477  fluxloop[dimen][FKS]=-SHIFT3; // " "
2478  fluxloop[dimen][FKE]=N3-1+SHIFT3;// " "
2479  }
2480 
2481 
2482  dimen=3;
2483  fluxloop[dimen][FIDEL]=0;
2484  fluxloop[dimen][FJDEL]=0;
2485  fluxloop[dimen][FKDEL]=SHIFT3;
2486  fluxloop[dimen][FFACE]=FACE3;
2489  if(FLUXB==FLUXCTSTAG){
2490  fluxloop[dimen][FIS]=INFULL1;
2491  fluxloop[dimen][FIE]=OUTFULL1;
2492  fluxloop[dimen][FJS]=INFULL2;
2493  fluxloop[dimen][FJE]=OUTFULL2;
2494  }
2495  else{
2496  fluxloop[dimen][FIS]=-SHIFT1; //atch: loop over additional row to provide enough fluxes for FLUXCT, etc. to operate near the boundary
2497  fluxloop[dimen][FIE]=N1-1+SHIFT1; // " "
2498  fluxloop[dimen][FJS]=-SHIFT2; // " "
2499  fluxloop[dimen][FJE]=N2-1+SHIFT2; // " "
2500  }
2501 
2502  }
2503 
2504 
2505 
2506  DIMENLOOP(dimen) DIMENLOOP(dir){
2507  avgoperdir[dir][dimen]=avgo[dir]*(dimen==dir);
2508  }
2509 
2510 
2511  // fluxloop for staggered field's EMF when doing old dofluxreconevolvepointfield==0 method
2512  DIMENLOOP(dimen){
2513  odimen1=dimen%3+1;
2514  odimen2=(dimen+1)%3+1;
2515 
2516  emffluxloop[dimen][FIDEL]=MAX(fluxloop[odimen1][FIDEL],fluxloop[odimen2][FIDEL]);
2517  emffluxloop[dimen][FJDEL]=MAX(fluxloop[odimen1][FJDEL],fluxloop[odimen2][FJDEL]);
2518  emffluxloop[dimen][FKDEL]=MAX(fluxloop[odimen1][FKDEL],fluxloop[odimen2][FKDEL]);
2519  if(dimen==1) emffluxloop[dimen][FFACE]=CORN1;
2520  else if(dimen==1) emffluxloop[dimen][FFACE]=CORN2;
2521  else if(dimen==1) emffluxloop[dimen][FFACE]=CORN3;
2522 
2523  if(extrazones4emf){
2524  // then need defined at more positions
2525  emffluxloop[dimen][FIS]=MIN(fluxloop[odimen1][FIS]-avgoperdir[odimen1][1],fluxloop[odimen2][FIS]-avgoperdir[odimen2][1]);
2526  emffluxloop[dimen][FIE]=MAX(fluxloop[odimen1][FIE]+avgoperdir[odimen1][1],fluxloop[odimen2][FIE]+avgoperdir[odimen2][1]);
2527  emffluxloop[dimen][FJS]=MIN(fluxloop[odimen1][FJS]-avgoperdir[odimen1][2],fluxloop[odimen2][FJS]-avgoperdir[odimen2][2]);
2528  emffluxloop[dimen][FJE]=MAX(fluxloop[odimen1][FJE]+avgoperdir[odimen1][2],fluxloop[odimen2][FJE]+avgoperdir[odimen2][2]);
2529  emffluxloop[dimen][FKS]=MIN(fluxloop[odimen1][FKS]-avgoperdir[odimen1][3],fluxloop[odimen2][FKS]-avgoperdir[odimen2][3]);
2530  emffluxloop[dimen][FKE]=MAX(fluxloop[odimen1][FKE]+avgoperdir[odimen1][3],fluxloop[odimen2][FKE]+avgoperdir[odimen2][3]);
2531  }
2532  else{
2533  emffluxloop[dimen][FIS]=MIN(fluxloop[odimen1][FIS],fluxloop[odimen2][FIS]);
2534  emffluxloop[dimen][FIE]=MAX(fluxloop[odimen1][FIE],fluxloop[odimen2][FIE]);
2535  emffluxloop[dimen][FJS]=MIN(fluxloop[odimen1][FJS],fluxloop[odimen2][FJS]);
2536  emffluxloop[dimen][FJE]=MAX(fluxloop[odimen1][FJE],fluxloop[odimen2][FJE]);
2537  emffluxloop[dimen][FKS]=MIN(fluxloop[odimen1][FKS],fluxloop[odimen2][FKS]);
2538  emffluxloop[dimen][FKE]=MAX(fluxloop[odimen1][FKE],fluxloop[odimen2][FKE]);
2539  }
2540  }
2541 
2542 
2543 
2544 
2546  //
2547  // Define range over which "average" conserved quantities are *evolved*/updated from some flux. See advance.c.
2548  // Defines cell centers where conserved quantity exists
2549  //
2550  // Don't really need to evolve ghost+active region if FLUXRECON method unless FLUXRECON&&(FLUXB==FLUXCTSTAG), but not a problem to be a bit excessive
2551  //
2552  // if doing FLUXRECON && evolving point field, then no need to evolve ghost+active region -- latest method
2553  //
2557 
2558  dimen=1;
2559  Uconsevolveloop[FIS]=0;
2560  Uconsevolveloop[FIE]=N1-1;
2561 
2562  dimen=2;
2563  Uconsevolveloop[FJS]=0;
2564  Uconsevolveloop[FJE]=N2-1;
2565 
2566  dimen=3;
2567  Uconsevolveloop[FKS]=0;
2568  Uconsevolveloop[FKE]=N3-1;
2569  }
2570  else{
2571  // expanded loop using expanded range of fluxes so update Uf and ucum in layer of ghost zones so don't have to bound flux or Uf/Ui/ucum
2572  // only needed for FLUXRECON with STAG field method and only for fields, but do all for simplicity
2573 
2574  // inversion for this method just involves CZLOOP
2575 
2576  // loop over averaged U to get Uf
2577  // Uconsevolveloop[FIDEL]=0;
2578  // Uconsevolveloop[FJDEL]=0;
2579  // Uconsevolveloop[FKDEL]=0;
2581 
2582  dimen=1;
2583  Uconsevolveloop[FIS]=-avgo[dimen]*N1NOT1;
2584  Uconsevolveloop[FIE]=N1-1+avgo[dimen]*N1NOT1;
2585 
2586  dimen=2;
2587  Uconsevolveloop[FJS]=-avgo[dimen]*N2NOT1;
2588  Uconsevolveloop[FJE]=N2-1+avgo[dimen]*N2NOT1;
2589 
2590  dimen=3;
2591  Uconsevolveloop[FKS]=-avgo[dimen]*N3NOT1;
2592  Uconsevolveloop[FKE]=N3-1+avgo[dimen]*N3NOT1;
2593  }
2594 
2595 
2596 
2598  //
2599  // Define ghost+active region over which face (interpolated from center or natively existing in FLUXCTSTAG case) values of primitives are needed as necessary to define the final dissipative flux.
2600  // Does not need to be modified for merged method's use of more primitives used ultimately to get this same flux position through temporary left-right fluxes on a larger grid
2601  //
2603  if(useghostplusactive){
2604 
2605  // scheme used to convert Uavg -> Upoint requires extra zones
2606  // avgo=(interporder[avgscheme]-1)/2;
2607  // i.e. if avgscheme=WENO5, then interporder[WENO5]=5 and the Uconsloop goes from -2 .. N+1 inclusive and fluxes go from -2 to N+2 inclusive
2608  // same for WENO4
2609  // this is -avgo .. N-1+avgo for Uconsloop and -avgo .. N+avgo for fluxes
2610 
2611  // loop over averaged U to get Uf
2612  // Uconsloop[FIDEL]=0;
2613  // Uconsloop[FJDEL]=0;
2614  // Uconsloop[FKDEL]=0;
2615  Uconsloop[FFACE]=CENT;
2616 
2617  dimen=1;
2618  Uconsloop[FIS]=-avgo[dimen]*N1NOT1;
2619  Uconsloop[FIE]=N1-1+avgo[dimen]*N1NOT1;
2620 
2621  dimen=2;
2622  Uconsloop[FJS]=-avgo[dimen]*N2NOT1;
2623  Uconsloop[FJE]=N2-1+avgo[dimen]*N2NOT1;
2624 
2625  dimen=3;
2626  Uconsloop[FKS]=-avgo[dimen]*N3NOT1;
2627  Uconsloop[FKE]=N3-1+avgo[dimen]*N3NOT1;
2628 
2629  // inversion for this method just involves CZLOOP
2630  }
2631  else{
2632  Uconsloop[FFACE]=CENT;
2633 
2634  dimen=1;
2635  Uconsloop[FIS]=0;
2636  Uconsloop[FIE]=N1-1;
2637 
2638  dimen=2;
2639  Uconsloop[FJS]=0;
2640  Uconsloop[FJE]=N2-1;
2641 
2642  dimen=3;
2643  Uconsloop[FKS]=0;
2644  Uconsloop[FKE]=N3-1;
2645  }
2646 
2647 
2648 
2649  if(extrazones4emf){
2651 
2652  dimen=1;
2653  emfUconsloop[FIS]=Uconsloop[FIS]-avgo[dimen]*N1NOT1;
2654  emfUconsloop[FIE]=Uconsloop[FIE]+avgo[dimen]*N1NOT1;
2655 
2656  dimen=2;
2657  emfUconsloop[FJS]=Uconsloop[FJS]-avgo[dimen]*N2NOT1;
2658  emfUconsloop[FJE]=Uconsloop[FJE]+avgo[dimen]*N2NOT1;
2659 
2660  dimen=3;
2661  emfUconsloop[FKS]=Uconsloop[FKS]-avgo[dimen]*N3NOT1;
2662  emfUconsloop[FKE]=Uconsloop[FKE]+avgo[dimen]*N3NOT1;
2663  }
2664  else{
2666 
2667  dimen=1;
2670 
2671  dimen=2;
2674 
2675  dimen=3;
2678  }
2679 
2680 
2681 
2682 
2683 
2684 
2685  DIMENLOOP(dimen){
2686  for(jj=0;jj<NUMFLUXLOOPNUMBERS;jj++) trifprintf("fluxloop[dimen=%d][%d] = %d\n",dimen,jj,fluxloop[dimen][jj]);
2687  }
2688  DIMENLOOP(dimen){
2689  for(jj=0;jj<NUMFLUXLOOPNUMBERS;jj++) trifprintf("emffluxloop[dimen=%d][%d] = %d\n",dimen,jj,emffluxloop[dimen][jj]);
2690  }
2691  for(jj=0;jj<NUMFLUXLOOPNUMBERS;jj++) trifprintf("Uconsevolveloop[%d] = %d\n",jj,Uconsevolveloop[jj]);
2692  for(jj=0;jj<NUMFLUXLOOPNUMBERS;jj++) trifprintf("Uconsloop[%d] = %d\n",jj,Uconsloop[jj]);
2693  for(jj=0;jj<NUMFLUXLOOPNUMBERS;jj++) trifprintf("emfUconsloop[%d] = %d\n",jj,emfUconsloop[jj]);
2694 
2695 
2696 
2697 
2698 
2699 
2700 
2701 
2702 
2703  return(0);
2704 
2705 }
2706 
2707 
2708 
2710 int get_loop(int pointorlinetype, int interporflux, int dir, struct of_loop *loop)
2711 {
2712 
2713  set_interpalltypes_loop_ranges(pointorlinetype, interporflux, dir, CENT, 0, &(loop->intdir), &(loop->is), &(loop->ie), &(loop->js), &(loop->je), &(loop->ks), &(loop->ke), &(loop->di), &(loop->dj), &(loop->dk), &(loop->bs), &(loop->ps), &(loop->pe), &(loop->be));
2714 
2715  return(0);
2716 
2717 }
2718 
2719 
2720 
2723 int set_interpalltypes_loop_ranges(int pointorlinetype, int interporflux, int dir, int loc, int continuous, int *intdir, int *is, int *ie, int *js, int *je, int *ks, int *ke, int *di, int *dj, int *dk, int *bs, int *ps, int *pe, int *be)
2724 {
2725  int withshifts;
2726 
2727  if(pointorlinetype==INTERPPOINTTYPE){
2728  set_interppoint_loop_ranges(interporflux, dir, loc, continuous, is, ie, js, je, ks, ke, di, dj, dk);
2729  // interpolation is always along dir-direction for point methods
2730  *intdir=dir;
2731  *ps=*is;
2732  *pe=*ie;
2733  // below is largest possible range that includes boundary cells
2734  *bs = *is - N1BND*(dir==1) - N2BND*(dir==2) - N3BND*(dir==3);
2735  *be = *ie + N1BND*(dir==1) + N2BND*(dir==2) + N3BND*(dir==3);
2736  }
2737  else if(pointorlinetype==INTERPLINETYPE){
2738  withshifts=0; // force to be without shifts so results can be put into loop that has shifts embedded
2739  set_interp_loop_gen(withshifts, interporflux, dir, loc, continuous, intdir, is, ie, js, je, ks, ke, di, dj, dk, bs, ps, pe, be);
2740  // transcribe from loop over starting positions to full 3D loop
2741  if(*intdir==1){
2742  *is=*ps;
2743  *ie=*pe;
2744  }
2745  else if(*intdir==2){
2746  *js=*ps;
2747  *je=*pe;
2748  }
2749  else if(*intdir==3){
2750  *ks=*ps;
2751  *ke=*pe;
2752  }
2753  }
2754  else{
2755  dualfprintf(fail_file,"No such pointorlinetype=%d\n",pointorlinetype);
2756  myexit(ERRORCODEBELOWCLEANFINISH+287687456);
2757  }
2758 
2759 
2760  return(0);
2761 
2762 }
2763 
2764 
2765 
2766 
2767 
2768 
2769 
2770 
2773 int pi2Uavg(int *fieldfrompotential, FTYPE (*prim)[NSTORE2][NSTORE3][NPR], FTYPE (*pstag)[NSTORE2][NSTORE3][NPR], FTYPE (*Upoint)[NSTORE2][NSTORE3][NPR], FTYPE (*Uavg)[NSTORE2][NSTORE3][NPR])
2774 {
2775  extern int initial_averageu_fv(int *fieldfrompotential, FTYPE (*prim)[NSTORE2][NSTORE3][NPR], FTYPE (*Upoint)[NSTORE2][NSTORE3][NPR], FTYPE (*Uavg)[NSTORE2][NSTORE3][NPR]);
2776  extern int initial_averageu_fluxrecon(int *fieldfrompotential, FTYPE (*prim)[NSTORE2][NSTORE3][NPR], FTYPE (*Upoint)[NSTORE2][NSTORE3][NPR], FTYPE (*Uavg)[NSTORE2][NSTORE3][NPR]);
2777 
2778 
2779 #pragma omp parallel
2780  {
2781  struct of_geom geom,geomf;
2782  struct of_geom *ptrgeom,*ptrgeomf;
2783  struct of_state q;
2784  int i,j,k;
2785  int pl,pliter;
2786  FTYPE Utemp[NPR];
2787 
2789 
2792 #pragma omp for schedule(OPENMPSCHEDULE(),OPENMPCHUNKSIZE(blocksize))
2794  OPENMP3DLOOPBLOCK2IJK(i,j,k);
2795 
2796 
2797  // set geometry
2798  ptrgeom=&geom; get_geometry(i, j, k, CENT, ptrgeom);
2799 
2800 
2801  // find U(p)
2802  MYFUN(get_state(MAC(prim,i,j,k), ptrgeom, &q),"initbasec:pi2Uavg()", "get_state()", 1);
2803  MYFUN(primtoU(UEVOLVE,MAC(prim,i,j,k), &q, ptrgeom, Utemp, NULL),"initbase.c:pi2Uavg()", "primtoU()", 1);
2804 
2805  PLOOPNOB1(pl) MACP0A1(Upoint,i,j,k,pl)=Utemp[pl];
2806  PLOOPNOB2(pl) MACP0A1(Upoint,i,j,k,pl)=Utemp[pl];
2807 
2808  if(FLUXB==FLUXCTSTAG){
2809  PLOOPBONLY(pl) if(fieldfrompotential[pl-B1+1]==0){
2810  ptrgeomf=&geomf; get_geometry(i, j, k, FACE1+(pl-B1), ptrgeomf);
2811  MACP0A1(Upoint,i,j,k,pl)=MACP0A1(pstag,i,j,k,pl)*(ptrgeomf->gdet);
2812  }
2813  }
2814  else{
2815  PLOOPBONLY(pl) if(fieldfrompotential[pl-B1+1]==0) MACP0A1(Upoint,i,j,k,pl)=Utemp[pl];
2816  }
2817 
2818  // dualfprintf(fail_file,"Upoint[%d][%d][%d][UU]=%21.15g prim[UU]=%21.15g\n",i,j,k,MACP0A1(Upoint,i,j,k,UU)/(ptrgeom->gdet),MACP0A1(prim,i,j,k,UU));
2819  }
2820  }// end parallel region
2821 
2822 
2824  //
2825  // now deal with higher-order interpolations
2826  //
2828  if(DOENOFLUX == ENOFINITEVOLUME){
2829  initial_averageu_fv(fieldfrompotential, prim, Upoint, Uavg);
2830  }
2831  else if(DOENOFLUX == ENOFLUXRECON){
2832  initial_averageu_fluxrecon(fieldfrompotential, prim, Upoint, Uavg);
2833  }
2834  else{
2835  // then just copy over
2837 
2838 
2839 #pragma omp parallel
2840  {
2841  int i,j,k;
2842  int pl,pliter;
2843 
2845 
2848 #pragma omp for schedule(OPENMPSCHEDULE(),OPENMPCHUNKSIZE(blocksize))
2850  OPENMP3DLOOPBLOCK2IJK(i,j,k);
2851 
2852 
2853  PLOOPNOB1(pl) MACP0A1(Uavg,i,j,k,pl)=MACP0A1(Upoint,i,j,k,pl);
2854  PLOOPNOB2(pl) MACP0A1(Uavg,i,j,k,pl)=MACP0A1(Upoint,i,j,k,pl);
2855  PLOOPBONLY(pl) if(fieldfrompotential[pl-B1+1]==0) MACP0A1(Uavg,i,j,k,pl)=MACP0A1(Upoint,i,j,k,pl);
2856  }// end 3D LOOP
2857  }// end parallel region
2858  }// end else
2859 
2860 
2861 
2862 
2863  return(0);
2864 }
2865 
2867 void makedirs(void)
2868 {
2869 
2870 #if( USINGMPIAVOIDMKDIR )
2871  //AT: for certain systems, neither way works to create dirs,
2872  // so not create them at all
2873  //stderrfprintf("USEMPIAVOIDMKDIR==1: User must create dumps and images\n");
2874 #else
2875  if ((mpicombine && (myid == 0)) || (mpicombine == 0)) {
2876 
2877  if(USEMPI && (!MPIAVOIDFORK) || USEMPI==0){
2878  system("mkdir dumps");
2879  system("mkdir images");
2880  }
2881  else{
2882 #ifndef WIN32
2883  // assumes unix commands exist in <sys/stat.h>
2884  // see also "info libc"
2885  // create directory with rxw permissions for user only
2886  mkdir("dumps",0700);
2887  mkdir("images",0700);
2888 #else
2889  stderrfprintf("WIN32: User must create dumps and images\n");
2890 #endif
2891  }
2892  }
2893 
2894 #if(USEMPI)
2895  // all cpus wait for directory to be created
2896  MPI_Barrier(MPI_COMM_GRMHD);
2897 #endif
2898 #endif //USINGMPIAVOIDMKDIR
2899 
2900 }
2901 
2902 
2903 #include<sys/stat.h>
2904 
2905 
2906 
2907 
2908 
2910 int addremovefromnpr(int doadd, int *whichpltoavg, int *ifnotavgthencopy, int *nprlocalstart, int *nprlocalend, int *nprlocallist, FTYPE (*in)[NSTORE2][NSTORE3][NPR], FTYPE (*out)[NSTORE2][NSTORE3][NPR])
2911 {
2912  int addremovefromanynpr(int doadd, int *whichpltoavg, int *ifnotavgthencopy, int *anynprstart, int *anynprend, int *anynprlist, int *nprlocalstart, int *nprlocalend, int *nprlocallist, FTYPE (*in)[NSTORE2][NSTORE3][NPR], FTYPE (*out)[NSTORE2][NSTORE3][NPR]);
2913 
2914  // applies only to NPR type list
2915  addremovefromanynpr(doadd, whichpltoavg, ifnotavgthencopy, &nprstart, &nprend, nprlist, nprlocalstart, nprlocalend, nprlocallist, in, out);
2916 
2917 
2918  return(0);
2919 
2920 }
2921 
2923 int addremovefromanynpr(int doadd, int *whichpltoavg, int *ifnotavgthencopy, int *anynprstart, int *anynprend, int *anynprlist, int *nprlocalstart, int *nprlocalend, int *nprlocallist, FTYPE (*in)[NSTORE2][NSTORE3][NPR], FTYPE (*out)[NSTORE2][NSTORE3][NPR])
2924 {
2925  int pl,pliter;
2926  int pl2,pl3;
2927  int i,j,k;
2928  int num;
2929 
2930 
2931 
2932  if(doadd==REMOVEFROMNPR){
2934  //
2935  // save choice for interpolations
2936  *nprlocalstart=*anynprstart;
2937  *nprlocalend=*anynprend;
2938  PMAXNPRLOOP(pl) nprlocallist[pl]=anynprlist[pl];
2939 
2940  if(anynprlist==nprlist) num=NPR;
2941  else if(anynprlist==npr2interplist) num=NPR2INTERP;
2942  else if(anynprlist==nprboundlist) num=NPRBOUND;
2943  else{
2944  dualfprintf(fail_file,"No such type of list in addremovefromanynpr\n");
2945  myexit(ERRORCODEBELOWCLEANFINISH+7615156);
2946  }
2947 
2948 
2949  // now remove any other pl's not wanting to average for whatever reason
2950  for(pl3=0;pl3<num;pl3++){ // as above, but loop over all undesired quantities
2951  for(pl= *anynprstart;pl<= *anynprend;pl++){
2952  if(whichpltoavg[pl3]==0 && anynprlist[pl]==pl3){
2953  // need to copy over unchanged quantity
2954  if(ifnotavgthencopy[pl3] && in!=NULL && out!=NULL) copy_3d_onepl_fullloop(pl3,in,out); //COMPFULLLOOP MACP0A1(out,i,j,k,pl3)=MACP0A1(in,i,j,k,pl3);
2955  for(pl2=pl+1;pl2<= *anynprend;pl2++) anynprlist[pl2-1]=anynprlist[pl2]; // moving upper to lower index
2956  *anynprend-=1; // removed dir-field
2957  break;
2958  }
2959  }
2960  }
2961 
2962  }
2963  else if(doadd==RESTORENPR){
2964 
2965 
2967  //
2968  // restore choice for interpolations
2969  *anynprstart= *nprlocalstart;
2970  *anynprend= *nprlocalend;
2971  PMAXNPRLOOP(pl) anynprlist[pl]=nprlocallist[pl];
2972  }
2973 
2974 
2975  // PALLLOOP(pl){
2976  // dualfprintf(fail_file,"dir=%d interptype=%d nprstart=%d nprend=%d nprlist[%d]=%d\n",dir,interptype,*anynprstart,*anynprend,pl,anynprlist[pl]);
2977  // }
2978 
2979 
2980  return(0);
2981 
2982 }
2983 
2984 
2987 int transform_primitive_vB(int whichvel, int whichcoord, int i,int j, int k, FTYPE (*p)[NSTORE2][NSTORE3][NPR], FTYPE (*pstag)[NSTORE2][NSTORE3][NPR])
2988 {
2989 
2990  // For p, transform from whichcoord to MCOORD
2991  if (bl2met2metp2v(whichvel,whichcoord,MAC(p,i,j,k), i,j,k) >= 1) FAILSTATEMENT("initbase.c:transform_primitive_vB()", "bl2ks2ksp2v()", 1);
2992 
2993 
2994  return(0);
2995 }
2996 
2997 
2998 
3000 int assert_func_empty( int is_bad_val, char *s, ... )
3001 {
3002  return(is_bad_val);
3003 }
3004 
3006 int assert_func( int is_bad_val, char *s, ... )
3007 {
3008  va_list arglist;
3009  FILE *fileptr = fail_file;
3010 
3011  va_start (arglist, s);
3012 
3013  if( 0 != is_bad_val ) {
3014  if(fileptr==NULL){
3015  stderrfprintf("tried to print to null file pointer: %s\n",s);
3016  fflush(stderr);
3017  }
3018  else{
3019  dualfprintf( fail_file, "Assertion failed: " );
3020  vfprintf (fileptr, s, arglist);
3021  fflush(fileptr);
3022  }
3023  if(myid==0){
3024  vfprintf (stderr, s, arglist);
3025  fflush(stderr);
3026  }
3027  va_end (arglist);
3028 
3029  myexit( 1 );
3030  }
3031 
3032  return is_bad_val;
3033 }
3034 
3035 
3037 void set_array(void *inbufptr, int num, MPI_Datatype datatype, long double value)
3038 {
3039  void *bufptr=NULL;
3040  long double *buf16;
3041  double *buf8;
3042  float *buf4;
3043  unsigned char *buf1;
3044  int *buf4i;
3045  long long int *buf8i;
3046 
3047  long double *inbuf16;
3048  double *inbuf8;
3049  float *inbuf4;
3050  unsigned char *inbuf1;
3051  int *inbuf4i;
3052  long long int *inbuf8i;
3053 
3054  int sizeofdatatype=getsizeofdatatype(datatype);
3055 
3056  int i;
3057  if(datatype==MPI_UNSIGNED_CHAR){ buf1=(unsigned char *)bufptr; inbuf1=(unsigned char *)inbufptr; for(i=0;i<num;i++) inbuf1[i]=(unsigned char)value; }
3058  else if(datatype==MPI_FLOAT){ buf4=(float *)bufptr; inbuf4=(float *)inbufptr; for(i=0;i<num;i++) inbuf4[i]=(float)value; }
3059  else if(datatype==MPI_DOUBLE){ buf8=(double*)bufptr; inbuf8=(double*)inbufptr; for(i=0;i<num;i++) inbuf8[i]=(double)value; }
3060  else if(datatype==MPI_LONG_DOUBLE){ buf16=(long double*)bufptr; inbuf16=(long double*)inbufptr; for(i=0;i<num;i++) inbuf16[i]=(long double)value; }
3061  else if(datatype==MPI_INT){ buf4i=(int *)bufptr; inbuf4i=(int *)inbufptr; for(i=0;i<num;i++) inbuf4i[i]=(int)value; }
3062  else if(datatype==MPI_LONG_LONG_INT){ buf8i=(long long int *)bufptr; inbuf8i=(long long int *)inbufptr; for(i=0;i<num;i++) inbuf8i[i]=(long long int) value; }
3063 
3064 }
3065 
3066 
3068 void debugdivb(void)
3069 {
3070 
3071  // HACK:
3072  bound_uavg(STAGEM1, 1, t, BOUNDPRIMTYPE, GLOBALPOINT(unewglobal),GLOBALPOINT(unewglobal), GLOBALPOINT(unewglobal),1);
3073  // bound_mpi(STAGEM1,1,0,BOUNDPRIMSIMPLETYPE,GLOBALPOINT(udump),NULL,NULL,NULL,NULL);
3074  //bound_mpi(STAGEM1,1,0,BOUNDPRIMSIMPLETYPE,GLOBALPOINT(unewglobal),NULL,NULL,NULL,NULL);
3075 
3076  struct of_geom geomdontuse;
3077  struct of_geom *ptrgeom=&geomdontuse;
3078  int i,j,k;
3079  FULLLOOP{
3080  get_geometry(i,j,k,FACE1,ptrgeom);
3081  GLOBALMACP0A1(pstagglobal,i,j,k,B1)=GLOBALMACP0A1(unewglobal,i,j,k,B1)/ptrgeom->gdet;
3082  get_geometry(i,j,k,FACE2,ptrgeom);
3083  GLOBALMACP0A1(pstagglobal,i,j,k,B2)=GLOBALMACP0A1(unewglobal,i,j,k,B2)/ptrgeom->gdet;
3084  get_geometry(i,j,k,FACE3,ptrgeom);
3085  GLOBALMACP0A1(pstagglobal,i,j,k,B3)=GLOBALMACP0A1(unewglobal,i,j,k,B3)/ptrgeom->gdet;
3086  }
3087 
3088  // dualfprintf(fail_file,"MONKEY: %g\n",GLOBALMACP0A1(unewglobal,0,32,4,B2));
3089  // dualfprintf(fail_file,"PIECE2: %g\n",GLOBALMACP0A1(unewglobal,62,0,30,B2));
3090 
3091  // FULLLOOP{
3092  // if(i==62&&j==0&&k==30 || i==63&&j==0&&k==30) dualfprintf(fail_file,"KILLGODB1: %d %d %g\n",i,k,GLOBALMACP0A1(unewglobal,i,j,k,B1));
3093  // if(i==62&&j==0&&k==30 || i==62&&j==1&&k==30) dualfprintf(fail_file,"KILLGODB2: %d %d %g\n",i,k,GLOBALMACP0A1(unewglobal,i,j,k,B2));
3094  // if(i==62&&j==0&&k==30 || i==62&&j==0&&k==31) dualfprintf(fail_file,"KILLGODB3: %d %d %g\n",i,k,GLOBALMACP0A1(unewglobal,i,j,k,B3));
3095  //}
3096 
3097  FTYPE divbmax=0,divbavg=0;
3098  divbmaxavg(GLOBALPOINT(pdump),&divbmax,&divbavg);
3099  dualfprintf(fail_file,"GOD0: %g %g\n",divbmax,divbavg);
3100  int finalstep=0; // only for diagnostics, no accounting.
3101  FTYPE localt=t;
3102  bound_allprim(STAGEM1,finalstep, localt,GLOBALPOINT(pdump),GLOBALPOINT(pstagdump),GLOBALPOINT(udump), USEMPI);
3103  // dualfprintf(fail_file,"MONKEY1.2: %g\n",GLOBALMACP0A1(unewglobal,0,32,4,B2));
3104  int fakedir=0;
3105  bound_mpi(STAGEM1,finalstep,fakedir,BOUNDPSTAGSIMPLETYPE,GLOBALPOINT(udump),NULL,NULL,NULL,NULL);
3106  // dualfprintf(fail_file,"MONKEY1.3: %g\n",GLOBALMACP0A1(unewglobal,0,32,4,B2));
3107  divbmaxavg(GLOBALPOINT(pdump),&divbmax,&divbavg);
3108  dualfprintf(fail_file,"GOD1: %g %g\n",divbmax,divbavg);
3109 
3110 
3111 
3112 }
3113 
3114