From dced1ad910ba1ba9f7c87aed09dad6f42a7735e8 Mon Sep 17 00:00:00 2001 From: Wenshan Wang Date: Sun, 24 May 2020 10:47:36 -0700 Subject: [PATCH 1/5] Replace -1e34 with _FillValue in active tracers --- src/core_ocean/shared/mpas_ocn_diagnostics.F | 5 +++-- src/core_ocean/shared/mpas_ocn_init_routines.F | 7 ++++--- src/core_ocean/shared/mpas_ocn_vmix.F | 3 ++- .../tracer_groups/Registry_activeTracers.xml | 2 +- src/tools/registry/gen_inc.c | 16 +++++++--------- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/core_ocean/shared/mpas_ocn_diagnostics.F b/src/core_ocean/shared/mpas_ocn_diagnostics.F index 3ef8183946..052276cc18 100644 --- a/src/core_ocean/shared/mpas_ocn_diagnostics.F +++ b/src/core_ocean/shared/mpas_ocn_diagnostics.F @@ -28,6 +28,7 @@ module ocn_diagnostics use mpas_vector_reconstruction use mpas_stream_manager use mpas_io_units + use mpas_io, only : MPAS_REAL_FILLVAL use ocn_constants use ocn_gm @@ -322,8 +323,8 @@ subroutine ocn_diagnostic_solve(dt, statePool, forcingPool, meshPool, diagnostic !$omp master normalVelocity(:,nEdges+1) = -1e34 layerThickness(:,nCells+1) = -1e34 - activeTracers(indexTemperature,:,nCells+1) = -1e34 - activeTracers(indexSalinity,:,nCells+1) = -1e34 + activeTracers(indexTemperature,:,nCells+1) = MPAS_REAL_FILLVAL + activeTracers(indexSalinity,:,nCells+1) = MPAS_REAL_FILLVAL !$omp end master call mpas_threading_barrier() diff --git a/src/core_ocean/shared/mpas_ocn_init_routines.F b/src/core_ocean/shared/mpas_ocn_init_routines.F index e737cac4de..246ba9dbe0 100644 --- a/src/core_ocean/shared/mpas_ocn_init_routines.F +++ b/src/core_ocean/shared/mpas_ocn_init_routines.F @@ -27,6 +27,7 @@ module ocn_init_routines use mpas_timer use mpas_dmpar use mpas_constants + use mpas_io, only : MPAS_REAL_FILLVAL use mpas_rbf_interpolation use mpas_vector_operations @@ -485,7 +486,7 @@ subroutine ocn_init_routines_vert_coord(domain)!{{{ do iCell = 1,nCells if (landIceMask(iCell)==0.and.abs(sum(layerThickness(1:maxLevelCell(iCell),iCell))-bottomDepth(iCell))>20.0_RKIND) then consistentSSH = .false. - call mpas_log_write(' Warning: Sea surface height is outside of acceptable physical range, i.e. abs(sum(h)-bottomDepth)>20m.', & + call mpas_log_write(' Warning: Sea surface height is outside of acceptable physical range, i.e. abs(sum(h)-bottomDepth)>20m.', & MPAS_LOG_ERR) call mpas_log_write(' iCell: $i, maxLevelCell(iCell): $i, bottomDepth(iCell): $r, sum(h): $r', & intArgs=(/iCell, maxLevelCell(iCell) /), & @@ -496,7 +497,7 @@ subroutine ocn_init_routines_vert_coord(domain)!{{{ do iCell = 1,nCells if (abs(sum(layerThickness(1:maxLevelCell(iCell),iCell))-bottomDepth(iCell))>20.0_RKIND) then consistentSSH = .false. - call mpas_log_write(' Warning: Sea surface height is outside of acceptable physical range, i.e. abs(sum(h)-bottomDepth)>20m.', & + call mpas_log_write(' Warning: Sea surface height is outside of acceptable physical range, i.e. abs(sum(h)-bottomDepth)>20m.', & MPAS_LOG_ERR) call mpas_log_write(' iCell: $i, maxLevelCell(iCell): $i, bottomDepth(iCell): $r, sum(h): $r', & intArgs=(/iCell, maxLevelCell(iCell) /), & @@ -659,7 +660,7 @@ subroutine ocn_init_routines_block(block, dt, err)!{{{ call mpas_pool_get_array(tracersPool, groupItr % memberName, tracersGroup, 1) if ( associated(tracersGroup) ) then do iCell=1,nCells - tracersGroup(:, maxLevelCell(iCell)+1:nVertLevels,iCell) = -1.0e34_RKIND + tracersGroup(:, maxLevelCell(iCell)+1:nVertLevels,iCell) = MPAS_REAL_FILLVAL end do end if end if diff --git a/src/core_ocean/shared/mpas_ocn_vmix.F b/src/core_ocean/shared/mpas_ocn_vmix.F index e7d9e4814c..e1c0143b0e 100644 --- a/src/core_ocean/shared/mpas_ocn_vmix.F +++ b/src/core_ocean/shared/mpas_ocn_vmix.F @@ -25,6 +25,7 @@ module ocn_vmix use mpas_derived_types use mpas_pool_routines use mpas_timer + use mpas_io, only : MPAS_REAL_FILLVAL use ocn_constants use ocn_vmix_coefs_const @@ -605,7 +606,7 @@ subroutine ocn_tracer_vmix_tend_implicit(meshPool, dt, vertDiffTopOfCell, layerT tracersTemp, N, nVertLevels, num_tracers) tracers(:,1:N,iCell) = tracersTemp(:,1:N) - tracers(:,N+1:nVertLevels,iCell) = -1e34 + tracers(:,N+1:nVertLevels,iCell) = MPAS_REAL_FILLVAL end do !$omp end do call mpas_timer_stop('vmix tracers tend imp loop') diff --git a/src/core_ocean/tracer_groups/Registry_activeTracers.xml b/src/core_ocean/tracer_groups/Registry_activeTracers.xml index 66e2dba813..dd57ea9ec5 100644 --- a/src/core_ocean/tracer_groups/Registry_activeTracers.xml +++ b/src/core_ocean/tracer_groups/Registry_activeTracers.xml @@ -61,7 +61,7 @@ - + diff --git a/src/tools/registry/gen_inc.c b/src/tools/registry/gen_inc.c index 965efed6c5..7a119117a6 100644 --- a/src/tools/registry/gen_inc.c +++ b/src/tools/registry/gen_inc.c @@ -1386,10 +1386,10 @@ int parse_var_array(FILE *fd, ezxml_t registry, ezxml_t superStruct, ezxml_t var fortprintf(fd, " call mpas_add_att(%s(%d) %% attLists(const_index) %% attList, 'units', '%s')\n", pointer_name, time_lev, temp_str); } - if ( vararrmissingval ) { - fortprintf(fd, " call mpas_add_att(%s(%d) %% attLists(const_index) %% attList, 'missing_value', %s)\n", pointer_name, time_lev, missing_value); + if ( vararrmissingval != NULL ) { + // fortprintf(fd, " call mpas_add_att(%s(%d) %% attLists(const_index) %% attList, 'missing_value', %s)\n", pointer_name, time_lev, missing_value); // Uncomment to add _FillValue to match missing_value - // fortprintf(fd, " call mpas_add_att(%s(%d) %% attLists(const_index) %% attList, '_FillValue', %s)\n", pointer_name, time_lev, missing_value); + fortprintf(fd, " call mpas_add_att(%s(%d) %% attLists(const_index) %% attList, '_FillValue', %s)\n", pointer_name, time_lev, missing_value); } fortprintf(fd, " %s(%d) %% missingValue = %s\n", pointer_name, time_lev, missing_value); fortprintf(fd, " %s(%d) %% constituentNames(const_index) = '%s'\n", pointer_name, time_lev, varname); @@ -1596,9 +1596,9 @@ int parse_var(FILE *fd, ezxml_t registry, ezxml_t superStruct, ezxml_t currentVa } if ( varmissingval != NULL ) { - fortprintf(fd, " call mpas_add_att(%s(%d) %% attLists(1) %% attList, 'missing_value', %s)\n", pointer_name, time_lev, missing_value); + // fortprintf(fd, " call mpas_add_att(%s(%d) %% attLists(1) %% attList, 'missing_value', %s)\n", pointer_name, time_lev, missing_value); // Uncomment to add _FillValue to match missing_value - // fortprintf(fd, " call mpas_add_att(%s(%d) %% attLists(1) %% attList, '_FillValue', %s)\n", pointer_name, time_lev, missing_value); + fortprintf(fd, " call mpas_add_att(%s(%d) %% attLists(1) %% attList, '_FillValue', %s)\n", pointer_name, time_lev, missing_value); } fortprintf(fd, " %s(%d) %% missingValue = %s\n", pointer_name, time_lev, missing_value); @@ -1672,7 +1672,7 @@ int parse_struct(FILE *fd, ezxml_t registry, ezxml_t superStruct, int subpool, c structname = ezxml_attr(superStruct, "name"); structnameincode = ezxml_attr(superStruct, "name_in_code"); - + if(!structnameincode){ structnameincode = ezxml_attr(superStruct, "name"); } @@ -2123,7 +2123,7 @@ int generate_immutable_streams(ezxml_t registry){/*{{{*/ fortprintf(fd, " call MPAS_stream_mgr_add_field(manager, \'%s\', \'%s\', packages=packages, ierr=ierr)\n", optname, optvarname); else fortprintf(fd, " call MPAS_stream_mgr_add_field(manager, \'%s\', \'%s\', ierr=ierr)\n", optname, optvarname); - + } /* Loop over arrays of fields listed within the stream */ @@ -2571,5 +2571,3 @@ int parse_structs_from_registry(ezxml_t registry)/*{{{*/ return 0; }/*}}}*/ - - From 75d400a1275b7d4b7319df8406a54c413af655a8 Mon Sep 17 00:00:00 2001 From: Wenshan Wang Date: Thu, 18 Jun 2020 19:03:22 -0700 Subject: [PATCH 2/5] Add _FillValue to all appropriate MPAS ocean fields --- src/core_ocean/tracer_groups/Registry_activeTracers.xml | 6 +++--- src/core_ocean/tracer_groups/Registry_debugTracers.xml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core_ocean/tracer_groups/Registry_activeTracers.xml b/src/core_ocean/tracer_groups/Registry_activeTracers.xml index dd57ea9ec5..7fe4ef553e 100644 --- a/src/core_ocean/tracer_groups/Registry_activeTracers.xml +++ b/src/core_ocean/tracer_groups/Registry_activeTracers.xml @@ -74,7 +74,7 @@ - + @@ -139,7 +139,7 @@ - + @@ -147,7 +147,7 @@ description="A non-negative field controlling the rate at which salinity is restored to salinityInteriorRestoringValue" /> - + diff --git a/src/core_ocean/tracer_groups/Registry_debugTracers.xml b/src/core_ocean/tracer_groups/Registry_debugTracers.xml index b2cab1dac8..d5e2b46913 100644 --- a/src/core_ocean/tracer_groups/Registry_debugTracers.xml +++ b/src/core_ocean/tracer_groups/Registry_debugTracers.xml @@ -49,7 +49,7 @@ - + From 1ba22cdc3783d5a5773383c5ded78488c6837461 Mon Sep 17 00:00:00 2001 From: Wenshan Wang Date: Wed, 15 Jul 2020 20:36:35 -0700 Subject: [PATCH 3/5] Add the CF-complient 'Time' variable in the test case --- src/core_ocean/Registry.xml | 7 ++- .../mode_forward/mpas_ocn_forward_mode.F | 4 ++ .../mode_forward/mpas_ocn_time_integration.F | 5 ++ src/tools/registry/gen_inc.c | 48 ++++++++++++++++--- .../global_ocean/QU240/test/config_test.xml | 5 ++ .../templates/streams/minimal_output.xml | 1 + 6 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/core_ocean/Registry.xml b/src/core_ocean/Registry.xml index 1910aa8310..89f21fef2d 100644 --- a/src/core_ocean/Registry.xml +++ b/src/core_ocean/Registry.xml @@ -2295,9 +2295,12 @@ - + /> + diff --git a/src/core_ocean/mode_forward/mpas_ocn_forward_mode.F b/src/core_ocean/mode_forward/mpas_ocn_forward_mode.F index f7e8f03ed3..eaee5f8132 100644 --- a/src/core_ocean/mode_forward/mpas_ocn_forward_mode.F +++ b/src/core_ocean/mode_forward/mpas_ocn_forward_mode.F @@ -122,6 +122,7 @@ function ocn_forward_mode_init(domain, startTimeStamp) result(ierr)!{{{ character (len=StrKIND), pointer :: xtime, simulationStartTime real (kind=RKIND), pointer :: daysSinceStartOfSim + real (kind=RKIND), pointer :: Time type (MPAS_Time_type) :: xtime_timeType, simulationStartTime_timeType type (MPAS_Time_Type) :: startTime, alarmTime type (MPAS_TimeInterval_type) :: timeStep @@ -350,6 +351,9 @@ function ocn_forward_mode_init(domain, startTimeStamp) result(ierr)!{{{ call mpas_get_timeInterval(xtime_timeType - simulationStartTime_timeType,dt=daysSinceStartOfSim) daysSinceStartOfSim = daysSinceStartOfSim*days_per_second + call mpas_pool_get_array(diagnosticsPool, 'Time',Time) + Time = daysSinceStartOfSim + block => block % next end do diff --git a/src/core_ocean/mode_forward/mpas_ocn_time_integration.F b/src/core_ocean/mode_forward/mpas_ocn_time_integration.F index 8a9618acba..a6011bf7fd 100644 --- a/src/core_ocean/mode_forward/mpas_ocn_time_integration.F +++ b/src/core_ocean/mode_forward/mpas_ocn_time_integration.F @@ -100,6 +100,7 @@ subroutine ocn_timestep(domain, dt, timeStamp)!{{{ character (len=StrKIND), pointer :: xtime real (kind=RKIND), pointer :: daysSinceStartOfSim + real (kind=RKIND), pointer :: Time character (len=StrKIND), pointer :: simulationStartTime type (MPAS_Time_type) :: xtime_timeType, simulationStartTime_timeType @@ -131,9 +132,13 @@ subroutine ocn_timestep(domain, dt, timeStamp)!{{{ daysSinceStartOfSim = daysSinceStartOfSim*days_per_second !$omp end single + call mpas_pool_get_array(diagnosticsPool, 'Time',Time) + Time = daysSinceStartOfSim + block => block % next end do + end subroutine ocn_timestep!}}} subroutine ocn_timestep_init(err)!{{{ diff --git a/src/tools/registry/gen_inc.c b/src/tools/registry/gen_inc.c index 7a119117a6..d763485e38 100644 --- a/src/tools/registry/gen_inc.c +++ b/src/tools/registry/gen_inc.c @@ -389,8 +389,8 @@ int build_dimension_information(ezxml_t registry, ezxml_t var, int *ndims, int * fprintf(stderr, "ERROR: Variable %s contains multiple decomposed dimensions in list: %s\n", varname, vardims); return 1; } - } else if (is_time) { - (*has_time) = 1; + } else if (is_time) { + (*has_time) = 1; } else if (!dim_exists) { fprintf(stderr, "ERROR: Dimension %s on variable %s doesn't exist.\n", token, varname); return 1; @@ -410,8 +410,8 @@ int build_dimension_information(ezxml_t registry, ezxml_t var, int *ndims, int * fprintf(stderr, "ERROR: Variable %s contains multiple decomposed dimensions in list: %s\n", varname, vardims); return 1; } - } else if (is_time) { - (*has_time) = 1; + } else if (is_time) { + (*has_time) = 1; } else if (!dim_exists) { fprintf(stderr, "ERROR: Dimension %s on variable %s doesn't exist.\n", token, varname); return 1; @@ -516,7 +516,6 @@ int parse_packages_from_registry(ezxml_t registry)/*{{{*/ return 0; }/*}}}*/ - int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/ { ezxml_t nmlrecs_xml, nmlopt_xml; @@ -1437,6 +1436,7 @@ int parse_var(FILE *fd, ezxml_t registry, ezxml_t superStruct, ezxml_t currentVa ezxml_t struct_xml, var_xml, var_xml2; ezxml_t packages_xml, package_xml; ezxml_t streams_xml, stream_xml, streams_xml2, stream_xml2; + ezxml_t nmlrecs_xml, nmlopt_xml; const char *structtimelevs, *vartimelevs; const char *structname, *structlevs, *structpackages; @@ -1447,6 +1447,10 @@ int parse_var(FILE *fd, ezxml_t registry, ezxml_t superStruct, ezxml_t currentVa const char *streamname, *streamname2; const char *packagename; + const char *nmlrecname; + const char *nmloptname, *nmloptval; + int is_cal; + int err; int iostreams; @@ -1595,6 +1599,39 @@ int parse_var(FILE *fd, ezxml_t registry, ezxml_t superStruct, ezxml_t currentVa fortprintf(fd, " call mpas_add_att(%s(%d) %% attLists(1) %% attList, 'long_name', '%s')\n", pointer_name, time_lev, temp_str); } + // Add calendar and time_bnds attributes for Time + if (strcmp(varname, "Time") == 0) { + is_cal = 0; + + // Read calendar_type from nml_record name="time_management" --> nml_option name="config_calendar_type" + for (nmlrecs_xml = ezxml_child(registry, "nml_record"); nmlrecs_xml; nmlrecs_xml = nmlrecs_xml->next){ + nmlrecname = ezxml_attr(nmlrecs_xml, "name"); + + if (strcmp(nmlrecname, "time_management") == 0) { + for (nmlopt_xml = ezxml_child(nmlrecs_xml, "nml_option"); nmlopt_xml; nmlopt_xml = nmlopt_xml->next){ + nmloptname = ezxml_attr(nmlopt_xml, "name"); + + if (strcmp(nmloptname, "config_calendar_type") == 0) { + is_cal = 1; + nmloptval = ezxml_attr(nmlopt_xml, "default_value"); + + fortprintf(fd, " call mpas_add_att(%s(%d) %% attLists(1) %% attList, 'calendar', '%s')\n", pointer_name, time_lev, nmloptval); + break; + } + } + break; + } + } + + // If not defined in Registry.xml --> hard code as gregorian_noleap + if (is_cal == 0) { + fortprintf(fd, " call mpas_add_att(%s(%d) %% attLists(1) %% attList, 'calendar', '%s')\n", pointer_name, time_lev, "gregorian_noleap"); + } + + // Add time_bnds attribute + fortprintf(fd, " call mpas_add_att(%s(%d) %% attLists(1) %% attList, 'bounds', '%s')\n", pointer_name, time_lev, "time_bnds"); + } + if ( varmissingval != NULL ) { // fortprintf(fd, " call mpas_add_att(%s(%d) %% attLists(1) %% attList, 'missing_value', %s)\n", pointer_name, time_lev, missing_value); // Uncomment to add _FillValue to match missing_value @@ -1603,7 +1640,6 @@ int parse_var(FILE *fd, ezxml_t registry, ezxml_t superStruct, ezxml_t currentVa fortprintf(fd, " %s(%d) %% missingValue = %s\n", pointer_name, time_lev, missing_value); fortprintf(fd, " %s(%d) %% block => block\n", pointer_name, time_lev); - } // Parse packages if they are defined diff --git a/testing_and_setup/compass/ocean/global_ocean/QU240/test/config_test.xml b/testing_and_setup/compass/ocean/global_ocean/QU240/test/config_test.xml index 3b7b2021e4..ff6ebf5542 100644 --- a/testing_and_setup/compass/ocean/global_ocean/QU240/test/config_test.xml +++ b/testing_and_setup/compass/ocean/global_ocean/QU240/test/config_test.xml @@ -21,6 +21,11 @@