grid.c 125 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


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

143

Deike Kleberg's avatar
Deike Kleberg committed
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
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);
}

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

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

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

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

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

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

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

199
static
200
void gridCheckPtr(const char *caller, int gridID, grid_t *gridptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
201
202
{
  if ( gridptr == NULL )
203
    Errorc("grid %d undefined!", gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
204
205
}

206
#define  grid_check_ptr(gridID, gridptr)  gridCheckPtr(__func__, gridID, gridptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
207

Uwe Schulzweida's avatar
Uwe Schulzweida committed
208

Uwe Schulzweida's avatar
Uwe Schulzweida committed
209
int gridSize(void)
Thomas Jahns's avatar
Thomas Jahns committed
210
{
211
  return reshCountType ( &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
212
213
214
215
216
}


void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *xvals)
{
217
  if ( (! (fabs(xinc) > 0)) && xsize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
218
219
    {
      if ( xfirst >= xlast )
Thomas Jahns's avatar
Thomas Jahns committed
220
221
222
223
        {
          while ( xfirst >= xlast ) xlast += 360;
          xinc = (xlast-xfirst)/(xsize);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
224
      else
Thomas Jahns's avatar
Thomas Jahns committed
225
226
227
        {
          xinc = (xlast-xfirst)/(xsize-1);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
228
229
    }

230
  for ( int i = 0; i < xsize; ++i )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
231
232
233
    xvals[i] = xfirst + i*xinc;
}

234
235
static
void calc_gaussgrid(double *yvals, int ysize, double yfirst, double ylast)
236
{
237
  double *yw = (double *)xmalloc((size_t)ysize * sizeof(double));
238
239
  gaussaw(yvals, yw, ysize);
  free(yw);
240
  for (int i = 0; i < ysize; i++ )
241
242
243
244
    yvals[i] = asin(yvals[i])/M_PI*180.0;

  if ( yfirst < ylast && yfirst > -90.0 && ylast < 90.0 )
    {
245
246
      int yhsize = ysize/2;
      for (int i = 0; i < yhsize; i++ )
Thomas Jahns's avatar
Thomas Jahns committed
247
        {
248
          double ytmp = yvals[i];
Thomas Jahns's avatar
Thomas Jahns committed
249
250
251
          yvals[i] = yvals[ysize-i-1];
          yvals[ysize-i-1] = ytmp;
        }
252
253
254
255
    }
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
256
257
void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *yvals)
{
Deike Kleberg's avatar
Deike Kleberg committed
258
  double deleps = 0.002;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
259
260
261
262

  if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
    {
      if ( ysize > 2 )
Deike Kleberg's avatar
Deike Kleberg committed
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
	{
	  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 )
		  {
		    ytmp = (double *) malloc(ny*sizeof(double));
		    calc_gaussgrid(ytmp, ny, yfirst, ylast);
279
                    int i;
Deike Kleberg's avatar
Deike Kleberg committed
280
281
282
283
284
285
286
287
288
289
290
		    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 )
		  {
291
		    for (int i = 0; i < ysize; i++) yvals[i] = ytmp[i+nstart];
Deike Kleberg's avatar
Deike Kleberg committed
292
293
294
295
		  }
		else
		  {
		    Warning("Cannot calculate gaussian latitudes for lat1 = %g latn = %g!", yfirst, ylast);
296
		    for (int i = 0; i < ysize; i++ ) yvals[i] = 0;
Deike Kleberg's avatar
Deike Kleberg committed
297
298
299
300
301
302
303
		    yvals[0] = yfirst;
		    yvals[ysize-1] = ylast;
		  }

		if ( ytmp ) free(ytmp);
	      }
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
304
      else
Thomas Jahns's avatar
Thomas Jahns committed
305
306
307
308
        {
          yvals[0] = yfirst;
          yvals[ysize-1] = ylast;
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
309
310
311
312
    }
  /*     else if ( gridtype == GRID_LONLAT || gridtype == GRID_GENERIC ) */
  else
    {
313
      if ( (! (fabs(yinc) > 0)) && ysize > 1 )
Thomas Jahns's avatar
Thomas Jahns committed
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
        {
          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
335
336
337

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

338
      for (int i = 0; i < ysize; i++ )
Thomas Jahns's avatar
Thomas Jahns committed
339
        yvals[i] = yfirst + i*yinc;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
340
341
342
    }
  /*
    else
343
    Error("unable to calculate values for %s grid!", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
344
345
346
347
  */
}

/*
348
@Function  gridCreate
349
@Title     Create a horizontal Grid
Uwe Schulzweida's avatar
Uwe Schulzweida committed
350

351
@Prototype int gridCreate(int gridtype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
352
353
@Parameter
    @Item  gridtype  The type of the grid, one of the set of predefined CDI grid types.
354
                     The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
355
                     @func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL},
356
                     @func{GRID_GME}, @func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED} and.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
357
358
359
    @Item  size      Number of gridpoints.

@Description
360
The function @func{gridCreate} creates a horizontal Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
361
362

@Result
363
@func{gridCreate} returns an identifier to the Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
364
365

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

@Source
Uwe Schulzweida's avatar
Uwe Schulzweida committed
369
370
#include "cdi.h"
   ...
371
372
#define  nlon  12
#define  nlat   6
Uwe Schulzweida's avatar
Uwe Schulzweida committed
373
   ...
374
375
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
376
377
int gridID;
   ...
378
379
380
gridID = gridCreate(GRID_LONLAT, nlon*nlat);
gridDefXsize(gridID, nlon);
gridDefYsize(gridID, nlat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
381
382
383
384
gridDefXvals(gridID, lons);
gridDefYvals(gridID, lats);
   ...
@EndSource
Uwe Schulzweida's avatar
Uwe Schulzweida committed
385
386
@EndFunction
*/
387
int gridCreate(int gridtype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
388
{
389
  if ( CDI_Debug ) Message("gridtype=%s  size=%d", gridNamePtr(gridtype), size);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
390

391
  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
392

393
  gridInit();
394

Uwe Schulzweida's avatar
Uwe Schulzweida committed
395
  grid_t *gridptr = gridNewEntry(CDI_UNDEFID);
396
  if ( ! gridptr ) Error("No memory");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
397

Uwe Schulzweida's avatar
Uwe Schulzweida committed
398
  int gridID = gridptr->self;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
399

400
  if ( CDI_Debug ) Message("gridID: %d", gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
401
402
403
404
405

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

  /*  if ( gridtype == GRID_GENERIC )     gridptr->xsize = size; */
406
407
  if ( gridtype == GRID_UNSTRUCTURED )  gridptr->xsize = size;
  if ( gridtype == GRID_CURVILINEAR  )  gridptr->nvertex = 4;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
408
409
410
411
412
413
414
415
416

  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
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
        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
448
449
      }
    case GRID_GME:
450
    case GRID_UNSTRUCTURED:
451
      {
Thomas Jahns's avatar
Thomas Jahns committed
452
453
454
455
456
457
458
        gridDefXname(gridID, "lon");
        gridDefYname(gridID, "lat");
        strcpy(gridptr->xstdname, "longitude");
        strcpy(gridptr->ystdname, "latitude");
        gridDefXunits(gridID, "degrees_east");
        gridDefYunits(gridID, "degrees_north");
        break;
459
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
460
461
    case GRID_GENERIC:
      {
Thomas Jahns's avatar
Thomas Jahns committed
462
463
        gridDefXname(gridID, "x");
        gridDefYname(gridID, "y");
464
        /*
Thomas Jahns's avatar
Thomas Jahns committed
465
466
467
468
        strcpy(gridptr->xstdname, "grid_longitude");
        strcpy(gridptr->ystdname, "grid_latitude");
        gridDefXunits(gridID, "degrees");
        gridDefYunits(gridID, "degrees");
469
        */
Thomas Jahns's avatar
Thomas Jahns committed
470
        break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
471
      }
472
    case GRID_LCC2:
473
    case GRID_SINUSOIDAL:
474
    case GRID_LAEA:
475
      {
Thomas Jahns's avatar
Thomas Jahns committed
476
477
478
479
480
481
482
        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;
483
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
484
485
486
487
488
    }

  return (gridID);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
489
490
static
void gridDestroyKernel( grid_t * gridptr )
491
492
493
{
  int id;

Deike Kleberg's avatar
Deike Kleberg committed
494
  xassert ( gridptr );
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509

  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 );

510
  reshRemove ( id, &gridOps );
511
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
512

513
514
515
516
517
518
/*
@Function  gridDestroy
@Title     Destroy a horizontal Grid

@Prototype void gridDestroy(int gridID)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
519
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
520
521
522
523
524

@EndFunction
*/
void gridDestroy(int gridID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
525
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
526

527
  gridDestroyKernel ( gridptr );
528
529
}

530
void gridDestroyP ( void * gridptr )
531
{
532
  gridDestroyKernel (( grid_t * ) gridptr );
533
534
535
}


536
const char *gridNamePtr(int gridtype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
537
{
538
  const char *name;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
539
  int size = (int) (sizeof(Grids)/sizeof(char *));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560

  if ( gridtype >= 0 && gridtype < size )
    name = Grids[gridtype];
  else
    name = Grids[GRID_GENERIC];

  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
561
562
    @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
563
564

@Description
565
The function @func{gridDefXname} defines the name of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
566
567
568

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
569
void gridDefXname(int gridID, const char *xname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
570
{
571
  grid_t *gridptr = (grid_t *)reshGetVal(gridID, &gridOps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
572

573
574
  grid_check_ptr(gridID, gridptr);

575
576
577
578
579
  if ( xname )
    {
      strcpy(gridptr->xname, xname);
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
580
581
582
583
584
585
586
587
}

/*
@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
588
589
    @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
590
591

@Description
592
The function @func{gridDefXlongname} defines the longname of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
593
594
595

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
596
void gridDefXlongname(int gridID, const char *xlongname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
597
{
598
599
  grid_t *gridptr = (grid_t *)reshGetVal(gridID, &gridOps);
  grid_check_ptr(gridID, gridptr);
600

601
602
603
604
605
  if ( xlongname )
    {
      strcpy(gridptr->xlongname, xlongname);
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
606
607
608
609
610
611
612
613
}

/*
@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
614
615
    @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
616
617

@Description
618
The function @func{gridDefXunits} defines the units of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
619
620
621

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
622
void gridDefXunits(int gridID, const char *xunits)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
623
{
624
  grid_t *gridptr = (grid_t *)reshGetVal(gridID, &gridOps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
625

626
627
  grid_check_ptr(gridID, gridptr);

628
629
630
631
632
  if ( xunits )
    {
      strcpy(gridptr->xunits, xunits);
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
633
634
635
636
637
638
639
640
}

/*
@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
641
642
    @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
643
644

@Description
645
The function @func{gridDefYname} defines the name of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
646
647
648

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
649
void gridDefYname(int gridID, const char *yname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
650
{
651
  grid_t *gridptr = (grid_t *)reshGetVal(gridID, &gridOps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
652

653
654
  grid_check_ptr(gridID, gridptr);

655
656
657
658
659
  if ( yname )
    {
      strcpy(gridptr->yname, yname);
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
660
661
662
663
664
665
666
667
}

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

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

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
676
void gridDefYlongname(int gridID, const char *ylongname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
677
{
678
  grid_t *gridptr = (grid_t *)reshGetVal(gridID, &gridOps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
679

680
681
  grid_check_ptr(gridID, gridptr);

682
683
684
685
686
  if ( ylongname )
    {
      strcpy(gridptr->ylongname, ylongname);
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
687
688
689
690
691
692
693
694
}

/*
@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
695
696
    @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
697
698

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

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
703
void gridDefYunits(int gridID, const char *yunits)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
704
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
705
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
706

707
708
  grid_check_ptr(gridID, gridptr);

709
710
711
712
713
  if ( yunits )
    {
      strcpy(gridptr->yunits, yunits);
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
714
715
716
717
718
719
}

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

Deike Kleberg's avatar
Deike Kleberg committed
720
@Prototype void gridInqXname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
721
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
722
723
    @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
724
                    returned string. The maximum possible length, in characters, of
725
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
726
727

@Description
728
The function @func{gridInqXname} returns the name of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
729
730

@Result
731
@func{gridInqXname} returns the name of the X-axis to the parameter name.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
732
733
734
735
736

@EndFunction
*/
void gridInqXname(int gridID, char *xname)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
737
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
738

739
740
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
741
742
743
744
745
746
747
  strcpy(xname, gridptr->xname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
748
@Prototype void gridInqXlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
749
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
750
751
    @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
752
                    returned string. The maximum possible length, in characters, of
753
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
755

@Description
756
The function @func{gridInqXlongname} returns the longname of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
757
758

@Result
759
@func{gridInqXlongname} returns the longname of the X-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
760
761
762
763
764

@EndFunction
*/
void gridInqXlongname(int gridID, char *xlongname)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
765
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
766

767
768
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
769
770
771
772
773
774
775
  strcpy(xlongname, gridptr->xlongname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
776
@Prototype void gridInqXunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
777
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
778
779
    @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
780
                    returned string. The maximum possible length, in characters, of
781
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
782
783

@Description
784
The function @func{gridInqXunits} returns the units of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
785
786

@Result
787
@func{gridInqXunits} returns the units of the X-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
788
789
790
791
792

@EndFunction
*/
void gridInqXunits(int gridID, char *xunits)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
793
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
794

795
796
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
797
798
799
800
801
802
  strcpy(xunits, gridptr->xunits);
}


void gridInqXstdname(int gridID, char *xstdname)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
803
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
804

805
806
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
807
808
809
810
811
812
813
  strcpy(xstdname, gridptr->xstdname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
814
@Prototype void gridInqYname(int gridID, char *name)
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  name     Name 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{gridInqYname} returns the name of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
823
824

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

@EndFunction
*/
void gridInqYname(int gridID, char *yname)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
831
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
832

833
834
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
835
836
837
838
839
840
841
  strcpy(yname, gridptr->yname);
}

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

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

@Description
850
The function @func{gridInqYlongname} returns the longname of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
851
852

@Result
853
@func{gridInqYlongname} returns the longname of the Y-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
854
855
856
857
858

@EndFunction
*/
void gridInqYlongname(int gridID, char *ylongname)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
859
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
860

861
862
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
863
864
865
866
867
868
869
  strcpy(ylongname, gridptr->ylongname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
870
@Prototype void gridInqYunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
871
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
872
873
    @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
874
                    returned string. The maximum possible length, in characters, of
875
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
876
877

@Description
878
The function @func{gridInqYunits} returns the units of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
879
880

@Result
881
@func{gridInqYunits} returns the units of the Y-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
882
883
884
885
886

@EndFunction
*/
void gridInqYunits(int gridID, char *yunits)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
887
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
888

889
890
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
891
892
893
894
895
  strcpy(yunits, gridptr->yunits);
}

void gridInqYstdname(int gridID, char *ystdname)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
896
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
897

898
899
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
900
901
902
903
904
905
906
907
908
  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
909
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
910
911

@Description
912
The function @func{gridInqType} returns the type of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
913
914

@Result
915
@func{gridInqType} returns the type of the grid,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
916
one of the set of predefined CDI grid types.
917
The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
918
@func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL}, @func{GRID_GME},
919
@func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
920
921
922
923
924

@EndFunction
*/
int gridInqType(int gridID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
925
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
926

927
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
928
929
930
931
932
933
934
935
936
937
938

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

@Description
942
The function @func{gridInqSize} returns the size of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
943
944

@Result
945
@func{gridInqSize} returns the number of grid points of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
946
947
948
949
950

@EndFunction
*/
int gridInqSize(int gridID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
951
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
952

953
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
954

Uwe Schulzweida's avatar
Uwe Schulzweida committed
955
  int size = gridptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
956
957
958
959
960
961
962
963
964

  if ( ! size )
    {
      int xsize, ysize;

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

      if ( ysize )
Thomas Jahns's avatar
Thomas Jahns committed
965
        size = xsize *ysize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
966
      else
Thomas Jahns's avatar
Thomas Jahns committed
967
        size = xsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
968

Thomas Jahns's avatar
Thomas Jahns committed
969
      gridptr->size = size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
970
971
972
973
974
    }

  return (size);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
975
976
static
int nsp2trunc(int nsp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
977
978
979
980
981
982
983
984
985
{
  /*  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)           */
  int trunc;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
986
  trunc = (int) (sqrt(nsp*4 + 1.) - 3) / 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
987
988
989
990
991
992
993

  return (trunc);
}


int gridInqTrunc(int gridID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
994
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
995

996
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
997
998
999
1000

  if ( gridptr->trunc == 0 )
    {
      if ( gridptr->type == GRID_SPECTRAL )
Thomas Jahns's avatar
Thomas Jahns committed
1001
        gridptr->trunc = nsp2trunc(gridptr->size);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1002
1003
      /*
      else if      ( gridptr->type == GRID_GAUSSIAN )
Thomas Jahns's avatar
Thomas Jahns committed
1004
        gridptr->trunc = nlat2trunc(gridptr->ysize);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1005
1006
1007
1008
1009
1010
      */
    }

  return (gridptr->trunc);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1011

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1012
1013
void gridDefTrunc(int gridID, int trunc)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1014
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1015

1016
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1017

1018
1019
1020
1021
1022
  if (gridptr->trunc != trunc)
    {
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
      gridptr->trunc = trunc;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1023
1024
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1025
1026
1027
1028
1029
1030
/*
@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
1031
1032
    @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
1033
1034

@Description
1035
The function @func{gridDefXsize} defines the number of values of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1036
1037
1038

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1039
1040
void gridDefXsize(int gridID, int xsize)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1041
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1042

1043
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1044
1045

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

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

1051
1052
1053
1054
1055
  if (gridptr->xsize != xsize)
    {
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
      gridptr->xsize = xsize;
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1056

1057
1058
1059
1060
1061
1062
1063
  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
1064
1065
1066
}

/*
Thomas Jahns's avatar
Thomas Jahns committed
1067
1068
@Function
@Title
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1069

Thomas Jahns's avatar
Thomas Jahns committed
1070
@Prototype
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1071
1072
1073
1074
1075
1076
1077
@Parameter
    @Item  Grid identifier

@EndFunction
*/
void gridDefPrec(int gridID, int prec)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1078
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1079

1080
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1081

1082
1083
1084
1085
1086
  if (gridptr->prec != prec)
    {
      reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE);
      gridptr->prec = prec;
    }
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
*/
int gridInqPrec(int gridID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1101
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1102

1103
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1104
1105
1106
1107
1108

  return (gridptr->prec);
}

/*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1109
1110
@Function  gridInqXsize
@Title     Get the number of values of a X-axis
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1111

1112
@Prototype int gridInqXsize(int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1113
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1114
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1115
1116

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

@Result
1120
@func{gridInqXsize} returns the number of values of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1121
1122
1123
1124
1125

@EndFunction
*/
int gridInqXsize(int gridID)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1126
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1127

1128
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1129
1130
1131
1132
1133

  return (gridptr->xsize);
}

/*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1134
1135
@Function  gridDefYsize
@Title     Define the number of values of a Y-axis
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1136

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1137
@Prototype void gridDefYsize(int gridID, int ysize)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1138
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
1139
1140
    @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
1141
1142

@Description
1143
The function @func{gridDefYsize} defines the number of values of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1144
1145
1146
1147
1148

@EndFunction
*/
void gridDefYsize(int gridID, int ysize)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1149
  grid_t *gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1150

1151
  grid_check_ptr(gridID, gridptr);