38 sprintf( errmsg,
"%s: %s", msg, (
char *)nc_strerror(
status) );
55 strptr = strrchr(file,
'/');
58 strncpy(dir, file,
len);
79 sprintf(msg,
"field_exist: in opening file %s", file);
90 sprintf(msg,
"field_exist: in closing file %s.", file);
95 error_handler(
"read_mosaic: Add flag -Duse_netCDF when compiling");
112 sprintf(msg,
"in opening file %s", file);
118 sprintf(msg,
"in getting dimid of %s from file %s.",
name, file);
124 sprintf(msg,
"in getting dimension size of %s from file %s.",
name, file);
129 sprintf(msg,
"in closing file %s.", file);
135 sprintf(msg,
"in closing file %s", file);
139 error_handler(
"read_mosaic: Add flag -Duse_netCDF when compiling");
158 sprintf(msg,
"in opening file %s", file);
163 sprintf(msg,
"in getting varid of %s from file %s.",
name, file);
168 sprintf(msg,
"in getting data of %s from file %s.",
name, file);
173 sprintf(msg,
"in closing file %s.", file);
177 error_handler(
"read_mosaic: Add flag -Duse_netCDF when compiling");
189 size_t start[4], nread[4];
195 sprintf(msg,
"in opening file %s", file);
200 sprintf(msg,
"in getting varid of %s from file %s.",
name, file);
209 sprintf(msg,
"in getting data of %s from file %s.",
name, file);
214 sprintf(msg,
"in closing file %s.", file);
218 error_handler(
"read_mosaic: Add flag -Duse_netCDF when compiling");
238 sprintf(msg,
"in opening file %s", file);
243 sprintf(msg,
"in getting varid of %s from file %s.",
name, file);
247 status = nc_inq_vartype(
ncid, varid, &vartype);
249 sprintf(msg,
"get_var_data: in getting vartype of of %s in file %s ",
name, file);
254 case NC_DOUBLE:
case NC_FLOAT:
258 status = nc_get_var_double(
ncid, varid, 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);
270 sprintf(msg,
"in getting data of %s from file %s.",
name, file);
275 sprintf(msg,
"in closing file %s.", file);
279 error_handler(
"read_mosaic: Add flag -Duse_netCDF when compiling");
298 sprintf(msg,
"get_var_data_region: in opening file %s", file);
303 sprintf(msg,
"in getting varid of %s from file %s.",
name, file);
307 status = nc_inq_vartype(
ncid, varid, &vartype);
309 sprintf(msg,
"get_var_data_region: in getting vartype of of %s in file %s ",
name, file);
314 case NC_DOUBLE:
case NC_FLOAT:
325 sprintf(msg,
"get_var_data_region: field %s in file %s has an invalid type, " 326 "the type should be NC_DOUBLE, NC_FLOAT or NC_INT",
name, file);
331 sprintf(msg,
"get_var_data_region: in getting data of %s from file %s.",
name, file);
336 sprintf(msg,
"get_var_data_region: in closing file %s.", file);
340 error_handler(
"read_mosaic: Add flag -Duse_netCDF when compiling");
357 sprintf(msg,
"in opening file %s", file);
362 sprintf(msg,
"in getting varid of %s from file %s.",
name, file);
365 status = nc_get_att_text(
ncid, varid, attname, att);
367 sprintf(msg,
"in getting attribute %s of %s from file %s.", attname,
name, file);
372 sprintf(msg,
"in closing file %s.", file);
376 error_handler(
"read_mosaic: Add flag -Duse_netCDF when compiling");
450 int *tile1_cell, *tile2_cell;
459 tile1_cell = (
int *)malloc(ncells*2*
sizeof(
int));
460 tile2_cell = (
int *)malloc(ncells*2*
sizeof(
int));
468 for(
n=0;
n<ncells;
n++) {
469 i1[
n] = tile1_cell[
n*2] - 1;
470 j1[
n] = tile1_cell[
n*2+1] - 1;
471 i2[
n] = tile2_cell[
n*2] - 1;
472 j2[
n] = tile2_cell[
n*2+1] - 1;
501 int *tile1_cell, *tile2_cell;
502 size_t start[4], nread[4];
511 tile1_cell = (
int *)malloc(ncells*2*
sizeof(
int));
512 tile2_cell = (
int *)malloc(ncells*2*
sizeof(
int));
530 for(
n=0;
n<ncells;
n++) {
531 i1[
n] = tile1_cell[
n*2] - 1;
532 j1[
n] = tile1_cell[
n*2+1] - 1;
533 i2[
n] = tile2_cell[
n*2] - 1;
534 j2[
n] = tile2_cell[
n*2+1] - 1;
564 int *tile1_cell, *tile2_cell;
565 double *tile1_distance;
573 tile1_cell = (
int *)malloc(ncells*2*
sizeof(
int ));
574 tile2_cell = (
int *)malloc(ncells*2*
sizeof(
int ));
575 tile1_distance = (
double *)malloc(ncells*2*
sizeof(
double));
579 get_var_data(xgrid_file,
"tile1_distance", tile1_distance);
583 for(
n=0;
n<ncells;
n++) {
584 i1[
n] = tile1_cell[
n*2] - 1;
585 j1[
n] = tile1_cell[
n*2+1] - 1;
586 i2[
n] = tile2_cell[
n*2] - 1;
587 j2[
n] = tile2_cell[
n*2+1] - 1;
588 di[
n] = tile1_distance[
n*2];
589 dj[
n] = tile1_distance[
n*2+1];
595 free(tile1_distance);
636 ncontacts =
get_dimlen(mosaic_file,
"ncontact");
667 sprintf(tilefile,
"%s/%s", dir, gridfile);
685 int *jstart1,
int *jend1,
int *istart2,
int *iend2,
int *jstart2,
int *jend2)
687 read_mosaic_contact(mosaic_file, tile1, tile2, istart1, iend1, jstart1, jend1, istart2, iend2, jstart2, jend2);
701 if( istart_in == iend_in ) {
703 istart_out[0] = (istart_in+1)/refine_ratio-1;
704 iend_out[0] = istart_out[0];
708 if( iend_in > istart_in ) {
709 istart_out[0] = istart_in - 1;
710 iend_out[0] = iend_in - refine_ratio;
713 istart_out[0] = istart_in - refine_ratio;
714 iend_out[0] = iend_in - 1;
717 if( istart_out[0]%refine_ratio || iend_out[0]%refine_ratio)
718 error_handler(
"Error from read_mosaic: mismatch between refine_ratio and istart_in/iend_in");
719 istart_out[0] /= refine_ratio;
720 iend_out[0] /= refine_ratio;
729 int *jstart1,
int *jend1,
int *istart2,
int *iend2,
int *jstart2,
int *jend2)
735 unsigned int nstr,
ntiles, ncontacts,
n,
m, l, found;
737 int i1_type, j1_type, i2_type, j2_type;
740 gridtiles = (
char **)malloc(
ntiles*
sizeof(
char *));
742 gridtiles[
n] = (
char *)malloc(
STRING*
sizeof(
char));
746 ncontacts =
get_dimlen(mosaic_file,
"ncontact");
747 for(
n = 0;
n < ncontacts;
n++) {
751 if(nstr != 4)
error_handler(
"Error from read_mosaic: number of elements " 752 "in contact seperated by :/:: should be 4");
755 if(strcmp(gridtiles[
m], pstring[1]) == 0) {
761 if(!found)
error_handler(
"error from read_mosaic: the first tile name specified " 762 "in contact is not found in tile list");
765 if(strcmp(gridtiles[
m], pstring[3]) == 0) {
771 if(!found)
error_handler(
"error from read_mosaic: the second tile name specified " 772 "in contact is not found in tile list");
776 if(nstr != 8)
error_handler(
"Error from read_mosaic: number of elements " 777 "in contact_index seperated by :/, should be 8");
779 for(
m=0;
m<nstr;
m++){
780 for(l=0; l<
strlen(pstring[
m]); l++){
781 if(pstring[
m][l] >
'9' || pstring[
m][l] <
'0' ) {
782 error_handler(
"Error from read_mosaic: some of the character in " 783 "contact_indices except token is not digit number");
787 istart1[
n] = atoi(pstring[0]);
788 iend1[
n] = atoi(pstring[1]);
789 jstart1[
n] = atoi(pstring[2]);
790 jend1[
n] = atoi(pstring[3]);
791 istart2[
n] = atoi(pstring[4]);
792 iend2[
n] = atoi(pstring[5]);
793 jstart2[
n] = atoi(pstring[6]);
794 jend2[
n] = atoi(pstring[7]);
799 if( i1_type == 0 && j1_type == 0 )
800 error_handler(
"Error from read_mosaic_contact:istart1==iend1 and jstart1==jend1");
801 if( i2_type == 0 && j2_type == 0 )
802 error_handler(
"Error from read_mosaic_contact:istart2==iend2 and jstart2==jend2");
803 if( i1_type + j1_type != i2_type + j2_type )
804 error_handler(
"Error from read_mosaic_contact: It is not a line or overlap contact");
828 double *data,
unsigned int level,
int ioff,
int joff)
832 int ni, nj, nxp, nyp,
i,
j;
837 sprintf(tilefile,
"%s/%s", dir, gridfile);
842 if( ni !=
nx*2 || nj !=
ny*2)
error_handler(
"supergrid size should be double of the model grid size");
843 tmp = (
double *)malloc((ni+1)*(nj+1)*
sizeof(
double));
847 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];
l_size ! loop over number of fields ke do je do i
subroutine error_handler(routine, message)
double get_global_area(void)
int read_mosaic_ncontacts_(const char *mosaic_file)
void read_mosaic_contact_(const char *mosaic_file, int *tile1, int *tile2, int *istart1, int *iend1, int *jstart1, int *jend1, int *istart2, int *iend2, int *jstart2, int *jend2)
integer, parameter, public strlen
integer, save, private iec
int read_mosaic_ntiles_(const char *mosaic_file)
int read_mosaic_xgrid_size_(const char *xgrid_file)
void get_string_data(const char *file, const char *name, char *data)
void read_mosaic_xgrid_order2(const char *xgrid_file, int *i1, int *j1, int *i2, int *j2, double *area, double *di, double *dj)
int transfer_to_model_index(int istart_in, int iend_in, int *istart_out, int *iend_out, int refine_ratio)
void get_var_data(const char *file, const char *name, void *data)
void tokenize(const char *const string, const char *tokens, unsigned int varlen, unsigned int maxvar, char *pstring, unsigned int *const nstr)
int read_mosaic_ncontacts(const char *mosaic_file)
void read_mosaic_grid_sizes_(const char *mosaic_file, int *nx, int *ny)
void read_mosaic_xgrid_order1_(const char *xgrid_file, int *i1, int *j1, int *i2, int *j2, double *area)
void get_var_text_att(const char *file, const char *name, const char *attname, char *att)
*f90 *************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************! this routine is used to retrieve scalar boundary data for symmetric domain. subroutine MPP_GET_BOUNDARY_2D_(field, domain, ebuffer, sbuffer, wbuffer, nbuffer, flags, &position, complete, tile_count) type(domain2D), intent(in) ::domain MPP_TYPE_, intent(in) ::field(:,:) MPP_TYPE_, intent(inout), optional ::ebuffer(:), sbuffer(:), wbuffer(:), nbuffer(:) integer, intent(in), optional ::flags, position, tile_count logical, intent(in), optional ::complete MPP_TYPE_ ::field3D(size(field, 1), size(field, 2), 1) MPP_TYPE_, allocatable, dimension(:,:) ::ebuffer2D, sbuffer2D, wbuffer2D, nbuffer2D integer ::xcount, ycount integer ::ntile logical ::need_ebuffer, need_sbuffer, need_wbuffer, need_nbuffer integer(LONG_KIND), dimension(MAX_DOMAIN_FIELDS, MAX_TILES), save ::f_addrs=-9999 integer(LONG_KIND), dimension(4, MAX_DOMAIN_FIELDS, MAX_TILES), save ::b_addrs=-9999 integer, save ::bsize(4)=0, isize=0, jsize=0, ksize=0, pos, list=0, l_size=0, upflags integer ::buffer_size(4) integer ::max_ntile, tile, update_position, ishift, jshift logical ::do_update, is_complete, set_mismatch character(len=3) ::text MPP_TYPE_ ::d_type type(overlapSpec), pointer ::bound=> NULL() ntile
void read_mosaic_xgrid_order2_(const char *xgrid_file, int *i1, int *j1, int *i2, int *j2, double *area, double *di, double *dj)
l_size ! loop over number of fields ke do j
int read_mosaic_xgrid_size(const char *xgrid_file)
void get_var_data_region(const char *file, const char *name, const size_t *start, const size_t *nread, void *data)
double get_global_area_(void)
void get_file_dir(const char *file, char *dir)
void read_mosaic_xgrid_order1(const char *xgrid_file, int *i1, int *j1, int *i2, int *j2, double *area)
int read_mosaic_ntiles(const char *mosaic_file)
int field_exist(const char *file, const char *name)
real, dimension(:,:), allocatable area
void read_mosaic_contact(const char *mosaic_file, int *tile1, int *tile2, int *istart1, int *iend1, int *jstart1, int *jend1, int *istart2, int *iend2, int *jstart2, int *jend2)
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> tlevel if(PRESENT(start_in) .AND. PRESENT(axsiz_in)) then if(size(start(! the data domain and compute domain must refer to the subdomain being passed ! In this ! since that attempts to gather all data on PE start
void get_string_data_level(const char *file, const char *name, char *data, const unsigned int *level)
integer, parameter x_refine
void handle_netcdf_error(const char *msg, int status)
void read_mosaic_grid_data(const char *mosaic_file, const char *name, int nx, int ny, double *data, unsigned int level, int ioff, int joff)
integer, save, private isc
************************************************************************GNU Lesser General Public License **This file is part of the GFDL Flexible Modeling System(FMS). ! *! *FMS is free software without even the implied warranty of MERCHANTABILITY or *FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License *for more details **You should have received a copy of the GNU Lesser General Public *License along with FMS If see< http:! ***********************************************************************subroutine READ_RECORD_CORE_(unit, field, nwords, data, start, axsiz) integer, intent(in) ::unit type(fieldtype), intent(in) ::field integer, intent(in) ::nwords MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in) ::start(:), axsiz(:) integer(SHORT_KIND) ::i2vals(nwords)!rab used in conjunction with transfer intrinsic to determine size of a variable integer(KIND=1) ::one_byte(8) integer ::word_sz!#ifdef __sgi integer(INT_KIND) ::ivals(nwords) real(FLOAT_KIND) ::rvals(nwords)!#else! integer ::ivals(nwords)! real ::rvals(nwords)!#endif real(DOUBLE_KIND) ::r8vals(nwords) pointer(ptr1, i2vals) pointer(ptr2, ivals) pointer(ptr3, rvals) pointer(ptr4, r8vals) if(mpp_io_stack_size< nwords) call mpp_io_set_stack_size(nwords) call mpp_error(FATAL, 'MPP_READ currently requires use_netCDF option') end subroutine READ_RECORD_CORE_ subroutine READ_RECORD_(unit, field, nwords, data, time_level, domain, position, tile_count, start_in, axsiz_in)!routine that is finally called by all mpp_read routines to perform the read!a non-netCDF record contains:! field ID! a set of 4 coordinates(is:ie, js:je) giving the data subdomain! a timelevel and a timestamp(=NULLTIME if field is static)! 3D real data(stored as 1D)!if you are using direct access I/O, the RECL argument to OPEN must be large enough for the above!in a global direct access file, record position on PE is given by %record.!Treatment of timestamp:! We assume that static fields have been passed without a timestamp.! Here that is converted into a timestamp of NULLTIME.! For non-netCDF fields, field is treated no differently, but is written! with a timestamp of NULLTIME. There is no check in the code to prevent! the user from repeatedly writing a static field. integer, intent(in) ::unit, nwords type(fieldtype), intent(in) ::field MPP_TYPE_, intent(inout) ::data(nwords) integer, intent(in), optional ::time_level type(domain2D), intent(in), optional ::domain integer, intent(in), optional ::position, tile_count integer, intent(in), optional ::start_in(:), axsiz_in(:) integer, dimension(size(field%axes(:))) ::start, axsiz integer ::tlevel !, subdomain(4) integer ::i, error, is, ie, js, je, isg, ieg, jsg, jeg type(domain2d), pointer ::io_domain=> tlevel if(PRESENT(start_in) .AND. PRESENT(axsiz_in)) then if(size(start(! the data domain and compute domain must refer to the subdomain being passed ! In this ! since that attempts to gather all data on PE size(field%axes(:)) axsiz(i)
void read_mosaic_xgrid_order1_region(const char *xgrid_file, int *i1, int *j1, int *i2, int *j2, double *area, int *isc, int *iec)
void read_mosaic_xgrid_order1_region_(const char *xgrid_file, int *i1, int *j1, int *i2, int *j2, double *area, int *isc, int *iec)
int get_dimlen(const char *file, const char *name)
void read_mosaic_grid_sizes(const char *mosaic_file, int *nx, int *ny)
integer, parameter y_refine