grid.c 143 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
#ifdef HAVE_CONFIG_H
2
#include "config.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
3
4
#endif

Thomas Jahns's avatar
Thomas Jahns committed
5
#include <assert.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
6
#include <string.h>
7

Uwe Schulzweida's avatar
Uwe Schulzweida committed
8
9
#include "dmemory.h"
#include "cdi.h"
10
#include "cdi_cksum.h"
11
#include "cdi_int.h"
12
#include "cdi_uuid.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
13
#include "grid.h"
14
#include "resource_handle.h"
15
#include "resource_unpack.h"
16
#include "namespace.h"
17
#include "serialize.h"
18
19
#include "vlist.h"

20
int (*proj_lonlat_to_lcc_func)() = NULL;
21
int (*proj_lcc_to_lonlat_func)() = NULL;
22
23
int (*proj_lonlat_to_stere_func)() = NULL;
int (*proj_stere_to_lonlat_func)() = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
24

25
26
27
/* the value in the second pair of brackets must match the length of
 * the longest string (including terminating NUL) */
static const char Grids[][17] = {
28
29
30
  /*  0 */  "undefined",
  /*  1 */  "generic",
  /*  2 */  "gaussian",
31
  /*  3 */  "gaussian_reduced",
32
33
34
35
36
  /*  4 */  "lonlat",
  /*  5 */  "spectral",
  /*  6 */  "fourier",
  /*  7 */  "gme",
  /*  8 */  "trajectory",
37
  /*  9 */  "unstructured",
38
39
  /* 10 */  "curvilinear",
  /* 11 */  "lcc",
40
  /* 12 */  "projection",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
41
  /* 13 */  "characterXY",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
42
43
};

44
45
46
47
48
/* must match table below */
enum xystdname_idx {
  grid_xystdname_grid_latlon,
  grid_xystdname_latlon,
  grid_xystdname_projection,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
49
  grid_xystdname_char,
50
51
52
53
54
55
56
57
};
static const char xystdname_tab[][2][24] = {
  [grid_xystdname_grid_latlon] = { "grid_longitude",
                                   "grid_latitude" },
  [grid_xystdname_latlon] = { "longitude",
                              "latitude" },
  [grid_xystdname_projection] = { "projection_x_coordinate",
                                  "projection_y_coordinate" },
Uwe Schulzweida's avatar
Uwe Schulzweida committed
58
59
  [grid_xystdname_char] = { "region",
                            "region" },
60
61
62
};


Uwe Schulzweida's avatar
Uwe Schulzweida committed
63

64
65
66
static int    gridCompareP    ( void * gridptr1, void * gridptr2 );
static void   gridDestroyP    ( void * gridptr );
static void   gridPrintP      ( void * gridptr, FILE * fp );
67
static int    gridGetPackSize ( void * gridptr, void *context);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
68
static void   gridPack        ( void * gridptr, void * buff, int size, int *position, void *context);
Deike Kleberg's avatar
minimal    
Deike Kleberg committed
69
static int    gridTxCode      ( void );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
70

71
static const resOps gridOps = {
72
73
74
75
76
77
  gridCompareP,
  gridDestroyP,
  gridPrintP,
  gridGetPackSize,
  gridPack,
  gridTxCode
78
};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
79

80
static int  GRID_Debug = 0;   /* If set to 1, debugging */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
81

Uwe Schulzweida's avatar
Uwe Schulzweida committed
82

