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

#include <string.h>

#include "dmemory.h"
#include "cdi.h"
#include "stream_int.h"
#include "grid.h"
11
#include "gaussgrid.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
12
13
14
15
16
17
18
19
20
21
22
23


#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


char *Grids[] = {
24
25
26
27
28
29
30
31
32
  /*  0 */  "undefined",
  /*  1 */  "generic",
  /*  2 */  "gaussian",
  /*  3 */  "gaussian reduced",
  /*  4 */  "lonlat",
  /*  5 */  "spectral",
  /*  6 */  "fourier",
  /*  7 */  "gme",
  /*  8 */  "trajectory",
33
  /*  9 */  "unstructured",
34
35
  /* 10 */  "curvilinear",
  /* 11 */  "lcc",
36
37
38
  /* 12 */  "lcc2",
  /* 13 */  "laea",
  /* 14 */  "sinusoidal",
39
  /* 15 */  "reference",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
40
  /* 16 */  "projection",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
41
42
43
44
45
};


static int  GRID_Debug = 0;   /* If set to 1, debugging */

46
static int _grid_max = MAX_GRIDS;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
47
48
49
50
51
52
53
54
55
56
57

static void grid_initialize(void);

static int _grid_init = FALSE;

#if  defined  (HAVE_LIBPTHREAD)
#  include <pthread.h>

static pthread_once_t _grid_init_thread = PTHREAD_ONCE_INIT;
static pthread_mutex_t _grid_mutex;

58
59
#  define GRID_LOCK()         pthread_mutex_lock(&_grid_mutex)
#  define GRID_UNLOCK()       pthread_mutex_unlock(&_grid_mutex)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
60
#  define GRID_INIT()        \
61
   if ( _grid_init == FALSE ) pthread_once(&_grid_init_thread, grid_initialize)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
62
63
64

#else

65
66
#  define GRID_LOCK()
#  define GRID_UNLOCK()
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
67
#  define GRID_INIT()        \
68
   if ( _grid_init == FALSE ) grid_initialize()
Uwe Schulzweida's avatar
Uwe Schulzweida committed
69
70
71
72
73
74

#endif


typedef struct _gridPtrToIdx {
  int idx;
75
  grid_t *ptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
76
77
78
79
  struct _gridPtrToIdx *next;
} gridPtrToIdx;


Uwe Schulzweida's avatar
Uwe Schulzweida committed
80
81
static gridPtrToIdx *_gridList  = NULL;
static gridPtrToIdx *_gridAvail = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
82
83


84
85
static
void grid_list_new(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
86
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
87
88
  assert(_gridList == NULL);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
89
90
91
  _gridList = (gridPtrToIdx *) malloc(_grid_max*sizeof(gridPtrToIdx));
}

