grid.c 130 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
5
#if defined (HAVE_CONFIG_H)
#  include "config.h"
#endif

#include <string.h>
6
#include <float.h>  /* FLT_EPSILON */
7
#include <limits.h> /* INT_MAX     */
8

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

#undef  UNDEFID
#define UNDEFID -1
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
31
32
33
34
35
36
  /*  0 */  "undefined",
  /*  1 */  "generic",
  /*  2 */  "gaussian",
  /*  3 */  "gaussian reduced",
  /*  4 */  "lonlat",
  /*  5 */  "spectral",
  /*  6 */  "fourier",
  /*  7 */  "gme",
  /*  8 */  "trajectory",
37
  /*  9 */  "unstructured",
38
39
  /* 10 */  "curvilinear",
  /* 11 */  "lcc",
40
41
42
  /* 12 */  "lcc2",
  /* 13 */  "laea",
  /* 14 */  "sinusoidal",
43
  /* 15 */  "projection",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
44
45
};

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/* must match table below */
enum xystdname_idx {
  grid_xystdname_grid_latlon,
  grid_xystdname_latlon,
  grid_xystdname_projection,
};
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
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);
68
static void   gridPack        ( void * gridptr, void * buff, int size,
69
				int *position, void *context);
Deike Kleberg's avatar
minimal    
Deike Kleberg committed
70
static int    gridTxCode      ( void );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
71

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

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

83
84
85
86
grid_t *gridID2Ptr(int gridID)
{
  return (grid_t *)reshGetVal(gridID, &gridOps);
}
87
#define gridID2Ptr(gridID) (grid_t *)reshGetVal(gridID, &gridOps)
88
#define gridMark4Update(gridID) reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
89

90

