7 #define rindex(X,Y) strrchr(X,Y)
8 #define index(X,Y) strchr(X,Y)
15 int as_long(char *str
,long *l
) {
19 *l
=strtol(str
,&endptr
,10);
20 if(!endptr
|| *endptr
) return 0;
24 int as_finite_double(char *str
,double *d
) {
28 *d
=strtod(str
,&endptr
);
29 if(!endptr
|| *endptr
) return 0;
30 if(*d
==*d
&& *d
+1!=*d
)
33 return 0; /* NaN or infinite */
36 int contains_str( char *s1
, char *s2
)
40 if ( s2
== NULL
|| s1
== NULL
) return ( 0 ) ;
41 if ( *s2
== '\0' || *s1
== '\0' ) return ( 0 ) ;
44 if ((r
= (char *)index( p
, *s2
)) == NULL
) { return( 0 ) ; }
45 for ( q
= s2
; *q
&& *r
== *q
; r
++ , q
++ ) ;
46 if ( *q
== '\0' ) return (1) ;
52 int contains_tok( char *s1
, char *s2
, char *delims
)
57 strcpy( tempstr
, s1
) ;
58 p
= strtok ( tempstr
, delims
) ;
61 if ( !strcmp ( p
, s2
) ) { return(1) ;}
62 p
= strtok( NULL
, delims
) ;
68 /* Had to increase size for SOA from 4*4096 to 4*7000 */
69 char halo_define
[4*7000], halo_use
[NAMELEN
], halo_id
[NAMELEN
], x
[NAMELEN
] ;
71 /*KAL added this for vertical interpolation */
72 /*DJW 131202 modified to create files required for vertical interpolation from parent to nest */
74 gen_nest_v_interp ( char * dirname
)
76 char * fnlst
[] = { "nest_forcedown_interp_vert.inc",
77 "nest_interpdown_interp_vert.inc",
79 int down_path
[] = { FORCE_DOWN
, INTERP_DOWN
};
81 char **fnp
; char *fn
;
85 for ( fnp
=fnlst
, ipath
=0 ; *fnp
; fnp
++, ipath
++ )
88 if ( dirname
== NULL
) return(1);
89 if ( strlen(dirname
) > 0 )
90 { sprintf(fname
,"%s/%s",dirname
,fn
); }
92 { sprintf(fname
,"%s",fn
); }
93 if ((fp
= fopen( fname
, "w" )) == NULL
) return(1);
94 print_warning(fp
,fname
);
96 gen_nest_interp2( fp
, Domain
.fields
, NULL
, down_path
[ipath
], (down_path
[ipath
]==FORCE_DOWN
)?2:2 );
104 gen_nest_interp ( char * dirname
)
106 char * fnlst
[] = { "nest_forcedown_interp.inc" , "nest_interpdown_interp.inc" ,
107 "nest_feedbackup_interp.inc", "nest_feedbackup_smooth.inc",
109 int down_path
[] = { FORCE_DOWN
, INTERP_DOWN
, INTERP_UP
, SMOOTH_UP
} ;
111 char ** fnp
; char * fn
;
112 char fname
[NAMELEN
] ;
115 /*KAL FORCE_DOWN, etc are integers defined in registry.h, so down_path is an array of integers*/
117 for ( fnp
= fnlst
, ipath
= 0 ; *fnp
; fnp
++ , ipath
++ )
120 if ( dirname
== NULL
) return(1) ;
121 if ( strlen(dirname
) > 0 )
122 { sprintf(fname
,"%s/%s",dirname
,fn
) ; }
124 { sprintf(fname
,"%s",fn
) ; }
125 if ((fp
= fopen( fname
, "w" )) == NULL
) return(1) ;
126 print_warning(fp
,fname
) ;
128 if ( down_path
[ipath
] == INTERP_DOWN
) { sprintf(halo_id
,"HALO_INTERP_DOWN") ; }
129 else if ( down_path
[ipath
] == FORCE_DOWN
) { sprintf(halo_id
,"HALO_FORCE_DOWN") ; }
130 else if ( down_path
[ipath
] == INTERP_UP
) { sprintf(halo_id
,"HALO_INTERP_UP") ; }
131 else if ( down_path
[ipath
] == SMOOTH_UP
) { sprintf(halo_id
,"HALO_INTERP_SMOOTH") ; }
132 sprintf(halo_define
,"80:") ;
133 sprintf(halo_use
,"") ;
134 gen_nest_interp1 ( fp
, Domain
.fields
, NULL
, down_path
[ipath
], (down_path
[ipath
]==FORCE_DOWN
)?2:2 ) ;
136 node_t
* comm_struct
;
137 comm_struct
= new_node( HALO
) ;
138 strcpy( comm_struct
->name
, halo_id
) ;
139 strcpy( comm_struct
->use
, halo_use
) ;
140 strcpy( comm_struct
->comm_define
, halo_define
) ;
141 add_node_to_end( comm_struct
, &Halos
) ;
152 gen_nest_interp1 ( FILE * fp
, node_t
* node
, char * fourdname
, int down_path
, int use_nest_time_level
)
155 char * fn
= "nest_interp.inc" ;
156 char fname
[NAMELEN
] ;
157 node_t
*p
, *p1
, *dim
;
158 int d2
, d3
, xdex
, ydex
, zdex
, nest_mask
;
159 char ddim
[3][2][NAMELEN
] ;
160 char mdim
[3][2][NAMELEN
] ;
161 char pdim
[3][2][NAMELEN
] ;
162 char ddim2
[3][2][NAMELEN
] ;
163 char mdim2
[3][2][NAMELEN
] ;
164 char pdim2
[3][2][NAMELEN
] ;
165 char nddim
[3][2][NAMELEN
] ;
166 char nmdim
[3][2][NAMELEN
] ;
167 char npdim
[3][2][NAMELEN
] ;
168 char nddim2
[3][2][NAMELEN
] ;
169 char nmdim2
[3][2][NAMELEN
] ;
170 char npdim2
[3][2][NAMELEN
] ;
171 char vname
[NAMELEN
], vname2
[NAMELEN
] ;
172 char tag
[NAMELEN
], tag2
[NAMELEN
] ;
173 char fcn_name
[NAMELEN
] ;
174 char xstag
[NAMELEN
], ystag
[NAMELEN
] ;
175 char dexes
[NAMELEN
] ;
176 char ndexes
[NAMELEN
] ;
179 char *colon
, r
[10],tx
[80],temp
[80],moredims
[80] ;
184 for ( p1
= node
; p1
!= NULL
; p1
= p1
->next
)
186 if ( p1
->node_kind
& FOURD
)
188 if ( p1
->members
->next
) {
189 nest_mask
= p1
->members
->next
->nest_mask
;
196 nest_mask
= p1
->nest_mask
;
200 if ( nest_mask
& down_path
)
202 if ( p
->ntl
> 1 ) { sprintf(tag
,"_2") ; sprintf(tag2
,"_%d", use_nest_time_level
) ; }
203 else { sprintf(tag
,"") ; sprintf(tag2
,"") ; }
205 /* construct variable name */
206 if ( p
->node_kind
& FOURD
) {
208 sprintf(x
, "%s%s", p
->name
, tag
) ;
209 if ( ! contains_tok ( halo_define
, x
, ":," ) ) {
210 if ( halo_define
[strlen(halo_define
)-1] == ':' ) { strcat(halo_define
,p
->name
) ; strcat(halo_define
,tag
) ; }
211 else { strcat(halo_define
,",") ; strcat(halo_define
,p
->name
) ; strcat(halo_define
,tag
) ; }
213 strcpy(moredims
,"") ;
214 for ( d
= 3 ; d
< p
->ndims
; d
++ ) {
215 sprintf(temp
,"idim%d",d
-2) ;
216 strcat(moredims
,",") ; strcat(moredims
,temp
) ;
218 strcat(moredims
,",") ;
220 strcpy(dexes
,"grid%sm31,grid%sm32,grid%sm33") ;
221 sprintf(vname
,"%s%s(%s%sitrace)",p
->name
,tag
,dexes
,moredims
) ;
222 strcpy(ndexes
,"ngrid%sm31,ngrid%sm32,ngrid%sm33") ;
223 sprintf(vname2
,"%s%s(%s%sitrace)",p
->name
,tag2
,ndexes
,moredims
) ;
225 if ( down_path
& SMOOTH_UP
) {
226 strcpy( fcn_name
, p
->members
->next
->smoothu_fcn_name
) ;
228 strcpy( fcn_name
, (down_path
& INTERP_UP
)?p
->members
->next
->interpu_fcn_name
:((down_path
& FORCE_DOWN
)?p
->members
->next
->force_fcn_name
:p
->members
->next
->interpd_fcn_name
) ) ;
233 sprintf(vname
,"%s%s",p
->name
,tag
) ;
235 if ( ! contains_tok ( halo_define
, vname
, ":," ) ) {
236 if ( halo_define
[strlen(halo_define
)-1] == ':' ) { strcat(halo_define
,vname
) ; }
237 else { strcat(halo_define
,",") ; strcat(halo_define
,vname
) ; }
239 sprintf(vname2
,"%s%s",p
->name
,tag2
) ;
240 if ( down_path
& SMOOTH_UP
) {
241 strcpy( fcn_name
, p
->smoothu_fcn_name
) ;
243 strcpy( fcn_name
, (down_path
& INTERP_UP
)?p
->interpu_fcn_name
:((down_path
& FORCE_DOWN
)?p
->force_fcn_name
:p
->interpd_fcn_name
) ) ;
247 if ( p1
->node_kind
& FOURD
) {
249 set_dim_strs2 ( p
->members
->next
, ddim
, mdim
, pdim
, "c", 1 ) ;
250 set_dim_strs2 ( p
->members
->next
, ddim2
, mdim2
, pdim2
, "c", 0 ) ;
251 set_dim_strs2 ( p
->members
->next
, nddim
, nmdim
, npdim
, "n", 1 ) ;
252 set_dim_strs2 ( p
->members
->next
, nddim2
, nmdim2
, npdim2
, "n", 0 ) ;
253 zdex
= get_index_for_coord( p
->members
->next
, COORD_Z
) ;
254 xdex
= get_index_for_coord( p
->members
->next
, COORD_X
) ;
255 ydex
= get_index_for_coord( p
->members
->next
, COORD_Y
) ;
256 if ( p
->members
->next
->stag_x
) strcpy( xstag
, ".TRUE." ) ; else strcpy( xstag
, ".FALSE." ) ;
257 if ( p
->members
->next
->stag_y
) strcpy( ystag
, ".TRUE." ) ; else strcpy( ystag
, ".FALSE." ) ;
258 if ( p
->members
->next
->stag_x
&& p
->members
->next
->stag_y
) {
259 maskstr
= "_xystag" ;
260 } else if ( p
->stag_x
) {
262 } else if ( p
->stag_y
) {
265 maskstr
= "_nostag" ;
269 set_dim_strs2 ( p
, ddim
, mdim
, pdim
, "c", 1 ) ;
270 set_dim_strs2 ( p
, ddim2
, mdim2
, pdim2
, "c", 0 ) ;
271 set_dim_strs2 ( p
, nddim
, nmdim
, npdim
, "n", 1 ) ;
272 set_dim_strs2 ( p
, nddim2
, nmdim2
, npdim2
, "n", 0 ) ;
273 zdex
= get_index_for_coord( p
, COORD_Z
) ;
274 xdex
= get_index_for_coord( p
, COORD_X
) ;
275 ydex
= get_index_for_coord( p
, COORD_Y
) ;
276 if ( p
->stag_x
) strcpy( xstag
, ".TRUE." ) ; else strcpy( xstag
, ".FALSE." ) ;
277 if ( p
->stag_y
) strcpy( ystag
, ".TRUE." ) ; else strcpy( ystag
, ".FALSE." ) ;
278 if ( p
->stag_x
&& p
->stag_y
) {
279 maskstr
= "_xystag" ;
280 } else if ( p
->stag_x
) {
282 } else if ( p
->stag_y
) {
285 maskstr
= "_nostag" ;
289 if ( p
->node_kind
& FOURD
)
291 fprintf(fp
,"DO itrace = PARAM_FIRST_SCALAR, num_%s\n",p
->name
) ;
292 for ( d
= p
->ndims
-1 ; d
>= 3 ; d
-- ) {
294 range_of_dimension( r
, tx
, d
, p
, "config_flags%" ) ;
295 colon
= index(tx
,':') ; *colon
= ',' ;
296 sprintf(temp
,"idim%d",d
-2) ;
297 strcat(moredims
,",") ; strcat(moredims
,temp
) ;
298 fprintf(fp
," DO %s = %s\n",temp
,tx
) ;
300 fprintf(fp
,"IF ( SIZE( %s%s, %d ) * SIZE( %s%s, %d ) .GT. 1", p
->name
,tag
,xdex
+1,p
->name
,tag
,ydex
+1 ) ;
302 if ( !strcmp( fcn_name
, "interp_mask_land_field" ) || !strcmp( fcn_name
, "interp_mask_water_field" ) ||
303 !strcmp( fcn_name
, "interp_mask_field") || !strcmp( fcn_name
, "interp_mask_soil") ) {
304 fprintf(fp
,"IF ( .TRUE.") ;
306 fprintf(fp
,"IF ( SIZE( %s%s, %d ) * SIZE( %s%s, %d ) .GT. 1", grid
,vname2
,xdex
+1,grid
,vname2
,ydex
+1 ) ;
310 fprintf(fp
," .and. (interp_mp .eqv. .true.)");
311 fprintf(fp
," ) THEN \n");
313 if(strcasecmp(fcn_name
,"nointerp")) {
314 /* We get here if we are calling any function other than
315 "NoInterp," a placeholder function that does not
316 interpolate and only exists to ensure the variable is
317 allocated on the intermediate domain. This is a
318 workaround for a bug in the IBM compiler: when the
319 interpolation routine is NoInterp, we do not generate the
322 This workaround is only enabled for the NMM
323 configurations since the other configurations do not use
324 the NoInterp placeholder function. */
326 fprintf(fp
,"CALL %s ( & \n", fcn_name
) ;
328 if ( !strcmp( fcn_name
, "interp_mask_land_field" ) || !strcmp( fcn_name
, "interp_mask_water_field" ) ||
329 !strcmp( fcn_name
, "interp_mask_field") || !strcmp( fcn_name
, "interp_mask_soil") ) {
330 fprintf(fp
," ( SIZE( %s%s , %d )*SIZE( %s%s , %d ) .GT. 1 ), & ! special argument needed because %s has bcasts in it\n",
331 grid
,vname2
,xdex
+1,grid
,vname2
,ydex
+1,fcn_name
) ;
333 fprintf(fp
," %s%s, & ! CD field\n", grid
, (p
->node_kind
& FOURD
)?vname
:vname2
) ;
334 fprintf(fp
," %s, %s, %s, %s, %s, %s, & ! CD dims\n",
335 ddim
[0][0], ddim
[0][1], ddim
[1][0], ddim
[1][1], ddim
[2][0], ddim
[2][1] ) ;
336 fprintf(fp
," %s, %s, %s, %s, %s, %s, & ! CD dims\n",
337 mdim
[0][0], mdim
[0][1], mdim
[1][0], mdim
[1][1], mdim
[2][0], mdim
[2][1] ) ;
338 fprintf(fp
," %s, %s, %s, %s, %s, %s, & ! CD dims\n",
339 pdim
[0][0], pdim
[0][1], pdim2
[1][0], pdim2
[1][1], pdim
[2][0], pdim
[2][1] ) ;
340 if ( ! (down_path
& SMOOTH_UP
) ) {
341 fprintf(fp
," ngrid%%%s, & ! ND field\n", vname2
) ;
343 fprintf(fp
," %s, %s, %s, %s, %s, %s, & ! ND dims\n",
344 nddim
[0][0], nddim
[0][1], nddim
[1][0], nddim
[1][1], nddim
[2][0], nddim
[2][1] ) ;
345 fprintf(fp
," %s, %s, %s, %s, %s, %s, & ! ND dims\n",
346 nmdim
[0][0], nmdim
[0][1], nmdim
[1][0], nmdim
[1][1], nmdim
[2][0], nmdim
[2][1] ) ;
347 fprintf(fp
," %s, %s, %s, %s, %s, %s, & ! ND dims\n",
348 npdim
[0][0], npdim
[0][1], npdim2
[1][0], npdim2
[1][1], npdim
[2][0], npdim
[2][1] ) ;
350 if ( ! (down_path
& SMOOTH_UP
) ) {
351 if ( sw_deref_kludge
== 1 ) {
352 fprintf(fp
," config_flags%%shw, ngrid%%imask%s(nims,njms), & ! stencil half width\n",maskstr
) ;
354 fprintf(fp
," config_flags%%shw, ngrid%%imask%s, & ! stencil half width\n",maskstr
) ;
357 fprintf(fp
," %s, %s, & ! xstag, ystag\n", xstag
, ystag
) ;
358 fprintf(fp
," ngrid%%i_parent_start, ngrid%%j_parent_start, &\n") ;
359 fprintf(fp
," ngrid%%parent_grid_ratio, ngrid%%parent_grid_ratio &\n") ;
362 char tmpstr
[NAMELEN
], *p1
;
365 if ( p
->node_kind
& FOURD
) {
366 if ( p
->members
->next
) {
367 pp
= p
->members
->next
;
373 strcpy( tmpstr
, "" ) ;
374 if ( down_path
& SMOOTH_UP
) {
375 strcpy( tmpstr
, pp
->smoothu_aux_fields
) ;
376 } else if ( down_path
& INTERP_UP
) {
377 strcpy( tmpstr
, pp
->interpu_aux_fields
) ;
378 } else if ( down_path
& FORCE_DOWN
) {
379 /* by default, add the boundary and boundary tendency fields to the arg list */
380 if ( (! p
->node_kind
) & FOURD
) {
381 sprintf( tmpstr
, "%s_b,%s_bt,", pp
->name
, pp
->name
) ;
383 sprintf( tmpstr
, "%s_b,%s_bt,", p
->name
, p
->name
) ;
385 strcat( tmpstr
, pp
->force_aux_fields
) ;
386 } else if ( down_path
& INTERP_DOWN
) {
387 strcpy( tmpstr
, pp
->interpd_aux_fields
) ;
390 for ( p1
= strtok(tmpstr
,",") ; p1
!= NULL
; p1
= strtok(NULL
,",") )
392 if(as_long(p1
,&long_store
)) {
393 /* Integer aux in registry (6, 0x5A, 0774, etc.).
394 Print in fortran-readable form. */
395 fprintf(fp
,",%ld &\n",long_store
);
396 } else if(as_finite_double(p1
,&real_store
)) {
397 /* Real aux in registry (3.7, -3.105e+04, etc.). Print in
398 fortran-readable form. */
399 fprintf(fp
,",%5.9e &\n",real_store
);
400 } else if( (p1
[0]=='l' || p1
[0]=='L') && p1
[1]=='%' && p1
[2]!='\0') {
401 /* Local variable requested (l%varname). */
402 fprintf(fp
,",%s &\n",p1
+2);
403 } else if( p1
[0]=='@' && p1
[1]!='\0' ) {
404 /* Local variable requested (@varname). */
405 fprintf(fp
,",%s &\n",p1
+1);
406 } else if( p1
[0]=='*' && p1
[1]=='\0' ) {
407 /* Entire grid requested (*) */
408 fprintf(fp
,",grid ,ngrid &\n");
409 } else if( !strcasecmp(p1
,"n%*") ) {
410 /* Nest grid requested (n%*) */
411 fprintf(fp
,",ngrid &\n");
412 } else if( !strcasecmp(p1
,"c%*") ) {
413 /* Coarse grid requested (c%*) */
414 fprintf(fp
,",grid &\n");
415 } else { /* is n%varname, c%varname, varname or an error */
419 if( (p1
[0]=='n' || p1
[0]=='N') && p1
[1]=='%' && p1
[2]!='\0' ) {
420 /* n%var, so we don't want the coarse domain var */
423 } else if( (p1
[0]=='c' || p1
[0]=='C') && p1
[1]=='%' && p1
[2]!='\0' ) {
424 /* c%var, so we don't want the nest domain var */
428 /* either "varname" (so we give coarse and nest) or an error */
431 if (( nd
= get_entry ( subvar
, Domain
.fields
)) != NULL
) {
432 /* Variable name is valid */
433 if ( nd
->boundary_array
) {
434 /* We're requesting boundary data, which may need
435 to be handled differently, depending on the
439 for ( bdy
= 1 ; bdy
<= 4 ; bdy
++ ) {
440 if ( strcmp( nd
->use
, "_4d_bdy_array_" ) ) {
441 if(want_coarse
) fprintf(fp
,",dummy_%s ",bdy_indicator(bdy
));
442 if(want_nest
) fprintf(fp
,",ngrid%%%s%s ",nd
->name
, bdy_indicator(bdy
));
445 c
= 'i' ; if ( bdy
<= 2 ) c
= 'j' ;
446 if(want_coarse
) fprintf(fp
,",%s%s(c%cms,1,1,itrace) ", nd
->name
, bdy_indicator(bdy
), c
);
447 if(want_nest
) fprintf(fp
,",ngrid%%%s%s(n%cms,1,1,itrace) ", nd
->name
, bdy_indicator(bdy
), c
);
452 if ( strcmp( nd
->use
, "_4d_bdy_array_" ) ) {
453 if(want_coarse
) fprintf(fp
,",%s ", nd
->name
) ;
454 if(want_nest
) fprintf(fp
,",ngrid%%%s ", nd
->name
) ;
456 if(want_coarse
) fprintf(fp
,",%s(1,1,1,1,itrace) ", nd
->name
) ;
457 if(want_nest
) fprintf(fp
,",ngrid%%%s(1,1,1,1,itrace) ", nd
->name
) ;
462 /* This is not a boundary array, so pass the
464 if(want_coarse
) fprintf(fp
,",grid%%%s", nd
->name
) ;
465 if(want_nest
) fprintf(fp
,",ngrid%%%s", nd
->name
) ;
469 fprintf(stderr
,"REGISTRY WARNING: %s: %s is not a variable or number; ignoring it\n",vname
,p1
) ;
476 fprintf(fp
," ) \n") ;
479 fprintf(fp
,"CONTINUE ! do not call %s\n", fcn_name
) ;
480 } /* end of "skip this if we would call NoInterp" */
482 if ( p
->node_kind
& FOURD
)
484 fprintf(fp
,"ENDIF\n") ;
485 for ( d
= p
->ndims
-1 ; d
>= 3 ; d
-- ) {
486 fprintf(fp
,"ENDDO\n") ;
488 fprintf(fp
,"ENDDO\n") ;
490 fprintf(fp
,"ENDIF\n") ; /* in_use_from_config */
499 /* DJW 131202 Modified this to include only variables that have a vertical dimension
500 * (excluding soil layers and other extra dimensions) and inserts a different
501 * function call depending on variable staggering in z. */
503 gen_nest_interp2 ( FILE * fp
, node_t
* node
, char * fourdname
, int down_path
, int use_nest_time_level
)
506 int xdex
, ydex
, nest_mask
;
507 char ddim
[3][2][NAMELEN
] ;
508 char mdim
[3][2][NAMELEN
] ;
509 char pdim
[3][2][NAMELEN
] ;
510 char vname
[NAMELEN
], vname2
[NAMELEN
] ;
511 char tag
[NAMELEN
], tag2
[NAMELEN
] ;
512 char dexes
[NAMELEN
] ;
513 char ndexes
[NAMELEN
] ;
515 char *colon
,r
[10],tx
[80],temp
[80],moredims
[80] ;
518 char fcn_name
[NAMELEN
];
520 for ( p1
= node
; p1
!= NULL
; p1
= p1
->next
)
523 /* KAL-get the nest mask to see what path the variable is on */
524 if ( p1
->node_kind
& FOURD
)
526 if ( p1
->members
->next
) {
527 nest_mask
= p1
->members
->next
->nest_mask
;
534 nest_mask
= p1
->nest_mask
;
540 if ( nest_mask
& down_path
)
542 /*KAL get the dimensions of the variable and only work on ones with vertical extents*/
543 if ( p1
->node_kind
& FOURD
) {
544 set_dim_strs2 ( p
->members
->next
, ddim
, mdim
, pdim
, "", 1 ) ;
546 set_dim_strs2 ( p
, ddim
, mdim
, pdim
, "", 1 ) ;
548 if ( !strcmp ( ddim
[0][1], "kde") ||
549 !strcmp ( ddim
[1][1], "kde") ||
550 !strcmp ( ddim
[2][1], "kde")) {
552 if ( p
->ntl
> 1 ) { sprintf(tag
,"_2") ; sprintf(tag2
,"_%d", use_nest_time_level
) ; }
553 else { sprintf(tag
,"") ; sprintf(tag2
,"") ; }
555 /* construct variable name */
556 if ( p
->node_kind
& FOURD
) {
557 sprintf(x
, "%s%s", p
->name
, tag
) ;
558 strcpy(moredims
,"") ;
559 for ( d
= 3 ; d
< p
->ndims
; d
++ ) {
560 sprintf(temp
,"idim%d",d
-2) ;
561 strcat(moredims
,",") ; strcat(moredims
,temp
) ;
563 strcat(moredims
,",") ;
564 strcpy(dexes
,"grid%sm31,grid%sm32,grid%sm33") ;
565 sprintf(vname
,"%s%s(%s%sitrace)",p
->name
,tag
,dexes
,moredims
) ;
566 strcpy(ndexes
,"ngrid%sm31,ngrid%sm32,ngrid%sm33") ;
567 sprintf(vname2
,"%s%s(%s%sitrace)",p
->name
,tag2
,ndexes
,moredims
) ;
571 sprintf(vname
,"%s%s",p
->name
,tag
) ;
572 sprintf(vname2
,"%s%s",p
->name
,tag2
) ;
575 if ( p1
->node_kind
& FOURD
) {
577 xdex
= get_index_for_coord( p
->members
->next
, COORD_X
) ;
578 ydex
= get_index_for_coord( p
->members
->next
, COORD_Y
) ;
581 xdex
= get_index_for_coord( p
, COORD_X
) ;
582 ydex
= get_index_for_coord( p
, COORD_Y
) ;
586 strcpy( zstag
, ".TRUE." );
587 strcpy(fcn_name
,"vert_interp_vert_nesting_w");
589 strcpy( zstag
, ".FALSE." );
590 strcpy(fcn_name
,"vert_interp_vert_nesting");
593 /* DJW 131202 The condition for the if-statement below is really really poorly written.
594 * I'm attempting to say "if the variable has a vertical dimension that spans multiple
595 * eta levels. Note that this is complicated because some variables have a vertical
596 * dimension that describes the number of soil levels they use. There are also other
597 * vertical dimensions that we need be wary of... hence my hack to make this work since
598 * at the moment all the variables I want to interpolate have kde points in the vertical!*/
599 if ( strcmp("kde",ddim
[1][1]) == 0 ) {
600 if ( p
->node_kind
& FOURD
) {
601 fprintf(fp
,"DO itrace = PARAM_FIRST_SCALAR, num_%s\n",p
->name
) ;
602 for ( d
= p
->ndims
-1 ; d
>= 3 ; d
-- ) {
604 range_of_dimension( r
, tx
, d
, p
, "config_flags%" ) ;
605 colon
= index(tx
,':') ; *colon
= ',' ;
606 sprintf(temp
,"idim%d",d
-2) ;
607 strcat(moredims
,",") ; strcat(moredims
,temp
) ;
608 fprintf(fp
," DO %s = %s\n",temp
,tx
) ;
610 fprintf(fp
,"IF ( SIZE( %s%s, %d ) * SIZE( %s%s, %d ) .GT. 1 ) THEN \n", p
->name
,tag
,xdex
+1,p
->name
,tag
,ydex
+1 ) ;
612 fprintf(fp
,"IF ( SIZE( %s%s, %d ) * SIZE( %s%s, %d ) .GT. 1 ) THEN \n", grid
,vname2
,xdex
+1,grid
,vname2
,ydex
+1 ) ;
615 fprintf(fp
," CALL %s( &\n",fcn_name
);
616 fprintf(fp
," %s%s, & !CD field\n",grid
,(p
->node_kind
& FOURD
)?vname
:vname2
);
617 fprintf(fp
," %s, %s, %s, %s, %s, %s, & !CD dims\n",ddim
[0][0],ddim
[0][1],ddim
[1][0],ddim
[1][1],ddim
[2][0],ddim
[2][1]);
618 fprintf(fp
," %s, %s, %s, %s, %s, %s, & !CD dims\n",mdim
[0][0],mdim
[0][1],mdim
[1][0],mdim
[1][1],mdim
[2][0],mdim
[2][1]);
619 fprintf(fp
," %s, %s, %s, MIN( (%s-1), %s ), %s, %s, & !CD dims\n",pdim
[0][0],pdim
[0][1],pdim
[1][0],ddim
[1][1],pdim
[1][1],pdim
[2][0],pdim
[2][1]);
620 fprintf(fp
," pgrid%%s_vert, pgrid%%e_vert, & !vertical dimension of the parent grid\n");
621 if ( strcmp(zstag
,".TRUE.") != 0 ) {
622 fprintf(fp
," pgrid%%cf1, pgrid%%cf2, pgrid%%cf3, pgrid%%cfn, pgrid%%cfn1, & !coarse grid extrapolation constants\n");
623 fprintf(fp
," alt_u_c, alt_u_n ) !coordinates for parent and nest\n");
625 fprintf(fp
," alt_w_c, alt_w_n ) !coordinates for parent and nest\n");
628 if ( p
->node_kind
& FOURD
)
630 fprintf(fp
,"ENDIF\n") ;
631 for ( d
= p
->ndims
-1 ; d
>= 3 ; d
-- ) {
632 fprintf(fp
,"ENDDO\n") ;
634 fprintf(fp
,"ENDDO\n") ;
636 fprintf(fp
,"ENDIF\n") ; /* in_use_from_config */
638 } /* end of if variable has > 1 vertical level*/
639 } /* end of if variable has vertical dimension*/
640 } /* end of mask for down_path*/
641 } /*end of loop over nodes*/