NaturalNeigbourInterpolation::NaturalNeigbourInterpolation( QVector<QVector3D> &values) : Interpolation(values), delaunay_(NULL), interpolator_(NULL) { points_.clear(); for (int i = 0; i < values_.size(); ++i) { point a; a.x = values_[i].x(); a.y = values_[i].y(); a.z = values_[i].z(); points_.append(a); } delaunay_ = delaunay_build(points_.size(), points_.data(), 0, NULL, 0, NULL); interpolator_ = nnpi_create(delaunay_); nnpi_setwmin(interpolator_, -DBL_MAX); }
/* A version of nnbathy that interpolates output points serially. Can save a * bit of memory for large output grids. */ int main(int argc, char* argv[]) { specs* s = specs_create(); int nin = 0; point* pin = NULL; minell* me = NULL; point* pout = NULL; double k = NaN; preader* pr = NULL; delaunay* d = NULL; void* interpolator = NULL; int ndone = 0; parse_commandline(argc, argv, s); if (s->fin == NULL) quit("no input data\n"); if (!s->generate_points && s->fout == NULL && !s->nointerp) quit("no output grid specified\n"); points_read(s->fin, 3, &nin, &pin); if (nin < 3) return 0; if (s->thin == 1) points_thingrid(&nin, &pin, s->nxd, s->nyd); else if (s->thin == 2) points_thinlin(&nin, &pin, s->rmax); if (s->nointerp) { points_write(nin, pin); specs_destroy(s); free(pin); return 0; } if (s->generate_points) { points_getrange(nin, pin, s->zoom, &s->xmin, &s->xmax, &s->ymin, &s->ymax); pr = preader_create1(s->xmin, s->xmax, s->ymin, s->ymax, s->nx, s->ny); } else pr = preader_create2(s->fout); if (s->invariant) { me = minell_build(nin, pin); minell_scalepoints(me, nin, pin); } else if (s->square) k = points_scaletosquare(nin, pin); d = delaunay_build(nin, pin, 0, NULL, 0, NULL); if (s->linear) interpolator = lpi_build(d); else { interpolator = nnpi_create(d); nnpi_setwmin(interpolator, s->wmin); } while ((pout = preader_getpoint(pr)) != NULL) { if (s->invariant) minell_scalepoints(me, 1, pout); else if (s->square) points_scale(1, pout, k); if (s->linear) lpi_interpolate_point(interpolator, pout); else nnpi_interpolate_point(interpolator, pout); if (s->invariant) minell_rescalepoints(me, 1, pout); else if (s->square) points_scale(1, pout, 1.0 / k); points_write(1, pout); ndone++; if (s->npoints > 0) fprintf(stderr, " %5.2f%% done\r", 100.0 * ndone / s->npoints); } if (s->npoints > 0) fprintf(stderr, " \r"); if (me != NULL) minell_destroy(me); if (s->linear) lpi_destroy(interpolator); else nnpi_destroy(interpolator); delaunay_destroy(d); preader_destroy(pr); specs_destroy(s); free(pin); return 0; }
int main(int argc, char* argv[]) { int nin = NPOINTSIN; int nx = NX; int nout = 0; point* pin = NULL; delaunay* d = NULL; point* pout = NULL; nnhpi* nn = NULL; int cpi = -1; /* control point index */ struct timeval tv0, tv1; struct timezone tz; int i; i = 1; while (i < argc) { switch (argv[i][1]) { case 'a': i++; nn_rule = NON_SIBSONIAN; break; case 'n': i++; if (i >= argc) nn_quit("no number of data points found after -n\n"); nin = atoi(argv[i]); i++; if (i >= argc) nn_quit("no number of ouput points per side found after -i\n"); nx = atoi(argv[i]); i++; break; case 'v': i++; nn_verbose = 1; break; case 'V': i++; nn_verbose = 2; break; default: usage(); break; } } if (nin < NMIN) nin = NMIN; if (nx < NXMIN) nx = NXMIN; printf("\nTest of Natural Neighbours hashing point interpolator:\n\n"); printf(" %d data points\n", nin); printf(" %d output points\n", nx * nx); /* * generate data */ printf(" generating data:\n"); fflush(stdout); pin = malloc(nin * sizeof(point)); for (i = 0; i < nin; ++i) { point* p = &pin[i]; p->x = (double) random() / RAND_MAX; p->y = (double) random() / RAND_MAX; p->z = franke(p->x, p->y); if (nn_verbose) printf(" (%f, %f, %f)\n", p->x, p->y, p->z); } /* * triangulate */ printf(" triangulating:\n"); fflush(stdout); d = delaunay_build(nin, pin, 0, NULL, 0, NULL); /* * generate output points */ points_generate(-0.1, 1.1, -0.1, 1.1, nx, nx, &nout, &pout); cpi = (nx / 2) * (nx + 1); gettimeofday(&tv0, &tz); /* * create interpolator */ printf(" creating interpolator:\n"); fflush(stdout); nn = nnhpi_create(d, nout); fflush(stdout); gettimeofday(&tv1, &tz); { long dt = 1000000 * (tv1.tv_sec - tv0.tv_sec) + tv1.tv_usec - tv0.tv_usec; printf(" interpolator creation time = %ld us (%.2f us / point)\n", dt, (double) dt / nout); } /* * interpolate */ printf(" interpolating:\n"); fflush(stdout); gettimeofday(&tv1, &tz); for (i = 0; i < nout; ++i) { point* p = &pout[i]; nnhpi_interpolate(nn, p); if (nn_verbose) printf(" (%f, %f, %f)\n", p->x, p->y, p->z); } fflush(stdout); gettimeofday(&tv0, &tz); { long dt = 1000000.0 * (tv0.tv_sec - tv1.tv_sec) + tv0.tv_usec - tv1.tv_usec; printf(" interpolation time = %ld us (%.2f us / point)\n", dt, (double) dt / nout); } if (!nn_verbose) printf(" control point: (%f, %f, %f) (expected z = %f)\n", pout[cpi].x, pout[cpi].y, pout[cpi].z, franke(pout[cpi].x, pout[cpi].y)); printf(" interpolating one more time:\n"); fflush(stdout); gettimeofday(&tv0, &tz); for (i = 0; i < nout; ++i) { point* p = &pout[i]; nnhpi_interpolate(nn, p); if (nn_verbose) printf(" (%f, %f, %f)\n", p->x, p->y, p->z); } fflush(stdout); gettimeofday(&tv1, &tz); { long dt = 1000000.0 * (tv1.tv_sec - tv0.tv_sec) + tv1.tv_usec - tv0.tv_usec; printf(" interpolation time = %ld us (%.2f us / point)\n", dt, (double) dt / nout); } if (!nn_verbose) printf(" control point: (%f, %f, %f) (expected z = %f)\n", pout[cpi].x, pout[cpi].y, pout[cpi].z, franke(pout[cpi].x, pout[cpi].y)); printf(" entering new data:\n"); fflush(stdout); for (i = 0; i < nin; ++i) { point* p = &pin[i]; p->z = p->x * p->x - p->y * p->y; nnhpi_modify_data(nn, p); if (nn_verbose) printf(" (%f, %f, %f)\n", p->x, p->y, p->z); } printf(" interpolating:\n"); fflush(stdout); gettimeofday(&tv1, &tz); for (i = 0; i < nout; ++i) { point* p = &pout[i]; nnhpi_interpolate(nn, p); if (nn_verbose) printf(" (%f, %f, %f)\n", p->x, p->y, p->z); } fflush(stdout); gettimeofday(&tv0, &tz); { long dt = 1000000.0 * (tv0.tv_sec - tv1.tv_sec) + tv0.tv_usec - tv1.tv_usec; printf(" interpolation time = %ld us (%.2f us / point)\n", dt, (double) dt / nout); } if (!nn_verbose) printf(" control point: (%f, %f, %f) (expected z = %f)\n", pout[cpi].x, pout[cpi].y, pout[cpi].z, pout[cpi].x * pout[cpi].x - pout[cpi].y * pout[cpi].y); printf(" restoring data:\n"); fflush(stdout); for (i = 0; i < nin; ++i) { point* p = &pin[i]; p->z = franke(p->x, p->y); nnhpi_modify_data(nn, p); if (nn_verbose) printf(" (%f, %f, %f)\n", p->x, p->y, p->z); } printf(" interpolating:\n"); fflush(stdout); gettimeofday(&tv0, &tz); for (i = 0; i < nout; ++i) { point* p = &pout[i]; nnhpi_interpolate(nn, p); if (nn_verbose) printf(" (%f, %f, %f)\n", p->x, p->y, p->z); } fflush(stdout); gettimeofday(&tv1, &tz); { long dt = 1000000.0 * (tv1.tv_sec - tv0.tv_sec) + tv1.tv_usec - tv0.tv_usec; printf(" interpolation time = %ld us (%.2f us / point)\n", dt, (double) dt / nout); } if (!nn_verbose) printf(" control point: (%f, %f, %f) (expected z = %f)\n", pout[cpi].x, pout[cpi].y, pout[cpi].z, franke(pout[cpi].x, pout[cpi].y)); printf(" hashtable stats:\n"); fflush(stdout); { hashtable* ht = nn->ht_data; printf(" input points: %d entries, %d table elements, %d filled elements\n", ht_getnentries(ht), ht_getsize(ht), ht_getnfilled(ht)); ht = nn->ht_weights; printf(" weights: %d entries, %d table elements, %d filled elements\n", ht_getnentries(ht), ht_getsize(ht), ht_getnfilled(ht)); } printf("\n"); nnhpi_destroy(nn); free(pout); delaunay_destroy(d); free(pin); return 0; }
void process_auswave(e *E){ // netcdf vars int ncid; int varid; int retval; size_t attlen = 0; size_t from[3]; size_t to[3]; // for time conversion static char *calendar = "Standard"; ut_system *u_system; double sec; int ierr, yr, mo, day, hr, min; int i,j,t; int count; // read in the auswave data so we can estimate wave setup //time = UNLIMITED ; // (192 currently) //lat = 411 ; //lon = 441 ; // open the file if((retval = nc_open(E->wave_input, NC_NOWRITE, &ncid))) fail("failed to open wave setup input file: error is %d\n",retval); // get the time data if((retval = nc_inq_dimid(ncid, "time", &varid))) fail("failed to get auswave dimid: error is %d\n",retval); if((retval = nc_inq_dimlen(ncid,varid,&E->nTimeWaves))) fail("failed to get auswave lat dimlen: error is %d\n",retval); //printf("aus waves_times = %zu\n", E->nTimeWaves); // get the auswave lat data if((retval = nc_inq_dimid(ncid, "lat", &varid))) fail("failed to get auswave lat dimid: error is %d\n",retval); if((retval = nc_inq_dimlen(ncid,varid,&E->nLatWaves))) fail("failed to get auswave lat dimlen: error is %d\n",retval); //printf("auswave lat = %zu\n", E->nLatWaves); // get the auswave lon data if((retval = nc_inq_dimid(ncid, "lon", &varid))) fail("failed to get auswave lon dimid: error is %d\n",retval); if((retval = nc_inq_dimlen(ncid,varid,&E->nLonWaves))) fail("failed to get auswave lon dimlen: error is %d\n",retval); //printf("auswave lat = %zu\n", E->nLonWaves); // process spatial dimensions // malloc room for the dim variable arrays E->wavesLat = malloc(E->nLatWaves*sizeof(double)); E->wavesLon = malloc(E->nLonWaves*sizeof(double)); nc_inq_varid(ncid, "lat", &varid); if((retval = nc_get_var_double(ncid, varid, &E->wavesLat[0]))) fail("failed to read waves lat data: error is %d\n", retval); //printf("waves lat[0] = %f\n", E->wavesLat[0]); nc_inq_varid(ncid, "lon", &varid); if((retval = nc_get_var_double(ncid, varid, &E->wavesLon[0]))) fail("failed to read waves lon data: error is %d\n", retval); //printf("waves lon[0] = %f\n", E->wavesLon[0]); // find the dimension indexes that cover the spatial region we need int lat_end; double dLatWaves, dLonWaves; // grid spacings for lat, lon for auswave dLatWaves = fabs(E->wavesLat[1] - E->wavesLat[0])*2.0; dLonWaves = fabs(E->wavesLon[1] - E->wavesLon[0])*2.0; for(i=0; i<E->nLatWaves; i++) { if(E->wavesLat[i] > (E->roms_min_lat-dLatWaves)) // greater than because auswave lat is monotonically decreasing lat_end = i; } int lat_start; for(i=E->nLatWaves-1; i>=0; i--) { if(E->wavesLat[i] < (E->roms_max_lat+dLatWaves)) // less than because auswave lat is monotonically decreasing lat_start = i; } //printf("wave data start lat = %f (%d), end lat = %f (%d)\n", E->wavesLat[lat_start],lat_start, E->wavesLat[lat_end],lat_end); int lon_start; for(i=0; i<E->nLonWaves; i++) { if(E->wavesLon[i] < (E->roms_min_lon-dLonWaves)) lon_start = i; } int lon_end; for(i=E->nLonWaves-1; i>=0; i--) { if(E->wavesLon[i] > (E->roms_max_lon+dLonWaves)) lon_end = i; } //printf("wave data start lon = %f, end lon = %f\n", E->wavesLon[lon_start], E->wavesLon[lon_end]); // TODO: add some error checking to the bounds code. // for example, if the spatial extent does not overlap then throw an exception // now just read in what we want from the files // reading in the whole dataset to avoid gaps in the interpolation lat_start = 0; lat_end = E->nLatWaves-1; lon_start = 0; lon_end = E->nLonWaves-1; free(E->wavesLat); free(E->wavesLon); E->nLatWaves = (lat_end - lat_start); E->nLonWaves = (lon_end - lon_start); E->wavesLat = malloc(E->nLatWaves*sizeof(double)); E->wavesLon = malloc(E->nLonWaves*sizeof(double)); // now re-read the lat and lon data size_t spatial_from[1], spatial_to[1]; spatial_from[0] = lat_start; spatial_to[0] = lat_end-lat_start; nc_inq_varid(ncid, "lat", &varid); if((retval = nc_get_vara_double(ncid, varid, spatial_from, spatial_to, &E->wavesLat[0]))) fail("failed to read waves lat data: error is %d\n", retval); spatial_from[0] = lon_start; spatial_to[0] = lon_end-lon_start; nc_inq_varid(ncid, "lon", &varid); if((retval = nc_get_vara_double(ncid, varid, spatial_from, spatial_to, &E->wavesLon[0]))) fail("failed to read waves lon data: error is %d\n", retval); // process time E->wavesTime = malloc(E->nTimeWaves*sizeof(double)); // read the data from the waves output file nc_inq_varid(ncid, "time", &varid); if((retval = nc_get_var_double(ncid, varid, &E->wavesTime[0]))) fail("failed to read auswave time data: error is %d\n", retval); // normalize the time information between the roms_his file // and the tide data file // get everything in ROMS ocean_time // get the time metadata units nc_inq_attlen (ncid, varid, "units", &attlen); E->waves_time_units = (char *) malloc(attlen + 1); /* + 1 for trailing null */ E->waves_time_units[attlen] = '\x0'; nc_get_att_text(ncid, varid, "units", E->waves_time_units); //printf("waves time units = %s\n", E->waves_time_units); //printf("wavesTime[0] = %f\n", E->wavesTime[0]); // Make the Calendar calls //tval = 86460.0; /* in seconds, this is 1 day and 1 minute */ //tval = 8580; // Parse the units strings if( (E->waves_ref_time = ut_parse( E->u_system, E->waves_time_units, UT_ASCII )) == NULL ) { fprintf( stderr, "Error parsing units string \"%s\"\n", E->waves_time_units ); exit(-1); } /* if( (ierr = utCalendar2_cal( E->wavesTime[0], E->waves_ref_time, &yr, &mo, &day, &hr, &min, &sec, calendar )) != 0 ) { fprintf( stderr, "Error on utCalendar2_cal call: %d\n", ierr ); exit(-1); } printf( "this date is %04d-%02d-%02d %02d:%02d:%06.3lf\n",yr, mo, day, hr, min, sec ); */ // put the waves time on the same time units as the roms time for(t=0; t<E->nTimeWaves; t++) { //printf("PRE: waveTimes[t] = %f ", E->wavesTime[t]); // convert tide time into year, month, day, hour, minute and seconds if( (ierr = utCalendar2_cal( E->wavesTime[t], E->waves_ref_time, &yr, &mo, &day, &hr, &min, &sec, E->calendar )) != 0 ) { fprintf( stderr, "Error on utCalendar2_cal call: %d\n", ierr ); exit(-1); } //printf( "this date is %04d-%02d-%02d %02d:%02d:%06.3lf\n",yr, mo, day, hr, min, sec ); // convert this date to be on the same units as the roms time if( (ierr = utInvCalendar2_cal( yr, mo, day, hr, min, sec, E->roms_ref_time, &E->wavesTime[t], E->calendar )) != 0 ) { fprintf( stderr, "Error on utCalendar2_cal call: %d\n", ierr ); exit(-1); } //printf( "POST: %04d-%02d-%02d %02d:%02d:%06.3lf is %lf %s in the %s calendar\n", // yr, mo, day, hr, min, sec, E->wavesTime[t], E->roms_time_units, E->calendar ); } // find the index bounds where the waves time overlaps the roms time // the waves times should fully cover the roms times E->waves_start_time_index = -1; E->start_time_roms = E->romsTime[0]; // get the time start index for the tide file for(t=0; t<E->nTimeWaves; t++) { if(E->wavesTime[t]<=E->start_time_roms) E->waves_start_time_index = t; } if(E->waves_start_time_index == -1) { fprintf(stderr,"couldn't find a matching start time in the waves file.\n"); fprintf(stderr,"check to make sure the waves file times sufficiently overlap\n"); fprintf(stderr,"the ROMS times.\n\n"); exit(1); } // get the end index for the tide file E->waves_end_time_index = -1; E->end_time_roms = E->romsTime[E->nTimeRoms-1]; for(t=E->nTimeWaves-1; t>=0; t--) { //printf("t = %d, wave_time = %f\n",t,E->wavesTime[t]); if(E->wavesTime[t] >= E->end_time_roms) E->waves_end_time_index = t; } if(E->waves_end_time_index == -1) { fprintf(stderr,"couldn't find a matching end time in the waves file.\n"); fprintf(stderr,"check to make sure the wave file times sufficiently overlap\n"); fprintf(stderr,"the ROMS times.\n\n"); fprintf(stderr,"end time ROMS = %f\n", E->end_time_roms); fprintf(stderr,"end time waves = %f\n", E->wavesTime[E->nTimeWaves-1]); exit(1); } //printf("start index = %d\n", E->waves_start_time_index); //printf("end index = %d\n", E->waves_end_time_index); E->nTimeWavesSubset = (E->waves_end_time_index - E->waves_start_time_index)+1; // malloc enough room for the variable arrays //sig_wav_ht(time, lat, lon) E->Hs = malloc3d_double(E->nTimeWavesSubset, E->nLatWaves, E->nLonWaves); E->Tp = malloc3d_double(E->nTimeWavesSubset, E->nLatWaves, E->nLonWaves); // make the time vector for the output file E->waves_interp_time = malloc(E->nTimeWavesSubset*sizeof(double)); count=0; for(t=E->waves_start_time_index; t<=E->waves_end_time_index; t++) { E->waves_interp_time[count] = E->wavesTime[t]; count++; } // get the sig wave height nc_inq_varid(ncid, "sig_wav_ht", &varid); //if((retval = nc_get_var_double(ncid, varid, &E->Hs[0][0][0]))) // fail("failed to read waves setup data: error is %d\n", retval); from[0] = E->waves_start_time_index; to[0] = E->nTimeWavesSubset; from[1] = lat_start; to[1] = lat_end - lat_start; from[2] = lon_start; to[2] = lon_end - lon_start; if((retval = nc_get_vara_double(ncid, varid, from, to, &E->Hs[0][0][0]))) fail("failed to read waves Hs data: error is %d\n", retval); //printf("sig_wave_ht[0][0][0] = %f\n", E->Hs[0][0][0]); // get the peak period nc_inq_varid(ncid, "pk_wav_per", &varid); if((retval = nc_get_vara_double(ncid, varid, from, to, &E->Tp[0][0][0]))) fail("failed to read waves Hs data: error is %d\n", retval); //printf("pk_wav_per[0][0][0] = %f\n", E->Tp[0][0][0]); // close the file nc_close(ncid); // flip the auswave data so the lat vector is monotonically increasing double ***flipData = malloc3d_double(E->nTimeWavesSubset, E->nLatWaves, E->nLonWaves); double *flipLat = malloc(E->nLatWaves*sizeof(double)); // flip the lat vector for(i=0; i<E->nLatWaves; i++) { flipLat[i] = E->wavesLat[E->nLatWaves-1-i]; } // copy the flipped data back for(i=0; i<E->nLatWaves; i++) { E->wavesLat[i] = flipLat[i]; } // flip the Hs data array for(t=0; t<E->nTimeWavesSubset; t++) { for(i=0; i<E->nLatWaves; i++) { for(j=0; j<E->nLonWaves; j++) { flipData[t][i][j] = E->Hs[t][E->nLatWaves-1-i][j]; } } } // copy it back for(t=0; t<E->nTimeWavesSubset; t++) { for(i=0; i<E->nLatWaves; i++) { for(j=0; j<E->nLonWaves; j++) { E->Hs[t][i][j] = flipData[t][i][j]; } } } // flip the Tp data array for(t=0; t<E->nTimeWavesSubset; t++) { for(i=0; i<E->nLatWaves; i++) { for(j=0; j<E->nLonWaves; j++) { flipData[t][i][j] = E->Tp[t][E->nLatWaves-1-i][j]; } } } // copy it back for(t=0; t<E->nTimeWavesSubset; t++) { for(i=0; i<E->nLatWaves; i++) { for(j=0; j<E->nLonWaves; j++) { E->Tp[t][i][j] = flipData[t][i][j]; } } } free(flipData); free(flipLat); #ifdef CHECK // temporarily mess with this input data to check! for(t=0; t<E->nTimeWavesSubset; t++) { for(i=0; i<E->nLatWaves; i++) { for(j=0; j<E->nLonWaves; j++) { E->Tp[t][i][j] = (double)t; E->Hs[t][i][j] = (double)t; } } } #endif // malloc room for the output nearest neighbor interp auswave data // target grid for auswave data data // do a natural neighbour interpolation on the tide data we just read in // to fill in the land masked values before interpolating onto the ROMS grid E->Hs_on_roms = malloc3d_double(E->nTimeWavesSubset, E->nLonRho, E->nLatRho); E->Tp_on_roms = malloc3d_double(E->nTimeWavesSubset, E->nLonRho, E->nLatRho); // just for writing the netcdf file - trash this! //double *time_vector = malloc(E->nTimeWavesSubset*sizeof(double)); //printf("(E->waves_end_time_index-E->waves_start_time_index) = %d\n", E->nTimeWavesSubset); // set up variables for the lib-nn calls // nn optimized E->pin = malloc(E->nLonWaves * E->nLatWaves * sizeof(point)); E->zin = malloc(E->nLonWaves * E->nLatWaves * sizeof(double)); E->xout = malloc(E->nLonRho * E->nLatRho * sizeof(double)); E->yout = malloc(E->nLonRho * E->nLatRho * sizeof(double)); E->zout = malloc(E->nLonRho * E->nLatRho * sizeof(double)); // find out how many valid data points we have // and setup the input array for lib-nn //time_vector[t] = (double)t; //printf("setting up source grid for nn...\n"); E->nin = 0; for(i=0; i<E->nLatWaves; i++) { for(j=0; j<E->nLonWaves; j++) { if(E->Hs[0][i][j] > -999.0) { E->pin[E->nin].x = E->wavesLon[j]; E->pin[E->nin].y = E->wavesLat[i]; //E->nn_diff[E->nn_n].z = E->Hs[t][i][j]; //printf("i = %d, j = %d, lat = %.15g lon = %.15g Hs = %.15g\n", E->nn_diff[E->nn_n].x, E->nn_diff[E->nn_n].y, E->nn_diff[E->nn_n].z); E->nin++; } } } //printf("done\n");fflush(stdout); // now set up the output array for the nn interpolation // this is the roms grid E->nout = 0; for(i=0; i<E->nLonRho; i++) { for(j=0; j<E->nLatRho; j++) { E->xout[E->nout] = E->lon_rho[i][j]; E->yout[E->nout] = E->lat_rho[i][j]; E->zout[E->nout] = NaN; E->nout++; } } //printf("done\n");fflush(stdout); // setup the natural neighbour interpolation // only need to do this once E->d = delaunay_build(E->nin, E->pin, 0, NULL, 0, NULL); // create interpolator E->nn = nnai_build(E->d, E->nout, E->xout, E->yout); // for each time level for(t=0; t<E->nTimeWavesSubset; t++) { //printf("Hs: t = %d\n",t); // setup nodal values for the nn interps E->nin = 0; for(i=0; i<E->nLatWaves; i++) { for(j=0; j<E->nLonWaves; j++) { if(E->Hs[t][i][j] > -999.0) { E->pin[E->nin].z = E->Hs[t][i][j]; E->zin[E->nin] = E->pin[E->nin].z; E->nin++; } } } // do the interpolation nnai_interpolate(E->nn, E->zin, E->zout); // splat interpolated values onto the roms grid and apply land-sea mask count = 0; for(i=0; i<E->nLonRho; i++) { for(j=0; j<E->nLatRho; j++) { if(E->mask_rho[i][j] == 0){ E->Hs_on_roms[t][i][j] = NC_FILL_DOUBLE; } else{ E->Hs_on_roms[t][i][j] = E->zout[count]; } count++; } } /* // write it out to check //E->nn_nx * E->nn_ny, E->nn_interp, int lat_dimid, lon_dimid, time_dimid, dimIds[2]; int lat_varid, lon_varid, time_varid, interp_varid; // create the file nc_create("hs_interp.nc", NC_CLOBBER, &ncid); // def dimensions nc_def_dim(ncid, "lat", E->nLonRho, &lat_dimid); nc_def_dim(ncid, "lon", E->nLatRho, &lon_dimid); // def vars dimIds[0] = lat_dimid; dimIds[1] = lon_dimid; //nc_def_var(ncid, "lat", NC_DOUBLE, 1, &dimIds[0], &lat_varid); //nc_def_var(ncid, "lon", NC_DOUBLE, 1, &dimIds[1], &lon_varid); nc_def_var(ncid, "hs_interp_on_roms", NC_DOUBLE, 2, dimIds, &interp_varid); nc_enddef(ncid); // write the data //nc_put_var_double(ncid, lat_varid, &E->wavesLat[0]); //nc_put_var_double(ncid, lon_varid, &E->wavesLon[0]); nc_put_var_double(ncid, interp_varid, &E->Hs_on_roms[0][0][0]); // close the file nc_close(ncid); exit(1); */ } // end of loop over Hs time levels // now interp the Tp variable // for each time level for(t=0; t<E->nTimeWavesSubset; t++) { //printf("Tp: t = %d\n", t); E->nin = 0; for(i=0; i<E->nLatWaves; i++) { for(j=0; j<E->nLonWaves; j++) { if(E->Tp[t][i][j] > -999.0) { E->pin[E->nin].z = E->Tp[t][i][j]; E->zin[E->nin] = E->pin[E->nin].z; E->nin++; } } } // do the interpolation nnai_interpolate(E->nn, E->zin, E->zout); // splat interpolated values onto the roms grid and apply land-sea mask count = 0; for(i=0; i<E->nLonRho; i++) { for(j=0; j<E->nLatRho; j++) { if(E->mask_rho[i][j] == 0){ E->Tp_on_roms[t][i][j] = NC_FILL_DOUBLE; } else{ E->Tp_on_roms[t][i][j] = E->zout[count]; } count++; } } /* // write it out to check //E->nn_nx * E->nn_ny, E->nn_interp, int lat_dimid, lon_dimid, time_dimid, dimIds[2]; int lat_varid, lon_varid, time_varid, interp_varid; // create the file nc_create("tp_interp.nc", NC_CLOBBER, &ncid); // def dimensions nc_def_dim(ncid, "lat", E->nLonRho, &lat_dimid); nc_def_dim(ncid, "lon", E->nLatRho, &lon_dimid); // def vars dimIds[0] = lat_dimid; dimIds[1] = lon_dimid; //nc_def_var(ncid, "lat", NC_DOUBLE, 1, &dimIds[0], &lat_varid); //nc_def_var(ncid, "lon", NC_DOUBLE, 1, &dimIds[1], &lon_varid); nc_def_var(ncid, "tp_interp_on_roms", NC_DOUBLE, 2, dimIds, &interp_varid); nc_enddef(ncid); // write the data //nc_put_var_double(ncid, lat_varid, &E->wavesLat[0]); //nc_put_var_double(ncid, lon_varid, &E->wavesLon[0]); nc_put_var_double(ncid, interp_varid, &E->Tp_on_roms[0][0][0]); // close the file nc_close(ncid); exit(1); */ } // end of loop over Tp time levels free(E->pin); free(E->zin); free(E->xout); free(E->yout); free(E->zout); free(E->d); free(E->nn); //printf("done nn interp for waves\n"); // estimate wave setup on roms // setup is only calculates at the coastal points // to calculate setup, we need Hs, Tp and slope at coastal pointers // read in the slope data //printf("calculating wave setup..."); get_coastal_slope(E); // malloc room for the setup field // jNOTE: fix up the size of the time dimension here! E->setup_on_roms = malloc3d_double(E->nTimeWavesSubset, E->nLonRho, E->nLatRho); // malloc room for the time interpolated data // assign closest slope value to costline derived from the roms rho_mask double this_time; double this_lat; double this_lon; int **nearest_index = malloc2d_int(E->nLonRho, E->nLatRho); // first get the index mapping for each coastal cell for(i=0; i<E->nLonRho; i++) { for(j=0; j<E->nLatRho; j++) { if(E->coastline_mask[i][j] == 1) { // if this point is a coastal point // get longitude and latitude of the point this_time = t; this_lat = E->lat_rho[i][j]; this_lon = E->lat_rho[i][j]; nearest_index[i][j] = get_nearest_slope_index(E, this_lat, this_lon, E->slopeLat, E->slopeLon); } else{ //printf("fill it: i = %d, j = %d\n",i,j); nearest_index[i][j] = -999; } } } for(t=0; t<E->nTimeWavesSubset; t++) { //printf("#### t = %d\n",t); for(i=0; i<E->nLonRho; i++) { for(j=0; j<E->nLatRho; j++) { if(E->coastline_mask[i][j] == 1.0) { // if this point is a coastal point /* // get longitude and latitude of the point this_time = t; this_lat = E->lat_rho[i][j]; this_lon = E->lon_rho[i][j]; E->setup_on_roms[t][i][j] = get_nearest_setup(E, this_time, this_lat, this_lon, E->setup, E->wavesLat, E->wavesLon); //exit(1); */ // some cases for Hs and Tp are zero. // don't call get_setup() for these because it will divide by zero if( (E->Hs_on_roms[t][i][j] == 0.0) || (E->Tp_on_roms[t][i][j] == 0.0)) E->setup_on_roms[t][i][j] = 0.0; else E->setup_on_roms[t][i][j] = get_setup(E->Hs_on_roms[t][i][j], E->Tp_on_roms[t][i][j], E->slope[nearest_index[i][j]]); #ifdef CHECK // temporarily splat with Hs to check E->setup_on_roms[t][i][j] = E->Hs_on_roms[t][i][j]; #endif } else{ //printf("fill it: i = %d, j = %d\n",i,j); E->setup_on_roms[t][i][j] = NC_FILL_DOUBLE; } } } } //printf("...done\n"); // time interpolate the wavesetup data onto the roms time vector //printf("creating %d interpolated time levels for the setup field\n", E->nTimeRoms); E->setup_on_roms_time_interp = malloc3d_double(E->nTimeRoms, E->nLonRho, E->nLatRho); // initialize this array for(t=0; t<E->nTimeRoms; t++) { for(i=0; i<E->nLonRho; i++) { for(j=0; j<E->nLatRho; j++) { E->setup_on_roms_time_interp[t][i][j] = NC_FILL_DOUBLE; } } } // target time vector = E->romsTime // source time vector = E->wavesTime // y value vector double *ypts = malloc(E->nTimeWavesSubset*sizeof(double)); double *interp_y = malloc(E->nTimeRoms*sizeof(double)); for(i=0; i<E->nLonRho; i++) { for(j=0; j<E->nLatRho; j++) { if(E->setup_on_roms[0][i][j] != NC_FILL_DOUBLE) { for(t=0; t<E->nTimeWavesSubset; t++) { // get the wave setup vector at this location ypts[t] = E->setup_on_roms[t][i][j]; } time_interp_field(&E->wavesTime[E->waves_start_time_index], &ypts[0], E->nTimeWavesSubset, &E->romsTime[0], &interp_y[0], E->nTimeRoms); // now put this data into the time interp array for(t=0; t<E->nTimeRoms; t++) { // get the wave setup vector at this location E->setup_on_roms_time_interp[t][i][j] = interp_y[t]; } } } } //printf("done\n"); free(ypts); free(interp_y); free(E->Hs); free(E->Tp); free(E->Hs_on_roms); free(E->Tp_on_roms); free(E->wavesLon); free(E->wavesLat); free(E->setup_on_roms); free(E->slope); free(E->slopeLat); free(E->slopeLon); }
int main(int argc, char* argv[]) { int nin = NPOINTSIN; int nx = NX; int nout = 0; point* pin = NULL; delaunay* d = NULL; point* pout = NULL; nnai* nn = NULL; double* zin = NULL; double* xout = NULL; double* yout = NULL; double* zout = NULL; int cpi = -1; /* control point index */ struct timeval tv0, tv1, tv2; struct timezone tz; int i; i = 1; while (i < argc) { switch (argv[i][1]) { case 'a': i++; nn_rule = NON_SIBSONIAN; break; case 'n': i++; if (i >= argc) nn_quit("no number of data points found after -i\n"); nin = atoi(argv[i]); i++; if (i >= argc) nn_quit("no number of ouput points per side found after -i\n"); nx = atoi(argv[i]); i++; break; case 'v': i++; nn_verbose = 1; break; case 'V': i++; nn_verbose = 2; break; default: usage(); break; } } if (nin < NMIN) nin = NMIN; if (nx < NXMIN) nx = NXMIN; printf("\nTest of Natural Neighbours array interpolator:\n\n"); printf(" %d data points\n", nin); printf(" %d output points\n", nx * nx); /* * generate data */ printf(" generating data:\n"); fflush(stdout); pin = (point *)malloc(nin * sizeof(point)); zin = (double *)malloc(nin * sizeof(double)); for (i = 0; i < nin; ++i) { point* p = &pin[i]; p->x = (double) random() / RAND_MAX; p->y = (double) random() / RAND_MAX; p->z = franke(p->x, p->y); zin[i] = p->z; if (nn_verbose) printf(" (%f, %f, %f)\n", p->x, p->y, p->z); } /* * triangulate */ printf(" triangulating:\n"); fflush(stdout); d = delaunay_build(nin, pin, 0, NULL, 0, NULL); /* * generate output points */ points_generate2(-0.1, 1.1, -0.1, 1.1, nx, nx, &nout, &pout); xout = (double *)malloc(nout * sizeof(double)); yout = (double *)malloc(nout * sizeof(double)); zout = (double *)malloc(nout * sizeof(double)); for (i = 0; i < nout; ++i) { point* p = &pout[i]; xout[i] = p->x; yout[i] = p->y; zout[i] = NaN; } cpi = (nx / 2) * (nx + 1); gettimeofday(&tv0, &tz); /* * create interpolator */ printf(" creating interpolator:\n"); fflush(stdout); nn = nnai_build(d, nout, xout, yout); fflush(stdout); gettimeofday(&tv1, &tz); { long dt = 1000000 * (tv1.tv_sec - tv0.tv_sec) + tv1.tv_usec - tv0.tv_usec; printf(" interpolator creation time = %ld us (%.2f us / point)\n", dt, (double) dt / nout); } /* * interpolate */ printf(" interpolating:\n"); fflush(stdout); nnai_interpolate(nn, zin, zout); if (nn_verbose) for (i = 0; i < nout; ++i) printf(" (%f, %f, %f)\n", xout[i], yout[i], zout[i]); fflush(stdout); gettimeofday(&tv2, &tz); { long dt = 1000000.0 * (tv2.tv_sec - tv1.tv_sec) + tv2.tv_usec - tv1.tv_usec; printf(" interpolation time = %ld us (%.2f us / point)\n", dt, (double) dt / nout); } if (!nn_verbose) printf(" control point: (%f, %f, %f) (expected z = %f)\n", xout[cpi], yout[cpi], zout[cpi], franke(xout[cpi], yout[cpi])); printf(" interpolating one more time:\n"); fflush(stdout); nnai_interpolate(nn, zin, zout); if (nn_verbose) for (i = 0; i < nout; ++i) printf(" (%f, %f, %f)\n", xout[i], yout[i], zout[i]); fflush(stdout); gettimeofday(&tv0, &tz); { long dt = 1000000.0 * (tv0.tv_sec - tv2.tv_sec) + tv0.tv_usec - tv2.tv_usec; printf(" interpolation time = %ld us (%.2f us / point)\n", dt, (double) dt / nout); } if (!nn_verbose) printf(" control point: (%f, %f, %f) (expected z = %f)\n", xout[cpi], yout[cpi], zout[cpi], franke(xout[cpi], yout[cpi])); printf(" entering new data:\n"); fflush(stdout); for (i = 0; i < nin; ++i) { point* p = &pin[i]; p->z = p->x * p->x - p->y * p->y; zin[i] = p->z; if (nn_verbose) printf(" (%f, %f, %f)\n", p->x, p->y, p->z); } printf(" interpolating:\n"); fflush(stdout); nnai_interpolate(nn, zin, zout); if (nn_verbose) for (i = 0; i < nout; ++i) printf(" (%f, %f, %f)\n", xout[i], yout[i], zout[i]); if (!nn_verbose) printf(" control point: (%f, %f, %f) (expected z = %f)\n", xout[cpi], yout[cpi], zout[cpi], xout[cpi] * xout[cpi] - yout[cpi] * yout[cpi]); printf(" restoring data:\n"); fflush(stdout); for (i = 0; i < nin; ++i) { point* p = &pin[i]; p->z = franke(p->x, p->y); zin[i] = p->z; if (nn_verbose) printf(" (%f, %f, %f)\n", p->x, p->y, p->z); } printf(" interpolating:\n"); fflush(stdout); nnai_interpolate(nn, zin, zout); if (nn_verbose) for (i = 0; i < nout; ++i) printf(" (%f, %f, %f)\n", xout[i], yout[i], zout[i]); if (!nn_verbose) printf(" control point: (%f, %f, %f) (expected z = %f)\n", xout[cpi], yout[cpi], zout[cpi], franke(xout[cpi], yout[cpi])); printf("\n"); nnai_destroy(nn); free(zin); free(xout); free(yout); free(zout); free(pout); delaunay_destroy(d); free(pin); return 0; }
int main(int argc, char* argv[]) { char* bathyfname = NULL; int nbathy = -1; point* pbathy = NULL; char* gridfname = NULL; NODETYPE nt = NT_DD; gridnodes* gn = NULL; gridmap* gm = NULL; char* maskfname = NULL; int** mask = NULL; int ppe = PPE_DEF; double zmin = ZMIN_DEF; double zmax = ZMAX_DEF; delaunay* d = NULL; void (*interpolate_point) (void*, point *) = NULL; void* interpolator = NULL; int i = -1, j = -1; parse_commandline(argc, argv, &bathyfname, &gridfname, &maskfname, &nt, &ppe, &zmin, &zmax, &i, &j); /* * sanity check */ if (bathyfname == NULL) quit("no input bathymetry data specified"); if (gridfname == NULL) quit("no input grid data specified"); if (ppe <= 0 || ppe > PPE_MAX) quit("number of points per edge specified = %d greater than %d", ppe, PPE_MAX); if (zmin >= zmax) quit("min depth = %.3g > max depth = %.3g", zmin, zmax); if (nt != NT_DD && nt != NT_COR) quit("unsupported node type"); /* * read bathymetry */ points_read(bathyfname, 3, &nbathy, &pbathy); if (gu_verbose) fprintf(stderr, "## %d input bathymetry values", nbathy); if (nbathy < 3) quit("less than 3 input bathymetry values"); /* * read and validate grid */ gn = gridnodes_read(gridfname, nt); gridnodes_validate(gn); /* * read mask */ if (maskfname != NULL) { int nx = gridnodes_getnce1(gn); int ny = gridnodes_getnce2(gn); mask = gu_readmask(maskfname, nx, ny); } /* * transform grid nodes to corner type */ if (nt != NT_COR) { gridnodes* newgn = gridnodes_transform(gn, NT_COR); gridnodes_destroy(gn); gn = newgn; } /* * build the grid map for physical <-> index space conversions */ gm = gridmap_build(gridnodes_getnce1(gn), gridnodes_getnce2(gn), gridnodes_getx(gn), gridnodes_gety(gn)); /* * convert bathymetry to index space if necessary */ if (indexspace) { point* newpbathy = malloc(nbathy * sizeof(point)); int newnbathy = 0; int ii; for (ii = 0; ii < nbathy; ++ii) { point* p = &pbathy[ii]; point* newp = &newpbathy[newnbathy]; double ic, jc; if (gridmap_xy2fij(gm, p->x, p->y, &ic, &jc)) { newp->x = ic; newp->y = jc; newp->z = p->z; newnbathy++; } } free(pbathy); pbathy = newpbathy; nbathy = newnbathy; } /* * create interpolator */ if (rule == CSA) { /* using libcsa */ interpolator = csa_create(); csa_addpoints(interpolator, nbathy, pbathy); csa_calculatespline(interpolator); interpolate_point = (void (*)(void*, point *)) csa_approximatepoint; } else if (rule == AVERAGE) { interpolator = ga_create(gm); ga_addpoints(interpolator, nbathy, pbathy); interpolate_point = (void (*)(void*, point *)) ga_getvalue; ppe = 1; } else { /* using libnn */ /* * triangulate */ if (gu_verbose) { fprintf(stderr, "## triangulating..."); fflush(stdout); } d = delaunay_build(nbathy, pbathy, 0, NULL, 0, NULL); if (gu_verbose) { fprintf(stderr, "done\n"); fflush(stderr); } if (rule == NN_SIBSON || rule == NN_NONSIBSONIAN) { interpolator = nnpi_create(d); if (rule == NN_SIBSON) nn_rule = SIBSON; else nn_rule = NON_SIBSONIAN; interpolate_point = (void (*)(void*, point *)) nnpi_interpolate_point; } else if (rule == LINEAR) { interpolator = lpi_build(d); interpolate_point = (void (*)(void*, point *)) lpi_interpolate_point; } } /* * main cycle -- over grid cells */ { double** gx = gridnodes_getx(gn); int jmin, jmax, imin, imax; if (i < 0) { imin = 0; imax = gridnodes_getnce1(gn) - 1; jmin = 0; jmax = gridnodes_getnce2(gn) - 1; } else { if (gu_verbose) fprintf(stderr, "## calculating depth for cell (%d,%d)\n", i, j); imin = i; imax = i; jmin = j; jmax = j; } for (j = jmin; j <= jmax; ++j) { for (i = imin; i <= imax; ++i) { double sum = 0.0; int count = 0; int ii, jj; if ((mask != NULL && mask[j][i] == 0) || isnan(gx[j][i]) || isnan(gx[j + 1][i + 1]) || isnan(gx[j][i + 1]) || isnan(gx[j + 1][i])) { printf("NaN\n"); continue; } for (ii = 0; ii < ppe; ++ii) { for (jj = 0; jj < ppe; ++jj) { double fi = (double) i + 0.5 / (double) ppe * (1.0 + 2.0 * (double) ii); double fj = (double) j + 0.5 / (double) ppe * (1.0 + 2.0 * (double) jj); point p; if (!indexspace) gridmap_fij2xy(gm, fi, fj, &p.x, &p.y); else { p.x = fi; p.y = fj; } interpolate_point(interpolator, &p); if (isnan(p.z)) continue; else if (p.z < zmin) p.z = zmin; else if (p.z > zmax) p.z = zmax; sum += p.z; count++; } } if (count == 0) printf("NaN\n"); else printf("%.2f\n", sum / (double) count); fflush(stdout); } } } /* * clean up, just because */ if (rule == CSA) csa_destroy(interpolator); else if (rule == AVERAGE) ga_destroy(interpolator); else { if (rule == NN_SIBSON || rule == NN_NONSIBSONIAN) nnpi_destroy(interpolator); else if (rule == LINEAR) lpi_destroy(interpolator); delaunay_destroy(d); } if (mask != NULL) gu_free2d(mask); gridmap_destroy(gm); gridnodes_destroy(gn); free(pbathy); return 0; }