23 #include "read_mosaic.h"
25 #include "mosaic_util.h"
38 void handle_netcdf_error(
const char *msg,
int status )
42 sprintf( errmsg,
"%s: %s", msg, (
char *)nc_strerror(status) );
43 error_handler(errmsg);
52 void get_file_dir(
const char *file,
char *dir)
55 const char *strptr = NULL;
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);
99 error_handler(
"read_mosaic: Add flag -Duse_netCDF when compiling");
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");
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");
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");
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");
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");
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");
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;
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;
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;
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];
532 free(tile1_distance);
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");
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");
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");
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);
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);
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) {
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) {
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);
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");
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++) {
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];
real(r8_kind), dimension(:,:), allocatable area
area of each grid box