/* * EasyWave - A realtime tsunami simulation program with GPU support. * Copyright (C) 2014 Andrey Babeyko, Johannes Spazier * GFZ German Research Centre for Geosciences (http://www.gfz-potsdam.de) * * Parts of this program (especially the GPU extension) were developed * within the context of the following publicly funded project: * - TRIDEC, EU 7th Framework Programme, Grant Agreement 258723 * (http://www.tridec-online.eu) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #include #include #include #include #include "easywave.h" //#define SSHMAX_TO_SINGLE_FILE 0 static int MaxPOIs; int NPOIs; static char **idPOI; long *idxPOI; static int *flagRunupPOI; static int NtPOI; static int *timePOI; static float **sshPOI; int ewLoadPOIs() { FILE *fp,*fpFit,*fpAcc,*fpRej; int ierr,line; int i,j,i0,j0,imin,imax,jmin,jmax,flag,it,n; int rad,nmin,itype; char record[256],buf[256],id[64]; double lon,lat,d2,d2min,lenLon,lenLat,depth; double POIdistMax,POIdepthMin,POIdepthMax; CNode& Node = *gNode; // if POIs file is not specified if( Par.filePOIs == NULL ) return 0; Log.print("Loading POIs from %s", Par.filePOIs ); MaxPOIs = utlGetNumberOfRecords( Par.filePOIs ); if( !MaxPOIs ) return Err.post( "Empty POIs file" ); idPOI = new char*[MaxPOIs]; if( !idPOI ) return Err.post( Err.msgAllocateMem() ); idxPOI = new long[MaxPOIs]; if( !idxPOI ) return Err.post( Err.msgAllocateMem() ); flagRunupPOI = new int[MaxPOIs]; if( !flagRunupPOI ) return Err.post( Err.msgAllocateMem() ); sshPOI = new float*[MaxPOIs]; if( !sshPOI ) return Err.post( Err.msgAllocateMem() ); // read first record and get idea about the input type fp = fopen( Par.filePOIs, "rt" ); line = 0; utlReadNextRecord( fp, record, &line ); itype = sscanf( record, "%s %s %s", buf, buf, buf ); fclose( fp ); if( itype == 2 ) { // poi-name and grid-index fp = fopen( Par.filePOIs, "rt" ); line = NPOIs = 0; while( utlReadNextRecord( fp, record, &line ) != EOF ) { i = sscanf( record, "%s %d", id, &nmin ); if( i != 2 ) { Log.print( "! Bad POI record: %s", record ); continue; } idPOI[NPOIs] = strdup(id); idxPOI[NPOIs] = nmin; flagRunupPOI[NPOIs] = 1; NPOIs++; } fclose( fp ); Log.print( "%d POIs of %d loaded successfully; %d POIs rejected", NPOIs, MaxPOIs, (MaxPOIs-NPOIs) ); } else if( itype == 3 ) { // poi-name and coordinates if( Par.poiReport ) { fpAcc = fopen( "poi_accepted.lst", "wt" ); fprintf( fpAcc, "ID lon lat lonIJ latIJ depthIJ dist[km]\n" ); fpRej = fopen( "poi_rejected.lst", "wt" ); } lenLat = My_PI*Re/180; fp = fopen( Par.filePOIs, "rt" ); line = NPOIs = 0; while( utlReadNextRecord( fp, record, &line ) != EOF ) { i = sscanf( record, "%s %lf %lf %d", id, &lon, &lat, &flag ); if( i == 3 ) flag = 1; else if( i == 4 ) ; else { Log.print( "! Bad POI record: %s", record ); if( Par.poiReport ) fprintf( fpRej, "%s\n", record ); continue; } // find the closest water grid node. Local distances could be treated as cartesian (2 min cell distortion at 60 degrees is only about 2 meters or 0.2%) i0 = (int)((lon - LonMin)/DLon) + 1; j0 = (int)((lat - LatMin)/DLat) + 1; if( i0<1 || i0>NLon || j0<1 || j0>NLat ) { Log.print( "!POI out of grid: %s", record ); if( Par.poiReport ) fprintf( fpRej, "%s\n", record ); continue; } lenLon = lenLat * R6[j0]; for( nmin=-1,rad=0; rad NLon ) imax = NLon; jmin = j0-rad; if( jmin < 1 ) jmin = 1; jmax = j0+rad+1; if( jmax > NLat ) jmax = NLat; for( i=imin; i<=imax; i++ ) for( j=jmin; j<=jmax; j++ ) { if( i != imin && i != imax && j != jmin && j != jmax ) continue; n = idx(j,i); depth = Node(n, iD); if( depth < Par.poiDepthMin || depth > Par.poiDepthMax ) continue; d2 = pow( lenLon*(lon-getLon(i)), 2. ) + pow( lenLat*(lat-getLat(j)), 2. ); if( d2 < d2min ) { d2min = d2; nmin = n; } } if( nmin > 0 ) break; } if( sqrt(d2min) > Par.poiDistMax ) { Log.print( "! Closest water node too far: %s", record ); if( Par.poiReport ) fprintf( fpRej, "%s\n", record ); continue; } idPOI[NPOIs] = strdup(id); idxPOI[NPOIs] = nmin; flagRunupPOI[NPOIs] = flag; NPOIs++; i = nmin/NLat + 1; j = nmin - (i-1)*NLat + 1; if( Par.poiReport ) fprintf( fpAcc, "%s %.4f %.4f %.4f %.4f %.1f %.3f\n", id, lon, lat, getLon(i), getLat(j), Node(nmin, iD), sqrt(d2min)/1000 ); } fclose( fp ); Log.print( "%d POIs of %d loaded successfully; %d POIs rejected", NPOIs, MaxPOIs, (MaxPOIs-NPOIs) ); if( Par.poiReport ) { fclose( fpAcc ); fclose( fpRej ); } } // if mareograms if( Par.poiDt ) { NtPOI = Par.timeMax/Par.poiDt + 1; timePOI = new int[NtPOI]; for( it=0; it