Deike Kleberg's avatar
Deike Kleberg committed
91
void grid_init(grid_t *gridptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
92
{
93
  gridptr->self         = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
94
  gridptr->type         = CDI_UNDEFID;
Deike Kleberg's avatar
Deike Kleberg committed
95
  gridptr->proj         = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
96
  gridptr->mask         = NULL;
97
  gridptr->mask_gme     = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
98
99
100
101
102
103
104
  gridptr->xvals        = NULL;
  gridptr->yvals        = NULL;
  gridptr->area         = NULL;
  gridptr->xbounds      = NULL;
  gridptr->ybounds      = NULL;
  gridptr->rowlon       = NULL;
  gridptr->nrowlon      = 0;
105
106
  gridptr->xfirst       = 0.0;
  gridptr->xlast        = 0.0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
107
  gridptr->xinc         = 0.0;
108
109
  gridptr->yfirst       = 0.0;
  gridptr->ylast        = 0.0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
110
  gridptr->yinc         = 0.0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
111
112
113
114
115
116
117
  gridptr->lcc_originLon = 0.0;
  gridptr->lcc_originLat = 0.0;
  gridptr->lcc_lonParY  = 0.0;
  gridptr->lcc_lat1     = 0.0;
  gridptr->lcc_lat2     = 0.0;
  gridptr->lcc_xinc     = 0.0;
  gridptr->lcc_yinc     = 0.0;
118
119
  gridptr->lcc_projflag = 0;
  gridptr->lcc_scanflag = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
120
  gridptr->lcc_defined  = FALSE;
121
122
123
124
125
126
  gridptr->lcc2_lon_0   = 0.0;
  gridptr->lcc2_lat_0   = 0.0;
  gridptr->lcc2_lat_1   = 0.0;
  gridptr->lcc2_lat_2   = 0.0;
  gridptr->lcc2_a       = 0.0;
  gridptr->lcc2_defined = FALSE;
127
128
129
130
  gridptr->laea_lon_0   = 0.0;
  gridptr->laea_lat_0   = 0.0;
  gridptr->laea_a       = 0.0;
  gridptr->laea_defined = FALSE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
131
132
133
134
135
136
  gridptr->trunc        = 0;
  gridptr->nvertex      = 0;
  gridptr->nd           = 0;
  gridptr->ni           = 0;
  gridptr->ni2          = 0;
  gridptr->ni3          = 0;
137
138
139
  gridptr->number       = 0;
  gridptr->position     = 0;
  gridptr->reference    = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
140
141
142
143
  gridptr->prec         = 0;
  gridptr->size         = 0;
  gridptr->xsize        = 0;
  gridptr->ysize        = 0;
144
  gridptr->np           = 0;
145
146
  gridptr->xdef         = 0;
  gridptr->ydef         = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
147
  gridptr->isCyclic     = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
148
149
150
151
  gridptr->isRotated    = FALSE;
  gridptr->xpole        = 0.0;
  gridptr->ypole        = 0.0;
  gridptr->angle        = 0.0;
152
  gridptr->lcomplex     = 0;
153
  gridptr->hasdims      = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
154
155
156
157
158
159
  gridptr->xname[0]     = 0;
  gridptr->yname[0]     = 0;
  gridptr->xlongname[0] = 0;
  gridptr->ylongname[0] = 0;
  gridptr->xunits[0]    = 0;
  gridptr->yunits[0]    = 0;
160
161
  gridptr->xstdname  = NULL;
  gridptr->ystdname  = NULL;
Thomas Jahns's avatar
Thomas Jahns committed
162
  memset(gridptr->uuid, 0, CDI_UUID_SIZE);
Deike Kleberg's avatar
Deike Kleberg committed
163
  gridptr->name         = NULL;
164
  gridptr->vtable       = &cdiGridVtable;
165
  gridptr->extraData    = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
166
167
}

168

169
170
static void
grid_free_components(grid_t *gridptr)
Deike Kleberg's avatar
Deike Kleberg committed
171
{
172
173
174
175
176
177
178
179
  void *p2free[] = { gridptr->mask, gridptr->mask_gme,
                   gridptr->xvals, gridptr->yvals,
                   gridptr->xbounds, gridptr->ybounds,
                   gridptr->rowlon, gridptr->area,
                   gridptr->reference, gridptr->name };
  for (size_t i = 0; i < sizeof (p2free) / sizeof (p2free[0]); ++i)
    if (p2free[i]) Free(p2free[i]);
}
Deike Kleberg's avatar
Deike Kleberg committed
180

181
182
183
void grid_free(grid_t *gridptr)
{
  grid_free_components(gridptr);
Deike Kleberg's avatar
Deike Kleberg committed
184
185
186
  grid_init(gridptr);
}

187
188
static grid_t *
gridNewEntry(cdiResH resH)
189
{
190
  grid_t *gridptr = (grid_t*) Malloc(sizeof(grid_t));
191
192
193
194
195
196
197
198
  grid_init(gridptr);
  if (resH == CDI_UNDEFID)
    gridptr->self = reshPut(gridptr, &gridOps);
  else
    {
      gridptr->self = resH;
      reshReplace(resH, gridptr, &gridOps);
    }
199
  return gridptr;
200
201
}

202
static
203
void gridInit (void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
204
{
205
206
  static int gridInitialized = 0;
  char *env;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
207

208
  if ( gridInitialized ) return;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
209

Thomas Jahns's avatar
Thomas Jahns committed
210
  gridInitialized = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
211

212
213
  env = getenv("GRID_DEBUG");
  if ( env ) GRID_Debug = atoi(env);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
214
215
}

216
217
static
void grid_copy(grid_t *gridptr2, grid_t *gridptr1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
218
219
220
221
{
  int gridID2;

  gridID2 = gridptr2->self;
222
  memcpy(gridptr2, gridptr1, sizeof(grid_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
223
224
225
  gridptr2->self = gridID2;
}

226
unsigned cdiGridCount(void)
Thomas Jahns's avatar
Thomas Jahns committed
227
{
228
  return reshCountType(&gridOps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
229
230
}

231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
static inline void
gridSetXname(grid_t *gridptr, const char *xname)
{
  strncpy(gridptr->xname, xname, CDI_MAX_NAME);
  gridptr->xname[CDI_MAX_NAME - 1] = 0;
}

static inline void
gridSetXlongname(grid_t *gridptr, const char *xlongname)
{
  strncpy(gridptr->xlongname, xlongname, CDI_MAX_NAME);
  gridptr->xlongname[CDI_MAX_NAME - 1] = 0;
}

static inline void
gridSetXunits(grid_t *gridptr, const char *xunits)
{
  strncpy(gridptr->xunits, xunits, CDI_MAX_NAME);
  gridptr->xunits[CDI_MAX_NAME - 1] = 0;
}

static inline void
gridSetYname(grid_t *gridptr, const char *yname)
{
  strncpy(gridptr->yname, yname, CDI_MAX_NAME);
  gridptr->yname[CDI_MAX_NAME - 1] = 0;
}

static inline void
gridSetYlongname(grid_t *gridptr, const char *ylongname)
{
  strncpy(gridptr->ylongname, ylongname, CDI_MAX_NAME);
  gridptr->ylongname[CDI_MAX_NAME - 1] = 0;
}

static inline void
gridSetYunits(grid_t *gridptr, const char *yunits)
{
  strncpy(gridptr->yunits, yunits, CDI_MAX_NAME);
  gridptr->yunits[CDI_MAX_NAME - 1] = 0;
}

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
void
cdiGridTypeInit(grid_t *gridptr, int gridtype, int size)
{

  gridptr->type = gridtype;
  gridptr->size = size;

  switch (gridtype)
    {
    case GRID_CURVILINEAR:
      gridptr->nvertex = 4;
      /* Fall through */
    case GRID_LONLAT:
    case GRID_GAUSSIAN:
    case GRID_GAUSSIAN_REDUCED:
    case GRID_TRAJECTORY:
      {
        if ( gridtype == GRID_TRAJECTORY )
          {
            gridSetXname(gridptr, "tlon");
            gridSetYname(gridptr, "tlat");
          }
        else
          {
            gridSetXname(gridptr, "lon");
            gridSetYname(gridptr, "lat");
          }
        gridSetXlongname(gridptr, "longitude");
        gridSetYlongname(gridptr, "latitude");

        /*
        if ( gridtype == GRID_CURVILINEAR )
          {
            gridptr->xstdname = xystdname_tab[grid_xystdname_grid_latlon][0];
            gridptr->ystdname = xystdname_tab[grid_xystdname_grid_latlon][1];
            gridDefXunits(gridID, "degrees");
            gridDefYunits(gridID, "degrees");
          }
        else
        */
          {
            gridptr->xstdname = xystdname_tab[grid_xystdname_latlon][0];
            gridptr->ystdname = xystdname_tab[grid_xystdname_latlon][1];
            gridSetXunits(gridptr, "degrees_east");
            gridSetYunits(gridptr, "degrees_north");
          }

        break;
      }
    case GRID_UNSTRUCTURED:
      gridptr->xsize = size;
      /* Fall through */
    case GRID_GME:
      {
        gridSetXname(gridptr, "lon");
        gridSetYname(gridptr, "lat");
        gridptr->xstdname = xystdname_tab[grid_xystdname_latlon][0];
        gridptr->ystdname = xystdname_tab[grid_xystdname_latlon][1];
        gridSetXunits(gridptr, "degrees_east");
        gridSetYunits(gridptr, "degrees_north");
        break;
      }
    case GRID_GENERIC:
      {

        /* gridptr->xsize = size; */
        gridSetXname(gridptr, "x");
        gridSetYname(gridptr, "y");
        /*
        strcpy(gridptr->xstdname, "grid_longitude");
        strcpy(gridptr->ystdname, "grid_latitude");
        gridptr->xstdname = xystdname_tab[grid_xystdname_grid_latlon][0];
        gridptr->ystdname = xystdname_tab[grid_xystdname_grid_latlon][1];
        gridDefXunits(gridID, "degrees");
        gridDefYunits(gridID, "degrees");
        */
        break;
      }
    case GRID_LCC2:
    case GRID_SINUSOIDAL:
    case GRID_LAEA:
      {
        gridSetXname(gridptr, "x");
        gridSetYname(gridptr, "y");
        gridptr->xstdname = xystdname_tab[grid_xystdname_projection][0];
        gridptr->ystdname = xystdname_tab[grid_xystdname_projection][1];
        gridSetXunits(gridptr, "m");
        gridSetYunits(gridptr, "m");
        break;
      }
    }

}


368
// used also in CDO
369
void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *restrict xvals)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
370
{
371
  if ( (! (fabs(xinc) > 0)) && xsize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
372
373
    {
      if ( xfirst >= xlast )
Thomas Jahns's avatar
Thomas Jahns committed
374
375
376
377
        {
          while ( xfirst >= xlast ) xlast += 360;
          xinc = (xlast-xfirst)/(xsize);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
378
      else
Thomas Jahns's avatar
Thomas Jahns committed
379
380
381
        {
          xinc = (xlast-xfirst)/(xsize-1);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
382
383
    }

384
  for ( int i = 0; i < xsize; ++i )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
385
386
387
    xvals[i] = xfirst + i*xinc;
}

388
static
389
void calc_gaussgrid(double *restrict yvals, int ysize, double yfirst, double ylast)
390
{
391
  double *restrict yw = (double *) Malloc((size_t)ysize * sizeof(double));
392
  gaussaw(yvals, yw, (size_t)ysize);
393
  Free(yw);
394
  for (int i = 0; i < ysize; i++ )
395
396
397
398
    yvals[i] = asin(yvals[i])/M_PI*180.0;

  if ( yfirst < ylast && yfirst > -90.0 && ylast < 90.0 )
    {
399
400
      int yhsize = ysize/2;
      for (int i = 0; i < yhsize; i++ )
Thomas Jahns's avatar
Thomas Jahns committed
401
        {
402
          double ytmp = yvals[i];
Thomas Jahns's avatar
Thomas Jahns committed
403
404
405
          yvals[i] = yvals[ysize-i-1];
          yvals[ysize-i-1] = ytmp;
        }
406
407
408
    }
}

409
// used also in CDO
Thomas Jahns's avatar
Thomas Jahns committed
410
void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *restrict yvals)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
411
{
412
  const double deleps = 0.002;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
413
414
415
416

  if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
    {
      if ( ysize > 2 )
Deike Kleberg's avatar
Deike Kleberg committed
417
418
419
420
421
422
	{
	  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 )
	      {
423
		double *restrict ytmp = NULL;
Deike Kleberg's avatar
Deike Kleberg committed
424
		int nstart, lfound = 0;
425
		int ny = (int) (180./fabs(ylast-yfirst)/(ysize-1) + 0.5);
Deike Kleberg's avatar
Deike Kleberg committed
426
427
428
		ny -= ny%2;
		if ( ny > ysize && ny < 4096 )
		  {
429
		    ytmp = (double *) Malloc((size_t)ny * sizeof (double));
Deike Kleberg's avatar
Deike Kleberg committed
430
		    calc_gaussgrid(ytmp, ny, yfirst, ylast);
431
432
433
434
435
436
                    {
                      int i;
                      for ( i = 0; i < (ny-ysize); i++ )
                        if ( fabs(ytmp[i] - yfirst) < deleps ) break;
                      nstart = i;
                    }
Deike Kleberg's avatar
Deike Kleberg committed
437

438
439
		    lfound = (nstart+ysize-1) < ny
                      && fabs(ytmp[nstart+ysize-1] - ylast) < deleps;
440
441
442
443
                    if ( lfound )
                      {
                        for (int i = 0; i < ysize; i++) yvals[i] = ytmp[i+nstart];
                      }
Deike Kleberg's avatar
Deike Kleberg committed
444
445
		  }

446
		if ( !lfound )
Deike Kleberg's avatar
Deike Kleberg committed
447
448
		  {
		    Warning("Cannot calculate gaussian latitudes for lat1 = %g latn = %g!", yfirst, ylast);
449
		    for (int i = 0; i < ysize; i++ ) yvals[i] = 0;
Deike Kleberg's avatar
Deike Kleberg committed
450
451
452
453
		    yvals[0] = yfirst;
		    yvals[ysize-1] = ylast;
		  }

454
		if ( ytmp ) Free(ytmp);
Deike Kleberg's avatar
Deike Kleberg committed
455
456
	      }
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
457
      else
Thomas Jahns's avatar
Thomas Jahns committed
458
459
460
461
        {
          yvals[0] = yfirst;
          yvals[ysize-1] = ylast;
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
462
463
464
465
    }
  /*     else if ( gridtype == GRID_LONLAT || gridtype == GRID_GENERIC ) */
  else
    {
466
      if ( (! (fabs(yinc) > 0)) && ysize > 1 )
Thomas Jahns's avatar
Thomas Jahns committed
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
        {
          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;
                }
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
488
489
490

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

491
      for (int i = 0; i < ysize; i++ )
Thomas Jahns's avatar
Thomas Jahns committed
492
        yvals[i] = yfirst + i*yinc;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
493
494
495
    }
  /*
    else
496
    Error("unable to calculate values for %s grid!", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
497
498
499
500
  */
}

/*
501
@Function  gridCreate
502
@Title     Create a horizontal Grid
Uwe Schulzweida's avatar
Uwe Schulzweida committed
503

504
@Prototype int gridCreate(int gridtype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
505
506
@Parameter
    @Item  gridtype  The type of the grid, one of the set of predefined CDI grid types.
507
                     The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
508
                     @func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL},
509
                     @func{GRID_GME}, @func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED} and.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
510
511
512
    @Item  size      Number of gridpoints.

@Description
513
The function @func{gridCreate} creates a horizontal Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
514
515

@Result
516
@func{gridCreate} returns an identifier to the Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
517
518

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

@Source
Uwe Schulzweida's avatar
Uwe Schulzweida committed
522
523
#include "cdi.h"
   ...
524
525
#define  nlon  12
#define  nlat   6
Uwe Schulzweida's avatar
Uwe Schulzweida committed
526
   ...
527
528
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
529
530
int gridID;
   ...
531
532
533
gridID = gridCreate(GRID_LONLAT, nlon*nlat);
gridDefXsize(gridID, nlon);
gridDefYsize(gridID, nlat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
534
535
536
537
gridDefXvals(gridID, lons);
gridDefYvals(gridID, lats);
   ...
@EndSource
Uwe Schulzweida's avatar
Uwe Schulzweida committed
538
539
@EndFunction
*/
540
int gridCreate(int gridtype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
541
{
542
  if ( CDI_Debug ) Message("gridtype=%s  size=%d", gridNamePtr(gridtype), size);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
543

544
  if ( size < 0 || size > INT_MAX ) Error("Grid size (%d) out of bounds (0 - %d)!", size, INT_MAX);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
545

546
  gridInit();
547

Uwe Schulzweida's avatar
Uwe Schulzweida committed
548
  grid_t *gridptr = gridNewEntry(CDI_UNDEFID);
549
  if ( ! gridptr ) Error("No memory");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
550

Uwe Schulzweida's avatar
Uwe Schulzweida committed
551
  int gridID = gridptr->self;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
552

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

555
  cdiGridTypeInit(gridptr, gridtype, size);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
556
557
558
559

  return (gridID);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
560
561
static
void gridDestroyKernel( grid_t * gridptr )
562
563
564
{
  int id;

Deike Kleberg's avatar
Deike Kleberg committed
565
  xassert ( gridptr );
566
567
568

  id = gridptr->self;

569
  grid_free_components(gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
570
  Free( gridptr );
571

572
  reshRemove ( id, &gridOps );
573
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
574

575
576
577
578
579
580
/*
@Function  gridDestroy
@Title     Destroy a horizontal Grid

@Prototype void gridDestroy(int gridID)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
581
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
582
583
584
585
586

@EndFunction
*/
void gridDestroy(int gridID)
{
587
  grid_t *gridptr = gridID2Ptr(gridID);
588
  gridptr->vtable->destroy(gridptr);
589
590
}

591
void gridDestroyP ( void * gridptr )
592
{
593
  ((grid_t *)gridptr)->vtable->destroy((grid_t *)gridptr);
594
595
596
}


597
const char *gridNamePtr(int gridtype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
598
{
599
  int size = (int) (sizeof(Grids)/sizeof(Grids[0]));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
600

601
  const char *name = gridtype >= 0 && gridtype < size ? Grids[gridtype] : Grids[GRID_GENERIC];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617

  return (name);
}


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
618
619
    @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
620
621

@Description
622
The function @func{gridDefXname} defines the name of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
623
624
625

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
626
void gridDefXname(int gridID, const char *xname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
627
{
628
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
629

630
631
  if ( xname )
    {
632
      gridSetXname(gridptr, xname);
633
      gridMark4Update(gridID);
634
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
635
636
}

637

Uwe Schulzweida's avatar
Uwe Schulzweida committed
638
639
640
641
642
643
/*
@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
644
645
    @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
646
647

@Description
648
The function @func{gridDefXlongname} defines the longname of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
649
650
651

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
652
void gridDefXlongname(int gridID, const char *xlongname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
653
{
654
  grid_t *gridptr = gridID2Ptr(gridID);
655
656
  if ( xlongname )
    {
657
      gridSetXlongname(gridptr, xlongname);
658
      gridMark4Update(gridID);
659
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
660
661
662
663
664
665
666
667
}

/*
@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
668
669
    @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
670
671

@Description
672
The function @func{gridDefXunits} defines the units of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
673
674
675

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
676
void gridDefXunits(int gridID, const char *xunits)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
677
{
678
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
679

680
681
  if ( xunits )
    {
682
      gridSetXunits(gridptr, xunits);
683
      gridMark4Update(gridID);
684
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
685
686
687
688
689
690
691
692
}

/*
@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
693
694
    @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
695
696

@Description
697
The function @func{gridDefYname} defines the name of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
698
699
700

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
701
void gridDefYname(int gridID, const char *yname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
702
{
703
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
704

705
706
  if ( yname )
    {
707
      gridSetYname(gridptr, yname);
708
      gridMark4Update(gridID);
709
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
710
711
712
713
714
715
716
717
}

/*
@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
718
719
    @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
720
721

@Description
722
The function @func{gridDefYlongname} defines the longname of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
723
724
725

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
726
void gridDefYlongname(int gridID, const char *ylongname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
727
{
728
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
729

730
731
  if ( ylongname )
    {
732
      gridSetYlongname(gridptr, ylongname);
733
      gridMark4Update(gridID);
734
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
735
736
737
738
739
740
741
742
}

/*
@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
743
744
    @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
745
746

@Description
747
The function @func{gridDefYunits} defines the units of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
748
749
750

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
751
void gridDefYunits(int gridID, const char *yunits)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
752
{
753
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
754

755
756
  if ( yunits )
    {
757
      gridSetYunits(gridptr, yunits);
758
      gridMark4Update(gridID);
759
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
760
761
762
763
764
765
}

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

Deike Kleberg's avatar
Deike Kleberg committed
766
@Prototype void gridInqXname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
767
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
768
769
    @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
770
                    returned string. The maximum possible length, in characters, of
771
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
772
773

@Description
774
The function @func{gridInqXname} returns the name of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
775
776

@Result
777
@func{gridInqXname} returns the name of the X-axis to the parameter name.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
778
779
780
781
782

@EndFunction
*/
void gridInqXname(int gridID, char *xname)
{
783
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
784
785
786
787
788
789
790
791

  strcpy(xname, gridptr->xname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
792
@Prototype void gridInqXlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
793
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
794
795
    @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
796
                    returned string. The maximum possible length, in characters, of
797
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
798
799

@Description
800
The function @func{gridInqXlongname} returns the longname of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
801
802

@Result
803
@func{gridInqXlongname} returns the longname of the X-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
804
805
806
807
808

@EndFunction
*/
void gridInqXlongname(int gridID, char *xlongname)
{
809
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
810
811
812
813
814
815
816
817

  strcpy(xlongname, gridptr->xlongname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
818
@Prototype void gridInqXunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
819
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
820
821
    @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
822
                    returned string. The maximum possible length, in characters, of
823
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
824
825

@Description
826
The function @func{gridInqXunits} returns the units of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
827
828

@Result
829
@func{gridInqXunits} returns the units of the X-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
830
831
832
833
834

@EndFunction
*/
void gridInqXunits(int gridID, char *xunits)
{
835
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
836
837
838
839
840
841
842

  strcpy(xunits, gridptr->xunits);
}


void gridInqXstdname(int gridID, char *xstdname)
{
843
  grid_t *gridptr = gridID2Ptr(gridID);
844
845
846
847
  if ( gridptr->xstdname )
    strcpy(xstdname, gridptr->xstdname);
  else
    xstdname[0] = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
848
849
850
851
852
853
}

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

Deike Kleberg's avatar
Deike Kleberg committed
854
@Prototype void gridInqYname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
855
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
856
857
    @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
858
                    returned string. The maximum possible length, in characters, of
859
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
860
861

@Description
862
The function @func{gridInqYname} returns the name of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
863
864

@Result
865
@func{gridInqYname} returns the name of the Y-axis to the parameter name.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
866
867
868
869
870

@EndFunction
*/
void gridInqYname(int gridID, char *yname)
{
871
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
872
873
874
875
876
877
878
879

  strcpy(yname, gridptr->yname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
880
@Prototype void gridInqXlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
881
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
882
883
    @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
884
                    returned string. The maximum possible length, in characters, of
885
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
886
887

@Description
888
The function @func{gridInqYlongname} returns the longname of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
889
890

@Result
891
@func{gridInqYlongname} returns the longname of the Y-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
892
893
894
895
896

@EndFunction
*/
void gridInqYlongname(int gridID, char *ylongname)
{
897
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
898
899
900
901
902
903
904
905

  strcpy(ylongname, gridptr->ylongname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
906
@Prototype void gridInqYunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
907
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
908
909
    @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
910
                    returned string. The maximum possible length, in characters, of
911
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
912
913

@Description
914
The function @func{gridInqYunits} returns the units of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
915
916

@Result
917
@func{gridInqYunits} returns the units of the Y-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
918
919
920
921
922

@EndFunction
*/
void gridInqYunits(int gridID, char *yunits)
{
923
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
924
925
926
927
928
929

  strcpy(yunits, gridptr->yunits);
}

void gridInqYstdname(int gridID, char *ystdname)
{
930
  grid_t *gridptr = gridID2Ptr(gridID);
931
932
933
934
  if ( gridptr->ystdname )
    strcpy(ystdname, gridptr->ystdname);
  else
    ystdname[0] = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
935
936
937
938
939
940
941
942
}

/*
@Function  gridInqType
@Title     Get the type of a Grid

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

@Description
946
The function @func{gridInqType} returns the type of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
947
948

@Result
949
@func{gridInqType} returns the type of the grid,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
950
one of the set of predefined CDI grid types.
951
The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
952
@func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL}, @func{GRID_GME},
953
@func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
954
955
956
957
958

@EndFunction
*/
int gridInqType(int gridID)
{
959
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
960
961
962
963
964
965
966
967
968
969
970

  return (gridptr->type);
}


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

@Prototype int gridInqSize(int gridID)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
971
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
972
973

@Description
974
The function @func{gridInqSize} returns the size of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
975
976

@Result
977
@func{gridInqSize} returns the number of grid points of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
978
979
980
981
982

@EndFunction
*/
int gridInqSize(int gridID)
{
983
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
984

Uwe Schulzweida's avatar
Uwe Schulzweida committed
985
  int size = gridptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
986
987
988
989
990
991
992
993
994

  if ( ! size )
    {
      int xsize, ysize;

      xsize = gridptr->xsize;
      ysize = gridptr->ysize;

      if ( ysize )
995
        size = xsize * ysize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
996
      else
Thomas Jahns's avatar
Thomas Jahns committed
997
        size = xsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
998

Thomas Jahns's avatar
Thomas Jahns committed
999
      gridptr->size = size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1000
1001
1002
1003
1004
    }

  return (size);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1005
1006
static
int nsp2trunc(int nsp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1007
1008
1009
1010
1011
1012
1013
{
  /*  nsp = (trunc+1)*(trunc+1)              */
  /*      => trunc^2 + 3*trunc - (x-2) = 0   */
  /*                                         */
  /*  with:  y^2 + p*y + q = 0               */
  /*         y = -p/2 +- sqrt((p/2)^2 - q)   */
  /*         p = 3 and q = - (x-2)           */
1014
  int trunc = (int) (sqrt(nsp*4 + 1.) - 3) / 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1015
1016
1017
1018
1019
1020
  return (trunc);
}


int gridInqTrunc(int gridID)
{
1021
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1022
1023
1024
1025

  if ( gridptr->trunc == 0 )
    {
      if ( gridptr->type == GRID_SPECTRAL )
Thomas Jahns's avatar
Thomas Jahns committed
1026
        gridptr->trunc = nsp2trunc(gridptr->size);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1027
1028
      /*
      else if      ( gridptr->type == GRID_GAUSSIAN )
Thomas Jahns's avatar
Thomas Jahns committed
1029
        gridptr->trunc = nlat2trunc(gridptr->ysize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1030
1031
1032
1033
1034
1035
      */
    }

  return (gridptr->trunc);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1036

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1037
1038
void gridDefTrunc(int gridID, int trunc)
{
1039
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1040

1041
1042
  if (gridptr->trunc != trunc)
    {
1043
      gridMark4Update(gridID);
1044
1045
      gridptr->trunc = trunc;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1046
1047
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1048
1049
1050
1051
1052
1053
/*
@Function  gridDefXsize
@Title     Define the number of values of a X-axis

@Prototype void gridDefXsize(int gridID, int xsize)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
1054
1055
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
    @Item  xsize    Number of values of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1056
1057

@Description
1058
The function @func{gridDefXsize} defines the number of values of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1059
1060
1061

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1062
1063
void gridDefXsize(int gridID, int xsize)
{
1064
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1065

1066
1067
1068
  int gridSize = gridInqSize(gridID);
  if ( xsize > gridSize )
    Error("xsize %d is greater then gridsize %d", xsize, gridSize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1069

1070
1071
  int gridType = gridInqType(gridID);
  if ( gridType == GRID_UNSTRUCTURED && xsize != gridSize )
1072
    Error("xsize %d must be equal to gridsize %d for gridtype: UNSTRUCTURED", xsize, gridSize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1073

1074
1075
  if (gridptr->xsize != xsize)
    {
1076
      gridMark4Update(gridID);
1077
1078
      gridptr->xsize = xsize;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1079

1080
  if ( gridType != GRID_UNSTRUCTURED )
1081
    {
1082
1083
      long axisproduct = gridptr->xsize*gridptr->ysize;
      if ( axisproduct > 0 && axisproduct != gridSize )
1084
        Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
1085
              gridptr->xsize, gridptr->ysize, gridSize);
1086
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1087
1088
1089
}

/*
Thomas Jahns's avatar
Thomas Jahns committed
1090
1091
@Function
@Title
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1092

Thomas Jahns's avatar
Thomas Jahns committed
1093
@Prototype
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1094
1095
1096
1097
1098
1099
1100
@Parameter
    @Item  Grid identifier

@EndFunction
*/
void gridDefPrec(int gridID, int prec)
{
1101
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1102

1103
1104
  if (gridptr->prec != prec)
    {
1105
      gridMark4Update(gridID);
1106
1107
      gridptr->prec = prec;
    }