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

#include <string.h>
6
#include <float.h>  /* FLT_EPSILON */
7
#include <limits.h> /* INT_MAX     */
8

Uwe Schulzweida's avatar
Uwe Schulzweida committed
9
10
#include "dmemory.h"
#include "cdi.h"
11
#include "cdi_cksum.h"
12
#include "cdi_int.h"
13
#include "cdi_uuid.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
14
#include "grid.h"
15
#include "gaussgrid.h"
16
#include "resource_handle.h"
17
#include "resource_unpack.h"
18
#include "namespace.h"
19
#include "serialize.h"
20
21
22
23
#include "vlist.h"

#undef  UNDEFID
#define UNDEFID -1
Uwe Schulzweida's avatar
Uwe Schulzweida committed
24

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

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/* must match table below */
enum xystdname_idx {
  grid_xystdname_grid_latlon,
  grid_xystdname_latlon,
  grid_xystdname_projection,
};
static const char xystdname_tab[][2][24] = {
  [grid_xystdname_grid_latlon] = { "grid_longitude",
                                   "grid_latitude" },
  [grid_xystdname_latlon] = { "longitude",
                              "latitude" },
  [grid_xystdname_projection] = { "projection_x_coordinate",
                                  "projection_y_coordinate" },

};


Uwe Schulzweida's avatar
Uwe Schulzweida committed
63

64
65
66
static int    gridCompareP    ( void * gridptr1, void * gridptr2 );
static void   gridDestroyP    ( void * gridptr );
static void   gridPrintP      ( void * gridptr, FILE * fp );
67
static int    gridGetPackSize ( void * gridptr, void *context);
68
static void   gridPack        ( void * gridptr, void * buff, int size,
69
				int *position, void *context);
Deike Kleberg's avatar
minimal    
Deike Kleberg committed
70
static int    gridTxCode      ( void );
Uwe Schulzweida's avatar
Uwe Schulzweida committed
71

72
static const resOps gridOps = {
73
74
75
76
77
78
  gridCompareP,
  gridDestroyP,
  gridPrintP,
  gridGetPackSize,
  gridPack,
  gridTxCode
79
};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
80

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

83
#define gridID2Ptr(gridID) (grid_t *)reshGetVal(gridID, &gridOps)
84
#define gridMark4Update(gridID) reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
85

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

161

Deike Kleberg's avatar
Deike Kleberg committed
162
163
void grid_free(grid_t *gridptr)
{
164
165
166
167
168
169
170
171
172
173
  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);
Deike Kleberg's avatar
Deike Kleberg committed
174
175
176
177

  grid_init(gridptr);
}

178
179
static grid_t *
gridNewEntry(cdiResH resH)
180
{
181
  grid_t *gridptr = (grid_t*) Malloc(sizeof(grid_t));
182
183
184
185
186
187
188
189
  grid_init(gridptr);
  if (resH == CDI_UNDEFID)
    gridptr->self = reshPut(gridptr, &gridOps);
  else
    {
      gridptr->self = resH;
      reshReplace(resH, gridptr, &gridOps);
    }
190
  return gridptr;
191
192
}

