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

io.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 <errno.h>
00007 
00008 #ifdef HAVE_HDF5
00009 #include <hdf5.h>
00010 #endif
00011 
00012 #include "allvars.h"
00013 #include "proto.h"
00014 
00015 
00016 
00021 static int n_type[6];
00022 static long long ntot_type_all[6];
00023 
00024 
00025 
00026 
00033 void savepositions(int num)
00034 {
00035   double t0, t1;
00036   char buf[500];
00037   int i, j, *temp, n, filenr, gr, ngroups, masterTask, lastTask;
00038 
00039   t0 = second();
00040 
00041   if(ThisTask == 0)
00042     printf("\nwriting snapshot file... \n");
00043 
00044 #if defined(SFR) || defined(BLACK_HOLES)
00045   rearrange_particle_sequence();
00046   /* ensures that new tree will be constructed */
00047   All.NumForcesSinceLastDomainDecomp = 1 + All.TreeDomainUpdateFrequency * All.TotNumPart;
00048 #endif
00049 
00050   if(NTask < All.NumFilesPerSnapshot)
00051     {
00052       if(ThisTask == 0)
00053         printf("Fatal error.\nNumber of processors must be larger or equal than All.NumFilesPerSnapshot.\n");
00054       endrun(0);
00055     }
00056   if(All.SnapFormat < 1 || All.SnapFormat > 3)
00057     {
00058       if(ThisTask == 0)
00059         printf("Unsupported File-Format\n");
00060       endrun(0);
00061     }
00062 #ifndef  HAVE_HDF5
00063   if(All.SnapFormat == 3)
00064     {
00065       if(ThisTask == 0)
00066         printf("Code wasn't compiled with HDF5 support enabled!\n");
00067       endrun(0);
00068     }
00069 #endif
00070 
00071 
00072   /* determine global and local particle numbers */
00073   for(n = 0; n < 6; n++)
00074     n_type[n] = 0;
00075 
00076   for(n = 0; n < NumPart; n++)
00077     n_type[P[n].Type]++;
00078 
00079   /* because ntot_type_all[] is of type `long long', we cannot do a simple
00080    * MPI_Allreduce() to sum the total particle numbers 
00081    */
00082   temp = malloc(NTask * 6 * sizeof(int));
00083   MPI_Allgather(n_type, 6, MPI_INT, temp, 6, MPI_INT, MPI_COMM_WORLD);
00084   for(i = 0; i < 6; i++)
00085     {
00086       ntot_type_all[i] = 0;
00087       for(j = 0; j < NTask; j++)
00088         ntot_type_all[i] += temp[j * 6 + i];
00089     }
00090   free(temp);
00091 
00092 
00093   /* assign processors to output files */
00094   distribute_file(All.NumFilesPerSnapshot, 0, 0, NTask - 1, &filenr, &masterTask, &lastTask);
00095 
00096   fill_Tab_IO_Labels();
00097 
00098   if(All.NumFilesPerSnapshot > 1)
00099     sprintf(buf, "%s%s_%03d.%d", All.OutputDir, All.SnapshotFileBase, num, filenr);
00100   else
00101     sprintf(buf, "%s%s_%03d", All.OutputDir, All.SnapshotFileBase, num);
00102 
00103   ngroups = All.NumFilesPerSnapshot / All.NumFilesWrittenInParallel;
00104   if((All.NumFilesPerSnapshot % All.NumFilesWrittenInParallel))
00105     ngroups++;
00106 
00107   for(gr = 0; gr < ngroups; gr++)
00108     {
00109       if((filenr / All.NumFilesWrittenInParallel) == gr)        /* ok, it's this processor's turn */
00110         write_file(buf, masterTask, lastTask);
00111       MPI_Barrier(MPI_COMM_WORLD);
00112     }
00113 
00114 
00115   if(ThisTask == 0)
00116     printf("done with snapshot.\n");
00117 
00118   t1 = second();
00119 
00120   All.CPU_Snapshot += timediff(t0, t1);
00121 
00122 }
00123 
00124 
00125 
00129 void fill_write_buffer(enum iofields blocknr, int *startindex, int pc, int type)
00130 {
00131   int n, k, pindex;
00132   float *fp;
00133 
00134 #ifdef LONGIDS
00135   long long *ip;
00136 #else
00137   int *ip;
00138 #endif
00139 
00140 #ifdef PERIODIC
00141   FLOAT boxSize;
00142 #endif
00143 #ifdef PMGRID
00144   double dt_gravkick_pm = 0;
00145 #endif
00146   double dt_gravkick, dt_hydrokick, a3inv = 1, fac1, fac2;
00147 
00148 
00149   if(All.ComovingIntegrationOn)
00150     {
00151       a3inv = 1 / (All.Time * All.Time * All.Time);
00152       fac1 = 1 / (All.Time * All.Time);
00153       fac2 = 1 / pow(All.Time, 3 * GAMMA - 2);
00154     }
00155   else
00156     a3inv = fac1 = fac2 = 1;
00157 
00158 #ifdef PMGRID
00159   if(All.ComovingIntegrationOn)
00160     dt_gravkick_pm =
00161       get_gravkick_factor(All.PM_Ti_begstep,
00162                           All.Ti_Current) -
00163       get_gravkick_factor(All.PM_Ti_begstep, (All.PM_Ti_begstep + All.PM_Ti_endstep) / 2);
00164   else
00165     dt_gravkick_pm = (All.Ti_Current - (All.PM_Ti_begstep + All.PM_Ti_endstep) / 2) * All.Timebase_interval;
00166 #endif
00167 
00168 
00169 
00170   fp = CommBuffer;
00171   ip = CommBuffer;
00172 
00173   pindex = *startindex;
00174 
00175   switch (blocknr)
00176     {
00177     case IO_POS:                /* positions */
00178       for(n = 0; n < pc; pindex++)
00179         if(P[pindex].Type == type)
00180           {
00181             for(k = 0; k < 3; k++)
00182               {
00183                 fp[k] = P[pindex].Pos[k];
00184 #ifdef PERIODIC
00185                 boxSize = All.BoxSize;
00186 #ifdef LONG_X
00187                 if(k == 0)
00188                   boxSize = All.BoxSize * LONG_X;
00189 #endif
00190 #ifdef LONG_Y
00191                 if(k == 1)
00192                   boxSize = All.BoxSize * LONG_Y;
00193 #endif
00194 #ifdef LONG_Z
00195                 if(k == 2)
00196                   boxSize = All.BoxSize * LONG_Z;
00197 #endif
00198                 while(fp[k] < 0)
00199                   fp[k] += boxSize;
00200                 while(fp[k] >= boxSize)
00201                   fp[k] -= boxSize;
00202 #endif
00203               }
00204             n++;
00205             fp += 3;
00206           }
00207       break;
00208 
00209     case IO_VEL:                /* velocities */
00210       for(n = 0; n < pc; pindex++)
00211         if(P[pindex].Type == type)
00212           {
00213             if(All.ComovingIntegrationOn)
00214               {
00215                 dt_gravkick =
00216                   get_gravkick_factor(P[pindex].Ti_begstep,
00217                                       All.Ti_Current) -
00218                   get_gravkick_factor(P[pindex].Ti_begstep,
00219                                       (P[pindex].Ti_begstep + P[pindex].Ti_endstep) / 2);
00220                 dt_hydrokick =
00221                   get_hydrokick_factor(P[pindex].Ti_begstep,
00222                                        All.Ti_Current) -
00223                   get_hydrokick_factor(P[pindex].Ti_begstep,
00224                                        (P[pindex].Ti_begstep + P[pindex].Ti_endstep) / 2);
00225               }
00226             else
00227               dt_gravkick = dt_hydrokick =
00228                 (All.Ti_Current - (P[pindex].Ti_begstep + P[pindex].Ti_endstep) / 2) * All.Timebase_interval;
00229 
00230             for(k = 0; k < 3; k++)
00231               {
00232                 fp[k] = P[pindex].Vel[k] + P[pindex].GravAccel[k] * dt_gravkick;
00233                 if(P[pindex].Type == 0)
00234                   fp[k] += SphP[pindex].HydroAccel[k] * dt_hydrokick;
00235               }
00236 #ifdef PMGRID
00237             for(k = 0; k < 3; k++)
00238               fp[k] += P[pindex].GravPM[k] * dt_gravkick_pm;
00239 #endif
00240             for(k = 0; k < 3; k++)
00241               fp[k] *= sqrt(a3inv);
00242 
00243             n++;
00244             fp += 3;
00245           }
00246       break;
00247 
00248     case IO_ID:         /* particle ID */
00249       for(n = 0; n < pc; pindex++)
00250         if(P[pindex].Type == type)
00251           {
00252             *ip++ = P[pindex].ID;
00253             n++;
00254           }
00255       break;
00256 
00257     case IO_MASS:               /* particle mass */
00258       for(n = 0; n < pc; pindex++)
00259         if(P[pindex].Type == type)
00260           {
00261             *fp++ = P[pindex].Mass;
00262             n++;
00263           }
00264       break;
00265 
00266     case IO_U:                  /* internal energy */
00267       for(n = 0; n < pc; pindex++)
00268         if(P[pindex].Type == type)
00269           {
00270 #ifdef ISOTHERM_EQS
00271             *fp++ = SphP[pindex].Entropy;
00272 #else
00273             *fp++ =
00274               dmax(All.MinEgySpec,
00275                    SphP[pindex].Entropy / GAMMA_MINUS1 * pow(SphP[pindex].Density * a3inv, GAMMA_MINUS1));
00276 #endif
00277             n++;
00278           }
00279       break;
00280 
00281     case IO_RHO:                /* density */
00282       for(n = 0; n < pc; pindex++)
00283         if(P[pindex].Type == type)
00284           {
00285             *fp++ = SphP[pindex].Density;
00286             n++;
00287           }
00288       break;
00289 
00290     case IO_HSML:               /* SPH smoothing length */
00291       for(n = 0; n < pc; pindex++)
00292         if(P[pindex].Type == type)
00293           {
00294             *fp++ = SphP[pindex].Hsml;
00295             n++;
00296           }
00297       break;
00298 
00299 
00300     case IO_POT:                /* gravitational potential */
00301 #ifdef OUTPUTPOTENTIAL
00302       for(n = 0; n < pc; pindex++)
00303         if(P[pindex].Type == type)
00304           {
00305             *fp++ = P[pindex].Potential;
00306             n++;
00307           }
00308 #endif
00309       break;
00310 
00311     case IO_ACCEL:              /* acceleration */
00312 #ifdef OUTPUTACCELERATION
00313       for(n = 0; n < pc; pindex++)
00314         if(P[pindex].Type == type)
00315           {
00316             for(k = 0; k < 3; k++)
00317               fp[k] = fac1 * P[pindex].GravAccel[k];
00318 #ifdef PMGRID
00319             for(k = 0; k < 3; k++)
00320               fp[k] += fac1 * P[pindex].GravPM[k];
00321 #endif
00322             if(P[pindex].Type == 0)
00323               for(k = 0; k < 3; k++)
00324                 fp[k] += fac2 * SphP[pindex].HydroAccel[k];
00325             fp += 3;
00326             n++;
00327           }
00328 #endif
00329       break;
00330 
00331     case IO_DTENTR:             /* rate of change of entropy */
00332 #ifdef OUTPUTCHANGEOFENTROPY
00333       for(n = 0; n < pc; pindex++)
00334         if(P[pindex].Type == type)
00335           {
00336             *fp++ = SphP[pindex].DtEntropy;
00337             n++;
00338           }
00339 #endif
00340       break;
00341 
00342     case IO_TSTP:               /* timestep  */
00343 #ifdef OUTPUTTIMESTEP
00344 
00345       for(n = 0; n < pc; pindex++)
00346         if(P[pindex].Type == type)
00347           {
00348             *fp++ = (P[pindex].Ti_endstep - P[pindex].Ti_begstep) * All.Timebase_interval;
00349             n++;
00350           }
00351 #endif
00352       break;
00353 
00354     }
00355 
00356   *startindex = pindex;
00357 }
00358 
00359 
00360 
00361 
00366 int get_bytes_per_blockelement(enum iofields blocknr)
00367 {
00368   int bytes_per_blockelement = 0;
00369 
00370   switch (blocknr)
00371     {
00372     case IO_POS:
00373     case IO_VEL:
00374     case IO_ACCEL:
00375       bytes_per_blockelement = 3 * sizeof(float);
00376       break;
00377 
00378     case IO_ID:
00379 #ifdef LONGIDS
00380       bytes_per_blockelement = sizeof(long long);
00381 #else
00382       bytes_per_blockelement = sizeof(int);
00383 #endif
00384       break;
00385 
00386     case IO_MASS:
00387     case IO_U:
00388     case IO_RHO:
00389     case IO_HSML:
00390     case IO_POT:
00391     case IO_DTENTR:
00392     case IO_TSTP:
00393       bytes_per_blockelement = sizeof(float);
00394       break;
00395     }
00396 
00397   return bytes_per_blockelement;
00398 }
00399 
00400 
00405 int get_datatype_in_block(enum iofields blocknr)
00406 {
00407   int typekey;
00408 
00409   switch (blocknr)
00410     {
00411     case IO_ID:
00412 #ifdef LONGIDS
00413       typekey = 2;              /* native long long */
00414 #else
00415       typekey = 0;              /* native int */
00416 #endif
00417       break;
00418 
00419     default:
00420       typekey = 1;              /* native float */
00421       break;
00422     }
00423 
00424   return typekey;
00425 }
00426 
00427 
00432 int get_values_per_blockelement(enum iofields blocknr)
00433 {
00434   int values = 0;
00435 
00436   switch (blocknr)
00437     {
00438     case IO_POS:
00439     case IO_VEL:
00440     case IO_ACCEL:
00441       values = 3;
00442       break;
00443 
00444     case IO_ID:
00445     case IO_MASS:
00446     case IO_U:
00447     case IO_RHO:
00448     case IO_HSML:
00449     case IO_POT:
00450     case IO_DTENTR:
00451     case IO_TSTP:
00452       values = 1;
00453       break;
00454     }
00455 
00456   return values;
00457 }
00458 
00459 
00465 int get_particles_in_block(enum iofields blocknr, int *typelist)
00466 {
00467   int i, nall, ntot_withmasses, ngas, nstars;
00468 
00469   nall = 0;
00470   ntot_withmasses = 0;
00471 
00472   for(i = 0; i < 6; i++)
00473     {
00474       typelist[i] = 0;
00475 
00476       if(header.npart[i] > 0)
00477         {
00478           nall += header.npart[i];
00479           typelist[i] = 1;
00480         }
00481 
00482       if(All.MassTable[i] == 0)
00483         ntot_withmasses += header.npart[i];
00484     }
00485 
00486   ngas = header.npart[0];
00487   nstars = header.npart[4];
00488 
00489 
00490   switch (blocknr)
00491     {
00492     case IO_POS:
00493     case IO_VEL:
00494     case IO_ACCEL:
00495     case IO_TSTP:
00496     case IO_ID:
00497     case IO_POT:
00498       return nall;
00499       break;
00500 
00501     case IO_MASS:
00502       for(i = 0; i < 6; i++)
00503         {
00504           typelist[i] = 0;
00505           if(All.MassTable[i] == 0 && header.npart[i] > 0)
00506             typelist[i] = 1;
00507         }
00508       return ntot_withmasses;
00509       break;
00510 
00511     case IO_U:
00512     case IO_RHO:
00513     case IO_HSML:
00514     case IO_DTENTR:
00515       for(i = 1; i < 6; i++)
00516         typelist[i] = 0;
00517       return ngas;
00518       break;
00519     }
00520 
00521   endrun(212);
00522   return 0;
00523 }
00524 
00525 
00526 
00532 int blockpresent(enum iofields blocknr)
00533 {
00534 
00535 #ifndef OUTPUTPOTENTIAL
00536   if(blocknr == IO_POT)
00537     return 0;
00538 #endif
00539 
00540 #ifndef OUTPUTACCELERATION
00541   if(blocknr == IO_ACCEL)
00542     return 0;
00543 #endif
00544 
00545 #ifndef OUTPUTCHANGEOFENTROPY
00546   if(blocknr == IO_DTENTR)
00547     return 0;
00548 #endif
00549 
00550 #ifndef OUTPUTTIMESTEP
00551   if(blocknr == IO_TSTP)
00552     return 0;
00553 #endif
00554 
00555   return 1;                     /* default: present */
00556 }
00557 
00558 
00559 
00560 
00566 void fill_Tab_IO_Labels(void)
00567 {
00568   enum iofields i;
00569 
00570   for(i = 0; i < IO_NBLOCKS; i++)
00571     switch (i)
00572       {
00573       case IO_POS:
00574         strncpy(Tab_IO_Labels[IO_POS], "POS ", 4);
00575         break;
00576       case IO_VEL:
00577         strncpy(Tab_IO_Labels[IO_VEL], "VEL ", 4);
00578         break;
00579       case IO_ID:
00580         strncpy(Tab_IO_Labels[IO_ID], "ID  ", 4);
00581         break;
00582       case IO_MASS:
00583         strncpy(Tab_IO_Labels[IO_MASS], "MASS", 4);
00584         break;
00585       case IO_U:
00586         strncpy(Tab_IO_Labels[IO_U], "U   ", 4);
00587         break;
00588       case IO_RHO:
00589         strncpy(Tab_IO_Labels[IO_RHO], "RHO ", 4);
00590         break;
00591       case IO_HSML:
00592         strncpy(Tab_IO_Labels[IO_HSML], "HSML", 4);
00593         break;
00594       case IO_POT:
00595         strncpy(Tab_IO_Labels[IO_POT], "POT ", 4);
00596         break;
00597       case IO_ACCEL:
00598         strncpy(Tab_IO_Labels[IO_ACCEL], "ACCE", 4);
00599         break;
00600       case IO_DTENTR:
00601         strncpy(Tab_IO_Labels[IO_DTENTR], "ENDT", 4);
00602         break;
00603       case IO_TSTP:
00604         strncpy(Tab_IO_Labels[IO_TSTP], "TSTP", 4);
00605         break;
00606       }
00607 }
00608 
00613 void get_dataset_name(enum iofields blocknr, char *buf)
00614 {
00615 
00616   strcpy(buf, "default");
00617 
00618   switch (blocknr)
00619     {
00620     case IO_POS:
00621       strcpy(buf, "Coordinates");
00622       break;
00623     case IO_VEL:
00624       strcpy(buf, "Velocities");
00625       break;
00626     case IO_ID:
00627       strcpy(buf, "ParticleIDs");
00628       break;
00629     case IO_MASS:
00630       strcpy(buf, "Masses");
00631       break;
00632     case IO_U:
00633       strcpy(buf, "InternalEnergy");
00634       break;
00635     case IO_RHO:
00636       strcpy(buf, "Density");
00637       break;
00638     case IO_HSML:
00639       strcpy(buf, "SmoothingLength");
00640       break;
00641     case IO_POT:
00642       strcpy(buf, "Potential");
00643       break;
00644     case IO_ACCEL:
00645       strcpy(buf, "Acceleration");
00646       break;
00647     case IO_DTENTR:
00648       strcpy(buf, "RateOfChangeOfEntropy");
00649       break;
00650     case IO_TSTP:
00651       strcpy(buf, "TimeStep");
00652       break;
00653     }
00654 }
00655 
00656 
00657 
00672 void write_file(char *fname, int writeTask, int lastTask)
00673 {
00674   int type, bytes_per_blockelement, npart, nextblock, typelist[6];
00675   int n_for_this_task, ntask, n, p, pc, offset = 0, task;
00676   int blockmaxlen, ntot_type[6], nn[6];
00677   enum iofields blocknr;
00678   int blksize;
00679   MPI_Status status;
00680   FILE *fd = 0;
00681 
00682 #ifdef HAVE_HDF5
00683   hid_t hdf5_file = 0, hdf5_grp[6], hdf5_headergrp = 0, hdf5_dataspace_memory;
00684   hid_t hdf5_datatype = 0, hdf5_dataspace_in_file = 0, hdf5_dataset = 0;
00685   herr_t hdf5_status;
00686   hsize_t dims[2], count[2], start[2];
00687   int rank, pcsum = 0;
00688   char buf[500];
00689 #endif
00690 
00691 #define SKIP  {my_fwrite(&blksize,sizeof(int),1,fd);}
00692 
00693   /* determine particle numbers of each type in file */
00694 
00695   if(ThisTask == writeTask)
00696     {
00697       for(n = 0; n < 6; n++)
00698         ntot_type[n] = n_type[n];
00699 
00700       for(task = writeTask + 1; task <= lastTask; task++)
00701         {
00702           MPI_Recv(&nn[0], 6, MPI_INT, task, TAG_LOCALN, MPI_COMM_WORLD, &status);
00703           for(n = 0; n < 6; n++)
00704             ntot_type[n] += nn[n];
00705         }
00706 
00707       for(task = writeTask + 1; task <= lastTask; task++)
00708         MPI_Send(&ntot_type[0], 6, MPI_INT, task, TAG_N, MPI_COMM_WORLD);
00709     }
00710   else
00711     {
00712       MPI_Send(&n_type[0], 6, MPI_INT, writeTask, TAG_LOCALN, MPI_COMM_WORLD);
00713       MPI_Recv(&ntot_type[0], 6, MPI_INT, writeTask, TAG_N, MPI_COMM_WORLD, &status);
00714     }
00715 
00716 
00717 
00718   /* fill file header */
00719 
00720   for(n = 0; n < 6; n++)
00721     {
00722       header.npart[n] = ntot_type[n];
00723       header.npartTotal[n] = (unsigned int) ntot_type_all[n];
00724       header.npartTotalHighWord[n] = (unsigned int) (ntot_type_all[n] >> 32);
00725     }
00726 
00727   for(n = 0; n < 6; n++)
00728     header.mass[n] = All.MassTable[n];
00729 
00730   header.time = All.Time;
00731 
00732   if(All.ComovingIntegrationOn)
00733     header.redshift = 1.0 / All.Time - 1;
00734   else
00735     header.redshift = 0;
00736 
00737   header.flag_sfr = 0;
00738   header.flag_feedback = 0;
00739   header.flag_cooling = 0;
00740   header.flag_stellarage = 0;
00741   header.flag_metals = 0;
00742 
00743 #ifdef COOLING
00744   header.flag_cooling = 1;
00745 #endif
00746 #ifdef SFR
00747   header.flag_sfr = 1;
00748   header.flag_feedback = 1;
00749 #ifdef STELLARAGE
00750   header.flag_stellarage = 1;
00751 #endif
00752 #ifdef METALS
00753   header.flag_metals = 1;
00754 #endif
00755 #endif
00756 
00757   header.num_files = All.NumFilesPerSnapshot;
00758   header.BoxSize = All.BoxSize;
00759   header.Omega0 = All.Omega0;
00760   header.OmegaLambda = All.OmegaLambda;
00761   header.HubbleParam = All.HubbleParam;
00762 
00763 
00764   /* open file and write header */
00765 
00766   if(ThisTask == writeTask)
00767     {
00768       if(All.SnapFormat == 3)
00769         {
00770 #ifdef HAVE_HDF5
00771           sprintf(buf, "%s.hdf5", fname);
00772           hdf5_file = H5Fcreate(buf, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
00773 
00774           hdf5_headergrp = H5Gcreate(hdf5_file, "/Header", 0);
00775 
00776           for(type = 0; type < 6; type++)
00777             {
00778               if(header.npart[type] > 0)
00779                 {
00780                   sprintf(buf, "/PartType%d", type);
00781                   hdf5_grp[type] = H5Gcreate(hdf5_file, buf, 0);
00782                 }
00783             }
00784 
00785           write_header_attributes_in_hdf5(hdf5_headergrp);
00786 #endif
00787         }
00788       else
00789         {
00790           if(!(fd = fopen(fname, "w")))
00791             {
00792               printf("can't open file `%s' for writing snapshot.\n", fname);
00793               endrun(123);
00794             }
00795 
00796           if(All.SnapFormat == 2)
00797             {
00798               blksize = sizeof(int) + 4 * sizeof(char);
00799               SKIP;
00800               my_fwrite("HEAD", sizeof(char), 4, fd);
00801               nextblock = sizeof(header) + 2 * sizeof(int);
00802               my_fwrite(&nextblock, sizeof(int), 1, fd);
00803               SKIP;
00804             }
00805 
00806           blksize = sizeof(header);
00807           SKIP;
00808           my_fwrite(&header, sizeof(header), 1, fd);
00809           SKIP;
00810         }
00811     }
00812 
00813   ntask = lastTask - writeTask + 1;
00814 
00815   for(blocknr = 0; blocknr < IO_NBLOCKS; blocknr++)
00816     {
00817       if(blockpresent(blocknr))
00818         {
00819           bytes_per_blockelement = get_bytes_per_blockelement(blocknr);
00820 
00821           blockmaxlen = ((int) (All.BufferSize * 1024 * 1024)) / bytes_per_blockelement;
00822 
00823           npart = get_particles_in_block(blocknr, &typelist[0]);
00824 
00825           if(npart > 0)
00826             {
00827               if(ThisTask == writeTask)
00828                 {
00829 
00830                   if(All.SnapFormat == 1 || All.SnapFormat == 2)
00831                     {
00832                       if(All.SnapFormat == 2)
00833                         {
00834                           blksize = sizeof(int) + 4 * sizeof(char);
00835                           SKIP;
00836                           my_fwrite(Tab_IO_Labels[blocknr], sizeof(char), 4, fd);
00837                           nextblock = npart * bytes_per_blockelement + 2 * sizeof(int);
00838                           my_fwrite(&nextblock, sizeof(int), 1, fd);
00839                           SKIP;
00840                         }
00841 
00842                       blksize = npart * bytes_per_blockelement;
00843                       SKIP;
00844 
00845                     }
00846                 }
00847 
00848               for(type = 0; type < 6; type++)
00849                 {
00850                   if(typelist[type])
00851                     {
00852 #ifdef HAVE_HDF5
00853                       if(ThisTask == writeTask && All.SnapFormat == 3 && header.npart[type] > 0)
00854                         {
00855                           switch (get_datatype_in_block(blocknr))
00856                             {
00857                             case 0:
00858                               hdf5_datatype = H5Tcopy(H5T_NATIVE_UINT);
00859                               break;
00860                             case 1:
00861                               hdf5_datatype = H5Tcopy(H5T_NATIVE_FLOAT);
00862                               break;
00863                             case 2:
00864                               hdf5_datatype = H5Tcopy(H5T_NATIVE_UINT64);
00865                               break;
00866                             }
00867 
00868                           dims[0] = header.npart[type];
00869                           dims[1] = get_values_per_blockelement(blocknr);
00870                           if(dims[1] == 1)
00871                             rank = 1;
00872                           else
00873                             rank = 2;
00874 
00875                           get_dataset_name(blocknr, buf);
00876 
00877                           hdf5_dataspace_in_file = H5Screate_simple(rank, dims, NULL);
00878                           hdf5_dataset =
00879                             H5Dcreate(hdf5_grp[type], buf, hdf5_datatype, hdf5_dataspace_in_file,
00880                                       H5P_DEFAULT);
00881                           pcsum = 0;
00882                         }
00883 #endif
00884 
00885                       for(task = writeTask, offset = 0; task <= lastTask; task++)
00886                         {
00887                           if(task == ThisTask)
00888                             {
00889                               n_for_this_task = n_type[type];
00890 
00891                               for(p = writeTask; p <= lastTask; p++)
00892                                 if(p != ThisTask)
00893                                   MPI_Send(&n_for_this_task, 1, MPI_INT, p, TAG_NFORTHISTASK, MPI_COMM_WORLD);
00894                             }
00895                           else
00896                             MPI_Recv(&n_for_this_task, 1, MPI_INT, task, TAG_NFORTHISTASK, MPI_COMM_WORLD,
00897                                      &status);
00898 
00899                           while(n_for_this_task > 0)
00900                             {
00901                               pc = n_for_this_task;
00902 
00903                               if(pc > blockmaxlen)
00904                                 pc = blockmaxlen;
00905 
00906                               if(ThisTask == task)
00907                                 fill_write_buffer(blocknr, &offset, pc, type);
00908 
00909                               if(ThisTask == writeTask && task != writeTask)
00910                                 MPI_Recv(CommBuffer, bytes_per_blockelement * pc, MPI_BYTE, task,
00911                                          TAG_PDATA, MPI_COMM_WORLD, &status);
00912 
00913                               if(ThisTask != writeTask && task == ThisTask)
00914                                 MPI_Ssend(CommBuffer, bytes_per_blockelement * pc, MPI_BYTE, writeTask,
00915                                           TAG_PDATA, MPI_COMM_WORLD);
00916 
00917                               if(ThisTask == writeTask)
00918                                 {
00919                                   if(All.SnapFormat == 3)
00920                                     {
00921 #ifdef HAVE_HDF5
00922                                       start[0] = pcsum;
00923                                       start[1] = 0;
00924 
00925                                       count[0] = pc;
00926                                       count[1] = get_values_per_blockelement(blocknr);
00927                                       pcsum += pc;
00928 
00929                                       H5Sselect_hyperslab(hdf5_dataspace_in_file, H5S_SELECT_SET,
00930                                                           start, NULL, count, NULL);
00931 
00932                                       dims[0] = pc;
00933                                       dims[1] = get_values_per_blockelement(blocknr);
00934                                       hdf5_dataspace_memory = H5Screate_simple(rank, dims, NULL);
00935 
00936                                       hdf5_status =
00937                                         H5Dwrite(hdf5_dataset, hdf5_datatype, hdf5_dataspace_memory,
00938                                                  hdf5_dataspace_in_file, H5P_DEFAULT, CommBuffer);
00939 
00940                                       H5Sclose(hdf5_dataspace_memory);
00941 #endif
00942                                     }
00943                                   else
00944                                     my_fwrite(CommBuffer, bytes_per_blockelement, pc, fd);
00945                                 }
00946 
00947                               n_for_this_task -= pc;
00948                             }
00949                         }
00950 
00951 #ifdef HAVE_HDF5
00952                       if(ThisTask == writeTask && All.SnapFormat == 3 && header.npart[type] > 0)
00953                         {
00954                           if(All.SnapFormat == 3)
00955                             {
00956                               H5Dclose(hdf5_dataset);
00957                               H5Sclose(hdf5_dataspace_in_file);
00958                               H5Tclose(hdf5_datatype);
00959                             }
00960                         }
00961 #endif
00962                     }
00963                 }
00964 
00965               if(ThisTask == writeTask)
00966                 {
00967                   if(All.SnapFormat == 1 || All.SnapFormat == 2)
00968                     SKIP;
00969                 }
00970             }
00971         }
00972     }
00973 
00974   if(ThisTask == writeTask)
00975     {
00976       if(All.SnapFormat == 3)
00977         {
00978 #ifdef HAVE_HDF5
00979           for(type = 5; type >= 0; type--)
00980             if(header.npart[type] > 0)
00981               H5Gclose(hdf5_grp[type]);
00982           H5Gclose(hdf5_headergrp);
00983           H5Fclose(hdf5_file);
00984 #endif
00985         }
00986       else
00987         fclose(fd);
00988     }
00989 }
00990 
00991 
00992 
00993 
00997 #ifdef HAVE_HDF5
00998 void write_header_attributes_in_hdf5(hid_t handle)
00999 {
01000   hsize_t adim[1] = { 6 };
01001   hid_t hdf5_dataspace, hdf5_attribute;
01002 
01003   hdf5_dataspace = H5Screate(H5S_SIMPLE);
01004   H5Sset_extent_simple(hdf5_dataspace, 1, adim, NULL);
01005   hdf5_attribute = H5Acreate(handle, "NumPart_ThisFile", H5T_NATIVE_INT, hdf5_dataspace, H5P_DEFAULT);
01006   H5Awrite(hdf5_attribute, H5T_NATIVE_UINT, header.npart);
01007   H5Aclose(hdf5_attribute);
01008   H5Sclose(hdf5_dataspace);
01009 
01010   hdf5_dataspace = H5Screate(H5S_SIMPLE);
01011   H5Sset_extent_simple(hdf5_dataspace, 1, adim, NULL);
01012   hdf5_attribute = H5Acreate(handle, "NumPart_Total", H5T_NATIVE_UINT, hdf5_dataspace, H5P_DEFAULT);
01013   H5Awrite(hdf5_attribute, H5T_NATIVE_UINT, header.npartTotal);
01014   H5Aclose(hdf5_attribute);
01015   H5Sclose(hdf5_dataspace);
01016 
01017   hdf5_dataspace = H5Screate(H5S_SIMPLE);
01018   H5Sset_extent_simple(hdf5_dataspace, 1, adim, NULL);
01019   hdf5_attribute = H5Acreate(handle, "NumPart_Total_HW", H5T_NATIVE_UINT, hdf5_dataspace, H5P_DEFAULT);
01020   H5Awrite(hdf5_attribute, H5T_NATIVE_UINT, header.npartTotalHighWord);
01021   H5Aclose(hdf5_attribute);
01022   H5Sclose(hdf5_dataspace);
01023 
01024 
01025   hdf5_dataspace = H5Screate(H5S_SIMPLE);
01026   H5Sset_extent_simple(hdf5_dataspace, 1, adim, NULL);
01027   hdf5_attribute = H5Acreate(handle, "MassTable", H5T_NATIVE_DOUBLE, hdf5_dataspace, H5P_DEFAULT);
01028   H5Awrite(hdf5_attribute, H5T_NATIVE_DOUBLE, header.mass);
01029   H5Aclose(hdf5_attribute);
01030   H5Sclose(hdf5_dataspace);
01031 
01032   hdf5_dataspace = H5Screate(H5S_SCALAR);
01033   hdf5_attribute = H5Acreate(handle, "Time", H5T_NATIVE_DOUBLE, hdf5_dataspace, H5P_DEFAULT);
01034   H5Awrite(hdf5_attribute, H5T_NATIVE_DOUBLE, &header.time);
01035   H5Aclose(hdf5_attribute);
01036   H5Sclose(hdf5_dataspace);
01037 
01038   hdf5_dataspace = H5Screate(H5S_SCALAR);
01039   hdf5_attribute = H5Acreate(handle, "Redshift", H5T_NATIVE_DOUBLE, hdf5_dataspace, H5P_DEFAULT);
01040   H5Awrite(hdf5_attribute, H5T_NATIVE_DOUBLE, &header.redshift);
01041   H5Aclose(hdf5_attribute);
01042   H5Sclose(hdf5_dataspace);
01043 
01044   hdf5_dataspace = H5Screate(H5S_SCALAR);
01045   hdf5_attribute = H5Acreate(handle, "BoxSize", H5T_NATIVE_DOUBLE, hdf5_dataspace, H5P_DEFAULT);
01046   H5Awrite(hdf5_attribute, H5T_NATIVE_DOUBLE, &header.BoxSize);
01047   H5Aclose(hdf5_attribute);
01048   H5Sclose(hdf5_dataspace);
01049 
01050   hdf5_dataspace = H5Screate(H5S_SCALAR);
01051   hdf5_attribute = H5Acreate(handle, "NumFilesPerSnapshot", H5T_NATIVE_INT, hdf5_dataspace, H5P_DEFAULT);
01052   H5Awrite(hdf5_attribute, H5T_NATIVE_INT, &header.num_files);
01053   H5Aclose(hdf5_attribute);
01054   H5Sclose(hdf5_dataspace);
01055 
01056   hdf5_dataspace = H5Screate(H5S_SCALAR);
01057   hdf5_attribute = H5Acreate(handle, "Omega0", H5T_NATIVE_DOUBLE, hdf5_dataspace, H5P_DEFAULT);
01058   H5Awrite(hdf5_attribute, H5T_NATIVE_DOUBLE, &header.Omega0);
01059   H5Aclose(hdf5_attribute);
01060   H5Sclose(hdf5_dataspace);
01061 
01062   hdf5_dataspace = H5Screate(H5S_SCALAR);
01063   hdf5_attribute = H5Acreate(handle, "OmegaLambda", H5T_NATIVE_DOUBLE, hdf5_dataspace, H5P_DEFAULT);
01064   H5Awrite(hdf5_attribute, H5T_NATIVE_DOUBLE, &header.OmegaLambda);
01065   H5Aclose(hdf5_attribute);
01066   H5Sclose(hdf5_dataspace);
01067 
01068   hdf5_dataspace = H5Screate(H5S_SCALAR);
01069   hdf5_attribute = H5Acreate(handle, "HubbleParam", H5T_NATIVE_DOUBLE, hdf5_dataspace, H5P_DEFAULT);
01070   H5Awrite(hdf5_attribute, H5T_NATIVE_DOUBLE, &header.HubbleParam);
01071   H5Aclose(hdf5_attribute);
01072   H5Sclose(hdf5_dataspace);
01073 
01074   hdf5_dataspace = H5Screate(H5S_SCALAR);
01075   hdf5_attribute = H5Acreate(handle, "Flag_Sfr", H5T_NATIVE_INT, hdf5_dataspace, H5P_DEFAULT);
01076   H5Awrite(hdf5_attribute, H5T_NATIVE_INT, &header.flag_sfr);
01077   H5Aclose(hdf5_attribute);
01078   H5Sclose(hdf5_dataspace);
01079 
01080   hdf5_dataspace = H5Screate(H5S_SCALAR);
01081   hdf5_attribute = H5Acreate(handle, "Flag_Cooling", H5T_NATIVE_INT, hdf5_dataspace, H5P_DEFAULT);
01082   H5Awrite(hdf5_attribute, H5T_NATIVE_INT, &header.flag_cooling);
01083   H5Aclose(hdf5_attribute);
01084   H5Sclose(hdf5_dataspace);
01085 
01086   hdf5_dataspace = H5Screate(H5S_SCALAR);
01087   hdf5_attribute = H5Acreate(handle, "Flag_StellarAge", H5T_NATIVE_INT, hdf5_dataspace, H5P_DEFAULT);
01088   H5Awrite(hdf5_attribute, H5T_NATIVE_INT, &header.flag_stellarage);
01089   H5Aclose(hdf5_attribute);
01090   H5Sclose(hdf5_dataspace);
01091 
01092   hdf5_dataspace = H5Screate(H5S_SCALAR);
01093   hdf5_attribute = H5Acreate(handle, "Flag_Metals", H5T_NATIVE_INT, hdf5_dataspace, H5P_DEFAULT);
01094   H5Awrite(hdf5_attribute, H5T_NATIVE_INT, &header.flag_metals);
01095   H5Aclose(hdf5_attribute);
01096   H5Sclose(hdf5_dataspace);
01097 
01098   hdf5_dataspace = H5Screate(H5S_SCALAR);
01099   hdf5_attribute = H5Acreate(handle, "Flag_Feedback", H5T_NATIVE_INT, hdf5_dataspace, H5P_DEFAULT);
01100   H5Awrite(hdf5_attribute, H5T_NATIVE_INT, &header.flag_feedback);
01101   H5Aclose(hdf5_attribute);
01102   H5Sclose(hdf5_dataspace);
01103 
01104   header.flag_entropy_instead_u = 0;
01105 
01106   hdf5_dataspace = H5Screate(H5S_SIMPLE);
01107   H5Sset_extent_simple(hdf5_dataspace, 1, adim, NULL);
01108   hdf5_attribute = H5Acreate(handle, "Flag_Entropy_ICs", H5T_NATIVE_UINT, hdf5_dataspace, H5P_DEFAULT);
01109   H5Awrite(hdf5_attribute, H5T_NATIVE_UINT, &header.flag_entropy_instead_u);
01110   H5Aclose(hdf5_attribute);
01111   H5Sclose(hdf5_dataspace);
01112 }
01113 #endif
01114 
01115 
01116 
01117 
01118 
01122 size_t my_fwrite(void *ptr, size_t size, size_t nmemb, FILE * stream)
01123 {
01124   size_t nwritten;
01125 
01126   if((nwritten = fwrite(ptr, size, nmemb, stream)) != nmemb)
01127     {
01128       printf("I/O error (fwrite) on task=%d has occured: %s\n", ThisTask, strerror(errno));
01129       fflush(stdout);
01130       endrun(777);
01131     }
01132   return nwritten;
01133 }
01134 
01135 
01139 size_t my_fread(void *ptr, size_t size, size_t nmemb, FILE * stream)
01140 {
01141   size_t nread;
01142 
01143   if((nread = fread(ptr, size, nmemb, stream)) != nmemb)
01144     {
01145       printf("I/O error (fread) on task=%d has occured: %s\n", ThisTask, strerror(errno));
01146       fflush(stdout);
01147       endrun(778);
01148     }
01149   return nread;
01150 }

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