surfDepValues *determineSurfaceDepthsBasin(globalBasinData *basinData ,gridStruct *location, char *fileName, int basinNum, int surfNum) /* Purpose: obtain the depths for all lat lon points within the for a given surface file Input variables: location - structure containing lat lon grid fileName - filename of the surface file for reading Output variables: surfDep - (malloc'd) pointer to structure containing surface depths for all lat lon points */ { // read in the filename surfRead *currentSurface; currentSurface = loadSurface(fileName); surfDepValues *surfDep; surfDep = malloc(sizeof(surfDepValues)); adjacentPointsStruct *points; // loop over values and find the depth of the surface at all points (2D interpolation) for(int i = 0; i < location->nX; i++) { for(int j = 0; j < location->nY; j++) { if(basinData->inBasinLatLon[basinNum][basinData->boundaryType[basinNum][surfNum]][i][j] == 1) { // find adjacent points points = findAdjacentPoints(currentSurface, location->Lat[i][j], location->Lon[i][j]); // printf("%lf %lf\n",location->Lat[i][j], location->Lon[i][j]); // printf("%i\n",basinData->inBasinLatLon[basinNum][basinData->boundaryType[basinNum][surfNum]][i][j]); if (points->inSurfaceBounds == 1) { // interpolate surfDep->dep[i][j] = biLinearInterpolation( currentSurface->loni[points->lonInd[0]], currentSurface->loni[points->lonInd[1]], currentSurface->lati[points->latInd[0]], currentSurface->lati[points->latInd[1]], currentSurface->raster[points->lonInd[0]][points->latInd[0]], currentSurface->raster[points->lonInd[0]][points->latInd[1]], currentSurface->raster[points->lonInd[1]][points->latInd[0]], currentSurface->raster[points->lonInd[1]][points->latInd[1]], location->Lon[i][j], location->Lat[i][j]); free(points); } else { printf("%lf %lf\n",location->Lat[i][j], location->Lon[i][j]); printf("Error, point lies outside basin surface domain.\n"); } } else { surfDep->dep[i][j] = NAN; // define as NAN if surface is outside of the boundary } } } free(currentSurface); return surfDep; }
TEST(stencil, biLinearInterpolationTest) { ASSERT_EQ(1.0, biLinearInterpolation(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)); // CORNERS ASSERT_EQ(1.0, biLinearInterpolation(0.0, 1.0, 0.0, 1.0, 1.0, 2.0, 3.0, 4.0)); ASSERT_EQ(2.0, biLinearInterpolation(1.0, 0.0, 0.0, 1.0, 1.0, 2.0, 3.0, 4.0)); ASSERT_EQ(3.0, biLinearInterpolation(1.0, 0.0, 1.0, 0.0, 1.0, 2.0, 3.0, 4.0)); ASSERT_EQ(4.0, biLinearInterpolation(0.0, 1.0, 1.0, 0.0, 1.0, 2.0, 3.0, 4.0)); // CENTER OF EDGES ASSERT_EQ(1.5, biLinearInterpolation(1.0, 1.0, 0.0, 1.0, 1.0, 2.0, 3.0, 4.0)); ASSERT_EQ(2.5, biLinearInterpolation(1.0, 0.0, 1.0, 1.0, 1.0, 2.0, 3.0, 4.0)); ASSERT_EQ(3.5, biLinearInterpolation(1.0, 1.0, 1.0, 0.0, 1.0, 2.0, 3.0, 4.0)); ASSERT_EQ(2.5, biLinearInterpolation(0.0, 1.0, 1.0, 1.0, 1.0, 2.0, 3.0, 4.0)); // CENTRE ASSERT_EQ(2.5, biLinearInterpolation(1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 3.0, 4.0)); }
void extractSlice(gridStruct *location, modOrigin modelOrigin, sliceExtent sliceBounds, globalDataValues *globDataVals, char *outputDirectory, int sliceNumber) { sliceExtractData *sliceData; sliceData = malloc(sizeof(sliceExtractData)); generateSliceXYpoints(sliceData, modelOrigin, sliceBounds); // loop over points int xInd = 0; int yInd = 0; double X1, X2, Y1, Y2; double Q11Vp, Q12Vp, Q21Vp, Q22Vp; double Q11Vs, Q12Vs, Q21Vs, Q22Vs; double Q11Rho, Q12Rho, Q21Rho, Q22Rho; for(int i = 0; i < sliceData->nPts; i++) { // if x or y value is outside of the bound of the dataset return NaNs. // printf("%lf %lf %lf\n", sliceData->xPts[i], location->X[0],location->X[location->nX-1]); // printf("%lf %lf %lf\n", sliceData->yPts[i], location->Y[0],location->Y[location->nY-1]); if(sliceData->xPts[i]<location->X[0] || sliceData->xPts[i]>location->X[location->nX-1] || sliceData->yPts[i]>location->Y[location->nY-1] || sliceData->yPts[i]<location->Y[0] ) { for(int k = 0; k < location->nZ; k++) { sliceData->Vp[i][k] = NAN; sliceData->Vs[i][k] = NAN; sliceData->Rho[i][k] = NAN; } } else // get indice of nearby points { for(int k = 0; k < location->nX; k++) { if(location->X[k]>=sliceData->xPts[i]) { xInd = k-1; break; } } for(int j = 0; j < location->nY; j++) { if(location->Y[j]>=sliceData->yPts[i]) { yInd = j-1; break; } } // interpolate points X1 = location->X[xInd]; X2 = location->X[xInd+1]; Y1 = location->Y[yInd]; Y2 = location->Y[yInd+1]; // double lat1, lat2, lon1, lon2; // lat1 = location->Lat[xInd][yInd]; // lat2 = location->Lat[xInd+1][yInd+1]; // lon1 = location->Lon[xInd][yInd]; // lon2 = location->Lon[xInd+1][yInd+1]; // // printf("%lf %lf %lf %lf\n", X1, X2, Y1,Y2); // printf("%lf %lf\n",sliceData->xPts[i], sliceData->yPts[i]); // printf("%lf %lf %lf %lf\n", lat1, lat2, lon1, lon2); // printf("%lf %lf\n",sliceData->latPts[i], sliceData->lonPts[i]); for(int k = 0; k < location->nZ; k++) { // Vs Q11Vs = globDataVals->Vs[xInd][yInd][k]; Q12Vs = globDataVals->Vs[xInd][yInd+1][k]; Q21Vs = globDataVals->Vs[xInd+1][yInd][k]; Q22Vs = globDataVals->Vs[xInd+1][yInd+1][k]; // printf("%lf %lf %lf %lf\n", Q11Vs, Q21Vs, Q22Vs, Q12Vs); sliceData->Vs[i][k] = biLinearInterpolation(X1, X2, Y1, Y2, Q11Vs, Q12Vs, Q21Vs, Q22Vs, sliceData->xPts[i], sliceData->yPts[i]); // Vp Q11Vp = globDataVals->Vp[xInd][yInd][k]; Q12Vp = globDataVals->Vp[xInd][yInd+1][k]; Q21Vp = globDataVals->Vp[xInd+1][yInd][k]; Q22Vp = globDataVals->Vp[xInd+1][yInd+1][k]; // printf("%lf %lf %lf %lf\n", Q11Vp, Q21Vp, Q22Vp, Q12Vp); sliceData->Vp[i][k] = biLinearInterpolation(X1, X2, Y1, Y2, Q11Vp, Q12Vp, Q21Vp, Q22Vp, sliceData->xPts[i], sliceData->yPts[i]); // Rho Q11Rho = globDataVals->Rho[xInd][yInd][k]; Q12Rho = globDataVals->Rho[xInd][yInd+1][k]; Q21Rho = globDataVals->Rho[xInd+1][yInd][k]; Q22Rho = globDataVals->Rho[xInd+1][yInd+1][k]; sliceData->Rho[i][k] = biLinearInterpolation(X1, X2, Y1, Y2, Q11Rho, Q12Rho, Q21Rho, Q22Rho, sliceData->xPts[i], sliceData->yPts[i]); } } } char sliceDir[128]; sprintf(sliceDir,"%s/Slices",outputDirectory); struct stat st = {0}; if (stat(sliceDir, &st) == -1) { // create output directory and the velocity model mkdir(sliceDir, 0700); } // generate file for writing FILE *fp2; double currRho, currVp, currVs; char fName[128]; sprintf(fName,"%s/ExtractedSlice%i.txt",sliceDir,sliceNumber); fp2 = fopen(fName,"w"); fprintf(fp2,"Extracted slice #%i.\n",sliceNumber); fprintf(fp2,"Slice_Horizontal_Resolution\t%i\n",sliceBounds.resXY); fprintf(fp2,"LatA:\t%lf\n",sliceData->latPts[0]); fprintf(fp2,"LatB:\t%lf\n",sliceData->latPts[sliceData->nPts-1]); fprintf(fp2,"LonA:\t%lf\n",sliceData->lonPts[0]); fprintf(fp2,"LonB:\t%lf\n",sliceData->lonPts[sliceData->nPts-1]); fprintf(fp2,"Lat \t Lon \t Depth \t Vp \t Vs \t Rho\n"); for(int i = 0; i < sliceData->nPts; i++) { for(int m = 0; m < location->nZ; m++) { currVp = sliceData->Vp[i][m]; currRho = sliceData->Rho[i][m]; currVs = sliceData->Vs[i][m]; fprintf(fp2, "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n",sliceData->latPts[i],sliceData->lonPts[i], location->Z[m], currVp, currVs, currRho); } } fclose(fp2); free(sliceData); }
surfDepValues *determineSurfaceDepths(gridStruct *location, char *fileName) /* Purpose: obtain the depths for all lat lon points for a given surface file Input variables: location - structure containing lat lon grid fileName - filename of the surface file for reading Output variables: surfDep - (malloc'd) pointer to structure containing surface depths for all lat lon points */ { // read in the filename surfRead *currentSurface; currentSurface = loadSurface(fileName); surfDepValues *surfDep; surfDep = malloc(sizeof(surfDepValues)); adjacentPointsStruct *points; double p1, p2, p3, v1, v2; // loop over values and find the depth of the surface at all points (2D interpolation) for(int i = 0; i < location->nX; i++) { for(int j = 0; j < location->nY; j++) { // find adjacent points points = findAdjacentPoints(currentSurface, location->Lat[i][j], location->Lon[i][j]); if (points->inSurfaceBounds == 1) { // interpolate surfDep->dep[i][j] = biLinearInterpolation( currentSurface->loni[points->lonInd[0]], currentSurface->loni[points->lonInd[1]], currentSurface->lati[points->latInd[0]], currentSurface->lati[points->latInd[1]], currentSurface->raster[points->lonInd[0]][points->latInd[0]], currentSurface->raster[points->lonInd[0]][points->latInd[1]], currentSurface->raster[points->lonInd[1]][points->latInd[0]], currentSurface->raster[points->lonInd[1]][points->latInd[1]], location->Lon[i][j], location->Lat[i][j]); } else if (points->inLatExtensionZone == 1) { p1 = currentSurface->loni[points->lonInd[0]]; p2 = currentSurface->loni[points->lonInd[1]]; v1 = currentSurface->raster[points->lonInd[0]][points->latEdgeInd]; v2 = currentSurface->raster[points->lonInd[1]][points->latEdgeInd]; p3 = location->Lon[i][j]; surfDep->dep[i][j] = linearInterpolation(p1, p2, v1, v2, p3); } else if (points->inLonExtensionZone == 1) { p1 = currentSurface->lati[points->latInd[0]]; p2 = currentSurface->lati[points->latInd[1]]; v1 = currentSurface->raster[points->lonEdgeInd][points->latInd[0]]; v2 = currentSurface->raster[points->lonEdgeInd][points->latInd[1]]; p3 = location->Lat[i][j]; surfDep->dep[i][j] = linearInterpolation(p1, p2, v1, v2, p3); } else if (points->inCornerZone == 1) { surfDep->dep[i][j] = currentSurface->raster[points->cornerLonInd][points->cornerLatInd]; } free(points); } } free(currentSurface); return surfDep; }
depInterpVals *loadEPtomo2010subMod(gridStruct *location) /* Purpose: read in the Eberhart-Phillips 2010 tomography dataset Input variables: location - struct containing the lat lon and dep points Output variables: surfDepVals - (malloc'd) pointer to a struct containing the values of the "surfaces" at each lat lon value */ { const char *varNames[3]; varNames[0] = "vp", varNames[1] = "vs", varNames[2] = "rho"; int nElev = 14; // only read first 14 for efficiency int elev[17] = {15, 1, -3, -8, -15, -23, -30, -38, -48, -65, -85, -105, -130, -155, -185, -225, -275 }; // int elev[21] = {15, 1, -3, -5, -8, -11, -15, -23, -30, -38, -48, -65, -85, -105, -130, -155, -185, -225, -275, -370, -630}; //int elev[20] = {10, 1, -5, -8, -11, -15, -23, -30, -38, -48, -65, -85, -105, -130, -155, -185, -225, -275, -370, -620}; char baseFilename[256]; depInterpVals *surfDepVals = NULL; surfDepVals = malloc(sizeof(depInterpVals)); surfDepVals->numSurf = nElev; surfRead *tempSurf; adjacentPointsStruct *points; double X1, X2, Y1, Y2, Q11, Q12, Q22, Q21, X, Y, interpVal; for(int i = 0; i < nElev; i++) { surfDepVals->deps[i] = elev[i]; for(int j = 0; j < 3; j++) { sprintf(baseFilename,"Data/Tomography/surf_tomography_%s_elev%i.in",varNames[j],elev[i]); // read the surface tempSurf = loadSurface(baseFilename); // write a surface vector (for IDW) for(int k = 0; k < location->nX; k++) { for(int n = 0; n < location->nY; n++) { points = findAdjacentPoints(tempSurf, location->Lat[k][n], location->Lon[k][n]); // a little inefficient as process is repeated for each of Vp Vs and Rho! X1 = tempSurf->loni[points->lonInd[0]]; X2 = tempSurf->loni[points->lonInd[1]]; Y1 = tempSurf->lati[points->latInd[0]]; Y2 = tempSurf->lati[points->latInd[1]]; X = location->Lon[k][n]; Y = location->Lat[k][n]; Q11 = tempSurf->raster[points->lonInd[0]][points->latInd[0]]; Q12 = tempSurf->raster[points->lonInd[0]][points->latInd[1]]; Q21 = tempSurf->raster[points->lonInd[1]][points->latInd[0]]; Q22 = tempSurf->raster[points->lonInd[1]][points->latInd[1]]; interpVal = biLinearInterpolation(X1, X2, Y1, Y2, Q11, Q12, Q21, Q22, X, Y); if(j == 0) { surfDepVals->Vp[i][k][n] = interpVal; } else if(j == 1) { surfDepVals->Vs[i][k][n] = interpVal; } else if(j ==2) { surfDepVals->Rho[i][k][n] = interpVal; } free(points); } } free(tempSurf); } printf("\rReading tomography data %d%% complete.", i*100/nElev); fflush(stdout); } printf("\rReading tomography data 100%% complete."); fflush(stdout); printf("\n"); return surfDepVals; }