00001 #include <stdlib.h>
00002 #include <string.h>
00003 #include <math.h>
00004 #include <mpi.h>
00005
00006 #include "allvars.h"
00007 #include "proto.h"
00008
00009
00020 void init(void)
00021 {
00022 int i, j;
00023 double a3;
00024
00025 All.Time = All.TimeBegin;
00026
00027 switch (All.ICFormat)
00028 {
00029 case 1:
00030 #if (MAKEGLASS > 1)
00031 seed_glass();
00032 #else
00033 read_ic(All.InitCondFile);
00034 #endif
00035 break;
00036 case 2:
00037 case 3:
00038 read_ic(All.InitCondFile);
00039 break;
00040 default:
00041 if(ThisTask == 0)
00042 printf("ICFormat=%d not supported.\n", All.ICFormat);
00043 endrun(0);
00044 }
00045
00046 All.Time = All.TimeBegin;
00047 All.Ti_Current = 0;
00048
00049 if(All.ComovingIntegrationOn)
00050 {
00051 All.Timebase_interval = (log(All.TimeMax) - log(All.TimeBegin)) / TIMEBASE;
00052 a3 = All.Time * All.Time * All.Time;
00053 }
00054 else
00055 {
00056 All.Timebase_interval = (All.TimeMax - All.TimeBegin) / TIMEBASE;
00057 a3 = 1;
00058 }
00059
00060 set_softenings();
00061
00062 All.NumCurrentTiStep = 0;
00063 All.SnapshotFileCount = 0;
00064 if(RestartFlag == 2)
00065 All.SnapshotFileCount = atoi(All.InitCondFile + strlen(All.InitCondFile) - 3) + 1;
00066
00067 All.TotNumOfForces = 0;
00068 All.NumForcesSinceLastDomainDecomp = 0;
00069
00070 if(All.ComovingIntegrationOn)
00071 if(All.PeriodicBoundariesOn == 1)
00072 check_omega();
00073
00074 All.TimeLastStatistics = All.TimeBegin - All.TimeBetStatistics;
00075
00076 if(All.ComovingIntegrationOn)
00077 {
00078 for(i = 0; i < NumPart; i++)
00079 for(j = 0; j < 3; j++)
00080 P[i].Vel[j] *= sqrt(All.Time) * All.Time;
00081 }
00082
00083 for(i = 0; i < NumPart; i++)
00084 {
00085 for(j = 0; j < 3; j++)
00086 P[i].GravAccel[j] = 0;
00087 #ifdef PMGRID
00088 for(j = 0; j < 3; j++)
00089 P[i].GravPM[j] = 0;
00090 #endif
00091 P[i].Ti_endstep = 0;
00092 P[i].Ti_begstep = 0;
00093
00094 P[i].OldAcc = 0;
00095 P[i].GravCost = 1;
00096 P[i].Potential = 0;
00097 }
00098
00099 #ifdef PMGRID
00100 All.PM_Ti_endstep = All.PM_Ti_begstep = 0;
00101 #endif
00102
00103 #ifdef FLEXSTEPS
00104 All.PresentMinStep = TIMEBASE;
00105 for(i = 0; i < NumPart; i++)
00106 {
00107 P[i].FlexStepGrp = (int) (TIMEBASE * get_random_number(P[i].ID));
00108 }
00109 #endif
00110
00111
00112 for(i = 0; i < N_gas; i++)
00113 {
00114 for(j = 0; j < 3; j++)
00115 {
00116 SphP[i].VelPred[j] = P[i].Vel[j];
00117 SphP[i].HydroAccel[j] = 0;
00118 }
00119
00120 SphP[i].DtEntropy = 0;
00121
00122 if(RestartFlag == 0)
00123 {
00124 SphP[i].Hsml = 0;
00125 SphP[i].Density = -1;
00126 }
00127 }
00128
00129 ngb_treeallocate(MAX_NGB);
00130
00131 force_treeallocate(All.TreeAllocFactor * All.MaxPart, All.MaxPart);
00132
00133 All.NumForcesSinceLastDomainDecomp = 1 + All.TotNumPart * All.TreeDomainUpdateFrequency;
00134
00135 Flag_FullStep = 1;
00136
00137 domain_Decomposition();
00138
00139 ngb_treebuild();
00140
00141 setup_smoothinglengths();
00142
00143 TreeReconstructFlag = 1;
00144
00145
00146
00147
00148
00149
00150 #ifndef ISOTHERM_EQS
00151 if(header.flag_entropy_instead_u == 0)
00152 for(i = 0; i < N_gas; i++)
00153 SphP[i].Entropy = GAMMA_MINUS1 * SphP[i].Entropy / pow(SphP[i].Density / a3, GAMMA_MINUS1);
00154 #endif
00155 }
00156
00157
00161 void check_omega(void)
00162 {
00163 double mass = 0, masstot, omega;
00164 int i;
00165
00166 for(i = 0; i < NumPart; i++)
00167 mass += P[i].Mass;
00168
00169 MPI_Allreduce(&mass, &masstot, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
00170
00171 omega =
00172 masstot / (All.BoxSize * All.BoxSize * All.BoxSize) / (3 * All.Hubble * All.Hubble / (8 * M_PI * All.G));
00173
00174 if(fabs(omega - All.Omega0) > 1.0e-3)
00175 {
00176 if(ThisTask == 0)
00177 {
00178 printf("\n\nI've found something odd!\n");
00179 printf
00180 ("The mass content accounts only for Omega=%g,\nbut you specified Omega=%g in the parameterfile.\n",
00181 omega, All.Omega0);
00182 printf("\nI better stop.\n");
00183
00184 fflush(stdout);
00185 }
00186 endrun(1);
00187 }
00188 }
00189
00190
00191
00198 void setup_smoothinglengths(void)
00199 {
00200 int i, no, p;
00201
00202 if(RestartFlag == 0)
00203 {
00204
00205 for(i = 0; i < N_gas; i++)
00206 {
00207 no = Father[i];
00208
00209 while(10 * All.DesNumNgb * P[i].Mass > Nodes[no].u.d.mass)
00210 {
00211 p = Nodes[no].u.d.father;
00212
00213 if(p < 0)
00214 break;
00215
00216 no = p;
00217 }
00218 #ifndef TWODIMS
00219 SphP[i].Hsml =
00220 pow(3.0 / (4 * M_PI) * All.DesNumNgb * P[i].Mass / Nodes[no].u.d.mass, 1.0 / 3) * Nodes[no].len;
00221 #else
00222 SphP[i].Hsml =
00223 pow(1.0 / (M_PI) * All.DesNumNgb * P[i].Mass / Nodes[no].u.d.mass, 1.0 / 2) * Nodes[no].len;
00224 #endif
00225 }
00226 }
00227
00228 density();
00229 }
00230
00231
00235 #if (MAKEGLASS > 1)
00236 void seed_glass(void)
00237 {
00238 int i, k, n_for_this_task;
00239 double Range[3], LowerBound[3];
00240 double drandom, partmass;
00241 long long IDstart;
00242
00243 All.TotNumPart = MAKEGLASS;
00244 partmass = All.Omega0 * (3 * All.Hubble * All.Hubble / (8 * M_PI * All.G))
00245 * (All.BoxSize * All.BoxSize * All.BoxSize) / All.TotNumPart;
00246
00247 All.MaxPart = All.PartAllocFactor * (All.TotNumPart / NTask);
00248
00249 allocate_memory();
00250
00251 header.npartTotal[1] = All.TotNumPart;
00252 header.mass[1] = partmass;
00253
00254 if(ThisTask == 0)
00255 {
00256 printf("\nGlass initialising\nPartMass= %g\n", partmass);
00257 printf("TotNumPart= %d%09d\n\n",
00258 (int) (All.TotNumPart / 1000000000), (int) (All.TotNumPart % 1000000000));
00259 }
00260
00261
00262 n_for_this_task = All.TotNumPart / NTask;
00263
00264 if(ThisTask == NTask - 1)
00265 n_for_this_task = All.TotNumPart - (NTask - 1) * n_for_this_task;
00266
00267 NumPart = 0;
00268 IDstart = 1 + (All.TotNumPart / NTask) * ThisTask;
00269
00270
00271
00272 Range[0] = Range[1] = All.BoxSize;
00273 Range[2] = All.BoxSize / NTask;
00274 LowerBound[0] = LowerBound[1] = 0;
00275 LowerBound[2] = ThisTask * Range[2];
00276
00277 srand48(ThisTask);
00278
00279 for(i = 0; i < n_for_this_task; i++)
00280 {
00281 for(k = 0; k < 3; k++)
00282 {
00283 drandom = drand48();
00284
00285 P[i].Pos[k] = LowerBound[k] + Range[k] * drandom;
00286 P[i].Vel[k] = 0;
00287 }
00288
00289 P[i].Mass = partmass;
00290 P[i].Type = 1;
00291 P[i].ID = IDstart + i;
00292
00293 NumPart++;
00294 }
00295 }
00296 #endif