diff --git a/unit/ctest_rect_grid.c b/unit/ctest_rect_grid.c index 98613e002..3bbdd0485 100644 --- a/unit/ctest_rect_grid.c +++ b/unit/ctest_rect_grid.c @@ -35,6 +35,139 @@ void test_grid_2d() } } +void test_find_cell_1x(){ + double lower[] = {0.0}, upper[] = {5.0}; + int cells[] = {5}; + double point[] = {2.5}; + bool pickLower = false; + int idx = 1; + const int *ptr = &idx; + const int *knownIdx[1] = {NULL}; + const int *knownIdx2[1] = {ptr}; + int cellIdx[]={0}; + int correctIdx[1]={3}; + struct gkyl_rect_grid grid; + + gkyl_rect_grid_init(&grid, 1, lower, upper, cells); + gkyl_rect_grid_find_cell(&grid, point, pickLower, knownIdx, cellIdx); + for(int i=0;i<1;i++){ + TEST_CHECK( cellIdx[i]==correctIdx[i]); + } + + point[0]=2.0+1e-15; + gkyl_rect_grid_find_cell(&grid, point, pickLower, knownIdx, cellIdx); + for(int i=0;i<1;i++){ + TEST_CHECK( cellIdx[i]==correctIdx[i]); + } + + pickLower=true; + correctIdx[0]=2; + gkyl_rect_grid_find_cell(&grid, point, pickLower, knownIdx, cellIdx); + for(int i=0;i<1;i++){ + TEST_CHECK( cellIdx[i]==correctIdx[i]); + } + + correctIdx[0] = idx; + point[0] = 0.2; + gkyl_rect_grid_find_cell(&grid, point, pickLower, knownIdx2, cellIdx); + for(int i=0;i<1;i++){ + TEST_CHECK( cellIdx[i]==correctIdx[i]); + } + +} + +void test_find_cell_2x(){ + double lower[] = {0.0, -10.0}, upper[] = {5.0, 10.0}; + int cells[] = {5, 20}; + double point[] = {2.5, 1.3}; + bool pickLower = false; + int idx = 18; + const int *ptr = &idx; + const int *knownIdx[2] = {NULL,NULL}; + const int *knownIdx2[2] = {NULL,ptr}; + int cellIdx[]={0,0}; + int correctIdx[2]={3,12}; + struct gkyl_rect_grid grid; + + gkyl_rect_grid_init(&grid, 2, lower, upper, cells); + gkyl_rect_grid_find_cell(&grid, point, pickLower, knownIdx, cellIdx); + for(int i=0;i<2;i++){ + TEST_CHECK( cellIdx[i]==correctIdx[i]); + } + + point[0]=2.0; + point[1]=1.0; + gkyl_rect_grid_find_cell(&grid, point, pickLower, knownIdx, cellIdx); + for(int i=0;i<2;i++){ + TEST_CHECK( cellIdx[i]==correctIdx[i]); + } + + pickLower=true; + correctIdx[0]=2; + correctIdx[1]=11; + gkyl_rect_grid_find_cell(&grid, point, pickLower, knownIdx, cellIdx); + for(int i=0;i<2;i++){ + TEST_CHECK( cellIdx[i]==correctIdx[i]); + } + + pickLower=false; + correctIdx[0]=3; + correctIdx[1]=idx; + point[1]=7.5; + gkyl_rect_grid_find_cell(&grid, point, pickLower, knownIdx2, cellIdx); + for(int i=0;i<2;i++){ + TEST_CHECK( cellIdx[i]==correctIdx[i]); + } + +} + +void test_find_cell_3x(){ + double lower[] = {0.0, -10.0, 1.3}, upper[] = {5.0, 10.0, 2.5}; + int cells[] = {5, 20, 100}; + double point[] = {2.5, 1.3, 1.4}; + bool pickLower = false; + int idx = 18, idx2 = 35; + const int *ptr = &idx, *ptr2 = &idx2; + const int *knownIdx[] = {NULL,NULL,NULL}; + const int *knownIdx2[] = {NULL,ptr,ptr2}; + int cellIdx[]={0,0,0}; + int correctIdx[]={3,12,9}; + struct gkyl_rect_grid grid; + + gkyl_rect_grid_init(&grid, 3, lower, upper, cells); + gkyl_rect_grid_find_cell(&grid, point, pickLower, knownIdx, cellIdx); + for(int i=0;i<3;i++){ + TEST_CHECK( cellIdx[i]==correctIdx[i]); + } + + point[0]=2.0; + point[1]=1.0+1e-15; + gkyl_rect_grid_find_cell(&grid, point, pickLower, knownIdx, cellIdx); + for(int i=0;i<3;i++){ + TEST_CHECK( cellIdx[i]==correctIdx[i]); + } + + pickLower=true; + correctIdx[0]=2; + correctIdx[1]=11; + gkyl_rect_grid_find_cell(&grid, point, pickLower, knownIdx, cellIdx); + for(int i=0;i<3;i++){ + TEST_CHECK( cellIdx[i]==correctIdx[i]); + } + + pickLower=false; + correctIdx[0]=3; + correctIdx[1]=idx; + correctIdx[2]=idx2; + point[1]=7.5; + point[2]=1.71; + gkyl_rect_grid_find_cell(&grid, point, pickLower, knownIdx2, cellIdx); + for(int i=0;i<3;i++){ + TEST_CHECK( cellIdx[i]==correctIdx[i]); + } + +} + void test_grid_io() { double lower[] = {1.0, 1.0}, upper[] = {2.5, 5.0}; @@ -79,6 +212,9 @@ void test_cu_grid_2d() TEST_LIST = { { "grid_2d", test_grid_2d }, + { "grid_find_cell_1x", test_find_cell_1x }, + { "grid_find_cell_2x", test_find_cell_2x }, + { "grid_find_cell_3x", test_find_cell_3x }, { "grid_io", test_grid_io }, #ifdef GKYL_HAVE_CUDA { "cu_grid_2d", test_cu_grid_2d }, diff --git a/zero/gkyl_rect_grid.h b/zero/gkyl_rect_grid.h index 8b32f0cf1..62b085252 100644 --- a/zero/gkyl_rect_grid.h +++ b/zero/gkyl_rect_grid.h @@ -29,6 +29,19 @@ struct gkyl_rect_grid { void gkyl_rect_grid_init(struct gkyl_rect_grid *grid, int ndim, const double *lower, const double *upper, const int *cells); +/** + * Find cell indecies of point + * + * @param grid Grid object + * @param point The point to find the cell incecies at + * @param pickLower + * @param knownIdx Any known indecies of where the point is + * @param cellIdx Pointer to cell indecies + * Asserts: point lies within cell(s) specified by knownIdx (if specified). + */ +void gkyl_rect_grid_find_cell(struct gkyl_rect_grid *grid, const double *point, + bool pickLower,const int **knownIdx, int *cellIdx); + /** * Get cell-center coordinates. Note that idx is a 1-based cell index, * i.e. the lower-left corner is (1,1,...). diff --git a/zero/gkyl_rect_grid_priv.h b/zero/gkyl_rect_grid_priv.h new file mode 100644 index 000000000..d42fe1583 --- /dev/null +++ b/zero/gkyl_rect_grid_priv.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +bool isInCell(const struct gkyl_rect_grid *grid, const double *pIn, int *iIn, int *dimTrans[1], const int **knownIdx); + +void InDir(const struct gkyl_rect_grid *grid, int *iIn, int *dimTrans[1], const int **knownIdx, double lowerInDir[], double upperInDir[]); diff --git a/zero/rect_grid.c b/zero/rect_grid.c index 157893430..689bde709 100644 --- a/zero/rect_grid.c +++ b/zero/rect_grid.c @@ -1,8 +1,10 @@ #include #include +#include #include #include +#include void gkyl_rect_grid_init(struct gkyl_rect_grid *grid, int ndim, @@ -22,6 +24,138 @@ gkyl_rect_grid_init(struct gkyl_rect_grid *grid, int ndim, } } +GKYL_CU_DH +void gkyl_rect_grid_find_cell(struct gkyl_rect_grid *grid, const double *point, bool pickLower, const int **knownIdx, int *cellIdx){ + int nDim = grid->ndim; + int searchNum = 0; + int searchDim[GKYL_MAX_DIM], *idxOut; + int *dimTrans[GKYL_MAX_DIM]; + int plusminus[2] = {-1,1}; + bool allLessEq = true; + int iStart[GKYL_MAX_DIM], iEnd[GKYL_MAX_DIM], iMid[GKYL_MAX_DIM], iNew[GKYL_MAX_DIM]; + int *cells, lowHighCellIdx[2*GKYL_MAX_DIM]; + double lowerInDir[nDim], upperInDir[nDim]; + double low, high; + + for(int d=0; dlower[d]+(*knownIdx[d]-1)*grid->dx[d]; + high = grid->lower[d]+(*knownIdx[d])*grid->dx[d]; + assert(lowpoint[d]); + } + } + + cells = grid -> cells; + for(int d=0; d upperInDir[searchDim[d]]){ + iStart[d] = iMid[d]+1; + } + } + } + + for(int d=0; diEnd[d]){ + allLessEq = false; + break; + } + } + } + +} + +GKYL_CU_DH +bool isInCell(const struct gkyl_rect_grid *grid, const double *pIn, int *iIn, int *dimTrans[1], const int **knownIdx){ + double eps = 1.0e-14; + int checkIdx; + bool inCell = true; + int nDim; + nDim = grid -> ndim; + double lowerInDir[nDim], upperInDir[nDim]; + + for(int d=0;dpIn[d] || upperInDir[d]+eps ndim; + double testarr[nDim]; + setbuf(stdout, NULL); + dx = grid -> dx; + lower = grid -> lower; + + for(int d=0; d