grid.c 82.7 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;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
219
220
  gridptr->xdef         = 0;
  gridptr->ydef         = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
221
  gridptr->isCyclic     = CDI_UNDEFID;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
222
223
224
225
226
  gridptr->isRotated    = FALSE;
  gridptr->xpole        = 0.0;
  gridptr->ypole        = 0.0;
  gridptr->angle        = 0.0;
  gridptr->locked       = FALSE;
227
  gridptr->lcomplex     = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
228
229
230
231
232
233
234
235
  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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
  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
262
263
}

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

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

  if ( gridptr ) grid_init_entry(gridptr);

  return (gridptr);
}

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

  idx = gridptr->self;

283
  GRID_LOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
284
285
286
287
288

  free(gridptr);

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

291
  GRID_UNLOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
292
293

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

297
298
static
void grid_initialize(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
299
300
301
302
303
304
305
306
307
308
309
310
311
312
{
  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);

313
  GRID_LOCK();
314

Uwe Schulzweida's avatar
Uwe Schulzweida committed
315
316
  grid_init_pointer();

317
  GRID_UNLOCK();
318

Uwe Schulzweida's avatar
Uwe Schulzweida committed
319
320
321
  _grid_init = TRUE;
}

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

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

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

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

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

348
  GRID_LOCK();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
349
350
351
352

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

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

  return (gridsize);
}


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

