1/*********************************************************************
2 *   Copyright 1993, UCAR/Unidata
3 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 *   $Header: /upc/share/CVS/netcdf-3/nctest/slabs.c,v 1.13 2009/02/11 16:17:39 ed Exp $
5 *********************************************************************/
6
7#include <config.h>
8#include <stdlib.h> /* for free() */
9#include "netcdf.h"
10#include "testcdf.h" /* defines in-memory test cdf structure */
11#include "emalloc.h"
12#include "add.h" /* functions to update in-memory netcdf */
13#include "error.h"
14#include "tests.h"
15
16#define LEN_OF(array) ((sizeof array) / (sizeof array[0]))
17/* dimension sizes */
18#define NDIMS   4 /* number of dimensions */
19#define WSIZE 7 /* sizes of dimensions */
20#define XSIZE 5
21#define YSIZE   6
22#define ZSIZE   4
23/* Any function that maps dimension values 1-1 to values is OK here */
24#define VF(w)  1000*w[0]+100*w[1]+10*w[2]+w[3]
25#define NVARS   6 /* number of variables */
26
27
28/*
29 * Fill typed array element with specified value, that is
30 * 
31 *  v[ii] = val;
32 */
33static void
34val_stuff(typeviival) /* v[ii] = val */
35     nc_type type; /* netcdf type of v, NC_BYTE, ..., NC_DOUBLE */
36     void *v; /* array of specified type */
37     int ii; /* it's v[ii] we want to store into */
38     long val; /* value to store */
39{
40    static char pname[] = "val_stuff";
41
42    switch (type) {
43      case NC_BYTE:
44      case NC_CHAR:
45  ((char *)v)[ii] = (char) val;
46 break;
47      case NC_SHORT:
48  ((short *)v)[ii] = (short) val;
49 break;
50      case NC_LONG:
51  ((nclong *)v)[ii] = (nclongval;
52 break;
53      case NC_FLOAT:
54  ((float *)v)[ii] = (float) val;
55 break;
56      case NC_DOUBLE:
57  ((double *)v)[ii] = (double) val;
58 break;
59      default:
60 error("%s: bad type, test program error", pname);
61    }
62}
63
64
65/*
66 * Compare typed array element with specified value, that is return
67 *
68 *  (v[ii] != val)
69 *
70 * returns 0 if equal, 1 if not equal
71 */
72
73static int
74val_diff(typeviival) /* v[ii] != val */
75     nc_type type; /* netcdf type of v, NC_BYTE, ..., NC_DOUBLE */
76     void *v; /* array of specified type */
77     int ii; /* it's v[ii] we want to compare */
78     long val; /* value to compare with */
79{
80    static char pname[] = "val_diff";
81
82    switch (type) {
83      case NC_BYTE:
84      case NC_CHAR:
85  return (((char *)v)[ii] != (char) val);
86      case NC_SHORT:
87  return (((short *)v)[ii] != (short) val);
88      case NC_LONG:
89  return (((nclong *)v)[ii] != (nclongval);
90      case NC_FLOAT:
91  return (((float *)v)[ii] != (float) val);
92      case NC_DOUBLE:
93  return (((double *)v)[ii] != (double) val);
94      default:
95 error("%s: bad type, test program error", pname);
96 return (-1);
97    }
98}
99
100
101/*
102 * For each type of variable, put a four-dimensional hypercube of values
103 * with a single call to ncvarput.  Then use ncvarget to retrieve a single
104 * interior value, an interior vector of values along each of the four
105 * dimensions, an interior plane of values along each of the six pairs of
106 * dimensions, and an interior cube of values along each of the four
107 * triples of dimensions.  In each case, compare the retrieved values with
108 * the written values.
109 */
110
111int
112test_slabs(cdfid)
113     int cdfid; /* handle of netcdf open and in data mode */
114{
115    int nerrs = 0;
116    static char pname[] = "test_slabs";
117    static struct cdfdim dims[NDIMS] = {
118 {"w", WSIZE},
119 {"x", XSIZE},
120 {"y", YSIZE},
121 {"z", ZSIZE}
122    };
123    int dimids[NDIMS]; /* dimension ids */
124    long corner[NDIMS], edge[NDIMS], point[NDIMS];
125
126    static struct cdfvar va[NVARS] = { /* variables of all types */
127 {"bytevar", NC_BYTENDIMS___, 0},
128 {"charvar", NC_CHARNDIMS___, 0},
129 {"shortvar", NC_SHORTNDIMS___, 0},
130 {"longvar", NC_LONGNDIMS___, 0},
131 {"floatvar", NC_FLOATNDIMS___, 0},
132 {"doublevar", NC_DOUBLENDIMS___, 0},
133    };
134    void *v;
135
136    int varid[NVARS], iv; /* variable id */
137    int idimjdimkdimldim;
138    int iwixiyiziijjkk;
139
140    if (ncredef(cdfid) == -1) {
141 error("%s: cdredef failed", pname);
142 ncclose(cdfid); return 1;
143    }
144
145    /* back in define mode OK, now add dimensions */
146
147    for (idim = 0; idim < NDIMSidim++) {
148 dimids[idim] = ncdimdef(cdfiddims[idim].namedims[idim].size);
149 if (dimids[idim] == -1) {
150     error("%s: ncdimdef failed", pname);
151     ncclose(cdfid);
152     return 1;
153 }
154 add_dim(&test, &dims[idim]);
155    }
156
157    /* define a multi-dimensional variable of each type */
158
159    for (iv = 0; iv < NVARSiv++) {
160 va[iv].dims = (int *) emalloc(sizeof(int) * va[iv].ndims);
161 for (idim = 0; idim < va[iv].ndimsidim++)
162   va[iv].dims[idim] = dimids[idim];
163 varid[iv] = ncvardef(cdfidva[iv].nameva[iv].typeva[iv].ndims,
164      va[iv].dims);
165 if (varid[iv] == -1) {
166     error("%s: ncvardef failed", pname);
167     ncclose(cdfid); return 1;
168 }
169 add_var(&test, &va[iv]); /* keep in-memory netcdf in sync */
170 free(va[iv].dims);
171    }
172
173    if (ncendef (cdfid) == -1) {
174 error("%s: ncendef failed", pname);
175 ncclose(cdfid); return 1;
176    }
177
178    for (iv = 0; iv < NVARSiv++) { /* test each type of variable */
179
180 v = emalloc(WSIZE*XSIZE*YSIZE*ZSIZE * nctypelen(va[iv].type));
181
182 /* fill it with values using a function of dimension indices */
183 ii = 0;
184 for (iw=0; iw < WSIZEiw++) {
185     corner[0] = iw;
186     for (ix=0; ix < XSIZEix++) {
187 corner[1] = ix;
188 for (iy=0; iy < YSIZEiy++) {
189     corner[2] = iy;
190     for (iz=0; iz < ZSIZEiz++) {
191 corner[3] = iz;
192 /* v[ii++] = VF(corner); */
193 val_stuff(va[iv].typeviiVF(corner));
194 ii++;
195     }
196 }
197     }
198 }
199
200 for (idim = 0; idim < NDIMSidim++) {
201     corner[idim] = 0;
202     edge[idim] = dims[idim].size;
203 }
204
205 /* ncvarput the whole variable */
206 if (ncvarput(cdfidvarid[iv], corneredge, (void *) v) == -1) {
207     error("%s: ncvarput failed", pname);
208     nerrs++;
209 }
210
211 add_data(&testvarid[iv], corneredge); /* keep test in sync */
212 /*
213  * For several combinations of fixed dimensions, get a slab and compare
214  * values to function values.
215  */
216
217 /* get an interior point */
218 for (idim=0; idim < NDIMSidim++) {
219     corner[idim] = dims[idim].size/2;
220     edge[idim] = 1;
221     point[idim] = corner[idim];
222 }
223 if (ncvarget(cdfidvarid[iv], corneredge, (void *) v) == -1) {
224     error("%s: ncvarget of one point failed", pname);
225     nerrs++;
226 }
227 /* if (v[0] != VF(point)) */
228 if (val_diff(va[iv].typev, 0, VF(point))) {
229     error("%s: ncvarget got wrong value for point", pname);
230     nerrs++;
231 }
232
233 /* get an interior vector in each direction */
234 for (idim=0; idim < NDIMSidim++) {
235     for (jdim=0; jdim < NDIMSjdim++) {
236 corner[jdim] = dims[jdim].size/2;
237 edge[jdim] = 1;
238 point[jdim] = corner[jdim];
239     }
240     corner[idim] = 1; /* get vector along dimension idim */
241     edge[idim] = dims[idim].size - 2;
242     if (ncvarget(cdfidvarid[iv], corneredge, (void *) v) == -1) {
243 error("%s: ncvarget of vector failed", pname);
244 nerrs++;
245     }
246     for (ii=(int)corner[idim]; ii <= edge[idim]; ii++) {
247 point[idim] = ii;
248 /* if (v[ii-1] != VF(point)) */
249 if (val_diff(va[iv].typevii-1, VF(point))) {
250     error("%s: ncvarget got wrong value for vector", pname);
251     nerrs++;
252 }
253     }
254 }
255
256 /* get an interior plane in each direction */
257 for (idim=0; idim < NDIMSidim++) {
258     for (jdim=idim+1; jdim < NDIMSjdim++) {
259 for (kdim=0; kdim < NDIMSkdim++) { /* reset corners and edges */
260     corner[kdim] = dims[kdim].size/2;
261     edge[kdim] = 1;
262     point[kdim] = corner[kdim];
263 }
264 corner[idim] = 1; /* interior plane along dimensions idim jdim */
265 corner[jdim] = 1;
266 edge[idim] = dims[idim].size - 2;
267 edge[jdim] = dims[jdim].size - 2;
268 if (ncvarget(cdfidvarid[iv], corneredge, (void *) v) == -1) {
269     error("%s: ncvarget of plane failed", pname);
270     nerrs++;
271 }
272 for (ii=(int)corner[idim]; ii <= edge[idim]; ii++) {
273     for (jj=(int)corner[jdim]; jj <= edge[jdim]; jj++) {
274 point[idim] = ii;
275 point[jdim] = jj;
276 /* if (v[(ii-1)*edge[jdim]+jj-1] != VF(point)) { */
277 if (val_diff(va[iv].typev,
278      (ii-1)*(int)edge[jdim]+jj-1, VF(point))) {
279     error("%s: ncvarget got wrong value in plane", pname);
280     error("idim=%d,jdim=%d,ii=%d,jj=%d",
281   idim,
282   jdim,
283   ii,
284   jj);
285     nerrs++;
286 }
287     }
288 }
289     }
290 }
291
292 /* get an interior cube in each direction */
293 for (idim=0; idim < NDIMSidim++) {
294     for (jdim=idim+1; jdim < NDIMSjdim++) {
295 for (kdim=jdim+1; kdim < NDIMSkdim++) {
296     for (ldim=0; ldim < NDIMSldim++) { /* reset corners, edges */
297 corner[ldim] = dims[ldim].size/2;
298 edge[ldim] = 1;
299 point[ldim] = corner[ldim];
300     }
301     corner[idim] = 1; /* intr. cube along idim jdim kdim */
302     corner[jdim] = 1;
303     corner[kdim] = 1;
304     edge[idim] = dims[idim].size - 2;
305     edge[jdim] = dims[jdim].size - 2;
306     edge[kdim] = dims[kdim].size - 2;
307     if (ncvarget(cdfidvarid[iv], corneredge, (void *) v) == -1) {
308 error("%s: ncvarget of cube failed", pname);
309 nerrs++;
310     }
311     for (ii=(int)corner[idim]; ii <= edge[idim]; ii++) {
312 for (jj=(int)corner[jdim]; jj <= edge[jdim]; jj++) {
313     for (kk=(int)corner[kdim]; kk <= edge[kdim]; kk++) {
314 point[idim] = ii;
315 point[jdim] = jj;
316 point[kdim] = kk;
317 /* if (v[((ii-1)*edge[jdim]+jj-1)*
318    edge[kdim]+kk-1] != VF(point)) { */
319 if (val_diff(va[iv].type,v,
320      ((ii-1)*(int)edge[jdim]+jj-1)*
321      (int)edge[kdim]+kk-1,VF(point))) {
322     error("%s: ncvarget got wrong value in cube", pname);
323     error("idim=%d,jdim=%d,kdim=%d,ii=%d,jj=%d,kk=%d",
324   idim,
325   jdim,
326   kdim,
327   ii,
328   jj,
329   kk);
330     nerrs++;
331 }
332     }
333 }
334     }
335 }
336     }
337 }
338 free(v);
339    }
340    return nerrs;
341}
342


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed