00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <math.h>
00005 #include <mpi.h>
00006
00007 #include <fcntl.h>
00008 #include <sys/stat.h>
00009 #include <sys/types.h>
00010 #include <sys/file.h>
00011 #include <unistd.h>
00012 #include <gsl/gsl_rng.h>
00013
00014 #include "allvars.h"
00015 #include "proto.h"
00016
00021 static FILE *fd;
00022
00023 static void in(int *x, int modus);
00024 static void byten(void *x, size_t n, int modus);
00025
00026
00035 void restart(int modus)
00036 {
00037 char buf[200], buf_bak[200], buf_mv[500];
00038 double save_PartAllocFactor, save_TreeAllocFactor;
00039 int i, nprocgroup, masterTask, groupTask, old_MaxPart, old_MaxNodes;
00040 struct global_data_all_processes all_task0;
00041
00042
00043 sprintf(buf, "%s%s.%d", All.OutputDir, All.RestartFile, ThisTask);
00044 sprintf(buf_bak, "%s%s.%d.bak", All.OutputDir, All.RestartFile, ThisTask);
00045 sprintf(buf_mv, "mv %s %s", buf, buf_bak);
00046
00047
00048 if((NTask < All.NumFilesWrittenInParallel))
00049 {
00050 printf
00051 ("Fatal error.\nNumber of processors must be a smaller or equal than `NumFilesWrittenInParallel'.\n");
00052 endrun(2131);
00053 }
00054
00055 nprocgroup = NTask / All.NumFilesWrittenInParallel;
00056
00057 if((NTask % All.NumFilesWrittenInParallel))
00058 {
00059 nprocgroup++;
00060 }
00061
00062 masterTask = (ThisTask / nprocgroup) * nprocgroup;
00063
00064 for(groupTask = 0; groupTask < nprocgroup; groupTask++)
00065 {
00066 if(ThisTask == (masterTask + groupTask))
00067 {
00068 if(modus)
00069 {
00070 if(!(fd = fopen(buf, "r")))
00071 {
00072 printf("Restart file '%s' not found.\n", buf);
00073 endrun(7870);
00074 }
00075 }
00076 else
00077 {
00078 system(buf_mv);
00079
00080 if(!(fd = fopen(buf, "w")))
00081 {
00082 printf("Restart file '%s' cannot be opened.\n", buf);
00083 endrun(7878);
00084 }
00085 }
00086
00087
00088 save_PartAllocFactor = All.PartAllocFactor;
00089 save_TreeAllocFactor = All.TreeAllocFactor;
00090
00091
00092 byten(&All, sizeof(struct global_data_all_processes), modus);
00093
00094 if(ThisTask == 0 && modus > 0)
00095 all_task0 = All;
00096
00097 if(modus > 0 && groupTask == 0)
00098 {
00099 MPI_Bcast(&all_task0, sizeof(struct global_data_all_processes), MPI_BYTE, 0, MPI_COMM_WORLD);
00100 }
00101
00102 old_MaxPart = All.MaxPart;
00103 old_MaxNodes = All.TreeAllocFactor * All.MaxPart;
00104
00105 if(modus)
00106 {
00107 if(All.PartAllocFactor != save_PartAllocFactor)
00108 {
00109 All.PartAllocFactor = save_PartAllocFactor;
00110 All.MaxPart = All.PartAllocFactor * (All.TotNumPart / NTask);
00111 All.MaxPartSph = All.PartAllocFactor * (All.TotN_gas / NTask);
00112 save_PartAllocFactor = -1;
00113 }
00114
00115 if(All.TreeAllocFactor != save_TreeAllocFactor)
00116 {
00117 All.TreeAllocFactor = save_TreeAllocFactor;
00118 save_TreeAllocFactor = -1;
00119 }
00120
00121 if(all_task0.Time != All.Time)
00122 {
00123 printf("The restart file on task=%d is not consistent with the one on task=0\n", ThisTask);
00124 fflush(stdout);
00125 endrun(16);
00126 }
00127
00128 allocate_memory();
00129 }
00130
00131 in(&NumPart, modus);
00132
00133 if(NumPart > All.MaxPart)
00134 {
00135 printf
00136 ("it seems you have reduced(!) 'PartAllocFactor' below the value of %g needed to load the restart file.\n",
00137 NumPart / (((double) All.TotNumPart) / NTask));
00138 printf("fatal error\n");
00139 endrun(22);
00140 }
00141
00142
00143 byten(&P[0], NumPart * sizeof(struct particle_data), modus);
00144
00145 in(&N_gas, modus);
00146
00147 if(N_gas > 0)
00148 {
00149 if(N_gas > All.MaxPartSph)
00150 {
00151 printf
00152 ("SPH: it seems you have reduced(!) 'PartAllocFactor' below the value of %g needed to load the restart file.\n",
00153 N_gas / (((double) All.TotN_gas) / NTask));
00154 printf("fatal error\n");
00155 endrun(222);
00156 }
00157
00158 byten(&SphP[0], N_gas * sizeof(struct sph_particle_data), modus);
00159 }
00160
00161
00162 byten(gsl_rng_state(random_generator), gsl_rng_size(random_generator), modus);
00163
00164
00165
00166
00167 if(modus)
00168 {
00169 ngb_treeallocate(MAX_NGB);
00170
00171 force_treeallocate(All.TreeAllocFactor * All.MaxPart, All.MaxPart);
00172 }
00173
00174
00175 in(&Numnodestree, modus);
00176
00177 if(Numnodestree > MaxNodes)
00178 {
00179 printf
00180 ("Tree storage: it seems you have reduced(!) 'PartAllocFactor' below the value needed to load the restart file (task=%d). "
00181 "Numnodestree=%d MaxNodes=%d\n", ThisTask, Numnodestree, MaxNodes);
00182 endrun(221);
00183 }
00184
00185 byten(Nodes_base, Numnodestree * sizeof(struct NODE), modus);
00186 byten(Extnodes_base, Numnodestree * sizeof(struct extNODE), modus);
00187
00188 byten(Father, NumPart * sizeof(int), modus);
00189
00190 byten(Nextnode, NumPart * sizeof(int), modus);
00191 byten(Nextnode + All.MaxPart, MAXTOPNODES * sizeof(int), modus);
00192
00193 byten(DomainStartList, NTask * sizeof(int), modus);
00194 byten(DomainEndList, NTask * sizeof(int), modus);
00195 byten(DomainTask, MAXTOPNODES * sizeof(int), modus);
00196 byten(DomainNodeIndex, MAXTOPNODES * sizeof(int), modus);
00197 byten(DomainTreeNodeLen, MAXTOPNODES * sizeof(FLOAT), modus);
00198 byten(DomainHmax, MAXTOPNODES * sizeof(FLOAT), modus);
00199 byten(DomainMoment, MAXTOPNODES * sizeof(struct DomainNODE), modus);
00200
00201 byten(DomainCorner, 3 * sizeof(double), modus);
00202 byten(DomainCenter, 3 * sizeof(double), modus);
00203 byten(&DomainLen, sizeof(double), modus);
00204 byten(&DomainFac, sizeof(double), modus);
00205 byten(&DomainMyStart, sizeof(int), modus);
00206 byten(&DomainMyLast, sizeof(int), modus);
00207
00208 if(modus)
00209 if(All.PartAllocFactor != save_PartAllocFactor || All.TreeAllocFactor != save_TreeAllocFactor)
00210 {
00211 for(i = 0; i < NumPart; i++)
00212 Father[i] += (All.MaxPart - old_MaxPart);
00213
00214 for(i = 0; i < NumPart; i++)
00215 if(Nextnode[i] >= old_MaxPart)
00216 {
00217 if(Nextnode[i] >= old_MaxPart + old_MaxNodes)
00218 Nextnode[i] += (All.MaxPart - old_MaxPart) + (MaxNodes - old_MaxPart);
00219 else
00220 Nextnode[i] += (All.MaxPart - old_MaxPart);
00221 }
00222
00223 for(i = 0; i < Numnodestree; i++)
00224 {
00225 if(Nodes_base[i].u.d.sibling >= old_MaxPart)
00226 {
00227 if(Nodes_base[i].u.d.sibling >= old_MaxPart + old_MaxNodes)
00228 Nodes_base[i].u.d.sibling +=
00229 (All.MaxPart - old_MaxPart) + (MaxNodes - old_MaxNodes);
00230 else
00231 Nodes_base[i].u.d.sibling += (All.MaxPart - old_MaxPart);
00232 }
00233
00234 if(Nodes_base[i].u.d.father >= old_MaxPart)
00235 {
00236 if(Nodes_base[i].u.d.father >= old_MaxPart + old_MaxNodes)
00237 Nodes_base[i].u.d.father += (All.MaxPart - old_MaxPart) + (MaxNodes - old_MaxNodes);
00238 else
00239 Nodes_base[i].u.d.father += (All.MaxPart - old_MaxPart);
00240 }
00241
00242 if(Nodes_base[i].u.d.nextnode >= old_MaxPart)
00243 {
00244 if(Nodes_base[i].u.d.nextnode >= old_MaxPart + old_MaxNodes)
00245 Nodes_base[i].u.d.nextnode +=
00246 (All.MaxPart - old_MaxPart) + (MaxNodes - old_MaxNodes);
00247 else
00248 Nodes_base[i].u.d.nextnode += (All.MaxPart - old_MaxPart);
00249 }
00250 }
00251
00252 for(i = 0; i < MAXTOPNODES; i++)
00253 if(Nextnode[i + All.MaxPart] >= old_MaxPart)
00254 {
00255 if(Nextnode[i + All.MaxPart] >= old_MaxPart + old_MaxNodes)
00256 Nextnode[i + All.MaxPart] += (All.MaxPart - old_MaxPart) + (MaxNodes - old_MaxNodes);
00257 else
00258 Nextnode[i + All.MaxPart] += (All.MaxPart - old_MaxPart);
00259 }
00260
00261 for(i = 0; i < MAXTOPNODES; i++)
00262 if(DomainNodeIndex[i] >= old_MaxPart)
00263 {
00264 if(DomainNodeIndex[i] >= old_MaxPart + old_MaxNodes)
00265 DomainNodeIndex[i] += (All.MaxPart - old_MaxPart) + (MaxNodes - old_MaxNodes);
00266 else
00267 DomainNodeIndex[i] += (All.MaxPart - old_MaxPart);
00268 }
00269 }
00270
00271 fclose(fd);
00272 }
00273 else
00274 {
00275 if(modus > 0 && groupTask == 0)
00276 {
00277 MPI_Bcast(&all_task0, sizeof(struct global_data_all_processes), MPI_BYTE, 0, MPI_COMM_WORLD);
00278 }
00279 }
00280
00281 MPI_Barrier(MPI_COMM_WORLD);
00282 }
00283 }
00284
00285
00286
00289 void byten(void *x, size_t n, int modus)
00290 {
00291 if(modus)
00292 my_fread(x, n, 1, fd);
00293 else
00294 my_fwrite(x, n, 1, fd);
00295 }
00296
00297
00300 void in(int *x, int modus)
00301 {
00302 if(modus)
00303 my_fread(x, 1, sizeof(int), fd);
00304 else
00305 my_fwrite(x, 1, sizeof(int), fd);
00306 }