363
  if ( (! (fabs(xinc) > 0)) && xsize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
    {
      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;
}

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

  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
407
408
void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *yvals)
{
409
  long i;
410
  double deleps = 0.002;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
411
412
413
414
415

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

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

434
		    nstart = i;
435

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

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

452
		if ( ytmp ) free(ytmp);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
453
454
455
456
457
458
459
460
461
462
463
	      }
	}
      else
	{
	  yvals[0] = yfirst;
	  yvals[ysize-1] = ylast;
	}
    }
  /*     else if ( gridtype == GRID_LONLAT || gridtype == GRID_GENERIC ) */
  else
    {
464
      if ( (! (fabs(yinc) > 0)) && ysize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
465
	{
466
	  if ( IS_EQUAL(yfirst, ylast) && IS_NOT_EQUAL(yfirst, 0) ) ylast *= -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
467
468
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

	  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
494
    Error("unable to calculate values for %s grid!", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
495
496
497
498
499
  */
}


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

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

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

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

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

@Source
Uwe Schulzweida's avatar
Uwe Schulzweida committed
522
523
#include "cdi.h"
   ...
Uwe Schulzweida's avatar
Uwe Schulzweida committed
524
525
#define  nlon  12
#define  nlat   6
Uwe Schulzweida's avatar
Uwe Schulzweida committed
526
   ...
Uwe Schulzweida's avatar
Uwe Schulzweida committed
527
528
double lons[nlon] = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330};
double lats[nlat] = {-75, -45, -15, 15, 45, 75};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
529
530
int gridID;
   ...
Uwe Schulzweida's avatar
Uwe Schulzweida committed
531
532
533
gridID = gridCreate(GRID_LONLAT, nlon*nlat);
gridDefXsize(gridID, nlon);
gridDefYsize(gridID, nlat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
534
535
536
537
gridDefXvals(gridID, lons);
gridDefYvals(gridID, lats);
   ...
@EndSource
Uwe Schulzweida's avatar
Uwe Schulzweida committed
538
539
@EndFunction
*/
540
int gridCreate(int gridtype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
541
542
{
  int gridID;
543
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
544
545

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

548
  GRID_INIT();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
549
550

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

  gridID = gridptr->self;

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

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

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

  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");
584
	/*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
585
586
587
588
589
590
591
592
	if ( gridtype == GRID_CURVILINEAR )
	  {
	    strcpy(gridptr->xstdname, "grid_longitude");
	    strcpy(gridptr->ystdname, "grid_latitude");
	    gridDefXunits(gridID, "degrees");
	    gridDefYunits(gridID, "degrees");
	  }
	else
593
	*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
594
595
596
597
598
599
600
601
602
603
	  {
	    strcpy(gridptr->xstdname, "longitude");
	    strcpy(gridptr->ystdname, "latitude");
	    gridDefXunits(gridID, "degrees_east");
	    gridDefYunits(gridID, "degrees_north");
	  }

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

  return (gridID);
}


642
643
644
645
646
647
/*
@Function  gridDestroy
@Title     Destroy a horizontal Grid

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

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

  gridptr = grid_to_pointer(gridID);
  
658
  grid_check_ptr(gridID, gridptr);
659

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

  grid_delete_entry(gridptr);
671
672
673
}


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

  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
700
701
    @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
702
703

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

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

  gridptr = grid_to_pointer(gridID);

714
715
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
716
717
718
719
720
721
722
723
724
725
726
  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
727
728
    @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
729
730

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

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

  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
752
753
    @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
754
755

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

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

  gridptr = grid_to_pointer(gridID);

766
767
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
768
769
770
771
772
773
774
775
776
777
778
  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
779
780
    @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
781
782

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

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

  gridptr = grid_to_pointer(gridID);

793
794
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
795
796
797
798
799
800
801
802
803
804
805
  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
806
807
    @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
808
809

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

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

  gridptr = grid_to_pointer(gridID);

820
821
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
822
823
824
825
826
827
828
829
830
831
832
  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
833
834
    @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
835
836

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

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

  gridptr = grid_to_pointer(gridID);

847
848
  grid_check_ptr(gridID, gridptr);

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


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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
858
@Prototype void gridInqXname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
859
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
860
861
862
863
    @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
                    the string is given by the predefined constant CDI_MAX_NAME.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
864
865

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

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

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

  gridptr = grid_to_pointer(gridID);

879
880
  grid_check_ptr(gridID, gridptr);

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


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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
889
@Prototype void gridInqXlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
890
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
891
892
893
894
    @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
                    the string is given by the predefined constant CDI_MAX_NAME.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
895
896

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

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

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

  gridptr = grid_to_pointer(gridID);

910
911
  grid_check_ptr(gridID, gridptr);

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


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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
920
@Prototype void gridInqXunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
921
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
922
923
924
925
    @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
                    the string is given by the predefined constant CDI_MAX_NAME.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
926
927

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

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

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

  gridptr = grid_to_pointer(gridID);

941
942
  grid_check_ptr(gridID, gridptr);

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


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

  gridptr = grid_to_pointer(gridID);

953
954
  grid_check_ptr(gridID, gridptr);

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


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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
963
@Prototype void gridInqYname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
964
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
965
966
967
968
    @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
                    the string is given by the predefined constant CDI_MAX_NAME.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
969
970

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

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

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

  gridptr = grid_to_pointer(gridID);

984
985
  grid_check_ptr(gridID, gridptr);

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


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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
994
@Prototype void gridInqXlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
995
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
996
997
998
999
    @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
                    the string is given by the predefined constant CDI_MAX_NAME.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1000
1001

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

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

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

  gridptr = grid_to_pointer(gridID);

1015
1016
  grid_check_ptr(gridID, gridptr);

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


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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1025
@Prototype void gridInqYunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1026
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1027
1028
1029
1030
    @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
                    the string is given by the predefined constant CDI_MAX_NAME.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1031
1032

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

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

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

  gridptr = grid_to_pointer(gridID);

1046
1047
  grid_check_ptr(gridID, gridptr);

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

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

  gridptr = grid_to_pointer(gridID);

1057
1058
  grid_check_ptr(gridID, gridptr);

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

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

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

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

  gridptr = grid_to_pointer(gridID);

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

  return (gridptr->type);
}


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

@Prototype int gridInqSize(int gridID)
@Parameter
1101
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1102
1103

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

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

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

  gridptr = grid_to_pointer(gridID);

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

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

  return (trunc);
}


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

  gridptr = grid_to_pointer(gridID);

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

  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
1178

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

  gridptr = grid_to_pointer(gridID);

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

  gridptr->trunc = trunc;
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1190
1191
1192
1193
1194
1195
1196

/*
@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
1197
1198
    @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
1199
1200

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

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

  gridptr = grid_to_pointer(gridID);

1211
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1212
1213

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

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

  gridptr->xsize = xsize;

1221
  if ( gridInqType(gridID) != GRID_UNSTRUCTURED && 
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1222
       gridptr->xsize*gridptr->ysize > gridInqSize(gridID) )
1223
    Error("inconsistent grid declaration! (xsize %d ysize %d gridsize %d)",
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
	  gridptr->xsize, gridptr->ysize, gridInqSize(gridID));
}


/*
@Function  
@Title     

@Prototype 
@Parameter
    @Item  Grid identifier

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

  gridptr = grid_to_pointer(gridID);

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

  gridptr->prec = prec;
}


/*
@Function  
@Title     

@Prototype 
@Parameter
    @Item  Grid identifier

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

  gridptr = grid_to_pointer(gridID);

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

  return (gridptr->prec);
}


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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1276
@Prototype void gridInqXsize(int gridID)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1277
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1278
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1279
1280

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

@Result
1284
@func{gridInqXsize} returns the number of values of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1285
1286
1287
1288
1289

@EndFunction
*/
int gridInqXsize(int gridID)
{
1290
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1291
1292
1293

  gridptr = grid_to_pointer(gridID);

1294
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1295
1296