1 /**
2 * @file mergedx.c
3 * @author Stephen Bond and Nathan Baker
4 * @brief Program that merges OpenDX files
5 * @version $Id$
6 */
7
8 #include "apbs.h"
9
10 #define SHORTINT short
11 #define IJK(i,j,k) (((k)*(nx)*(ny))+((j)*(nx))+(i))
12 #define INTERVAL(x,a,b) (((x) >= (a)) && ((x) <= (b)))
13
14 VEMBED(rcsid="$Id$")
15
16 VPRIVATE int Vgrid_readDXhead(Vgrid *thee,
17 const char *iodev, const char *iofmt, const char *thost, const char *fname);
18 VPRIVATE int Vgrid_value2(Vgrid *thee, double pt[3], double *value);
19 VPRIVATE int Char_parseARGV(int argc, char **argv, int *nx, int *ny, int *nz,
20 int *pad, char ***fnams, int *numfnams, char *outname, int *vflag);
21
22 VPRIVATE char *MCwhiteChars = " =,;\t\n";
23 VPRIVATE char *MCcommChars = "#%";
24
main(int argc,char ** argv)25 int main(int argc, char **argv) {
26
27 /* *************** VARIABLES ******************* */
28 int i, j, k, vlev = 1, vvlev = 0, vflag = 1;
29 int nx, ny, nz, count, numfnams;
30 double pt[3],value;
31 double xmin, ymin, zmin, xmax, ymax, zmax;
32 char **fnams = VNULL;
33 SHORTINT *carray = VNULL;
34 char *usage0 = "[FLAGS] nx ny nz file1.dx [file2.dx ...]\n";
35 char *req0 = "nx ny nz Grid points on the merged grid";
36 char *req1 = "file1.dx Names of unmerged grid files";
37 char *flag0 = "-v Verbose (default: off)";
38 char *flag1 = "-quiet Silent (default: off)";
39 char *flag2 = "-pad integer Num. of pad grid points (default: 1 )";
40 char *flag3 = "-o filename.dx Output file (default: gridmerged.dx)";
41 char *note0 = "Each subgrid is extended by the number of pad points,";
42 char *note1 = "which is often necessary to fill gaps between the grids.";
43 char *note2 = "Any overlap between subgrids is resolved by averaging.";
44 char *snam = "# main: ";
45 char outname[80];
46 Vgrid *grid, *mgrid;
47 int pad = 1;
48
49 Vio_start();
50 sprintf(outname,"gridmerged.dx");
51
52 /* **************** OBSOLETE WARNING ***************** */
53 printf("WARNING: mergedx is deprecated. Please consider using mergedx2\n");
54
55 /* **************** PARSE INPUT ARGS ***************** */
56
57 if ( Char_parseARGV(argc, argv, &nx, &ny, &nz, &pad,
58 &fnams, &numfnams, outname, &vflag) != 0 ) {
59 Vnm_print(2,"\nImproper or Unrecognized Switches?\nUsage: ");
60 Vnm_print(2,"%s %s\n",argv[0],usage0);
61 Vnm_print(2,"Input:\t\t%s\n\t\t%s\n\n", req0, req1);
62 Vnm_print(2,"Flags:\t\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\n",
63 flag0, flag1, flag2, flag3);
64 Vnm_print(2,"Notes:\t\t%s\n\t\t%s\n\t\t%s\n",
65 note0, note1, note2);
66 return -1;
67 }
68
69 if (vflag == 1) {
70 vlev = 1;
71 vvlev = 0;
72 } else if (vflag) {
73 vlev = 2;
74 vvlev = 2;
75 } else {
76 vlev = 0;
77 vvlev = 0;
78 }
79
80 /* *********** PREPARE MERGED GRID OBJECT ************* */
81 mgrid = Vgrid_ctor(nx, ny, nz, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, VNULL);
82 mgrid->xmin = VLARGE; mgrid->xmax = -VLARGE;
83 mgrid->ymin = VLARGE; mgrid->ymax = -VLARGE;
84 mgrid->zmin = VLARGE; mgrid->zmax = -VLARGE;
85
86 /* *************** GET FILE HEADERS ******************* */
87 Vnm_print(vlev, "%s Reading Headers...\n",snam);
88 grid = Vgrid_ctor(0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, VNULL);
89 for(count=0; count<numfnams; count++) {
90 Vnm_print(vvlev, "%s Reading header from %s...\n",snam,
91 fnams[count]);
92 Vnm_tstart(26, "HEADER READ");
93 Vgrid_readDXhead(grid, "FILE", "ASC", VNULL, fnams[count]);
94 Vnm_tstop(26, "HEADER READ");
95 /* set the merged grid bounds to include all the subgrids */
96 if( grid->xmin < mgrid->xmin ) mgrid->xmin = grid->xmin;
97 if( grid->xmax > mgrid->xmax ) mgrid->xmax = grid->xmax;
98 if( grid->ymin < mgrid->ymin ) mgrid->ymin = grid->ymin;
99 if( grid->ymax > mgrid->ymax ) mgrid->ymax = grid->ymax;
100 if( grid->zmin < mgrid->zmin ) mgrid->zmin = grid->zmin;
101 if( grid->zmax > mgrid->zmax ) mgrid->zmax = grid->zmax;
102 }
103
104 /* set the grid increment for the merged grid */
105 mgrid->hx = (mgrid->xmax - mgrid->xmin)/(mgrid->nx - 1);
106 mgrid->hy = (mgrid->ymax - mgrid->ymin)/(mgrid->ny - 1);
107 mgrid->hzed = (mgrid->zmax - mgrid->zmin)/(mgrid->nz - 1);
108
109 /* print out the dimensions of the merged grid */
110 Vnm_print(vlev, "%s Dimensions of the merged grid\n",snam);
111 Vnm_print(vlev, "%s nx = %d, ny = %d, nz = %d\n",snam,
112 mgrid->nx, mgrid->ny, mgrid->nz);
113 Vnm_print(vlev, "%s hx = %g, hy = %g, hz = %g\n",snam,
114 mgrid->hx, mgrid->hy, mgrid->hzed);
115 Vnm_print(vlev, "%s xmin = %g, ymin = %g, zmin = %g\n",snam,
116 mgrid->xmin, mgrid-> ymin, mgrid->zmin);
117 Vnm_print(vlev, "%s xmax = %g, ymax = %g, zmax = %g\n",snam,
118 mgrid->xmax, mgrid-> ymax, mgrid->zmax);
119
120 mgrid->data = (double *)
121 Vmem_malloc(mgrid->mem,(mgrid->nx*mgrid->ny*mgrid->nz),sizeof(double));
122 mgrid->ctordata = 1;
123 carray = (SHORTINT *)
124 Vmem_malloc(VNULL, (mgrid->nx*mgrid->ny*mgrid->nz), sizeof(SHORTINT) );
125
126 /* initialize the data of the merged grid with zeros */
127 nx = mgrid->nx;
128 ny = mgrid->ny;
129 nz = mgrid->nz;
130 for (i=0; i<nx; i++) {
131 for (j=0; j<ny; j++) {
132 for (k=0; k<nz; k++) {
133 (mgrid->data)[IJK(i,j,k)] = 0.0;
134 carray[IJK(i,j,k)] = 0;
135 }
136 }
137 }
138
139 /* ************** MERGE THE GRID FILES **************** */
140 Vnm_print(vlev, "%s Reading and Merging...\n",snam);
141 for (count=0; count<numfnams; count++) {
142 Vnm_print(vvlev, "%s Reading data from %s...\n",snam,fnams[count]);
143 Vnm_tstart(26, "DATA READ");
144 Vgrid_readDX(grid, "FILE", "ASC", VNULL, fnams[count]);
145 Vnm_tstop(26, "DATA READ");
146 Vnm_print(vvlev, "%s Merging data from %s...\n",snam,fnams[count]);
147 Vnm_tstart(26, "MERGING");
148 xmin = grid->xmin - pad*grid->hx - VSMALL;
149 ymin = grid->ymin - pad*grid->hy - VSMALL;
150 zmin = grid->zmin - pad*grid->hzed - VSMALL;
151 xmax = grid->xmax + pad*grid->hx + VSMALL;
152 ymax = grid->ymax + pad*grid->hy + VSMALL;
153 zmax = grid->zmax + pad*grid->hzed + VSMALL;
154 Vnm_print(vvlev, "%s MIN (%g,%g,%g) IMIN (%g,%g,%g)\n",snam,
155 grid->xmin,grid->ymin,grid->zmin,xmin,ymin,zmin);
156 Vnm_print(vvlev, "%s MAX (%g,%g,%g) IMAX (%g,%g,%g)\n",snam,
157 grid->xmax,grid->ymax,grid->zmax,xmax,ymax,zmax);
158 for (i=0; i<nx; i++) {
159 pt[0] = mgrid->xmin + i*mgrid->hx;
160 if(INTERVAL(pt[0],xmin,xmax)) {
161 for (j=0; j<ny; j++) {
162 pt[1] = mgrid->ymin + j*mgrid->hy;
163 if(INTERVAL(pt[1],ymin,ymax)) {
164 for (k=0; k<nz; k++) {
165 pt[2] = mgrid->zmin + k*mgrid->hzed;
166 if(INTERVAL(pt[2],zmin,zmax)) {
167 if (Vgrid_value2(grid, pt, &value)) {
168 (mgrid->data)[IJK(i,j,k)] += value;
169 carray[IJK(i,j,k)] += 1;
170 }
171 }
172 }
173 }
174 }
175 }
176 }
177 Vnm_tstop(26, "MERGING");
178 Vmem_free(grid->mem,(grid->nx*grid->ny*grid->nz), sizeof(double),
179 (void **)&(grid->data));
180 grid->readdata = 0;
181 grid->ctordata = 0;
182 }
183 Vgrid_dtor( &grid );
184
185 mgrid->readdata = 1;
186
187 /* Check for skipped points, and account for overlap */
188 nx = mgrid->nx;
189 ny = mgrid->ny;
190 nz = mgrid->nz;
191 for (i=0; i<nx; i++) {
192 for (j=0; j<ny; j++) {
193 for (k=0; k<nz; k++) {
194 if ( carray[IJK(i,j,k)] >= 1 ) {
195 (mgrid->data)[IJK(i,j,k)] /= carray[IJK(i,j,k)];
196 } else {
197 Vnm_print(2,"%s %s %s (%g,%g,%g)\n",snam,
198 "Warning: ",
199 "Gap in subgrids at point",
200 mgrid->xmin + i*mgrid->hx,
201 mgrid->ymin + j*mgrid->hy,
202 mgrid->zmin + k*mgrid->hzed );
203 }
204 }
205 }
206 }
207
208 /* ************** WRITE THE MERGED GRID **************** */
209 Vnm_print(vlev, "%s Writing...\n",snam);
210 Vnm_print(vvlev, "%s Writing merged data to %s...\n",snam,outname);
211 Vgrid_writeDX(mgrid, "FILE", "ASC", VNULL, outname,"mergedx",VNULL);
212
213 Vmem_free(VNULL,(mgrid->nx*mgrid->ny*mgrid->nz), sizeof(SHORTINT),
214 (void **)&(carray));
215 Vgrid_dtor( &mgrid );
216
217 if ( vflag > 1 ) {
218 Vnm_print(2,"%s Memory Profiling Information\n",snam);
219 Vnm_print(2,"# --------------------------------------"
220 "--------------------------------------\n");
221 Vnm_print(2,"# Footprint Areas Malloc Free"
222 " Highwater Class\n");
223 Vnm_print(2,"# --------------------------------------"
224 "--------------------------------------\n");
225 Vmem_print(VNULL);
226 Vmem_printTotal();
227 Vnm_print(2,"# --------------------------------------"
228 "--------------------------------------\n");
229 }
230
231 return 0;
232 }
233
234 /* ///////////////////////////////////////////////////////////////////////////
235 // Routine: Vgrid_readDXhead
236 //
237 // Author: Nathan Baker and Stephen Bond
238 /////////////////////////////////////////////////////////////////////////// */
Vgrid_readDXhead(Vgrid * thee,const char * iodev,const char * iofmt,const char * thost,const char * fname)239 VPRIVATE int Vgrid_readDXhead(Vgrid *thee,
240 const char *iodev, const char *iofmt, const char *thost, const char *fname) {
241
242 int itmp;
243 double dtmp;
244 char tok[VMAX_BUFSIZE];
245 char *snam = "Vgrid_readDXhead:";
246 Vio *sock;
247
248 /* Check to see if the existing data is null and, if not, clear it out */
249 if (thee->data != VNULL) {
250 Vnm_print(1, "%s destroying existing data!\n",snam);
251 Vmem_free(thee->mem, (thee->nx*thee->ny*thee->nz), sizeof(double),
252 (void **)&(thee->data)); }
253 thee->readdata = 0;
254 thee->ctordata = 0;
255
256 /* Set up the virtual socket */
257 sock = Vio_ctor(iodev,iofmt,thost,fname,"r");
258 if (sock == VNULL) {
259 Vnm_print(2, "%s Problem opening virtual socket %s\n",snam,fname);
260 return 0;
261 }
262 if (Vio_accept(sock, 0) < 0) {
263 Vnm_print(2, "%s Problem accepting virtual socket %s\n",snam,fname);
264 return 0;
265 }
266
267 Vio_setWhiteChars(sock, MCwhiteChars);
268 Vio_setCommChars(sock, MCcommChars);
269
270 /* Read in the DX regular positions */
271 /* Get "object" */
272 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
273 VJMPERR1(!strcmp(tok, "object"));
274 /* Get "1" */
275 VJMPERR2(1 == Vio_scanf(sock, "%d", &itmp));
276 /* Get "class" */
277 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
278 VJMPERR1(!strcmp(tok, "class"));
279 /* Get "gridpositions" */
280 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
281 VJMPERR1(!strcmp(tok, "gridpositions"));
282 /* Get "counts" */
283 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
284 VJMPERR1(!strcmp(tok, "counts"));
285 /* Get nx */
286 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
287 VJMPERR1(1 == sscanf(tok, "%d", &(thee->nx)));
288 /* Get ny */
289 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
290 VJMPERR1(1 == sscanf(tok, "%d", &(thee->ny)));
291 /* Get nz */
292 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
293 VJMPERR1(1 == sscanf(tok, "%d", &(thee->nz)));
294 Vnm_print(0, "%s Grid dimensions %d x %d x %d grid\n",snam,
295 thee->nx, thee->ny, thee->nz);
296 /* Get "origin" */
297 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
298 VJMPERR1(!strcmp(tok, "origin"));
299 /* Get xmin */
300 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
301 VJMPERR1(1 == sscanf(tok, "%lf", &(thee->xmin)));
302 /* Get ymin */
303 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
304 VJMPERR1(1 == sscanf(tok, "%lf", &(thee->ymin)));
305 /* Get zmin */
306 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
307 VJMPERR1(1 == sscanf(tok, "%lf", &(thee->zmin)));
308 Vnm_print(0, "%s Grid origin = (%g, %g, %g)\n",snam,
309 thee->xmin, thee->ymin, thee->zmin);
310 /* Get "delta" */
311 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
312 VJMPERR1(!strcmp(tok, "delta"));
313 /* Get hx */
314 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
315 VJMPERR1(1 == sscanf(tok, "%lf", &(thee->hx)));
316 /* Get 0.0 */
317 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
318 VJMPERR1(1 == sscanf(tok, "%lf", &dtmp));
319 VJMPERR1(dtmp == 0.0);
320 /* Get 0.0 */
321 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
322 VJMPERR1(1 == sscanf(tok, "%lf", &dtmp));
323 VJMPERR1(dtmp == 0.0);
324 /* Get "delta" */
325 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
326 VJMPERR1(!strcmp(tok, "delta"));
327 /* Get 0.0 */
328 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
329 VJMPERR1(1 == sscanf(tok, "%lf", &dtmp));
330 VJMPERR1(dtmp == 0.0);
331 /* Get hy */
332 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
333 VJMPERR1(1 == sscanf(tok, "%lf", &(thee->hy)));
334 /* Get 0.0 */
335 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
336 VJMPERR1(1 == sscanf(tok, "%lf", &dtmp));
337 VJMPERR1(dtmp == 0.0);
338 /* Get "delta" */
339 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
340 VJMPERR1(!strcmp(tok, "delta"));
341 /* Get 0.0 */
342 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
343 VJMPERR1(1 == sscanf(tok, "%lf", &dtmp));
344 VJMPERR1(dtmp == 0.0);
345 /* Get 0.0 */
346 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
347 VJMPERR1(1 == sscanf(tok, "%lf", &dtmp));
348 VJMPERR1(dtmp == 0.0);
349 /* Get hz */
350 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
351 VJMPERR1(1 == sscanf(tok, "%lf", &(thee->hzed)));
352 Vnm_print(0, "%s Grid spacings = (%g, %g, %g)\n",snam,
353 thee->hx, thee->hy, thee->hzed);
354 /* calculate grid maxima */
355 thee->xmax = thee->xmin + (thee->nx-1)*thee->hx;
356 thee->ymax = thee->ymin + (thee->ny-1)*thee->hy;
357 thee->zmax = thee->zmin + (thee->nz-1)*thee->hzed;
358
359 /* Close off the socket */
360 Vio_acceptFree(sock);
361 Vio_dtor(&sock);
362
363 return 1;
364
365 VERROR1:
366 Vio_dtor(&sock);
367 Vnm_print(2, "%s Format problem with input file <%s>\n",snam,fname);
368 return 0;
369
370 VERROR2:
371 Vio_dtor(&sock);
372 Vnm_print(2, "%s I/O problem with input file <%s>\n",snam,fname);
373 return 0;
374 }
375
376 /* ///////////////////////////////////////////////////////////////////////////
377 // Routine: Vgrid_value2
378 //
379 // Author: Nathan Baker and Stephen Bond
380 /////////////////////////////////////////////////////////////////////////// */
Vgrid_value2(Vgrid * thee,double pt[3],double * value)381 VPUBLIC int Vgrid_value2(Vgrid *thee, double pt[3], double *value) {
382
383 int nx, ny, nz, ihi, jhi, khi, ilo, jlo, klo;
384 double hx, hy, hzed, xmin, ymin, zmin, ifloat, jfloat, kfloat;
385 double u, dx, dy, dz;
386
387 VASSERT(thee != VNULL);
388 VASSERT(thee->ctordata || thee->readdata);
389
390 nx = thee->nx;
391 ny = thee->ny;
392 nz = thee->nz;
393 hx = thee->hx;
394 hy = thee->hy;
395 hzed = thee->hzed;
396 xmin = thee->xmin;
397 ymin = thee->ymin;
398 zmin = thee->zmin;
399
400 u = 0;
401
402 ifloat = (pt[0] - xmin)/hx;
403 jfloat = (pt[1] - ymin)/hy;
404 kfloat = (pt[2] - zmin)/hzed;
405 ihi = (int)ceil(ifloat);
406 jhi = (int)ceil(jfloat);
407 khi = (int)ceil(kfloat);
408 ilo = (int)floor(ifloat);
409 jlo = (int)floor(jfloat);
410 klo = (int)floor(kfloat);
411
412 /* If the point is outside the mesh, push it to the mesh */
413 if ( ilo < 0 ) {
414 ilo = 0;
415 ihi = ilo + 1;
416 ifloat = (double)(ilo);
417 } else if ( ihi >= nx ) {
418 ihi = nx - 1;
419 ilo = ihi - 1;
420 ifloat = (double)(ihi);
421 }
422 if ( jlo < 0 ) {
423 jlo = 0;
424 jhi = jlo + 1;
425 jfloat = (double)(jlo);
426 } else if ( jhi >= ny ) {
427 jhi = ny - 1;
428 jlo = jhi - 1;
429 jfloat = (double)(jhi);
430 }
431 if ( klo < 0 ) {
432 klo = 0;
433 khi = klo + 1;
434 kfloat = (double)(klo);
435 } else if ( khi >= nz ) {
436 khi = nz - 1;
437 klo = khi - 1;
438 kfloat = (double)(khi);
439 }
440
441 /* See if we're on the mesh */
442 if ((ihi<nx) && (jhi<ny) && (khi<nz) &&
443 (ilo>=0) && (jlo>=0) && (klo>=0)) {
444 dx = ifloat - (double)(ilo);
445 dy = jfloat - (double)(jlo);
446 dz = kfloat - (double)(klo);
447 u = dx *dy *dz *(thee->data[IJK(ihi,jhi,khi)])
448 + dx *(1.0-dy)*dz *(thee->data[IJK(ihi,jlo,khi)])
449 + dx *dy *(1.0-dz)*(thee->data[IJK(ihi,jhi,klo)])
450 + dx *(1.0-dy)*(1.0-dz)*(thee->data[IJK(ihi,jlo,klo)])
451 + (1.0-dx)*dy *dz *(thee->data[IJK(ilo,jhi,khi)])
452 + (1.0-dx)*(1.0-dy)*dz *(thee->data[IJK(ilo,jlo,khi)])
453 + (1.0-dx)*dy *(1.0-dz)*(thee->data[IJK(ilo,jhi,klo)])
454 + (1.0-dx)*(1.0-dy)*(1.0-dz)*(thee->data[IJK(ilo,jlo,klo)]);
455
456 *value = u;
457 return 1;
458
459 }
460
461 *value = 0.0;
462 return 0;
463 }
464
Char_parseARGV(int argc,char ** argv,int * nx,int * ny,int * nz,int * pad,char *** fnams,int * numfnams,char * outname,int * vflag)465 VPRIVATE int Char_parseARGV(int argc, char **argv,
466 int *nx, int *ny, int *nz, int *pad, char ***fnams, int *numfnams,
467 char *outname, int *vflag)
468 {
469 int i, j, hflag, nflags, sflag;
470
471 i = 1;
472 hflag = 0;
473 nflags = 0;
474 while( i < argc ) {
475 if( argv[i][0] == '-' ) {
476 nflags++;
477 if (!strcmp(argv[i],"-v")) {
478 (*vflag) = 2;
479 } else if (!strcmp(argv[i],"-quiet")) {
480 (*vflag) = 0;
481 } else if (!strcmp(argv[i],"-o")) {
482 i++;
483 if( i < argc ) {
484 nflags++;
485 sprintf(outname,"%s",argv[i]);
486 }
487 } else if (!strcmp(argv[i],"-pad")) {
488 i++;
489 if( i < argc ) {
490 nflags++;
491 (*pad) = atoi(argv[i]);
492 }
493 } else {
494 hflag = 1;
495 }
496 }
497 i++;
498 }
499
500 /* *************** CHECK INVOCATION ******************* */
501 if ((argc - nflags) < 5 || hflag) {
502 return 1;
503 }
504
505 /* ************* PARSE REMAINING ARGS ****************** */
506 i = 1;
507 j = 0;
508 hflag = 0;
509 sflag = 1;
510 while(i<argc && sflag) {
511 if( argv[i][0] == '-' ) {
512 j++;
513 if (!strcmp(argv[i],"-o")) {
514 i++;
515 j++;
516 } else if (!strcmp(argv[i],"-pad")) {
517 i++;
518 j++;
519 }
520 } else {
521 if( (i+2) < argc && nflags == j) {
522 (*nx) = atoi(argv[i]);
523 (*ny) = atoi(argv[i+1]);
524 (*nz) = atoi(argv[i+2]);
525 i += 2;
526 } else {
527 hflag = 1;
528 }
529 sflag = 0;
530 }
531 i++;
532 }
533
534 if (hflag) {
535 return 1;
536 }
537
538 (*fnams) = &(argv[i]);
539 (*numfnams) = argc - i;
540
541 return 0;
542 }
543
544