193
static
194
void gridInit (void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
195
{
196
197
  static int gridInitialized = 0;
  char *env;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
198

199
  if ( gridInitialized ) return;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
200

Thomas Jahns's avatar
Thomas Jahns committed
201
  gridInitialized = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
202

203
204
  env = getenv("GRID_DEBUG");
  if ( env ) GRID_Debug = atoi(env);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
205
206
}

207
208
static
void grid_copy(grid_t *gridptr2, grid_t *gridptr1)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
209
210
211
212
{
  int gridID2;

  gridID2 = gridptr2->self;
213
  memcpy(gridptr2, gridptr1, sizeof(grid_t));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
214
215
216
  gridptr2->self = gridID2;
}

217
unsigned cdiGridCount(void)
Thomas Jahns's avatar
Thomas Jahns committed
218
{
219
  return reshCountType(&gridOps);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
220
221
}

222
223
224
225
226
227
228
229
230
231
232
233
234
235
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
262
263
static inline void
gridSetXname(grid_t *gridptr, const char *xname)
{
  strncpy(gridptr->xname, xname, CDI_MAX_NAME);
  gridptr->xname[CDI_MAX_NAME - 1] = 0;
}

static inline void
gridSetXlongname(grid_t *gridptr, const char *xlongname)
{
  strncpy(gridptr->xlongname, xlongname, CDI_MAX_NAME);
  gridptr->xlongname[CDI_MAX_NAME - 1] = 0;
}

static inline void
gridSetXunits(grid_t *gridptr, const char *xunits)
{
  strncpy(gridptr->xunits, xunits, CDI_MAX_NAME);
  gridptr->xunits[CDI_MAX_NAME - 1] = 0;
}

static inline void
gridSetYname(grid_t *gridptr, const char *yname)
{
  strncpy(gridptr->yname, yname, CDI_MAX_NAME);
  gridptr->yname[CDI_MAX_NAME - 1] = 0;
}

static inline void
gridSetYlongname(grid_t *gridptr, const char *ylongname)
{
  strncpy(gridptr->ylongname, ylongname, CDI_MAX_NAME);
  gridptr->ylongname[CDI_MAX_NAME - 1] = 0;
}

static inline void
gridSetYunits(grid_t *gridptr, const char *yunits)
{
  strncpy(gridptr->yunits, yunits, CDI_MAX_NAME);
  gridptr->yunits[CDI_MAX_NAME - 1] = 0;
}

264
265
// used also in CDO
void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *xvals)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
266
{
267
  if ( (! (fabs(xinc) > 0)) && xsize > 1 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
268
269
    {
      if ( xfirst >= xlast )
Thomas Jahns's avatar
Thomas Jahns committed
270
271
272
273
        {
          while ( xfirst >= xlast ) xlast += 360;
          xinc = (xlast-xfirst)/(xsize);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
274
      else
Thomas Jahns's avatar
Thomas Jahns committed
275
276
277
        {
          xinc = (xlast-xfirst)/(xsize-1);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
278
279
    }

280
  for ( int i = 0; i < xsize; ++i )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
281
282
283
    xvals[i] = xfirst + i*xinc;
}

284
285
static
void calc_gaussgrid(double *yvals, int ysize, double yfirst, double ylast)
286
{
287
  double *restrict yw = (double *) Malloc((size_t)ysize * sizeof(double));
288
  gaussaw(yvals, yw, (size_t)ysize);
289
  Free(yw);
290
  for (int i = 0; i < ysize; i++ )
291
292
293
294
    yvals[i] = asin(yvals[i])/M_PI*180.0;

  if ( yfirst < ylast && yfirst > -90.0 && ylast < 90.0 )
    {
295
296
      int yhsize = ysize/2;
      for (int i = 0; i < yhsize; i++ )
Thomas Jahns's avatar
Thomas Jahns committed
297
        {
298
          double ytmp = yvals[i];
Thomas Jahns's avatar
Thomas Jahns committed
299
300
301
          yvals[i] = yvals[ysize-i-1];
          yvals[ysize-i-1] = ytmp;
        }
302
303
304
    }
}

305
// used also in CDO
Thomas Jahns's avatar
Thomas Jahns committed
306
void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *restrict yvals)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
307
{
308
  const double deleps = 0.002;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
309
310
311
312

  if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
    {
      if ( ysize > 2 )
Deike Kleberg's avatar
Deike Kleberg committed
313
314
315
316
317
318
	{
	  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 )
	      {
319
		double *restrict ytmp = NULL;
Deike Kleberg's avatar
Deike Kleberg committed
320
		int nstart, lfound = 0;
321
		int ny = (int) (180./fabs(ylast-yfirst)/(ysize-1) + 0.5);
Deike Kleberg's avatar
Deike Kleberg committed
322
323
324
		ny -= ny%2;
		if ( ny > ysize && ny < 4096 )
		  {
325
		    ytmp = (double *) Malloc((size_t)ny * sizeof (double));
Deike Kleberg's avatar
Deike Kleberg committed
326
		    calc_gaussgrid(ytmp, ny, yfirst, ylast);
327
328
329
330
331
332
                    {
                      int i;
                      for ( i = 0; i < (ny-ysize); i++ )
                        if ( fabs(ytmp[i] - yfirst) < deleps ) break;
                      nstart = i;
                    }
Deike Kleberg's avatar
Deike Kleberg committed
333

334
335
		    lfound = (nstart+ysize-1) < ny
                      && fabs(ytmp[nstart+ysize-1] - ylast) < deleps;
336
337
338
339
                    if ( lfound )
                      {
                        for (int i = 0; i < ysize; i++) yvals[i] = ytmp[i+nstart];
                      }
Deike Kleberg's avatar
Deike Kleberg committed
340
341
		  }

342
		if ( !lfound )
Deike Kleberg's avatar
Deike Kleberg committed
343
344
		  {
		    Warning("Cannot calculate gaussian latitudes for lat1 = %g latn = %g!", yfirst, ylast);
345
		    for (int i = 0; i < ysize; i++ ) yvals[i] = 0;
Deike Kleberg's avatar
Deike Kleberg committed
346
347
348
349
		    yvals[0] = yfirst;
		    yvals[ysize-1] = ylast;
		  }

350
		if ( ytmp ) Free(ytmp);
Deike Kleberg's avatar
Deike Kleberg committed
351
352
	      }
	}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
353
      else
Thomas Jahns's avatar
Thomas Jahns committed
354
355
356
357
        {
          yvals[0] = yfirst;
          yvals[ysize-1] = ylast;
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
358
359
360
361
    }
  /*     else if ( gridtype == GRID_LONLAT || gridtype == GRID_GENERIC ) */
  else
    {
362
      if ( (! (fabs(yinc) > 0)) && ysize > 1 )
Thomas Jahns's avatar
Thomas Jahns committed
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
        {
          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
384
385
386

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

387
      for (int i = 0; i < ysize; i++ )
Thomas Jahns's avatar
Thomas Jahns committed
388
        yvals[i] = yfirst + i*yinc;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
389
390
391
    }
  /*
    else
392
    Error("unable to calculate values for %s grid!", gridNamePtr(gridtype));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
393
394
395
396
  */
}

/*
397
@Function  gridCreate
398
@Title     Create a horizontal Grid
Uwe Schulzweida's avatar
Uwe Schulzweida committed
399

400
@Prototype int gridCreate(int gridtype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
401
402
@Parameter
    @Item  gridtype  The type of the grid, one of the set of predefined CDI grid types.
403
                     The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
404
                     @func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL},
405
                     @func{GRID_GME}, @func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED} and.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
406
407
408
    @Item  size      Number of gridpoints.

@Description
409
The function @func{gridCreate} creates a horizontal Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
410
411

@Result
412
@func{gridCreate} returns an identifier to the Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
413
414

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

@Source
Uwe Schulzweida's avatar
Uwe Schulzweida committed
418
419
#include "cdi.h"
   ...
420
421
#define  nlon  12
#define  nlat   6
Uwe Schulzweida's avatar
Uwe Schulzweida committed
422
   ...
423
424
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
425
426
int gridID;
   ...
427
428
429
gridID = gridCreate(GRID_LONLAT, nlon*nlat);
gridDefXsize(gridID, nlon);
gridDefYsize(gridID, nlat);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
430
431
432
433
gridDefXvals(gridID, lons);
gridDefYvals(gridID, lats);
   ...
@EndSource
Uwe Schulzweida's avatar
Uwe Schulzweida committed
434
435
@EndFunction
*/
436
int gridCreate(int gridtype, int size)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
437
{
438
  if ( CDI_Debug ) Message("gridtype=%s  size=%d", gridNamePtr(gridtype), size);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
439

440
  if ( size < 0 || size > INT_MAX ) Error("Grid size (%d) out of bounds (0 - %d)!", size, INT_MAX);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
441

442
  gridInit();
443

Uwe Schulzweida's avatar
Uwe Schulzweida committed
444
  grid_t *gridptr = gridNewEntry(CDI_UNDEFID);
445
  if ( ! gridptr ) Error("No memory");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
446

Uwe Schulzweida's avatar
Uwe Schulzweida committed
447
  int gridID = gridptr->self;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
448

449
  if ( CDI_Debug ) Message("gridID: %d", gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
450
451
452
453
454

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

  /*  if ( gridtype == GRID_GENERIC )     gridptr->xsize = size; */
455
456
  if ( gridtype == GRID_UNSTRUCTURED )  gridptr->xsize = size;
  if ( gridtype == GRID_CURVILINEAR  )  gridptr->nvertex = 4;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
457
458
459
460
461
462
463
464
465

  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
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
        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 )
          {
482
483
            gridptr->xstdname = xystdname_tab[grid_xystdname_grid_latlon][0];
            gridptr->ystdname = xystdname_tab[grid_xystdname_grid_latlon][1];
Thomas Jahns's avatar
Thomas Jahns committed
484
485
486
487
488
489
            gridDefXunits(gridID, "degrees");
            gridDefYunits(gridID, "degrees");
          }
        else
        */
          {
490
491
            gridptr->xstdname = xystdname_tab[grid_xystdname_latlon][0];
            gridptr->ystdname = xystdname_tab[grid_xystdname_latlon][1];
Thomas Jahns's avatar
Thomas Jahns committed
492
493
494
495
496
            gridDefXunits(gridID, "degrees_east");
            gridDefYunits(gridID, "degrees_north");
          }

        break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
497
498
      }
    case GRID_GME:
499
    case GRID_UNSTRUCTURED:
500
      {
Thomas Jahns's avatar
Thomas Jahns committed
501
502
        gridDefXname(gridID, "lon");
        gridDefYname(gridID, "lat");
503
504
        gridptr->xstdname = xystdname_tab[grid_xystdname_latlon][0];
        gridptr->ystdname = xystdname_tab[grid_xystdname_latlon][1];
Thomas Jahns's avatar
Thomas Jahns committed
505
506
507
        gridDefXunits(gridID, "degrees_east");
        gridDefYunits(gridID, "degrees_north");
        break;
508
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
509
510
    case GRID_GENERIC:
      {
Thomas Jahns's avatar
Thomas Jahns committed
511
512
        gridDefXname(gridID, "x");
        gridDefYname(gridID, "y");
513
        /*
Thomas Jahns's avatar
Thomas Jahns committed
514
515
        strcpy(gridptr->xstdname, "grid_longitude");
        strcpy(gridptr->ystdname, "grid_latitude");
516
517
        gridptr->xstdname = xystdname_tab[grid_xystdname_grid_latlon][0];
        gridptr->ystdname = xystdname_tab[grid_xystdname_grid_latlon][1];
Thomas Jahns's avatar
Thomas Jahns committed
518
519
        gridDefXunits(gridID, "degrees");
        gridDefYunits(gridID, "degrees");
520
        */
Thomas Jahns's avatar
Thomas Jahns committed
521
        break;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
522
      }
523
    case GRID_LCC2:
524
    case GRID_SINUSOIDAL:
525
    case GRID_LAEA:
526
      {
Thomas Jahns's avatar
Thomas Jahns committed
527
528
        gridDefXname(gridID, "x");
        gridDefYname(gridID, "y");
529
530
        gridptr->xstdname = xystdname_tab[grid_xystdname_projection][0];
        gridptr->ystdname = xystdname_tab[grid_xystdname_projection][1];
Thomas Jahns's avatar
Thomas Jahns committed
531
532
533
        gridDefXunits(gridID, "m");
        gridDefYunits(gridID, "m");
        break;
534
      }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
535
536
537
538
539
    }

  return (gridID);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
540
541
static
void gridDestroyKernel( grid_t * gridptr )
542
543
544
{
  int id;

Deike Kleberg's avatar
Deike Kleberg committed
545
  xassert ( gridptr );
546
547
548

  id = gridptr->self;

549
550
551
552
553
554
555
556
557
  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);
558

Uwe Schulzweida's avatar
Uwe Schulzweida committed
559
  Free( gridptr );
560

561
  reshRemove ( id, &gridOps );
562
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
563

564
565
566
567
568
569
/*
@Function  gridDestroy
@Title     Destroy a horizontal Grid

@Prototype void gridDestroy(int gridID)
@Parameter
Deike Kleberg's avatar
Deike Kleberg committed
570
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
571
572
573
574
575

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

578
  gridDestroyKernel ( gridptr );
579
580
}

581
void gridDestroyP ( void * gridptr )
582
{
583
  gridDestroyKernel (( grid_t * ) gridptr );
584
585
586
}


587
const char *gridNamePtr(int gridtype)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
588
{
589
  int size = (int) (sizeof(Grids)/sizeof(Grids[0]));
Uwe Schulzweida's avatar
Uwe Schulzweida committed
590

591
  const char *name = gridtype >= 0 && gridtype < size ? Grids[gridtype] : Grids[GRID_GENERIC];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607

  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
608
609
    @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
610
611

@Description
612
The function @func{gridDefXname} defines the name of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
613
614
615

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
616
void gridDefXname(int gridID, const char *xname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
617
{
618
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
619

620
621
  if ( xname )
    {
622
      gridSetXname(gridptr, xname);
623
      gridMark4Update(gridID);
624
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
625
626
}

627

Uwe Schulzweida's avatar
Uwe Schulzweida committed
628
629
630
631
632
633
/*
@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
634
635
    @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
636
637

@Description
638
The function @func{gridDefXlongname} defines the longname of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
639
640
641

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
642
void gridDefXlongname(int gridID, const char *xlongname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
643
{
644
  grid_t *gridptr = gridID2Ptr(gridID);
645
646
  if ( xlongname )
    {
647
      gridSetXlongname(gridptr, xlongname);
648
      gridMark4Update(gridID);
649
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
650
651
652
653
654
655
656
657
}

/*
@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
658
659
    @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
660
661

@Description
662
The function @func{gridDefXunits} defines the units of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
663
664
665

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
666
void gridDefXunits(int gridID, const char *xunits)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
667
{
668
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
669

670
671
  if ( xunits )
    {
672
      gridSetXunits(gridptr, xunits);
673
      gridMark4Update(gridID);
674
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
675
676
677
678
679
680
681
682
}

/*
@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
683
684
    @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
685
686

@Description
687
The function @func{gridDefYname} defines the name of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
688
689
690

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
691
void gridDefYname(int gridID, const char *yname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
692
{
693
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
694

695
696
  if ( yname )
    {
697
      gridSetYname(gridptr, yname);
698
      gridMark4Update(gridID);
699
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
700
701
702
703
704
705
706
707
}

/*
@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
708
709
    @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
710
711

@Description
712
The function @func{gridDefYlongname} defines the longname of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
713
714
715

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
716
void gridDefYlongname(int gridID, const char *ylongname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
717
{
718
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
719

720
721
  if ( ylongname )
    {
722
      gridSetYlongname(gridptr, ylongname);
723
      gridMark4Update(gridID);
724
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
725
726
727
728
729
730
731
732
}

/*
@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
733
734
    @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
735
736

@Description
737
The function @func{gridDefYunits} defines the units of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
738
739
740

@EndFunction
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
741
void gridDefYunits(int gridID, const char *yunits)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
742
{
743
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
744

745
746
  if ( yunits )
    {
747
      gridSetYunits(gridptr, yunits);
748
      gridMark4Update(gridID);
749
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
750
751
752
753
754
755
}

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

Deike Kleberg's avatar
Deike Kleberg committed
756
@Prototype void gridInqXname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
757
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
758
759
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
    @Item  name     Name of the X-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
760
                    returned string. The maximum possible length, in characters, of
761
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
762
763

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

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

@EndFunction
*/
void gridInqXname(int gridID, char *xname)
{
773
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
774
775
776
777
778
779
780
781

  strcpy(xname, gridptr->xname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
782
@Prototype void gridInqXlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
783
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
784
785
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
    @Item  longname Longname of the X-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
786
                    returned string. The maximum possible length, in characters, of
787
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
788
789

@Description
790
The function @func{gridInqXlongname} returns the longname of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
791
792

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

@EndFunction
*/
void gridInqXlongname(int gridID, char *xlongname)
{
799
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
800
801
802
803
804
805
806
807

  strcpy(xlongname, gridptr->xlongname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
808
@Prototype void gridInqXunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
809
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
810
811
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
    @Item  units    Units of the X-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
812
                    returned string. The maximum possible length, in characters, of
813
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
814
815

@Description
816
The function @func{gridInqXunits} returns the units of a X-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
817
818

@Result
819
@func{gridInqXunits} returns the units of the X-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
820
821
822
823
824

@EndFunction
*/
void gridInqXunits(int gridID, char *xunits)
{
825
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
826
827
828
829
830
831
832

  strcpy(xunits, gridptr->xunits);
}


void gridInqXstdname(int gridID, char *xstdname)
{
833
  grid_t *gridptr = gridID2Ptr(gridID);
834
835
836
837
  if ( gridptr->xstdname )
    strcpy(xstdname, gridptr->xstdname);
  else
    xstdname[0] = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
838
839
840
841
842
843
}

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

Deike Kleberg's avatar
Deike Kleberg committed
844
@Prototype void gridInqYname(int gridID, char *name)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
845
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
846
847
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
    @Item  name     Name of the Y-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
848
                    returned string. The maximum possible length, in characters, of
849
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
850
851

@Description
852
The function @func{gridInqYname} returns the name of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
853
854

@Result
855
@func{gridInqYname} returns the name of the Y-axis to the parameter name.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
856
857
858
859
860

@EndFunction
*/
void gridInqYname(int gridID, char *yname)
{
861
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
862
863
864
865
866
867
868
869

  strcpy(yname, gridptr->yname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
870
@Prototype void gridInqXlongname(int gridID, char *longname)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
871
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
872
873
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
    @Item  longname Longname of the Y-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
874
                    returned string. The maximum possible length, in characters, of
875
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
876
877

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

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

@EndFunction
*/
void gridInqYlongname(int gridID, char *ylongname)
{
887
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
888
889
890
891
892
893
894
895

  strcpy(ylongname, gridptr->ylongname);
}

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

Deike Kleberg's avatar
Deike Kleberg committed
896
@Prototype void gridInqYunits(int gridID, char *units)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
897
@Parameter
Uwe Schulzweida's avatar
Uwe Schulzweida committed
898
899
    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
    @Item  units    Units of the Y-axis. The caller must allocate space for the
Deike Kleberg's avatar
Deike Kleberg committed
900
                    returned string. The maximum possible length, in characters, of
901
                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
902
903

@Description
904
The function @func{gridInqYunits} returns the units of a Y-axis.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
905
906

@Result
907
@func{gridInqYunits} returns the units of the Y-axis to the parameter units.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
908
909
910
911
912

@EndFunction
*/
void gridInqYunits(int gridID, char *yunits)
{
913
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
914
915
916
917
918
919

  strcpy(yunits, gridptr->yunits);
}

void gridInqYstdname(int gridID, char *ystdname)
{
920
  grid_t *gridptr = gridID2Ptr(gridID);
921
922
923
924
  if ( gridptr->ystdname )
    strcpy(ystdname, gridptr->ystdname);
  else
    ystdname[0] = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
925
926
927
928
929
930
931
932
}

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

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

@Description
936
The function @func{gridInqType} returns the type of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
937
938

@Result
939
@func{gridInqType} returns the type of the grid,
Uwe Schulzweida's avatar
Uwe Schulzweida committed
940
one of the set of predefined CDI grid types.
941
The valid CDI grid types are @func{GRID_GENERIC}, @func{GRID_GAUSSIAN},
Uwe Schulzweida's avatar
Uwe Schulzweida committed
942
@func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL}, @func{GRID_GME},
943
@func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED}.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
944
945
946
947
948

@EndFunction
*/
int gridInqType(int gridID)
{
949
  grid_t *gridptr = gridID2Ptr(gridID);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
950
951
952
953
954
955
956
957
958
959
960

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

@Description
964
The function @func{gridInqSize} returns the size of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
965
966

@Result
967
@func{gridInqSize} returns the number of grid points of a Grid.
Uwe Schulzweida's avatar
Uwe Schulzweida committed
968
969
970
971
972

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
975
  int size = gridptr->size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
976
977
978
979
980
981
982
983
984

  if ( ! size )
    {
      int xsize, ysize;

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

      if ( ysize )
Thomas Jahns's avatar
Thomas Jahns committed
985
        size = xsize *ysize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
986
      else
Thomas Jahns's avatar
Thomas Jahns committed
987
        size = xsize;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
988

Thomas Jahns's avatar
Thomas Jahns committed
989
      gridptr->size = size;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
990
991
992
993
994
    }

  return (size);
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
995
996
static
int nsp2trunc(int nsp)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
997
998
999
1000
{
  /*  nsp = (trunc+1)*(trunc+1)              */
  /*      => trunc^2 + 3*trunc - (x-2) = 0   */
  /*                                         */
For faster browsing, not all history is shown. View entire blame