示例#1
0
/*
 * ?---p0---p1---p2---p3---     ---pm'---?
 * |    |    |    |    |    ...     |    | 
 * | r0 | r1 | r2 | r3 |    ...  rm'| rm | 
 * |    |    |    |    |    ...     |    | 
 * ?---n0---n1---n2---n3---     ---nm'---?
 */
void
interpolate_line(size_t m, float const *p, float const *n, float *r)
{
    size_t i;
    r[0] = extrapolate_point(p[0], n[0], p[1], n[1]);
    r[m] = extrapolate_point(p[m-1], n[m-1], p[m-2], n[m-2]);
    for (i = 0; i < m-1; i++)
    {
        r[i+1] = interpolate_point(p[i], n[i], p[i+1], n[i+1]);
    }
}
示例#2
0
// update particle position using 4th order Runge-Kutta method
void update_particle_position_rk4( e *E, double* cart_pos, double* vel, double dt, int dim){

        int d;
        double accumPos[DIM_MAX];       // where the pos[] solution vector is accumulated
        double pos[DIM_MAX];  // position in longitude, latitude
        double posPred[DIM_MAX];  // position in meters
        double k1[DIM_MAX];
        int whereILive;
        double fac;

        fac = 1.0/6.0;

        for( d=0; d<dim; d++ ) {

                accumPos[d] = cart_pos[d]; // initial step

                k1[d] = dt * vel[d];
                posPred[d] = cart_pos[d] + 0.5 * k1[d];

                accumPos[d] = accumPos[d] + fac * k1[d]; // first step ( + 1/6 k1 )

        }

        // convert posPred back to lon lat so we can call get_owner_element
  			pos[1] = r2d(posPred[1]/R);	// calc lat first
  			pos[0] = r2d(posPred[0] / (R*cos(d2r(pos[1]))));	// now lon
        // find out which element containts this position
        whereILive = get_owner_element(E, pos);
        // update weights
  			calculate_interpolation_weights(&E->el[whereILive], E->xi, E->eta, pos);
  			// interpolate the nodal velocity to the current point
  			interpolate_point(&E->el[whereILive], vel);


        /* Reuse k1. Here k1 = k2 */
        for( d=0; d<dim; d++ ) {
                k1[d] = dt * vel[d];
                posPred[d] = cart_pos[d] + 0.5 * k1[d];
                accumPos[d] = accumPos[d] + 2.0*fac*k1[d];      /* second step ( + 1/3 k2 ) */
        }


        /* Put positions back in posPred */
        //for( d=0; d<dim; d++ ) {
        //        posPred[d] = cart_pos[d] + 0.5 * k1[d];
        //}

        // convert cart_pos back to lon lat
  			pos[1] = r2d(posPred[1]/R);	// calc lat first
  			pos[0] = r2d(posPred[0] / (R*cos(d2r(pos[1]))));	// now lon
        // find out which element containts this position
        //printf("\t\t2: posPred[0] = %f, posPred[1] = %f\n", posPred[0], posPred[1]);
        //printf("\t\t2: pos[0] = %f, pos[1] = %f\n", pos[0], pos[1]);
        whereILive = get_owner_element(E, pos);
  			calculate_interpolation_weights(&E->el[whereILive], E->xi, E->eta, pos);
  			// interpolate the nodal velocity to the current point
  			interpolate_point(&E->el[whereILive], vel);

        /* Reuse k1. Here k1 = k3 */
        for( d=0; d<dim; d++ ) {
                k1[d] = dt * vel[d];
                posPred[d] = cart_pos[d] + k1[d];
                accumPos[d] = accumPos[d] + 2.0*fac*k1[d];      /* third step ( + 1/3 k3 ) */
        }



        /* Put positions back in posPred */
        //for( d=0; d<dim; d++ ) {
        //        posPred[d] = cart_pos[d] + k1[d];
        //}


        // convert cart_pos back to lon lat
  			pos[1] = r2d(posPred[1]/R);	// calc lat first
  			pos[0] = r2d(posPred[0] / (R*cos(d2r(pos[1]))));	// now lon
        // find out which element containts this position
        whereILive = get_owner_element(E, pos);
  			calculate_interpolation_weights(&E->el[whereILive], E->xi, E->eta, pos);
  			// interpolate the nodal velocity to the current point
  			interpolate_point(&E->el[whereILive], vel);

        /* Reuse k1. Here k1 = k4 */
        for( d=0; d<dim; d++ ) {
                k1[d] = dt * vel[d];

                accumPos[d] = accumPos[d] + fac*k1[d];  /* fourth step ( + 1/6 k4 ) */

                // get new position
                cart_pos[d] = accumPos[d];

        }

        //printf("done\n"); fflush(stdout);
}
示例#3
0
void interp_bathy_on_grid(e *E){

    int i,j;
    int el;
    double  pos[2];
    //double  interp_value;


    // setup the interpolation source grid data structures
	E->nx = E->b.nlon-1; //E->nc.x-1;
	E->ny = E->b.nlat-1; //E->nc.y-1;
	E->nElements = E->nx*E->ny ;
	E->ele = malloc(E->nElements*sizeof(element));
	E->nodesPerEl = 4;

	E->msh.x = malloc((E->nx+1) * sizeof(double));
	E->msh.y = malloc((E->ny+1) * sizeof(double));

	init_xi_eta(E);

	el = 0;
	for(i=0;i<E->ny;i++){
		for(j=0;j<E->nx;j++){

			// set positions for this element
			// element node numbering is anti-clockwise
			E->ele[el].node_coord[0][0] = E->b.lon[j];
			E->ele[el].node_coord[0][1] = E->b.lat[i]; // 0

			E->ele[el].node_coord[1][0] = E->b.lon[j+1];
			E->ele[el].node_coord[1][1] = E->b.lat[i]; // 1

			E->ele[el].node_coord[2][0] = E->b.lon[j+1];
			E->ele[el].node_coord[2][1] = E->b.lat[i+1]; // 2

			E->ele[el].node_coord[3][0] = E->b.lon[j];
			E->ele[el].node_coord[3][1] = E->b.lat[i+1]; // 3

			// now set the nodal value for this element
			E->ele[el].node_value[0] = -E->b.field[i][j];
			E->ele[el].node_value[1] = -E->b.field[i][j+1];
			E->ele[el].node_value[2] = -E->b.field[i+1][j+1];
			E->ele[el].node_value[3] = -E->b.field[i+1][j];

			el++;
		}
	}

    // the store_mesh call is required for the function get_owner_element
	store_mesh(E, E->nx, E->ny);
    //print_elements(E);

    // for each rho grid point
    for(i=0;i<E->g.nY;i++){
        for(j=0;j<E->g.nX;j++){

            // get pos of grid point
            pos[0] = E->lon_rho[i][j];
            pos[1] = E->lat_rho[i][j];

            // find out which element this lies within
			el = get_owner_element(E, pos);

            calculate_interpolation_weights(&E->ele[el], E->xi, E->eta, pos);
			interpolate_point(&E->ele[el], &E->h[i][j]);

        }
    }
}
示例#4
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;
}