@@ -10,6 +10,22 @@ extern "C" {
1010
1111#define CHECKERROR (res ) do {if (res != SUCCESS) return res;} while (0)
1212
13+ typedef struct
14+ {
15+ int gtype ;
16+ void * grid ;
17+ } CGrid ;
18+
19+ typedef struct
20+ {
21+ int xdim , ydim , zdim , tdim , z4d ;
22+ int sphere_mesh , zonal_periodic ;
23+ float * lonlat_minmax ;
24+ float * lon , * lat , * depth ;
25+ double * time ;
26+ } CStructuredGrid ;
27+
28+
1329typedef enum
1430 {
1531 SUCCESS = 0 , REPEAT = 1 , DELETE = 2 , ERROR = 3 , ERROR_OUT_OF_BOUNDS = 4 , ERROR_TIME_EXTRAPOLATION = 5
@@ -102,22 +118,35 @@ static inline void reconnect_bnd_indices(int *xi, int *yi, int xdim, int ydim, i
102118}
103119
104120
105- static inline ErrorCode search_indices_rectilinear (float x , float y , float z , int xdim , int ydim , int zdim ,
106- float * xvals , float * yvals , float * zvals , int sphere_mesh , int zonal_periodic , GridCode gcode ,
107- int * xi , int * yi , int * zi , double * xsi , double * eta , double * zeta ,
108- int z4d , int ti , int tdim , double time , double t0 , double t1 )
121+ static inline ErrorCode search_indices_rectilinear (float x , float y , float z , CStructuredGrid * grid , GridCode gcode ,
122+ int * xi , int * yi , int * zi , double * xsi , double * eta , double * zeta ,
123+ int ti , double time , double t0 , double t1 )
109124{
125+ int xdim = grid -> xdim ;
126+ int ydim = grid -> ydim ;
127+ int zdim = grid -> zdim ;
128+ int tdim = grid -> tdim ;
129+ float * xvals = grid -> lon ;
130+ float * yvals = grid -> lat ;
131+ float * zvals = grid -> depth ;
132+ float * xy_minmax = grid -> lonlat_minmax ;
133+ int sphere_mesh = grid -> sphere_mesh ;
134+ int zonal_periodic = grid -> zonal_periodic ;
135+ int z4d = grid -> z4d ;
136+
137+ if (zonal_periodic == 0 ){
138+ if ((x < xy_minmax [0 ]) || (x > xy_minmax [1 ]))
139+ return ERROR_OUT_OF_BOUNDS ;
140+ }
141+ if ((y < xy_minmax [2 ]) || (y > xy_minmax [3 ]))
142+ return ERROR_OUT_OF_BOUNDS ;
143+
110144 if (sphere_mesh == 0 ){
111- if (x < xvals [0 ] || x > xvals [xdim - 1 ]) {return ERROR_OUT_OF_BOUNDS ;}
112145 while (* xi < xdim - 1 && x > xvals [* xi + 1 ]) ++ (* xi );
113146 while (* xi > 0 && x < xvals [* xi ]) -- (* xi );
114147 * xsi = (x - xvals [* xi ]) / (xvals [* xi + 1 ] - xvals [* xi ]);
115148 }
116149 else {
117- if (zonal_periodic == 0 ){
118- if ((xvals [0 ] < xvals [xdim - 1 ]) && (x < xvals [0 ] || x > xvals [xdim - 1 ])) {return ERROR_OUT_OF_BOUNDS ;}
119- else if ((xvals [0 ] >= xvals [xdim - 1 ]) && (x < xvals [0 ] && x > xvals [xdim - 1 ])) {return ERROR_OUT_OF_BOUNDS ;}
120- }
121150
122151 float xvalsi = xvals [* xi ];
123152 // TODO: this will fail if longitude is e.g. only [-180, 180] (so length 2)
@@ -150,7 +179,6 @@ static inline ErrorCode search_indices_rectilinear(float x, float y, float z, in
150179 * xsi = (x - xvalsi ) / (xvalsi1 - xvalsi );
151180 }
152181
153- if (y < yvals [0 ] || y > yvals [ydim - 1 ]) {return ERROR_OUT_OF_BOUNDS ;}
154182 while (* yi < ydim - 1 && y > yvals [* yi + 1 ]) ++ (* yi );
155183 while (* yi > 0 && y < yvals [* yi ]) -- (* yi );
156184
@@ -183,19 +211,34 @@ static inline ErrorCode search_indices_rectilinear(float x, float y, float z, in
183211}
184212
185213
186- static inline ErrorCode search_indices_curvilinear (float x , float y , float z , int xdim , int ydim , int zdim ,
187- float * xvals , float * yvals , float * zvals , int sphere_mesh , int zonal_periodic , GridCode gcode ,
188- int * xi , int * yi , int * zi , double * xsi , double * eta , double * zeta ,
189- int z4d , int ti , int tdim , double time , double t0 , double t1 )
214+ static inline ErrorCode search_indices_curvilinear (float x , float y , float z , CStructuredGrid * grid , GridCode gcode ,
215+ int * xi , int * yi , int * zi , double * xsi , double * eta , double * zeta ,
216+ int ti , double time , double t0 , double t1 )
190217{
218+ int xdim = grid -> xdim ;
219+ int ydim = grid -> ydim ;
220+ int zdim = grid -> zdim ;
221+ int tdim = grid -> tdim ;
222+ float * xvals = grid -> lon ;
223+ float * yvals = grid -> lat ;
224+ float * zvals = grid -> depth ;
225+ float * xy_minmax = grid -> lonlat_minmax ;
226+ int sphere_mesh = grid -> sphere_mesh ;
227+ int zonal_periodic = grid -> zonal_periodic ;
228+ int z4d = grid -> z4d ;
229+
191230 // NEMO convention
192231 float (* xgrid )[xdim ] = (float (* )[xdim ]) xvals ;
193232 float (* ygrid )[xdim ] = (float (* )[xdim ]) yvals ;
194233
195- if (zonal_periodic == 0 || sphere_mesh == 0 ) {
196- if ((xgrid [0 ][0 ] < xgrid [0 ][xdim - 1 ]) && (x < xgrid [0 ][0 ] || x > xgrid [0 ][xdim - 1 ])) {return ERROR_OUT_OF_BOUNDS ;}
197- else if ((xgrid [0 ][0 ] >= xgrid [0 ][xdim - 1 ]) && (x < xgrid [0 ][0 ] && x > xgrid [0 ][xdim - 1 ])) {return ERROR_OUT_OF_BOUNDS ;}
234+ if (zonal_periodic == 0 ){
235+ if ((x < xy_minmax [0 ]) || (x > xy_minmax [1 ])){
236+ if (xgrid [0 ][0 ] < xgrid [0 ][xdim - 1 ]) {return ERROR_OUT_OF_BOUNDS ;}
237+ else if (x < xgrid [0 ][0 ] && x > xgrid [0 ][xdim - 1 ]) {return ERROR_OUT_OF_BOUNDS ;}
238+ }
198239 }
240+ if ((y < xy_minmax [2 ]) || (y > xy_minmax [3 ]))
241+ return ERROR_OUT_OF_BOUNDS ;
199242
200243 double a [4 ], b [4 ];
201244
@@ -292,23 +335,20 @@ static inline ErrorCode search_indices_curvilinear(float x, float y, float z, in
292335/* Local linear search to update grid index
293336 * params ti, sizeT, time. t0, t1 are only used for 4D S grids
294337 * */
295- static inline ErrorCode search_indices (float x , float y , float z , int xdim , int ydim , int zdim ,
296- float * xvals , float * yvals , float * zvals ,
297- int * xi , int * yi , int * zi , double * xsi , double * eta , double * zeta ,
298- int sphere_mesh , int zonal_periodic ,
299- GridCode gcode , int z4d ,
300- int ti , int tdim , double time , double t0 , double t1 )
338+ static inline ErrorCode search_indices (float x , float y , float z , CStructuredGrid * grid ,
339+ int * xi , int * yi , int * zi , double * xsi , double * eta , double * zeta ,
340+ GridCode gcode , int ti , double time , double t0 , double t1 )
301341{
302342 switch (gcode ){
303343 case RECTILINEAR_Z_GRID :
304344 case RECTILINEAR_S_GRID :
305- return search_indices_rectilinear (x , y , z , xdim , ydim , zdim , xvals , yvals , zvals , sphere_mesh , zonal_periodic , gcode , xi , yi , zi , xsi , eta , zeta ,
306- z4d , ti , tdim , time , t0 , t1 );
345+ return search_indices_rectilinear (x , y , z , grid , gcode , xi , yi , zi , xsi , eta , zeta ,
346+ ti , time , t0 , t1 );
307347 break ;
308348 case CURVILINEAR_Z_GRID :
309349 case CURVILINEAR_S_GRID :
310- return search_indices_curvilinear (x , y , z , xdim , ydim , zdim , xvals , yvals , zvals , sphere_mesh , zonal_periodic , gcode , xi , yi , zi , xsi , eta , zeta ,
311- z4d , ti , tdim , time , t0 , t1 );
350+ return search_indices_curvilinear (x , y , z , grid , gcode , xi , yi , zi , xsi , eta , zeta ,
351+ ti , time , t0 , t1 );
312352 break ;
313353 default :
314354 printf ("Only RECTILINEAR_Z_GRID, RECTILINEAR_S_GRID, CURVILINEAR_Z_GRID and CURVILINEAR_S_GRID grids are currently implemented\n" );
0 commit comments