/* ********************************************************************* */ void WriteData (const Data *d, Output *output, Grid *grid) /*! * Write data to disk using any of the available formats. * * \param [in] d pointer to PLUTO Data structre * \param [in] output the output structure corresponding to a given * format * \param [in] grid pointer to an array of Grid structures *********************************************************************** */ { int i, j, k, nv; int single_file; size_t dsize; char filename[512], sline[512]; static int last_computed_var = -1; double units[MAX_OUTPUT_VARS]; float ***Vpt3; void *Vpt; FILE *fout, *fbin; time_t tbeg, tend; long long offset; /* ----------------------------------------------------------- Increment the file number and initialize units ----------------------------------------------------------- */ output->nfile++; print1 ("> Writing file #%d (%s) to disk...", output->nfile, output->ext); #ifdef PARALLEL MPI_Barrier (MPI_COMM_WORLD); if (prank == 0) time(&tbeg); #endif for (nv = 0; nv < MAX_OUTPUT_VARS; nv++) units[nv] = 1.0; if (output->cgs) GetCGSUnits(units); /* -------------------------------------------------------- Get user var if necessary -------------------------------------------------------- */ if (last_computed_var != g_stepNumber && d->Vuser != NULL) { ComputeUserVar (d, grid); last_computed_var = g_stepNumber; } /* -------------------------------------------------------- Select the output type -------------------------------------------------------- */ if (output->type == DBL_OUTPUT) { /* ------------------------------------------------------------------- */ /*! - \b DBL output: Double-precision data files can be written using single or multiple file mode. - for single file, serial: we open the file just once before the main variable loop, dump variables and then close. - for single file, parallel the distributed array descriptor sz is different for cell-centered or staggered data type and we thus have to open and close the file after each variable has been dumped. - when writing multiple files we open, write to and close the file one each loop cycle. \note In all cases, the pointer to the data array that has to be written must be cast into (void *) and the starting index of the array must be zero. */ /* ------------------------------------------------------------------- */ int sz; single_file = strcmp(output->mode,"single_file") == 0; dsize = sizeof(double); if (single_file){ /* -- single output file -- */ sprintf (filename, "%s/data.%04d.%s", output->dir,output->nfile, output->ext); offset = 0; #ifndef PARALLEL fbin = OpenBinaryFile (filename, 0, "w"); #endif for (nv = 0; nv < output->nvar; nv++) { if (!output->dump_var[nv]) continue; if (output->stag_var[nv] == -1) { /* -- cell-centered data -- */ sz = SZ; Vpt = (void *)output->V[nv][0][0]; } else if (output->stag_var[nv] == 0) { /* -- x-staggered data -- */ sz = SZ_stagx; Vpt = (void *)(output->V[nv][0][0]-1); } else if (output->stag_var[nv] == 1) { /* -- y-staggered data -- */ sz = SZ_stagy; Vpt = (void *)output->V[nv][0][-1]; } else if (output->stag_var[nv] == 2) { /* -- z-staggered data -- */ sz = SZ_stagz; Vpt = (void *)output->V[nv][-1][0]; } #ifdef PARALLEL fbin = OpenBinaryFile (filename, sz, "w"); AL_Set_offset(sz, offset); #endif WriteBinaryArray (Vpt, dsize, sz, fbin, output->stag_var[nv]); #ifdef PARALLEL offset = AL_Get_offset(sz); CloseBinaryFile(fbin, sz); #endif } #ifndef PARALLEL CloseBinaryFile(fbin, sz); #endif }else{ /* -- multiple files -- */ for (nv = 0; nv < output->nvar; nv++) { if (!output->dump_var[nv]) continue; sprintf (filename, "%s/%s.%04d.%s", output->dir, output->var_name[nv], output->nfile, output->ext); if (output->stag_var[nv] == -1) { /* -- cell-centered data -- */ sz = SZ; Vpt = (void *)output->V[nv][0][0]; } else if (output->stag_var[nv] == 0) { /* -- x-staggered data -- */ sz = SZ_stagx; Vpt = (void *)(output->V[nv][0][0]-1); } else if (output->stag_var[nv] == 1) { /* -- y-staggered data -- */ sz = SZ_stagy; Vpt = (void *)output->V[nv][0][-1]; } else if (output->stag_var[nv] == 2) { /* -- z-staggered data -- */ sz = SZ_stagz; Vpt = (void *)output->V[nv][-1][0]; } fbin = OpenBinaryFile (filename, sz, "w"); WriteBinaryArray (Vpt, dsize, sz, fbin, output->stag_var[nv]); CloseBinaryFile (fbin, sz); } } } else if (output->type == FLT_OUTPUT) { /* ---------------------------------------------------------- FLT output for cell-centered data ---------------------------------------------------------- */ single_file = strcmp(output->mode,"single_file") == 0; if (single_file){ /* -- single output file -- */ sprintf (filename, "%s/data.%04d.%s", output->dir, output->nfile, output->ext); fbin = OpenBinaryFile (filename, SZ_float, "w"); for (nv = 0; nv < output->nvar; nv++) { if (!output->dump_var[nv]) continue; /* Vpt = (void *)(Convert_dbl2flt(output->V[nv],0))[0][0]; */ Vpt3 = Convert_dbl2flt(output->V[nv], units[nv],0); Vpt = (void *)Vpt3[0][0]; WriteBinaryArray (Vpt, sizeof(float), SZ_float, fbin, output->stag_var[nv]); } CloseBinaryFile(fbin, SZ_float); /* BOV_Header(output, filename); */ }else{ /* -- multiple files -- */ for (nv = 0; nv < output->nvar; nv++) { if (!output->dump_var[nv]) continue; sprintf (filename, "%s/%s.%04d.%s", output->dir, output->var_name[nv], output->nfile, output->ext); fbin = OpenBinaryFile (filename, SZ_float, "w"); /* Vpt = (void *)(Convert_dbl2flt(output->V[nv],0))[0][0]; */ Vpt3 = Convert_dbl2flt(output->V[nv], units[nv],0); Vpt = (void *)Vpt3[0][0]; WriteBinaryArray (Vpt, sizeof(float), SZ_float, fbin, output->stag_var[nv]); CloseBinaryFile (fbin, SZ_float); } } }else if (output->type == DBL_H5_OUTPUT || output->type == FLT_H5_OUTPUT){ /* ------------------------------------------------------ HDF5 (static grid) output (single/double precision) ------------------------------------------------------ */ #ifdef USE_HDF5 single_file = YES; WriteHDF5 (output, grid); #else print1 ("! WriteData: HDF5 library not available\n"); return; #endif }else if (output->type == VTK_OUTPUT) { /* ------------------------------------------------------------------- */ /*! - \b VTK output: in order to enable parallel writing, files must be closed and opened again for scalars, since the distributed array descriptors used by ArrayLib (Float_Vect) and (float) are different. This is done using the AL_Get_offset() and AL_Set_offset() functions. */ /* ------------------------------------------------------------------- */ single_file = strcmp(output->mode,"single_file") == 0; sprintf (filename, "%s/data.%04d.%s", output->dir, output->nfile, output->ext); if (single_file){ /* -- single output file -- */ fbin = OpenBinaryFile(filename, SZ_Float_Vect, "w"); WriteVTK_Header(fbin, grid); for (nv = 0; nv < output->nvar; nv++) { /* -- write vectors -- */ if (output->dump_var[nv] != VTK_VECTOR) continue; WriteVTK_Vector (fbin, output->V + nv, units[nv], output->var_name[nv], grid); } #ifdef PARALLEL offset = AL_Get_offset(SZ_Float_Vect); CloseBinaryFile(fbin, SZ_Float_Vect); fbin = OpenBinaryFile(filename, SZ_float, "w"); AL_Set_offset(SZ_float, offset); #endif for (nv = 0; nv < output->nvar; nv++) { /* -- write scalars -- */ if (output->dump_var[nv] != YES) continue; WriteVTK_Scalar (fbin, output->V[nv], units[nv], output->var_name[nv], grid); } CloseBinaryFile(fbin, SZ_float); }else{ /* -- multiple output files -- */ for (nv = 0; nv < output->nvar; nv++) { /* -- write vectors -- */ if (output->dump_var[nv] != VTK_VECTOR) continue; if (strcmp(output->var_name[nv],"vx1") == 0) { sprintf (filename, "%s/vfield.%04d.%s", output->dir, output->nfile, output->ext); }else if (strcmp(output->var_name[nv],"bx1") == 0) { sprintf (filename, "%s/bfield.%04d.%s", output->dir, output->nfile, output->ext); }else{ print1 ("! WriteData: unknown vector type in VTK output\n"); QUIT_PLUTO(1); } fbin = OpenBinaryFile(filename, SZ_Float_Vect, "w"); WriteVTK_Header(fbin, grid); WriteVTK_Vector(fbin, output->V + nv, units[nv], output->var_name[nv], grid); CloseBinaryFile(fbin, SZ_Float_Vect); } for (nv = 0; nv < output->nvar; nv++) { /* -- write scalars -- */ if (output->dump_var[nv] != YES) continue; sprintf (filename, "%s/%s.%04d.%s", output->dir, output->var_name[nv], output->nfile, output->ext); fbin = OpenBinaryFile(filename, SZ_Float_Vect, "w"); WriteVTK_Header(fbin, grid); #ifdef PARALLEL offset = AL_Get_offset(SZ_Float_Vect); CloseBinaryFile(fbin, SZ_Float_Vect); fbin = OpenBinaryFile(filename, SZ_float, "w"); AL_Set_offset(SZ_float, offset); #endif WriteVTK_Scalar(fbin, output->V[nv], units[nv], output->var_name[nv], grid); CloseBinaryFile (fbin, SZ_float); } } }else if (output->type == TAB_OUTPUT) { /* ------------------------------------------------------ Tabulated (ASCII) output ------------------------------------------------------ */ single_file = YES; sprintf (filename,"%s/data.%04d.%s", output->dir, output->nfile, output->ext); WriteTabArray (output, filename, grid); }else if (output->type == PPM_OUTPUT) { /* ------------------------------------------------------ PPM output ------------------------------------------------------ */ single_file = NO; for (nv = 0; nv < output->nvar; nv++) { if (!output->dump_var[nv]) continue; sprintf (filename, "%s/%s.%04d.%s", output->dir, output->var_name[nv], output->nfile, output->ext); WritePPM (output->V[nv], output->var_name[nv], filename, grid); } }else if (output->type == PNG_OUTPUT) { /* ------------------------------------------------------ PNG output ------------------------------------------------------ */ #ifdef USE_PNG single_file = NO; for (nv = 0; nv < output->nvar; nv++) { if (!output->dump_var[nv]) continue; sprintf (filename, "%s/%s.%04d.%s", output->dir, output->var_name[nv], output->nfile, output->ext); WritePNG (output->V[nv], output->var_name[nv], filename, grid); } #else print1 ("! PNG library not available\n"); return; #endif } /* ------------------------------------------------------------- Update corresponding ".out" file ------------------------------------------------------------- */ sprintf (filename,"%s/%s.out",output->dir, output->ext); if (prank == 0) { if (output->nfile == 0) { fout = fopen (filename, "w"); }else { fout = fopen (filename, "r+"); for (nv = 0; nv < output->nfile; nv++) fgets (sline, 512, fout); fseek (fout, ftell(fout), SEEK_SET); } /* -- write a multi-column file -- */ fprintf (fout, "%d %12.6e %12.6e %ld ", output->nfile, g_time, g_dt, g_stepNumber); if (single_file) fprintf (fout,"single_file "); else fprintf (fout,"multiple_files "); if (IsLittleEndian()) fprintf (fout, "little "); else fprintf (fout, "big "); for (nv = 0; nv < output->nvar; nv++) { if (output->dump_var[nv]) fprintf (fout, "%s ", output->var_name[nv]); } fprintf (fout,"\n"); fclose (fout); } #ifdef PARALLEL MPI_Barrier (MPI_COMM_WORLD); if (prank == 0){ time(&tend); print1 (" [%5.2f sec]",difftime(tend,tbeg)); } #endif print1 ("\n"); }
Var* ff_write(vfuncptr func, Var* arg) { Var* ob = NULL; char* filename = NULL; char* title = NULL; char* type = NULL; char* separator = NULL; /* for csv */ int header = 0; /* for csv */ int force = 0; /* Force file overwrite */ int hdf_old = 0; // write hdf file backward like davinci used to unsigned short iom_type_idx, iom_type_found; Alist alist[9]; alist[0] = make_alist("object", ID_UNK, NULL, &ob); alist[1] = make_alist("filename", ID_STRING, NULL, &filename); alist[2] = make_alist("type", ID_ENUM, NULL, &type); alist[3] = make_alist("title", ID_STRING, NULL, &title); alist[4] = make_alist("force", DV_INT32, NULL, &force); alist[5] = make_alist("separator", ID_STRING, NULL, &separator); alist[6] = make_alist("header", DV_INT32, NULL, &header); alist[7] = make_alist("hdf_old", DV_INT32, NULL, &hdf_old); alist[8].name = NULL; if (parse_args(func, arg, alist) == 0) return (NULL); /** ** Make sure user specified an object **/ if (ob == NULL) { parse_error("%s: No object specified.", func->name); return (NULL); } /** ** get filename. Verify type **/ if (filename == NULL) { parse_error("No filename specified."); return (NULL); } filename = dv_locate_file(filename); if (type == NULL) { parse_error("No type specified."); return (NULL); } /* ** Get title string */ if (title == NULL) { title = (char*)"DV data product"; } /* Check type against list of types supported by iomedley. */ iom_type_idx = iom_type_found = 0; while (iom_filetypes[iom_type_idx]) { if (!strcasecmp(type, iom_filetypes[iom_type_idx])) { iom_type_found = 1; break; } iom_type_idx++; } if (iom_type_found) dv_WriteIOM(ob, filename, type, force); else if (!strcasecmp(type, "raw")) dv_WriteRaw(ob, filename, force); else if (!strcasecmp(type, "vicar")) dv_WriteVicar(ob, filename, force); else if (!strcasecmp(type, "grd")) dv_WriteGRD(ob, filename, force, title, (char*)"davinci"); /* else if (!strcasecmp(type, "pnm")) dv_WritePNM(ob, filename, force); */ else if (!strcasecmp(type, "pgm")) dv_WritePGM(ob, filename, force); else if (!strcasecmp(type, "ppm")) dv_WritePPM(ob, filename, force); else if (!strcasecmp(type, "ascii")) WriteAscii(ob, filename, force); else if (!strcasecmp(type, "csv")) dv_WriteCSV(ob, filename, separator, header, force); else if (!strcasecmp(type, "ers")) dv_WriteERS(ob, filename, force); else if (!strcasecmp(type, "imath")) dv_WriteIMath(ob, filename, force); else if (!strcasecmp(type, "isis")) dv_WriteISIS(ob, filename, force, title); else if (!strcasecmp(type, "envi")) dv_WriteENVI(ob, filename, force); else if (!strcasecmp(type, "specpr")) { if (!force && file_exists(filename)) { parse_error("File %s already exists.\n", filename); return NULL; } WriteSpecpr(ob, filename, title); } /* ** Below here are optional packages */ #ifdef HAVE_LIBHDF5 else if (!strcasecmp(type, "hdf")) { struct stat statbuf; if (!force && !stat(filename, &statbuf)) { parse_error("File %s already exists.\n", filename); return NULL; } /* force ? */ WriteHDF5(-1, filename, ob, hdf_old); } #endif #ifdef BUILD_MODULE_SUPPORT else if (iomod_handler_for_type(type)) write_to_io_module(ob, filename, type, force); #endif #if 0 #ifdef HAVE_LIBMAGICK // else if (dvio_ValidGfx(type, GFX_type)) dv_WriteGFX_Image(ob, filename, force, GFX_type); else if (1) paramdvWriteImage(ob, filename, type, force); #endif #endif else { sprintf(error_buf, "Unrecognized type: %s", type); parse_error(NULL); return (NULL); } free(filename); return (NULL); }