Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

run.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <math.h>
00005 #include <mpi.h>
00006 #include <unistd.h>
00007 
00008 #include "allvars.h"
00009 #include "proto.h"
00010 
00020 void run(void)
00021 {
00022   FILE *fd;
00023   int stopflag = 0;
00024   char stopfname[200], contfname[200];
00025   double t0, t1;
00026 
00027 
00028   sprintf(stopfname, "%sstop", All.OutputDir);
00029   sprintf(contfname, "%scont", All.OutputDir);
00030   unlink(contfname);
00031 
00032   do                            /* main loop */
00033     {
00034       t0 = second();
00035 
00036       find_next_sync_point_and_drift(); /* find next synchronization point and drift particles to this time.
00037                                          * If needed, this function will also write an output file
00038                                          * at the desired time.
00039                                          */
00040 
00041       every_timestep_stuff();   /* write some info to log-files */
00042 
00043 
00044       domain_Decomposition();   /* do domain decomposition if needed */
00045 
00046 
00047       compute_accelerations(0); /* compute accelerations for 
00048                                  * the particles that are to be advanced  
00049                                  */
00050 
00051       /* check whether we want a full energy statistics */
00052       if((All.Time - All.TimeLastStatistics) >= All.TimeBetStatistics)
00053         {
00054 #ifdef COMPUTE_POTENTIAL_ENERGY
00055           compute_potential();
00056 #endif
00057           energy_statistics();  /* compute and output energy statistics */
00058           All.TimeLastStatistics += All.TimeBetStatistics;
00059         }
00060 
00061       advance_and_find_timesteps();     /* 'kick' active particles in
00062                                          * momentum space and compute new
00063                                          * timesteps for them
00064                                          */
00065       All.NumCurrentTiStep++;
00066 
00067       /* Check whether we need to interrupt the run */
00068       if(ThisTask == 0)
00069         {
00070           /* Is the stop-file present? If yes, interrupt the run. */
00071           if((fd = fopen(stopfname, "r")))
00072             {
00073               fclose(fd);
00074               stopflag = 1;
00075               unlink(stopfname);
00076             }
00077 
00078           /* are we running out of CPU-time ? If yes, interrupt run. */
00079           if(CPUThisRun > 0.85 * All.TimeLimitCPU)
00080             {
00081               printf("reaching time-limit. stopping.\n");
00082               stopflag = 2;
00083             }
00084         }
00085 
00086       MPI_Bcast(&stopflag, 1, MPI_INT, 0, MPI_COMM_WORLD);
00087 
00088       if(stopflag)
00089         {
00090           restart(0);           /* write restart file */
00091           MPI_Barrier(MPI_COMM_WORLD);
00092 
00093           if(stopflag == 2 && ThisTask == 0)
00094             {
00095               if((fd = fopen(contfname, "w")))
00096                 fclose(fd);
00097             }
00098 
00099           if(stopflag == 2 && All.ResubmitOn && ThisTask == 0)
00100             {
00101               close_outputfiles();
00102               system(All.ResubmitCommand);
00103             }
00104           return;
00105         }
00106 
00107       /* is it time to write a regular restart-file? (for security) */
00108       if(ThisTask == 0)
00109         {
00110           if((CPUThisRun - All.TimeLastRestartFile) >= All.CpuTimeBetRestartFile)
00111             {
00112               All.TimeLastRestartFile = CPUThisRun;
00113               stopflag = 3;
00114             }
00115           else
00116             stopflag = 0;
00117         }
00118 
00119       MPI_Bcast(&stopflag, 1, MPI_INT, 0, MPI_COMM_WORLD);
00120 
00121       if(stopflag == 3)
00122         {
00123           restart(0);           /* write an occasional restart file */
00124           stopflag = 0;
00125         }
00126 
00127       t1 = second();
00128 
00129       All.CPU_Total += timediff(t0, t1);
00130       CPUThisRun += timediff(t0, t1);
00131     }
00132   while(All.Ti_Current < TIMEBASE && All.Time <= All.TimeMax);
00133 
00134   restart(0);
00135 
00136   savepositions(All.SnapshotFileCount++);       /* write a last snapshot
00137                                                  * file at final time (will
00138                                                  * be overwritten if
00139                                                  * All.TimeMax is increased
00140                                                  * and the run is continued)
00141                                                  */
00142 }
00143 
00144 
00151 void find_next_sync_point_and_drift(void)
00152 {
00153   int n, min, min_glob, flag, *temp;
00154   double timeold;
00155   double t0, t1;
00156 
00157   t0 = second();
00158 
00159   timeold = All.Time;
00160 
00161   for(n = 1, min = P[0].Ti_endstep; n < NumPart; n++)
00162     if(min > P[n].Ti_endstep)
00163       min = P[n].Ti_endstep;
00164 
00165   MPI_Allreduce(&min, &min_glob, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
00166 
00167   /* We check whether this is a full step where all particles are synchronized */
00168   flag = 1;
00169   for(n = 0; n < NumPart; n++)
00170     if(P[n].Ti_endstep > min_glob)
00171       flag = 0;
00172 
00173   MPI_Allreduce(&flag, &Flag_FullStep, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
00174 
00175 #ifdef PMGRID
00176   if(min_glob > All.PM_Ti_endstep)
00177     {
00178       min_glob = All.PM_Ti_endstep;
00179       Flag_FullStep = 1;
00180     }
00181 #endif
00182 
00183   /* Determine 'NumForceUpdate', i.e. the number of particles on this processor that are going to be active */
00184   for(n = 0, NumForceUpdate = 0; n < NumPart; n++)
00185     {
00186       if(P[n].Ti_endstep == min_glob)
00187 #ifdef SELECTIVE_NO_GRAVITY
00188         if(!((1 << P[n].Type) & (SELECTIVE_NO_GRAVITY)))
00189 #endif
00190           NumForceUpdate++;
00191     }
00192 
00193   /* note: NumForcesSinceLastDomainDecomp has type "long long" */
00194   temp = malloc(NTask * sizeof(int));
00195   MPI_Allgather(&NumForceUpdate, 1, MPI_INT, temp, 1, MPI_INT, MPI_COMM_WORLD);
00196   for(n = 0; n < NTask; n++)
00197     All.NumForcesSinceLastDomainDecomp += temp[n];
00198   free(temp);
00199 
00200 
00201 
00202   t1 = second();
00203 
00204   All.CPU_Predict += timediff(t0, t1);
00205 
00206   while(min_glob >= All.Ti_nextoutput && All.Ti_nextoutput >= 0)
00207     {
00208       move_particles(All.Ti_Current, All.Ti_nextoutput);
00209 
00210       All.Ti_Current = All.Ti_nextoutput;
00211 
00212       if(All.ComovingIntegrationOn)
00213         All.Time = All.TimeBegin * exp(All.Ti_Current * All.Timebase_interval);
00214       else
00215         All.Time = All.TimeBegin + All.Ti_Current * All.Timebase_interval;
00216 
00217 #ifdef OUTPUTPOTENTIAL
00218       All.NumForcesSinceLastDomainDecomp = 1 + All.TotNumPart * All.TreeDomainUpdateFrequency;
00219       domain_Decomposition();
00220       compute_potential();
00221 #endif
00222       savepositions(All.SnapshotFileCount++);   /* write snapshot file */
00223 
00224       All.Ti_nextoutput = find_next_outputtime(All.Ti_nextoutput + 1);
00225     }
00226 
00227   move_particles(All.Ti_Current, min_glob);
00228 
00229   All.Ti_Current = min_glob;
00230 
00231   if(All.ComovingIntegrationOn)
00232     All.Time = All.TimeBegin * exp(All.Ti_Current * All.Timebase_interval);
00233   else
00234     All.Time = All.TimeBegin + All.Ti_Current * All.Timebase_interval;
00235 
00236   All.TimeStep = All.Time - timeold;
00237 }
00238 
00239 
00240 
00244 int find_next_outputtime(int ti_curr)
00245 {
00246   int i, ti, ti_next, iter = 0;
00247   double next, time;
00248 
00249   ti_next = -1;
00250 
00251   if(All.OutputListOn)
00252     {
00253       for(i = 0; i < All.OutputListLength; i++)
00254         {
00255           time = All.OutputListTimes[i];
00256 
00257           if(time >= All.TimeBegin && time <= All.TimeMax)
00258             {
00259               if(All.ComovingIntegrationOn)
00260                 ti = log(time / All.TimeBegin) / All.Timebase_interval;
00261               else
00262                 ti = (time - All.TimeBegin) / All.Timebase_interval;
00263 
00264               if(ti >= ti_curr)
00265                 {
00266                   if(ti_next == -1)
00267                     ti_next = ti;
00268 
00269                   if(ti_next > ti)
00270                     ti_next = ti;
00271                 }
00272             }
00273         }
00274     }
00275   else
00276     {
00277       if(All.ComovingIntegrationOn)
00278         {
00279           if(All.TimeBetSnapshot <= 1.0)
00280             {
00281               printf("TimeBetSnapshot > 1.0 required for your simulation.\n");
00282               endrun(13123);
00283             }
00284         }
00285       else
00286         {
00287           if(All.TimeBetSnapshot <= 0.0)
00288             {
00289               printf("TimeBetSnapshot > 0.0 required for your simulation.\n");
00290               endrun(13123);
00291             }
00292         }
00293 
00294       time = All.TimeOfFirstSnapshot;
00295 
00296       iter = 0;
00297 
00298       while(time < All.TimeBegin)
00299         {
00300           if(All.ComovingIntegrationOn)
00301             time *= All.TimeBetSnapshot;
00302           else
00303             time += All.TimeBetSnapshot;
00304 
00305           iter++;
00306 
00307           if(iter > 1000000)
00308             {
00309               printf("Can't determine next output time.\n");
00310               endrun(110);
00311             }
00312         }
00313 
00314       while(time <= All.TimeMax)
00315         {
00316           if(All.ComovingIntegrationOn)
00317             ti = log(time / All.TimeBegin) / All.Timebase_interval;
00318           else
00319             ti = (time - All.TimeBegin) / All.Timebase_interval;
00320 
00321           if(ti >= ti_curr)
00322             {
00323               ti_next = ti;
00324               break;
00325             }
00326 
00327           if(All.ComovingIntegrationOn)
00328             time *= All.TimeBetSnapshot;
00329           else
00330             time += All.TimeBetSnapshot;
00331 
00332           iter++;
00333 
00334           if(iter > 1000000)
00335             {
00336               printf("Can't determine next output time.\n");
00337               endrun(111);
00338             }
00339         }
00340     }
00341 
00342   if(ti_next == -1)
00343     {
00344       ti_next = 2 * TIMEBASE;   /* this will prevent any further output */
00345 
00346       if(ThisTask == 0)
00347         printf("\nThere is no valid time for a further snapshot file.\n");
00348     }
00349   else
00350     {
00351       if(All.ComovingIntegrationOn)
00352         next = All.TimeBegin * exp(ti_next * All.Timebase_interval);
00353       else
00354         next = All.TimeBegin + ti_next * All.Timebase_interval;
00355 
00356       if(ThisTask == 0)
00357         printf("\nSetting next time for snapshot file to Time_next= %g\n\n", next);
00358     }
00359 
00360   return ti_next;
00361 }
00362 
00363 
00364 
00365 
00370 void every_timestep_stuff(void)
00371 {
00372   double z;
00373 
00374   if(ThisTask == 0)
00375     {
00376       if(All.ComovingIntegrationOn)
00377         {
00378           z = 1.0 / (All.Time) - 1;
00379           fprintf(FdInfo, "\nBegin Step %d, Time: %g, Redshift: %g, Systemstep: %g, Dloga: %g\n",
00380                   All.NumCurrentTiStep, All.Time, z, All.TimeStep,
00381                   log(All.Time) - log(All.Time - All.TimeStep));
00382           printf("\nBegin Step %d, Time: %g, Redshift: %g, Systemstep: %g, Dloga: %g\n", All.NumCurrentTiStep,
00383                  All.Time, z, All.TimeStep, log(All.Time) - log(All.Time - All.TimeStep));
00384           fflush(FdInfo);
00385         }
00386       else
00387         {
00388           fprintf(FdInfo, "\nBegin Step %d, Time: %g, Systemstep: %g\n", All.NumCurrentTiStep, All.Time,
00389                   All.TimeStep);
00390           printf("\nBegin Step %d, Time: %g, Systemstep: %g\n", All.NumCurrentTiStep, All.Time, All.TimeStep);
00391           fflush(FdInfo);
00392         }
00393 
00394       fprintf(FdCPU, "Step %d, Time: %g, CPUs: %d\n", All.NumCurrentTiStep, All.Time, NTask);
00395 
00396       fprintf(FdCPU,
00397               "%10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f %10.2f\n",
00398               All.CPU_Total, All.CPU_Gravity, All.CPU_Hydro, All.CPU_Domain, All.CPU_Potential,
00399               All.CPU_Predict, All.CPU_TimeLine, All.CPU_Snapshot, All.CPU_TreeWalk, All.CPU_TreeConstruction,
00400               All.CPU_CommSum, All.CPU_Imbalance, All.CPU_HydCompWalk, All.CPU_HydCommSumm,
00401               All.CPU_HydImbalance, All.CPU_EnsureNgb, All.CPU_PM, All.CPU_Peano);
00402       fflush(FdCPU);
00403     }
00404 
00405   set_random_numbers();
00406 }
00407 
00408 
00413 void energy_statistics(void)
00414 {
00415   compute_global_quantities_of_system();
00416 
00417   if(ThisTask == 0)
00418     {
00419       fprintf(FdEnergy,
00420               "%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g\n",
00421               All.Time, SysState.EnergyInt, SysState.EnergyPot, SysState.EnergyKin, SysState.EnergyIntComp[0],
00422               SysState.EnergyPotComp[0], SysState.EnergyKinComp[0], SysState.EnergyIntComp[1],
00423               SysState.EnergyPotComp[1], SysState.EnergyKinComp[1], SysState.EnergyIntComp[2],
00424               SysState.EnergyPotComp[2], SysState.EnergyKinComp[2], SysState.EnergyIntComp[3],
00425               SysState.EnergyPotComp[3], SysState.EnergyKinComp[3], SysState.EnergyIntComp[4],
00426               SysState.EnergyPotComp[4], SysState.EnergyKinComp[4], SysState.EnergyIntComp[5],
00427               SysState.EnergyPotComp[5], SysState.EnergyKinComp[5], SysState.MassComp[0],
00428               SysState.MassComp[1], SysState.MassComp[2], SysState.MassComp[3], SysState.MassComp[4],
00429               SysState.MassComp[5]);
00430 
00431       fflush(FdEnergy);
00432     }
00433 }

Generated on Sun May 22 17:33:29 2005 for GADGET-2 by  doxygen 1.3.9.1