1 /***********************************************************************
2 * GNU Lesser General Public License
4 * This file is part of the GFDL Flexible Modeling System (FMS).
6 * FMS is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or (at
9 * your option) any later version.
11 * FMS is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FMS. If not, see <http://www.gnu.org/licenses/>.
18 **********************************************************************/
23 #include "read_mosaic.h"
25 #include "mosaic_util.h"
30 * \brief Support for reading mosaic netcdf grid files.
33 /*********************************************************************
34 void netcdf_error( int status )
35 status is the returning value of netcdf call. this routine will
36 handle the error when status is not NC_NOERR.
37 ********************************************************************/
38 void handle_netcdf_error(const char *msg
, int status
)
42 sprintf( errmsg
, "%s: %s", msg
, (char *)nc_strerror(status
) );
43 error_handler(errmsg
);
45 } /* handle_netcdf_error */
47 /***************************************************************************
48 void get_file_dir(const char *file, char *dir)
49 get the directory where file is located. The dir will be the complate path
50 before the last "/". If no "/" exist in file, the path will be current ".".
51 ***************************************************************************/
52 void get_file_dir(const char *file
, char *dir
)
55 const char *strptr
= NULL
;
57 /* get the diretory */
59 strptr
= strrchr(file
, '/');
62 strncpy(dir
, file
, len
);
73 int field_exist(const char* file
, const char *name
)
75 int ncid
, varid
, status
;
81 status
= nc_open(file
, NC_NOWRITE
, &ncid
);
82 if(status
!= NC_NOERR
) {
83 sprintf(msg
, "field_exist: in opening file %s", file
);
84 handle_netcdf_error(msg
, status
);
87 status
= nc_inq_varid(ncid
, name
, &varid
);
88 if(status
== NC_NOERR
){
92 status
= nc_close(ncid
);
93 if(status
!= NC_NOERR
) {
94 sprintf(msg
, "field_exist: in closing file %s.", file
);
95 handle_netcdf_error(msg
, status
);
98 #else /* ndef use_netCDF */
99 error_handler("read_mosaic: Add flag -Duse_netCDF when compiling");
100 #endif /* use_netcdf */
106 int get_dimlen(const char* file
, const char *name
)
108 int ncid
, dimid
, status
, len
;
114 status
= nc_open(file
, NC_NOWRITE
, &ncid
);
115 if(status
!= NC_NOERR
) {
116 sprintf(msg
, "in opening file %s", file
);
117 handle_netcdf_error(msg
, status
);
120 status
= nc_inq_dimid(ncid
, name
, &dimid
);
121 if(status
!= NC_NOERR
) {
122 sprintf(msg
, "in getting dimid of %s from file %s.", name
, file
);
123 handle_netcdf_error(msg
, status
);
126 status
= nc_inq_dimlen(ncid
, dimid
, &size
);
127 if(status
!= NC_NOERR
) {
128 sprintf(msg
, "in getting dimension size of %s from file %s.", name
, file
);
129 handle_netcdf_error(msg
, status
);
131 status
= nc_close(ncid
);
132 if(status
!= NC_NOERR
) {
133 sprintf(msg
, "in closing file %s.", file
);
134 handle_netcdf_error(msg
, status
);
138 if(status
!= NC_NOERR
) {
139 sprintf(msg
, "in closing file %s", file
);
140 handle_netcdf_error(msg
, status
);
143 error_handler("read_mosaic: Add flag -Duse_netCDF when compiling");
150 /*******************************************************************************
151 void get_string_data(const char *file, const char *name, char *data)
152 get string data of field with "name" from "file".
153 ******************************************************************************/
154 void get_string_data(const char *file
, const char *name
, char *data
)
156 int ncid
, varid
, status
;
160 status
= nc_open(file
, NC_NOWRITE
, &ncid
);
161 if(status
!= NC_NOERR
) {
162 sprintf(msg
, "in opening file %s", file
);
163 handle_netcdf_error(msg
, status
);
165 status
= nc_inq_varid(ncid
, name
, &varid
);
166 if(status
!= NC_NOERR
) {
167 sprintf(msg
, "in getting varid of %s from file %s.", name
, file
);
168 handle_netcdf_error(msg
, status
);
170 status
= nc_get_var_text(ncid
, varid
, data
);
171 if(status
!= NC_NOERR
) {
172 sprintf(msg
, "in getting data of %s from file %s.", name
, file
);
173 handle_netcdf_error(msg
, status
);
175 status
= nc_close(ncid
);
176 if(status
!= NC_NOERR
) {
177 sprintf(msg
, "in closing file %s.", file
);
178 handle_netcdf_error(msg
, status
);
181 error_handler("read_mosaic: Add flag -Duse_netCDF when compiling");
184 } /* get_string_data */
186 /*******************************************************************************
187 void get_string_data_level(const char *file, const char *name, const size_t *start, const size_t *nread, char *data)
188 get string data of field with "name" from "file".
189 ******************************************************************************/
190 void get_string_data_level(const char *file
, const char *name
, char *data
, const unsigned int *level
)
192 int ncid
, varid
, status
, i
;
193 size_t start
[4], nread
[4];
197 status
= nc_open(file
, NC_NOWRITE
, &ncid
);
198 if(status
!= NC_NOERR
) {
199 sprintf(msg
, "in opening file %s", file
);
200 handle_netcdf_error(msg
, status
);
202 status
= nc_inq_varid(ncid
, name
, &varid
);
203 if(status
!= NC_NOERR
) {
204 sprintf(msg
, "in getting varid of %s from file %s.", name
, file
);
205 handle_netcdf_error(msg
, status
);
208 start
[i
] = 0; nread
[i
] = 1;
210 start
[0] = *level
; nread
[1] = STRING
;
211 status
= nc_get_vara_text(ncid
, varid
, start
, nread
, data
);
212 if(status
!= NC_NOERR
) {
213 sprintf(msg
, "in getting data of %s from file %s.", name
, file
);
214 handle_netcdf_error(msg
, status
);
216 status
= nc_close(ncid
);
217 if(status
!= NC_NOERR
) {
218 sprintf(msg
, "in closing file %s.", file
);
219 handle_netcdf_error(msg
, status
);
222 error_handler("read_mosaic: Add flag -Duse_netCDF when compiling");
225 } /* get_string_data_level */
228 /*******************************************************************************
229 void get_var_data(const char *file, const char *name, double *data)
230 get var data of field with "name" from "file".
231 ******************************************************************************/
232 void get_var_data(const char *file
, const char *name
, void *data
)
235 int ncid
, varid
, status
;
240 status
= nc_open(file
, NC_NOWRITE
, &ncid
);
241 if(status
!= NC_NOERR
) {
242 sprintf(msg
, "in opening file %s", file
);
243 handle_netcdf_error(msg
, status
);
245 status
= nc_inq_varid(ncid
, name
, &varid
);
246 if(status
!= NC_NOERR
) {
247 sprintf(msg
, "in getting varid of %s from file %s.", name
, file
);
248 handle_netcdf_error(msg
, status
);
251 status
= nc_inq_vartype(ncid
, varid
, &vartype
);
252 if(status
!= NC_NOERR
) {
253 sprintf(msg
, "get_var_data: in getting vartype of of %s in file %s ", name
, file
);
254 handle_netcdf_error(msg
, status
);
258 case NC_DOUBLE
:case NC_FLOAT
:
259 status
= nc_get_var_double(ncid
, varid
, (double *)data
);
262 status
= nc_get_var_int(ncid
, varid
, (int *)data
);
265 sprintf(msg
, "get_var_data: field %s in file %s has an invalid type, "
266 "the type should be NC_DOUBLE, NC_FLOAT or NC_INT", name
, file
);
269 if(status
!= NC_NOERR
) {
270 sprintf(msg
, "in getting data of %s from file %s.", name
, file
);
271 handle_netcdf_error(msg
, status
);
273 status
= nc_close(ncid
);
274 if(status
!= NC_NOERR
) {
275 sprintf(msg
, "in closing file %s.", file
);
276 handle_netcdf_error(msg
, status
);
279 error_handler("read_mosaic: Add flag -Duse_netCDF when compiling");
284 /*******************************************************************************
285 void get_var_data(const char *file, const char *name, double *data)
286 get var data of field with "name" from "file".
287 ******************************************************************************/
288 void get_var_data_region(const char *file
, const char *name
, const size_t *start
, const size_t *nread
, void *data
)
291 int ncid
, varid
, status
;
296 status
= nc_open(file
, NC_NOWRITE
, &ncid
);
297 if(status
!= NC_NOERR
) {
298 sprintf(msg
, "get_var_data_region: in opening file %s", file
);
299 handle_netcdf_error(msg
, status
);
301 status
= nc_inq_varid(ncid
, name
, &varid
);
302 if(status
!= NC_NOERR
) {
303 sprintf(msg
, "in getting varid of %s from file %s.", name
, file
);
304 handle_netcdf_error(msg
, status
);
307 status
= nc_inq_vartype(ncid
, varid
, &vartype
);
308 if(status
!= NC_NOERR
) {
309 sprintf(msg
, "get_var_data_region: in getting vartype of of %s in file %s ", name
, file
);
310 handle_netcdf_error(msg
, status
);
314 case NC_DOUBLE
:case NC_FLOAT
:
315 status
= nc_get_vara_double(ncid
, varid
, start
, nread
, (double *)data
);
318 status
= nc_get_vara_int(ncid
, varid
, start
, nread
, (int *)data
);
321 sprintf(msg
, "get_var_data_region: field %s in file %s has an invalid type, "
322 "the type should be NC_DOUBLE, NC_FLOAT or NC_INT", name
, file
);
326 if(status
!= NC_NOERR
) {
327 sprintf(msg
, "get_var_data_region: in getting data of %s from file %s.", name
, file
);
328 handle_netcdf_error(msg
, status
);
330 status
= nc_close(ncid
);
331 if(status
!= NC_NOERR
) {
332 sprintf(msg
, "get_var_data_region: in closing file %s.", file
);
333 handle_netcdf_error(msg
, status
);
336 error_handler("read_mosaic: Add flag -Duse_netCDF when compiling");
339 } /* get_var_data_region */
341 /******************************************************************************
342 void get_var_text_att(const char *file, const char *name, const char *attname, char *att)
343 get text attribute of field 'name' from 'file
344 ******************************************************************************/
345 void get_var_text_att(const char *file
, const char *name
, const char *attname
, char *att
)
347 int ncid
, varid
, status
;
351 status
= nc_open(file
, NC_NOWRITE
, &ncid
);
352 if(status
!= NC_NOERR
) {
353 sprintf(msg
, "in opening file %s", file
);
354 handle_netcdf_error(msg
, status
);
356 status
= nc_inq_varid(ncid
, name
, &varid
);
357 if(status
!= NC_NOERR
) {
358 sprintf(msg
, "in getting varid of %s from file %s.", name
, file
);
359 handle_netcdf_error(msg
, status
);
361 status
= nc_get_att_text(ncid
, varid
, attname
, att
);
362 if(status
!= NC_NOERR
) {
363 sprintf(msg
, "in getting attribute %s of %s from file %s.", attname
, name
, file
);
364 handle_netcdf_error(msg
, status
);
366 status
= nc_close(ncid
);
367 if(status
!= NC_NOERR
) {
368 sprintf(msg
, "in closing file %s.", file
);
369 handle_netcdf_error(msg
, status
);
372 error_handler("read_mosaic: Add flag -Duse_netCDF when compiling");
375 } /* get_var_text_att */
377 /***********************************************************************
378 return number of overlapping cells.
379 ***********************************************************************/
380 int read_mosaic_xgrid_size_( const char *xgrid_file
)
382 return read_mosaic_xgrid_size(xgrid_file
);
385 int read_mosaic_xgrid_size( const char *xgrid_file
)
389 ncells
= get_dimlen(xgrid_file
, "ncells");
393 double get_global_area(void)
396 garea
= 4*M_PI
*RADIUS
*RADIUS
;
401 double get_global_area_(void)
404 garea
= 4*M_PI
*RADIUS
*RADIUS
;
410 /****************************************************************************/
411 void read_mosaic_xgrid_order1_(const char *xgrid_file
, int *i1
, int *j1
, int *i2
, int *j2
, double *area
)
413 read_mosaic_xgrid_order1(xgrid_file
, i1
, j1
, i2
, j2
, area
);
417 void read_mosaic_xgrid_order1(const char *xgrid_file
, int *i1
, int *j1
, int *i2
, int *j2
, double *area
)
420 int *tile1_cell
, *tile2_cell
;
423 ncells
= get_dimlen(xgrid_file
, "ncells");
425 tile1_cell
= (int *)malloc(ncells
*2*sizeof(int));
426 tile2_cell
= (int *)malloc(ncells
*2*sizeof(int));
427 get_var_data(xgrid_file
, "tile1_cell", tile1_cell
);
428 get_var_data(xgrid_file
, "tile2_cell", tile2_cell
);
430 get_var_data(xgrid_file
, "xgrid_area", area
);
432 garea
= 4*M_PI
*RADIUS
*RADIUS
;
434 for(n
=0; n
<ncells
; n
++) {
435 i1
[n
] = tile1_cell
[n
*2] - 1;
436 j1
[n
] = tile1_cell
[n
*2+1] - 1;
437 i2
[n
] = tile2_cell
[n
*2] - 1;
438 j2
[n
] = tile2_cell
[n
*2+1] - 1;
439 area
[n
] /= garea
; /* rescale the exchange grid area to unit earth area */
445 } /* read_mosaic_xgrid_order1 */
448 void read_mosaic_xgrid_order1_region_(const char *xgrid_file
, int *i1
, int *j1
, int *i2
, int *j2
, double *area
, int *isc
, int *iec
)
450 read_mosaic_xgrid_order1_region(xgrid_file
, i1
, j1
, i2
, j2
, area
, isc
, iec
);
454 void read_mosaic_xgrid_order1_region(const char *xgrid_file
, int *i1
, int *j1
, int *i2
, int *j2
, double *area
, int *isc
, int *iec
)
457 int *tile1_cell
, *tile2_cell
;
458 size_t start
[4], nread
[4];
461 ncells
= *iec
-*isc
+1;
463 tile1_cell
= (int *)malloc(ncells
*2*sizeof(int));
464 tile2_cell
= (int *)malloc(ncells
*2*sizeof(int));
466 start
[i
] = 0; nread
[i
] = 1;
473 get_var_data_region(xgrid_file
, "tile1_cell", start
, nread
, tile1_cell
);
474 get_var_data_region(xgrid_file
, "tile2_cell", start
, nread
, tile2_cell
);
478 get_var_data_region(xgrid_file
, "xgrid_area", start
, nread
, area
);
480 garea
= 4*M_PI
*RADIUS
*RADIUS
;
482 for(n
=0; n
<ncells
; n
++) {
483 i1
[n
] = tile1_cell
[n
*2] - 1;
484 j1
[n
] = tile1_cell
[n
*2+1] - 1;
485 i2
[n
] = tile2_cell
[n
*2] - 1;
486 j2
[n
] = tile2_cell
[n
*2+1] - 1;
487 area
[n
] /= garea
; /* rescale the exchange grid area to unit earth area */
493 } /* read_mosaic_xgrid_order1 */
495 /* NOTE: di, dj is for tile1, */
496 /****************************************************************************/
497 void read_mosaic_xgrid_order2_(const char *xgrid_file
, int *i1
, int *j1
, int *i2
, int *j2
, double *area
, double *di
, double *dj
)
499 read_mosaic_xgrid_order2(xgrid_file
, i1
, j1
, i2
, j2
, area
, di
, dj
);
502 void read_mosaic_xgrid_order2(const char *xgrid_file
, int *i1
, int *j1
, int *i2
, int *j2
, double *area
, double *di
, double *dj
)
505 int *tile1_cell
, *tile2_cell
;
506 double *tile1_distance
;
508 ncells
= get_dimlen(xgrid_file
, "ncells");
510 tile1_cell
= (int *)malloc(ncells
*2*sizeof(int ));
511 tile2_cell
= (int *)malloc(ncells
*2*sizeof(int ));
512 tile1_distance
= (double *)malloc(ncells
*2*sizeof(double));
513 get_var_data(xgrid_file
, "tile1_cell", tile1_cell
);
514 get_var_data(xgrid_file
, "tile2_cell", tile2_cell
);
515 get_var_data(xgrid_file
, "xgrid_area", area
);
516 get_var_data(xgrid_file
, "tile1_distance", tile1_distance
);
518 garea
= 4*M_PI
*RADIUS
*RADIUS
;
520 for(n
=0; n
<ncells
; n
++) {
521 i1
[n
] = tile1_cell
[n
*2] - 1;
522 j1
[n
] = tile1_cell
[n
*2+1] - 1;
523 i2
[n
] = tile2_cell
[n
*2] - 1;
524 j2
[n
] = tile2_cell
[n
*2+1] - 1;
525 di
[n
] = tile1_distance
[n
*2];
526 dj
[n
] = tile1_distance
[n
*2+1];
527 area
[n
] /= garea
; /* rescale the exchange grid area to unit earth area */
532 free(tile1_distance
);
534 } /* read_mosaic_xgrid_order2 */
536 /******************************************************************************
537 int read_mosaic_ntiles(const char *mosaic_file)
538 return number tiles in mosaic_file
539 ******************************************************************************/
540 int read_mosaic_ntiles_(const char *mosaic_file
)
542 return read_mosaic_ntiles(mosaic_file
);
544 int read_mosaic_ntiles(const char *mosaic_file
)
549 ntiles
= get_dimlen(mosaic_file
, "ntiles");
553 } /* read_mosaic_ntiles */
555 /******************************************************************************
556 int read_mosaic_ncontacts(const char *mosaic_file)
557 return number of contacts in mosaic_file
558 ******************************************************************************/
559 int read_mosaic_ncontacts_(const char *mosaic_file
)
561 return read_mosaic_ncontacts(mosaic_file
);
563 int read_mosaic_ncontacts(const char *mosaic_file
)
568 if(field_exist(mosaic_file
, "contacts") )
569 ncontacts
= get_dimlen(mosaic_file
, "ncontact");
575 } /* read_mosaic_ncontacts */
578 /*****************************************************************************
579 void read_mosaic_grid_sizes(const char *mosaic_file, int *nx, int *ny)
580 read mosaic grid size of each tile, currently we are assuming the refinement is 2.
581 We assume the grid files are located at the same directory as mosaic_file.
582 *****************************************************************************/
583 void read_mosaic_grid_sizes_(const char *mosaic_file
, int *nx
, int *ny
)
585 read_mosaic_grid_sizes(mosaic_file
, nx
, ny
);
587 void read_mosaic_grid_sizes(const char *mosaic_file
, int *nx
, int *ny
)
589 unsigned int ntiles
, n
;
590 char gridfile
[STRING
], tilefile
[2*STRING
];
592 const int x_refine
= 2, y_refine
= 2;
594 get_file_dir(mosaic_file
, dir
);
595 ntiles
= get_dimlen(mosaic_file
, "ntiles");
596 for(n
= 0; n
< ntiles
; n
++) {
597 get_string_data_level(mosaic_file
, "gridfiles", gridfile
, &n
);
598 sprintf(tilefile
, "%s/%s", dir
, gridfile
);
599 nx
[n
] = get_dimlen(tilefile
, "nx");
600 ny
[n
] = get_dimlen(tilefile
, "ny");
601 if(nx
[n
]%x_refine
!= 0) error_handler("Error from read_mosaic_grid_sizes: nx is not divided by x_refine");
602 if(ny
[n
]%y_refine
!= 0) error_handler("Error from read_mosaic_grid_sizes: ny is not divided by y_refine");
607 } /* read_mosaic_grid_sizes */
610 /******************************************************************************
611 void read_mosaic_contact(const char *mosaic_file)
612 read mosaic contact information
613 ******************************************************************************/
614 void read_mosaic_contact_(const char *mosaic_file
, int *tile1
, int *tile2
, int *istart1
, int *iend1
,
615 int *jstart1
, int *jend1
, int *istart2
, int *iend2
, int *jstart2
, int *jend2
)
617 read_mosaic_contact(mosaic_file
, tile1
, tile2
, istart1
, iend1
, jstart1
, jend1
, istart2
, iend2
, jstart2
, jend2
);
620 /* transfer the index from supergrid to model grid
621 return 0 if istart = iend
625 int transfer_to_model_index(int istart_in
, int iend_in
, int *istart_out
, int *iend_out
, int refine_ratio
)
630 if( istart_in
== iend_in
) {
632 istart_out
[0] = (istart_in
+1)/refine_ratio
-1;
633 iend_out
[0] = istart_out
[0];
637 if( iend_in
> istart_in
) {
638 istart_out
[0] = istart_in
- 1;
639 iend_out
[0] = iend_in
- refine_ratio
;
642 istart_out
[0] = istart_in
- refine_ratio
;
643 iend_out
[0] = iend_in
- 1;
646 if( istart_out
[0]%refine_ratio
|| iend_out
[0]%refine_ratio
)
647 error_handler("Error from read_mosaic: mismatch between refine_ratio and istart_in/iend_in");
648 istart_out
[0] /= refine_ratio
;
649 iend_out
[0] /= refine_ratio
;
657 void read_mosaic_contact(const char *mosaic_file
, int *tile1
, int *tile2
, int *istart1
, int *iend1
,
658 int *jstart1
, int *jend1
, int *istart2
, int *iend2
, int *jstart2
, int *jend2
)
660 char contacts
[STRING
];
663 char pstring
[MAXVAR
][STRING
];
664 unsigned int nstr
, ntiles
, ncontacts
, n
, m
, l
, found
;
665 const int x_refine
= 2, y_refine
= 2;
666 int i1_type
, j1_type
, i2_type
, j2_type
;
668 ntiles
= get_dimlen(mosaic_file
, "ntiles");
669 gridtiles
= (char **)malloc(ntiles
*sizeof(char *));
670 for(n
=0; n
<ntiles
; n
++) {
671 gridtiles
[n
] = (char *)malloc(STRING
*sizeof(char));
672 get_string_data_level(mosaic_file
, "gridtiles", gridtiles
[n
], &n
);
675 ncontacts
= get_dimlen(mosaic_file
, "ncontact");
676 for(n
= 0; n
< ncontacts
; n
++) {
677 get_string_data_level(mosaic_file
, "contacts", contacts
, &n
);
678 /* parse the string contacts to get tile number */
679 tokenize( contacts
, ":", STRING
, MAXVAR
, (char *)pstring
, &nstr
);
680 if(nstr
!= 4) error_handler("Error from read_mosaic: number of elements "
681 "in contact seperated by :/:: should be 4");
683 for(m
=0; m
<ntiles
; m
++) {
684 if(strcmp(gridtiles
[m
], pstring
[1]) == 0) { /*found the tile name */
690 if(!found
) error_handler("error from read_mosaic: the first tile name specified "
691 "in contact is not found in tile list");
693 for(m
=0; m
<ntiles
; m
++) {
694 if(strcmp(gridtiles
[m
], pstring
[3]) == 0) { /*found the tile name */
700 if(!found
) error_handler("error from read_mosaic: the second tile name specified "
701 "in contact is not found in tile list");
702 get_string_data_level(mosaic_file
, "contact_index", contacts
, &n
);
703 /* parse the string to get contact index */
704 tokenize( contacts
, ":,", STRING
, MAXVAR
, (char *)pstring
, &nstr
);
705 if(nstr
!= 8) error_handler("Error from read_mosaic: number of elements "
706 "in contact_index seperated by :/, should be 8");
707 /* make sure the string is only composed of numbers */
708 for(m
=0; m
<nstr
; m
++){
709 for(l
=0; l
<strlen(pstring
[m
]); l
++){
710 if(pstring
[m
][l
] > '9' || pstring
[m
][l
] < '0' ) {
711 error_handler("Error from read_mosaic: some of the character in "
712 "contact_indices except token is not digit number");
716 istart1
[n
] = atoi(pstring
[0]);
717 iend1
[n
] = atoi(pstring
[1]);
718 jstart1
[n
] = atoi(pstring
[2]);
719 jend1
[n
] = atoi(pstring
[3]);
720 istart2
[n
] = atoi(pstring
[4]);
721 iend2
[n
] = atoi(pstring
[5]);
722 jstart2
[n
] = atoi(pstring
[6]);
723 jend2
[n
] = atoi(pstring
[7]);
724 i1_type
= transfer_to_model_index(istart1
[n
], iend1
[n
], istart1
+n
, iend1
+n
, x_refine
);
725 j1_type
= transfer_to_model_index(jstart1
[n
], jend1
[n
], jstart1
+n
, jend1
+n
, y_refine
);
726 i2_type
= transfer_to_model_index(istart2
[n
], iend2
[n
], istart2
+n
, iend2
+n
, x_refine
);
727 j2_type
= transfer_to_model_index(jstart2
[n
], jend2
[n
], jstart2
+n
, jend2
+n
, y_refine
);
728 if( i1_type
== 0 && j1_type
== 0 )
729 error_handler("Error from read_mosaic_contact:istart1==iend1 and jstart1==jend1");
730 if( i2_type
== 0 && j2_type
== 0 )
731 error_handler("Error from read_mosaic_contact:istart2==iend2 and jstart2==jend2");
732 if( i1_type
+ j1_type
!= i2_type
+ j2_type
)
733 error_handler("Error from read_mosaic_contact: It is not a line or overlap contact");
737 for(m
=0; m
<ntiles
; m
++) {
744 } /* read_mosaic_contact */
747 /******************************************************************************
748 void read_mosaic_grid_data(const char *mosaic_file, const char *name, int nx, int ny,
749 double *data, int level, int ioff, int joff)
750 read mosaic grid information onto model grid. We assume the refinement is 2 right now.
751 We may remove this restriction in the future. nx and ny are model grid size. level
752 is the tile number. ioff and joff to indicate grid location. ioff =0 and joff = 0
753 for C-cell. ioff=0 and joff=1 for E-cell, ioff=1 and joff=0 for N-cell,
754 ioff=1 and joff=1 for T-cell
755 ******************************************************************************/
756 void read_mosaic_grid_data(const char *mosaic_file
, const char *name
, int nx
, int ny
,
757 double *data
, unsigned int level
, int ioff
, int joff
)
759 char tilefile
[STRING
], gridfile
[STRING
], dir
[STRING
];
761 int ni
, nj
, nxp
, nyp
, i
, j
;
763 get_file_dir(mosaic_file
, dir
);
765 get_string_data_level(mosaic_file
, "gridfiles", gridfile
, &level
);
766 sprintf(tilefile
, "%s/%s", dir
, gridfile
);
768 ni
= get_dimlen(tilefile
, "nx");
769 nj
= get_dimlen(tilefile
, "ny");
771 if( ni
!= nx
*2 || nj
!= ny
*2) error_handler("supergrid size should be double of the model grid size");
772 tmp
= (double *)malloc((ni
+1)*(nj
+1)*sizeof(double));
773 get_var_data( tilefile
, name
, tmp
);
776 for(j
=0; j
<nyp
; j
++) for(i
=0; i
<nxp
; i
++) data
[j
*nxp
+i
] = tmp
[(2*j
+joff
)*(ni
+1)+2*i
+ioff
];
779 } /* read_mosaic_grid_data */