92
93
static
void grid_list_delete(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
94
95
96
97
{
  if ( _gridList ) free(_gridList);
}

98
99
static
void grid_init_pointer(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
{
  int  i;
  
  for ( i = 0; i < _grid_max; i++ )
    {
      _gridList[i].next = _gridList + i + 1;
      _gridList[i].idx  = i;
      _gridList[i].ptr  = 0;
    }

  _gridList[_grid_max-1].next = 0;

  _gridAvail = _gridList;
}

115
static
116
grid_t *grid_to_pointer(int idx)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
117
{
118
  grid_t *gridptr = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
119

120
  GRID_INIT();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
121
122
123

  if ( idx >= 0 && idx < _grid_max )
    {
124
      GRID_LOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
125
126
127

      gridptr = _gridList[idx].ptr;

128
      GRID_UNLOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
129
130
    }
  else
131
    Error("grid index %d undefined!", idx);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
132
133
134
135
136

  return (gridptr);
}

/* Create an index from a pointer */
137
138
static
int grid_from_pointer(grid_t *ptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
139
140
141
142
143
144
{
  int      idx = -1;
  gridPtrToIdx *newptr;

  if ( ptr )
    {
145
      GRID_LOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
146
147
148
149
150
151
152
153
154
155

      if ( _gridAvail )
	{
	  newptr       = _gridAvail;
	  _gridAvail   = _gridAvail->next;
	  newptr->next = 0;
	  idx	       = newptr->idx;
	  newptr->ptr  = ptr;
      
	  if ( GRID_Debug )
156
	    Message("Pointer %p has idx %d from grid list", ptr, idx);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
157
158
	}
      else
159
	Warning("Too many open grids (limit is %d)!", _grid_max);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
160

161
      GRID_UNLOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
162
163
    }
  else
164
    Error("Internal problem (pointer %p undefined)", ptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
165
166
167
168
169

  return (idx);
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
170
171
172
void grid_init(grid_t *gridptr)
{
  gridptr->self         = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
173
  gridptr->type         = CDI_UNDEFID;
174
  gridptr->proj         = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
175
  gridptr->mask         = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
176
  gridptr->mask_gme     = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
177
178
179
180
181
182
183
184
185
  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
186
187
188
189
190
191
192
  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;
193
194
  gridptr->lcc_projflag = 0;
  gridptr->lcc_scanflag = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
195
  gridptr->lcc_defined  = FALSE;
196
197
198
199
200
201
  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;
202
203
204
205
  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
206
207
208
209
210
211
  gridptr->trunc        = 0;
  gridptr->nvertex      = 0;
  gridptr->nd           = 0;
  gridptr->ni           = 0;
  gridptr->ni2          = 0;
  gridptr->ni3          = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
212
213
  gridptr->number       = 0;
  gridptr->position     = 0;
214
  gridptr->reference    = NULL;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
215
216
217
218
  gridptr->prec         = 0;
  gridptr->size         = 0;
  gridptr->xsize        = 0;
  gridptr->ysize        = 0;
219
  gridptr->np           = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
220
221
  gridptr->xdef         = 0;
  gridptr->ydef         = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
222
  gridptr->isCyclic     = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
223
224
225
226
227
  gridptr->isRotated    = FALSE;
  gridptr->xpole        = 0.0;
  gridptr->ypole        = 0.0;
  gridptr->angle        = 0.0;
  gridptr->locked       = FALSE;
228
  gridptr->lcomplex     = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
229
230
231
232
233
234
235
236
  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;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
237
  gridptr->uuid[0]      = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
  gridptr->name         = NULL;
}


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

static
void grid_init_entry(grid_t *gridptr)
{
  grid_init(gridptr);

  gridptr->self = grid_from_pointer(gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
264
265
}

266
267
static
grid_t *grid_new_entry(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
268
{
269
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
270

271
  gridptr = (grid_t *) malloc(sizeof(grid_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
272
273
274
275
276
277

  if ( gridptr ) grid_init_entry(gridptr);

  return (gridptr);
}

278
279
static
void grid_delete_entry(grid_t *gridptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
280
281
282
283
284
{
  int idx;

  idx = gridptr->self;

285
  GRID_LOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
286
287
288
289
290

  free(gridptr);

  _gridList[idx].next = _gridAvail;
  _gridList[idx].ptr  = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
291
  _gridAvail          = &_gridList[idx];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
292

293
  GRID_UNLOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
294
295

  if ( GRID_Debug )
296
    Message("Removed idx %d from grid list", idx);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
297
298
}

299
300
static
void grid_initialize(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
301
302
303
304
305
306
307
308
309
310
311
312
313
314
{
  char *env;

#if  defined  (HAVE_LIBPTHREAD)
  /* initialize global API mutex lock */
  pthread_mutex_init(&_grid_mutex, NULL);
#endif

  env = getenv("GRID_DEBUG");
  if ( env ) GRID_Debug = atoi(env);

  grid_list_new();
  atexit(grid_list_delete);

315
  GRID_LOCK();
316

Uwe Schulzweida's avatar
Uwe Schulzweida committed
317
318
  grid_init_pointer();

319
  GRID_UNLOCK();
320

Uwe Schulzweida's avatar
Uwe Schulzweida committed
321
322
323
  _grid_init = TRUE;
}

324
325
static
void grid_copy(grid_t *gridptr2, grid_t *gridptr1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
326
327
328
329
{
  int gridID2;

  gridID2 = gridptr2->self;
330
  memcpy(gridptr2, gridptr1, sizeof(grid_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
331
332
333
  gridptr2->self = gridID2;
}

334
static
335
void gridCheckPtr(const char *caller, int gridID, grid_t *gridptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
336
337
{
  if ( gridptr == NULL )
338
    Errorc("grid %d undefined!", gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
339
340
}

341
#define  grid_check_ptr(gridID, gridptr)  gridCheckPtr(__func__, gridID, gridptr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
342
343
344
345

int gridSize(void)
{
  int gridsize = 0;
346
  long i;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
347
  
348
  GRID_INIT();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
349

350
  GRID_LOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
351
352
353
354

  for ( i = 0; i < _grid_max; i++ )
    if ( _gridList[i].ptr ) gridsize++;

355
  GRID_UNLOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
356
357
358
359
360
361
362

  return (gridsize);
}


void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *xvals)
{
363
  long i;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
364

365
  if ( (! (fabs(xinc) > 0)) && xsize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
    {
      if ( xfirst >= xlast )
	{
	  while ( xfirst >= xlast ) xlast += 360;
	  xinc = (xlast-xfirst)/(xsize);
	}
      else
	{
	  xinc = (xlast-xfirst)/(xsize-1);
	}
    }

  for ( i = 0; i < xsize; i++ )
    xvals[i] = xfirst + i*xinc;
}

382
383
static
void calc_gaussgrid(double *yvals, int ysize, double yfirst, double ylast)
384
385
{
  double *yw;
386
387
  long yhsize;
  long i;
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408

  yw = (double *) malloc(ysize*sizeof(double));
  gaussaw(yvals, yw, ysize);
  free(yw);
  for ( i = 0; i < ysize; i++ )
    yvals[i] = asin(yvals[i])/M_PI*180.0;

  if ( yfirst < ylast && yfirst > -90.0 && ylast < 90.0 )
    {
      double ytmp;
      yhsize = ysize/2;
      for ( i = 0; i < yhsize; i++ )
	{
	  ytmp = yvals[i];
	  yvals[i] = yvals[ysize-i-1];
	  yvals[ysize-i-1] = ytmp;
	}
    }
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
409
410
void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *yvals)
{
411
  long i;
412
  double deleps = 0.002;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
413
414
415
416
417

  if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
    {
      if ( ysize > 2 )
	{
418
	  calc_gaussgrid(yvals, ysize, yfirst, ylast);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
419

420
	  if ( ! (IS_EQUAL(yfirst, 0) && IS_EQUAL(ylast, 0)) )
421
	    if ( fabs(yvals[0] - yfirst) > deleps || fabs(yvals[ysize-1] - ylast) > deleps )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
422
	      {
423
		double yinc = fabs(ylast-yfirst)/(ysize-1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
424
		double *ytmp = NULL;
425
426
427
428
		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); */
429
		if ( ny > ysize && ny < 4096 )
430
		  {
431
		    ytmp = (double *) malloc(ny*sizeof(double));
432
433
		    calc_gaussgrid(ytmp, ny, yfirst, ylast);
		    for ( i = 0; i < (ny-ysize); i++ )
434
		      if ( fabs(ytmp[i] - yfirst) < deleps ) break;
435

436
		    nstart = i;
437

438
		    if ( (nstart+ysize-1) < ny )
439
		      if ( fabs(ytmp[nstart+ysize-1] - ylast) < deleps ) lfound = 1;
440
		  }
441
442
443
444
445
446
447

		if ( lfound )
		  {
		    for ( i = 0; i < ysize; i++ ) yvals[i] = ytmp[i+nstart];
		  }
		else
		  {
448
		    Warning("Cannot calculate gaussian latitudes for lat1 = %g latn = %g!", yfirst, ylast);
449
450
451
452
453
		    for ( i = 0; i < ysize; i++ ) yvals[i] = 0;
		    yvals[0] = yfirst;
		    yvals[ysize-1] = ylast;
		  }

454
		if ( ytmp ) free(ytmp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
455
456
457
458
459
460
461
462
463
464
465
	      }
	}
      else
	{
	  yvals[0] = yfirst;
	  yvals[ysize-1] = ylast;
	}
    }
  /*     else if ( gridtype == GRID_LONLAT || gridtype == GRID_GENERIC ) */
  else
    {
466
      if ( (! (fabs(yinc) > 0)) && ysize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
467
	{
468
	  if ( IS_EQUAL(yfirst, ylast) && IS_NOT_EQUAL(yfirst, 0) ) ylast *= -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495

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

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

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


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

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

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

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

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

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

  if ( CDI_Debug )
548
    Message("gridtype: %d size: %d", gridtype, size);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
549

550
  GRID_INIT();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
551
552

  gridptr = grid_new_entry();
553
  if ( ! gridptr ) Error("No memory");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
554
555
556

  gridID = gridptr->self;

557
  if ( CDI_Debug ) Message("gridID: %d", gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
558
559
560
561
562

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

  /*  if ( gridtype == GRID_GENERIC )     gridptr->xsize = size; */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
563
564
  if ( gridtype == GRID_UNSTRUCTURED )  gridptr->xsize = size;
  if ( gridtype == GRID_CURVILINEAR  )  gridptr->nvertex = 4;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585

  switch (gridtype)
    {
    case GRID_LONLAT:
    case GRID_GAUSSIAN:
    case GRID_GAUSSIAN_REDUCED:
    case GRID_CURVILINEAR:
    case GRID_TRAJECTORY:
      {
	if ( gridtype == GRID_TRAJECTORY )
	  {
	    gridDefXname(gridID, "tlon");
	    gridDefYname(gridID, "tlat");
	  }
	else
	  {
	    gridDefXname(gridID, "lon");
	    gridDefYname(gridID, "lat");
	  }
	gridDefXlongname(gridID, "longitude");
	gridDefYlongname(gridID, "latitude");
586
	/*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
587
588
589
590
591
592
593
594
	if ( gridtype == GRID_CURVILINEAR )
	  {
	    strcpy(gridptr->xstdname, "grid_longitude");
	    strcpy(gridptr->ystdname, "grid_latitude");
	    gridDefXunits(gridID, "degrees");
	    gridDefYunits(gridID, "degrees");
	  }
	else
595
	*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
596
597
598
599
600
601
602
603
604
605
	  {
	    strcpy(gridptr->xstdname, "longitude");
	    strcpy(gridptr->ystdname, "latitude");
	    gridDefXunits(gridID, "degrees_east");
	    gridDefYunits(gridID, "degrees_north");
	  }

	break;
      }
    case GRID_GME:
606
    case GRID_UNSTRUCTURED:
607
608
609
610
611
612
613
614
615
      {
	gridDefXname(gridID, "lon");
	gridDefYname(gridID, "lat");
	strcpy(gridptr->xstdname, "longitude");
	strcpy(gridptr->ystdname, "latitude");
	gridDefXunits(gridID, "degrees_east");
	gridDefYunits(gridID, "degrees_north");
	break;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
616
617
618
619
    case GRID_GENERIC:
      {
	gridDefXname(gridID, "x");
	gridDefYname(gridID, "y");
620
621
622
623
	strcpy(gridptr->xstdname, "grid_longitude");
	strcpy(gridptr->ystdname, "grid_latitude");
	gridDefXunits(gridID, "degrees");
	gridDefYunits(gridID, "degrees");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
624
625
	break;
      }
626
    case GRID_LCC2:
627
    case GRID_SINUSOIDAL:
628
    case GRID_LAEA:
629
630
631
632
633
634
635
636
637
      {
	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;
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
638
639
640
641
642
643
    }

  return (gridID);
}


644
645
646
647
648
649
/*
@Function  gridDestroy
@Title     Destroy a horizontal Grid

@Prototype void gridDestroy(int gridID)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
650
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
651
652
653
654
655

@EndFunction
*/
void gridDestroy(int gridID)
{
656
657
658
659
  grid_t *gridptr;

  gridptr = grid_to_pointer(gridID);
  
660
  grid_check_ptr(gridID, gridptr);
661

662
663
664
665
666
667
668
669
670
  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);
671
672

  grid_delete_entry(gridptr);
673
674
675
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
676
677
678
char *gridNamePtr(int gridtype)
{
  char *name;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
679
  int size = (int) (sizeof(Grids)/sizeof(char *));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701

  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
Uwe Schulzweida's avatar
Uwe Schulzweida committed
702
703
    @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
704
705

@Description
706
The function @func{gridDefXname} defines the name of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
707
708
709

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
710
void gridDefXname(int gridID, const char *xname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
711
{
712
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
713
714
715

  gridptr = grid_to_pointer(gridID);

716
717
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
718
719
720
721
722
723
724
725
726
727
728
  if ( xname )
    strcpy(gridptr->xname, xname);
}


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

@Prototype void gridDefXlongname(int gridID, const char *longname)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
729
730
    @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
731
732

@Description
733
The function @func{gridDefXlongname} defines the longname of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
734
735
736

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
737
void gridDefXlongname(int gridID, const char *xlongname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
738
{
739
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
740
741
742
743
744
745
746
747
748
749
750
751
752
753

  gridptr = grid_to_pointer(gridID);

  if ( xlongname )
    strcpy(gridptr->xlongname, xlongname);
}


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

@Prototype void gridDefXunits(int gridID, const char *units)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
755
    @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
756
757

@Description
758
The function @func{gridDefXunits} defines the units of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
759
760
761

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
762
void gridDefXunits(int gridID, const char *xunits)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
763
{
764
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
765
766
767

  gridptr = grid_to_pointer(gridID);

768
769
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
770
771
772
773
774
775
776
777
778
779
780
  if ( xunits )
    strcpy(gridptr->xunits, xunits);
}


/*
@Function  gridDefYname
@Title     Define the name of a Y-axis

@Prototype void gridDefYname(int gridID, const char *name)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
781
782
    @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
783
784

@Description
785
The function @func{gridDefYname} defines the name of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
786
787
788

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
789
void gridDefYname(int gridID, const char *yname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
790
{
791
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
792
793
794

  gridptr = grid_to_pointer(gridID);

795
796
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
797
798
799
800
801
802
803
804
805
806
807
  if ( yname )
    strcpy(gridptr->yname, yname);
}


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

@Prototype void gridDefYlongname(int gridID, const char *longname)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
808
809
    @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
810
811

@Description
812
The function @func{gridDefYlongname} defines the longname of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
813
814
815

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
816
void gridDefYlongname(int gridID, const char *ylongname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
817
{
818
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
819
820
821

  gridptr = grid_to_pointer(gridID);

822
823
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
824
825
826
827
828
829
830
831
832
833
834
  if ( ylongname )
    strcpy(gridptr->ylongname, ylongname);
}


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

@Prototype void gridDefYunits(int gridID, const char *units)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
835
836
    @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
837
838

@Description
839
The function @func{gridDefYunits} defines the units of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
840
841
842

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
843
void gridDefYunits(int gridID, const char *yunits)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
844
{
845
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
846
847
848

  gridptr = grid_to_pointer(gridID);

849
850
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
851
852
853
854
855
856
857
858
859
  if ( yunits )
    strcpy(gridptr->yunits, yunits);
}


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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
860
@Prototype void gridInqXname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
861
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
862
863
864
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
    @Item  name     Name of the X-axis. The caller must allocate space for the 
                    returned string. The maximum possible length, in characters, of
Uwe Schulzweida's avatar
Uwe Schulzweida committed
865
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
866
867

@Description
868
The function @func{gridInqXname} returns the name of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
869
870

@Result
871
@func{gridInqXname} returns the name of the X-axis to the parameter name.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
872
873
874
875
876

@EndFunction
*/
void gridInqXname(int gridID, char *xname)
{
877
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
878
879
880

  gridptr = grid_to_pointer(gridID);

881
882
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
883
884
885
886
887
888
889
890
  strcpy(xname, gridptr->xname);
}


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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
891
@Prototype void gridInqXlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
892
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
893
894
895
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
    @Item  longname Longname of the X-axis. The caller must allocate space for the 
                    returned string. The maximum possible length, in characters, of
Uwe Schulzweida's avatar
Uwe Schulzweida committed
896
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
897
898

@Description
899
The function @func{gridInqXlongname} returns the longname of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
900
901

@Result
902
@func{gridInqXlongname} returns the longname of the X-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
903
904
905
906
907

@EndFunction
*/
void gridInqXlongname(int gridID, char *xlongname)
{
908
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
909
910
911

  gridptr = grid_to_pointer(gridID);

912
913
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
914
915
916
917
918
919
920
921
  strcpy(xlongname, gridptr->xlongname);
}


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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
922
@Prototype void gridInqXunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
923
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
924
925
926
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
    @Item  units    Units of the X-axis. The caller must allocate space for the 
                    returned string. The maximum possible length, in characters, of
Uwe Schulzweida's avatar
Uwe Schulzweida committed
927
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
928
929

@Description
930
The function @func{gridInqXunits} returns the units of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
931
932

@Result
933
@func{gridInqXunits} returns the units of the X-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
934
935
936
937
938

@EndFunction
*/
void gridInqXunits(int gridID, char *xunits)
{
939
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
940
941
942

  gridptr = grid_to_pointer(gridID);

943
944
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
945
946
947
948
949
950
  strcpy(xunits, gridptr->xunits);
}


void gridInqXstdname(int gridID, char *xstdname)
{
951
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
952
953
954

  gridptr = grid_to_pointer(gridID);

955
956
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
957
958
959
960
961
962
963
964
  strcpy(xstdname, gridptr->xstdname);
}


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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
965
@Prototype void gridInqYname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
966
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
967
968
969
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
    @Item  name     Name of the Y-axis. The caller must allocate space for the 
                    returned string. The maximum possible length, in characters, of
Uwe Schulzweida's avatar
Uwe Schulzweida committed
970
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
971
972

@Description
973
The function @func{gridInqYname} returns the name of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
974
975

@Result
976
@func{gridInqYname} returns the name of the Y-axis to the parameter name.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
977
978
979
980
981

@EndFunction
*/
void gridInqYname(int gridID, char *yname)
{
982
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
983
984
985

  gridptr = grid_to_pointer(gridID);

986
987
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
988
989
990
991
992
993
994
995
  strcpy(yname, gridptr->yname);
}


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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
996
@Prototype void gridInqXlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
997
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
998
999
1000
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
    @Item  longname Longname of the Y-axis. The caller must allocate space for the 
                    returned string. The maximum possible length, in characters, of
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1001
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1002
1003

@Description
1004
The function @func{gridInqYlongname} returns the longname of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1005
1006

@Result
1007
@func{gridInqYlongname} returns the longname of the Y-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1008
1009
1010
1011
1012

@EndFunction
*/
void gridInqYlongname(int gridID, char *ylongname)
{
1013
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1014
1015
1016

  gridptr = grid_to_pointer(gridID);

1017
1018
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1019
1020
1021
1022
1023
1024
1025
1026
  strcpy(ylongname, gridptr->ylongname);
}


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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1027
@Prototype void gridInqYunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1028
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1029
1030
1031
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
    @Item  units    Units of the Y-axis. The caller must allocate space for the 
                    returned string. The maximum possible length, in characters, of
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1032
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1033
1034

@Description
1035
The function @func{gridInqYunits} returns the units of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1036
1037

@Result
1038
@func{gridInqYunits} returns the units of the Y-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1039
1040
1041
1042
1043

@EndFunction
*/
void gridInqYunits(int gridID, char *yunits)
{
1044
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1045
1046
1047

  gridptr = grid_to_pointer(gridID);

1048
1049
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1050
1051
1052
1053
1054
  strcpy(yunits, gridptr->yunits);
}

void gridInqYstdname(int gridID, char *ystdname)
{
1055
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1056
1057
1058

  gridptr = grid_to_pointer(gridID);

1059
1060
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
  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
1071
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1072
1073

@Description
1074
The function @func{gridInqType} returns the type of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1075
1076

@Result
1077
@func{gridInqType} returns the type of the grid,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1078
one of the set of predefined CDI grid types.
1079
The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1080
@func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL}, @func{GRID_GME},
1081
@func{GRID_CURVILINEAR}, @func{GRID_UNSTRUCTURED} and @func{GRID_REFERENCE}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1082
1083
1084
1085
1086

@EndFunction
*/
int gridInqType(int gridID)
{
1087
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1088
1089
1090

  gridptr = grid_to_pointer(gridID);

1091
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102

  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
1103
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1104
1105

@Description
1106
The function @func{gridInqSize} returns the size of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1107
1108

@Result
1109
@func{gridInqSize} returns the number of grid points of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1110
1111
1112
1113
1114
1115

@EndFunction
*/
int gridInqSize(int gridID)
{
  int size = 0;
1116
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1117
1118
1119

  gridptr = grid_to_pointer(gridID);

1120
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141

  size = gridptr->size;

  if ( ! size )
    {
      int xsize, ysize;

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

      if ( ysize )
	size = xsize *ysize;
      else
	size = xsize;

      gridptr->size = size;  
    }

  return (size);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1142
1143
static
int nsp2trunc(int nsp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1144
1145
1146
1147
1148
1149
1150
1151
1152
{
  /*  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
1153
  trunc = (int) (sqrt(nsp*4 + 1.) - 3) / 2;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1154
1155
1156
1157
1158
1159
1160

  return (trunc);
}


int gridInqTrunc(int gridID)
{
1161
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1162
1163
1164

  gridptr = grid_to_pointer(gridID);

1165
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179

  if ( gridptr->trunc == 0 )
    {
      if ( gridptr->type == GRID_SPECTRAL )
	gridptr->trunc = nsp2trunc(gridptr->size);
      /*
      else if      ( gridptr->type == GRID_GAUSSIAN )
	gridptr->trunc = nlat2trunc(gridptr->ysize);
      */
    }

  return (gridptr->trunc);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1180

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1181
1182
void gridDefTrunc(int gridID, int trunc)
{
1183
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1184
1185
1186

  gridptr = grid_to_pointer(gridID);

1187
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1188
1189
1190
1191

  gridptr->trunc = trunc;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1192
1193
1194
1195
1196
1197
1198

/*
@Function  gridDefXsize
@Title     Define the number of values of a X-axis

@Prototype void gridDefXsize(int gridID, int xsize)
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1199
1200
    @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
1201
1202

@Description
1203
The function @func{gridDefXsize} defines the number of values of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1204
1205
1206

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1207
1208
void gridDefXsize(int gridID, int xsize)
{
1209
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1210
1211
1212

  gridptr = grid_to_pointer(gridID);

1213
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1214
1215

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

1218
  if ( gridInqType(gridID) == GRID_UNSTRUCTURED && xsize != gridInqSize(gridID) )
1219
    Error("xsize %d must be equal gridsize %d for gridtype CELL", xsize, gridInqSize(gridID));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1220
1221
1222

  gridptr->xsize = xsize;

1223
  if ( gridInqType(gridID) != GRID_UNSTRUCTURED &&
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1224
       gridptr->xsize*gridptr->ysize > gridInqSize(gridID) )
1225
    Error("inconsistent grid declaration! (xsize %d ysize %d gridsize %d)",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1226
1227
1228
1229
1230
	  gridptr->xsize, gridptr->ysize, gridInqSize(gridID));
}


/*
1231
1232
@Function
@Title
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1233

1234
@Prototype
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1235
1236
1237
1238
1239
1240
1241
@Parameter
    @Item  Grid identifier

@EndFunction
*/
void gridDefPrec(int gridID, int prec)
{
1242
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1243
1244
1245

  gridptr = grid_to_pointer(gridID);

1246
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263

  gridptr->prec = prec;
}


/*
@Function  
@Title     

@Prototype 
@Parameter
    @Item  Grid identifier

@EndFunction
*/
int gridInqPrec(int gridID)
{
1264
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1265
1266
1267

  gridptr = grid_to_pointer(gridID);

1268
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1269
1270
1271
1272
1273
1274

  return (gridptr->prec);
}


/*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1275
1276
@Function  gridInqXsize
@Title     Get the number of values of a X-axis
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1277

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1278
@Prototype int gridInqXsize(int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1279
@Parameter