grid.c 119 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"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
13
#include "grid.h"
14
#include "gaussgrid.h"
15
#include "resource_handle.h"
16
#include "resource_unpack.h"
17
#include "namespace.h"
18
#include "serialize.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
19
20
21
22
23
24
25
26
27
28

#ifndef  RAD2DEG
#define  RAD2DEG  (180./M_PI)   /* conversion for rad to deg */
#endif

#ifndef  DEG2RAD
#define  DEG2RAD  (M_PI/180.)   /* conversion for deg to rad */
#endif


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


51
52
53
static int    gridCompareP    ( void * gridptr1, void * gridptr2 );
static void   gridDestroyP    ( void * gridptr );
static void   gridPrintP      ( void * gridptr, FILE * fp );
54
static int    gridGetPackSize ( void * gridptr, void *context);
55
static void   gridPack        ( void * gridptr, void * buff, int size,
56
				int *position, void *context);
Deike Kleberg's avatar
minimal    
Deike Kleberg committed
57
static int    gridTxCode      ( void );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
58

59
60
61
62
63
64
65
static const resOps gridOps = {
  gridCompareP,
  gridDestroyP,
  gridPrintP,
  gridGetPackSize,
  gridPack,
  gridTxCode
66
};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
67

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

70
#define gridID2Ptr(gridID) (grid_t *)reshGetVal(gridID, &gridOps)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
71

Deike Kleberg's avatar
Deike Kleberg committed
72
void grid_init(grid_t *gridptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
73
{
74
  gridptr->self         = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
75
  gridptr->type         = CDI_UNDEFID;
Deike Kleberg's avatar
Deike Kleberg committed
76
  gridptr->proj         = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
77
  gridptr->mask         = NULL;
78
  gridptr->mask_gme     = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
79
80
81
82
83
84
85
86
87
  gridptr->xvals        = NULL;
  gridptr->yvals        = NULL;
  gridptr->area         = NULL;
  gridptr->xbounds      = NULL;
  gridptr->ybounds      = NULL;
  gridptr->rowlon       = NULL;
  gridptr->nrowlon      = 0;
  gridptr->xinc         = 0.0;
  gridptr->yinc         = 0.0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
88
89
90
91
92
93
94
  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;
95
96
  gridptr->lcc_projflag = 0;
  gridptr->lcc_scanflag = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
97
  gridptr->lcc_defined  = FALSE;
98
99
100
101
102
103
  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;
104
105
106
107
  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
108
109
110
111
112
113
  gridptr->trunc        = 0;
  gridptr->nvertex      = 0;
  gridptr->nd           = 0;
  gridptr->ni           = 0;
  gridptr->ni2          = 0;
  gridptr->ni3          = 0;
114
115
116
  gridptr->number       = 0;
  gridptr->position     = 0;
  gridptr->reference    = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
117
118
119
120
  gridptr->prec         = 0;
  gridptr->size         = 0;
  gridptr->xsize        = 0;
  gridptr->ysize        = 0;
121
  gridptr->np           = 0;
122
123
  gridptr->xdef         = 0;
  gridptr->ydef         = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
124
  gridptr->isCyclic     = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
125
126
127
128
129
  gridptr->isRotated    = FALSE;
  gridptr->xpole        = 0.0;
  gridptr->ypole        = 0.0;
  gridptr->angle        = 0.0;
  gridptr->locked       = FALSE;
130
  gridptr->lcomplex     = 0;
131
  gridptr->hasdims      = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
132
133
134
135
136
137
138
139
  gridptr->xname[0]     = 0;
  gridptr->yname[0]     = 0;
  gridptr->xlongname[0] = 0;
  gridptr->ylongname[0] = 0;
  gridptr->xunits[0]    = 0;
  gridptr->yunits[0]    = 0;
  gridptr->xstdname[0]  = 0;
  gridptr->ystdname[0]  = 0;
Thomas Jahns's avatar
Thomas Jahns committed
140
  memset(gridptr->uuid, 0, CDI_UUID_SIZE);
Deike Kleberg's avatar
Deike Kleberg committed
141
  gridptr->name         = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
142
143
}

144

Deike Kleberg's avatar
Deike Kleberg committed
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
void grid_free(grid_t *gridptr)
{
  if ( gridptr->mask      ) free(gridptr->mask);
  if ( gridptr->mask_gme  ) free(gridptr->mask_gme);
  if ( gridptr->xvals     ) free(gridptr->xvals);
  if ( gridptr->yvals     ) free(gridptr->yvals);
  if ( gridptr->area      ) free(gridptr->area);
  if ( gridptr->xbounds   ) free(gridptr->xbounds);
  if ( gridptr->ybounds   ) free(gridptr->ybounds);
  if ( gridptr->rowlon    ) free(gridptr->rowlon);
  if ( gridptr->reference ) free(gridptr->reference);
  if ( gridptr->name      ) free(gridptr->name);

  grid_init(gridptr);
}

161
162
static grid_t *
gridNewEntry(cdiResH resH)
163
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
164
  grid_t *gridptr = (grid_t*) xmalloc(sizeof(grid_t));
165
166
167
168
169
170
171
172
  grid_init(gridptr);
  if (resH == CDI_UNDEFID)
    gridptr->self = reshPut(gridptr, &gridOps);
  else
    {
      gridptr->self = resH;
      reshReplace(resH, gridptr, &gridOps);
    }
173
  return gridptr;
174
175
}

