Convert ADCIRC ascii grid files and accompanying simulation output into F5. The levee information contained in the grid file is put into a specific triangular mesh for visualization purposes.
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <hdf5.h>
 
#include <F5/F5X.h>
#include <F5/F5F.h>
#include <F5/F5B.h>
#include <F5/F5R.h>
#include <F5/F5coordinates.h>
#include <F5/F5surface.h>
#include <F5/F5defs.h>
 
 
#include <vector>
#include <string>
#include <iostream>
 
using namespace std;
 
 
 
 
void AppendSurfaceData( hid_t fileID, const string&gridname, 
                        const vector<F5_vec3_point_t>&Coords,
                        const vector<F5_triangle_t>&Triangles,
                        int time_steps_to_load) 
{
char    buf[2048];
 
double  time = 0; 
FILE*kat63 = fopen("fort.63", "rt"),
    *kat64 = fopen("fort.64", "rt"),
    *kat74 = fopen("fort.74", "rt"); 
FILE*elev = 0;
 
#ifdef  R_OK
        if (access("fort.63.gz", R_OK) == 0)
        {
                elev = popen("zcat fort.63.gz", "r"); 
                if (elev==0)
                        perror("Error in reading fort.63"); 
                else
                        fputs("Fine, could open fort63 file.\n", stderr);
        } 
#endif
 
        if (!(kat63 || kat74 || kat64|| elev))
        {
                fputs("No additional field information available.\n", stderr);
                return; 
        }
 
 
unsigned int    Timesteps = 0, Nodes = 0;
 
 
        
        if (kat63)
        {
                fgets(buf, sizeof(buf), kat63); 
                fprintf(stderr, buf ); 
 
                fgets(buf, sizeof(buf), kat63);
                sscanf(buf, "%d %d", &Timesteps, &Nodes);
 
                fgets(buf, sizeof(buf), kat63); 
                fprintf(stderr, buf );
        }
        if (kat64)
        {       
                fgets(buf, sizeof(buf), kat64); 
                fprintf(stderr, buf ); 
 
                fgets(buf, sizeof(buf), kat64); 
                sscanf(buf, "%d %d", &Timesteps, &Nodes);
 
                fgets(buf, sizeof(buf), kat64); 
                fprintf(stderr, buf );
        } 
        if (kat74)
        {       
                fgets(buf, sizeof(buf), kat74); 
                fprintf(stderr, buf ); 
 
                fgets(buf, sizeof(buf), kat74); 
                sscanf(buf, "%d %d", &Timesteps, &Nodes);
 
                fgets(buf, sizeof(buf), kat74); 
                fprintf(stderr, buf );
        } 
        if (elev)
        {       
                fgets(buf, sizeof(buf), elev); 
                fprintf(stderr, buf ); 
 
                fgets(buf, sizeof(buf), elev); 
                sscanf(buf, "  %d %d", &Timesteps, &Nodes); 
                
                
 
                fgets(buf, sizeof(buf), elev); 
                fprintf(stderr, buf );
        } 
 
 
        fprintf(stderr,"ADCIRC Surface Data: %d time steps, %d vertices\n", Timesteps, Nodes); 
        if (Nodes != Coords.size() )
        {
                fputs("Vertices and Coordinates mismatch.", stderr); 
                return;
        } 
 
        if(time_steps_to_load > 0 && (unsigned)time_steps_to_load < Timesteps )
                Timesteps = time_steps_to_load;
 
 
vector<float>   Elevation; 
vector<F5_vec3f_t> Wind; 
vector<F5_vec3f_t> DepthAverageVelocity;
 
        if (kat63 || elev) Elevation.resize( Coords.size() ); 
        if (kat74)         Wind.resize( Coords.size() ); 
        if (kat64)  DepthAverageVelocity.resize( Coords.size() );
 
        for(unsigned tstep=0; tstep < Timesteps; tstep++)
        {
                
                
        double  Time = time + 30*tstep; 
                fprintf(stderr, "Timestep %d -> t=%lg\n", tstep, Time); 
 
                if (!FirstSurface)
                {
                                                                  gridname.c_str(),
                                                                  &Coords[0],  Coords.size(),
                                                                  &Triangles[0], Triangles.size() ); 
                        myGrid = FirstSurface;
                } 
                else
                                                            gridname.c_str(),
                                                            0, Coords.size(), 
                                                            0, Triangles.size() 
                                                            );
 
                if (kat63)
                {
                        for(unsigned int i=0; i<Coords.size(); i++)
                        {
                        int     num;
                                fgets(buf, sizeof(buf), kat63); 
                                if ( sscanf(buf, "%d %g\n", &num, &Elevation[i] ) != 2 )
                                {
                                        fprintf(stderr, "Error can't find scalar value for vertex %d\n", i ); 
                                        return;
                                } 
 
                                
                                if ( Elevation[i] < -3333 ) Elevation[i] = 0.0; 
                        } 
                        fgets(buf, sizeof(buf), kat63); 
 
                        F5Fwrite_1D(myGrid, "height", Coords.size(),
                                    H5T_NATIVE_FLOAT, H5T_NATIVE_FLOAT,
                                    &Elevation[0], F5P_DEFAULT);
                }
 
                if (elev)
                {
                        for(unsigned i=0; i<Coords.size(); i++)
                        {unsigned
                        int     num;
                                fgets(buf, sizeof(buf), elev); 
                                if ( sscanf(buf, "%d %g\n", &num, &Elevation[i] ) != 2 )
                                {
                                        fprintf(stderr, "Error can't find scalar value for vertex %d\n", i ); 
                                        return;
                                }
 
                                
                                
                                if (num != i+1)
                                        fprintf(stderr, "Index mismatch: %s\n", buf);
                        } 
                        fgets(buf, sizeof(buf), elev); 
 
                        F5Fwrite_1D(myGrid, "elevation", Coords.size(),
                                    H5T_NATIVE_FLOAT, H5T_NATIVE_FLOAT,
                                    &Elevation[0], F5P_DEFAULT);
                }
 
 
                if (kat74)
                {
                        for(unsigned int i=0; i<Coords.size(); i++)
                        {
                        int     num;
                                fgets(buf, sizeof(buf), kat74); 
                                if ( sscanf(buf, "%d %g %g\n", &num, &Wind[i].x, &Wind[i].y ) != 3 )
                                {
                                        fprintf(stderr, "Error can't find vector value for vertex %d\n", i ); 
                                        return;
                                } 
                                Wind[i].z = 0.0;
                        } 
                        fgets(buf, sizeof(buf), kat74); 
 
                        F5Fwrite_1D(myGrid, "wind", Coords.size(),
                                    F5T_VEC3_FLOAT, F5T_VEC3_FLOAT,
                                    &Wind[0], F5P_DEFAULT);
                } 
 
                if (kat64)
                {
                        for(unsigned int i=0; i<Coords.size(); i++)
                        {
                        int     num;
                                fgets(buf, sizeof(buf), kat64); 
                                if ( sscanf(buf, "%d %g %g\n", &num, 
                                            &DepthAverageVelocity[i].x, 
                                            &DepthAverageVelocity[i].y ) != 3 )
                                {
                                        fprintf(stderr, "Error can't find vector value for vertex %d\n", i ); 
                                        return;
                                } 
                                DepthAverageVelocity[i].z = 0.0;
                        } 
                        fgets(buf, sizeof(buf), kat64); 
 
                        F5Fwrite_1D(myGrid, "depth average velocity", Coords.size(),
                                    F5T_VEC3_FLOAT, F5T_VEC3_FLOAT,
                                    &DepthAverageVelocity[0], F5P_DEFAULT);
                } 
 
 
                if (myGrid != FirstSurface)
        } 
 
        if (kat63) fclose(kat63); 
        if (kat74) fclose(kat74); 
        if (kat64) fclose(kat64);
 
        if (elev) pclose(elev);
}
 
 
void flip(
const vector<F5_vec3_point_t>&Coords, 
F5_triangle_t &T)
 
