vtf-logo

FileVisualGrid.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2002 Ralf Deiterding
00004 // Brandenburgische Universitaet Cottbus
00005 //
00006 // Copyright (C) 2003-2007 California Institute of Technology
00007 // Ralf Deiterding, ralf@amroc.net
00008 // Santiago Lombeyda (VTU, SILO)
00009 
00010 #ifndef AMROC_FILEVISUALGRID_H
00011 #define AMROC_FILEVISUALGRID_H
00012 
00020 #include "VisualGrid.h" 
00021 #include "HDFToFile/FileVisualGridBase.h"
00022 #include "EncodeToBase64.h"
00023 #include <strings.h>
00024 #include <cctype>
00025 #include <hlimits.h>
00026 
00027 #if defined(HAVE_LIBSILO) || defined(HAVE_LIBSILOH5)
00028 #include <silo.h>
00029 #endif
00030 
00031 #define PROBE_TOLERANCE 1.e-6
00032 
00033 typedef float points_list_type[][3];
00034 typedef int   cons_list_type[][8];
00035 
00042 template <class VectorType>
00043 class FileVisualGrid : public FileVisualGridBase, 
00044                        public VisualGrid<VectorType> {
00045   typedef typename VectorType::InternalDataType DataType;
00046   typedef VisualGrid<VectorType> base;
00047 public:
00048   typedef typename base::data_block_type data_block_type;
00049   typedef typename base::block_list_type block_list_type;
00050   typedef typename base::hierarchy_storage_type hierarchy_storage_type;
00051   typedef typename base::hdata_block_type hdata_block_type;
00052   typedef typename base::evaluator_type evaluator_type;
00053   typedef typename base::point_list_type point_list_type;
00054 
00055   typedef std::multimap<float, int> index_ordered_map_type;
00056   typedef std::pair<float, int> ordered_index_type;
00057 
00058 public:
00059   FileVisualGrid(evaluator_type* ev) : FileVisualGridBase(ev), 
00060                                        base(ev), OutputType(0) {
00061     base::_BlockList = (block_list_type *) new block_list_type;
00062     nkeys = 0;
00063     keys = (int *) 0;
00064     OutputName = "-";
00065     for (int d=0; d<3; d++) {
00066       LinePoint[d]  = 0.0;   
00067       LineVector[d] = 0.0;   
00068       RegData[d] = 10;
00069     } 
00070     RegLim[0] = FLT_MIN;
00071     RegLim[1] = FLT_MAX;
00072     RegMax = 1;
00073     LevelCutOut = 0;
00074     PointOutput = 0;
00075     _Step = -1;
00076     FileMerge = 1;
00077     PointFile = "";
00078   }
00079 
00080   ~FileVisualGrid() {
00081     if (keys) delete [] keys;
00082     for (typename block_list_type::iterator bit=BlockList().begin();
00083          bit!=BlockList().end(); bit++)
00084       delete (*bit);
00085     BlockList().clear();      
00086     delete base::_BlockList;
00087   }
00088 
00089   virtual void update() {    
00090     std::string iname;
00091     if (UpdateName()) iname = *UpdateName();
00092     else iname = "display_file.in";
00093 
00094     // Generating display_file.in if file is missing; 
00095     std::ifstream infile;
00096     std::ofstream outfile;
00097     infile.open(iname.c_str(), std::ios::in);
00098     if (!infile) {
00099       if (!UpdateName()) {
00100         outfile.open(iname.c_str(), std::ios::out);
00101         outfile << "Type  6\n\nDisplayMinLevel    0\nDisplayMaxLevel    10\n\n";
00102         outfile << "FileName convert\nFileType 6\nKeys p,t,s,i\n"; 
00103         outfile.close();
00104       }
00105     }
00106     else{
00107       infile.close();
00108     }
00109 
00110     ControlDevice DisplayCtrl(GetFileControlDevice(iname.c_str(),""));
00111     RegisterAt(DisplayCtrl,"Type",base::_FKeys); 
00112     RegisterAt(DisplayCtrl,"FileName",OutputName);     
00113     RegisterAt(DisplayCtrl,"FileType",OutputType);   
00114     RegisterAt(DisplayCtrl,"Keys",StrKeys);     
00115     RegisterAt(DisplayCtrl,"DisplayMinLevel",base::_MinLevel); 
00116     RegisterAt(DisplayCtrl,"DisplayMaxLevel",base::_MaxLevel);
00117     RegisterAt(DisplayCtrl,"CutOut",base::_Eliminate);
00118     RegisterAt(DisplayCtrl,"CutOutValue",base::_EliminateValue);
00119     RegisterAt(DisplayCtrl,"RegularMax",RegMax);
00120     RegisterAt(DisplayCtrl,"RegularLimit(1)",RegLim[0]);
00121     RegisterAt(DisplayCtrl,"RegularLimit(2)",RegLim[1]);
00122     RegisterAt(DisplayCtrl,"PointOutput",PointOutput);
00123     RegisterAt(DisplayCtrl,"LevelCutOut",LevelCutOut);
00124     RegisterAt(DisplayCtrl,"FileMerge",FileMerge);
00125     RegisterAt(DisplayCtrl,"PointFile",PointFile);
00126     for (int d=0; d<3; d++) {
00127       char VariableName[16];
00128       std::sprintf(VariableName,"ShowMin(%d)",d+1);
00129       RegisterAt(DisplayCtrl,VariableName,base::show[2*d]);
00130       std::sprintf(VariableName,"ShowMax(%d)",d+1);
00131       RegisterAt(DisplayCtrl,VariableName,base::show[2*d+1]);     
00132       std::sprintf(VariableName,"ShowCut(%d)",d+1);
00133       RegisterAt(DisplayCtrl,VariableName,base::cut[d]);     
00134       std::sprintf(VariableName,"Symmetry(%d)",d+1);
00135       RegisterAt(DisplayCtrl,VariableName,base::Symmetry[d]);     
00136       std::sprintf(VariableName,"Periodic(%d)",d+1);
00137       RegisterAt(DisplayCtrl,VariableName,base::Periodic[d]);     
00138       std::sprintf(VariableName,"LinePoint(%d)",d+1);
00139       RegisterAt(DisplayCtrl,VariableName,LinePoint[d]);     
00140       std::sprintf(VariableName,"LineVector(%d)",d+1);
00141       RegisterAt(DisplayCtrl,VariableName,LineVector[d]);          
00142       std::sprintf(VariableName,"RegularData(%d)",d+1);
00143       RegisterAt(DisplayCtrl,VariableName,RegData[d]);
00144     }   
00145     TheEvaluator().register_at(DisplayCtrl,"");
00146     DisplayCtrl.update();  
00147 
00148     TheEvaluator().update();
00149   }
00150 
00151   virtual int SetUp(int step, std::string** filenames, int Nfilenames) { 
00152     int res;
00153     if ((OutputType==0 || OutputType==1) && !PointFile.empty())
00154       base::_CutOut = 0;
00155     if (OutputType==6 || OutputType==7) { 
00156       base::_CutOut = 0;
00157       _Step = step;
00158     }
00159     if (OutputType==15)
00160       if (LevelCutOut<=0 && FKeys()!=1)
00161         base::_CutOut = 0;
00162       
00163     if ((res=base::SetUp(step,filenames,Nfilenames)) >= 0) {
00164       char append_str[32], time[20];
00165       base::OutputFileTime(time, step);
00166       if (OutputName != "-") {
00167         if (OutputType>=0 && OutputType<=2) 
00168           std::sprintf(append_str,"_%s.txt",time);
00169         else if (OutputType>=3 && OutputType<=5) 
00170           std::sprintf(append_str,"_%s.dx",time);
00171         else if (OutputType==8) 
00172           std::sprintf(append_str,"_%s.dat",time);
00173         else if (OutputType==10 || OutputType==11) 
00174           std::sprintf(append_str,"_%s.vtk",time);
00175         else if (OutputType==12 || OutputType==13) 
00176           std::sprintf(append_str,"_%s.vtu",time);
00177         else if (OutputType==15) 
00178           std::sprintf(append_str,"_%s.silo",time);
00179         if (OutputType<=5 || OutputType>=8) OutputName += append_str;
00180       }
00181 
00182       int* work = new int[StrKeys.length()];
00183       for (unsigned int sk=0; sk<StrKeys.length(); sk++) 
00184         for (int i=0; i<TheEvaluator().NKeys(); i++) 
00185           if (TheEvaluator().KeyboardKeys()[i] == StrKeys.c_str()[sk]) {
00186             work[nkeys] = i+1; nkeys++; 
00187           }
00188       
00189       if (keys) delete [] keys;
00190       keys = new int[nkeys];
00191       for (int k=0; k<nkeys; k++)
00192         keys[k] = work[k];
00193 
00194       delete work;
00195     }
00196     return res;
00197   }
00198 
00199 
00200   virtual void Write() {
00201     if (OutputType>=6 && OutputType<=7 && OutputName=="-")
00202       OutputName = "out";
00203     if (OutputName != "-") {
00204       if (OutputType <= 5 || ( OutputType >= 8 && OutputType < 15 )) {
00205         std::ofstream outfile;
00206         outfile.open(OutputName.c_str(), std::ios::out);
00207         std::ostream* out = new std::ostream(outfile.rdbuf());
00208         if (OutputType == 0) 
00209           WriteASCIITabular(0,0,*out);
00210         else if (OutputType == 1) 
00211           WriteASCIITabular(1,0,*out); 
00212         else if (OutputType == 2) 
00213           WriteRegularTabular(*out);
00214         else if (OutputType == 3) 
00215           WriteDXFile(*out);
00216         else if (OutputType == 4) 
00217           WriteDXASCIIFile(*out);
00218         else if (OutputType == 5) 
00219           WriteDXExternalFilter(*out);
00220         else if (OutputType == 8) 
00221           WriteTecplotASCII(*out);
00222         else if (OutputType == 10) 
00223           WriteVTKASCIIFile(*out);
00224         else if (OutputType == 11) 
00225           WriteVTKFile(*out);
00226         else if (OutputType == 12)
00227           WriteVTUASCIIFile(*out);
00228         else if (OutputType == 13)
00229           WriteVTUFile(*out);
00230         outfile.close();
00231         delete out;
00232       }
00233       else if (OutputType == 6) 
00234         WriteHDFConvert(0);
00235       else if (OutputType == 7) 
00236         WriteHDFConvert(1);
00237       else if (OutputType == 15)
00238         WriteSiloFile((char *)OutputName.c_str());
00239     }
00240     else {
00241       if (OutputType == 0) 
00242         WriteASCIITabular(0,0,std::cout);
00243       else if (OutputType == 1) 
00244         WriteASCIITabular(1,0,std::cout); 
00245       else if (OutputType == 2) 
00246         WriteRegularTabular(std::cout);
00247       else if (OutputType == 3) 
00248         WriteDXFile(std::cout);
00249       else if (OutputType == 4) 
00250         WriteDXASCIIFile(std::cout);
00251       else if (OutputType == 5) 
00252         WriteDXExternalFilter(std::cout);
00253       else if (OutputType == 8) 
00254         WriteTecplotASCII(std::cout);
00255       else if (OutputType == 10)
00256         WriteVTKASCIIFile(std::cout);
00257       else if (OutputType == 11)
00258         WriteVTKFile(std::cout);
00259       else if (OutputType == 12) 
00260         WriteVTUASCIIFile(std::cout);
00261       else if (OutputType == 13) 
00262         WriteVTUFile(std::cout);
00263       else if (OutputType == 15)
00264         WriteSiloFile(0);
00265     }
00266   }
00267 
00268   void WriteRegularTabular(std::ostream& out) {
00269     if (!keys) return;
00270     int length;
00271     if (FKeys() == 1) 
00272       length = NNodes();
00273     else
00274       length = NCells();
00275     
00276     float* xyz = new float[3*length];
00277     SetGrid((float (*)[3]) xyz); 
00278     float* dat = new float[nkeys*length];
00279     float* val = new float[nkeys];
00280     for (int i=0; i<nkeys*length; i++) *(dat+i) = 0.;
00281     for (int k=0; k<nkeys; k++) 
00282       SetScal(&(keys[k]),&(dat[k*length]));
00283 
00284     float regdx[3], reggeom[6];
00285     int xd = -1, yd = -1, fd = -1;
00286     for (int d=0; d<3; d++) {
00287       if (base::DimUsed(d)==0 || base::show[2*d]>=base::show[2*d+1]) {
00288         reggeom[2*d] = base::geom[2*d]; reggeom[2*d+1] = base::geom[2*d+1]; 
00289       }
00290       else {
00291         reggeom[2*d] = Max(base::show[2*d],base::geom[2*d]); 
00292         reggeom[2*d+1] = Min(base::show[2*d+1],base::geom[2*d+1]); 
00293       }
00294       if (RegData[d]>0) regdx[d] = (reggeom[2*d+1] - reggeom[2*d])/RegData[d];
00295       else regdx[d] = 0.0;
00296       if (yd<0 && xd>=0 && regdx[d]>0.0) yd = d;
00297       if (xd<0 && regdx[d]>0.0) xd = d;
00298       if (fd<0 && regdx[d]==0.0) fd = d;
00299     }
00300     float xs = reggeom[2*xd] + (FKeys()==1 ? 0.0 : regdx[xd]/2.0);
00301     while (xs<=reggeom[2*xd+1] && regdx[xd]>0.0) {
00302       float ys = reggeom[2*yd] + (FKeys()==1 ? 0.0 : regdx[yd]/2.0);
00303       while (ys<=reggeom[2*yd+1] && regdx[yd]>0.0) {
00304         float mindist=FLT_MAX;
00305         float fddist=(RegMax ? FLT_MIN : FLT_MAX);
00306         int inearest = -1;
00307         for (register int i=0; i<length; i++) {
00308           float sum=std::sqrt((xs-xyz[3*i+xd])*(xs-xyz[3*i+xd])+
00309                               (ys-xyz[3*i+yd])*(ys-xyz[3*i+yd]));
00310           if (sum<mindist-PROBE_TOLERANCE*(mindist>0?mindist:1.0) ||
00311               inearest<0) {
00312             mindist = sum;
00313             inearest = i;
00314           }
00315           if (fd>=0 && sum<mindist+PROBE_TOLERANCE*(mindist>0?mindist:1.0)) {
00316             if (RegMax && xyz[3*i+fd]>fddist &&
00317                 dat[i]>=RegLim[0] && dat[i]<=RegLim[1]) {
00318               fddist = xyz[3*i+fd]; inearest = i;
00319             }
00320             if (!RegMax && xyz[3*i+fd]<fddist &&
00321                 dat[i]>=RegLim[0] && dat[i]<=RegLim[1]) {
00322               fddist = xyz[3*i+fd]; inearest = i;
00323             }
00324           }
00325         }
00326         out << xs << " " << ys;
00327         for (register int k=0; k<nkeys; k++) 
00328           out << " " << dat[k*length+inearest];
00329         out << std::endl;
00330         std::cerr << ".";
00331         ys += regdx[yd];
00332       }
00333       out << std::endl;
00334       std::cerr << std::endl;
00335       xs += regdx[xd];
00336     }
00337 
00338     delete [] val;
00339     delete [] dat;
00340     delete [] xyz;
00341   }
00342 
00343   void WriteASCIITabular(int ordered, int tecplot, std::ostream& out) {
00344     if (!keys) return;
00345 
00346     if (PointFile.empty()) {
00347       int length;
00348       if (FKeys() == 1)
00349         length = NNodes();
00350       else
00351         length = NCells();
00352       
00353       float* xyz = new float[3*length];
00354       SetGrid((float (*)[3]) xyz);  
00355       int nkl = nkeys*length;
00356       float* dat = new float[nkl];
00357       for (register int i=0; i<nkl; i++) *(dat+i) = 0.;
00358       register int k;
00359       for (k=0; k<nkeys; k++) 
00360         SetScal(&(keys[k]),&(dat[k*length]));
00361       
00362       if (!tecplot) {
00363         out << RealTime() << ";";
00364         if (!LineProbe()) {
00365           if (!ordered) {
00366             if (base::DimUsed(0)) out << "x ;";
00367             if (base::DimUsed(1)) out << "y ;";
00368             if (base::DimUsed(2)) out << "z ;";
00369           }
00370           else
00371             if (base::DimUsed(0)) out << "x ;";
00372             else if (base::DimUsed(1)) out << "y ;";
00373             else if (base::DimUsed(2)) out << "z ;";
00374         }
00375         else
00376           out << "r ;";
00377         for (k=0; k<nkeys; k++) 
00378           out << TheEvaluator().TitleKeys(keys[k]-1) << ";";
00379       }
00380       else {
00381         out << "title = \"t = " << RealTime() << "\"" << std::endl;
00382         out << "variables = ";
00383         if (!LineProbe()) out << "\"x\"";
00384         else out << "\"r\"";
00385         for (k=0; k<nkeys; k++) 
00386           out << ", \"" << TheEvaluator().TitleKeys(keys[k]-1) << "\"";
00387       }
00388       out << std::endl;
00389    
00390       if (!ordered) {
00391         for (register int i=0; i<length; i++) {
00392           if (!LineProbe()) {
00393             for (register int d=0; d<3; d++) 
00394               if (base::DimUsed(d))
00395                 out << xyz[3*i+d] << " ";        
00396             for (k=0; k<nkeys; k++) 
00397                 out << dat[k*length+i] << " ";
00398             out << std::endl;
00399           }
00400           else {
00401             int lp = 1, d;
00402             float di = 0.0, xs = 0.0, c = 0.0;
00403             for (d=0; d<3; d++) 
00404               if (base::DimUsed(d)) {
00405                 di += (xyz[3*i+d]-LinePoint[d])*(xyz[3*i+d]-LinePoint[d]);
00406                 if (LineVector[d] != 0.0) {
00407                   xs += (xyz[3*i+d]-LinePoint[d])/LineVector[d]; c += 1.0;
00408                 }
00409               }   
00410             c = xs/c;
00411             for (d=0; d<3; d++) 
00412               if (base::DimUsed(d) && 
00413                   std::fabs(c*LineVector[d]-xyz[3*i+d]+LinePoint[d])>
00414                   PROBE_TOLERANCE) {
00415                 lp = 0; break;
00416               }
00417             if (lp) {
00418               out << std::sqrt(di) << " ";        
00419               for (k=0; k<nkeys; k++) 
00420                 out << dat[k*length+i] << " ";
00421               out << std::endl;
00422             }
00423           }
00424         }
00425       }
00426       else {
00427         index_ordered_map_type imap;
00428         for (register int i=0; i<length; i++) 
00429           if (!LineProbe()) {
00430             for (register int d=0; d<3; d++)
00431                 if (base::DimUsed(d)) {
00432                   imap.insert(ordered_index_type(xyz[3*i+d],i));
00433                   break;
00434                 }
00435           }
00436           else {
00437             int lp = 1, d;
00438             float di = 0.0, xs = 0.0, c = 0.0;
00439             for (d=0; d<3; d++) 
00440               if (base::DimUsed(d)) {
00441                 di += (xyz[3*i+d]-LinePoint[d])*(xyz[3*i+d]-LinePoint[d]);
00442                 if (LineVector[d] != 0.0) {
00443                   xs += (xyz[3*i+d]-LinePoint[d])/LineVector[d]; c += 1.0;
00444                 }
00445               }
00446             c = xs/c;
00447             for (d=0; d<3; d++) 
00448               if (base::DimUsed(d) && 
00449                   std::fabs(c*LineVector[d]-xyz[3*i+d]+LinePoint[d])>
00450                   PROBE_TOLERANCE) {
00451                 lp = 0; break;
00452               }
00453             if (lp) 
00454               imap.insert(ordered_index_type(std::sqrt(di),i));
00455           }
00456         
00457         for (index_ordered_map_type::iterator it = imap.begin();
00458              it != imap.end(); ++it) {
00459           out << (*it).first << " ";
00460           for (k=0; k<nkeys; k++) 
00461             out << dat[k*length+(*it).second] << " ";
00462           out << std::endl;
00463         }
00464       }
00465     
00466       delete [] dat;
00467       delete [] xyz;
00468     }    
00469     else {
00470       std::ifstream in(PointFile.c_str(), std::ios::in);
00471       if (!in) {
00472         std::cerr << "Cannot open " << PointFile << " for reading!" << std::endl;
00473         return;
00474       }
00475       float SP[3];
00476       int d, k;
00477       point_list_type p;
00478       while (!in.eof()) {
00479         for (d=0; d<3; d++) 
00480           if (base::DimUsed(d))
00481             in >> SP[d];
00482           else SP[d]=0.0;
00483         if (in.eof()) continue;
00484         p.insert(p.end(), SP, SP+3);
00485       }
00486       in.close();
00487       if (!p.empty()) {
00488         unsigned int Np=p.size()/3;
00489         float *v=new float[Np*nkeys];
00490         for (k=0; k<nkeys; k++) 
00491           if (FKeys() == 1)
00492             base::SetPointsNodes(&(keys[k]),p,&(v[k*Np]));
00493           else
00494             base::SetPointsCells(&(keys[k]),p,&(v[k*Np]));
00495         
00496         for (register unsigned int i=0;i<Np;i++) {
00497           bool print=true;
00498           for (k=0; k<nkeys; k++) 
00499             if (v[k*Np+i]<=float(-1.e37)) { print=false; break; }
00500           if (print) {
00501             for (d=0; d<3; d++) 
00502               if (base::DimUsed(d))
00503                 out << p[3*i+d] << " ";
00504             for (k=0; k<nkeys; k++) 
00505               out << v[k*Np+i] << " ";
00506             out << std::endl;
00507           }
00508           else {
00509             std::cerr << "Point ( ";
00510             for (d=0; d<3; d++) 
00511               if (base::DimUsed(d))
00512                 std::cerr << p[3*i+d] << " ";
00513             std::cerr << ") outside of domain. Skipping..." << std::endl; 
00514           }
00515         }
00516         delete [] v;
00517       }
00518     }
00519   }
00520   
00521   void DimShape(int& dimshape, int& conshape) {
00522     if (base::Make3d) {
00523       dimshape = 3;
00524       conshape = 8;
00525     }
00526     else {
00527       dimshape = 0;
00528       conshape = 1;
00529       for (int d=0; d<3; d++) {
00530         dimshape += base::DimUsed(d);
00531         conshape *= (base::DimUsed(d) ? 2 : 1);
00532       }
00533     }
00534   }
00535 
00536   //  
00537   // All nodes are dumped out. Equal nodes in different subgrids are NOT deleted, but
00538   // DX does not seem to be disturbed.
00539   //
00540   void WriteDXFile(std::ostream& out) {
00541     int dxfile_dataoffset=0;
00542     int dimshape, conshape;
00543     DimShape(dimshape,conshape);
00544 
00545     int nnodes = NNodes(), ncells = NCells();    
00546     float* xyz = new float[3*nnodes];
00547     out << "object 1 class array type float rank 1 shape " << dimshape;
00548     out << " items " << nnodes;
00549 #if defined DX_LSB
00550     out << " lsb";
00551 #else
00552     out << " msb";
00553 #endif   
00554     out << " binary data " << dxfile_dataoffset << std::endl;
00555     SetGridNodes((float (*)[3]) xyz);
00556     dxfile_dataoffset+=dimshape*nnodes*sizeof(float);
00557 
00558     int* con = new int[8*ncells];    
00559     out << "object 2 class array type int rank 1 shape " << conshape;
00560     out << " items " << ncells;
00561 #if defined DX_LSB
00562     out << " lsb";
00563 #else
00564     out << " msb";
00565 #endif   
00566     out << " binary data " << dxfile_dataoffset << std::endl;
00567     SetGridConns((int (*)[8]) con);  
00568     out << "attribute \"element type\" string ";
00569     if (dimshape==3) out << "\"cubes\"";
00570     else if (dimshape==2) out << "\"quads\"";
00571     else if (dimshape==1) out << "\"lines\"";
00572 
00573     out << std::endl << "attribute \"ref\" string \"positions\"" << std::endl;
00574     dxfile_dataoffset+=conshape*ncells*sizeof(int);
00575 
00576     int length;
00577     if (FKeys() == 1)
00578       length = nnodes;
00579     else
00580       length = ncells;
00581     int nkl = nkeys*length;
00582     float* dat = new float[nkl];
00583     for (register int i=0; i<nkl; i++) *(dat+i) = 0.;
00584     out << "object 3 class array type float";
00585     if (nkeys>1) out << " rank 1 shape " << nkeys;
00586     out << " items " << length;
00587 #if defined DX_LSB
00588     out << " lsb";
00589 #else
00590     out << " msb";
00591 #endif   
00592     out << " binary data " << dxfile_dataoffset << std::endl;
00593     register int k;
00594     for (k=0; k<nkeys; k++) 
00595       SetScal(&(keys[k]),&(dat[k*length]));
00596     if (FKeys() == 6)
00597       out << "attribute \"dep\" string \"connections\"" << std::endl;
00598     dxfile_dataoffset+= nkeys*length*sizeof(float);
00599 
00600     out << "object \"default\" class field" << std::endl;
00601     out << "component \"positions\" value 1" << std::endl;
00602     out << "component \"connections\" value 2" << std::endl;
00603     out << "component \"data\" value 3" << std::endl;
00604     out << "end" << std::endl;
00605     
00606     register int n,t;
00607     if (dimshape==1) {
00608       for (n=0,t=0; n<nnodes; n++)
00609         xyz[t++] = xyz[3*n];
00610     }
00611     else if (dimshape==2) {
00612       for (n=0,t=0; n<nnodes; n++) {
00613         xyz[t++] = xyz[3*n]; xyz[t++] = xyz[3*n+1];
00614       }
00615     }
00616     out.write((char*) xyz, dimshape*nnodes*sizeof(float));
00617 
00618     if (conshape==2) {
00619       for (n=0,t=0; n<ncells; n++) {
00620         con[t++] = con[8*n]; con[t++] = con[8*n+1];
00621       }
00622     }
00623     if (conshape==4) {
00624       for (n=0,t=0; n<ncells; n++) {
00625         con[t++] = con[8*n  ]; con[t++] = con[8*n+1]; 
00626         con[t++] = con[8*n+2]; con[t++] = con[8*n+3];
00627       }
00628     }
00629     out.write((char*) con, conshape*ncells*sizeof(int));
00630 
00631     if (nkeys>1) {
00632       float* datout = new float[nkeys*length];
00633       int nn = 0;
00634       for (n=0; n<length; n++)
00635         for (k=0; k<nkeys; k++) {
00636           datout[nn] = dat[k*length+n]; nn++;
00637         }
00638       out.write((char*) datout, sizeof(float)*nkeys*length);
00639       delete [] datout;
00640     }
00641     else 
00642       out.write((char*) dat, sizeof(float)*length);
00643       
00644     delete [] xyz;
00645     delete [] con;
00646     delete [] dat;
00647   }    
00648 
00649   void WriteDXASCIIFile(std::ostream& out) {
00650     int dimshape, conshape;
00651     DimShape(dimshape,conshape);
00652     
00653     int nnodes = NNodes(), ncells = NCells();
00654     float* xyz = new float[3*nnodes];
00655     out << "object 1 class array type float rank 1 shape " << dimshape;
00656     out << " items " << nnodes << " data follows" << std::endl;
00657     SetGridNodes((float (*)[3]) xyz);
00658     register int i;
00659     for (i=0; i<nnodes; i++) {
00660       for (int d=0; d<dimshape; d++) 
00661         out << xyz[3*i+d] << " ";
00662       out << std::endl;
00663     }
00664 
00665     int* con = new int[8*ncells];    
00666     out << "object 2 class array type int rank 1 shape " << conshape;
00667     out << " items " << ncells << " data follows" << std::endl;
00668     SetGridConns((int (*)[8]) con);  
00669     for (i=0; i<ncells; i++) {
00670       for (int d=0; d<conshape; d++) 
00671         out << con[8*i+d] << " ";
00672       out << std::endl;
00673     }
00674 
00675     out << "attribute \"element type\" string ";
00676     if (dimshape==3) out << "\"cubes\"";
00677     else if (dimshape==2) out << "\"quads\"";
00678     else if (dimshape==1) out << "\"lines\"";
00679 
00680     out << std::endl << "attribute \"ref\" string \"positions\"" << std::endl;
00681     int length;
00682     if (FKeys() == 1)
00683       length = nnodes;
00684     else
00685       length = ncells;
00686     float* dat = new float[nkeys*length];
00687     for (i=0; i<nkeys*length; i++) *(dat+i) = 0.;
00688     out << "object 3 class array type float";
00689     if (nkeys>1) out << " rank 1 shape " << nkeys;
00690     out << " items " << length << " data follows" << std::endl;
00691     register int k;
00692     for (k=0; k<nkeys; k++) 
00693       SetScal(&(keys[k]),&(dat[k*length]));
00694     for (i=0; i<length; i++) {
00695       for (k=0; k<nkeys; k++) 
00696         out << " " << dat[k*length+i];
00697       out << std::endl;
00698     }
00699     if (FKeys() == 6)
00700       out << "attribute \"dep\" string \"connections\"" << std::endl;
00701 
00702     out << "object \"default\" class field" << std::endl;
00703     out << "component \"positions\" value 1" << std::endl;
00704     out << "component \"data\" value 3" << std::endl;
00705     out << "component \"connections\" value 2" << std::endl;
00706     out << "end" << std::endl;
00707         
00708     delete [] xyz;
00709     delete [] con;
00710     delete [] dat;
00711   }    
00712 
00713   void WriteDXExternalFilter(std::ostream& out) {
00714     int dimshape, conshape;
00715     DimShape(dimshape,conshape);
00716     
00717     int nnodes = NNodes(), ncells = NCells();
00718     float* xyz = new float[3*nnodes];
00719     out << "object 1 class array type float rank 1 shape " << dimshape;
00720     out << " items " << nnodes;
00721 #if defined DX_LSB
00722     out << " lsb";
00723 #else
00724     out << " msb";
00725 #endif   
00726     out << " binary data follows" << std::endl;
00727     SetGridNodes((float (*)[3]) xyz);
00728     register int n,t;
00729     if (dimshape==1) {
00730       for (n=0,t=0; n<nnodes; n++)
00731         xyz[t++] = xyz[3*n];
00732     }
00733     else if (dimshape==2) {
00734       for (n=0,t=0; n<nnodes; n++) {
00735         xyz[t++] = xyz[3*n]; xyz[t++] = xyz[3*n+1];
00736       }
00737     }
00738     out.write((char*) xyz, dimshape*nnodes*sizeof(float));
00739     delete [] xyz;
00740 
00741     int* con = new int[8*ncells];    
00742     out << "object 2 class array type int rank 1 shape " << conshape;
00743     out << " items " << ncells;
00744 #if defined DX_LSB
00745     out << " lsb";
00746 #else
00747     out << " msb";
00748 #endif   
00749     out << " binary data follows" << std::endl;
00750     SetGridConns((int (*)[8]) con);  
00751     if (conshape==2) {
00752       for (n=0,t=0; n<ncells; n++) {
00753         con[t++] = con[8*n]; con[t++] = con[8*n+1];
00754       }
00755     }
00756     if (conshape==4) {
00757       for (n=0,t=0; n<ncells; n++) {
00758         con[t++] = con[8*n  ]; con[t++] = con[8*n+1]; 
00759         con[t++] = con[8*n+2]; con[t++] = con[8*n+3];
00760       }
00761     }
00762     out.write((char*) con, conshape*ncells*sizeof(int));
00763     delete [] con;
00764 
00765     out << "attribute \"element type\" string ";
00766     if (dimshape==3) out << "\"cubes\"";
00767     else if (dimshape==2) out << "\"quads\"";
00768     else if (dimshape==1) out << "\"lines\"";
00769 
00770     out << "attribute \"ref\" string \"positions\"" << std::endl;
00771 
00772     int length;
00773     if (FKeys() == 1)
00774       length = nnodes;
00775     else
00776       length = ncells;
00777     float* dat = new float[nkeys*length];
00778     for (int i=0; i<nkeys*length; i++) *(dat+i) = 0.;
00779     out << "object 3 class array type float ";
00780     if (nkeys>1) out << "rank 1 shape " << nkeys << " ";
00781     if (FKeys() == 6)
00782       out << "attribute \"dep\" string \"connections\"" << std::endl;
00783     out << "items " << length;
00784 #if defined DX_LSB
00785     out << " lsb";
00786 #else
00787     out << " msb";
00788 #endif   
00789     out << " binary data follows" << std::endl;
00790     register int k;
00791     for (k=0; k<nkeys; k++) 
00792       SetScal(&(keys[k]),&(dat[k*length]));
00793     if (nkeys>1) {
00794       float* datout = new float[nkeys*length];
00795       int nn = 0;
00796       for (n=0; n<length; n++)
00797         for (k=0; k<nkeys; k++) {
00798           datout[nn] = dat[k*length+n]; nn++;
00799         }
00800       out.write((char*) datout, sizeof(float)*nkeys*length);
00801       delete [] datout;
00802     }
00803     else 
00804       out.write((char*) dat, sizeof(float)*length);      
00805     delete [] dat;
00806 
00807     out << "object \"default\" class field" << std::endl;
00808     out << "component \"positions\" value 1" << std::endl;
00809     out << "component \"connections\" value 2" << std::endl;
00810     out << "component \"data\" value 3" << std::endl;
00811     out << "end" << std::endl;  
00812   }    
00813 
00814   void WriteHDFConvert(int DimReduce) {
00815     if (!keys || _Step<0 || OutputName == "-") return;
00816     float64 realtime = RealTime();
00817     int32 ori[3],dims[3],res[4];
00818     int32 proc,level,gridID;
00819     int32 step = _Step;
00820     int32 rank = 3;
00821     char target[256];
00822     char dname[16];
00823     
00824     if (BlockList().size()>MAX_NC_VARS && FileMerge>=0) {
00825       std::cerr << "Maximal block count in HDF4 file exceeded. Setting FileMerge to 0." << std::endl;
00826       FileMerge = 0;
00827     }
00828 
00829     for (register int k=0; k<nkeys; k++) {
00830       std::string TargetName = OutputName;
00831       dname[0] = TheEvaluator().KeyboardKeys()[keys[k]-1]; dname[1] = 0;
00832       char time[20];
00833       base::OutputFileTime(time, _Step);
00834       if (nkeys>1)
00835         std::sprintf(target,"%s_%s_%s.hdf",OutputName.c_str(),dname,time);   
00836       else
00837         std::sprintf(target,"%s_%s.hdf",OutputName.c_str(),time);   
00838       
00839       std::cerr << "SetScalCells()";
00840       gridID=0;
00841       int last_proc = -1;
00842       for (typename block_list_type::reverse_iterator bit=BlockList().rbegin();
00843            bit!=BlockList().rend(); bit++, gridID++) {
00844 
00845         proc = (**bit).Processor();
00846         level = (**bit).Level();
00847         
00848         if (base::_parData==1 && FileMerge<=0) 
00849           if (proc!=last_proc) {
00850             if (last_proc>=0) {
00851               SDSflush(target);
00852               SDSclose(target);
00853             }
00854             if (nkeys>1)
00855               std::sprintf(target,"%s_%s_%s.%d.hdf",OutputName.c_str(),dname,time,(int)proc);   
00856             else
00857               std::sprintf(target,"%s_%s.%d.hdf",OutputName.c_str(),time,(int)proc); 
00858             last_proc = proc;
00859           }
00860 
00861         int offset=0;
00862         hdata_block_type tmpblock((**bit).DB().bbox());
00863         float* work = new DataType[(**bit).DB().bbox().size()];
00864 
00865         (**bit).SetScalCells(&(keys[k]),work,offset,base::CompRead);    
00866         BeginFastIndex3(tmp, tmpblock.bbox(), tmpblock.data(), DataType);
00867         int idx = 0;
00868         for_3 (n,m,l,tmpblock.bbox(),tmpblock.bbox().stepsize())
00869           FastIndex3(tmp,n,m,l) = work[idx];
00870           idx++;              
00871         end_for
00872         EndFastIndex3(tmp); 
00873         delete [] work;
00874 
00875         register int d;
00876         for (d=0; d<3; d++) {
00877           ori[d] = (int32) tmpblock.lower(d);
00878           if (!base::show_exact[d]) res[d] = (int32) tmpblock.stepsize(d);
00879           else res[d] = 1;
00880           dims[d] = (int32) tmpblock.extents(d);
00881         }
00882         res[3] = 1;
00883         if (!base::DimUsed(2)) {
00884           dims[2] = 1;
00885           ori[2] = 0;
00886           res[2] = 1;
00887           res[3] = 1;
00888           if (!base::DimUsed(1)) {
00889             dims[1] = 1;
00890             ori[1] = 0;
00891             res[1] = 1;
00892           }
00893         }
00894         if (DimReduce) {
00895           int dc = 0;
00896           for (d=0; d<3; d++) 
00897             if (base::show_exact[d]) {
00898               for (register int dd=d+1; dd<3; dd++) {
00899                 ori[dd-1] = ori[dd];
00900                 res[dd-1] = res[dd];
00901                 dims[dd-1] = dims[dd]; 
00902               }
00903               dc++;
00904               ori[3-dc] = 0; res[3-dc] = 1; dims[3-dc] = 1; 
00905             }
00906         }       
00907 
00908         if (sizeof(DataType) == SIZE_FLOAT32)
00909           SDSsetNT(target,DFNT_FLOAT32);    
00910         else if (sizeof(DataType) == SIZE_FLOAT64)
00911           SDSsetNT(target,DFNT_FLOAT64);    
00912         else if (sizeof(DataType) == SIZE_FLOAT128)
00913           SDSsetNT(target,DFNT_FLOAT128); 
00914         else
00915           std::cerr << "SDSsetNT() not called!" << std::endl;
00916         AMRwriteData(target,dname,proc,level,gridID,
00917                      step,realtime,rank,dims,ori,res,
00918                      tmpblock.data());
00919       }
00920       SDSflush(target);
00921       SDSclose(target);
00922       std::cerr << std::endl;
00923     }
00924   }    
00925   
00926   void WriteTecplotASCII(std::ostream& out) {
00927     int dimshape, conshape;
00928     DimShape(dimshape,conshape);
00929 
00930     if (dimshape==1) { 
00931       WriteASCIITabular(1,1,out); 
00932       return;
00933     }
00934     
00935     int length;
00936     if (FKeys() == 1)
00937       length = NNodes();
00938     else
00939       length = NCells();
00940     out << "title = \"t = " << RealTime() << "\"" << std::endl;
00941     float* xyz = new float[3*length];
00942     SetGrid((float (*)[3]) xyz);
00943 
00944     out << "variables = \"x\", \"y\"";
00945     if (dimshape>2) out << ", \"z\"";
00946     register int i,k;
00947     for (k=0; k<nkeys; k++) {
00948       char* title = new char[LEN_TKEYS];
00949       std::strcpy(title,TheEvaluator().TitleKeys(keys[k]-1));
00950       i=std::strlen(title)-1;
00951       while (title[i]==' ' && i>1) { title[i] = '\0'; i--; }      
00952       out << ", \"" << title << "\"";
00953     }
00954     out << std::endl;
00955     float* dat = new float[nkeys*length];
00956     for (i=0; i<nkeys*length; i++) *(dat+i) = 0.;
00957     for (k=0; k<nkeys; k++) 
00958       SetScal(&(keys[k]),&(dat[k*length]));
00959 
00960     int cnt=0,cbit=0,blength;
00961     for (typename block_list_type::iterator bit=BlockList().begin();
00962          bit!=BlockList().end(); bit++, cbit++) {
00963 
00964       Coords ext = (*bit)->DB().extents();
00965       if (FKeys() == 1) {
00966         ext += base::DimUsed; 
00967         blength = (*bit)->NNodes();
00968       }
00969       else
00970         blength = (*bit)->NCells();
00971 
00972       out << "zone t=\"B-" << cbit << " L-" << (*bit)->Level() << " P-" 
00973           << (*bit)->Processor() << "\", i=" << ext(0) << ", j=" << ext(1);
00974       if (dimshape>2) out << ", k=" << ext(2);
00975 
00976       if (PointOutput<=0) {
00977         out << ", f=block" << std::endl;
00978         for (register int d=0; d<dimshape; d++)
00979           for (i=0; i<blength; i++) {
00980             out << xyz[3*(cnt+i)+d] << " ";
00981             if ((i+1)%16==0) out << std::endl; 
00982           }
00983         out << std::endl << std::endl;
00984         for (k=0; k<nkeys; k++) {
00985           for (i=0; i<blength; i++) {
00986             out << dat[k*length+cnt+i] << " ";
00987             if ((i+1)%16==0) out << std::endl; 
00988           }
00989           out << std::endl << std::endl;
00990         }
00991       }
00992       else {
00993         out << ", f=point" << std::endl;
00994         for (i=0; i<blength; i++) {
00995           for (register int d=0; d<dimshape; d++) 
00996             out << xyz[3*(cnt+i)+d] << " ";
00997           for (k=0; k<nkeys; k++) 
00998             out << " " << dat[k*length+cnt+i];
00999           out << std::endl;
01000         }
01001         out << std::endl;
01002       }
01003       cnt += blength;
01004     }
01005         
01006     delete [] xyz;
01007     delete [] dat;
01008   }
01009 
01010 
01011   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
01012   //                                            WRITE VTU ASCII FILE
01013   //
01014   // this function converts the amroc dumped hdf files (in memory)
01015   // into an xml based VTK unstructured grid format. notice that the
01016   // levels have been flattened. it is quite inefficient.
01017   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
01018 # define VTK_USED_DIMS 3
01019   void WriteVTUASCIIFile(std::ostream& out)  {
01020     // VTI ASCI File writer. based of VTKASCII writer.
01021     // http://www.vtf.website/~slombey/asci/vtk/
01022     int dimshape, conshape;
01023     DimShape(dimshape,conshape);
01024 
01025     out << "<?xml version=\"1.0\"?>" << std::endl;
01026     out << "<?meta name=\"source\" content=\"HDF data created with AMROC's hdf2file\"?>" 
01027         << std::endl;
01028     out << "<?meta name=\"timestamp\" content=\"" << RealTime() << "\"?>" << std::endl;
01029 
01030     // VTU XML HEADER
01031     int nnodes = NNodes(), ncells = NCells();
01032     float* xyz = new float[3*nnodes];
01033     out << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">" 
01034         << std::endl;
01035     out << "<UnstructuredGrid>" << std::endl;
01036     out << "<Piece NumberOfPoints=\"" << nnodes << "\" NumberOfCells=\"" << ncells << "\">" 
01037         << std::endl;
01038 
01039     // flatten points (i.e. remove duplicates) and print
01040     out << "<Points>" << std::endl;
01041     out << "<DataArray type=\"Float32\" NumberOfComponents=\""<< VTK_USED_DIMS 
01042         << "\" format=\"ascii\" Name=\"vertex\">" << std::endl;
01043     SetGridNodes((float (*)[3]) xyz);
01044     register int i;
01045     for (i=0; i<nnodes; i++) {
01046       for (register int d=0; d<VTK_USED_DIMS; d++) 
01047         out << xyz[3*i+d] << " ";
01048       out << std::endl;
01049     }
01050     out << "</DataArray>" << std::endl;
01051     out << "</Points>" << std::endl;
01052 
01053     // cells
01054     int* con = new int[8*ncells];    
01055     out << "<Cells>" << std::endl;
01056     out << "<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">" << std::endl;
01057     // print cells->connectivities
01058     SetGridConns((int (*)[8]) con);  
01059     for (i=0; i<ncells; i++) {
01060       for (register int d=0; d<conshape; d++) 
01061         out << con[8*i+d] << " ";
01062       out << std::endl;
01063     }
01064     out << "</DataArray>" << std::endl;
01065 
01066     // print cells->element offsets
01067     out << "<DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">" << std::endl;
01068     for (i=1; i<=ncells; i++)
01069       out << i*conshape << std::endl;
01070     out << "</DataArray>" << std::endl;
01071     
01072     // print cells->types
01073     int cell_type = 1;
01074     if (dimshape==3) cell_type = 11;
01075     else if (dimshape==2) cell_type = 8;
01076     else if (dimshape==1) cell_type = 3;
01077 
01078     out << "<DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">" << std::endl;
01079     for (i=0; i<ncells; i++) 
01080       out << cell_type << std::endl;
01081     out << "</DataArray>" << std::endl;
01082 
01083     out << "</Cells>" << std::endl;
01084     
01085     int length;
01086     if (FKeys() == 1) {
01087       length = nnodes;
01088       out << "<PointData>" << std::endl;
01089     }
01090     else {
01091       length = ncells;
01092       out << "<CellData>" << std::endl;
01093     }
01094     float* dat = new float[nkeys*length];
01095     for (i=0; i<nkeys*length; i++) *(dat+i) = 0.;
01096     register int k;
01097     for (k=0; k<nkeys; k++) 
01098       SetScal(&(keys[k]),&(dat[k*length]));
01099     for (k=0; k<nkeys; k++) {
01100       char* title = new char[LEN_TKEYS];
01101       // clean up title string
01102         std::strcpy(title,TheEvaluator().TitleKeys(keys[k]-1));
01103         i=std::strlen(title)-1;
01104         while (title[i]==' ' && i>1) { title[i] = '\0'; i--; }
01105         int n=std::strlen(title);
01106         for (i=0; i<n; i++) if (title[i]==' ') title[i]='_';
01107       out << "<DataArray type=\"Float32\" Name=\"" << title 
01108           << "\" format=\"ascii\" NumberOfComponents=\"1\">" << std::endl;
01109       for (i=0; i<length; i++) 
01110         out << dat[k*length+i] << std::endl; 
01111       out << "</DataArray>" << std::endl;
01112     }
01113 
01114     if (FKeys() == 1)
01115       out << "</PointData>" << std::endl;
01116     else 
01117       out << "</CellData>" << std::endl;
01118     out << "</Piece>" << std::endl;
01119     out << "</UnstructuredGrid>" << std::endl;
01120     out << "</VTKFile>" << std::endl;
01121  
01122     delete [] xyz;
01123     delete [] con;
01124     delete [] dat;
01125   }
01126 
01127   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
01128   //                                                     WRITE VTU FILE
01129   //
01130   // this function converts the amroc dumped hdf files (in memory)
01131   // into an xml based VTK unstructured grid format. the data is dumped
01132   // in binary after being 64base converted. (see mime). an extra integer
01133   // is added at the beginning of each binary array with the length.
01134   // + some loops have been flattened for efficiency.
01135   // + the data is dumped to a buffer (2megs) to make more efficient
01136   //   writes. the size of this buffer can be altered (hardwired). see
01137   //   encodeToBase64.h
01138   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
01139   void WriteVTUFile(std::ostream& out)  {
01140     // VTI ASCI File writer. based of VTKASCII writer.
01141     // http://www.vtf.website/~slombey/asci/vtk/
01142     int dimshape, conshape;
01143     DimShape(dimshape,conshape);
01144     unsigned long appendedDataOffset=0;
01145 
01146      // hack or needed? not in vtk specs, but seems necessary
01147     bool addHeaderSizeAsInt32=true;
01148 
01149     out << "<?xml version=\"1.0\"?>" << std::endl;
01150     out << "<?meta name=\"source\" content=\"HDF data created with AMROC's hdf2file\"?>" 
01151         << std::endl;
01152     out << "<?meta name=\"timestamp\" content=\"" << RealTime() << "\"?>" << std::endl;
01153 
01154     // VTU XML HEADER
01155     int nnodes = NNodes(), ncells = NCells();
01156     float* xyz = new float[3*nnodes];
01157     out << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=";
01158     if (isBigEndian())
01159         out << "\"BigEndian\">" << std::endl;
01160     else
01161         out << "\"LittleEndian\">" << std::endl;
01162     out << "<UnstructuredGrid>" << std::endl;
01163     out << "<Piece NumberOfPoints=\"" << nnodes << "\" NumberOfCells=\"" << ncells << "\">" 
01164         << std::endl;
01165 
01166     // flatten points (i.e. remove duplicates) and print
01167     out << "<Points>" << std::endl;
01168     out << "<DataArray type=";
01169     if (sizeof(float)==4)
01170       out << "\"Float32\"";
01171     else if (sizeof(float)==8)
01172       out << "\"Float64\"";
01173     else out << "\"Float" << sizeof(float)*8 <<"\""; // usupported!
01174     out << " NumberOfComponents=\""<< VTK_USED_DIMS 
01175         << "\" Name=\"vertex\" format=\"appended\" offset=\"" << appendedDataOffset 
01176         << "\" />" << std::endl;
01177 
01178     unsigned long deltaDataOffset= VTK_USED_DIMS*nnodes;
01179     deltaDataOffset*=sizeof(float);
01180     if (addHeaderSizeAsInt32) deltaDataOffset+=4;
01181     if (deltaDataOffset%3>0) deltaDataOffset+=(3-(deltaDataOffset%3));
01182     deltaDataOffset=deltaDataOffset/3*4;
01183     appendedDataOffset+=deltaDataOffset;
01184 
01185     out << "</Points>" << std::endl;
01186     out << "<Cells>" << std::endl;
01187     out << "<DataArray type=\"Int32\" Name=\"connectivity\" format=\"appended\" offset=\"" 
01188         << appendedDataOffset << "\" />" << std::endl;
01189 
01190     deltaDataOffset= conshape*ncells;
01191     deltaDataOffset*=sizeof(int);
01192     if (addHeaderSizeAsInt32) deltaDataOffset+=4;
01193     if (deltaDataOffset%3>0) deltaDataOffset+=(3-(deltaDataOffset%3));
01194     deltaDataOffset=deltaDataOffset/3*4;
01195     appendedDataOffset+=deltaDataOffset;
01196 
01197     out << "<DataArray type=\"Int32\" Name=\"offsets\" format=\"appended\" offset=\"" 
01198         << appendedDataOffset << "\" />" << std::endl;
01199     deltaDataOffset= ncells;
01200     deltaDataOffset*=sizeof(int);
01201     if (addHeaderSizeAsInt32) deltaDataOffset+=4;
01202     if (deltaDataOffset%3>0) deltaDataOffset+=(3-(deltaDataOffset%3));
01203     deltaDataOffset=deltaDataOffset/3*4;
01204     appendedDataOffset+=deltaDataOffset;
01205 
01206     out << "<DataArray type=\"UInt8\" Name=\"types\" format=\"appended\" offset=\"" 
01207         << appendedDataOffset << "\" />" << std::endl;
01208     deltaDataOffset= ncells;
01209     deltaDataOffset*=sizeof(char);
01210     if (addHeaderSizeAsInt32) deltaDataOffset+=4;
01211     if (deltaDataOffset%3>0) deltaDataOffset+=(3-(deltaDataOffset%3));
01212     deltaDataOffset=deltaDataOffset/3*4;
01213     appendedDataOffset+=deltaDataOffset;
01214 
01215     out << "</Cells>" << std::endl;
01216     
01217     int length;
01218     if (FKeys() == 1) {
01219       length = nnodes;
01220       out << "<PointData>" << std::endl;
01221     } else {
01222       length = ncells;
01223       out << "<CellData>" << std::endl;
01224     }
01225 
01226     for (int k=0; k<nkeys; k++) {
01227       char* title = new char[LEN_TKEYS];
01228       // clean up title string
01229         std::strcpy(title,TheEvaluator().TitleKeys(keys[k]-1));
01230         int i=std::strlen(title)-1;
01231         while (title[i]==' ' && i>1) { title[i] = '\0'; i--; }
01232         int n=std::strlen(title);
01233         for (i=0; i<n; i++) if (title[i]==' ') title[i]='_';
01234 
01235       out << "<DataArray type=";
01236       if (sizeof(float)==4) out << "\"Float32\"";
01237       else if (sizeof(float)==8) out << "\"Float64\"";
01238       out << " Name=\"" << title << "\" NumberOfComponents=\"1\" format=\"appended\" offset=\"" 
01239           << appendedDataOffset << "\" />" << std::endl;
01240 
01241       deltaDataOffset=length;
01242       deltaDataOffset*=sizeof(float);
01243       if (addHeaderSizeAsInt32) deltaDataOffset+=4;
01244       if (deltaDataOffset%3>0) deltaDataOffset+=(3-(deltaDataOffset%3));
01245       deltaDataOffset=deltaDataOffset/3*4;
01246       appendedDataOffset+=deltaDataOffset;
01247     }
01248 
01249     if (FKeys() == 1)
01250       out << "</PointData>" << std::endl;
01251     else 
01252       out << "</CellData>" << std::endl;
01253     out << "</Piece>" << std::endl;
01254     out << "</UnstructuredGrid>" << std::endl;
01255 
01256     // APPENDED DATA 
01257 
01258     out << "<AppendedData encoding=\"base64\">" << std::endl;
01259     out << "_";
01260 
01261     SetGridNodes((float (*)[3]) xyz);
01262 
01263     // encode x,y,z (go in sets of 3, and encode leftovers at the end)
01264     register int i;
01265     int dataBlockSize;
01266     dataBlockSize=nnodes*VTK_USED_DIMS*sizeof(float);
01267     if (addHeaderSizeAsInt32)
01268       encodeToBase64AndWrite((unsigned char *)&dataBlockSize,sizeof(int),out);
01269     encodeToBase64AndWrite((unsigned char *)xyz,dataBlockSize,out,true);
01270 
01271     // cells
01272     int* con = new int[8*ncells];    
01273 
01274     // print cells->connectivities
01275     SetGridConns((int (*)[8]) con);  
01276 
01277     // encode conns(go in sets of 3, and encode leftovers at the end)
01278     dataBlockSize=ncells*conshape*sizeof(int);
01279     if (addHeaderSizeAsInt32)
01280       encodeToBase64AndWrite((unsigned char *)&dataBlockSize,sizeof(int),out);
01281     int deltamaxcon=8*sizeof(int);
01282     int deltacon   =conshape*sizeof(int);
01283     unsigned char *srccon=(unsigned char *)con;
01284     unsigned char *dstcon=(unsigned char *)con;
01285     if (deltamaxcon!=deltacon && conshape<8) {
01286       for (i=1; i<ncells; i++) {
01287          srccon+=deltamaxcon;
01288          dstcon+=deltacon;
01289          memcpy(dstcon,srccon,deltacon);
01290       }
01291     }
01292     encodeToBase64AndWrite((unsigned char *)con,dataBlockSize,out,true);
01293 
01294     // print cells->element offsets
01295     // encode element offsets (go in sets of 3, and encode leftovers at the end)
01296     dataBlockSize=ncells*sizeof(int);
01297     if (addHeaderSizeAsInt32)
01298       encodeToBase64AndWrite((unsigned char *)&dataBlockSize,sizeof(int),out);
01299     for (i=0; i<ncells; i++) con[i]= (i+1)*conshape;
01300     encodeToBase64AndWrite((unsigned char *)con,dataBlockSize,out,true);
01301 
01302 
01303     // print cells->types
01304     unsigned char cell_type = 1;
01305     if (dimshape==3) cell_type = 11;
01306     else if (dimshape==2) cell_type = 8;
01307     else if (dimshape==1) cell_type = 3;
01308 
01309 
01310     // encode element celltypes (go in sets of 3, and encode leftovers at the end)
01311     dataBlockSize=ncells;
01312     if (addHeaderSizeAsInt32) {
01313       encodeToBase64AndWrite((unsigned char *)&dataBlockSize,sizeof(int),out);
01314     }
01315     int four_cell_types;
01316     ((char *)(&four_cell_types))[0]=cell_type;
01317     ((char *)(&four_cell_types))[1]=cell_type;
01318     ((char *)(&four_cell_types))[2]=cell_type;
01319     ((char *)(&four_cell_types))[3]=cell_type;
01320     for (i=0; i<(ncells+3)/4; i++) con[i]= four_cell_types;
01321     encodeToBase64AndWrite((unsigned char *)con,dataBlockSize,out,true);
01322 
01323     float* dat = new float[nkeys*length];
01324     bzero(dat,nkeys*length*sizeof(float));
01325     register int k;
01326     for (k=0; k<nkeys; k++) 
01327       SetScal(&(keys[k]),&(dat[k*length]));
01328     for (k=0; k<nkeys; k++) {
01329       // encode each of the data keys [vars] (go in sets of 3, and encode leftovers at the end)
01330       dataBlockSize=length*sizeof(float);
01331       if (addHeaderSizeAsInt32) {
01332         encodeToBase64AndWrite((unsigned char *)&dataBlockSize,sizeof(int),out);
01333       }
01334       encodeToBase64AndWrite((unsigned char *)&(dat[k*length]),dataBlockSize,out,true);
01335     }
01336     out <<  std::endl;
01337 
01338     out << "<? meta name=\"datasize\" size=\"" << appendedDataOffset << "\" ?>" << std::endl;
01339 
01340     out << std::endl;
01341     out << "</AppendedData>" << std::endl;
01342     out << "</VTKFile>" << std::endl;
01343  
01344     delete [] xyz;
01345     delete [] con;
01346     delete [] dat;
01347   }
01348 
01349   void WriteVTKASCIIFile(std::ostream& out)  {
01350     int dimshape, conshape;
01351     DimShape(dimshape,conshape);
01352 
01353     int nnodes = NNodes(), ncells = NCells();
01354     float* xyz = new float[3*nnodes];
01355     out << "# vtk DataFile Version 3.0" << std::endl;
01356     out << "HDF data created with AMROC's hdf2file" << std::endl;
01357     out << "ASCII" << std::endl;
01358     out << "DATASET UNSTRUCTURED_GRID" << std::endl;
01359     out << "POINTS " << nnodes << " float" << std::endl;
01360     SetGridNodes((float (*)[3]) xyz);
01361     register int i;
01362     for (i=0; i<nnodes; i++) {
01363       for (int d=0; d<VTK_USED_DIMS; d++) 
01364         out << xyz[3*i+d] << " ";
01365       out << std::endl;
01366     }
01367 
01368     int* con = new int[8*ncells];    
01369     out << "CELLS " << ncells << " " << ncells*(conshape+1) << std::endl;
01370     SetGridConns((int (*)[8]) con);  
01371     for (i=0; i<ncells; i++) {
01372       out << conshape << " ";
01373       for (int d=0; d<conshape; d++) 
01374         out << con[8*i+d] << " ";
01375       out << std::endl;
01376     }
01377 
01378     int cell_type = 1;
01379     if (dimshape==3) cell_type = 11;
01380     else if (dimshape==2) cell_type = 8;
01381     else if (dimshape==1) cell_type = 3;
01382 
01383     out << "CELL_TYPES " << ncells << std::endl;
01384     for (i=0; i<ncells; i++) 
01385       out << cell_type << std::endl;
01386     
01387     int length;
01388     if (FKeys() == 1) {
01389       length = nnodes;
01390       out << "POINT_DATA ";
01391     }
01392     else {
01393       length = ncells;
01394       out << "CELL_DATA ";
01395     }
01396     out << length << std::endl;    
01397     float* dat = new float[nkeys*length];
01398     bzero(dat,nkeys*length*sizeof(float));
01399 
01400     register int k;
01401     for (k=0; k<nkeys; k++) 
01402       SetScal(&(keys[k]),&(dat[k*length]));
01403     out << "FIELD Data " << nkeys << std::endl;     
01404     for (k=0; k<nkeys; k++) {
01405       char* title = new char[LEN_TKEYS];
01406       std::strcpy(title,TheEvaluator().TitleKeys(keys[k]-1));
01407       i=std::strlen(title)-1;
01408       while (title[i]==' ' && i>1) { title[i] = '\0'; i--; }
01409       int n=std::strlen(title);
01410       for (i=0; i<n; i++) 
01411         if (title[i]==' ') title[i]='_';
01412       out << title << " 1 " << length << " float" << std::endl;
01413       for (i=0; i<length; i++) 
01414         out << dat[k*length+i] << std::endl; 
01415     }
01416     
01417     delete [] xyz;
01418     delete [] con;
01419     delete [] dat;
01420   }   
01421 
01422 
01423   void flipBytes(char *c, int n) {
01424      char *ptr=c;
01425      char x;
01426      n/=4;
01427      for (register int i=0; i<n; i++) {
01428        x=ptr[3]; ptr[3]=ptr[0]; ptr[0]=x;
01429        x=ptr[2]; ptr[2]=ptr[1]; ptr[1]=x;
01430        ptr+=4;
01431      }
01432   }
01433   void WriteVTKFile(std::ostream& out) {
01434     int dimshape, conshape;
01435     DimShape(dimshape,conshape);
01436     bool writeSizeAsHeader=false;       // equivalent to addHeaderSizeAsInt32 on binary VTU
01437     bool flipdatabytes=((char *)(&conshape))[3]==0;
01438 
01439     int nnodes = NNodes(), ncells = NCells();
01440     float* xyz = new float[3*nnodes];
01441     out << "# vtk DataFile Version 3.0" << std::endl;
01442     out << "HDF data created with AMROC's hdf2file" << std::endl;
01443     out << "BINARY" << std::endl;
01444     out << "DATASET UNSTRUCTURED_GRID" << std::endl;
01445     out << "POINTS " << nnodes << " float" << std::endl;
01446     SetGridNodes((float (*)[3]) xyz);
01447     register int n;
01448     if (writeSizeAsHeader) {
01449       int binaryBlockSize= VTK_USED_DIMS*nnodes;
01450       out.write((char*)&binaryBlockSize,sizeof(int));
01451     }
01452     if (flipdatabytes) flipBytes((char*) xyz, VTK_USED_DIMS*nnodes*sizeof(float));
01453     out.write((char*) xyz, VTK_USED_DIMS*nnodes*sizeof(float));
01454     out << std::endl;
01455     delete [] xyz;
01456 
01457     int* con = new int[8*ncells];    
01458     int* con2 = new int[9*ncells];  
01459     int c2shape = conshape+1;
01460     out << "CELLS " << ncells << " " 
01461         << ncells*(conshape+1) << std::endl;
01462     SetGridConns((int (*)[8]) con);  
01463     for (n=0; n<ncells; n++) 
01464       con2[c2shape*n] = conshape;
01465     for (register int i=0; i<conshape; i++)
01466       for (n=0; n<ncells; n++) 
01467         con2[c2shape*n+i+1] = con[8*n+i];
01468     if (writeSizeAsHeader) {
01469       int binaryBlockSize= (conshape+1)*ncells;
01470       out.write((char*)&binaryBlockSize,sizeof(int));
01471     }
01472     if (flipdatabytes) flipBytes((char*) con2, (conshape+1)*ncells*sizeof(int));
01473     out.write((char*) con2, (conshape+1)*ncells*sizeof(int));
01474     out << std::endl;
01475     delete [] con; delete [] con2;
01476     
01477     int cell_type = 1;
01478     if (dimshape==3) cell_type = 11;
01479     else if (dimshape==2) cell_type = 8;
01480     else if (dimshape==1) cell_type = 3;
01481     int* type = new int[ncells];    
01482     for (n=0; n<ncells; n++)
01483       type[n] = cell_type;
01484     out << "CELL_TYPES " << ncells << std::endl;
01485     if (writeSizeAsHeader) {
01486       int binaryBlockSize=  ncells;
01487       out.write((char*)&binaryBlockSize,sizeof(int));
01488     }
01489     if (flipdatabytes) flipBytes((char*) type, ncells*sizeof(int));
01490     out.write((char*) type, ncells*sizeof(int));
01491     out << std::endl;
01492     delete [] type;
01493 
01494     int length;
01495     if (FKeys() == 1) {
01496       length = nnodes;
01497       out << "POINT_DATA ";
01498     }
01499     else {
01500       length = ncells;
01501       out << "CELL_DATA ";
01502     }
01503     out << length << std::endl;    
01504     float* dat = new float[nkeys*length];
01505     for (n=0; n<nkeys*length; n++) *(dat+n) = 0.;
01506     register int k;
01507     for (k=0; k<nkeys; k++) 
01508       SetScal(&(keys[k]),&(dat[k*length]));
01509     out << "FIELD Data " << nkeys << std::endl;  
01510     for (k=0; k<nkeys; k++) {
01511       char* title = new char[LEN_TKEYS];
01512       std::strcpy(title,TheEvaluator().TitleKeys(keys[k]-1));
01513       int i=std::strlen(title)-1;
01514       while (title[i]==' ' && i>1) { title[i] = '\0'; i--; }
01515       int n=std::strlen(title);
01516       for (i=0; i<n; i++) 
01517         if (title[i]==' ') title[i]='_';
01518       out << title << " 1 " << length << " float" << std::endl;
01519       if (writeSizeAsHeader) {
01520         int binaryBlockSize=  length;
01521         out.write((char*)&binaryBlockSize,sizeof(int));
01522       }
01523 
01524       if (flipdatabytes) flipBytes((char*) &(dat[k*length]), length*sizeof(float));
01525       out.write((char*) &(dat[k*length]), length*sizeof(float));
01526       out << std::endl;
01527     }
01528     delete [] dat;
01529   }    
01530 
01531   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
01532   //                                                   WRITE SILO FILE
01533   //
01534   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
01535 #if defined(HAVE_LIBSILO) || defined(HAVE_LIBSILOH5)
01536   void WriteSiloFile(char *silofilename)  {
01537     if (silofilename==0 || silofilename[0]==0) {
01538       std::cerr << "Abort: Cannot write SILO to stdout. "
01539                 << "Please provide FileName in your display_file.in" << std::endl;
01540       return;
01541     }
01542 #if defined(HAVE_LIBSILOH5)
01543     DBfile * silofptr= DBCreate(silofilename, DB_CLOBBER, DB_LOCAL, NULL, DB_HDF5);
01544 #else
01545     DBfile * silofptr= DBCreate(silofilename, DB_CLOBBER, DB_LOCAL, NULL, DB_PDB);
01546 #endif
01547     if (!silofptr) {
01548       std::cerr << "Abort: could not create SILO file." << std::endl;
01549       return;
01550     }
01551 
01552     int dimshape, conshape;
01553     DimShape(dimshape,conshape);
01554 
01555     int nnodes = NNodes(), ncells = NCells();
01556     int vardatacentering, length;
01557     if (FKeys() == 1) {
01558       vardatacentering=DB_NODECENT;
01559       length = nnodes;
01560     } else {
01561       vardatacentering=DB_ZONECENT;
01562       length = ncells;
01563     }
01564 
01565     std::cerr << std::endl;
01566 
01567     float * xyz = new float[3*nnodes];
01568     char  * coordnames [3]= {"X","Y","Z"};
01569     float * coordinates[3];
01570 
01571     coordinates[0]=xyz;
01572     coordinates[1]=coordinates[0]+nnodes;
01573     coordinates[2]=coordinates[1]+nnodes;
01574 
01575 #   ifdef USE_PRESET_AMROC_BLOCK_COORDS
01576     SetGridNodes((float (*)[3]) xyz);
01577     register int n,t;
01578     if (dimshape==1) {
01579       for (n=0,t=0; n<nnodes; n++)
01580         xyz[t++] = xyz[3*n];
01581     }
01582     else if (dimshape==2) {
01583       for (n=0,t=0; n<nnodes; n++) {
01584         xyz[t++] = xyz[3*n]; xyz[t++] = xyz[3*n+1];
01585       }
01586     }
01587 #   endif
01588 
01589     float* dat = new float[nkeys*length];
01590     register int i,k;
01591     for (i=0; i<nkeys*length; i++) *(dat+i) = 0.;
01592     for (k=0; k<nkeys; k++) 
01593       SetScal(&(keys[k]),&(dat[k*length]));
01594 
01595     int    *blocklevel = new int[BlockList().size()];
01596     char  **vartitles  = new char* [nkeys];
01597     int     leveltitle = -1;
01598 
01599     // get variable name
01600     for (k=0; k<nkeys; k++) {
01601       char *title = new char[LEN_TKEYS];
01602       std::strcpy(title,TheEvaluator().TitleKeys(keys[k]-1));
01603       i=std::strlen(title)-1;
01604       while (title[i]==' ' && i>1) { title[i] = '\0'; i--; }
01605       int n=std::strlen(title);
01606       for (i=0; i<n; i++) {
01607         if (title[i]==' ' ||
01608             title[i]=='.' ||
01609             title[i]=='-' ||
01610             title[i]=='+' ||
01611             title[i]=='/'    ) title[i]='_';
01612       }
01613       vartitles[k] = new char[std::strlen(title)+1];
01614       for (i=0; i<n; i++) 
01615         vartitles[k][i]=std::toupper(title[i]);
01616       vartitles[k][i]='\0';
01617       delete [] title;
01618       if (!std::strcmp(vartitles[k],"LEVEL") || !std::strcmp(vartitles[k],"LEVELS"))
01619       leveltitle=k;
01620     }
01621 
01622     int offset=0, maxlevel=-1, nblock=0;
01623     char **meshptrs= new char *[BlockList().size()];
01624     char **varptrs=  new char *[BlockList().size()];
01625 
01626     for (typename block_list_type::iterator bit=BlockList().begin();
01627          bit!=BlockList().end(); bit++, nblock++) {
01628       float fmin[3], fmax[3];
01629       int idims[3], vardims[3];
01630       for (i=0; i<dimshape; i++) {
01631         fmin[i] = (**bit).DB().bbox().lower(i)*base::dx[i]+base::geom[i*2];
01632         fmax[i] = ((**bit).DB().bbox().upper(i)+
01633                    (**bit).DB().bbox().stepsize(i))*base::dx[i]+base::geom[i*2];
01634         idims[i]= (**bit).DB().bbox().extents(i)+1;
01635         vardims[i]=idims[i];
01636         if (vardatacentering==DB_ZONECENT) vardims[i]--;
01637         if (vardims[i]<=0) vardims[i]=1;
01638       }
01639 
01640       // creating a directory per block
01641       char *meshblockdirname= new char[LEN_TKEYS];
01642       meshblockdirname[0]='/';
01643       meshblockdirname++;
01644       sprintf(meshblockdirname,"BLOCK%04i",nblock);
01645       DBSetDir(silofptr,"/");
01646       DBMkDir(silofptr,meshblockdirname);
01647       DBSetDir(silofptr,meshblockdirname);
01648 
01649       char *meshblockname= meshblockdirname + std::strlen(meshblockdirname)+1;
01650       meshblockname[-1]='/';
01651       sprintf(meshblockname,"block%04i",nblock);
01652 
01653       meshptrs[nblock]=meshblockdirname;
01654       varptrs[nblock]= meshblockname;
01655 
01656 #     ifdef USE_PRESET_AMROC_BLOCK_COORDS
01657       std::cerr<<"using USE_PRESET_AMROC_BLOCK_COORDS" << std::endl;
01658       for (i=0; i<dimshape; i++)
01659         coordinates[i]=&(xyz[dimshape*offset+i]);
01660       DBPutQuadmesh(silofptr, meshblockname ,coordnames, coordinates, idims, dimshape, DB_FLOAT, DB_COLLINEAR, NULL);
01661 #     else
01662       for (i=0; i<dimshape; i++) {
01663         for (register int idx=0; idx<idims[i]; idx++)
01664           coordinates[i][idx]=fmin[i]+(float)idx*(fmax[i]-fmin[i])/(float)(idims[i]-1);
01665       }
01666       DBPutQuadmesh(silofptr, meshblockname ,coordnames, coordinates, idims, dimshape, DB_FLOAT, DB_COLLINEAR, NULL);
01667 #     endif
01668 
01669       for (k=0; k<nkeys; k++) {
01670         if (k==leveltitle) {
01671           blocklevel[nblock]=(**bit).Level();
01672           if (blocklevel[nblock]>maxlevel) maxlevel=blocklevel[nblock];
01673         }
01674         DBPutQuadvar1(silofptr, vartitles[k], meshblockname, &(dat[offset+k*length]),
01675                       vardims, dimshape, NULL, 0,DB_FLOAT,  vardatacentering, NULL);
01676       }
01677       if (FKeys()==1) offset += (**bit).NNodes();
01678       else offset += (**bit).NCells();
01679     }
01680 
01681     bool   dump_sets=true;
01682     if (dump_sets) {
01683     DBSetDir(silofptr,"/");
01684     char * levelmesh = new char[LEN_TKEYS];
01685     char * varmeshname = new char[LEN_TKEYS];
01686  
01687     int   * meshtypes=new int[BlockList().size()];
01688     char ** imeshptrs=new char *[nblock];
01689     for (int i=0; i<nblock; i++) {
01690       meshtypes[i]= DB_QUAD_RECT;
01691       imeshptrs[i]=meshptrs[nblock-i-1];
01692     }
01693     DBPutMultimesh(silofptr, "/ALL_LEVELS", nblock, meshptrs, meshtypes, NULL);
01694 
01695     DBSetDir(silofptr,"/");
01696     DBMkDir(silofptr,"LEVELS");
01697     for (int l=maxlevel; l>=0; l--) {
01698       int ninlevel=0;
01699       for (register int idx=0; idx<nblock; idx++) {
01700         if (blocklevel[idx]==l) {
01701           imeshptrs[ninlevel++]=meshptrs[idx]-1;
01702         }
01703       }  
01704       if (ninlevel>0) {
01705         sprintf(levelmesh,"/LEVELS/LEVEL_%03i",l);
01706         DBPutMultimesh(silofptr, levelmesh, ninlevel, imeshptrs, meshtypes, NULL);
01707       }
01708     }
01709 
01710     for (register int idx=0; idx<nblock; idx++) meshtypes[idx]= DB_QUADVAR;
01711     for (k=0; k<nkeys; k++) {
01712       sprintf(varmeshname,"VAR_%s",vartitles[k]);
01713       for (register int idx=0; idx<nblock; idx++) std::strcpy(varptrs[idx],vartitles[k]);
01714 
01715       DBSetDir(silofptr,"/");
01716       DBMkDir(silofptr,varmeshname);
01717       DBSetDir(silofptr,varmeshname);
01718       sprintf(varmeshname,"/VAR_%s/ALL_LEVELS",vartitles[k]);
01719       for (register int idx=0; idx<nblock; idx++) imeshptrs[idx]=meshptrs[idx]-1;
01720       DBPutMultivar(silofptr, varmeshname, nblock, imeshptrs, meshtypes, NULL);
01721       DBSetDir(silofptr,"/");
01722 
01723       for (int l=maxlevel; l>=0; l--) {
01724         int ninlevel=0;
01725         for (register int idx=0; idx<nblock; idx++)
01726           if (blocklevel[idx]==l)
01727             imeshptrs[ninlevel++]=meshptrs[idx]-1;
01728         if (ninlevel>0) {
01729           sprintf(varmeshname,"/VAR_%s/LEVEL_%03i",vartitles[k],l);
01730           DBPutMultivar(silofptr, varmeshname, ninlevel, imeshptrs, meshtypes, NULL);
01731         }
01732       }
01733     }
01734     delete [] levelmesh;
01735     delete [] varmeshname;
01736     }
01737     DBClose(silofptr);
01738 
01739 
01740     //for (i=0; i<nblock; i++) if (meshptrs[i]) delete meshptrs[i];
01741     delete [] meshptrs;
01742     delete [] varptrs;
01743     delete [] xyz;
01744     delete [] dat;
01745     delete [] blocklevel;
01746     delete [] vartitles;
01747 
01748   }
01749 #else
01750   void WriteSiloFile(char *silofilename)  {
01751      std::cerr << "hdf2file SILO package not compiled. "
01752                << "Please reconfigure with SILO_DIR defined and recompile." << std::endl;
01753   }  
01754 #endif
01755 
01756   virtual void SetGrid(float xyz[][3]) {
01757     if (FKeys() == 1)
01758       SetGridNodes(xyz);
01759     else
01760       SetGridCells(xyz);
01761   }
01762 
01763   virtual void SetScal(int *key,float v[]) {
01764     if (FKeys() == 1)
01765       SetScalNodes(key, v);
01766     else
01767       SetScalCells(key, v);
01768   }
01769 
01770   virtual void Vect(int *key,float v[][3]) {
01771     if (FKeys() == 1)
01772       VectNodes(key, v);
01773     else
01774       VectCells(key, v);
01775   }
01776 
01777   virtual void BlockListAppend(hdata_block_type& workdata, BBox& bb, int& comp, int& Level,
01778                                int& proc, float* dx, float* geom) {
01779     BlockList().push_back(new data_block_type(*this, workdata, bb, comp,
01780                                               TheEvaluator(), Level, proc, dx, geom));
01781   }
01782 
01783   block_list_type& BlockList() { return (block_list_type &)*base::_BlockList; }
01784   block_list_type& BlockList() const { return (block_list_type &)*base::_BlockList; }
01785 
01786   int LineProbe() const 
01787     { return (LinePoint[0]!=LineVector[0] || LinePoint[1]!=LineVector[1] || 
01788               LinePoint[2]!=LineVector[2]); }
01789  
01790   virtual void register_at(ControlDevice& Ctrl,const std::string& prefix) {
01791     base::register_at(Ctrl,prefix); }
01792   virtual void register_at(ControlDevice& Ctrl) {
01793     register_at(Ctrl, ""); }
01794   virtual int NCells() { return base::NCells(); }
01795   virtual int NNodes() { return base::NNodes(); }
01796   virtual void SetBlocks(int blocks[]) { base::SetBlocks(blocks); }
01797   virtual void SetGridCells(float xyz[][3]) {
01798     base::SetGridCells(xyz); }
01799   virtual void SetGridNodes(float xyz[][3]) {
01800     base::SetGridNodes(xyz); }
01801   virtual void SetGridConns(int con[][8]) {
01802     base::SetGridConns(con); }
01803   virtual void SetScalCells(int *key,float v[]) {
01804     base::SetScalCells(key,v); }
01805   virtual void SetScalNodes(int *key,float v[]) {
01806     base::SetScalNodes(key,v); }
01807   virtual void VectNodes(int *key,float v[][3]) {
01808     base::VectNodes(key,v); }
01809   virtual void VectCells(int *key,float v[][3]) {
01810     base::VectCells(key,v); }
01811   virtual int Size() const { return base::Size(); }
01812   virtual const int& MinLevel() const { return base::MinLevel(); }
01813   virtual const int& MaxLevel() const { return base::MaxLevel(); }
01814   virtual const int& NLevels() const { return base::NLevels(); }
01815   virtual const int& RefineFactor(const int l) const {
01816     return base::RefineFactor(l); }
01817   virtual const BBox& GlobalBBox() const {
01818     return base::GlobalBBox(); }
01819   virtual const int& FKeys() const { return base::FKeys(); }
01820   virtual evaluator_type& TheEvaluator() const {
01821     return base::TheEvaluator(); }
01822   virtual evaluator_type& TheEvaluator() {
01823     return base::TheEvaluator(); }
01824   virtual float64 RealTime() const { return base::RealTime(); }
01825   virtual void SetUpdateName(std::string* iname) {
01826     base::SetUpdateName(iname); }
01827   virtual std::string* UpdateName() { return base::UpdateName(); }
01828   virtual std::string* UpdateName() const {
01829     return base::UpdateName(); }
01830 
01831 private:
01832   std::string OutputName;
01833   int OutputType;   
01834   std::string StrKeys;   
01835   int* keys;
01836   int nkeys;
01837   float LinePoint[3], LineVector[3];
01838   int RegData[3];
01839   float RegLim[2];
01840   int RegMax;
01841   int LevelCutOut;
01842   int PointOutput;
01843   int _Step;
01844   int FileMerge;
01845   std::string PointFile;
01846 };
01847 
01848 #endif

Generated on Fri Aug 24 13:00:31 2007 for AMROC's HDF Tools - by  doxygen 1.4.7