176
static
177
void gridInit (void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
178
{
179
180
  static int gridInitialized = 0;
  char *env;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
181

182
  if ( gridInitialized ) return;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
183

Thomas Jahns's avatar
Thomas Jahns committed
184
  gridInitialized = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
185

186
187
  env = getenv("GRID_DEBUG");
  if ( env ) GRID_Debug = atoi(env);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
188
189
}

190
191
static
void grid_copy(grid_t *gridptr2, grid_t *gridptr1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
192
193
194
195
{
  int gridID2;

  gridID2 = gridptr2->self;
196
  memcpy(gridptr2, gridptr1, sizeof(grid_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
197
198
199
200
  gridptr2->self = gridID2;
}

int gridSize(void)
Thomas Jahns's avatar
Thomas Jahns committed
201
{
202
  return reshCountType ( &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
203
204
}

205
206
// used also in CDO
void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *xvals)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
207
{
208
  if ( (! (fabs(xinc) > 0)) && xsize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
209
210
    {
      if ( xfirst >= xlast )
Thomas Jahns's avatar
Thomas Jahns committed
211
212
213
214
        {
          while ( xfirst >= xlast ) xlast += 360;
          xinc = (xlast-xfirst)/(xsize);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
215
      else
Thomas Jahns's avatar
Thomas Jahns committed
216
217
218
        {
          xinc = (xlast-xfirst)/(xsize-1);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
219
220
    }

221
  for ( int i = 0; i < xsize; ++i )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
222
223
224
    xvals[i] = xfirst + i*xinc;
}

225
226
static
void calc_gaussgrid(double *yvals, int ysize, double yfirst, double ylast)
227
{
228
  double *yw = (double *)xmalloc((size_t)ysize * sizeof(double));
229
  gaussaw(yvals, yw, (size_t)ysize);
230
  free(yw);
231
  for (int i = 0; i < ysize; i++ )
232
233
234
235
    yvals[i] = asin(yvals[i])/M_PI*180.0;

  if ( yfirst < ylast && yfirst > -90.0 && ylast < 90.0 )
    {
236
237
      int yhsize = ysize/2;
      for (int i = 0; i < yhsize; i++ )
Thomas Jahns's avatar
Thomas Jahns committed
238
        {
239
          double ytmp = yvals[i];
Thomas Jahns's avatar
Thomas Jahns committed
240
241
242
          yvals[i] = yvals[ysize-i-1];
          yvals[ysize-i-1] = ytmp;
        }
243
244
245
    }
}

246
247
// used also in CDO
void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *yvals)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
248
{
249
  const double deleps = 0.002;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
250
251
252
253

  if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
    {
      if ( ysize > 2 )
Deike Kleberg's avatar
Deike Kleberg committed
254
255
256
257
258
259
260
261
262
263
264
265
266
267
	{
	  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 )
	      {
		double yinc = fabs(ylast-yfirst)/(ysize-1);
		double *ytmp = NULL;
		int nstart, lfound = 0;
		int ny = (int) (180./yinc + 0.5);
		ny -= ny%2;
		/* printf("%g %g %g %g %g %d\n", ylast, yfirst, ylast-yfirst,yinc, 180/yinc, ny); */
		if ( ny > ysize && ny < 4096 )
		  {
268
		    ytmp = (double *)xmalloc((size_t)ny * sizeof (double));
Deike Kleberg's avatar
Deike Kleberg committed
269
		    calc_gaussgrid(ytmp, ny, yfirst, ylast);
270
                    int i;
Deike Kleberg's avatar
Deike Kleberg committed
271
272
273
274
275
276
277
278
279
280
281
		    for ( i = 0; i < (ny-ysize); i++ )
		      if ( fabs(ytmp[i] - yfirst) < deleps ) break;

		    nstart = i;

		    if ( (nstart+ysize-1) < ny )
		      if ( fabs(ytmp[nstart+ysize-1] - ylast) < deleps ) lfound = 1;
		  }

		if ( lfound )
		  {
282
		    for (int i = 0; i < ysize; i++) yvals[i] = ytmp[i+nstart];
Deike Kleberg's avatar
Deike Kleberg committed
283
284
285
286
		  }
		else
		  {
		    Warning("Cannot calculate gaussian latitudes for lat1 = %g latn = %g!", yfirst, ylast);
287
		    for (int i = 0; i < ysize; i++ ) yvals[i] = 0;
Deike Kleberg's avatar
Deike Kleberg committed
288
289
290
291
292
293
294
		    yvals[0] = yfirst;
		    yvals[ysize-1] = ylast;
		  }

		if ( ytmp ) free(ytmp);
	      }
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
295
      else
Thomas Jahns's avatar
Thomas Jahns committed
296
297
298
299
        {
          yvals[0] = yfirst;
          yvals[ysize-1] = ylast;
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
300
301
302
303
    }
  /*     else if ( gridtype == GRID_LONLAT || gridtype == GRID_GENERIC ) */
  else
    {
304
      if ( (! (fabs(yinc) > 0)) && ysize > 1 )
Thomas Jahns's avatar
Thomas Jahns committed
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
        {
          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
326
327
328

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

329
      for (int i = 0; i < ysize; i++ )
Thomas Jahns's avatar
Thomas Jahns committed
330
        yvals[i] = yfirst + i*yinc;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
331
332
333
    }
  /*
    else
334
    Error("unable to calculate values for %s grid!", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
335
336
337
338
  */
}

/*
339
@Function  gridCreate
340
@Title     Create a horizontal Grid
Uwe Schulzweida's avatar
Uwe Schulzweida committed
341

342
@Prototype int gridCreate(int gridtype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
343
344
@Parameter
    @Item  gridtype  The type of the grid, one of the set of predefined CDI grid types.
345
                     The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
346
                     @func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL},
347
                     @func{GRID_GME}, @func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED} and.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
348
349
350
    @Item  size      Number of gridpoints.

@Description
351
The function @func{gridCreate} creates a horizontal Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
352
353

@Result
354
@func{gridCreate} returns an identifier to the Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
355
356

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

@Source
Uwe Schulzweida's avatar
Uwe Schulzweida committed
360
361
#include "cdi.h"
   ...
362
363
#define  nlon  12
#define  nlat   6
Uwe Schulzweida's avatar
Uwe Schulzweida committed
364
   ...
365
366
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
367
368
int gridID;
   ...
369
370
371
gridID = gridCreate(GRID_LONLAT, nlon*nlat);
gridDefXsize(gridID, nlon);
gridDefYsize(gridID, nlat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
372
373
374
375
gridDefXvals(gridID, lons);
gridDefYvals(gridID, lats);
   ...
@EndSource
Uwe Schulzweida's avatar
Uwe Schulzweida committed
376
377
@EndFunction
*/
378
int gridCreate(int gridtype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
379
{
380
  if ( CDI_Debug ) Message("gridtype=%s  size=%d", gridNamePtr(gridtype), size);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
381

382
  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
383

384
  gridInit();
385

Uwe Schulzweida's avatar
Uwe Schulzweida committed
386
  grid_t *gridptr = gridNewEntry(CDI_UNDEFID);
387
  if ( ! gridptr ) Error("No memory");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
388

Uwe Schulzweida's avatar
Uwe Schulzweida committed
389
  int gridID = gridptr->self;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
390

391
  if ( CDI_Debug ) Message("gridID: %d", gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
392
393
394
395
396

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

  /*  if ( gridtype == GRID_GENERIC )     gridptr->xsize = size; */
397
398
  if ( gridtype == GRID_UNSTRUCTURED )  gridptr->xsize = size;
  if ( gridtype == GRID_CURVILINEAR  )  gridptr->nvertex = 4;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
399
400
401
402
403
404
405
406
407

  switch (gridtype)
    {
    case GRID_LONLAT:
    case GRID_GAUSSIAN:
    case GRID_GAUSSIAN_REDUCED:
    case GRID_CURVILINEAR:
    case GRID_TRAJECTORY:
      {
Thomas Jahns's avatar
Thomas Jahns committed
408
409
410
411
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
        if ( gridtype == GRID_TRAJECTORY )
          {
            gridDefXname(gridID, "tlon");
            gridDefYname(gridID, "tlat");
          }
        else
          {
            gridDefXname(gridID, "lon");
            gridDefYname(gridID, "lat");
          }
        gridDefXlongname(gridID, "longitude");
        gridDefYlongname(gridID, "latitude");

        /*
        if ( gridtype == GRID_CURVILINEAR )
          {
            strcpy(gridptr->xstdname, "grid_longitude");
            strcpy(gridptr->ystdname, "grid_latitude");
            gridDefXunits(gridID, "degrees");
            gridDefYunits(gridID, "degrees");
          }
        else
        */
          {
            strcpy(gridptr->xstdname, "longitude");
            strcpy(gridptr->ystdname, "latitude");
            gridDefXunits(gridID, "degrees_east");
            gridDefYunits(gridID, "degrees_north");
          }

        break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
439
440
      }
    case GRID_GME:
441
    case GRID_UNSTRUCTURED:
442
      {
Thomas Jahns's avatar
Thomas Jahns committed
443
444
445
446
447
448
449
        gridDefXname(gridID, "lon");
        gridDefYname(gridID, "lat");
        strcpy(gridptr->xstdname, "longitude");
        strcpy(gridptr->ystdname, "latitude");
        gridDefXunits(gridID, "degrees_east");
        gridDefYunits(gridID, "degrees_north");
        break;
450
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
451
452
    case GRID_GENERIC:
      {
Thomas Jahns's avatar
Thomas Jahns committed
453
454
        gridDefXname(gridID, "x");
        gridDefYname(gridID, "y");
455
        /*
Thomas Jahns's avatar
Thomas Jahns committed
456
457
458
459
        strcpy(gridptr->xstdname, "grid_longitude");
        strcpy(gridptr->ystdname, "grid_latitude");
        gridDefXunits(gridID, "degrees");
        gridDefYunits(gridID, "degrees");
460
        */
Thomas Jahns's avatar
Thomas Jahns committed
461
        break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
462
      }
463
    case GRID_LCC2:
464
    case GRID_SINUSOIDAL:
465
    case GRID_LAEA:
466
      {
Thomas Jahns's avatar
Thomas Jahns committed
467
468
469
470
471
472
473
        gridDefXname(gridID, "x");
        gridDefYname(gridID, "y");
        strcpy(gridptr->xstdname, "projection_x_coordinate");
        strcpy(gridptr->ystdname, "projection_y_coordinate");
        gridDefXunits(gridID, "m");
        gridDefYunits(gridID, "m");
        break;
474
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
475
476
477
478
479
    }

  return (gridID);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
480
481
static
void gridDestroyKernel( grid_t * gridptr )
482
483
484
{
  int id;

Deike Kleberg's avatar
Deike Kleberg committed
485
  xassert ( gridptr );
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500

  id = gridptr->self;

  if ( gridptr->mask      ) free(gridptr->mask);
  if ( gridptr->mask_gme  ) free(gridptr->mask_gme);
  if ( gridptr->xvals     ) free(gridptr->xvals);
  if ( gridptr->yvals     ) free(gridptr->yvals);
  if ( gridptr->area      ) free(gridptr->area);
  if ( gridptr->xbounds   ) free(gridptr->xbounds);
  if ( gridptr->ybounds   ) free(gridptr->ybounds);
  if ( gridptr->rowlon    ) free(gridptr->rowlon);
  if ( gridptr->reference ) free(gridptr->reference);

  free ( gridptr );

501
  reshRemove ( id, &gridOps );
502
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
503

504
505
506
507
508
509
/*
@Function  gridDestroy
@Title     Destroy a horizontal Grid

@Prototype void gridDestroy(int gridID)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
510
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
511
512
513
514
515

@EndFunction
*/
void gridDestroy(int gridID)
{
516
  grid_t *gridptr = gridID2Ptr(gridID);
517

518
  gridDestroyKernel ( gridptr );
519
520
}

521
void gridDestroyP ( void * gridptr )
522
{
523
  gridDestroyKernel (( grid_t * ) gridptr );
524
525
526
}


527
const char *gridNamePtr(int gridtype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
528
{
529
  const char *name;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
530
  int size = (int) (sizeof(Grids)/sizeof(char *));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
531

Thomas Jahns's avatar
Thomas Jahns committed
532
  name = gridtype >= 0 && gridtype < size ? Grids[gridtype] : Grids[GRID_GENERIC];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548

  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
549
550
    @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
551
552

@Description
553
The function @func{gridDefXname} defines the name of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
554
555
556

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
557
void gridDefXname(int gridID, const char *xname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
558
{
559
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
560

561
562
  if ( xname )
    {
563
564
      strncpy(gridptr->xname, xname, CDI_MAX_NAME);
      gridptr->xname[CDI_MAX_NAME - 1] = 0;
565
566
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
567
568
569
570
571
572
573
574
}

/*
@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
575
576
    @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
577
578

@Description
579
The function @func{gridDefXlongname} defines the longname of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
580
581
582

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
583
void gridDefXlongname(int gridID, const char *xlongname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
584
{
585
  grid_t *gridptr = gridID2Ptr(gridID);
586
587
  if ( xlongname )
    {
588
589
      strncpy(gridptr->xlongname, xlongname, CDI_MAX_NAME);
      gridptr->xlongname[CDI_MAX_NAME - 1] = 0;
590
591
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
592
593
594
595
596
597
598
599
}

/*
@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
600
601
    @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
602
603

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

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
608
void gridDefXunits(int gridID, const char *xunits)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
609
{
610
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
611

612
613
  if ( xunits )
    {
614
615
      strncpy(gridptr->xunits, xunits, CDI_MAX_NAME);
      gridptr->xunits[CDI_MAX_NAME - 1] = 0;
616
617
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
618
619
620
621
622
623
624
625
}

/*
@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
626
627
    @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
628
629

@Description
630
The function @func{gridDefYname} defines the name of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
631
632
633

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
634
void gridDefYname(int gridID, const char *yname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
635
{
636
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
637

638
639
  if ( yname )
    {
640
641
      strncpy(gridptr->yname, yname, CDI_MAX_NAME);
      gridptr->yname[CDI_MAX_NAME - 1] = 0;
642
643
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
644
645
646
647
648
649
650
651
}

/*
@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
652
653
    @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
654
655

@Description
656
The function @func{gridDefYlongname} defines the longname of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
657
658
659

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
660
void gridDefYlongname(int gridID, const char *ylongname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
661
{
662
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
663

664
665
  if ( ylongname )
    {
666
667
      strncpy(gridptr->ylongname, ylongname, CDI_MAX_NAME);
      gridptr->ylongname[CDI_MAX_NAME - 1] = 0;
668
669
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
670
671
672
673
674
675
676
677
}

/*
@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
678
679
    @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
680
681

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

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
686
void gridDefYunits(int gridID, const char *yunits)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
687
{
688
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
689

690
691
  if ( yunits )
    {
692
693
      strncpy(gridptr->yunits, yunits, CDI_MAX_NAME);
      gridptr->yunits[CDI_MAX_NAME - 1] = 0;
694
695
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
696
697
698
699
700
701
}

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

Deike Kleberg's avatar
Deike Kleberg committed
702
@Prototype void gridInqXname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
703
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
704
705
    @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
706
                    returned string. The maximum possible length, in characters, of
707
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
708
709

@Description
710
The function @func{gridInqXname} returns the name of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
711
712

@Result
713
@func{gridInqXname} returns the name of the X-axis to the parameter name.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
714
715
716
717
718

@EndFunction
*/
void gridInqXname(int gridID, char *xname)
{
719
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
720
721
722
723
724
725
726
727

  strcpy(xname, gridptr->xname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
728
@Prototype void gridInqXlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
729
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
730
731
    @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
732
                    returned string. The maximum possible length, in characters, of
733
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
734
735

@Description
736
The function @func{gridInqXlongname} returns the longname of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
737
738

@Result
739
@func{gridInqXlongname} returns the longname of the X-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
740
741
742
743
744

@EndFunction
*/
void gridInqXlongname(int gridID, char *xlongname)
{
745
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
746
747
748
749
750
751
752
753

  strcpy(xlongname, gridptr->xlongname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
754
@Prototype void gridInqXunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
755
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
756
757
    @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
758
                    returned string. The maximum possible length, in characters, of
759
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
760
761

@Description
762
The function @func{gridInqXunits} returns the units of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
763
764

@Result
765
@func{gridInqXunits} returns the units of the X-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
766
767
768
769
770

@EndFunction
*/
void gridInqXunits(int gridID, char *xunits)
{
771
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
772
773
774
775
776
777
778

  strcpy(xunits, gridptr->xunits);
}


void gridInqXstdname(int gridID, char *xstdname)
{
779
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
780
781
782
783
784
785
786
787

  strcpy(xstdname, gridptr->xstdname);
}

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

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

@Description
796
The function @func{gridInqYname} returns the name of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
797
798

@Result
799
@func{gridInqYname} returns the name of the Y-axis to the parameter name.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
800
801
802
803
804

@EndFunction
*/
void gridInqYname(int gridID, char *yname)
{
805
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
806
807
808
809
810
811
812
813

  strcpy(yname, gridptr->yname);
}

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

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

@Description
822
The function @func{gridInqYlongname} returns the longname of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
823
824

@Result
825
@func{gridInqYlongname} returns the longname of the Y-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
826
827
828
829
830

@EndFunction
*/
void gridInqYlongname(int gridID, char *ylongname)
{
831
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
832
833
834
835
836
837
838
839

  strcpy(ylongname, gridptr->ylongname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
840
@Prototype void gridInqYunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
841
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
842
843
    @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
844
                    returned string. The maximum possible length, in characters, of
845
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
846
847

@Description
848
The function @func{gridInqYunits} returns the units of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849
850

@Result
851
@func{gridInqYunits} returns the units of the Y-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
852
853
854
855
856

@EndFunction
*/
void gridInqYunits(int gridID, char *yunits)
{
857
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
858
859
860
861
862
863

  strcpy(yunits, gridptr->yunits);
}

void gridInqYstdname(int gridID, char *ystdname)
{
864
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
865
866
867
868
869
870
871
872
873
874

  strcpy(ystdname, gridptr->ystdname);
}

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

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

@Description
878
The function @func{gridInqType} returns the type of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
879
880

@Result
881
@func{gridInqType} returns the type of the grid,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
882
one of the set of predefined CDI grid types.
883
The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
884
@func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL}, @func{GRID_GME},
885
@func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
886
887
888
889
890

@EndFunction
*/
int gridInqType(int gridID)
{
891
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
892
893
894
895
896
897
898
899
900
901
902

  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
903
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
904
905

@Description
906
The function @func{gridInqSize} returns the size of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
907
908

@Result
909
@func{gridInqSize} returns the number of grid points of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
910
911
912
913
914

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
917
  int size = gridptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
918
919
920
921
922
923
924
925
926

  if ( ! size )
    {
      int xsize, ysize;

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

      if ( ysize )
Thomas Jahns's avatar
Thomas Jahns committed
927
        size = xsize *ysize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
928
      else
Thomas Jahns's avatar
Thomas Jahns committed
929
        size = xsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
930

Thomas Jahns's avatar
Thomas Jahns committed
931
      gridptr->size = size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
932
933
934
935
936
    }

  return (size);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
937
938
static
int nsp2trunc(int nsp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
939
940
941
942
943
944
945
{
  /*  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)           */
946
  int trunc = (int) (sqrt(nsp*4 + 1.) - 3) / 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
947
948
949
950
951
952
  return (trunc);
}


int gridInqTrunc(int gridID)
{
953
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
954
955
956
957

  if ( gridptr->trunc == 0 )
    {
      if ( gridptr->type == GRID_SPECTRAL )
Thomas Jahns's avatar
Thomas Jahns committed
958
        gridptr->trunc = nsp2trunc(gridptr->size);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
959
960
      /*
      else if      ( gridptr->type == GRID_GAUSSIAN )
Thomas Jahns's avatar
Thomas Jahns committed
961
        gridptr->trunc = nlat2trunc(gridptr->ysize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
962
963
964
965
966
967
      */
    }

  return (gridptr->trunc);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
968

Uwe Schulzweida's avatar
Uwe Schulzweida committed
969
970
void gridDefTrunc(int gridID, int trunc)
{
971
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
972

973
974
975
976
977
  if (gridptr->trunc != trunc)
    {
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
      gridptr->trunc = trunc;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
978
979
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
980
981
982
983
984
985
/*
@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
986
987
    @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
988
989

@Description
990
The function @func{gridDefXsize} defines the number of values of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
991
992
993

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
994
995
void gridDefXsize(int gridID, int xsize)
{
996
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
997
998

  if ( xsize > gridInqSize(gridID) )
999
    Error("xsize %d is greater then gridsize %d", xsize, gridInqSize(gridID));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1000

1001
  if ( gridInqType(gridID) == GRID_UNSTRUCTURED && xsize != gridInqSize(gridID) )
1002
    Error("xsize %d must be equal to gridsize %d for gridtype: UNSTRUCTURED", xsize, gridInqSize(gridID));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1003

1004
1005
1006
1007
1008
  if (gridptr->xsize != xsize)
    {
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
      gridptr->xsize = xsize;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1009

1010
1011
1012
1013
1014
1015
1016
  if ( gridInqType(gridID) != GRID_UNSTRUCTURED )
    {
      long gridsize = gridptr->xsize*gridptr->ysize;
      if ( gridsize > 0 && gridsize != gridInqSize(gridID) )
        Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
              gridptr->xsize, gridptr->ysize, gridInqSize(gridID));
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1017
1018
1019
}

/*
Thomas Jahns's avatar
Thomas Jahns committed
1020
1021
@Function
@Title
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1022

Thomas Jahns's avatar
Thomas Jahns committed
1023
@Prototype
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1024
1025
1026
1027
1028
1029
1030
@Parameter
    @Item  Grid identifier

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

1033
1034
1035
1036
1037
  if (gridptr->prec != prec)
    {
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
      gridptr->prec = prec;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1038
1039
1040
}

/*
Thomas Jahns's avatar
Thomas Jahns committed
1041
1042
@Function
@Title
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1043

Thomas Jahns's avatar
Thomas Jahns committed
1044
@Prototype
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1045
1046
1047
1048
1049
1050
1051
@Parameter
    @Item  Grid identifier

@EndFunction
*/
int gridInqPrec(int gridID)
{
1052
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1053
1054
1055
1056
1057

  return (gridptr->prec);
}

/*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1058
1059
@Function  gridInqXsize
@Title     Get the number of values of a X-axis
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1060

1061
@Prototype int gridInqXsize(int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1062
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1063
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1064
1065

@Description
1066
The function @func{gridInqXsize} returns the number of values of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1067
1068

@Result
1069
@func{gridInqXsize} returns the number of values of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1070
1071
1072
1073
1074

@EndFunction
*/
int gridInqXsize(int gridID)
{
1075
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1076
1077
1078
1079
1080

  return (gridptr->xsize);
}

/*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1081
1082
@Function  gridDefYsize
@Title     Define the number of values of a Y-axis
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1083

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1084
@Prototype void gridDefYsize(int gridID, int ysize)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1085
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
1086
1087
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
    @Item  ysize    Number of values of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1088
1089

@Description
1090
The function @func{gridDefYsize} defines the number of values of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1091
1092
1093
1094
1095

@EndFunction
*/
void gridDefYsize(int gridID, int ysize)
{
1096
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1097
1098

  if ( ysize > gridInqSize(gridID) )
1099
    Error("ysize %d is greater then gridsize %d", ysize, gridInqSize(gridID));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1100

1101
  if ( gridInqType(gridID) == GRID_UNSTRUCTURED && ysize != gridInqSize(gridID) )
1102
    Error("ysize %d must be equal gridsize %d for gridtype: UNSTRUCTURED", ysize, gridInqSize(gridID));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1103

1104
1105
1106
1107
1108
  if (gridptr->ysize != ysize)
    {
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
      gridptr->ysize = ysize;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1109

1110
1111
1112
1113
1114
1115
1116
  if ( gridInqType(gridID) != GRID_UNSTRUCTURED )
    {
      long gridsize = gridptr->xsize*gridptr->ysize;
      if ( gridsize > 0 && gridsize != gridInqSize(gridID) )
        Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
              gridptr->xsize, gridptr->ysize, gridInqSize(gridID));
    }