{
 
        BA = { B.
x - A.x, B.y - A.
y, B.z - A.
z },
        CA = { C.x - A.x, C.y - A.y, C.z - A.z };
 
double  zDir = BA.x*CA.y - CA.x*BA.y;
 
        if (zDir < 0)
        {
        int     tmp = T.j;
                T.j = T.k;
                T.k = tmp;
        }
}
 
double zDir(
const vector<F5_vec3_point_t>&Coords, 
F5_triangle_t &T)
 
{
        A = Coords[T.i],
        B = Coords[T.j],
        C = Coords[T.k],
 
        BA = { B.x - A.x, B.y - A.y, B.z - A.z },
        CA = { C.x - A.x, C.y - A.y, C.z - A.z };
 
double  zDir = BA.x*CA.y - CA.x*BA.y; 
 
        return zDir;
}
 
{
int     tmp = T.j; 
        T.j = T.k; 
        T.k = tmp;
}
 
 
int     main(int argc, char*argv[])
{
        double  time = 0.0;
        hid_t   fileID;
        string  gridname;
        char    buf[1024]; 
        int     nCoords = 0, 
                nTriangles = 0;
        FILE*what; 
 
        int time_steps_to_load = -1;
 
        if (argc<2)
        {
                puts("Usage: ADCIRCtoF5 <inputfile.grd> <number of time steps>"); 
                puts("Time step argument may be ommitted to convert all time steps");
                return 1;
        } 
 
        if (argc > 2)
        {
                time_steps_to_load = atoi(argv[2]); 
        }
 
 
        strcpy(buf, argv[1]);
        {
        char*c = strrchr(buf, '.');
                if (c)
                {
                        *c = 0;
                        strcat(c, ".f5");
                        fileID = H5Fcreate(buf,       
                                           H5F_ACC_TRUNC,    
                                           H5P_DEFAULT,      
                                           H5P_DEFAULT);     
                }
                else
                {
                        puts("invalid filename.");
                        return 3;
                }
                *c = 0;
                gridname = buf;
        }
 
 
        what = fopen(argv[1], "rt");
        if (!what)
        {
                printf("Cannot open '%s'. That's not good.\n", argv[1] );
                return 2;
        }
        fgets(buf, sizeof(buf), what); 
 
         
 
        if (fscanf(what, "%d %d\n",&nTriangles, &nCoords) !=2) 
        {
                fprintf(stderr,"Error cant find no of points and triangles in header\n"); 
                return 5;
        } 
        fprintf(stderr,"Read no of coords %d and triangles %d\n",nCoords, nTriangles); 
        fflush(stderr);
 
        vector<F5_vec3_point_t> Coords; 
        Coords.resize( nCoords );
 
         
        {for (int i=0; i<nCoords; i++)
        {
        int  index; 
        double  x,y,z;
                if (fscanf(what, "%d %lg %lg %lg\n",&index, &x, &y, &z) !=4) {
                        fprintf(stderr,"Error cant find 3 coords for index %d\n",i); 
                        return 5;
                } 
                assert(index == i+ 1); 
                Coords[i].x = x; 
                Coords[i].y = y; 
                Coords[i].z = z; 
                
                
 
                
                
                
                
        }} 
 
         
        vector<F5_triangle_t> Triangles; 
        Triangles.resize( nTriangles ); 
 
        vector<F5_triangle_t> Levees; 
        vector<vector<int> >  LeveeComplex;
 
        {for (int i=0; i<nTriangles; i++) 
        {
        int index; 
        int nodes_nr; 
        int idx[3]; 
                if (fscanf(what, "%d %d %d %d %d\n",&index, &nodes_nr, &idx[0], &idx[1], &idx[2]) !=5) 
                {
                        fprintf(stderr,"Error cant find 3 vertices for index %d\n",i); 
                        return 5;
                } 
 
                assert(index == i + 1); 
                assert(nodes_nr == 3); 
                Triangles[i].i = idx[0]-1; 
                Triangles[i].j = idx[1]-1; 
                Triangles[i].k = idx[2]-1; 
                
        }} 
 
 
        
 
        vector<vector<int> > WeirComplex;
 
int     DoID = -1;
char    *ADCIRC_ID = getenv("ADCIRC_ID");
        if (ADCIRC_ID)
                DoID = atoi( ADCIRC_ID );
 
        for(int N=0; N<2; N++)
        {
        int     Number;
                fgets(buf, sizeof(buf), what); 
                if (sscanf(buf, "%d", &Number) < 1)
                {
                        puts("ERROR in decoding object number"); 
                        break;
                } 
                printf("Got Object number line: %s", buf);
 
        int TotalNodeNumber; 
                fgets(buf, sizeof(buf), what); 
                if (sscanf(buf, "%d", &TotalNodeNumber) < 1)
                {
                        puts("ERROR in getting the total number of nodes"); 
                        break;
                }
                printf("Got Object total node number: %s", buf);
 
                for(int ID=0; ID<Number; ID++)
                {
                int nodes, type;
 
                        fgets(buf, sizeof(buf), what); 
                int got = sscanf(buf, "%d %d", &nodes, &type); 
                        
 
                        if (got < 2)
                        {
                                if (got<1)
                                {
                                        puts("ERROR in decoding boundary type"); 
                                        printf("LINE: %s\n", buf); 
                                        return 1;
                                }
                                
                                for(int i=0; i<nodes; i++)
                                {
                                int     I;
                                        fgets(buf, sizeof(buf), what); 
                                        sscanf(buf, "%d\n", &I); 
                                } 
                                puts("open boundary done.");
                        } 
                        
                        else if ( type==0 || type==1 || type==2 || type==10 ||  type==11 ||type==11 ||
                                  type==12 || type==20 || type==21 ||  type==22  
                                  || type == 52 
                                )    
                        {
                        int     I; 
                                for(int i=0; i<nodes; i++)
                                {
                                        fgets(buf, sizeof(buf), what); 
                                        if (sscanf(buf, "%d\n", &I)<1)
                                        {
                                                puts("ERROR: cannot decode boundary"); 
                                                break;
                                        }
                                } 
                                printf("Boundary No. %d done\n", ID); fflush(stdout);
                        } 
                        
                        else if ( type==3 || type==13 || type==23 )
                        {
                        int I; 
                        double height, CoeffA; 
                                WeirComplex.push_back( vector<int>() ); 
                                LeveeComplex.push_back( vector<int>() );
 
                                fgets(buf, sizeof(buf), what); 
                                if (sscanf(buf, "%d %lg %lg\n", &I, &height, &CoeffA )<3)
                                {
                                        puts("ERROR: cannot decode weirs"); 
                                        break;
                                }
                                I--; 
 
                        double  HeightScale = 0.001;
 
 
                                height *= HeightScale;
                        int     VI; 
                                VI = Coords.size(); 
                                VIc.z = height; 
                                Coords.push_back( VIc ); 
 
 
                                std::cerr << "Weir " << ID << "found - adding " 
                                          << 2*nodes << "triangles (now at "
                                          << Triangles.size() << ")" << std::endl; 
 
                                
                                fflush(stderr); 
 
                                
 
                                for(int i=0; i<nodes-1; i++)
                                {
                                int     Inew;
                                        fgets(buf, sizeof(buf), what); 
                                        if (sscanf(buf, "%d  %lg %lg\n", &Inew,  &height, &CoeffA)<3)
                                        {
                                                puts("ERROR: cannot decode weirs"); 
                                                break;
                                        } 
                                        Inew--;  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                              
 
                                        
                                        I = Inew; 
                                } 
                        } 
                        
                        else if (type==24 || type== 4) 
                        {
                        int I, J; 
                        double height, CoeffA, CoeffB; 
                                WeirComplex.push_back( vector<int>() ); 
                                LeveeComplex.push_back( vector<int>() );
 
                                fgets(buf, sizeof(buf), what); 
                                if (sscanf(buf, "%d %d %lg %lg %lg\n", &I, &J, &height, &CoeffA, &CoeffB)<5)
                                {
                                        puts("ERROR: cannot decode weirs"); 
                                        break;
                                }
                                I--; J--; 
 
                        double  HeightScale = 0.001;
 
 
                                height *= HeightScale;
                        int     VI; 
                                VI = Coords.size(); 
                                VIc.z = height; 
                                Coords.push_back( VIc );
 
                        int     VJ;
                                VJ = Coords.size(); 
                                VJc.z = height; 
                                Coords.push_back( VJc ); 
 
                                std::cerr << "Weir " << ID << " found - adding " 
                                          << 2*nodes << " triangles (now at "
                                          << Triangles.size() << ")" << std::endl; 
                                
                                fflush(stderr);
 
                        bool    flipit = false; 
 
                                for(int i=0; i<nodes-1; i++)
                                {
                                int     Inew, Jnew;
                                        fgets(buf, sizeof(buf), what); 
                                        if (sscanf(buf, "%d %d %lg %lg %lg\n", &Inew, &Jnew, &height, &CoeffA, &CoeffB)<5)
                                        {
                                                puts("ERROR: cannot decode weirs"); 
                                                break;
                                        } 
                                        Inew--; Jnew--; 
 
 
                                        if (DoID>0 && ID != DoID) continue;
 
                                        
                                        {
                                                left.i = I;  left.j = J;   left.k = Inew; 
                                                right.i=Inew; right.j = J; right.k = Jnew; 
 
                                                if (i==0)
                                                {
                                                        flipit = (zDir( Coords, left) <= 0.0)
                                                                 
                                                                 
                                                                 ;
                                                }
 
                                        
                                        
                                        
 
                                                WeirComplex.back().push_back( Triangles.size() );
                                                if (flipit) flip(left);
                                                Triangles.push_back( left ); 
 
                                                WeirComplex.back().push_back( Triangles.size() ); 
                                                if (flipit) flip(right);
                                                Triangles.push_back( right ); 
                                        }
 
                                        
                                        {
                                                height *= HeightScale;
 
                                        int     VInew; 
                                                VInew = Coords.size(); 
                                                VIc.z = height; 
                                                Coords.push_back( VIc ); 
 
                                        int     VJnew; 
                                                VJnew = Coords.size(); 
                                                VJc.z = height; 
                                                Coords.push_back( VJc ); 
 
 
                                                Trngl.i = I; Trngl.j = VI; Trngl.k = Inew;
                                                if (flipit) flip(Trngl);
                                                LeveeComplex.back().push_back( Levees.size() ); Levees.push_back( Trngl );
 
                                                Trngl.i = Inew; Trngl.j = VI; Trngl.k = VInew;
                                                if (flipit) flip(Trngl);
                                                LeveeComplex.back().push_back( Levees.size() ); Levees.push_back( Trngl );
 
 
                                                Trngl.i = VI; Trngl.j = VJ; Trngl.k = VInew;
                                                if (flipit) flip(Trngl);
                                                LeveeComplex.back().push_back( Levees.size() ); Levees.push_back( Trngl );
 
                                                Trngl.i = VJ; Trngl.j = VJnew; Trngl.k = VInew;
                                                if (flipit) flip(Trngl);
                                                LeveeComplex.back().push_back( Levees.size() ); Levees.push_back( Trngl );
 
 
                                                Trngl.i = VJnew; Trngl.j = J; Trngl.k = Jnew;
                                                if (flipit) flip(Trngl);
                                                LeveeComplex.back().push_back( Levees.size() ); Levees.push_back( Trngl );
 
                                                Trngl.i = VJnew; Trngl.j = VJ; Trngl.k = J;
                                                if (flipit) flip(Trngl);
                                                LeveeComplex.back().push_back( Levees.size() ); Levees.push_back( Trngl );
 
 
                                                VI = VInew; 
                                                VJ = VJnew;
                                        }
                                        
 
                                        
                                        I = Inew; 
                                        J = Jnew;
                                } 
                        } 
                        
                        else
                        {
                                puts("ERROR in decoding ADCIRC file"); 
                                printf("ERROR LINE: %s\n", buf); 
                                printf("Unsupported type = %d", type);
                                return 1;
                                break;
                        }
                } 
                printf("Boundary Complex %d done.\n", N);
        } 
 
        std::cerr << "Triangular surface: " << nCoords << " vertices, "
                  << Triangles.size() << " triangles - " 
                  << Triangles.size() - nTriangles << " for weirs" << std::endl; 
 
        fflush(stderr); 
 
                                                      &Coords[0],  nCoords,
                                                      &Triangles[0], Triangles.size() );
 
        if (!MainGrid)
                puts("ERROR in writing grid...");
 
 
 
 
        std::cerr << "Levee Triangular surface: " << Coords.size() << " vertices, "
                  << Levees.size() << " triangles" << std::endl; 
 
        fflush(stderr); 
 
        
        if( Levees.size()>0 )
        {
                                                       &Coords[0],  Coords.size(),
                                                       &Levees[0], Levees.size() ); 
 
        if (!LeveeGrid)
                puts("ERROR in writing grid..."); 
 
 
        }
 
        
        
        
        Coords.resize( nCoords ); 
        AppendSurfaceData( fileID, gridname, Coords, Triangles, time_steps_to_load ); 
        
 
        H5Fclose(fileID);       
        return 0;
}
void F5Fclose(F5Path *f)
Definition: F5F.c:92
F5Path * F5Flink_triangular_surface(F5Path *target, double time, const char *gridname, const F5_vec3_point_t *Coords, int nCoords, const F5_triangle_t *Triangles, int nTriangles, const char *coordinate_system)
Definition: F5surface.c:51
F5Path * F5write_triangular_surface(hid_t file_id, double time, const char *name, const F5_vec3_point_t *Coords, int nCoords, const F5_triangle_t *Triangles, int nTriangles)
Definition: F5surface.c:9
Definition: F5coordinates.h:58
Definition: F5coordinates.h:246