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
00033 {
00034 t0 = second();
00035
00036 find_next_sync_point_and_drift();
00037
00038
00039
00040
00041 every_timestep_stuff();
00042
00043
00044 domain_Decomposition();
00045
00046
00047 compute_accelerations(0);
00048
00049
00050
00051
00052 if((All.Time - All.TimeLastStatistics) >= All.TimeBetStatistics)
00053 {
00054 #ifdef COMPUTE_POTENTIAL_ENERGY
00055 compute_potential();
00056 #endif
00057 energy_statistics();
00058 All.TimeLastStatistics += All.TimeBetStatistics;
00059 }
00060
00061 advance_and_find_timesteps();
00062
00063
00064
00065 All.NumCurrentTiStep++;
00066
00067
00068 if(ThisTask == 0)
00069 {
00070
00071 if((fd = fopen(stopfname, "r")))
00072 {
00073 fclose(fd);
00074 stopflag = 1;
00075 unlink(stopfname);
00076 }
00077
00078
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);
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
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);
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++);
00137
00138
00139
00140
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
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
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
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++);
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;
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 }