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

#include <string.h>

7
8
9
10
#ifdef USE_MPI
#include <mpi.h>
#endif

Uwe Schulzweida's avatar
Uwe Schulzweida committed
11
12
13
14
#include "dmemory.h"
#include "cdi.h"
#include "stream_int.h"
#include "grid.h"
15
#include "gaussgrid.h"
16
#include "pio_util.h"
17
#include "resource_handle.h"
18
#include "pio_rpc.h"
19
#include "namespace.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
20
21
22
23
24
25
26
27
28
29
30

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


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

61
62
resOps gridOps = { gridCompareP, gridDestroyP, gridPrintP
#ifdef USE_MPI
63
                   , gridGetPackSize, gridPack, gridTxCode
64
65
#endif
};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
66
67


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


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

142

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

159
static
160
grid_t *gridNewEntry ( void )
161
{
162
  grid_t *gridptr;
163

164
  gridptr = ( grid_t *) xmalloc ( sizeof ( grid_t ));
Deike Kleberg's avatar
Deike Kleberg committed
165
  grid_init ( gridptr );
166
  gridptr->self = reshPut (( void * ) gridptr, &gridOps );
167
168

  return gridptr;
169
170
}

171
static
172
void gridInit (void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
173
{
174
175
  static int gridInitialized = 0;
  char *env;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
176

177
  if ( gridInitialized ) return;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
178

Thomas Jahns's avatar
Thomas Jahns committed
179
  gridInitialized = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
180

181
182
  env = getenv("GRID_DEBUG");
  if ( env ) GRID_Debug = atoi(env);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
183
184
}

185
186
static
void grid_copy(grid_t *gridptr2, grid_t *gridptr1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
187
188
189
190
{
  int gridID2;

  gridID2 = gridptr2->self;
191
  memcpy(gridptr2, gridptr1, sizeof(grid_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
192
193
194
  gridptr2->self = gridID2;
}

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

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
204

Uwe Schulzweida's avatar
Uwe Schulzweida committed
205
int gridSize(void)
Thomas Jahns's avatar
Thomas Jahns committed
206
{
207
  return reshCountType ( &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
208
209
210
211
212
}


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

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

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

232
233
static
void calc_gaussgrid(double *yvals, int ysize, double yfirst, double ylast)
234
235
{
  double *yw;
236
237
  long yhsize;
  long i;
238
239
240
241
242
243
244
245
246
247
248
249

  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++ )
Thomas Jahns's avatar
Thomas Jahns committed
250
251
252
253
254
        {
          ytmp = yvals[i];
          yvals[i] = yvals[ysize-i-1];
          yvals[ysize-i-1] = ytmp;
        }
255
256
257
258
    }
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
259
260
void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *yvals)
{
261
  long i;
Deike Kleberg's avatar
Deike Kleberg committed
262
  double deleps = 0.002;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
263
264
265
266

  if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
    {
      if ( ysize > 2 )
Deike Kleberg's avatar
Deike Kleberg committed
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
	{
	  calc_gaussgrid(yvals, ysize, yfirst, ylast);

	  if ( ! (IS_EQUAL(yfirst, 0) && IS_EQUAL(ylast, 0)) )
	    if ( fabs(yvals[0] - yfirst) > deleps || fabs(yvals[ysize-1] - ylast) > deleps )
	      {
		double yinc = fabs(ylast-yfirst)/(ysize-1);
		double *ytmp = NULL;
		int nstart, lfound = 0;
		int ny = (int) (180./yinc + 0.5);
		ny -= ny%2;
		/* printf("%g %g %g %g %g %d\n", ylast, yfirst, ylast-yfirst,yinc, 180/yinc, ny); */
		if ( ny > ysize && ny < 4096 )
		  {
		    ytmp = (double *) malloc(ny*sizeof(double));
		    calc_gaussgrid(ytmp, ny, yfirst, ylast);
		    for ( i = 0; i < (ny-ysize); i++ )
		      if ( fabs(ytmp[i] - yfirst) < deleps ) break;

		    nstart = i;

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

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

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

          if ( yfirst > ylast )
            yinc = (yfirst-ylast)/(ysize-1);
          else if ( yfirst < ylast )
            yinc = (ylast-yfirst)/(ysize-1);
          else
            {
              if ( ysize%2 != 0 )
                {
                  yinc = 180.0/(ysize-1);
                  yfirst = -90;
                }
              else
                {
                  yinc = 180.0/ysize;
                  yfirst = -90 + yinc/2;
                }
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
338
339
340
341

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

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

/*
351
@Function  gridCreate
352
@Title     Create a horizontal Grid
Uwe Schulzweida's avatar
Uwe Schulzweida committed
353

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

@Description
364
The function @func{gridCreate} creates a horizontal Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
365
366

@Result
367
@func{gridCreate} returns an identifier to the Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
368
369

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

@Source
Uwe Schulzweida's avatar
Uwe Schulzweida committed
373
374
#include "cdi.h"
   ...
375
376
#define  nlon  12
#define  nlat   6
Uwe Schulzweida's avatar
Uwe Schulzweida committed
377
   ...
378
379
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
380
381
int gridID;
   ...
382
383
384
gridID = gridCreate(GRID_LONLAT, nlon*nlat);
gridDefXsize(gridID, nlon);
gridDefYsize(gridID, nlat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
385
386
387
388
gridDefXvals(gridID, lons);
gridDefYvals(gridID, lats);
   ...
@EndSource
Uwe Schulzweida's avatar
Uwe Schulzweida committed
389
390
@EndFunction
*/
391
int gridCreate(int gridtype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
392
393
{
  int gridID;
394
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
395
396

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

399
400
401
  gridInit ();

  gridptr = gridNewEntry();
402
  if ( ! gridptr ) Error("No memory");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
403
404
405

  gridID = gridptr->self;

406
  if ( CDI_Debug ) Message("gridID: %d", gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
407
408
409
410
411

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

  /*  if ( gridtype == GRID_GENERIC )     gridptr->xsize = size; */
412
413
  if ( gridtype == GRID_UNSTRUCTURED )  gridptr->xsize = size;
  if ( gridtype == GRID_CURVILINEAR  )  gridptr->nvertex = 4;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
414
415
416
417
418
419
420
421
422

  switch (gridtype)
    {
    case GRID_LONLAT:
    case GRID_GAUSSIAN:
    case GRID_GAUSSIAN_REDUCED:
    case GRID_CURVILINEAR:
    case GRID_TRAJECTORY:
      {
Thomas Jahns's avatar
Thomas Jahns committed
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
        if ( gridtype == GRID_TRAJECTORY )
          {
            gridDefXname(gridID, "tlon");
            gridDefYname(gridID, "tlat");
          }
        else
          {
            gridDefXname(gridID, "lon");
            gridDefYname(gridID, "lat");
          }
        gridDefXlongname(gridID, "longitude");
        gridDefYlongname(gridID, "latitude");

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

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

  return (gridID);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
493
494
static
void gridDestroyKernel( grid_t * gridptr )
495
496
497
{
  int id;

Deike Kleberg's avatar
Deike Kleberg committed
498
  xassert ( gridptr );
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513

  id = gridptr->self;

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

  free ( gridptr );

514
  reshRemove ( id, &gridOps );
515
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
516

517
518
519
520
521
522
/*
@Function  gridDestroy
@Title     Destroy a horizontal Grid

@Prototype void gridDestroy(int gridID)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
523
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
524
525
526
527
528

@EndFunction
*/
void gridDestroy(int gridID)
{
529
530
  grid_t *gridptr;

531
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
532

533
  gridDestroyKernel ( gridptr );
534
535
}

536
void gridDestroyP ( void * gridptr )
537
{
538
  gridDestroyKernel (( grid_t * ) gridptr );
539
540
541
}


Uwe Schulzweida's avatar
Uwe Schulzweida committed
542
543
544
char *gridNamePtr(int gridtype)
{
  char *name;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
545
  int size = (int) (sizeof(Grids)/sizeof(char *));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566

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

  return (name);
}


void gridName(int gridtype, char *gridname)
{
  strcpy(gridname, gridNamePtr(gridtype));
}

/*
@Function  gridDefXname
@Title     Define the name of a X-axis

@Prototype void gridDefXname(int gridID, const char *name)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
567
568
    @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
569
570

@Description
571
The function @func{gridDefXname} defines the name of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
572
573
574

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
575
void gridDefXname(int gridID, const char *xname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
576
{
577
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
578

579
580
  if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
    {
581
      xwarning ("%s", "Operation not executed." );
582
583
584
      return;
    }

585
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
586

587
588
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
589
590
591
592
593
594
595
596
597
598
  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
Deike Kleberg's avatar
Deike Kleberg committed
599
600
    @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
601
602

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

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
607
void gridDefXlongname(int gridID, const char *xlongname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
608
{
609
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
610

611
612
  if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
    {
613
      xwarning ("%s", "Operation not executed." );
614
615
616
      return;
    }

617
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
618

Uwe Schulzweida's avatar
Uwe Schulzweida committed
619
620
621
622
623
624
625
626
627
628
  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
Deike Kleberg's avatar
Deike Kleberg committed
629
630
    @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
631
632

@Description
633
The function @func{gridDefXunits} defines the units of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
634
635
636

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
637
void gridDefXunits(int gridID, const char *xunits)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
638
{
639
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
640

641
642
  if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
    {
643
      xwarning("%s", "Operation not executed." );
644
645
646
      return;
    }

647
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
648

649
650
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
651
652
653
654
655
656
657
658
659
660
  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
Deike Kleberg's avatar
Deike Kleberg committed
661
662
    @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
663
664

@Description
665
The function @func{gridDefYname} defines the name of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
666
667
668

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
669
void gridDefYname(int gridID, const char *yname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
670
{
671
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
672

673
674
  if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
    {
675
      xwarning("%s", "Operation not executed.");
676
677
678
      return;
    }

679
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
680

681
682
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
683
684
685
686
687
688
689
690
691
692
  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
Deike Kleberg's avatar
Deike Kleberg committed
693
694
    @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
695
696

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

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

705
706
  if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
    {
707
      xwarning("%s", "Operation not executed.");
708
709
710
      return;
    }

711
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
712

713
714
  grid_check_ptr(gridID, gridptr);

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

@Description
729
The function @func{gridDefYunits} defines the units of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
730
731
732

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
733
void gridDefYunits(int gridID, const char *yunits)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
734
{
735
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
736

737
738
  if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
    {
739
      xwarning("%s", "Operation not executed.");
740
741
742
      return;
    }

743
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
744

745
746
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
747
748
749
750
751
752
753
754
  if ( yunits )
    strcpy(gridptr->yunits, yunits);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
755
@Prototype void gridInqXname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
756
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
757
758
759
    @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
760
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
761
762

@Description
763
The function @func{gridInqXname} returns the name of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
764
765

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

@EndFunction
*/
void gridInqXname(int gridID, char *xname)
{
772
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
773

774
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
775

776
777
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
778
779
780
781
782
783
784
  strcpy(xname, gridptr->xname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
785
@Prototype void gridInqXlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
786
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
787
788
789
    @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
790
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
791
792

@Description
793
The function @func{gridInqXlongname} returns the longname of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
794
795

@Result
796
@func{gridInqXlongname} returns the longname of the X-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
797
798
799
800
801

@EndFunction
*/
void gridInqXlongname(int gridID, char *xlongname)
{
802
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
803

804
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
805

806
807
  grid_check_ptr(gridID, gridptr);

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

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

Deike Kleberg's avatar
Deike Kleberg committed
815
@Prototype void gridInqXunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
816
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
817
818
819
    @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
820
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
821
822

@Description
823
The function @func{gridInqXunits} returns the units of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
824
825

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

@EndFunction
*/
void gridInqXunits(int gridID, char *xunits)
{
832
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
833

834
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
835

836
837
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
838
839
840
841
842
843
  strcpy(xunits, gridptr->xunits);
}


void gridInqXstdname(int gridID, char *xstdname)
{
844
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
845

846
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
847

848
849
  grid_check_ptr(gridID, gridptr);

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

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

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

@Description
865
The function @func{gridInqYname} returns the name of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
866
867

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

@EndFunction
*/
void gridInqYname(int gridID, char *yname)
{
874
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
875

876
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
877

878
879
  grid_check_ptr(gridID, gridptr);

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

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

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

@Description
895
The function @func{gridInqYlongname} returns the longname of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
896
897

@Result
898
@func{gridInqYlongname} returns the longname of the Y-axis to the parameter longname.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
899
900
901
902
903

@EndFunction
*/
void gridInqYlongname(int gridID, char *ylongname)
{
904
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
905

906
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
907

908
909
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
910
911
912
913
914
915
916
  strcpy(ylongname, gridptr->ylongname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
917
@Prototype void gridInqYunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
918
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
919
920
921
    @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
922
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
923
924

@Description
925
The function @func{gridInqYunits} returns the units of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
926
927

@Result
928
@func{gridInqYunits} returns the units of the Y-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
929
930
931
932
933

@EndFunction
*/
void gridInqYunits(int gridID, char *yunits)
{
934
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
935

936
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
937

938
939
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
940
941
942
943
944
  strcpy(yunits, gridptr->yunits);
}

void gridInqYstdname(int gridID, char *ystdname)
{
945
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
946

947
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
948

949
950
  grid_check_ptr(gridID, gridptr);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
951
952
953
954
955
956
957
958
959
  strcpy(ystdname, gridptr->ystdname);
}

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

@Prototype int gridInqType(int gridID)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
960
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
961
962

@Description
963
The function @func{gridInqType} returns the type of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
964
965

@Result
966
@func{gridInqType} returns the type of the grid,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
967
one of the set of predefined CDI grid types.
968
The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
969
@func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL}, @func{GRID_GME},
970
@func{GRID_CURVILINEAR}, @func{GRID_UNSTRUCTURED} and @func{GRID_REFERENCE}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
971
972
973
974
975

@EndFunction
*/
int gridInqType(int gridID)
{
976
  grid_t *gridptr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
977

978
  gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
979

980
  grid_check_ptr(gridID, gridptr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
981
982
983
984
985
986
987
988
989
990
991

  return (gridptr->type);
}


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

@Prototype int gridInqSize(int gridID)
@Parameter
992
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
993
994

@Description
995
The function @func{gridInqSize} returns the size of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
996
997

@Result
998
@func{gridInqSize} returns the number of grid points of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
999
1000

@EndFunction