83
grid_t *grid_to_pointer(int gridID)
84
85
86
{
  return (grid_t *)reshGetVal(gridID, &gridOps);
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
87

88
#define gridMark4Update(gridID) reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
89

90
91
92
93
94
95
96
static
bool cdiInqAttConvertedToFloat(int gridID, int atttype, const char *attname, int attlen, double *attflt)
{
  bool status = true;

  if ( atttype == CDI_DATATYPE_INT32 )
    {
97
98
      int attint;
      int *pattint = attlen > 1 ? (int*) malloc(attlen*sizeof(int)) : &attint;
99
100
      cdiInqAttInt(gridID, CDI_GLOBAL, attname, attlen, pattint);
      for ( int i = 0; i < attlen; ++i ) attflt[i] = (double)pattint[i];
101
      if (attlen > 1) free(pattint);
102
103
104
105
106
107
108
109
110
111
112
113
114
    }
  else if ( atttype == CDI_DATATYPE_FLT32 || atttype == CDI_DATATYPE_FLT64 )
    {
      cdiInqAttFlt(gridID, CDI_GLOBAL, attname, attlen, attflt);
    }
  else
    {
      status = false;
    }

  return status;
}

115
116
117
static
void grid_axis_init(struct gridaxis_t *axisptr)
{
118
119
120
121
122
123
124
  axisptr->size           = 0;
  axisptr->vals           = NULL;
  axisptr->bounds         = NULL;
  axisptr->flag           = 0;
  axisptr->first          = 0.0;
  axisptr->last           = 0.0;
  axisptr->inc            = 0.0;
125
#ifndef USE_MPI
126
127
  axisptr->clength        = 0;
  axisptr->cvals          = NULL;
128
#endif
129
  axisptr->stdname        = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
130
  cdiInitKeys(&axisptr->keys);
131
}
132

Deike Kleberg's avatar
Deike Kleberg committed
133
void grid_init(grid_t *gridptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
134
{
135
136
137
138
139
140
141
  gridptr->self           = CDI_UNDEFID;
  gridptr->type           = CDI_UNDEFID;
  gridptr->proj           = CDI_UNDEFID;
  gridptr->projtype       = CDI_UNDEFID;
  gridptr->mask           = NULL;
  gridptr->mask_gme       = NULL;
  gridptr->size           = 0;
142
143
144
145

  grid_axis_init(&gridptr->x);
  grid_axis_init(&gridptr->y);

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  gridptr->area           = NULL;
  gridptr->reducedPoints  = NULL;
  gridptr->reducedPointsSize = 0;

  gridptr->gme.nd         = 0;
  gridptr->gme.ni         = 0;
  gridptr->gme.ni2        = 0;
  gridptr->gme.ni3        = 0;

  gridptr->trunc          = 0;
  gridptr->nvertex        = 0;
  gridptr->datatype       = CDI_DATATYPE_FLT64;
  gridptr->np             = 0;
  gridptr->isCyclic       = CDI_UNDEFID;

  gridptr->lcomplex       = false;
  gridptr->hasdims        = true;
163
164
  gridptr->name           = NULL;
  gridptr->vtable         = &cdiGridVtable;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
165
  cdiInitKeys(&gridptr->keys);
166
167
  gridptr->atts.nalloc    = MAX_ATTRIBUTES;
  gridptr->atts.nelems    = 0;
168
169

  cdiDefVarKeyInt(&gridptr->keys, CDI_KEY_SCANNINGMODE, 64);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
170
171
}

172

173
174
static
void grid_free_components(grid_t *gridptr)
Deike Kleberg's avatar
Deike Kleberg committed
175
{
176
  void *p2free[] = { gridptr->mask, gridptr->mask_gme,
177
                     gridptr->x.vals, gridptr->y.vals,
178
#ifndef USE_MPI
Uwe Schulzweida's avatar
Uwe Schulzweida committed
179
                     gridptr->x.cvals, gridptr->y.cvals,
180
#endif
181
                     gridptr->x.bounds, gridptr->y.bounds,
182
                     gridptr->reducedPoints, gridptr->area,
183
                     gridptr->name};
184

185
  for ( size_t i = 0; i < sizeof(p2free)/sizeof(p2free[0]); ++i )
186
    if ( p2free[i] ) Free(p2free[i]);
187
188

  int gridID = gridptr->self;
189
  /*
190
191
192
193
  cdiDeleteKeys(gridID, CDI_XAXIS);
  cdiDeleteKeys(gridID, CDI_YAXIS);
  cdiDeleteKeys(gridID, CDI_GLOBAL);
  cdiDeleteAtts(gridID, CDI_GLOBAL);
194
  */
195
}
Deike Kleberg's avatar
Deike Kleberg committed
196

197
198
199
void grid_free(grid_t *gridptr)
{
  grid_free_components(gridptr);
Deike Kleberg's avatar
Deike Kleberg committed
200
201
202
  grid_init(gridptr);
}

203
204
static
grid_t *gridNewEntry(cdiResH resH)
205
{
206
  grid_t *gridptr = (grid_t*) Malloc(sizeof(grid_t));
207
  grid_init(gridptr);
208

209
  if ( resH == CDI_UNDEFID )
210
211
212
213
214
215
    gridptr->self = reshPut(gridptr, &gridOps);
  else
    {
      gridptr->self = resH;
      reshReplace(resH, gridptr, &gridOps);
    }
216

217
  return gridptr;
218
219
}

220
static
221
void gridInit(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
222
{
223
  static bool gridInitialized = false;
224
  if ( gridInitialized ) return;
225
  gridInitialized = true;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
226

Uwe Schulzweida's avatar
Uwe Schulzweida committed
227
  const char *env = getenv("GRID_DEBUG");
228
  if ( env ) GRID_Debug = atoi(env);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
229
230
}

231
232
static
void grid_copy_base_scalar_fields(grid_t *gridptrOrig, grid_t *gridptrDup)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
233
{
Thomas Jahns's avatar
Thomas Jahns committed
234
235
  memcpy(gridptrDup, gridptrOrig, sizeof(grid_t));
  gridptrDup->self = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
236
  cdiInitKeys(&gridptrDup->keys);
237
  cdiCopyVarKeys(&gridptrOrig->keys, &gridptrDup->keys);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
238
  cdiInitKeys(&gridptrDup->x.keys);
239
  cdiCopyVarKeys(&gridptrOrig->x.keys, &gridptrDup->x.keys);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
240
  cdiInitKeys(&gridptrDup->y.keys);
241
  cdiCopyVarKeys(&gridptrOrig->y.keys, &gridptrDup->y.keys);
Thomas Jahns's avatar
Thomas Jahns committed
242
243
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
244

245
246
static
grid_t *grid_copy_base(grid_t *gridptrOrig)
Thomas Jahns's avatar
Thomas Jahns committed
247
248
249
250
251
{
  grid_t *gridptrDup = (grid_t *)Malloc(sizeof (*gridptrDup));
  gridptrOrig->vtable->copyScalarFields(gridptrOrig, gridptrDup);
  gridptrOrig->vtable->copyArrayFields(gridptrOrig, gridptrDup);
  return gridptrDup;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
252
253
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
254

255
unsigned cdiGridCount(void)
Thomas Jahns's avatar
Thomas Jahns committed
256
{
257
  return reshCountType(&gridOps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
258
259
}

260
261
262
263
264
265
266
static inline
void gridaxisSetKey(struct gridaxis_t *axisptr, int key, const char *name)
{
  if (find_key(&axisptr->keys, key) == NULL)
    cdiDefVarKeyBytes(&axisptr->keys, key, (const unsigned char*)name, (int)strlen(name)+1);
}

267
void cdiGridTypeInit(grid_t *gridptr, int gridtype, size_t size)
268
269
270
271
{
  gridptr->type = gridtype;
  gridptr->size = size;

272
273
  if      ( gridtype == GRID_LONLAT   ) gridptr->nvertex = 2;
  else if ( gridtype == GRID_GAUSSIAN ) gridptr->nvertex = 2;
274
  else if ( gridtype == GRID_GAUSSIAN_REDUCED ) gridptr->nvertex = 2;
275
  else if ( gridtype == GRID_CURVILINEAR  ) gridptr->nvertex = 4;
276
277
  else if ( gridtype == GRID_UNSTRUCTURED ) gridptr->x.size = size;

278
279
280
281
282
283
  switch (gridtype)
    {
    case GRID_LONLAT:
    case GRID_GAUSSIAN:
    case GRID_GAUSSIAN_REDUCED:
    case GRID_TRAJECTORY:
284
285
286
    case GRID_CURVILINEAR:
    case GRID_UNSTRUCTURED:
    case GRID_GME:
287
288
289
      {
        if ( gridtype == GRID_TRAJECTORY )
          {
290
291
            gridaxisSetKey(&gridptr->x, CDI_KEY_NAME, "tlon");
            gridaxisSetKey(&gridptr->y, CDI_KEY_NAME, "tlat");
292
293
294
          }
        else
          {
295
296
            gridaxisSetKey(&gridptr->x, CDI_KEY_NAME, "lon");
            gridaxisSetKey(&gridptr->y, CDI_KEY_NAME, "lat");
297
          }
298

299
300
        gridaxisSetKey(&gridptr->x, CDI_KEY_LONGNAME, "longitude");
        gridaxisSetKey(&gridptr->y, CDI_KEY_LONGNAME, "latitude");
301

302
303
        gridaxisSetKey(&gridptr->x, CDI_KEY_UNITS, "degrees_east");
        gridaxisSetKey(&gridptr->y, CDI_KEY_UNITS, "degrees_north");
304

305
306
        gridptr->x.stdname = xystdname_tab[grid_xystdname_latlon][0];
        gridptr->y.stdname = xystdname_tab[grid_xystdname_latlon][1];
307

308
309
        break;
      }
310
#ifndef USE_MPI
Uwe Schulzweida's avatar
Uwe Schulzweida committed
311
312
    case GRID_CHARXY:
      {
313
314
315
316
        if ( gridptr->x.cvals ) gridptr->x.stdname = xystdname_tab[grid_xystdname_char][0];
        if ( gridptr->y.cvals ) gridptr->y.stdname = xystdname_tab[grid_xystdname_char][0];

        break;
317
318
      }
#endif
319
    case GRID_GENERIC:
320
    case GRID_PROJECTION:
321
      {
322
323
        gridaxisSetKey(&gridptr->x, CDI_KEY_NAME, "x");
        gridaxisSetKey(&gridptr->y, CDI_KEY_NAME, "y");
324
325
        if ( gridtype == GRID_PROJECTION )
          {
326
327
            const char *gmapname = "Projection";
            cdiDefVarKeyBytes(&gridptr->keys, CDI_KEY_GRIDMAP_NAME, (const unsigned char *)gmapname, (int)sizeof(gmapname)+1);
328

329
330
            gridptr->x.stdname = xystdname_tab[grid_xystdname_projection][0];
            gridptr->y.stdname = xystdname_tab[grid_xystdname_projection][1];
331

332
333
            gridaxisSetKey(&gridptr->x, CDI_KEY_UNITS, "m");
            gridaxisSetKey(&gridptr->y, CDI_KEY_UNITS, "m");
334
          }
335
336
337
338
339
340
        break;
      }
    }
}


341
// used also in CDO
342
void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *restrict xvals)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
343
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
344
  if (fabs(xinc) <= 0 && xsize > 1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
345
346
    {
      if ( xfirst >= xlast )
Thomas Jahns's avatar
Thomas Jahns committed
347
348
349
350
        {
          while ( xfirst >= xlast ) xlast += 360;
          xinc = (xlast-xfirst)/(xsize);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
351
      else
Thomas Jahns's avatar
Thomas Jahns committed
352
353
354
        {
          xinc = (xlast-xfirst)/(xsize-1);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
355
356
    }

357
  for ( int i = 0; i < xsize; ++i )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
358
359
360
    xvals[i] = xfirst + i*xinc;
}

361
static
362
void calc_gaussgrid(double *restrict yvals, size_t ysize, double yfirst, double ylast)
363
{
364
  double *restrict yw = (double *) Malloc(ysize * sizeof(double));
365
  gaussianLatitudes(yvals, yw, ysize);
366
  Free(yw);
367
  for (size_t i = 0; i < ysize; i++ )
368
369
370
371
    yvals[i] = asin(yvals[i])/M_PI*180.0;

  if ( yfirst < ylast && yfirst > -90.0 && ylast < 90.0 )
    {
372
      const size_t yhsize = ysize/2;
373
      for (size_t i = 0; i < yhsize; i++ )
Thomas Jahns's avatar
Thomas Jahns committed
374
        {
375
          const double ytmp = yvals[i];
Thomas Jahns's avatar
Thomas Jahns committed
376
377
378
          yvals[i] = yvals[ysize-i-1];
          yvals[ysize-i-1] = ytmp;
        }
379
380
381
    }
}

382
383
static
void gridGenYvalsGaussian(int ysize, double yfirst, double ylast, double *restrict yvals)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
384
{
385
  const double deleps = 0.002;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
386

387
388
389
390
391
392
393
394
395
396
  calc_gaussgrid(yvals, ysize, yfirst, ylast);

  if ( ! (IS_EQUAL(yfirst, 0) && IS_EQUAL(ylast, 0)) )
    if ( fabs(yvals[0] - yfirst) > deleps || fabs(yvals[ysize-1] - ylast) > deleps )
      {
        bool lfound = false;
        int ny = (int) (180./(fabs(ylast-yfirst)/(ysize-1)) + 0.5);
        ny -= ny%2;
        if ( ny > ysize && ny < 4096 )
          {
397
            double *ytmp = (double *) Malloc((size_t)ny * sizeof (double));
398
            calc_gaussgrid(ytmp, ny, yfirst, ylast);
399
400
401
402
403

            int i;
            for ( i = 0; i < (ny-ysize); i++ )
              if ( fabs(ytmp[i] - yfirst) < deleps ) break;
            int nstart = i;
404
405
406
407

            lfound = (nstart+ysize-1) < ny && fabs(ytmp[nstart+ysize-1] - ylast) < deleps;
            if ( lfound )
              {
408
                for (i = 0; i < ysize; i++) yvals[i] = ytmp[i+nstart];
409
              }
410
411

            if ( ytmp ) Free(ytmp);
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
          }

        if ( !lfound )
          {
            Warning("Cannot calculate gaussian latitudes for lat1 = %g latn = %g!", yfirst, ylast);
            for (int i = 0; i < ysize; i++ ) yvals[i] = 0;
            yvals[0] = yfirst;
            yvals[ysize-1] = ylast;
          }
      }
}

static
void gridGenYvalsRegular(int ysize, double yfirst, double ylast, double yinc, double *restrict yvals)
{
  if (fabs(yinc) <= 0 && ysize > 1)
    {
      if ( IS_EQUAL(yfirst, ylast) && IS_NOT_EQUAL(yfirst, 0) ) ylast *= -1;

      if ( yfirst > ylast )
        yinc = (yfirst-ylast)/(ysize-1);
      else if ( yfirst < ylast )
        yinc = (ylast-yfirst)/(ysize-1);
      else
        {
          if ( ysize%2 != 0 )
            {
              yinc = 180.0/(ysize-1);
              yfirst = -90;
            }
          else
            {
              yinc = 180.0/ysize;
              yfirst = -90 + yinc/2;
            }
        }
    }

  if ( yfirst > ylast && yinc > 0 ) yinc = -yinc;

  for (int i = 0; i < ysize; i++ )
    yvals[i] = yfirst + i*yinc;
}

// used also in CDO
void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *restrict yvals)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
459
460
461
  if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
    {
      if ( ysize > 2 )
Deike Kleberg's avatar
Deike Kleberg committed
462
	{
463
          gridGenYvalsGaussian(ysize, yfirst, ylast, yvals);
Deike Kleberg's avatar
Deike Kleberg committed
464
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
465
      else
Thomas Jahns's avatar
Thomas Jahns committed
466
467
468
469
        {
          yvals[0] = yfirst;
          yvals[ysize-1] = ylast;
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
470
471
472
473
    }
  /*     else if ( gridtype == GRID_LONLAT || gridtype == GRID_GENERIC ) */
  else
    {
474
      gridGenYvalsRegular(ysize, yfirst, ylast, yinc, yvals);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
475
    }
476
   /*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
477
    else
478
    Error("unable to calculate values for %s grid!", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
479
480
481
482
  */
}

/*
483
@Function  gridCreate
484
@Title     Create a horizontal Grid
Uwe Schulzweida's avatar
Uwe Schulzweida committed
485

486
@Prototype int gridCreate(int gridtype, size_t size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
487
488
@Parameter
    @Item  gridtype  The type of the grid, one of the set of predefined CDI grid types.
489
                     The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
490
                     @func{GRID_LONLAT}, @func{GRID_PROJECTION}, @func{GRID_SPECTRAL},
491
                     @func{GRID_GME}, @func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
492
493
494
    @Item  size      Number of gridpoints.

@Description
495
The function @func{gridCreate} creates a horizontal Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
496
497

@Result
498
@func{gridCreate} returns an identifier to the Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
499
500

@Example
501
Here is an example using @func{gridCreate} to create a regular lon/lat Grid:
Uwe Schulzweida's avatar
Uwe Schulzweida committed
502
503

@Source
Uwe Schulzweida's avatar
Uwe Schulzweida committed
504
505
#include "cdi.h"
   ...
506
507
#define  nlon  12
#define  nlat   6
Uwe Schulzweida's avatar
Uwe Schulzweida committed
508
   ...
509
510
double lons[nlon] = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330};
double lats[nlat] = {-75, -45, -15, 15, 45, 75};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
511
512
int gridID;
   ...
513
514
515
gridID = gridCreate(GRID_LONLAT, nlon*nlat);
gridDefXsize(gridID, nlon);
gridDefYsize(gridID, nlat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
516
517
518
519
gridDefXvals(gridID, lons);
gridDefYvals(gridID, lats);
   ...
@EndSource
Uwe Schulzweida's avatar
Uwe Schulzweida committed
520
521
@EndFunction
*/
522
int gridCreate(int gridtype, size_t size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
523
{
524
  if ( CDI_Debug ) Message("gridtype=%s  size=%zu", gridNamePtr(gridtype), size);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
525

526
  xassert(size);
527
  gridInit();
528

Uwe Schulzweida's avatar
Uwe Schulzweida committed
529
  grid_t *gridptr = gridNewEntry(CDI_UNDEFID);
530
  if ( ! gridptr ) Error("No memory");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
531

532
  const int gridID = gridptr->self;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
533

534
  if ( CDI_Debug ) Message("gridID: %d", gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
535

536
  cdiGridTypeInit(gridptr, gridtype, size);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
537

Uwe Schulzweida's avatar
Uwe Schulzweida committed
538
  return gridID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
539
540
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
541
542
static
void gridDestroyKernel( grid_t * gridptr )
543
{
Deike Kleberg's avatar
Deike Kleberg committed
544
  xassert ( gridptr );
545

546
  const int id = gridptr->self;
547

548
  grid_free_components(gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
549
  Free( gridptr );
550

551
  reshRemove( id, &gridOps );
552
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
553

554
555
556
557
558
559
/*
@Function  gridDestroy
@Title     Destroy a horizontal Grid

@Prototype void gridDestroy(int gridID)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
560
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
561
562
563
564
565

@EndFunction
*/
void gridDestroy(int gridID)
{
566
567
568
  //cdiDeleteKeys(gridID, CDI_GLOBAL);
  //cdiDeleteAtts(gridID, CDI_GLOBAL);

569
  grid_t *gridptr = grid_to_pointer(gridID);
570
  gridptr->vtable->destroy(gridptr);
571
572
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
573
574
static
void gridDestroyP(void * gridptr)
575
{
576
  ((grid_t *)gridptr)->vtable->destroy((grid_t *)gridptr);
577
578
579
}


580
const char *gridNamePtr(int gridtype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
581
{
582
  const int size = (int) (sizeof(Grids)/sizeof(Grids[0]));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
583

Uwe Schulzweida's avatar
Uwe Schulzweida committed
584
  const char *name = (gridtype >= 0 && gridtype < size) ? Grids[gridtype] : Grids[GRID_GENERIC];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
585

Uwe Schulzweida's avatar
Uwe Schulzweida committed
586
  return name;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
587
588
589
590
591
592
593
594
595
596
597
598
599
600
}


void gridName(int gridtype, char *gridname)
{
  strcpy(gridname, gridNamePtr(gridtype));
}

/*
@Function  gridDefXname
@Title     Define the name of a X-axis

@Prototype void gridDefXname(int gridID, const char *name)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
601
602
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
    @Item  name     Name of the X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
603
604

@Description
605
The function @func{gridDefXname} defines the name of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
606
607
608

@EndFunction
*/
609
void gridDefXname(int gridID, const char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
610
{
611
  (void)cdiDefKeyString(gridID, CDI_XAXIS, CDI_KEY_NAME, name);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
612
613
614
615
616
617
618
619
}

/*
@Function  gridDefXlongname
@Title     Define the longname of a X-axis

@Prototype void gridDefXlongname(int gridID, const char *longname)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
620
621
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
    @Item  longname Longname of the X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
622
623

@Description
624
The function @func{gridDefXlongname} defines the longname of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
625
626
627

@EndFunction
*/
628
void gridDefXlongname(int gridID, const char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
629
{
630
  (void)cdiDefKeyString(gridID, CDI_XAXIS, CDI_KEY_LONGNAME, longname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
631
632
633
634
635
636
637
638
}

/*
@Function  gridDefXunits
@Title     Define the units of a X-axis

@Prototype void gridDefXunits(int gridID, const char *units)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
639
640
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
    @Item  units    Units of the X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
641
642

@Description
643
The function @func{gridDefXunits} defines the units of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
644
645
646

@EndFunction
*/
647
void gridDefXunits(int gridID, const char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
648
{
649
  (void)cdiDefKeyString(gridID, CDI_XAXIS, CDI_KEY_UNITS, units);
650
651
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
652
653
654
655
656
657
/*
@Function  gridDefYname
@Title     Define the name of a Y-axis

@Prototype void gridDefYname(int gridID, const char *name)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
658
659
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
    @Item  name     Name of the Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
660
661

@Description
662
The function @func{gridDefYname} defines the name of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
663
664
665

@EndFunction
*/
666
void gridDefYname(int gridID, const char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
667
{
668
  (void)cdiDefKeyString(gridID, CDI_YAXIS, CDI_KEY_NAME, name);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
669
670
671
672
673
674
675
676
}

/*
@Function  gridDefYlongname
@Title     Define the longname of a Y-axis

@Prototype void gridDefYlongname(int gridID, const char *longname)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
677
678
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
    @Item  longname Longname of the Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
679
680

@Description
681
The function @func{gridDefYlongname} defines the longname of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
682
683
684

@EndFunction
*/
685
void gridDefYlongname(int gridID, const char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
686
{
687
  (void)cdiDefKeyString(gridID, CDI_YAXIS, CDI_KEY_LONGNAME, longname);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
688
689
690
691
692
693
694
695
}

/*
@Function  gridDefYunits
@Title     Define the units of a Y-axis

@Prototype void gridDefYunits(int gridID, const char *units)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
696
697
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
    @Item  units    Units of the Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
698
699

@Description
700
The function @func{gridDefYunits} defines the units of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
701
702
703

@EndFunction
*/
704
void gridDefYunits(int gridID, const char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
705
{
706
  (void)cdiDefKeyString(gridID, CDI_YAXIS, CDI_KEY_UNITS, units);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
707
708
709
710
711
712
}

/*
@Function  gridInqXname
@Title     Get the name of a X-axis

Deike Kleberg's avatar
Deike Kleberg committed
713
@Prototype void gridInqXname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
714
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
715
716
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
    @Item  name     Name of the X-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
717
                    returned string. The maximum possible length, in characters, of
718
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
719
720

@Description
721
The function @func{gridInqXname} returns the name of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
722
723

@Result
724
@func{gridInqXname} returns the name of the X-axis to the parameter name.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
725
726
727

@EndFunction
*/
728
void gridInqXname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
729
{
730
731
  int length = CDI_MAX_NAME;
  (void)cdiInqKeyString(gridID, CDI_XAXIS, CDI_KEY_NAME, name, &length);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
732
733
734
735
736
737
}

/*
@Function  gridInqXlongname
@Title     Get the longname of a X-axis

Deike Kleberg's avatar
Deike Kleberg committed
738
@Prototype void gridInqXlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
739
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
740
741
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
    @Item  longname Longname of the X-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
742
                    returned string. The maximum possible length, in characters, of
743
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
744
745

@Description
746
The function @func{gridInqXlongname} returns the longname of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
747
748

@Result
749
@func{gridInqXlongname} returns the longname of the X-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
750
751
752

@EndFunction
*/
753
void gridInqXlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
{
755
756
  int length = CDI_MAX_NAME;
  (void)cdiInqKeyString(gridID, CDI_XAXIS, CDI_KEY_LONGNAME, longname, &length);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
757
758
759
760
761
762
}

/*
@Function  gridInqXunits
@Title     Get the units of a X-axis

Deike Kleberg's avatar
Deike Kleberg committed
763
@Prototype void gridInqXunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
764
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
765
766
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
    @Item  units    Units of the X-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
767
                    returned string. The maximum possible length, in characters, of
768
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
769
770

@Description
771
The function @func{gridInqXunits} returns the units of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
772
773

@Result
774
@func{gridInqXunits} returns the units of the X-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
775
776
777

@EndFunction
*/
778
void gridInqXunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
779
{
780
781
  int length = CDI_MAX_NAME;
  (void)cdiInqKeyString(gridID, CDI_XAXIS, CDI_KEY_UNITS, units, &length);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
782
783
784
785
786
}


void gridInqXstdname(int gridID, char *xstdname)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
787
788
789
790
791
792
  if ( xstdname )
    {
      xstdname[0] = 0;
      grid_t *gridptr = grid_to_pointer(gridID);
      if ( gridptr->x.stdname ) strcpy(xstdname, gridptr->x.stdname);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
793
794
795
796
797
798
}

/*
@Function  gridInqYname
@Title     Get the name of a Y-axis

Deike Kleberg's avatar
Deike Kleberg committed
799
@Prototype void gridInqYname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
800
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
801
802
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
    @Item  name     Name of the Y-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
803
                    returned string. The maximum possible length, in characters, of
804
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
805
806

@Description
807
The function @func{gridInqYname} returns the name of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
808
809

@Result
810
@func{gridInqYname} returns the name of the Y-axis to the parameter name.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
811
812
813

@EndFunction
*/
814
void gridInqYname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
815
{
816
817
  int length = CDI_MAX_NAME;
  (void)cdiInqKeyString(gridID, CDI_YAXIS, CDI_KEY_NAME, name, &length);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
818
819
820
821
822
823
}

/*
@Function  gridInqYlongname
@Title     Get the longname of a Y-axis

824
@Prototype void gridInqYlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
825
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
826
827
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
    @Item  longname Longname of the Y-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
828
                    returned string. The maximum possible length, in characters, of
829
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
830
831

@Description
832
The function @func{gridInqYlongname} returns the longname of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
833
834

@Result
835
@func{gridInqYlongname} returns the longname of the Y-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
836
837
838

@EndFunction
*/
839
void gridInqYlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
840
{
841
842
  int length = CDI_MAX_NAME;
  (void)cdiInqKeyString(gridID, CDI_YAXIS, CDI_KEY_LONGNAME, longname, &length);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
843
844
845
846
847
848
}

/*
@Function  gridInqYunits
@Title     Get the units of a Y-axis

Deike Kleberg's avatar
Deike Kleberg committed
849
@Prototype void gridInqYunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
850
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
851
852
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
    @Item  units    Units of the Y-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
853
                    returned string. The maximum possible length, in characters, of
854
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
855
856

@Description
857
The function @func{gridInqYunits} returns the units of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
858
859

@Result
860
@func{gridInqYunits} returns the units of the Y-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
861
862
863

@EndFunction
*/
864
void gridInqYunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
865
{
866
867
  int length = CDI_MAX_NAME;
  (void)cdiInqKeyString(gridID, CDI_YAXIS, CDI_KEY_UNITS, units, &length);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
868
869
}

870

Uwe Schulzweida's avatar
Uwe Schulzweida committed
871
872
void gridInqYstdname(int gridID, char *ystdname)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
873
874
875
876
877
878
  if ( ystdname )
    {
      ystdname[0] = 0;
      grid_t *gridptr = grid_to_pointer(gridID);
      if ( gridptr->y.stdname ) strcpy(ystdname, gridptr->y.stdname);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
879
880
}

881

882
void gridDefProj(int gridID, int projID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
883
{
884
  grid_t *gridptr = grid_to_pointer(gridID);
885
  gridptr->proj = projID;
886
887
888

  if ( gridptr->type == GRID_CURVILINEAR )
    {
889
      grid_t *projptr = grid_to_pointer(projID);
890
891
892
893
      const char *xdimname = cdiInqVarKeyStringPtr(&gridptr->x.keys, CDI_KEY_DIMNAME);
      const char *ydimname = cdiInqVarKeyStringPtr(&gridptr->y.keys, CDI_KEY_DIMNAME);
      if (xdimname && find_key(&projptr->x.keys, CDI_KEY_NAME)) cdiDefKeyString(projID, CDI_XAXIS, CDI_KEY_NAME, xdimname);
      if (ydimname && find_key(&projptr->y.keys, CDI_KEY_NAME)) cdiDefKeyString(projID, CDI_YAXIS, CDI_KEY_NAME, ydimname);
894
    }
895
896
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
897

898
899
int gridInqProj(int gridID)
{
900
  grid_t *gridptr = grid_to_pointer(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
901
902
903
  return gridptr->proj;
}

904
905
906

int gridInqProjType(int gridID)
{
907
  grid_t *gridptr = grid_to_pointer(gridID);
908
909
910
911

  int projtype = gridptr->projtype;
  if ( projtype == -1 )
    {
912
913
914
915
      char gmapname[CDI_MAX_NAME];
      int length = CDI_MAX_NAME;
      cdiInqKeyString(gridID, CDI_GLOBAL, CDI_KEY_GRIDMAP_NAME, gmapname, &length);
      if ( gmapname[0] )
916
        {
917
          // clang-format off
918
919
920
921
922
          if      ( strIsEqual(gmapname, "rotated_latitude_longitude") )   projtype = CDI_PROJ_RLL;
          else if ( strIsEqual(gmapname, "lambert_azimuthal_equal_area") ) projtype = CDI_PROJ_LAEA;
          else if ( strIsEqual(gmapname, "lambert_conformal_conic") )      projtype = CDI_PROJ_LCC;
          else if ( strIsEqual(gmapname, "sinusoidal") )                   projtype = CDI_PROJ_SINU;
          else if ( strIsEqual(gmapname, "polar_stereographic") )          projtype = CDI_PROJ_STERE;
923
          // clang-format on
924
925
926
927
928
929
930
          gridptr->projtype = projtype;
        }
    }

  return projtype;
}

931
932
933

void gridVerifyProj(int gridID)
{
934
  grid_t *gridptr = grid_to_pointer(gridID);
935

936
  const int projtype = gridInqProjType(gridID);
937
938
939
940
  if ( projtype == CDI_PROJ_RLL )
    {
      gridptr->x.stdname = xystdname_tab[grid_xystdname_grid_latlon][0];
      gridptr->y.stdname = xystdname_tab[grid_xystdname_grid_latlon][1];
941
942
      gridaxisSetKey(&gridptr->x, CDI_KEY_UNITS, "degrees");
      gridaxisSetKey(&gridptr->y, CDI_KEY_UNITS, "degrees");
943
    }
944
945
946
947
  else if ( projtype == CDI_PROJ_LCC )
    {
      gridptr->x.stdname = xystdname_tab[grid_xystdname_projection][0];
      gridptr->y.stdname = xystdname_tab[grid_xystdname_projection][1];
948
949
      gridaxisSetKey(&gridptr->x, CDI_KEY_UNITS, "m");
      gridaxisSetKey(&gridptr->y, CDI_KEY_UNITS, "m");
950
    }
951
952
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
953
954
955
956
957
958
/*
@Function  gridInqType
@Title     Get the type of a Grid

@Prototype int gridInqType(int gridID)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
959
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
960
961

@Description
962
The function @func{gridInqType} returns the type of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
963
964

@Result
965
@func{gridInqType} returns the type of the grid,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
966
one of the set of predefined CDI grid types.
967
The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
968
@func{GRID_LONLAT}, @func{GRID_PROJECTION}, @func{GRID_SPECTRAL}, @func{GRID_GME},
969
@func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
970
971
972
973
974

@EndFunction
*/
int gridInqType(int gridID)
{
975
  grid_t *gridptr = grid_to_pointer(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
976
  return gridptr->type;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
977
978
979
980
981
982
983
}


/*
@Function  gridInqSize
@Title     Get the size of a Grid

984
@Prototype size_t gridInqSize(int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
985
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
986
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
987
988

@Description
989
The function @func{gridInqSize} returns the size of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
990
991

@Result
992
@func{gridInqSize} returns the number of grid points of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
993
994
995

@EndFunction
*/
996
size_t gridInqSize(int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
997
{
998
  grid_t *gridptr = grid_to_pointer(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
999

1000
  size_t size = gridptr