From 1738fbacca4665d76f5f6f133f8199438c84c1ac Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Sat, 7 Jul 2018 18:10:08 +0200 Subject: [PATCH] Added remap_cell_search.cc. --- src/Makefile.am | 3 ++- src/grid_cell_search.cc | 47 ++++++++++++++++++++++++++++++++++++++-- src/grid_cell_search.h | 7 ++++++ src/grid_point_search.cc | 8 +++---- src/remap.h | 1 + src/remap_cell_search.cc | 43 ++++++++++++++++++++++++++++++++++++ src/remap_conserv.cc | 22 +++---------------- 7 files changed, 105 insertions(+), 26 deletions(-) create mode 100644 src/remap_cell_search.cc diff --git a/src/Makefile.am b/src/Makefile.am index 17e88ce14..aec2f6865 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -167,7 +167,8 @@ libcdo_la_SOURCES = \ remap_scrip_io.cc \ remap_search_reg2d.cc \ remap_search_latbins.cc \ - remap_search.cc \ + remap_point_search.cc \ + remap_cell_search.cc \ remap_store_link.cc \ remap_store_link.h \ remap_store_link_cnsrv.cc \ diff --git a/src/grid_cell_search.cc b/src/grid_cell_search.cc index 3890193da..f1442e351 100644 --- a/src/grid_cell_search.cc +++ b/src/grid_cell_search.cc @@ -46,8 +46,6 @@ gridCellSearchCreateReg2d(size_t dims[2], const double *reg2d_corner_lon, const size_t nx = dims[0]; size_t ny = dims[1]; - printf("nx, ny %zu %zu\n", nx, ny); - gcs->reg2d_corner_lon = (double *) Malloc(nx * sizeof(double)); gcs->reg2d_corner_lat = (double *) Malloc(ny * sizeof(double)); @@ -62,6 +60,8 @@ gridCellSearchCreate(size_t numCells, size_t numCellCorners, double *cellCornerL { GridCellSearch *gcs = (GridCellSearch *) Calloc(1, sizeof(GridCellSearch)); + gcs->method = cellSearchMethod; + struct grid *yacSrcGrid = yac_scrip_grid_new(cellCornerLon, cellCornerLat, numCells, numCellCorners); gcs->yacSearch = yac_sphere_part_search_new(yacSrcGrid); gcs->yacSrcGrid = yacSrcGrid; @@ -83,3 +83,46 @@ gridCellSearchDelete(GridCellSearch *gcs) Free(gcs); } } + +static size_t +doGridCellSearchYac(grid_search *yacSearch, bool isLonLatCell, size_t numCellCorners, grid_cell &gridCell, size_t *srchAddr) +{ + struct bounding_circle bndCircle; + double *xyz = gridCell.coordinates_xyz; + if (numCellCorners == 4 && isLonLatCell) + yac_get_cell_bounding_circle_reg_quad(xyz, xyz+3, xyz+6, xyz+9, &bndCircle); + else if (numCellCorners == 3) + yac_get_cell_bounding_circle_unstruct_triangle(xyz, xyz+3, xyz+6, &bndCircle); + else + yac_get_cell_bounding_circle(gridCell, &bndCircle); + + struct dep_list resultList; + yac_do_bnd_circle_search(yacSearch, &bndCircle, 1, &resultList); + + size_t numSrchCells = resultList.num_deps_per_element[0]; + unsigned const *currNeighs = yac_get_dependencies_of_element(resultList, 0); + for (size_t i = 0; i < numSrchCells; ++i) srchAddr[i] = currNeighs[i]; + + yac_free_dep_list(&resultList); + + return numSrchCells; +} + +size_t +doGridCellSearch(GridCellSearch *gcs, bool isLonLatCell, size_t numCellCorners, grid_cell &gridCell, size_t *srchAddr) +{ + if (gcs) + { + size_t nadds = 0; + // clang-format off + if (gcs->method == CellSearchMethod::spherepart) + nadds = doGridCellSearchYac((grid_search*)gcs->yacSearch, isLonLatCell, numCellCorners, gridCell, srchAddr); + else + cdoAbort("%s::method undefined!", __func__); + // clang-format on + + return nadds; + } + + return 0; +} diff --git a/src/grid_cell_search.h b/src/grid_cell_search.h index f97f7d181..1a3b39592 100644 --- a/src/grid_cell_search.h +++ b/src/grid_cell_search.h @@ -18,6 +18,10 @@ #ifndef GRID_CELL_SEARCH_H #define GRID_CELL_SEARCH_H +extern "C" { +#include "lib/yac/grid_cell.h" +} + enum struct CellSearchMethod { spherepart, @@ -26,6 +30,8 @@ enum struct CellSearchMethod struct GridCellSearch { + CellSearchMethod method; + bool is_reg2d; size_t dims[2]; @@ -40,5 +46,6 @@ struct GridCellSearch GridCellSearch *gridCellSearchCreateReg2d(size_t dims[2], const double *reg2d_corner_lon, const double *reg2d_corner_lat); GridCellSearch *gridCellSearchCreate(size_t numCells, size_t numCellCorners, double *cellCornerLon, double *cellCornerLat); void gridCellSearchDelete(GridCellSearch *gcs); +size_t doGridCellSearch(GridCellSearch *gcs, bool isLonLatCell, size_t numCellCorners, grid_cell &gridCell, size_t *srchAddr); #endif diff --git a/src/grid_point_search.cc b/src/grid_point_search.cc index f8ed42fe3..7887d70f6 100644 --- a/src/grid_point_search.cc +++ b/src/grid_point_search.cc @@ -616,10 +616,10 @@ gridPointSearchNearest(GridPointSearch *gps, double lon, double lat, size_t *add double searchRadius = gps->searchRadius; void *sc = gps->search_container; // clang-format off - if ( gps->method == PointSearchMethod::kdtree ) nadds = gps_nearest_kdtree(sc, lon, lat, searchRadius, addr, dist, gps); - else if ( gps->method == PointSearchMethod::nanoflann ) nadds = gps_nearest_nanoflann(sc, lon, lat, searchRadius, addr, dist, gps); - else if ( gps->method == PointSearchMethod::spherepart ) nadds = gps_nearest_spherepart(sc, lon, lat, searchRadius, addr, dist, gps); - else if ( gps->method == PointSearchMethod::full ) nadds = gps_nearest_full(sc, lon, lat, searchRadius, addr, dist); + if (gps->method == PointSearchMethod::kdtree) nadds = gps_nearest_kdtree(sc, lon, lat, searchRadius, addr, dist, gps); + else if (gps->method == PointSearchMethod::nanoflann) nadds = gps_nearest_nanoflann(sc, lon, lat, searchRadius, addr, dist, gps); + else if (gps->method == PointSearchMethod::spherepart) nadds = gps_nearest_spherepart(sc, lon, lat, searchRadius, addr, dist, gps); + else if (gps->method == PointSearchMethod::full) nadds = gps_nearest_full(sc, lon, lat, searchRadius, addr, dist); else cdoAbort("%s::method undefined!", __func__); // clang-format on diff --git a/src/remap.h b/src/remap.h index 54a83b9dc..9ddfa7ab5 100644 --- a/src/remap.h +++ b/src/remap.h @@ -138,6 +138,7 @@ void remapSearchFree(RemapSearch &search); void remapSearchPoints(RemapSearch &rsearch, double plon, double plat, knnWeightsType &knnWeights); int remapSearchSquare(RemapSearch &rsearch, double plon, double plat, size_t *src_add, double *src_lats, double *src_lons); +size_t remapSearchCells(RemapSearch &rsearch, bool isLonLatCell, size_t numCellCorners, grid_cell &gridCell, size_t *srchAddr); void remapBilinearWeights(RemapSearch &rsearch, RemapVars &rv); void remapBicubicWeights(RemapSearch &rsearch, RemapVars &rv); diff --git a/src/remap_cell_search.cc b/src/remap_cell_search.cc new file mode 100644 index 000000000..24bfd121a --- /dev/null +++ b/src/remap_cell_search.cc @@ -0,0 +1,43 @@ +/* + This file is part of CDO. CDO is a collection of Operators to + manipulate and analyse Climate model Data. + + Copyright (C) 2003-2018 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de> + See COPYING file for copying and redistribution conditions. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + 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 General Public License for more details. +*/ + +#include "cdo_int.h" +#include "remap.h" + +static void +gridSearchCellsReg2d(GridCellSearch *gcs) +{ +} + +static size_t +gridSearchCells(GridCellSearch *gcs, bool isLonLatCell, size_t numCellCorners, grid_cell &gridCell, size_t *srchAddr) +{ + return doGridCellSearch(gcs, isLonLatCell, numCellCorners, gridCell, srchAddr); +} + +size_t +remapSearchCells(RemapSearch &rsearch, bool isLonLatCell, size_t numCellCorners, grid_cell &gridCell, size_t *srchAddr) +{ + int nadds = 0; + + if (rsearch.srcGrid->remap_grid_type == REMAP_GRID_TYPE_REG2D) + gridSearchCellsReg2d(rsearch.gcs); + else + nadds = gridSearchCells(rsearch.gcs, isLonLatCell, numCellCorners, gridCell, srchAddr); + + return nadds; +} diff --git a/src/remap_conserv.cc b/src/remap_conserv.cc index bcedc0d24..7638c3221 100644 --- a/src/remap_conserv.cc +++ b/src/remap_conserv.cc @@ -753,26 +753,10 @@ remapConservWeights(RemapSearch &rsearch, RemapVars &rv) // Get search cells - if ( useCellsearch ) + if (useCellsearch) { - struct bounding_circle bnd_circle; - double *xyz = tgt_grid_cell[ompthID].coordinates_xyz; - if (tgt_num_cell_corners == 4 && target_cell_type == LON_LAT_CELL) - yac_get_cell_bounding_circle_reg_quad(xyz, xyz+3, xyz+6, xyz+9, &bnd_circle); - else if (tgt_num_cell_corners == 3) - yac_get_cell_bounding_circle_unstruct_triangle(xyz, xyz+3, xyz+6, &bnd_circle); - else - yac_get_cell_bounding_circle(tgt_grid_cell[ompthID], &bnd_circle); - - struct dep_list result_list; - yac_do_bnd_circle_search((struct grid_search *)rsearch.gcs->yacSearch, &bnd_circle, 1, &result_list); - - num_srch_cells = result_list.num_deps_per_element[0]; - unsigned const *curr_neighs = yac_get_dependencies_of_element(result_list,0); - for (size_t i = 0; i < num_srch_cells; ++i) - srch_add[ompthID][i] = curr_neighs[i]; - - yac_free_dep_list(&result_list); + num_srch_cells = remapSearchCells(rsearch, target_cell_type == LON_LAT_CELL, tgt_num_cell_corners, + tgt_grid_cell[ompthID], srch_add[ompthID].data()); } else if (src_remap_grid_type == REMAP_GRID_TYPE_REG2D) { -- GitLab