diff --git a/.gitignore b/.gitignore index 601619279..bdef88131 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ latex *.pyc build +._* diff --git a/.travis.yml b/.travis.yml index f83328a8c..51742264b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,15 +20,15 @@ env: global: - MAIN_REPO=soca - - LIB_REPOS="gsw mom6 icepack oops vader ioda ufo saber" - - BUILD_OPT="-DBUILD_ICEPACK=ON" + - LIB_REPOS="gsw mom6 icepack oasim oops vader ioda ufo saber" + - BUILD_OPT="-DBUILD_ICEPACK=ON -DBUILD_OASIM=ON" - BUILD_OPT_mom6="-DENABLE_OCEAN_BGC=ON" - BUILD_OPT_oops="-DENABLE_QG_MODEL=OFF -DENABLE_LORENZ95_MODEL=OFF" - BUILD_OPT_ioda="-DBUILD_PYTHON_BINDINGS=OFF -DBUILD_TESTING=OFF" - BUILD_OPT_ufo="-DLOCAL_PATH_TESTFILES_IODA=NONE" - BUILD_OPT_saber="-DENABLE_TESTS=OFF" - BUILD_OPT_soca="-DENABLE_OCEAN_BGC=ON" - - MATCH_REPOS="saber oops ioda ufo mom6 soca" + - MATCH_REPOS="saber oops ioda ufo mom6 soca oasim vader" - LFS_REPOS="" # ENABLE_VALGRIND="ON" @@ -108,13 +108,13 @@ script: - | # Build code docker exec -it jcsda_container bash \ - -c '. /etc/profile.d/z10_spack_environment.sh && cd /jcsda/work && /jcsda/work/repo.src/${MAIN_REPO}/.github/travisci/build.sh; exit $?' \ + -c '. /opt/spack-environment/activate.sh && cd /jcsda/work && /jcsda/work/repo.src/${MAIN_REPO}/.github/travisci/build.sh; exit $?' \ || travis_terminate 1 - | # run tests docker exec -it jcsda_container bash \ - -c '. /etc/profile.d/z10_spack_environment.sh && cd /jcsda/work/repo.build/${MAIN_REPO} && ctest --output-on-failure' \ + -c '. /opt/spack-environment/activate.sh && cd /jcsda/work/repo.build/${MAIN_REPO} && ctest --output-on-failure' \ || travis_terminate 1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 05ffe511b..12408512e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ ################################################################################ cmake_minimum_required( VERSION 3.12 ) -project( soca VERSION 1.5.0 LANGUAGES C CXX Fortran) +project( soca VERSION 1.6.0 LANGUAGES C CXX Fortran) find_package(ecbuild 3.3.2 REQUIRED) include( ecbuild_system NO_POLICY_SCOPE ) @@ -31,6 +31,13 @@ find_package( vader 1.4.0 REQUIRED) find_package( saber 1.7.0 REQUIRED) find_package( ioda 2.6.0 REQUIRED) find_package( ufo 1.7.0 REQUIRED) +# fms +find_package(FMS 2022.04 REQUIRED COMPONENTS R4 R8) +if (FV3_PRECISION MATCHES DOUBLE OR NOT FV3_PRECISION) + add_library(fms ALIAS FMS::fms_r8) +else() + add_library(fms ALIAS FMS::fms_r4) +endif() if(FV3_FORECAST_MODEL MATCHES UFS) find_package( ESMF MODULE REQUIRED STATIC) find_package( crtm 2.2.3) @@ -43,13 +50,11 @@ if(FV3_FORECAST_MODEL MATCHES UFS) find_package( nemsio REQUIRED) find_package( PIO 2.5.3 REQUIRED COMPONENTS C Fortran) else() - find_package( fms 2020.4.0 REQUIRED) find_package( mom6 2020.4.0 REQUIRED) endif() -if ( BUILD_ICEPACK ) - find_package( icepack 1.2.0 REQUIRED) -endif() +# Optionally look for icepack +find_package( icepack 1.2.0 QUIET) include_directories( ${NETCDF_INCLUDE_DIRS} ${DEPEND_LIB_ROOT}/include_r8 ${DEPEND_LIB_ROOT}/MOM6/mod ) include_directories( ${DEPEND_LIB_ROOT}/../ufs-weather-model/src/ufs-weather-model-build/MOM6-interface/mod_solo) diff --git a/bundle/.gitignore b/bundle/.gitignore index d012c05b1..79798c4ad 100644 --- a/bundle/.gitignore +++ b/bundle/.gitignore @@ -1,14 +1,18 @@ atlas/ crtm/ -eckit/ -fckit/ fms/ gsw/ icepack/ +ioda-data/ ioda/ jedicmake/ mom6/ +oasim/ oops/ +saber-data/ saber/ soca +test-data-release/ +ufo-data/ ufo/ +vader/ \ No newline at end of file diff --git a/bundle/CMakeLists.txt b/bundle/CMakeLists.txt index ae78a0725..d712940bc 100644 --- a/bundle/CMakeLists.txt +++ b/bundle/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) COPYRIGHT 2018-2020 UCAR +# (C) COPYRIGHT 2018-2023 UCAR # # THIS SOFTWARE IS LICENSED UNDER THE TERMS OF THE APACHE LICENCE VERSION 2.0 # WHICH CAN BE OBTAINED AT HTTP://WWW.APACHE.ORG/LICENSES/LICENSE-2.0. @@ -14,32 +14,19 @@ include( ecbuild_bundle ) ecbuild_bundle_initialize() -ecbuild_bundle( PROJECT jedicmake GIT "https://github.com/jcsda-internal/jedi-cmake.git" UPDATE BRANCH develop RECURSIVE ) -include( jedicmake/cmake/Functions/git_functions.cmake ) - -# ECMWF repos that you probably dont need to build yourself because they -# should be in jedi-stack and the containers - -option(BUILD_ECKIT "download and build eckit (not needed if in a jedi container)") -if ( BUILD_ECKIT ) - ecbuild_bundle( PROJECT eckit GIT "https://github.com/ecmwf/eckit.git" UPDATE TAG 1.16.0 ) -endif () - -option(BUILD_FCKIT "download and build fckit (not needed if in a jedi container)") -if (BUILD_FCKIT) - ecbuild_bundle( PROJECT fckit GIT "https://github.com/jcsda-internal/fckit.git" UPDATE BRANCH release-stable ) - # TODO: replace with https://github.com/ecmwf/fckit.git TAG 0.9.2 -endif() - -option(BUILD_ATLAS "download and build atlas") -if (BUILD_ATLAS) - ecbuild_bundle( PROJECT atlas GIT "https://github.com/ecmwf/atlas.git" TAG 0.29.0 ) +# Use external jedi-cmake or build in bundle +if(DEFINED ENV{jedi_cmake_ROOT}) + include( $ENV{jedi_cmake_ROOT}/share/jedicmake/Functions/git_functions.cmake ) +else () + ecbuild_bundle( PROJECT jedicmake GIT "https://github.com/jcsda-internal/jedi-cmake.git" UPDATE BRANCH develop RECURSIVE ) + include( jedicmake/cmake/Functions/git_functions.cmake ) endif() +#=================================================================================================== # other optional repositories - -option(BUILD_FMS "download and build fms" ON) +#=================================================================================================== +option(BUILD_FMS "download and build fms" OFF) # NOTE, changed to default=OFF, but this will be removed in the future if ( BUILD_FMS ) ecbuild_bundle( PROJECT fms GIT "https://github.com/jcsda/FMS.git" UPDATE BRANCH release-stable ) endif () @@ -49,17 +36,50 @@ if ( BUILD_ICEPACK ) ecbuild_bundle( PROJECT icepack GIT "https://github.com/JCSDA-internal/Icepack.git" UPDATE BRANCH feature/ecbuild-new ) endif() -option(BUILD_UFSM6C6 "download and install the UFS" OFF) +option(BUILD_OASIM "download and build OASIM ocean color forward operator" OFF) +if ( BUILD_OASIM ) + ecbuild_bundle( PROJECT oasim GIT "https://github.com/JCSDA-internal/oasim.git" UPDATE BRANCH develop ) +endif () +#=================================================================================================== # required repositories - +#=================================================================================================== +ecbuild_bundle( PROJECT gsw GIT "https://github.com/jcsda-internal/GSW-Fortran.git" UPDATE BRANCH develop ) ecbuild_bundle( PROJECT oops GIT "https://github.com/jcsda-internal/oops.git" UPDATE BRANCH develop ) ecbuild_bundle( PROJECT vader GIT "https://github.com/jcsda-internal/vader.git" UPDATE BRANCH develop ) ecbuild_bundle( PROJECT saber GIT "https://github.com/jcsda-internal/saber.git" UPDATE BRANCH develop ) ecbuild_bundle( PROJECT ioda GIT "https://github.com/jcsda-internal/ioda.git" UPDATE BRANCH develop ) -ecbuild_bundle( PROJECT gsw GIT "https://github.com/jcsda-internal/GSW-Fortran.git" UPDATE BRANCH develop ) ecbuild_bundle( PROJECT ufo GIT "https://github.com/jcsda-internal/ufo.git" UPDATE BRANCH develop ) ecbuild_bundle( PROJECT mom6 GIT "https://github.com/jcsda-internal/MOM6.git" UPDATE BRANCH main-ecbuild RECURSIVE ) ecbuild_bundle( PROJECT soca SOURCE "../" ) +#=================================================================================================== +# optional test data for the upstream repos +#=================================================================================================== +option(TEST_IODA "download and ioda-data repo needed for ioda ctests" OFF) +if ( TEST_IODA ) + find_branch_name(REPO_DIR_NAME ioda) + if( NOT DEFINED ENV{LOCAL_PATH_JEDI_TESTFILES} AND NOT DEFINED ${GIT_TAG_FUNC} ) + ecbuild_bundle( PROJECT ioda-data GIT "https://github.com/JCSDA-internal/ioda-data.git" BRANCH develop UPDATE ) + endif() +endif () + +option(TEST_UFO "download and ufo-data repo needed for ufo ctests" OFF) +if ( TEST_UFO ) + find_branch_name(REPO_DIR_NAME ufo) + if( NOT DEFINED ENV{LOCAL_PATH_JEDI_TESTFILES} AND NOT DEFINED ${GIT_TAG_FUNC} ) + ecbuild_bundle( PROJECT ufo-data GIT "https://github.com/JCSDA-internal/ufo-data.git" BRANCH develop UPDATE ) + endif() +endif () + +option(TEST_SABER "download and saber-data repo needed for ioda ctests" OFF) +if ( TEST_SABER ) + find_branch_name(REPO_DIR_NAME saber) + if( NOT DEFINED ENV{LOCAL_PATH_JEDI_TESTFILES} AND NOT DEFINED ${GIT_TAG_FUNC} ) + ecbuild_bundle( PROJECT saber-data GIT "https://github.com/JCSDA-internal/saber-data.git" BRANCH develop UPDATE ) + endif() +endif () + +#=================================================================================================== + ecbuild_bundle_finalize() diff --git a/cmake/soca_compiler_flags.cmake b/cmake/soca_compiler_flags.cmake index cd8ca6a82..0131df335 100644 --- a/cmake/soca_compiler_flags.cmake +++ b/cmake/soca_compiler_flags.cmake @@ -5,6 +5,16 @@ add_definitions ( -Duse_libMPI -Duse_netCDF -DSPMD ) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS OFF) +set(CMAKE_FORTRAN_STANDARD 08) +set(CMAKE_FORTRAN_STANDARD_REQUIRED ON) +set(CMAKE_FORTRAN_EXTENSIONS OFF) + if( NOT CMAKE_BUILD_TYPE MATCHES "Debug" ) add_definitions( -DNDEBUG ) endif( ) diff --git a/src/mains/CMakeLists.txt b/src/mains/CMakeLists.txt index b67c1693a..b4ec4121d 100644 --- a/src/mains/CMakeLists.txt +++ b/src/mains/CMakeLists.txt @@ -1,13 +1,3 @@ -#ecbuild_add_executable( TARGET soca_dirac.x -# SOURCES Dirac.cc -# LIBS ${UFS_LIBS} -# ) - -ecbuild_add_executable( TARGET test_soca_model.x - SOURCES TestModel.cc - LIBS ${UFS_LIBS} - ) - ecbuild_add_executable( TARGET soca_forecast.x SOURCES Forecast.cc LIBS ${UFS_LIBS} @@ -55,11 +45,6 @@ ecbuild_add_executable( TARGET soca_ensmeanandvariance.x LIBS ${UFS_LIBS} ) -ecbuild_add_executable( TARGET soca_ensvariance.x - SOURCES EnsVariance.cc - LIBS ${UFS_LIBS} - ) - ecbuild_add_executable( TARGET soca_ensrecenter.x SOURCES EnsRecenter.cc LIBS ${UFS_LIBS} diff --git a/src/mains/EnsVariance.cc b/src/mains/EnsVariance.cc deleted file mode 100644 index 9405891c9..000000000 --- a/src/mains/EnsVariance.cc +++ /dev/null @@ -1,17 +0,0 @@ -/* - * (C) Copyright 2017-2021 UCAR. - * - * This software is licensed under the terms of the Apache Licence Version 2.0 - * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. - */ - - -#include "oops/runs/EnsVariance.h" -#include "oops/runs/Run.h" -#include "soca/Traits.h" - -int main(int argc, char ** argv) { - oops::Run run(argc, argv); - oops::EnsVariance ensvariance; - return run.execute(ensvariance); -} diff --git a/src/soca/CMakeLists.txt b/src/soca/CMakeLists.txt index 4d1c77952..ed37d9b0c 100644 --- a/src/soca/CMakeLists.txt +++ b/src/soca/CMakeLists.txt @@ -29,8 +29,6 @@ target_include_directories(soca PUBLIC $ $) -target_compile_features( soca PUBLIC cxx_std_11 ) - target_link_libraries( soca PUBLIC NetCDF::NetCDF_Fortran ) target_link_libraries( soca PUBLIC fckit ) target_link_libraries( soca PUBLIC atlas ) @@ -39,20 +37,21 @@ target_link_libraries( soca PUBLIC FMS::fms_r8 ) target_link_libraries( soca PUBLIC gsw ) target_link_libraries( soca PUBLIC mom6 ) target_link_libraries( soca PUBLIC oops ) -target_link_libraries( soca PUBLIC vader ) target_link_libraries( soca PUBLIC saber ) target_link_libraries( soca PUBLIC ioda ) target_link_libraries( soca PUBLIC ufo ) +target_link_libraries( soca PUBLIC vader ) include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${DEPEND_LIB_ROOT}/mod ) -if ( BUILD_ICEPACK ) +if( ${icepack_FOUND} ) target_link_libraries( soca PUBLIC icepack ) endif() # Add source code in the subdirectories add_subdirectory(AnalyticInit) add_subdirectory(Covariance) +add_subdirectory(ExplicitDiffusion) add_subdirectory(Fields) add_subdirectory(Geometry) add_subdirectory(GeometryIterator) diff --git a/src/soca/Covariance/soca_covariance_mod.F90 b/src/soca/Covariance/soca_covariance_mod.F90 index 76cbd0d9a..3ed0c615c 100644 --- a/src/soca/Covariance/soca_covariance_mod.F90 +++ b/src/soca/Covariance/soca_covariance_mod.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 2017-2021 UCAR. +! (C) Copyright 2017-2023 UCAR. ! ! This software is licensed under the terms of the Apache Licence Version 2.0 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. @@ -9,7 +9,7 @@ module soca_covariance_mod use atlas_module, only: atlas_fieldset, atlas_field, atlas_real, atlas_integer, atlas_functionspace use fckit_configuration_module, only: fckit_configuration -use fckit_log_module, only: fckit_log +use logger_mod use kinds, only: kind_real use oops_variables_mod, only: oops_variables use random_mod, only: normal_distribution @@ -34,6 +34,7 @@ module soca_covariance_mod real(kind=kind_real), allocatable :: pert_scale(:) !< index matches "vars" type(oops_variables), allocatable :: conv_vars(:) !< index mathces "conv" + type(soca_geom), pointer :: geom contains !> \copybrief soca_cov_setup \see soca_cov_setup procedure :: setup => soca_cov_setup @@ -67,7 +68,7 @@ module soca_covariance_mod subroutine soca_cov_setup(self, f_conf, geom, bkg, vars) class(soca_cov), intent(inout) :: self !< The covariance structure type(fckit_configuration), intent(in) :: f_conf !< The configuration - type(soca_geom), intent(in) :: geom !< Geometry + type(soca_geom), pointer, intent(in) :: geom !< Geometry type(soca_state), target, intent(in) :: bkg !< Background type(oops_variables), intent(in) :: vars !< List of variables @@ -77,6 +78,9 @@ subroutine soca_cov_setup(self, f_conf, geom, bkg, vars) character(len=:), allocatable :: domain integer :: i, isc, iec, jsc, jec, ivar + ! save a copy of geometry for use later + self%geom => geom + ! Setup list of variables to apply B on self%vars = vars @@ -86,7 +90,7 @@ subroutine soca_cov_setup(self, f_conf, geom, bkg, vars) if (f_conf%get("perturbation scales", f_conf2)) then do ivar=1,self%vars%nvars() if ( .not. f_conf2%get(self%vars%variable(ivar), self%pert_scale(ivar))) then - if (geom%f_comm%rank() == 0) call fckit_log%warning( & + call oops_log%info( & "WARNING: no pertubation scale given for '" //trim(self%vars%variable(ivar)) & // "' using default of 1.0") end if @@ -151,7 +155,7 @@ subroutine soca_cov_get_conv(self, field, conv) ! TODO we really should have separate variable names for staggered/destaggered variables. ! The "abort" has been turned into a "warning" until we get u/v names straightened out. if (field%metadata%grid /= "h") then - call fckit_log%warning("WARNING: Attempting to use a field (" // & + call oops_log%info("WARNING: Attempting to use a field (" // & trim(field%name) // ") which is on the u/v grid. PROCEED WITH CAUTION") end if @@ -181,6 +185,9 @@ subroutine soca_cov_C_mult(self, dx) integer :: i, z type(soca_field), pointer :: field type(bump_type), pointer :: conv + real(kind=kind_real), allocatable :: fld_2d(:,:) + + allocate(fld_2d(self%geom%isd:self%geom%ied, self%geom%jsd:self%geom%jed)) do i = 1, self%vars%nvars() ! why is this sometimes getting an "empty" list with "none" in it? @@ -196,7 +203,9 @@ subroutine soca_cov_C_mult(self, dx) ! apply convolution on each level do z = 1, field%nz - call soca_2d_convol(field%val(:,:,z), conv, dx%geom) + fld_2d = field%val(:,:,z) + call soca_2d_convol(fld_2d, conv, dx%geom) + field%val(:,:,z) = fld_2d end do end do end subroutine soca_cov_C_mult @@ -214,6 +223,9 @@ subroutine soca_cov_sqrt_C_mult(self, dx) type(soca_field), pointer :: field real(kind=kind_real) :: scale type(bump_type), pointer :: conv + real(kind=kind_real), allocatable :: fld_2d(:,:) + + allocate(fld_2d(self%geom%isd:self%geom%ied, self%geom%jsd:self%geom%jed)) do i = 1, self%vars%nvars() conv => null() @@ -236,7 +248,9 @@ subroutine soca_cov_sqrt_C_mult(self, dx) ! apply convolution do z = 1,field%nz - call soca_2d_sqrt_convol(field%val(:,:,z), conv, dx%geom, scale) + fld_2d = field%val(:,:,z) + call soca_2d_sqrt_convol(fld_2d, conv, dx%geom, scale) + field%val(:,:,z) = fld_2d end do end do @@ -264,49 +278,25 @@ subroutine soca_bump_correlation(self, horiz_convol, geom, f_conf_bump, f_conf_d integer :: i integer, allocatable :: hmask(:,:) integer, pointer :: int_ptr(:,:) - real(kind=kind_real), pointer :: real_ptr(:,:) - real(kind=kind_real), allocatable :: area(:) + real(kind=kind_real), pointer :: real_ptr(:,:), vArea(:,:), vRossby(:,:) type(atlas_functionspace) :: afunctionspace type(fieldset_type) :: afieldset, rh, rv - type(atlas_field) :: afield + + type(atlas_field) :: afield, fArea, fRossby real(kind=kind_real) :: r_base, r_mult, r_min, r_max, r_min_grid - ! Wrap functionspace - afunctionspace = atlas_functionspace(geom%functionspaceInchalo%c_ptr()) + ! wrap the functionspace + afunctionspace = atlas_functionspace(geom%functionspace%c_ptr()) ! Geometry fieldset setup afieldset = atlas_fieldset() - ! Add area - afield = geom%functionspaceInchalo%create_field(name='area', kind=atlas_real(kind_real), levels=1) - call afield%data(real_ptr) - area = pack(geom%cell_area,geom%valid_halo_mask) - real_ptr(1,:) = area - call afieldset%add(afield) - call afield%final() - - ! Add vertical unit - afield = geom%functionspaceInchalo%create_field(name='vunit', kind=atlas_real(kind_real), levels=1) - call afield%data(real_ptr) - real_ptr(1,:) = 1.0 - call afieldset%add(afield) - call afield%final() - - ! Add geographical mask - afield = geom%functionspaceInchalo%create_field(name='gmask', kind=atlas_integer(kind(0)), levels=1) - call afield%data(int_ptr) - int_ptr(1,:) = int(pack(geom%mask2d,geom%valid_halo_mask)) - call afieldset%add(afield) - call afield%final() - - afield = geom%functionspaceInchalo%create_field(name='hmask', kind=atlas_integer(kind(0)), levels=1) - allocate(hmask(geom%isd:geom%ied, geom%jsd:geom%jed)) - hmask = 0 - hmask(geom%isc:geom%iec, geom%jsc:geom%jec) = 1 - call afield%data(int_ptr) - int_ptr(1,:) = pack(hmask, geom%valid_halo_mask) - call afieldset%add(afield) - call afield%final() + ! add existing fields that were created by geometry + call afieldset%add(geom%fieldset%field('area')) + call afieldset%add(geom%fieldset%field('vert_coord')) + call afieldset%add(geom%fieldset%field('gmask')) + call afieldset%add(geom%fieldset%field('owned')) + ! Set verbosity horiz_convol%mpl%verbose = (geom%f_comm%rank()==0) @@ -315,6 +305,12 @@ subroutine soca_bump_correlation(self, horiz_convol, geom, f_conf_bump, f_conf_d call horiz_convol%create(geom%f_comm,afunctionspace,afieldset,f_conf_bump) if (horiz_convol%nam%new_nicas) then + ! get some fields from the geom fieldset + fArea = geom%fieldset%field('area') + call fArea%data(vArea) + fRossby = geom%fieldset%field('rossby_radius') + call fRossby%data(vRossby) + ! get parameters for correlation lengths if (.not. f_conf_domain%get('base value', r_base)) r_base = 0.0 if (.not. f_conf_domain%get('rossby mult', r_mult)) r_mult = 0.0 @@ -328,13 +324,13 @@ subroutine soca_bump_correlation(self, horiz_convol, geom, f_conf_bump, f_conf_d ! 3) min/max are imposed based on "min value" and "max value" ! 4) converted from a gaussian sigma to Gaspari-Cohn cutoff distance rh = atlas_fieldset() - afield = geom%functionspaceInchalo%create_field('var',kind=atlas_real(kind_real),levels=1) + afield = geom%functionspace%create_field('var',kind=atlas_real(kind_real),levels=1) call rh%add(afield) call afield%data(real_ptr) - real_ptr(1,:) = r_base + r_mult*pack(geom%rossby_radius, geom%valid_halo_mask) + real_ptr(1,:) = r_base + r_mult*vRossby(1,:) ! min based on grid size if (r_min_grid .gt. 0.0) then - real_ptr(1,:) = max(real_ptr(1,:), sqrt(area)*r_min_grid ) + real_ptr(1,:) = max(real_ptr(1,:), sqrt(vArea(1,:))*r_min_grid ) end if real_ptr(1,:) = min(r_max, real_ptr(1,:)) real_ptr(1,:) = max(r_min, real_ptr(1,:)) @@ -344,7 +340,7 @@ subroutine soca_bump_correlation(self, horiz_convol, geom, f_conf_bump, f_conf_d ! rv rv = atlas_fieldset() - afield = geom%functionspaceInchalo%create_field('var',kind=atlas_real(kind_real),levels=1) + afield = geom%functionspace%create_field('var',kind=atlas_real(kind_real),levels=1) call rv%add(afield) call afield%data(real_ptr) real_ptr = 1.0 @@ -357,6 +353,8 @@ subroutine soca_bump_correlation(self, horiz_convol, geom, f_conf_bump, f_conf_d ! Clean up call rh%final() call rv%final() + call fRossby%final() + call fArea%final() end if ! Run BUMP drivers @@ -371,24 +369,41 @@ end subroutine soca_bump_correlation !! Used by soca_cov::mult() !! \relates soca_covariance_mod::soca_cov subroutine soca_2d_convol(dx, horiz_convol, geom) - real(kind=kind_real), intent(inout) :: dx(:,:) + real(kind=kind_real), allocatable, intent(inout) :: dx(:,:) type(bump_type), intent(inout) :: horiz_convol type(soca_geom), intent(in) :: geom - type(fieldset_type) :: tmp_incr - - ! Allocate ATLAS tmp_increment and make copy of dx - call geom%struct2atlas(dx(:,:), tmp_incr) + type(fieldset_type) :: fieldset + type(atlas_field) :: field + real(kind_real), pointer :: real_ptr(:,:) + integer :: i, j, n + + ! array to atlas + ! (Yeah, this code is duplicated in a few places, but this whole + ! class is going away "soon" so I don't care) + fieldset = atlas_fieldset() + field = geom%functionspace%create_field('var', kind=atlas_real(kind_real), levels=1) + call fieldset%add(field) + call field%data(real_ptr) + do j=geom%jsc,geom%jec + do i=geom%isc,geom%iec + real_ptr(1,geom%atlas_ij2idx(i,j)) = dx(i,j) + end do + end do ! Apply 2D convolution - call horiz_convol%apply_nicas(tmp_incr) - - ! Copy ATLAS tmp_incr to structured dx - call geom%atlas2struct(dx(:,:), tmp_incr) + call horiz_convol%apply_nicas(fieldset) + ! atlas to array + do j=geom%jsc,geom%jec + do i=geom%isc,geom%iec + dx(i,j) = real_ptr(1,geom%atlas_ij2idx(i,j)) + end do + end do + ! Clean up - call tmp_incr%final() - + call field%final() + call fieldset%final() end subroutine soca_2d_convol @@ -398,36 +413,55 @@ end subroutine soca_2d_convol !! used by soca_cov::sqrt_C_mult() !! \relates soca_covariance_mod::soca_cov subroutine soca_2d_sqrt_convol(dx, horiz_convol, geom, pert_scale) - real(kind=kind_real), intent(inout) :: dx(:,:) + real(kind=kind_real), allocatable, intent(inout) :: dx(:,:) type(bump_type), intent(inout) :: horiz_convol type(soca_geom), intent(in) :: geom real(kind=kind_real), intent(in) :: pert_scale - type(fieldset_type) :: tmp_incr - real(kind=kind_real), allocatable :: pcv(:) + type(fieldset_type) :: fieldset + type(atlas_field) :: field + real(kind_real), pointer :: real_ptr(:,:) + integer :: i, j, n + + type(atlas_field) :: acv integer, parameter :: rseed = 1 ! constant for reproducability of tests ! TODO: pass seed through config integer :: nn - - ! Allocate ATLAS tmp_increment and make copy of dx - call geom%struct2atlas(dx(:,:), tmp_incr) + real(kind=kind_real), pointer :: ptr(:) + + ! array to atlas fieldset + fieldset = atlas_fieldset() + field = geom%functionspace%create_field('var', kind=atlas_real(kind_real), levels=1) + call fieldset%add(field) + call field%data(real_ptr) + do j=geom%jsc,geom%jec + do i=geom%isc,geom%iec + real_ptr(1,geom%atlas_ij2idx(i,j)) = dx(i,j) + end do + end do ! Get control variable size call horiz_convol%get_cv_size(nn) - allocate(pcv(nn)) - pcv = 0.0_kind_real - call normal_distribution(pcv, 0.0_kind_real, 1.0_kind_real, rseed) - pcv = pert_scale * pcv + acv = atlas_field("ctlVec", atlas_real(kind_real), (/nn/)) + call acv%data(ptr) + ptr = 0.0_kind_real + call normal_distribution(ptr, 0.0_kind_real, 1.0_kind_real, rseed) + ptr = pert_scale * ptr ! Apply C^1/2 - call horiz_convol%apply_nicas_sqrt(pcv, tmp_incr) + call horiz_convol%apply_nicas_sqrt(acv, fieldset, 0) - ! Back to structured grid - call geom%atlas2struct(dx(:,:), tmp_incr) + ! atlas to array + do j=geom%jsc,geom%jec + do i=geom%isc,geom%iec + dx(i,j) = real_ptr(1,geom%atlas_ij2idx(i,j)) + end do + end do ! Clean up - deallocate(pcv) - call tmp_incr%final() + call acv%final() + call field%final() + call fieldset%final() end subroutine soca_2d_sqrt_convol diff --git a/src/soca/ExplicitDiffusion/CMakeLists.txt b/src/soca/ExplicitDiffusion/CMakeLists.txt new file mode 100644 index 000000000..ce3016a3a --- /dev/null +++ b/src/soca/ExplicitDiffusion/CMakeLists.txt @@ -0,0 +1,8 @@ +soca_target_sources( + ExplicitDiffusion.cc + ExplicitDiffusion.F90 + ExplicitDiffusion.h + ExplicitDiffusionFortran.h + ExplicitDiffusionParameters.h + soca_diffusion.F90 +) diff --git a/src/soca/ExplicitDiffusion/ExplicitDiffusion.F90 b/src/soca/ExplicitDiffusion/ExplicitDiffusion.F90 new file mode 100644 index 000000000..2490ff5e6 --- /dev/null +++ b/src/soca/ExplicitDiffusion/ExplicitDiffusion.F90 @@ -0,0 +1,115 @@ +! (C) Copyright 2023-2023 UCAR +! +! This software is licensed under the terms of the Apache Licence Version 2.0 +! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + +module soca_explicitdiffusion_c + +use iso_c_binding + +use atlas_module, only : atlas_fieldset +use fckit_configuration_module, only: fckit_configuration + +use soca_geom_mod +use soca_geom_mod_c +use soca_increment_mod +use soca_increment_reg, only : soca_increment_registry +use soca_diffusion_mod, only : soca_diffusion + +implicit none +private + +#define LISTED_TYPE soca_diffusion +#include "oops/util/linkedList_i.f" +type(registry_t), public :: soca_diffusion_registry + +! ------------------------------------------------------------------------------ +contains +! ------------------------------------------------------------------------------ + +#include "oops/util/linkedList_c.f" + +! ------------------------------------------------------------------------------ + +subroutine soca_explicitdiffusion_setup_c(c_key_self, c_geom, c_conf) bind(c, name='soca_explicitdiffusion_setup_f90') + integer(c_int), intent(inout) :: c_key_self + integer(c_int), intent(in) :: c_geom + type(c_ptr), intent(in) :: c_conf + + type(soca_diffusion), pointer :: self + type(soca_geom), pointer :: geom + + call soca_diffusion_registry%init() + call soca_diffusion_registry%add(c_key_self) + call soca_diffusion_registry%get(c_key_self, self) + + call soca_geom_registry%get(c_geom, geom) + + call self%init(geom, fckit_configuration(c_conf)) +end subroutine + +! ------------------------------------------------------------------------------ + +subroutine soca_explicitdiffusion_calibrate_c(c_key_self, c_conf) bind(c, name='soca_explicitdiffusion_calibrate_f90') + integer(c_int), intent(inout) :: c_key_self + type(c_ptr), intent(in) :: c_conf + + type(soca_diffusion), pointer :: self + + call soca_diffusion_registry%get(c_key_self, self) + + call self%calibrate(fckit_configuration(c_conf)) +end subroutine + +! ------------------------------------------------------------------------------ + +subroutine soca_explicitdiffusion_multiply_c(c_key_self, c_key_dx) bind(c, name='soca_explicitdiffusion_multiply_f90') + integer(c_int), intent(inout) :: c_key_self + integer(c_int), intent(in) :: c_key_dx + + type(soca_diffusion), pointer :: self + type(soca_increment), pointer :: dx + + call soca_diffusion_registry%get(c_key_self, self) + call soca_increment_registry%get(c_key_dx, dx) + + call self%multiply(dx) +end subroutine + +! ------------------------------------------------------------------------------ + +subroutine soca_explicitdiffusion_writeparams_c(c_key_self, c_conf) & + bind (c, name='soca_explicitdiffusion_writeparams_f90') + integer(c_int), intent(inout) :: c_key_self + type(c_ptr), intent(in) :: c_conf + + character(len=:), allocatable :: filename + type(soca_diffusion), pointer :: self + type(fckit_configuration) :: f_conf + + f_conf = fckit_configuration(c_conf) + call f_conf%get_or_die("filename", filename) + call soca_diffusion_registry%get(c_key_self, self) + call self%write_params(filename) +end subroutine + +! ------------------------------------------------------------------------------ + +subroutine soca_explicitdiffusion_readparams_c(c_key_self, c_conf) & + bind (c, name='soca_explicitdiffusion_readparams_f90') + integer(c_int), intent(inout) :: c_key_self + type(c_ptr), intent(in) :: c_conf + + character(len=:), allocatable :: filename + type(soca_diffusion), pointer :: self + type(fckit_configuration) :: f_conf + + f_conf = fckit_configuration(c_conf) + call f_conf%get_or_die("filename", filename) + call soca_diffusion_registry%get(c_key_self, self) + call self%read_params(filename) +end subroutine + +! ------------------------------------------------------------------------------ + +end module \ No newline at end of file diff --git a/src/soca/ExplicitDiffusion/ExplicitDiffusion.cc b/src/soca/ExplicitDiffusion/ExplicitDiffusion.cc new file mode 100644 index 000000000..16e790221 --- /dev/null +++ b/src/soca/ExplicitDiffusion/ExplicitDiffusion.cc @@ -0,0 +1,87 @@ +/* + * (C) Copyright 2023-2023 UCAR + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + */ + +#include "soca/ExplicitDiffusion/ExplicitDiffusion.h" +#include "soca/ExplicitDiffusion/ExplicitDiffusionFortran.h" +#include "soca/Geometry/Geometry.h" +#include "soca/Increment/Increment.h" + +namespace soca { + +// -------------------------------------------------------------------------------------- + +static saber::SaberCentralBlockMaker + makerExplicitDiffusion_("EXPLICIT_DIFFUSION"); + +// -------------------------------------------------------------------------------------- + +ExplicitDiffusion::ExplicitDiffusion( + const oops::GeometryData & geometryData, + const oops::Variables & centralVars, + const eckit::Configuration & covarConf, + const Parameters_ & params, + const oops::FieldSet3D & xb, + const oops::FieldSet3D & fg) + : saber::SaberCentralBlockBase(params, xb.validTime()), params_(params) +{ + // setup geometry + geom_.reset(new Geometry(params_.geometry.value(), geometryData.comm())); + + // setup the fortran code + eckit::LocalConfiguration conf = params_.toConfiguration(); + soca_explicitdiffusion_setup_f90(keyFortran_, geom_->toFortran(), &conf); + + vars_ = params.activeVars.value().get_value_or(centralVars); +} + +// -------------------------------------------------------------------------------------- + +void ExplicitDiffusion::randomize(oops::FieldSet3D &) const { + throw eckit::NotImplemented("read not implemented yet for ExplictDiffusion"); +} + +// -------------------------------------------------------------------------------------- + +void ExplicitDiffusion::multiply(oops::FieldSet3D & fset) const { + Increment dx(*geom_, vars_, util::DateTime()); + dx.fromFieldSet(fset.fieldSet()); + + soca_explicitdiffusion_multiply_f90(keyFortran_, dx.toFortran()); + + dx.toFieldSet(fset.fieldSet()); +} + +// -------------------------------------------------------------------------------------- + +void ExplicitDiffusion::directCalibration(const oops::FieldSets &) { + eckit::LocalConfiguration conf = (*params_.calibration.value()).toConfiguration(); + soca_explicitdiffusion_calibrate_f90(keyFortran_, &conf); +} + +// -------------------------------------------------------------------------------------- + +void ExplicitDiffusion::read() { + eckit::LocalConfiguration conf = (*params_.read.value()).toConfiguration(); + soca_explicitdiffusion_readparams_f90(keyFortran_, &conf); +} + +// -------------------------------------------------------------------------------------- + +void ExplicitDiffusion::write() const { + eckit::LocalConfiguration conf = + (*(*params_.calibration.value()).write.value()).toConfiguration(); + soca_explicitdiffusion_writeparams_f90(keyFortran_, &conf); +} + +// -------------------------------------------------------------------------------------- + +void ExplicitDiffusion::print(std::ostream &) const { +} + +// -------------------------------------------------------------------------------------- + +} // namespace soca diff --git a/src/soca/ExplicitDiffusion/ExplicitDiffusion.h b/src/soca/ExplicitDiffusion/ExplicitDiffusion.h new file mode 100644 index 000000000..6aad31d88 --- /dev/null +++ b/src/soca/ExplicitDiffusion/ExplicitDiffusion.h @@ -0,0 +1,59 @@ +/* + * (C) Copyright 2023-2023 UCAR + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + */ + +#pragma once + +#include +#include +#include + +#include "soca/ExplicitDiffusion/ExplicitDiffusionParameters.h" +#include "saber/blocks/SaberCentralBlockBase.h" + + +// -------------------------------------------------------------------------------------- +// Forward declarations +namespace soca { + class Geometry; +} + +// -------------------------------------------------------------------------------------- + +namespace soca { + +// -------------------------------------------------------------------------------------- + +class ExplicitDiffusion : public saber::SaberCentralBlockBase { + public: + static const std::string classname() { return "soca::ExplicitDiffusion"; } + typedef ExplicitDiffusionParameters Parameters_; + + ExplicitDiffusion(const oops::GeometryData &, + const oops::Variables &, + const eckit::Configuration &, + const Parameters_ &, + const oops::FieldSet3D &, + const oops::FieldSet3D &); + + void randomize(oops::FieldSet3D &) const override; + void multiply(oops::FieldSet3D &) const override; + + void directCalibration(const oops::FieldSets &) override; + void read() override; + void write() const override; + + private: + void print(std::ostream &) const override; + std::shared_ptr geom_; + int keyFortran_; + oops::Variables vars_; + Parameters_ params_; +}; + +// -------------------------------------------------------------------------------------- + +} // namespace soca diff --git a/src/soca/ExplicitDiffusion/ExplicitDiffusionFortran.h b/src/soca/ExplicitDiffusion/ExplicitDiffusionFortran.h new file mode 100644 index 000000000..890819866 --- /dev/null +++ b/src/soca/ExplicitDiffusion/ExplicitDiffusionFortran.h @@ -0,0 +1,33 @@ +/* + * (C) Copyright 2023-2023 UCAR + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + */ + +#pragma once + +#include "soca/Fortran.h" + +namespace eckit { + class Configuration; +} + +namespace soca { + +typedef int F90explicitdiffusion; + +extern "C" { + void soca_explicitdiffusion_setup_f90(F90explicitdiffusion &, const F90geom &, + const eckit::Configuration * const &); + void soca_explicitdiffusion_calibrate_f90(const F90explicitdiffusion &, + const eckit::Configuration * const &); + void soca_explicitdiffusion_multiply_f90(const F90explicitdiffusion &, + const F90flds &); + void soca_explicitdiffusion_writeparams_f90(const F90explicitdiffusion &, + const eckit::Configuration * const &); + void soca_explicitdiffusion_readparams_f90(const F90explicitdiffusion &, + const eckit::Configuration * const &); +} + +} // namespace soca diff --git a/src/soca/ExplicitDiffusion/ExplicitDiffusionParameters.h b/src/soca/ExplicitDiffusion/ExplicitDiffusionParameters.h new file mode 100644 index 000000000..2b7d7d49b --- /dev/null +++ b/src/soca/ExplicitDiffusion/ExplicitDiffusionParameters.h @@ -0,0 +1,62 @@ +/* + * (C) Copyright 2023-2023 UCAR + * + * This software is licensed under the terms of the Apache Licence Version 2.0 + * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + */ + +#pragma once + +#include +#include + +#include "saber/blocks/SaberBlockParametersBase.h" + +namespace soca { + +// -------------------------------------------------------------------------------------- + +class ExplicitDiffusionIOParameters : public oops::Parameters { + OOPS_CONCRETE_PARAMETERS(ExplicitDiffusionIOParameters, oops::Parameters) + public: + oops::RequiredParameter filename{"filename", this}; + oops::OptionalParameter varName{"variable name", this}; +}; + +// -------------------------------------------------------------------------------------- + +class ExplicitDiffusionScalesParameters : public oops::Parameters { + OOPS_CONCRETE_PARAMETERS(ExplicitDiffusionScalesParameters, oops::Parameters) + public: + oops::RequiredParameter name{"name", this}; + oops::OptionalParameter fixedValue{"fixed value", this}; + oops::OptionalParameter fromFile{"from file", this}; + oops::Parameter asGaussian{"as gaussian", false, this}; +}; + +// -------------------------------------------------------------------------------------- + +class ExplicitDiffusionCalibrationParameters : public oops::Parameters { + OOPS_CONCRETE_PARAMETERS(ExplicitDiffusionCalibrationParameters, oops::Parameters) + public: + oops::RequiredParameter normalization{"normalization", this}; + oops::RequiredParameter > scales{"scales", this}; + oops::OptionalParameter write {"write", this}; +}; + +// -------------------------------------------------------------------------------------- + +class ExplicitDiffusionParameters : public saber::SaberBlockParametersBase { + OOPS_CONCRETE_PARAMETERS(ExplicitDiffusionParameters, saber::SaberBlockParametersBase) + public: + oops::OptionalParameter read{"read", this}; + oops::OptionalParameter + calibration{"calibration", this}; + oops::RequiredParameter geometry{"geometry", this}; + oops::OptionalParameter groups{"groups", this}; + + oops::Variables mandatoryActiveVars() const override {return oops::Variables();} +}; + +// -------------------------------------------------------------------------------------- +} // namespace soca diff --git a/src/soca/ExplicitDiffusion/soca_diffusion.F90 b/src/soca/ExplicitDiffusion/soca_diffusion.F90 new file mode 100644 index 000000000..06d6b66f5 --- /dev/null +++ b/src/soca/ExplicitDiffusion/soca_diffusion.F90 @@ -0,0 +1,768 @@ +! (C) Copyright 2023-2023 UCAR +! +! This software is licensed under the terms of the Apache Licence Version 2.0 +! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. + +module soca_diffusion_mod + +use fckit_configuration_module, only: fckit_configuration +use fckit_mpi_module, only: fckit_mpi_min, fckit_mpi_max, fckit_mpi_sum +use kinds, only: kind_real +use logger_mod +use mpp_domains_mod, only : mpp_update_domains, mpp_update_domains_ad +use random_mod +use fms_io_mod +use oops_variables_mod + +use soca_increment_mod +use soca_geom_mod, only : soca_geom + +implicit none +private + +! ------------------------------------------------------------------------------ +! convenience macros, because I'm TIRED of the unreadability of endless isc, jsc ..... +#define DOMAIN self%geom%isc:self%geom%iec,self%geom%jsc:self%geom%jec +#define DOMAIN_WITH_HALO self%geom%isd:self%geom%ied,self%geom%jsd:self%geom%jed +#define LOOP_DOMAIN_I self%geom%isc, self%geom%iec +#define LOOP_DOMAIN_J self%geom%jsc, self%geom%jec +#define LOOP_DOMAIN_WITH_HALO_I self%geom%isd, self%geom%ied +#define LOOP_DOMAIN_WITH_HALO_J self%geom%jsd, self%geom%jed + +! ------------------------------------------------------------------------------ +! The diffusion parameters needed by a group of variables. +! More than one model variable can be part of a group, they will all share the +! same correlation lengths. +type :: soca_diffusion_group_params + character(len=:),allocatable :: name + real(kind_real), allocatable :: KhDt(:,:) !< horizontal diffusion coefficient + real(kind_real), allocatable :: normalization(:,:) !< horizontal normalization constant + integer :: n_iter = -1 !< number of iterations for diffusion, + ! (set to -1 to indicate has not been initialized) +end type soca_diffusion_group_params + +! ------------------------------------------------------------------------------ +! do the mapping between a group name and one or more variables names +type :: soca_diffusion_group_mapping +character(len=:), allocatable :: group_name +type(oops_variables) :: variables +end type + +! ------------------------------------------------------------------------------ +! The main EXPLICIT_DIFFUSION class. +type, public :: soca_diffusion + private + ! grid metrics + real(kind_real), allocatable :: inv_sqrt_area(:,:) !< 1/sqrt(area) + real(kind_real), allocatable :: dx(:,:) !< cell spacing, x-direction (m) + real(kind_real), allocatable :: dy(:,:) !< cell spacing, y-direction (m) + real(kind_real), allocatable :: pmon_u(:,:) !< pm/pn at u points (pm = 1/dx, pn = 1/dy) + real(kind_real), allocatable :: pnom_v(:,:) !< pn/pm at v points + real(kind_real), allocatable :: mask(:,:) !< 1.0 where water, 0.0 where land + + ! parameters calculated during calibration() / read() + ! "group" contains the weights / normalizations for one or more variables + type(soca_diffusion_group_params), allocatable :: group(:) + type(soca_diffusion_group_mapping), allocatable :: group_mapping(:) + + class(soca_geom), pointer :: geom + +contains + procedure :: init => soca_diffusion_init + procedure :: calibrate => soca_diffusion_calibrate + procedure :: multiply => soca_diffusion_multiply + procedure :: write_params => soca_diffusion_write_params + procedure :: read_params => soca_diffusion_read_params + + procedure, private :: multiply_2D => soca_diffusion_multiply_2D + procedure, private :: multiply_2D_tl => soca_diffusion_multiply_2D_tl + procedure, private :: multiply_2D_ad => soca_diffusion_multiply_2D_ad + procedure, private :: diffusion_steps_tl => soca_diffusion_diffusion_steps_tl + procedure, private :: diffusion_steps_ad => soca_diffusion_diffusion_steps_ad + procedure, private :: calc_stats => soca_diffusion_calc_stats + + procedure, private :: calc_norm_bruteforce => soca_diffusion_calc_norm_bruteforce + procedure, private :: calc_norm_randomization => soca_diffusion_calc_norm_randomization +end type soca_diffusion + +! ------------------------------------------------------------------------------ +contains +! ------------------------------------------------------------------------------ + +! ------------------------------------------------------------------------------ +! calculate the masked global min/max/mean values for a given field +! TODO: is there any chance we need to also operate on unmasked fields?!? +subroutine soca_diffusion_calc_stats(self, field, stats) + class(soca_diffusion), intent(inout) :: self + real(kind=kind_real), allocatable, intent(in) :: field(:,:) + real(kind=kind_real), intent(out) :: stats(3) + + real(kind=kind_real) :: l_min, l_max, l_sum, l_count, g_count + + l_min = minval(field(DOMAIN), & + mask=self%mask(DOMAIN)==1.0) + l_max = maxval(field(DOMAIN), & + mask=self%mask(DOMAIN)==1.0) + l_sum = sum(field(DOMAIN), & + mask=self%mask(DOMAIN)==1.0) + l_count = count(self%mask(DOMAIN)==1.0) + + call self%geom%f_comm%allreduce(l_min, stats(1), fckit_mpi_min()) + call self%geom%f_comm%allreduce(l_max, stats(2), fckit_mpi_max()) + call self%geom%f_comm%allreduce(l_sum, stats(3), fckit_mpi_sum()) + call self%geom%f_comm%allreduce(l_count, g_count, fckit_mpi_sum()) + stats(3) = stats(3) / g_count +end subroutine + +! ------------------------------------------------------------------------------ +! Initialize the grid, allocate memory, for the diffusion operator. +! A call to either calibrate() or read() should be done before +! this class is ready to use. +subroutine soca_diffusion_init(self, geom, f_conf) + class(soca_diffusion), intent(inout) :: self + class(soca_geom), target, intent(in) :: geom + type(fckit_configuration), intent(in) :: f_conf + + type(fckit_configuration), allocatable :: f_conf_list(:) + + real(kind=kind_real) :: stats(3) ! min, max, mean + character(len=1024) :: str + character(len=:), allocatable :: str_list(:) + integer :: i, j + + call oops_log%trace("soca_diffusion::init() starting", flush=.true.) + call oops_log%info("") + self%geom => geom + + ! read variable -> group_name mapping + if (f_conf%has("groups")) then + call oops_log%info("ExplicitDiffusion: variable groups") + call f_conf%get_or_die("groups", f_conf_list) + allocate(self%group_mapping(size(f_conf_list))) + do i=1,size(f_conf_list) + call f_conf_list(i)%get_or_die("name", self%group_mapping(i)%group_name) + call oops_log%info(" group name: "//self%group_mapping(i)%group_name) + call oops_log%info(" variables:") + call f_conf_list(i)%get_or_die("variables", str_list) + self%group_mapping(i)%variables = oops_variables() + call self%group_mapping(i)%variables%push_back(str_list) + do j=1,self%group_mapping(i)%variables%nvars() + call oops_log%info(" "//self%group_mapping(i)%variables%variable(j)) + end do + end do + end if + + ! grid and derived grid parameters + !--------------------------------------------------------------------------- + call oops_log%info("ExplicitDiffusion: Initializing grid") + + allocate(self%mask(DOMAIN_WITH_HALO)) + allocate(self%dx(DOMAIN_WITH_HALO)) + allocate(self%dy(DOMAIN_WITH_HALO)) + ! NOTE MOM6 likes to leave unused halo regions undefined, + ! so we explicitly set safe default values here (should probably do this in geom instead??) + self%mask = 0.0 + self%mask(DOMAIN) = self%geom%mask2d(DOMAIN) + self%dx = 1.0e-5 + self%dx(DOMAIN) = geom%dx(DOMAIN) + self%dy = 1.0e-5 + self%dy(DOMAIN) = geom%dy(DOMAIN) + call mpp_update_domains(self%mask, self%geom%Domain%mpp_domain, complete=.true.) + call mpp_update_domains(self%dx, self%geom%Domain%mpp_domain, complete=.true.) + call mpp_update_domains(self%dy, self%geom%Domain%mpp_domain, complete=.true.) + + call self%calc_stats(self%dx,stats) + write (str, *) " dx: min=", stats(1), "max=", stats(2), "mean=", stats(3) + call oops_log%info(str) + call self%calc_stats(self%dy, stats) + write (str, *) " dy: min=", stats(1), "max=", stats(2), "mean=", stats(3) + call oops_log%info(str) + call self%calc_stats(self%geom%cell_area, stats) + write (str, *) " area: min=", stats(1), "max=", stats(2), "mean=", stats(3) + call oops_log%info(str) + + ! calculate derived parameters + allocate(self%pmon_u(DOMAIN_WITH_HALO)) + allocate(self%pnom_v(DOMAIN_WITH_HALO)) + allocate(self%inv_sqrt_area(DOMAIN_WITH_HALO)) + self%pmon_u = 0.0 + self%pnom_v = 0.0 + self%inv_sqrt_area = 0.0 + + do j = LOOP_DOMAIN_J + do i = LOOP_DOMAIN_I + self%inv_sqrt_area(i,j) = 1.0 / sqrt(self%dx(i,j)*self%dy(i,j)) + self%pmon_u(i,j) = (1.0/self%dx(i-1,j) + 1.0/self%dx(i,j)) / (1.0/self%dy(i-1,j) + 1.0/self%dy(i,j)) + self%pnom_v(i,j) = (1.0/self%dy(i,j-1) + 1.0/self%dy(i,j)) / (1.0/self%dx(i,j-1) + 1.0/self%dx(i,j)) + end do + end do + + call mpp_update_domains(self%inv_sqrt_area, self%geom%Domain%mpp_domain, complete=.true.) + call mpp_update_domains(self%pmon_u, self%geom%Domain%mpp_domain, complete=.true.) + call mpp_update_domains(self%pnom_v, self%geom%Domain%mpp_domain, complete=.true.) + + call oops_log%trace("soca_diffusion::init() done", flush=.true.) +end subroutine + +! ------------------------------------------------------------------------------ +! Calibration for the explicit diffuion operator. +! The following are calculated and saved to a file: +! 1) number of iterations required +! 2) the diffusion constants +! 3) the normalization constants +subroutine soca_diffusion_calibrate(self, f_conf) + class(soca_diffusion), intent(inout) :: self + type(fckit_configuration), intent(in) :: f_conf + + type(fckit_configuration), allocatable :: group_conf(:) + real(kind=kind_real) :: stats(3) ! min, max, mean + character(len=1024) :: str + character(len=:), allocatable :: str2, str3 + integer :: i, j, idr, grp, ngroup + type(restart_file_type) :: restart_file + logical :: b + + real(kind=kind_real) :: fixed_scale + real(kind=kind_real), allocatable :: hz_scales(:,:), r_tmp(:,:) + + call oops_log%trace("soca_diffusion::calibrate() starting", flush=.true.) + call oops_log%info("ExplicitDiffusion: running calibration") + + ! allocate things for use later in the loops + allocate(hz_scales(DOMAIN_WITH_HALO)) + allocate(r_tmp(DOMAIN_WITH_HALO)) + + ! how many groups do we have? + call f_conf%get_or_die('scales', group_conf) + ngroup = size(group_conf) + allocate(self%group(ngroup)) + + ! perform calibration once for each variable group + do grp=1,size(group_conf) + write (str, *) "Group ", grp, " of ", size(group_conf) + call oops_log%info(str) + + ! get group name + call group_conf(grp)%get_or_die("name", self%group(grp)%name) + write (str, *) " name: ", self%group(grp)%name + call oops_log%info(str) + + ! allocate space and initialize with safe values + allocate(self%group(grp)%KhDt(DOMAIN_WITH_HALO)) + allocate(self%group(grp)%normalization(DOMAIN_WITH_HALO)) + self%group(grp)%KhDt = 0.0 + self%group(grp)%normalization = 1.0 + + ! Get input lengthscales. Either from: + ! 1) a fixed length scale used globally + ! 2) read in from a file + ! the result is hz_scales containing the length scales (defined as 1 sigma of a guassian) + hz_scales = 1e10 + if (.not. group_conf(grp)%has("fixed value") .neqv. group_conf(grp)%has("from file")) then + ! that was an XOR opperation above, if you were curious + call abor1_ftn("ERROR: calibration.scales[] must define 1 of 'fixed value' or 'from file'") + end if + if ( group_conf(grp)%has("fixed value")) then + ! used a single fixed value globally + call oops_log%info(" Using fixed length scales") + call group_conf(grp)%get_or_die("fixed value", fixed_scale) + hz_scales = fixed_scale + else + ! read lengths from a file. a 2d field is expected + call oops_log%info(" Reading length scales from file") + call group_conf(grp)%get_or_die("from file.filename", str2) + call group_conf(grp)%get_or_die("from file.variable name", str3) + call fms_io_init() + idr = register_restart_field(restart_file, str2, str3, & + hz_scales, domain=self%geom%Domain%mpp_domain) + call restore_state(restart_file, directory='') + call free_restart_type(restart_file) + call fms_io_exit() + end if + call group_conf(grp)%get_or_die("as gaussian", b) + write (str,*) " input values as gaussian (vs GC half width): ", b + call oops_log%info(str) + if (.not. b) then + ! by default, a gaspari cohn half width is expected in the config. + ! (but the rest of this code asssumes gaussian 1 sigma) + ! Do the conversion if needed + hz_scales = hz_scales / 3.57_kind_real + end if + + ! make sure halos are up to date + call mpp_update_domains(hz_scales, self%geom%Domain%mpp_domain, complete=.true.) + + ! print some stats + call self%calc_stats(hz_scales, stats) + write (str, *) " L_hz: min=", stats(1), "max=", stats(2), "mean=", stats(3) + call oops_log%info(str) + + ! calculate the minimum number of iterations needed, rounding up to the + ! nearest even number. + ! M >= 2.0 *(L^2 / (1/dx^2 + 1/dy^2)) + r_tmp = 0.0 + do j = LOOP_DOMAIN_J + do i = LOOP_DOMAIN_I + if (self%mask(i,j) == 0.0 ) cycle + r_tmp(i,j) = 2.0 * hz_scales(i,j)**2 * (1.0/(self%dx(i,j)**2) + 1.0/(self%dy(i,j)**2)) + end do + end do + call self%calc_stats(r_tmp, stats) + i = ceiling(stats(2)) + if (mod(i,2) == 1) i = i + 1 + self%group(grp)%n_iter = i + write (str, *) " minimum iterations: ", i + call oops_log%info(str) + + ! calculate KhDt based on scales and number of iterations + self%group(grp)%KhDt = hz_scales**2 / (2.0 * self%group(grp)%n_iter) + + ! calculate normalization + call oops_log%info(" Calculating normalization...") + call f_conf%get_or_die("normalization.method", str2) + self%group(grp)%normalization = 1.0 + if (str2 == "brute force") then + call self%calc_norm_bruteforce(self%group(grp)) + else if (str2 == "randomization") then + call f_conf%get_or_die("normalization.iterations", i) + call self%calc_norm_randomization(i, self%group(grp)) + else + call abor1_ftn("ERROR: normalization.method must be 'brute force' or 'randomization'") + end if + end do + call oops_log%trace("soca_diffusion::calibrate() done", flush=.true.) +end subroutine + +! ------------------------------------------------------------------------------ +! Perform horizontal diffusion on each level +subroutine soca_diffusion_multiply(self, dx) + class(soca_diffusion), intent(inout) :: self + type(soca_increment), intent(inout) :: dx + + real(kind=kind_real), allocatable :: tmp2d(:,:) + character(len=1024) :: str + integer :: f, z, grp, g, g2 + + call oops_log%trace("soca_diffusion::multiply() starting", flush=.true.) + + if (.not. allocated(self%group) .or. .not. allocated(self%group_mapping)) then + ! uninitialized, calibrate or read should have been called before now + call abor1_ftn("ERROR: soca_diffusion has not been initialized.") + end if + + allocate(tmp2d(DOMAIN_WITH_HALO)) + + do f=1, size(dx%fields) + ! find the group associated with this variable + ! TODO, simplify this + call oops_log%debug("running multiply on "//dx%fields(f)%name) + grp = -1 + do g=1, size(self%group_mapping) + if (self%group_mapping(g)%variables%has(dx%fields(f)%name)) then + do g2=1, size(self%group) + if (self%group(g2)%name == self%group_mapping(g)%group_name) then + grp = g2 + end if + end do + end if + end do + if (grp == -1) then + call abor1_ftn("ERROR: could not find a valid group for the variable "//dx%fields(f)%name) + end if + + do z = 1, dx%fields(f)%nz + tmp2d = dx%fields(f)%val(:,:,z) + call self%multiply_2D(tmp2d, self%group(grp)) + ! NOTE: this is here because the SABERadjoint test doesn't take into account the halo correctly + ! so we have to leave the halo alone + dx%fields(f)%val(DOMAIN,z) = tmp2d(DOMAIN) + end do + call oops_log%debug(str) + end do + + call oops_log%trace("soca_diffusion::multiply() done", flush=.true.) +end subroutine + +! ------------------------------------------------------------------------------ +! perform horizontal diffusion on a single level +subroutine soca_diffusion_multiply_2D(self, field, params) + class(soca_diffusion), intent(inout) :: self + real(kind=kind_real), allocatable :: field(:,:) + type(soca_diffusion_group_params), intent(in) :: params + + call self%multiply_2D_ad(field, params) + call self%multiply_2D_tl(field, params) + +end subroutine + +! ------------------------------------------------------------------------------ + +subroutine soca_diffusion_multiply_2D_tl(self, field, params) + class(soca_diffusion), intent(inout) :: self + real(kind=kind_real), allocatable :: field(:,:) + type(soca_diffusion_group_params), intent(in) :: params + + ! apply grid metric + field = field * self%inv_sqrt_area + + ! apply M/2 iterations of diffusion + call self%diffusion_steps_tl(field, params) + + ! apply normalization + field = field * params%normalization + +end subroutine + +! ------------------------------------------------------------------------------ + +subroutine soca_diffusion_multiply_2D_ad(self, field, params) + class(soca_diffusion), intent(inout) :: self + real(kind=kind_real), allocatable :: field(:,:) + type(soca_diffusion_group_params), intent(in) :: params + + ! apply normalization + field = field * params%normalization + + ! apply M/2 iterations of diffusion + call self%diffusion_steps_ad(field, params) + + ! apply grid metric + field = field * self%inv_sqrt_area + +end subroutine + +! ------------------------------------------------------------------------------ +! Apply half the required iterations of diffusion +subroutine soca_diffusion_diffusion_steps_tl(self, field, params) + class(soca_diffusion), intent(inout) :: self + real(kind=kind_real), allocatable, intent(inout) :: field(:,:) + type(soca_diffusion_group_params), intent(in) :: params + + real(kind=kind_real), allocatable :: flux_x(:,:), flux_y(:,:), hfac(:,:) + integer :: i, j, iter, niter + + ! note, number of iterations is half of what is required + ! (the other half come from application of adjoint) + niter = params%n_iter / 2 + + ! NOTE: flux_x(i,j) is the flux through the western edge of the grid cell. + ! this is opposite of MOM6 conventions where u(i,j) points are east of t(i,j) points. + ! (dosen't really matter, just something to note) + allocate(flux_x(DOMAIN_WITH_HALO)) + allocate(flux_y(DOMAIN_WITH_HALO)) + flux_x = 0.0 + flux_y = 0.0 + + ! calculate some needed constants (TODO, move to initialization?) + allocate(hfac(DOMAIN_WITH_HALO)) + hfac = 0.0 + do j=LOOP_DOMAIN_J + do i=LOOP_DOMAIN_I + hfac(i,j) = (1.0/self%dy(i,j)/self%dx(i,j)) + end do + end do + call mpp_update_domains(field, self%geom%Domain%mpp_domain, complete=.true.) + + do iter=1,niter + ! calculate diffusive flux on each edge of a grid box. masking out where there is land + do j=LOOP_DOMAIN_J + do i=LOOP_DOMAIN_I+1 ! assume halo size is >= 1, and skip doing a halo update + flux_x(i,j) = self%pmon_u(i,j) * 0.5 * (params%KhDt(i,j) + params%KhDt(i-1,j)) * (field(i,j) - field(i-1,j)) + flux_x(i,j) = flux_x(i,j) * self%mask(i,j) * self%mask(i-1,j) + end do + end do + do j=LOOP_DOMAIN_J+1 ! assume halo size is >= 1, and skip doing a halo update + do i=LOOP_DOMAIN_I + flux_y(i,j) = self%pnom_v(i,j) * 0.5 * (params%KhDt(i,j) + params%KhDt(i,j-1)) * (field(i,j) - field(i,j-1)) + flux_y(i,j) = flux_y(i,j) * self%mask(i,j) * self%mask(i,j-1) + end do + end do + + ! time-step hz diffusion terms + do j=LOOP_DOMAIN_J + do i=LOOP_DOMAIN_I + field(i,j) = field(i,j) + hfac(i,j) * & + (flux_x(i+1, j) - flux_x(i,j) + flux_y(i, j+1) - flux_y(i,j)) + end do + end do + call mpp_update_domains(field, self%geom%Domain%mpp_domain, complete=.true.) + end do +end subroutine + + +! ------------------------------------------------------------------------------ +subroutine soca_diffusion_diffusion_steps_ad(self, field, params) + class(soca_diffusion), intent(inout) :: self + real(kind=kind_real), allocatable, intent(inout) :: field(:,:) + type(soca_diffusion_group_params), intent(in) :: params + + real(kind=kind_real), allocatable :: wrk_old(:,:), wrk_new(:,:), tmp(:,:) + real(kind=kind_real), allocatable :: flux_x(:,:), flux_y(:,:), hfac(:,:) + real(kind=kind_real) :: adfac + integer :: i, j, iter, niter + + ! note, number of iterations is half of what is required + ! (the other half come from application of tl) + niter = params%n_iter / 2 + + ! NOTE: flux_x(i,j) is the flux through the western edge of the grid cell. + ! this is opposite of MOM6 conventions where u(i,j) points are east of t(i,j) points. + ! (dosen't really matter, just something to note) + allocate(wrk_new(DOMAIN_WITH_HALO)) + allocate(wrk_old(DOMAIN_WITH_HALO)) + allocate(tmp(DOMAIN_WITH_HALO)) + allocate(flux_x(DOMAIN_WITH_HALO)) + allocate(flux_y(DOMAIN_WITH_HALO)) + wrk_old = 0.0 + wrk_new = 0.0 + flux_x = 0.0 + flux_y = 0.0 + + ! calculate some needed constants (TODO, move to initialization?) + allocate(hfac(DOMAIN_WITH_HALO)) + hfac = 0.0 + do j=LOOP_DOMAIN_J + do i=LOOP_DOMAIN_I + hfac(i,j) = (1.0/self%dy(i,j)/self%dx(i,j)) + end do + end do + + ! adjoint of convoled solution + do j=LOOP_DOMAIN_J + do i=LOOP_DOMAIN_I + wrk_old(i,j) = wrk_old(i,j) + field(i,j) + field(i,j) = 0.0 + end do + end do + + ! integrate adjoint hz diffusion terms + do iter=1,niter + tmp = wrk_new + wrk_new = wrk_old + wrk_old = tmp + flux_x = 0.0 + flux_y = 0.0 + + ! time-step adjoint hz diffusion terms + do j=LOOP_DOMAIN_J + do i=LOOP_DOMAIN_I + adfac=hfac(i,j)*wrk_new(i,j) + flux_y(i,j ) = flux_y(i,j ) - adfac + flux_y(i,j+1) = flux_y(i,j+1) + adfac + flux_x(i ,j) = flux_x(i ,j) - adfac + flux_x(i+1,j) = flux_x(i+1,j) + adfac + wrk_old(i,j) = wrk_new(i,j) + end do + end do + wrk_new = 0.0 + + ! compute adjoint diffusive flux + do j=LOOP_DOMAIN_J+1 + do i=LOOP_DOMAIN_I + flux_y(i,j) = flux_y(i,j) * self%mask(i,j) * self%mask(i,j-1) + adfac = self%pnom_v(i,j) * 0.5*(params%KhDt(i,j-1)+params%KhDt(i,j)) * flux_y(i,j) + wrk_old(i,j-1) = wrk_old(i,j-1) - adfac + wrk_old(i,j ) = wrk_old(i,j ) + adfac + flux_y(i,j) = 0.0 + end do + end do + do j=LOOP_DOMAIN_J + do i=LOOP_DOMAIN_I+1 + flux_x(i,j) = flux_x(i,j) * self%mask(i,j) * self%mask(i-1,j) + adfac = self%pmon_u(i,j) * 0.5*(params%KhDt(i-1,j)+params%KhDt(i,j)) * flux_x(i,j) + wrk_old(i-1,j) = wrk_old(i-1,j) - adfac + wrk_old(i, j) = wrk_old(i, j) + adfac + flux_x(i,j) = 0.0 + end do + end do + call mpp_update_domains_ad(wrk_old, self%geom%Domain%mpp_domain, complete=.true.) + end do + + ! set adjoint initial conditions + field = field + wrk_old + wrk_old = 0.0 + +end subroutine + +! ------------------------------------------------------------------------------ +! Calculate the exact normalization weights using the brute force method +! (creating a dirac at every SINGLE point). +! You probably don't want to use this, except for testing. +! Use randomization instead. +! ------------------------------------------------------------------------------ +subroutine soca_diffusion_calc_norm_bruteforce(self, params) + class(soca_diffusion), intent(inout) :: self + type(soca_diffusion_group_params), intent(inout) :: params + + integer :: i, j + logical :: local + real(kind=kind_real), allocatable :: r_tmp(:,:), norm(:,:) + + call oops_log%info(" Calculating normalization with BRUTEFORCE (eeeek!)") + + allocate(r_tmp(DOMAIN_WITH_HALO)) + allocate(norm(DOMAIN_WITH_HALO)) + + params%normalization = 1.0 + do j=self%geom%jsg, self%geom%jeg + do i=self%geom%isg, self%geom%ieg + r_tmp = 0.0 + local = i >= self%geom%isc .and. i <= self%geom%iec .and. & + j >= self%geom%jsc .and. j <= self%geom%jec + if (local) r_tmp(i,j) = 1.0 + call self%multiply_2D(r_tmp, params) + if (local) then + if(self%mask(i,j) == 0.0) cycle + norm(i,j) = 1.0 / sqrt(r_tmp(i,j)) + end if + end do + end do + call mpp_update_domains(norm, self%geom%Domain%mpp_domain, complete=.true.) + params%normalization = norm +end subroutine + + +! ------------------------------------------------------------------------------ +! Estimate the normalization weights by creating random vectors (normally distributed) +! applying the diffusion TL, and keeping a running statistic of the variance of +! those results. +! +! Typically a good number of iterations is around 10,000 +! ------------------------------------------------------------------------------ +subroutine soca_diffusion_calc_norm_randomization(self, iter, params) + class(soca_diffusion), intent(inout) :: self + integer, intent(in) :: iter + type(soca_diffusion_group_params), intent(inout) :: params + + real(kind=kind_real), allocatable :: field(:,:) + real(kind=kind_real), allocatable :: s(:,:) + real(kind=kind_real), allocatable :: m(:,:), new_m(:,:) + + integer :: n, n10pct, rnd + character(len=1024) :: str + + allocate(field(DOMAIN_WITH_HALO)) + allocate(s(DOMAIN_WITH_HALO)) + allocate(m(DOMAIN_WITH_HALO)) + allocate(new_m(DOMAIN_WITH_HALO)) + + s = 0.0 + m = 0.0 + n10pct = iter/10 !< ouput info to screen every 10% + + call oops_log%info(" Calculating normalization via randomization") + do n=1,iter + if (mod(n, n10pct) == 0) then + write (str, *) " normalization: ", 10*n/n10pct, "% complete" + call oops_log%info(str, flush=.true.) + end if + + ! create a random vector + ! Ensure random number are different on each PE. + ! TODO: when this is all refactored into saber, it would + ! be nice to generate the random numbers on 1 PE then scatter, + ! this will ensure answers don't change when PE counts change + rnd=n*self%geom%f_comm%size() + self%geom%f_comm%rank() + call normal_distribution(field, 0.0_kind_real, 1.0_kind_real, rnd, .true.) + + ! apply the diffusion TL + call self%multiply_2D_tl(field, params) + + ! keep track of the stats needed for a running variance calculation + ! (Welford 1962 algorithm) + new_m = m + (field-m)/n + s = s + (field - m)*(field - new_m) + m = new_m + end do + + ! calculate final variance + field = (s/(iter-1)) + + ! normalization (where ocean) is 1/sqrt(variance) + where (self%mask == 1.0) params%normalization = 1.0 / sqrt(field) + + call mpp_update_domains(params%normalization, self%geom%Domain%mpp_domain, complete=.true.) +end subroutine + +! ------------------------------------------------------------------------------ +! write out the parameters to a restart file +subroutine soca_diffusion_write_params(self, filename) + class(soca_diffusion), intent(inout) :: self + character(len=*), intent(in) :: filename + + type(restart_file_type) :: restart_file + character(len=1024) :: str + integer :: idr, grp + + ! write to file + call fms_io_init() + do grp=1,size(self%group) + str = self%group(grp)%name // "@iterations" + idr = register_restart_field(restart_file, filename, str, & + self%group(grp)%n_iter, domain=self%geom%Domain%mpp_domain) + + str = self%group(grp)%name // "@khdt" + idr = register_restart_field(restart_file, filename, str, & + self%group(grp)%KhDt, domain=self%geom%Domain%mpp_domain) + + str = self%group(grp)%name // "@normalization" + idr = register_restart_field(restart_file, filename, str, & + self%group(grp)%normalization, domain=self%geom%Domain%mpp_domain) + end do + + call save_restart(restart_file, directory='') + call free_restart_type(restart_file) + call fms_io_exit() +end subroutine + +! ------------------------------------------------------------------------------ +! read in the parameters from a restart file +subroutine soca_diffusion_read_params(self, filename) + class(soca_diffusion), intent(inout) :: self + character(len=*), intent(in) :: filename + + type(restart_file_type) :: restart_file + integer :: idr, grp + character(len=1024) :: str + + ! make sure we havent read in parameters already + if ( allocated(self%group)) then + call abor1_ftn("ERROR: soca_diffusion has already been initialized.") + end if + + allocate(self%group(size(self%group_mapping))) + + ! read from file + call fms_io_init() + do grp=1,size(self%group) + self%group(grp)%name = trim(self%group_mapping(grp)%group_name) + allocate(self%group(grp)%KhDt(DOMAIN_WITH_HALO)) + allocate(self%group(grp)%normalization(DOMAIN_WITH_HALO)) + + str = self%group(grp)%name // "@iterations" + idr = register_restart_field(restart_file, filename, str, & + self%group(grp)%n_iter, domain=self%geom%Domain%mpp_domain) + + str = self%group(grp)%name // "@khdt" + idr = register_restart_field(restart_file, filename, str, & + self%group(grp)%KhDt, domain=self%geom%Domain%mpp_domain) + + str = self%group(grp)%name // "@normalization" + idr = register_restart_field(restart_file, filename, str, & + self%group(grp)%normalization, domain=self%geom%Domain%mpp_domain) + end do + + call restore_state(restart_file, directory='') + call free_restart_type(restart_file) + call fms_io_exit() + + ! update halos + do grp=1,size(self%group) + call mpp_update_domains(self%group(grp)%normalization, self%geom%Domain%mpp_domain, complete=.true.) + call mpp_update_domains(self%group(grp)%KhDt, self%geom%Domain%mpp_domain, complete=.true.) + end do +end subroutine + +! ------------------------------------------------------------------------------ + +end module soca_diffusion_mod diff --git a/src/soca/Fields/soca_fields_metadata_mod.F90 b/src/soca/Fields/soca_fields_metadata_mod.F90 index fd317241c..c37e05758 100644 --- a/src/soca/Fields/soca_fields_metadata_mod.F90 +++ b/src/soca/Fields/soca_fields_metadata_mod.F90 @@ -8,6 +8,7 @@ module soca_fields_metadata_mod use fckit_configuration_module, only: fckit_configuration, fckit_yamlconfiguration use fckit_pathname_module, only : fckit_pathname +use kinds, only: kind_real implicit none private @@ -24,9 +25,12 @@ module soca_fields_metadata_mod character(len=:), allocatable :: levels !< "1", or "full_ocn" character(len=:), allocatable :: getval_name !< variable name used by UFO character(len=:), allocatable :: getval_name_surface ! name used by UFO for the surface (if this is a 3D field) - character(len=:), allocatable :: io_file !< the restart file domain (ocn, sfc, ice) + character(len=:), allocatable :: io_file !< the restart file domain (ocn, sfc, ice). Or if "CONSTANT" use the value in "constant_value" character(len=:), allocatable :: io_name !< the name use in the restart IO character(len=:), allocatable :: property !< physical property of the field, "none" or "positive_definite" + real(kind=kind_real) :: fillvalue + logical :: vert_interp !< true if the field can be vertically interpolated + real(kind=kind_real) :: constant_value !< An optional value to use globally for the field end type @@ -72,7 +76,9 @@ subroutine soca_fields_metadata_create(self, filename) integer :: i, j logical :: bool + real(kind=kind_real) :: r character(len=:), allocatable :: str + real(kind=kind_real) :: val ! parse all the metadata from a yaml configuration file conf = fckit_yamlconfiguration( fckit_pathname(filename)) @@ -106,6 +112,28 @@ subroutine soca_fields_metadata_create(self, filename) if(.not. conf_list(i)%get("property", str)) str = "none" self%metadata(i)%property = str + if(.not. conf_list(i)%get("fill value", val)) val = 0.0 + self%metadata(i)%fillvalue = val + + if(.not. conf_list(i)%get("vert interp", bool)) then + if (self%metadata(i)%levels == "1" ) then + bool = .false. + else + bool = .true. + end if + end if + self%metadata(i)%vert_interp = bool + + if(conf_list(i)%get("constant value", r)) then + if (.not. self%metadata(i)%io_file == "") then + str=repeat(" ", 1024) + write(str, *) "error in field metadata file for '", self%metadata(i)%name, & + "' : 'io file' cannot be set if 'constant value' is given" + call abor1_ftn(str) + end if + self%metadata(i)%constant_value = r + self%metadata(i)%io_file = "CONSTANT" + end if end do ! check for duplicates diff --git a/src/soca/Fields/soca_fields_mod.F90 b/src/soca/Fields/soca_fields_mod.F90 index 6efcb07f8..a99c2f683 100644 --- a/src/soca/Fields/soca_fields_mod.F90 +++ b/src/soca/Fields/soca_fields_mod.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 2017-2021 UCAR +! (C) Copyright 2017-2023 UCAR ! ! This software is licensed under the terms of the Apache Licence Version 2.0 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. @@ -18,6 +18,7 @@ module soca_fields_mod datetime_create, datetime_diff use duration_mod, only: duration, duration_to_string use fckit_configuration_module, only: fckit_configuration +use logger_mod use fckit_mpi_module, only: fckit_mpi_min, fckit_mpi_max, fckit_mpi_sum use kinds, only: kind_real use oops_variables_mod, only: oops_variables @@ -29,7 +30,7 @@ module soca_fields_mod use fms_mod, only: write_data, set_domain use MOM_remapping, only : remapping_CS, initialize_remapping, remapping_core_h, & end_remapping -use mpp_domains_mod, only : mpp_update_domains, mpp_update_domains_ad +use mpp_domains_mod, only : mpp_update_domains ! SOCA modules use soca_fields_metadata_mod, only : soca_field_metadata @@ -99,6 +100,9 @@ module soca_fields_mod !>\copybrief soca_field_stencil_interp \see soca_field_stencil_interp procedure :: stencil_interp => soca_field_stencil_interp + !>\copybrief soca_field_fill_masked \see soca_field_fill_masked + procedure :: fill_masked => soca_field_fill_masked + end type soca_field @@ -224,9 +228,6 @@ module soca_fields_mod !> copybrief soca_fields_to_fieldset \see soca_fields_to_fieldset procedure :: to_fieldset => soca_fields_to_fieldset - !> copybrief soca_fields_to_fieldset_ad \see soca_fields_to_fieldset_ad - procedure :: to_fieldset_ad => soca_fields_to_fieldset_ad - procedure :: from_fieldset => soca_fields_from_fieldset !> \} @@ -361,7 +362,7 @@ subroutine soca_field_stencil_interp(self, geom, fromto) ! source point on land, skip if (masksrc_local(ij(1,sti), ij(2,sti)) == 0_kind_real) cycle - ! outcroping of layers, skip + ! outcroping of layers, skip if (abs(self%val(ij(1,sti), ij(2,sti),1)) > val_max) cycle ! store the valid neighbors @@ -384,6 +385,25 @@ subroutine soca_field_stencil_interp(self, geom, fromto) end subroutine soca_field_stencil_interp +! ------------------------------------------------------------------------------ +!> Fill masked values +!! +!! Needed when reading fms history which can contain NaN's over land +subroutine soca_field_fill_masked(self, geom) + class(soca_field), intent(inout) :: self + type(soca_geom), intent(in) :: geom + + integer :: i, j + + if (.not. associated(self%mask)) return + do j = geom%jsc, geom%jec + do i = geom%isc, geom%iec + if (self%mask(i,j)==0) self%val(i,j,:) = self%metadata%fillvalue + end do + end do + +end subroutine soca_field_fill_masked + ! ------------------------------------------------------------------------------ !> Delete the soca_field object. !! @@ -905,7 +925,11 @@ subroutine soca_fields_read(self, f_conf, vdate) ! built-in variables do i=1,size(self%fields) - if(self%fields(i)%metadata%io_name /= "") then + + if(self%fields(i)%metadata%io_file == "CONSTANT") then + self%fields(i)%val(:,:,:) = self%fields(i)%metadata%constant_value + + else if(self%fields(i)%metadata%io_file /= "") then ! which file are we reading from? select case(self%fields(i)%metadata%io_file) case ('ocn') @@ -956,6 +980,12 @@ subroutine soca_fields_read(self, f_conf, vdate) call fms_io_exit() + ! Change masked values + do n=1,size(self%fields) + field => self%fields(n) + call field%fill_masked(self%geom) + end do + ! Update halo and return if reading increment if (iread==3) then ! do n=1,size(self%fields) @@ -969,6 +999,44 @@ subroutine soca_fields_read(self, f_conf, vdate) isc = self%geom%isc ; iec = self%geom%iec jsc = self%geom%jsc ; jec = self%geom%jec + ! Remap layers if needed + if (vert_remap) then + + ! output log of what fields are going to be interpolated vertically + if ( self%geom%f_comm%rank() == 0 ) then + do n=1,size(self%fields) + if (.not. self%fields(n)%metadata%vert_interp) cycle + call oops_log%info("vertically remapping "//trim(self%fields(n)%name)) + end do + end if + + allocate(h_common_ij(nz), hocn_ij(nz), varocn_ij(nz), varocn2_ij(nz)) + call initialize_remapping(remapCS,'PCM') + do i = isc, iec + do j = jsc, jec + h_common_ij = h_common(i,j,:) + hocn_ij = hocn%val(i,j,:) + + do n=1,size(self%fields) + field => self%fields(n) + ! TODO Vertical remapping is only valid if the field is on the tracer grid point. + if (.not. field%metadata%vert_interp) cycle + if (associated(field%mask) .and. field%mask(i,j).eq.1) then + varocn_ij = field%val(i,j,:) + call remapping_core_h(remapCS, nz, h_common_ij, varocn_ij,& + &nz, hocn_ij, varocn2_ij) + field%val(i,j,:) = varocn2_ij + else + field%val(i,j,:) = 0.0_kind_real + end if + end do + end do + end do + hocn%val = h_common + deallocate(h_common_ij, hocn_ij, varocn_ij, varocn2_ij) + call end_remapping(remapCS) + end if + ! Initialize mid-layer depth from layer thickness if (self%has("layer_depth")) then call self%get("layer_depth", layer_depth) @@ -980,48 +1048,19 @@ subroutine soca_fields_read(self, f_conf, vdate) call self%get("tocn", field) call self%get("socn", field2) call self%get("mld", mld) + mld%val = 0.0 do i = isc, iec do j = jsc, jec + if (self%geom%mask2d(i,j)==0) cycle + mld%val(i,j,1) = soca_mld(& &field2%val(i,j,:),& &field%val(i,j,:),& &layer_depth%val(i,j,:),& &self%geom%lon(i,j),& - &self%geom%lat(i,j)) - end do - end do - end if - - ! Remap layers if needed - if (vert_remap) then - allocate(h_common_ij(nz), hocn_ij(nz), varocn_ij(nz), varocn2_ij(nz)) - call initialize_remapping(remapCS,'PCM') - do i = isc, iec - do j = jsc, jec - h_common_ij = h_common(i,j,:) - hocn_ij = hocn%val(i,j,:) - - do n=1,size(self%fields) - field => self%fields(n) - select case(field%name) - ! TODO remove hardcoded variable names here - ! TODO Add u and v. Remapping u and v will require interpolating h - case ('tocn','socn') - if (associated(field%mask) .and. field%mask(i,j).eq.1) then - varocn_ij = field%val(i,j,:) - call remapping_core_h(remapCS, nz, h_common_ij, varocn_ij,& - &nz, hocn_ij, varocn2_ij) - field%val(i,j,:) = varocn2_ij - else - field%val(i,j,:) = 0.0_kind_real - end if - end select - end do + &self%geom%lat(i,j)) end do end do - hocn%val = h_common - deallocate(h_common_ij, hocn_ij, varocn_ij, varocn2_ij) - call end_remapping(remapCS) end if ! Update halo @@ -1207,6 +1246,7 @@ subroutine soca_fields_write_rst(self, f_conf, vdate) ! built in variables do i=1,size(self%fields) field => self%fields(i) + call field%fill_masked(self%geom) if (len_trim(field%metadata%io_file) /= 0) then ! which file are we writing to select case(field%metadata%io_file) @@ -1514,9 +1554,8 @@ subroutine soca_fields_to_fieldset(self, vars, afieldset) type(atlas_fieldset), intent(inout) :: afieldset type(atlas_field) :: afield - integer :: v, z + integer :: v, n, i, j type(soca_field), pointer :: field - real(kind=kind_real), pointer :: mask(:,:) => null() !< field mask type(atlas_metadata) :: meta real(kind=kind_real), pointer :: real_ptr(:,:) @@ -1524,13 +1563,16 @@ subroutine soca_fields_to_fieldset(self, vars, afieldset) call self%get(vars%variable(v), field) ! make sure halos are updated (remove? is redundant?) + ! NOTE: this breaks the saber adjoint test for the diffusion operator. + ! Fixing it is more work than I want to do right now. So if you want to run the + ! adjoint test, comment out this line first! call field%update_halo(self%geom) ! get/create field if (afieldset%has_field(vars%variable(v))) then afield = afieldset%field(vars%variable(v)) else - afield = self%geom%functionspaceInchalo%create_field( & + afield = self%geom%functionspace%create_field( & name=vars%variable(v), kind=atlas_real(kind_real), levels=field%nz) meta = afield%metadata() call meta%set('interp_type', 'default') @@ -1542,53 +1584,16 @@ subroutine soca_fields_to_fieldset(self, vars, afieldset) ! create and fill field call afield%data(real_ptr) - do z=1,field%nz - real_ptr(z,:) = pack(field%val(:,:, z), mask=self%geom%valid_halo_mask) + do j=self%geom%jsc,self%geom%jec + do i=self%geom%isc,self%geom%iec + real_ptr(:, self%geom%atlas_ij2idx(i,j)) = field%val(i,j,:) + end do end do - call afield%final() - - end do -end subroutine - -! ------------------------------------------------------------------------------ -!> Adjoint of get fields used by the interpolation. -!! -!! The fields that are input ahave have halos (minus the invalid and duplicate halo points) -subroutine soca_fields_to_fieldset_ad(self, vars, afieldset) - class(soca_fields), intent(in) :: self - type(oops_variables), intent(in) :: vars - type(atlas_fieldset), intent(in) :: afieldset - - integer :: v, z - integer :: is, ie, js, je - type(soca_field), pointer :: field - type(atlas_field) :: afield - real(kind=kind_real), pointer :: real_ptr(:,:) - real(kind=kind_real), pointer :: tmp(:,:) - - ! start/stop idx, assuming halo - is = self%geom%isd; ie = self%geom%ied - js = self%geom%jsd; je = self%geom%jed - - allocate(tmp(is:ie, js:je)) - - do v=1,vars%nvars() - call self%get(vars%variable(v), field) - afield = afieldset%field(vars%variable(v)) - tmp = 0.0 - call afield%data(real_ptr) - do z=1,field%nz - tmp = unpack(real_ptr(z,:), self%geom%valid_halo_mask, 0.0_kind_real) - call mpp_update_domains_ad(tmp, self%geom%Domain%mpp_domain, complete=.true.) - field%val(:,:,z) = field%val(:,:,z) + tmp - end do call afield%final() - end do end subroutine - ! ------------------------------------------------------------------------------ !> Set the our values from an atlas fieldset subroutine soca_fields_from_fieldset(self, vars, afieldset) @@ -1596,7 +1601,7 @@ subroutine soca_fields_from_fieldset(self, vars, afieldset) type(oops_variables), intent(in) :: vars type(atlas_fieldset), intent(in) :: afieldset - integer :: jvar, i, jz + integer :: jvar, i, j, n, f real(kind=kind_real), pointer :: real_ptr(:,:) logical :: var_found character(len=1024) :: fieldname @@ -1608,20 +1613,20 @@ subroutine soca_fields_from_fieldset(self, vars, afieldset) do jvar = 1,vars%nvars() var_found = .false. - do i=1,size(self%fields) - field => self%fields(i) + do f=1,size(self%fields) + field => self%fields(f) if (trim(vars%variable(jvar))==trim(field%name)) then ! Get field afield = afieldset%field(vars%variable(jvar)) ! Copy data call afield%data(real_ptr) - do jz=1,field%nz - ! NOTE, any missing values from unpacking are filled with 0.0 - field%val(:,:,jz) = unpack(real_ptr(jz,:), self%geom%valid_halo_mask, 0.0_kind_real) + do j=self%geom%jsc,self%geom%jec + do i=self%geom%isc,self%geom%iec + field%val(i,j,:) = real_ptr(:, self%geom%atlas_ij2idx(i,j)) + end do end do - - ! Release pointer + call afield%final() ! Set flag @@ -1631,7 +1636,6 @@ subroutine soca_fields_from_fieldset(self, vars, afieldset) end do if (.not.var_found) call abor1_ftn('variable '//trim(vars%variable(jvar))//' not found in increment') end do - end subroutine end module soca_fields_mod diff --git a/src/soca/Geometry/Geometry.cc b/src/soca/Geometry/Geometry.cc index 338598219..2873837c0 100644 --- a/src/soca/Geometry/Geometry.cc +++ b/src/soca/Geometry/Geometry.cc @@ -1,17 +1,23 @@ /* - * (C) Copyright 2017-2021 UCAR + * (C) Copyright 2017-2023 UCAR * * This software is licensed under the terms of the Apache Licence Version 2.0 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. */ -#include "atlas/grid.h" -#include "atlas/util/Config.h" +#include -#include "eckit/config/YAMLConfiguration.h" +#include "atlas/functionspace.h" +#include "atlas/mesh/actions/BuildHalo.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/mesh/MeshBuilder.h" +#include "atlas/output/Gmsh.h" + +#include "eckit/config/Configuration.h" #include "soca/Geometry/Geometry.h" + // ----------------------------------------------------------------------------- namespace soca { @@ -27,27 +33,90 @@ namespace soca { soca_geo_setup_f90(keyGeom_, &conf, &comm); - // Set ATLAS lonlat and function space (with and without halos) - atlas::FieldSet lonlat; - soca_geo_lonlat_f90(keyGeom_, lonlat.get()); - functionSpace_ = atlas::functionspace::PointCloud(lonlat->field("lonlat")); - functionSpaceIncHalo_ = atlas::functionspace::PointCloud(lonlat->field("lonlat_inc_halos")); - - // Set ATLAS function space pointer in Fortran - soca_geo_set_atlas_functionspace_pointer_f90( - keyGeom_, functionSpace_.get(), functionSpaceIncHalo_.get()); - - // Fill ATLAS fieldset - soca_geo_to_fieldset_f90(keyGeom_, extraFields_.get()); - - // messy, fix this // generate the grid ONLY if being run under the gridgen application. - // also, if true, then don't bother with the kdtree generation in the next step. if (gen) { soca_geo_gridgen_f90(keyGeom_); - return; } + + // setup the atlas functionspace + { + using atlas::gidx_t; + using atlas::idx_t; + + // get the number of nodes and cells owned by this PE + int num_nodes; + int num_quad_elements; + soca_geo_get_mesh_size_f90(keyGeom_, num_nodes, num_quad_elements); + + // get the mesh connectivity from the soca fortran + std::vector lons(num_nodes); + std::vector lats(num_nodes); + std::vector ghosts(num_nodes); + std::vector global_indices(num_nodes); + std::vector remote_indices(num_nodes); + std::vector partitions(num_nodes); + const int num_quad_nodes = num_quad_elements * 4; + std::vector raw_quad_nodes(num_quad_nodes); + soca_geo_gen_mesh_f90(keyGeom_, + num_nodes, lons.data(), lats.data(), ghosts.data(), global_indices.data(), + remote_indices.data(), partitions.data(), + num_quad_nodes, raw_quad_nodes.data()); + + // calculate per-PE global quad numbering offset + std::vector num_elements_per_rank(comm_.size()); + comm_.allGather(num_quad_elements, num_elements_per_rank.begin(), + num_elements_per_rank.end()); + int global_element_index = 0; + for (size_t i = 0; i < comm_.rank(); ++i) { + global_element_index += num_elements_per_rank[i]; + } + + // convert some of the temporary arrays into a form atlas expects + std::vector atlas_global_indices(num_nodes); + std::transform(global_indices.begin(), global_indices.end(), atlas_global_indices.begin(), + [](const int index) {return atlas::gidx_t{index};}); + std::vector atlas_remote_indices(num_nodes); + std::transform(remote_indices.begin(), remote_indices.end(), atlas_remote_indices.begin(), + [](const int index) {return atlas::idx_t{index};}); + std::vector> tri_boundary_nodes{}; // MOM does not have triangles + std::vector tri_global_indices{}; // MOM does not have triangles + std::vector> quad_boundary_nodes(num_quad_elements); + std::vector quad_global_indices(num_quad_elements); + for (size_t quad = 0; quad < num_quad_elements; ++quad) { + for (size_t i = 0; i < 4; ++i) { + quad_boundary_nodes[quad][i] = raw_quad_nodes[4*quad + i]; + } + quad_global_indices[quad] = global_element_index++; + } + + // build the mesh! + const atlas::idx_t remote_index_base = 1; // 1-based indexing from Fortran + eckit::LocalConfiguration config{}; + config.set("mpi_comm", comm_.name()); + const atlas::mesh::MeshBuilder mesh_builder{}; + atlas::Mesh mesh = mesh_builder( + lons, lats, ghosts, + atlas_global_indices, atlas_remote_indices, remote_index_base, partitions, + tri_boundary_nodes, tri_global_indices, + quad_boundary_nodes, quad_global_indices, config); + atlas::mesh::actions::build_halo(mesh, 1); + functionSpace_ = atlas::functionspace::NodeColumns(mesh, config); + + // optionally save output for viewing with gmsh + if (conf.getBool("gmsh save", false)) { + std::string filename = conf.getString("gmsh filename", "out.msh"); + atlas::output::Gmsh gmsh(filename, + atlas::util::Config("coordinates", "xyz") + | atlas::util::Config("ghost", true)); // enables viewing halos per task + gmsh.write(mesh); + } + } + + // Set ATLAS function space in Fortran, and fill in the + // geometry fieldset from the fortran side. + soca_geo_init_atlas_f90(keyGeom_, functionSpace_.get(), fields_.get()); } + // ----------------------------------------------------------------------------- Geometry::Geometry(const Geometry & other) : comm_(other.comm_), @@ -56,16 +125,8 @@ namespace soca { const int key_geo = other.keyGeom_; soca_geo_clone_f90(keyGeom_, key_geo); - functionSpace_ = atlas::functionspace::PointCloud(other.functionSpace_->lonlat()); - functionSpaceIncHalo_ = atlas::functionspace::PointCloud(other.functionSpaceIncHalo_->lonlat()); - soca_geo_set_atlas_functionspace_pointer_f90(keyGeom_, functionSpace_.get(), - functionSpaceIncHalo_.get()); - - extraFields_ = atlas::FieldSet(); - for (int jfield = 0; jfield < other.extraFields_->size(); ++jfield) { - atlas::Field atlasField = other.extraFields_->field(jfield); - extraFields_->add(atlasField); - } + functionSpace_ = atlas::functionspace::NodeColumns(other.functionSpace_); + soca_geo_init_atlas_f90(keyGeom_, functionSpace_.get(), fields_.get()); } // ----------------------------------------------------------------------------- Geometry::~Geometry() { @@ -110,14 +171,32 @@ namespace soca { // ----------------------------------------------------------------------------- void Geometry::latlon(std::vector & lats, std::vector & lons, const bool halo) const { - // get the number of gridpoints - int gridSize; - soca_geo_gridsize_f90(keyGeom_, halo, gridSize); + // get the number of total grid points (including halo) + int gridSizeWithHalo = functionSpace_.size(); + auto vLonlat = atlas::array::make_view(functionSpace_.lonlat()); + + // count the number of owned non-ghost points (isn't there an atlas function for this??) + auto vGhost = atlas::array::make_view(functionSpace_.ghost()); + int gridSizeNoHalo = 0; + for (size_t i = 0; i < gridSizeWithHalo; i++) { + if (vGhost(i) == 0) gridSizeNoHalo++; + } - // get the lat/lon of those gridpoints - lats.resize(gridSize); + // allocate arrays + int gridSize = (halo) ? gridSizeWithHalo : gridSizeNoHalo; lons.resize(gridSize); - soca_geo_gridlatlon_f90(keyGeom_, halo, gridSize, lats.data(), lons.data()); + lats.resize(gridSize); + + // fill + int idx = 0; + for (size_t i=0; i < gridSizeWithHalo; i++) { + if (!halo && vGhost(i)) continue; + double lon = vLonlat(i, 0); + double lat = vLonlat(i, 1); + lats[idx] = lat; + lons[idx++] = lon; + } + ASSERT(idx == gridSize); } } // namespace soca diff --git a/src/soca/Geometry/Geometry.h b/src/soca/Geometry/Geometry.h index ba4c426a1..17bcb1320 100644 --- a/src/soca/Geometry/Geometry.h +++ b/src/soca/Geometry/Geometry.h @@ -69,10 +69,10 @@ namespace soca { const int& toFortran() const {return keyGeom_;} const eckit::mpi::Comm & getComm() const {return comm_;} - const atlas::FunctionSpace & functionSpace() const {return functionSpaceIncHalo_;} - atlas::FunctionSpace & functionSpace() {return functionSpaceIncHalo_;} - const atlas::FieldSet & extraFields() const {return extraFields_;} - atlas::FieldSet & extraFields() {return extraFields_;} + const atlas::FunctionSpace & functionSpace() const {return functionSpace_;} + atlas::FunctionSpace & functionSpace() {return functionSpace_;} + const atlas::FieldSet & fields() const {return fields_;} + atlas::FieldSet & fields() {return fields_;} void latlon(std::vector &, std::vector &, const bool) const; @@ -84,9 +84,8 @@ namespace soca { int keyGeom_; const eckit::mpi::Comm & comm_; FmsInput fmsinput_; - atlas::FunctionSpace functionSpace_; - atlas::FunctionSpace functionSpaceIncHalo_; - atlas::FieldSet extraFields_; + atlas::functionspace::NodeColumns functionSpace_; + atlas::FieldSet fields_; }; // ----------------------------------------------------------------------------- diff --git a/src/soca/Geometry/GeometryFortran.h b/src/soca/Geometry/GeometryFortran.h index 77b465a81..1d4d855f5 100644 --- a/src/soca/Geometry/GeometryFortran.h +++ b/src/soca/Geometry/GeometryFortran.h @@ -16,6 +16,7 @@ namespace atlas { namespace field { class FieldSetImpl; + class FieldImpl; } namespace functionspace { class FunctionSpaceImpl; @@ -32,14 +33,14 @@ namespace soca { const eckit::Configuration * const &, const eckit::mpi::Comm *); - void soca_geo_lonlat_f90(const F90geom &, - atlas::field::FieldSetImpl *); - void soca_geo_set_atlas_functionspace_pointer_f90(const F90geom &, + void soca_geo_init_atlas_f90(const F90geom &, atlas::functionspace::FunctionSpaceImpl *, - atlas::functionspace::FunctionSpaceImpl *); - void soca_geo_to_fieldset_f90(const F90geom &, - atlas::field::FieldSetImpl *); - + atlas::field::FieldSetImpl *); + void soca_geo_get_mesh_size_f90(const F90geom &, int &, int&); + void soca_geo_gen_mesh_f90( + const F90geom &, + const int &, double[], double[], int[], int[], int[], int[], + const int &, int[]); void soca_geo_clone_f90(F90geom &, const F90geom &); void soca_geo_gridgen_f90(const F90geom &); void soca_geo_delete_f90(F90geom &); @@ -48,9 +49,6 @@ namespace soca { void soca_geo_get_num_levels_f90(const F90geom &, const oops::Variables &, const size_t &, size_t[]); void soca_geo_iterator_dimension_f90(const F90geom &, int &); - - void soca_geo_gridsize_f90(const F90geom &, const bool &, int &); - void soca_geo_gridlatlon_f90(const F90geom &, const bool &, const int &, double[], double[]); } } // namespace soca #endif // SOCA_GEOMETRY_GEOMETRYFORTRAN_H_ diff --git a/src/soca/Geometry/soca_geom.interface.F90 b/src/soca/Geometry/soca_geom.interface.F90 index 7f440037d..6157a413c 100644 --- a/src/soca/Geometry/soca_geom.interface.F90 +++ b/src/soca/Geometry/soca_geom.interface.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 2017-2021 UCAR +! (C) Copyright 2017-2023UCAR ! ! This software is licensed under the terms of the Apache Licence Version 2.0 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. @@ -7,13 +7,15 @@ !> C++ interfaces for soca_geom_mod::soca_geom module soca_geom_mod_c -use atlas_module, only: atlas_fieldset, atlas_functionspace_pointcloud +use atlas_module, only: atlas_fieldset, atlas_functionspace_NodeColumns, atlas_field use fckit_configuration_module, only: fckit_configuration use fckit_mpi_module, only: fckit_mpi_comm use iso_c_binding use oops_variables_mod, only: oops_variables use kinds, only: kind_real +use mpp_domains_mod, only : mpp_update_domains + ! soca modules use soca_geom_mod, only: soca_geom use soca_fields_metadata_mod, only : soca_field_metadata @@ -57,53 +59,23 @@ end subroutine soca_geo_setup_c ! -------------------------------------------------------------------------------------------------- -!> C++ interface for soca_geom_mod::soca_geom::set_atlas_lonlat() -subroutine soca_geo_lonlat_c(c_key_self, c_afieldset) bind(c,name='soca_geo_lonlat_f90') - integer(c_int), intent(in) :: c_key_self - type(c_ptr), intent(in), value :: c_afieldset - - type(soca_geom), pointer :: self - type(atlas_fieldset) :: afieldset - - call soca_geom_registry%get(c_key_self,self) - afieldset = atlas_fieldset(c_afieldset) - - call self%lonlat(afieldset) -end subroutine soca_geo_lonlat_c - - -! -------------------------------------------------------------------------------------------------- -!> C++ interface to get atlas functionspace pointr from soca_geom_mod::soca_geom -subroutine soca_geo_set_atlas_functionspace_pointer_c(c_key_self, c_functionspace, c_functionspaceIncHalo) & - bind(c,name='soca_geo_set_atlas_functionspace_pointer_f90') +!> C++ interface to get atlas functionspace pointr from soca_geom_mod::soca_geom, +! and then fill in the atlas fieldset with the required geometry fields +subroutine soca_geo_init_atlas_c(c_key_self, c_functionspace, c_fieldset) & + bind(c,name='soca_geo_init_atlas_f90') integer(c_int), intent(in) :: c_key_self - type(c_ptr), intent(in), value :: c_functionspace, c_functionspaceIncHalo + type(c_ptr), intent(in), value :: c_functionspace, c_fieldset type(soca_geom),pointer :: self call soca_geom_registry%get(c_key_self,self) + self%functionspace = atlas_functionspace_NodeColumns(c_functionspace) - self%functionspace = atlas_functionspace_pointcloud(c_functionspace) - self%functionspaceIncHalo = atlas_functionspace_pointcloud(c_functionspaceIncHalo) -end subroutine soca_geo_set_atlas_functionspace_pointer_c - - -! -------------------------------------------------------------------------------------------------- -!> C++ interface for soca_geom_mod::soca_geom::fill_atlas_fieldset() -subroutine soca_geo_to_fieldset_c(c_key_self, c_afieldset) & - & bind(c,name='soca_geo_to_fieldset_f90') - - integer(c_int), intent(in) :: c_key_self - type(c_ptr), value, intent(in) :: c_afieldset - - type(soca_geom), pointer :: self - type(atlas_fieldset) :: afieldset - - call soca_geom_registry%get(c_key_self,self) - afieldset = atlas_fieldset(c_afieldset) - - call self%to_fieldset(afieldset) -end subroutine soca_geo_to_fieldset_c + ! fill in the geometry fieldset + self%fieldset = atlas_fieldset(c_fieldset) + call self%init_fieldset() + +end subroutine soca_geo_init_atlas_c ! ------------------------------------------------------------------------------ @@ -215,56 +187,115 @@ subroutine soca_geo_get_num_levels_c(c_key_self, c_vars, c_levels_size, c_levels end subroutine soca_geo_get_num_levels_c ! ------------------------------------------------------------------------------ -!> Get the number of points valid in the local grid (skipping masked points) -subroutine soca_geo_gridsize_c(c_key_self, c_halo, c_size) & - bind(c, name='soca_geo_gridsize_f90') - integer(c_int), intent(in) :: c_key_self - logical(c_bool), intent(in) :: c_halo !< true if halo should be included in number of points - integer(c_int), intent(out):: c_size !< the resulting number of gridpoints +! Get the number of nodes and number of quadrilaterals that +! will be generated by a subsequent call to soca_geo_gen_mesh +subroutine soca_geo_get_mesh_size_c(c_key_self, c_nodes, c_quads) bind(c, name='soca_geo_get_mesh_size_f90') + integer(c_int), intent(in) :: c_key_self + integer(c_int), intent(out) :: c_nodes, c_quads type(soca_geom), pointer :: self + logical, allocatable :: valid_nodes(:,:), valid_cells(:,:) call soca_geom_registry%get(c_key_self, self) - if (c_halo) then - c_size = self%ngrid_halo_valid - else - c_size = self%ngrid - end if -end subroutine soca_geo_gridsize_c - -! ------------------------------------------------------------------------------ -!> Get the lat/lons for the h grid -!> If c_halo is true, then only the "valid" halo points are used -!> (i.e. duplicate halo points and invalid halo points are skipped) -subroutine soca_geo_gridlatlon_c(c_key_self, c_halo, c_size, & - c_lat, c_lon) bind(c, name='soca_geo_gridlatlon_f90') + + call self%mesh_valid_nodes_cells(valid_nodes, valid_cells) + c_nodes = count(valid_nodes) + c_quads = count(valid_cells) - integer(c_int), intent(in) :: c_key_self - logical(c_bool), intent(in) :: c_halo - integer(c_int), intent(in) :: c_size - real(c_double), intent(inout) :: c_lat(c_size), c_lon(c_size) +end subroutine +! ------------------------------------------------------------------------------ +! Generate the node and quadrilateral information that is needed +! by the C++ side of Geometry::Geometry() to create a connected mesh +! in atlas. +subroutine soca_geo_gen_mesh_c(c_key_self, c_nodes, c_lon, c_lat, c_ghosts, c_global_idx, c_remote_idx, c_partition, & + c_quad_nodes, c_quad_node_list) bind(c, name='soca_geo_gen_mesh_f90') + integer(c_int), intent(in) :: c_key_self + integer(c_int), intent(in) :: c_nodes, c_quad_nodes + integer(c_int), intent(inout) :: c_ghosts(c_nodes), c_global_idx(c_nodes), c_remote_idx(c_nodes), c_partition(c_nodes) + integer(c_int), intent(inout) :: c_quad_node_list(c_quad_nodes) + real(c_double), intent(inout) :: c_lon(c_nodes), c_lat(c_nodes) + + integer :: idx, i, j + integer :: nx, ny + integer, allocatable :: global_idx(:,:), local_idx(:,:), partition(:,:) + logical, allocatable :: valid_nodes(:,:), valid_cells(:,:) + type(soca_geom), pointer :: self - real(kind=kind_real), pointer :: lon(:,:) => null() !< field lon - real(kind=kind_real), pointer :: lat(:,:) => null() !< field lat call soca_geom_registry%get(c_key_self, self) - - ! TODO: re-enable the ability to get lat/lon for different grids? - ! For now just use h grid - lon => self%lon - lat => self%lat - - if (c_halo) then - ! get all lat/lon points, except for duplicate or invalid halo points - c_lat(:) = pack(self%lat, mask=self%valid_halo_mask) - c_lon(:) = pack(self%lon, mask=self%valid_halo_mask) - else - ! get all non-halo lat/lon points - c_lat(:) = pack(self%lat(self%isc:self%iec, self%jsc:self%jec), .true.) - c_lon(:) = pack(self%lon(self%isc:self%iec, self%jsc:self%jec), .true.) + + ! parameters pulled from grid + nx=self%domain%NIGLOBAL + ny=self%domain%NJGLOBAL + + ! find global/local indexes, and the PE owner of each grid point + ! (requiring a halo communications) + allocate(global_idx(self%isd:self%ied, self%jsd:self%jed)) + allocate(local_idx(self%isd:self%ied, self%jsd:self%jed)) + allocate(partition(self%isd:self%ied, self%jsd:self%jed)) + idx=0 ! local index + do j=self%jsc,self%jec + do i=self%isc, self%iec + idx = idx + 1 + local_idx(i,j) = idx + global_idx(i,j) = (j-1)*nx + i + partition(i,j) = self%f_comm%rank() + end do + end do + call mpp_update_domains(local_idx, self%Domain%mpp_domain) + call mpp_update_domains(global_idx, self%Domain%mpp_domain) + call mpp_update_domains(partition, self%Domain%mpp_domain) + + ! find which quads / vertices are we going to skip (in case of non cyclic or tripolar_fold special cases) + call self%mesh_valid_nodes_cells(valid_nodes, valid_cells) + + + ! fill in the node arrays to return to C++. + ! AND while were at it, save the atlas array to + ! soca fortran array mapping for use later by to_fieldset + ! and from_fieldset + c_ghosts = 1 + idx=1 + do j=self%jsc,self%jec+1 + do i=self%isc, self%iec+1 + if (.not. valid_nodes(i,j)) cycle + + ! fill in the node information arrays + c_lon(idx) = self%lon(i,j) + c_lat(idx) = self%lat(i,j) + if(j .le. self%jec .and. i .le. self%iec) then + c_ghosts(idx) = 0 + self%atlas_ij2idx(i,j) = idx + end if + c_global_idx(idx) = global_idx(i,j) + c_remote_idx(idx) = local_idx(i,j) + c_partition(idx) = partition(i,j) + + idx = idx + 1 + end do + end do + if (c_nodes /= idx-1) then + call abor1_ftn("ERROR: c_nodes != idx-1") end if -end subroutine + ! fill in the quad node list arrays + idx=1 + do j=self%jsc,self%jec + do i=self%isc, self%iec + if(.not. valid_cells(i,j)) cycle + + c_quad_node_list(idx ) = global_idx(i ,j ) + c_quad_node_list(idx+1) = global_idx(i ,j+1) + c_quad_node_list(idx+2) = global_idx(i+1,j+1) + c_quad_node_list(idx+3) = global_idx(i+1,j ) + + idx = idx + 4 + end do + end do + if (c_quad_nodes /= idx-1) then + call abor1_ftn("ERROR: c_quad_nodes != idx-1") + end if +end subroutine ! ------------------------------------------------------------------------------ end module soca_geom_mod_c diff --git a/src/soca/Geometry/soca_geom_mod.F90 b/src/soca/Geometry/soca_geom_mod.F90 index 48b880933..751b59262 100644 --- a/src/soca/Geometry/soca_geom_mod.F90 +++ b/src/soca/Geometry/soca_geom_mod.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 2017-2021 UCAR +! (C) Copyright 2017-2023 UCAR ! ! This software is licensed under the terms of the Apache Licence Version 2.0 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. @@ -7,8 +7,8 @@ !> Geometry module module soca_geom_mod -! jedi modules -use atlas_module, only: atlas_functionspace_pointcloud, atlas_fieldset, & + ! jedi modules +use atlas_module, only: atlas_functionspace_NodeColumns, atlas_fieldset, & atlas_field, atlas_real, atlas_integer, atlas_geometry, atlas_indexkdtree use fckit_configuration_module, only: fckit_configuration use fckit_mpi_module, only: fckit_mpi_comm @@ -24,7 +24,8 @@ module soca_geom_mod use MOM_domains, only : MOM_domain_type use MOM_EOS, only : EOS_type use mpp_domains_mod, only : mpp_get_compute_domain, mpp_get_data_domain, & - mpp_get_global_domain, mpp_update_domains + mpp_get_global_domain, mpp_update_domains, & + CYCLIC_GLOBAL_DOMAIN, FOLD_NORTH_EDGE ! soca modules use soca_fields_metadata_mod, only : soca_fields_metadata use soca_mom6, only: soca_mom6_config, soca_mom6_init, soca_geomdomain_init @@ -80,11 +81,6 @@ module soca_geom_mod integer :: iterator_dimension !> \} - integer :: ngrid !< number of non-halo gridpoints - integer :: ngrid_halo !< number of gridpoints, including halo - integer :: ngrid_halo_valid !< number of gridpoints, including halo, but - !! excluding duplicate or invalid halo points - !> \name grid latitude/longitude !! \{ real(kind=kind_real), allocatable, dimension(:) :: lonh !< cell center nominal longitude @@ -114,6 +110,8 @@ module soca_geom_mod !! \{ real(kind=kind_real), allocatable, dimension(:,:) :: sin_rot !< sine of rotation between logical grid north real(kind=kind_real), allocatable, dimension(:,:) :: cos_rot !< cosine of rotation between logical grid north + real(kind=kind_real), allocatable, dimension(:,:) :: dx !< cell x width (m) + real(kind=kind_real), allocatable, dimension(:,:) :: dy !< cell y width (m) real(kind=kind_real), allocatable, dimension(:,:) :: cell_area !< cell area (m^2) real(kind=kind_real), allocatable, dimension(:,:) :: rossby_radius !< rossby radius (m) at the gridpoint real(kind=kind_real), allocatable, dimension(:,:) :: distance_from_coast !< distance to closest land grid point (m) @@ -130,9 +128,11 @@ module soca_geom_mod character(len=:), allocatable :: rossby_file !< filename of rossby radius input file (if used) type(fckit_mpi_comm) :: f_comm !< MPI communicator - type(atlas_functionspace_pointcloud) :: functionspace - type(atlas_functionspace_pointcloud) :: functionspaceInchalo + !> mesh parameters + type(atlas_functionspace_NodeColumns) :: functionspace + integer, allocatable :: atlas_ij2idx(:,:) + type(atlas_fieldset) :: fieldset !< the geom fields (area, mask, etc) contains @@ -143,11 +143,8 @@ module soca_geom_mod !> \copybrief soca_geom_end \see soca_geom_end procedure :: end => soca_geom_end - !> \copybrief soca_geom_set_atlas_lonlat \see soca_geom_set_atlas_lonlat - procedure :: lonlat => soca_geom_lonlat - !> \copybrief soca_geom_fill_atlas_fieldset \see soca_geom_fill_atlas_fieldset - procedure :: to_fieldset => soca_geom_to_fieldset + procedure :: init_fieldset => soca_geom_init_fieldset !> \copybrief soca_geom_clone \see soca_geom_clone procedure :: clone => soca_geom_clone @@ -158,15 +155,11 @@ module soca_geom_mod !> \copybrief soca_geom_thickness2depth \see soca_geom_thickness2depth procedure :: thickness2depth => soca_geom_thickness2depth - !> \copybrief soca_geom_struct2atlas \see soca_geom_struct2atlas - procedure :: struct2atlas => soca_geom_struct2atlas - - !> \copybrief soca_geom_atlas2struct \ see soca_geom_atlas2struct - procedure :: atlas2struct => soca_geom_atlas2struct - !> \copybrief soca_geom_write \see soca_geom_write procedure :: write => soca_geom_write + !> \copybrief soca_geom_mesh_valid_nodes_cells \see soca_geom_mesh_valid_nodes_cells + procedure :: mesh_valid_nodes_cells => soca_geom_mesh_valid_nodes_cells end type soca_geom ! ------------------------------------------------------------------------------ @@ -219,6 +212,8 @@ subroutine soca_geom_init(self, f_conf, f_comm) call mpp_update_domains(self%mask2d, self%Domain%mpp_domain) call mpp_update_domains(self%mask2du, self%Domain%mpp_domain) call mpp_update_domains(self%mask2dv, self%Domain%mpp_domain) + call mpp_update_domains(self%dx, self%Domain%mpp_domain) + call mpp_update_domains(self%dy, self%Domain%mpp_domain) call mpp_update_domains(self%cell_area, self%Domain%mpp_domain) call mpp_update_domains(self%rossby_radius, self%Domain%mpp_domain) call mpp_update_domains(self%distance_from_coast, self%Domain%mpp_domain) @@ -262,6 +257,8 @@ subroutine soca_geom_end(self) if (allocated(self%mask2d)) deallocate(self%mask2d) if (allocated(self%mask2du)) deallocate(self%mask2du) if (allocated(self%mask2dv)) deallocate(self%mask2dv) + if (allocated(self%dx)) deallocate(self%dx) + if (allocated(self%dy)) deallocate(self%dy) if (allocated(self%cell_area)) deallocate(self%cell_area) if (allocated(self%rossby_radius)) deallocate(self%rossby_radius) if (allocated(self%distance_from_coast)) deallocate(self%distance_from_coast) @@ -270,99 +267,79 @@ subroutine soca_geom_end(self) if (allocated(self%valid_halo_mask)) deallocate(self%valid_halo_mask) nullify(self%Domain) call self%functionspace%final() - call self%functionspaceIncHalo%final() end subroutine soca_geom_end ! -------------------------------------------------------------------------------------------------- -!> Set ATLAS lonlat fieldset +!> Fill ATLAS fieldset !! !! \related soca_geom_mod::soca_geom -subroutine soca_geom_lonlat(self, afieldset) +subroutine soca_geom_init_fieldset(self) class(soca_geom), intent(inout) :: self - type(atlas_fieldset), intent(inout) :: afieldset - - real(kind_real), pointer :: real_ptr(:,:) - type(atlas_field) :: afield - - ! Create lon/lat field - afield = atlas_field(name="lonlat", kind=atlas_real(kind_real), shape=(/2,self%ngrid/)) - call afield%data(real_ptr) - real_ptr(1,:) = pack(self%lon(self%isc:self%iec,self%jsc:self%jec),.true.) - real_ptr(2,:) = pack(self%lat(self%isc:self%iec,self%jsc:self%jec),.true.) - call afieldset%add(afield) - call afield%final() - afield = atlas_field(name="lonlat_inc_halos", kind=atlas_real(kind_real), shape=(/2,self%ngrid_halo_valid/)) - call afield%data(real_ptr) - real_ptr(1,:) = pack(self%lon, self%valid_halo_mask) - real_ptr(2,:) = pack(self%lat, self%valid_halo_mask) - call afieldset%add(afield) - call afield%final() + integer :: i, j, n, jz + type(atlas_field) :: fArea, fInterpMask, fVertCoord, fGmask, fOwned, fRossby + real(kind=kind_real), pointer :: vArea(:,:), vInterpMask(:,:), vVertCoord(:,:), vRossby(:,:) + integer, pointer :: vGmask(:,:), vOwned(:,:) -end subroutine soca_geom_lonlat - - -! -------------------------------------------------------------------------------------------------- -!> Fill ATLAS fieldset -!! -!! \related soca_geom_mod::soca_geom -subroutine soca_geom_to_fieldset(self, afieldset) - class(soca_geom), intent(inout) :: self - type(atlas_fieldset), intent(inout) :: afieldset - - integer :: i, jz, ngrid - integer, pointer :: int_ptr(:,:) - real(kind=kind_real), pointer :: real_ptr(:,:) - integer, allocatable :: hmask(:,:) - type(atlas_field) :: afield - - ngrid = (self%ied-self%isd+1)*(self%jed-self%jsd+1) - - ! Add area - afield = self%functionspaceInchalo%create_field(name='area', kind=atlas_real(kind_real), levels=1) - call afield%data(real_ptr) - real_ptr(1,:) = pack(self%cell_area, self%valid_halo_mask) - call afieldset%add(afield) - call afield%final() - - ! Add vertical unit - afield = self%functionspaceInchalo%create_field(name='vunit', kind=atlas_real(kind_real), levels=self%nzo) - call afield%data(real_ptr) - do jz=1,self%nzo - real_ptr(jz,:) = real(jz, kind_real) + ! create fields, get pointers to their data + fArea = self%functionspace%create_field(name='area', kind=atlas_real(kind_real), levels=1) + call self%fieldset%add(fArea) + call fArea%data(vArea) + + fInterpMask = self%functionspace%create_field(name='interp_mask', kind=atlas_real(kind_real), levels=1) + call self%fieldset%add(fInterpMask) + call fInterpMask%data(vInterpMask) + + fVertCoord = self%functionspace%create_field(name='vert_coord', kind=atlas_real(kind_real), levels=self%nzo) + call self%fieldset%add(fVertCoord) + call fVertCoord%data(vVertCoord) + + fGmask = self%functionspace%create_field(name='gmask', kind=atlas_integer(kind(0)), levels=self%nzo) + call self%fieldset%add(fGmask) + call fGmask%data(vGmask) + + fOwned = self%functionspace%create_field(name='owned', kind=atlas_integer(kind(0)), levels=1) + call self%fieldset%add(fOwned) + call fOwned%data(vOwned) + + fRossby = self%functionspace%create_field(name='rossby_radius', kind=atlas_real(kind_real), levels=1) + call self%fieldset%add(fRossby) + call fRossby%data(vRossby) + + ! set the data + vOwned = 0 ! need to set to 0, it's the only one that doesn't get halo update + do j=self%jsc,self%jec + do i=self%isc,self%iec + n = self%atlas_ij2idx(i,j) + vArea(1,n) = self%cell_area(i,j) + vInterpMask(1,n) = self%mask2d(i,j) + vGmask(:, n) = int(self%mask2d(i,j)) + vOwned(1, n) = 1 + vRossby(1, n) = self%rossby_radius(i,j) + end do end do - call afieldset%add(afield) - call afield%final() - - ! Add geographical mask - afield = self%functionspaceInchalo%create_field(name='gmask', kind=atlas_integer(kind(0)), levels=self%nzo) - call afield%data(int_ptr) do jz=1,self%nzo - int_ptr(jz,:) = int(pack(self%mask2d, self%valid_halo_mask)) + vVertCoord(jz,:) = real(jz, kind_real) end do - call afieldset%add(afield) - call afield%final() - ! Add halo mask - afield = self%functionspaceInchalo%create_field(name='hmask', kind=atlas_integer(kind(0)), levels=1) - allocate(hmask(self%isd:self%ied, self%jsd:self%jed)) - hmask = 0 - hmask(self%isc:self%iec, self%jsc:self%jec) = 1 - call afield%data(int_ptr) - int_ptr(1,:) = pack(hmask, self%valid_halo_mask) - call afieldset%add(afield) - call afield%final() + ! halo exchanges for some of the fields + call fGmask%halo_exchange() + call fInterpMask%halo_exchange() + call fArea%halo_exchange() + call fVertCoord%halo_exchange() + call fRossby%halo_exchange() - ! Add interpolation mask - afield = self%functionspaceInchalo%create_field(name='interp_mask', kind=atlas_real(kind_real), levels=1) - call afield%data(real_ptr) - real_ptr(1,:) = pack(self%mask2d, self%valid_halo_mask) - call afieldset%add(afield) - call afield%final() + ! done, cleanup + call fArea%final() + call fInterpMask%final() + call fVertCoord%final() + call fGmask%final() + call fOwned%final() + call fRossby%final() -end subroutine soca_geom_to_fieldset +end subroutine soca_geom_init_fieldset ! ------------------------------------------------------------------------------ @@ -403,11 +380,13 @@ subroutine soca_geom_clone(self, other) self%mask2d = other%mask2d self%mask2du = other%mask2du self%mask2dv = other%mask2dv + self%dx = other%dx + self%dy = other%dy self%cell_area = other%cell_area self%rossby_radius = other%rossby_radius self%distance_from_coast = other%distance_from_coast self%h = other%h - self%valid_halo_mask = other%valid_halo_mask + self%atlas_ij2idx = other%atlas_ij2idx call self%fields_metadata%clone(other%fields_metadata) end subroutine soca_geom_clone @@ -446,6 +425,8 @@ subroutine soca_geom_gridgen(self) self%mask2d = mom6_config%grid%mask2dT self%mask2du = mom6_config%grid%mask2dCu self%mask2dv = mom6_config%grid%mask2dCv + self%dx = mom6_config%grid%dxT + self%dy = mom6_config%grid%dyT self%cell_area = mom6_config%grid%areaT self%h = mom6_config%MOM_CSp%h @@ -497,8 +478,6 @@ subroutine soca_geom_allocate(self) call soca_geom_get_domain_indices(self, "global", self%isg, self%ieg, self%jsg, self%jeg) call soca_geom_get_domain_indices(self, "compute", self%iscl, self%iecl, self%jscl, self%jecl, local=.true.) call soca_geom_get_domain_indices(self, "data", self%isdl, self%iedl, self%jsdl, self%jedl, local=.true.) - self%ngrid = (self%iec-self%isc+1) * (self%jec-self%jsc+1) - self%ngrid_halo = (self%ied-self%isd+1) * (self%jed-self%jsd+1) ! Allocate arrays on compute domain ! NOTE, sometimes MOM6 doesn't use all the halo points, we set @@ -522,10 +501,14 @@ subroutine soca_geom_allocate(self) allocate(self%mask2du(isd:ied,jsd:jed)); self%mask2du = 0.0_kind_real allocate(self%mask2dv(isd:ied,jsd:jed)); self%mask2dv = 0.0_kind_real + allocate(self%dx(isd:ied,jsd:jed)); self%dx = 0.0_kind_real + allocate(self%dy(isd:ied,jsd:jed)); self%dy = 0.0_kind_real allocate(self%cell_area(isd:ied,jsd:jed)); self%cell_area = 0.0_kind_real allocate(self%rossby_radius(isd:ied,jsd:jed)); self%rossby_radius = 0.0_kind_real allocate(self%distance_from_coast(isd:ied,jsd:jed)); self%distance_from_coast = 0.0_kind_real allocate(self%h(isd:ied,jsd:jed,1:nzo)); self%h = 0.0_kind_real + + allocate(self%atlas_ij2idx(isd:ied,jsd:jed)); self%atlas_ij2idx = -1 allocate(self%valid_halo_mask(isd:ied,jsd:jed));self%valid_halo_mask = .true. @@ -722,6 +705,16 @@ subroutine soca_geom_write(self) &'cos_rot', & &self%cos_rot(:,:), & domain=self%Domain%mpp_domain) + idr_geom = register_restart_field(geom_restart, & + &self%geom_grid_file, & + &'dx', & + &self%dx(:,:), & + domain=self%Domain%mpp_domain) + idr_geom = register_restart_field(geom_restart, & + &self%geom_grid_file, & + &'dy', & + &self%dy(:,:), & + domain=self%Domain%mpp_domain) idr_geom = register_restart_field(geom_restart, & &self%geom_grid_file, & &'area', & @@ -859,6 +852,16 @@ subroutine soca_geom_read(self) &'cos_rot', & &self%cos_rot(:,:), & domain=self%Domain%mpp_domain) + idr_geom = register_restart_field(geom_restart, & + &self%geom_grid_file, & + &'dx', & + &self%dx(:,:), & + domain=self%Domain%mpp_domain) + idr_geom = register_restart_field(geom_restart, & + &self%geom_grid_file, & + &'dy', & + &self%dy(:,:), & + domain=self%Domain%mpp_domain) idr_geom = register_restart_field(geom_restart, & &self%geom_grid_file, & &'area', & @@ -965,48 +968,105 @@ subroutine soca_geom_thickness2depth(self, h, z) end do end subroutine soca_geom_thickness2depth - -! ------------------------------------------------------------------------------ -!> Copy a structured field into an ATLAS fieldset -!! -!! \related soca_geom_mod::soca_geom -subroutine soca_geom_struct2atlas(self, dx_struct, dx_atlas) - class(soca_geom), intent(in ) :: self - real(kind=kind_real), intent(in ) :: dx_struct(:,:) - type(fieldset_type), intent(out) :: dx_atlas - - real(kind_real), pointer :: real_ptr(:,:) - type(atlas_field) :: afield - - dx_atlas = atlas_fieldset() - afield = self%functionspaceInchalo%create_field('var',kind=atlas_real(kind_real),levels=1) - call dx_atlas%add(afield) - call afield%data(real_ptr) - real_ptr(1,:) = pack(dx_struct, self%valid_halo_mask) - call afield%final() - -end subroutine soca_geom_struct2atlas - - ! ------------------------------------------------------------------------------ -!> Copy a structured field from an ATLAS fieldset -!! -!! \related soca_geom_mod::soca_geom -subroutine soca_geom_atlas2struct(self, dx_struct, dx_atlas) - class(soca_geom), intent(in ) :: self - real(kind=kind_real), intent(inout) :: dx_struct(:,:) - type(fieldset_type), intent(inout) :: dx_atlas +! Get a 2d array of the valid nodes / cells that are to be used on this PE +! for ATLAS mesh generation. +! We assume that owned cells (quads) are generated north and east of the PE's owned nodes (vertices) +! NOTE: this code assumes that a regional domain does NOT make use of halos on the boundary. +! We currently have our regional domain surrounded by "virtual land", so this is currently a correct +! assumption. When we get around to removing that "virtual land", and intend to populate the +! halo with a boundary conditions, the grid will need to be constructed slightly differently. +subroutine soca_geom_mesh_valid_nodes_cells(self, nodes, cells) + class(soca_geom), intent(inout) :: self + logical, allocatable, intent(out) :: nodes(:,:), cells(:,:) + + integer :: i, j, start_i + logical :: tripolar, cyclic, regional + + allocate(nodes(self%isc:self%iec+1, self%jsc:self%jec+1)) + allocate(cells(self%isc:self%iec, self%jsc:self%jec)) + + nodes = .true. + cells = .true. + + tripolar = iand(self%domain%Y_FLAGS, FOLD_NORTH_EDGE) /= 0 + cyclic = iand(self%domain%X_FLAGS, CYCLIC_GLOBAL_DOMAIN) /= 0 + regional = iand(self%domain%X_FLAGS, CYCLIC_GLOBAL_DOMAIN) == 0 .and. & + iand(self%domain%Y_FLAGS, CYCLIC_GLOBAL_DOMAIN) == 0 + + ! ------------------------------------------------------------------------------------- + ! we need to mask out cells and/or nodes for 3 special cases. + ! Remove halo points that are otherwise going to be duplicated in the node list for the the PEs, + ! or, for regional (for now) remove unowned halo points at the domain boundary. + ! ------------------------------------------------------------------------------------- + + ! The grid is tripolar, and we are a PE at the northern edge + ! ------------------------------------------------------------------------------------- + if(tripolar .and. self%jec == self%domain%NJGLOBAL) then + ! (start_i is the x index where we start removing nodes) + ! Remove all nodes in the eastern half. + start_i = max(self%domain%NIGLOBAL/2, self%isc) + + ! additionally, this PE crosses the E/W midpoint, remove all extra nodes at the north for this PE + if (self%isc <= self%domain%NIGLOBAL/2 .and. self%iec > self%domain%NIGLOBAL/2) then + start_i = self%isc + end if + + ! remove some nodes + do i=start_i, self%iec+1 + nodes(i, self%jec+1) = .false. + end do - real(kind_real), pointer :: real_ptr(:,:) - type(atlas_field) :: afield + ! remove some cells + do i=self%isc, self%iec + if (i >= self%domain%NIGLOBAL/2) then + cells(i, self%jec) = .false. + end if + end do + end if + + ! the grid is cyclic in the E/W direction and we are a PE at the eastern edge + ! ------------------------------------------------------------------------------------- + if (cyclic .and. self%isc == 1 .and. self%iec == self%domain%NIGLOBAL) then + ! cyclic boundaries, and this PE spans entire width. + ! Remove all nodes on the easternmost column. + do j=self%jsc, self%jec+1 + nodes(self%iec+1, j) = .false. + end do + end if - afield = dx_atlas%field('var') - call afield%data(real_ptr) - dx_struct = unpack(real_ptr(1,:), self%valid_halo_mask, 0.0_kind_real) + ! We are a regional grid + ! NOTE: this logic should change at some point so that there ARE halos around the + ! outer boundary + ! ------------------------------------------------------------------------------------- + if (regional) then + ! are we are a PE at the top edge? + if(self%jec == self%domain%NJGLOBAL) then + ! remove nodes on top + do i=self%isc,self%iec+1 + nodes(i, self%jec+1) = .false. + end do + ! remove cells on top + do i=self%isc, self%iec + cells(i, self%jec) = .false. + end do + end if + + ! are we a PE at the right edge? + if(self%iec == self%domain%NIGLOBAL) then + ! remove nodes on right + do j=self%jsc,self%jec+1 + nodes(self%iec+1, j) = .false. + end do + ! remove cells on right + do j=self%jsc, self%jec + cells(self%iec, j) = .false. + end do + end if - call afield%final() + end if -end subroutine soca_geom_atlas2struct +end subroutine ! ------------------------------------------------------------------------------ !> Examine the halo gridpoints to determine which ones are non-duplicate and valid @@ -1056,9 +1116,6 @@ subroutine soca_geom_find_invalid_halo(self) end do end do outer - ! count the number of points - self%ngrid_halo_valid = count(self%valid_halo_mask) - end subroutine soca_geom_find_invalid_halo ! ------------------------------------------------------------------------------ diff --git a/src/soca/Increment/Increment.cc b/src/soca/Increment/Increment.cc index 895cc4f1d..ad501d492 100755 --- a/src/soca/Increment/Increment.cc +++ b/src/soca/Increment/Increment.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 2017-2022 UCAR + * (C) Copyright 2017-2023 UCAR * * This software is licensed under the terms of the Apache Licence Version 2.0 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. @@ -358,13 +358,7 @@ namespace soca { void Increment::toFieldSet(atlas::FieldSet &fs) const { soca_increment_to_fieldset_f90(toFortran(), vars_, fs.get()); - } - -// ----------------------------------------------------------------------------- - - void Increment::toFieldSetAD(const atlas::FieldSet &fs) { - if (fs.empty()) return; - soca_increment_to_fieldset_ad_f90(toFortran(), vars_, fs.get()); + geom_.functionSpace().haloExchange(fs); } // ----------------------------------------------------------------------------- diff --git a/src/soca/Increment/Increment.h b/src/soca/Increment/Increment.h index 4c4df95df..0d25add8a 100644 --- a/src/soca/Increment/Increment.h +++ b/src/soca/Increment/Increment.h @@ -1,6 +1,6 @@ /* * (C) Copyright 2009-2016 ECMWF. - * (C) Copyright 2017-2022 UCAR. + * (C) Copyright 2017-2023 UCAR. * * This software is licensed under the terms of the Apache Licence Version 2.0 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. @@ -90,7 +90,6 @@ namespace soca { /// ATLAS void toFieldSet(atlas::FieldSet &) const; - void toFieldSetAD(const atlas::FieldSet &); void fromFieldSet(const atlas::FieldSet &); /// I/O and diagnostics diff --git a/src/soca/Increment/IncrementFortran.h b/src/soca/Increment/IncrementFortran.h index 6b09e5cce..2bc722ddd 100644 --- a/src/soca/Increment/IncrementFortran.h +++ b/src/soca/Increment/IncrementFortran.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 2020-2022 UCAR + * (C) Copyright 2020-2023 UCAR * * This software is licensed under the terms of the Apache Licence Version 2.0 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. @@ -60,9 +60,6 @@ namespace soca { void soca_increment_to_fieldset_f90(const F90flds &, const oops::Variables &, atlas::field::FieldSetImpl *); - void soca_increment_to_fieldset_ad_f90(const F90flds &, - const oops::Variables &, - const atlas::field::FieldSetImpl *); void soca_increment_from_fieldset_f90(const F90flds &, const oops::Variables &, const atlas::field::FieldSetImpl *); diff --git a/src/soca/Increment/soca_increment.interface.F90 b/src/soca/Increment/soca_increment.interface.F90 index 1112d7500..310d8c531 100644 --- a/src/soca/Increment/soca_increment.interface.F90 +++ b/src/soca/Increment/soca_increment.interface.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 2020-2022 UCAR +! (C) Copyright 2020-2023 UCAR ! ! This software is licensed under the terms of the Apache Licence Version 2.0 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. @@ -633,24 +633,5 @@ subroutine soca_increment_vert_scales_c(c_key_self, c_vert) bind(c,name='soca_in end subroutine soca_increment_vert_scales_c -! ------------------------------------------------------------------------------ -!> C++ interface for Increment version of soca_field_mod::soca_field::get_fieldset_ad() -subroutine soca_increment_to_fieldset_ad_c(c_key_self, c_vars, c_fieldset) & - bind (c, name='soca_increment_to_fieldset_ad_f90') - integer(c_int), intent(in) :: c_key_self - type(c_ptr), value, intent(in) :: c_vars - type(c_ptr), value, intent(in) :: c_fieldset - - type(soca_increment), pointer :: self - type(oops_variables) :: vars - type(atlas_fieldset) :: afieldset - - call soca_increment_registry%get(c_key_self, self) - vars = oops_variables(c_vars) - afieldset = atlas_fieldset(c_fieldset) - - call self%to_fieldset_ad(vars, afieldset) -end subroutine - ! ------------------------------------------------------------------------------ end module diff --git a/src/soca/Increment/soca_increment_mod.F90 b/src/soca/Increment/soca_increment_mod.F90 index c9a4f3327..0e8841c18 100644 --- a/src/soca/Increment/soca_increment_mod.F90 +++ b/src/soca/Increment/soca_increment_mod.F90 @@ -349,21 +349,39 @@ subroutine soca_horiz_scales(self, f_conf) type(fckit_configuration), value, intent(in):: f_conf !< Configuration integer :: i, jz - real(kind=kind_real) :: r_mult, r_min_grid, r_min + type(fckit_configuration) :: subconf + real(kind=kind_real) :: r_base, r_mult, r_min_grid, r_min, r_max + + ! NOTE, this is duplicated code also present in soca_covariance_mod and possibly elsewhere. + ! This does not belong in soca_increment_mod and should be moved out + + ! rh is calculated as follows : + ! 1) rh = "base value" + rossby_radius * "rossby mult" + ! 2) minimum value of "min grid mult" * grid_size is imposed + ! 3) min/max are imposed based on "min value" and "max value" + ! 4) converted from a gaussian sigma to Gaspari-Cohn cutoff distance + do i=1,size(self%fields) + ! get parameters for correlation lengths + call f_conf%get_or_die(trim(self%fields(i)%name), subconf) + if (.not. subconf%get("base value", r_base)) r_base = 0.0 + if (.not. subconf%get("rossby mult", r_mult)) r_mult = 0.0 + if (.not. subconf%get("min grid mult", r_min_grid)) r_min_grid = 1.0 + if (.not. subconf%get("min value", r_min)) r_min = 0.0 + if (.not. subconf%get("max value", r_max)) r_max = huge(r_max) + + self%fields(i)%val(:,:,1) = r_base + r_mult*self%geom%rossby_radius(:,:) + if (r_min_grid .gt. 0.0) then + self%fields(i)%val(:,:,1) = max(self%fields(i)%val(:,:,1), sqrt(self%geom%cell_area)*r_min_grid) + end if + self%fields(i)%val(:,:,1) = min(r_max, self%fields(i)%val(:,:,1)) + self%fields(i)%val(:,:,1) = max(r_min, self%fields(i)%val(:,:,1)) + self%fields(i)%val(:,:,1) = 3.57_kind_real * self%fields(i)%val(:,:,1) ! convert from gaussian sigma to + ! Gaspari-Cohn half width - ! compute scales cor_rh = max( r_mult * rossby radius, max( r_min_grid * dx, r_min ) ) - do i=1,size(self%fields) - do jz=1,self%fields(i)%nz - call f_conf%get_or_die(trim(self%fields(i)%name//".rossby mult"), r_mult) - call f_conf%get_or_die(trim(self%fields(i)%name//".min grid mult"), r_min_grid) - if ( .not. f_conf%get(trim(self%fields(i)%name//".min"), r_min) ) then - r_min = 0.0_kind_real - end if - self%fields(i)%val(:,:,jz) = 3.57_kind_real*self%geom%mask2d(:,:)* & - max(r_mult*self%geom%rossby_radius(:,:), & - max(r_min_grid*sqrt(self%geom%cell_area(:,:)), & - r_min)) + do jz=2,self%fields(i)%nz + self%fields(i)%val(:,:,jz) = self%fields(i)%val(:,:,1) end do + end do end subroutine soca_horiz_scales diff --git a/src/soca/LinearVariableChange/Balance/soca_balance_mod.F90 b/src/soca/LinearVariableChange/Balance/soca_balance_mod.F90 index 664686fbe..3f735f6c0 100644 --- a/src/soca/LinearVariableChange/Balance/soca_balance_mod.F90 +++ b/src/soca/LinearVariableChange/Balance/soca_balance_mod.F90 @@ -161,6 +161,7 @@ subroutine soca_balance_setup(self, f_conf, traj, geom) self%ksshts%ksshs=0.0_kind_real do i = isc, iec do j = jsc, jec + if (geom%mask2d(i,j) == 0.0) cycle do k = 1, nl call soca_steric_jacobian (jac, & tocn%val(i,j,k), & diff --git a/src/soca/LinearVariableChange/HorizFilt/soca_horizfilt_mod.F90 b/src/soca/LinearVariableChange/HorizFilt/soca_horizfilt_mod.F90 index 5a9b1dac6..b8c176799 100644 --- a/src/soca/LinearVariableChange/HorizFilt/soca_horizfilt_mod.F90 +++ b/src/soca/LinearVariableChange/HorizFilt/soca_horizfilt_mod.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 2017-2021 UCAR. +! (C) Copyright 2017-2023 UCAR. ! ! This software is licensed under the terms of the Apache Licence Version 2.0 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. @@ -109,11 +109,6 @@ subroutine soca_horizfilt_setup(self, f_conf, geom, traj, vars) do i = self%isc, self%iec do ii = -1,1 do jj = -1,1 - ! if the adjacent cell is an invalid halo, skip it - if (.not. geom%valid_halo_mask(i+ii, j+jj)) then - dist(ii, jj) = 0.0 - cycle - end if ! Great circle distance if(self%scale_dist > 0) then diff --git a/src/soca/LinearVariableChange/LinearVariableChange.cc b/src/soca/LinearVariableChange/LinearVariableChange.cc index 59f8319a8..f4ef49436 100644 --- a/src/soca/LinearVariableChange/LinearVariableChange.cc +++ b/src/soca/LinearVariableChange/LinearVariableChange.cc @@ -23,8 +23,10 @@ namespace soca { // ----------------------------------------------------------------------------- LinearVariableChange::LinearVariableChange(const Geometry & geom, - const Parameters_ & params) - : geom_(geom), params_(params), linVarChas_() {} + const eckit::Configuration & config) + : geom_(geom), params_(), linVarChas_() { + params_.deserialize(config); +} // ----------------------------------------------------------------------------- diff --git a/src/soca/LinearVariableChange/LinearVariableChange.h b/src/soca/LinearVariableChange/LinearVariableChange.h index 4993b52a8..d1ef99409 100644 --- a/src/soca/LinearVariableChange/LinearVariableChange.h +++ b/src/soca/LinearVariableChange/LinearVariableChange.h @@ -52,7 +52,7 @@ class LinearVariableChange : public util::Printable { typedef typename LinVarChaVec_::const_iterator icst_; typedef typename LinVarChaVec_::const_reverse_iterator ircst_; - explicit LinearVariableChange(const Geometry &, const Parameters_ &); + explicit LinearVariableChange(const Geometry &, const eckit::Configuration &); ~LinearVariableChange(); void changeVarTraj(const State &, const oops::Variables &); diff --git a/src/soca/Model/mom6solo/Model.cc b/src/soca/Model/mom6solo/Model.cc index e1e35ed82..38d94a56f 100644 --- a/src/soca/Model/mom6solo/Model.cc +++ b/src/soca/Model/mom6solo/Model.cc @@ -31,11 +31,9 @@ namespace soca { : keyConfig_(0), tstep_(0), geom_(resol), - vars_(model, "model variables"), setup_mom6_(true) { Log::trace() << "Model::Model" << std::endl; - Log::trace() << "Model vars: " << vars_ << std::endl; tstep_ = util::Duration(model.getString("tstep")); setup_mom6_ = model.getBool("setup_mom6", true); const eckit::Configuration * configc = &model; diff --git a/src/soca/Model/mom6solo/Model.h b/src/soca/Model/mom6solo/Model.h index de320f6d4..c12989812 100644 --- a/src/soca/Model/mom6solo/Model.h +++ b/src/soca/Model/mom6solo/Model.h @@ -64,7 +64,6 @@ namespace soca { /// Utilities const util::Duration & timeResolution() const {return tstep_;} - const oops::Variables & variables() const {return vars_;} private: void print(std::ostream &) const; @@ -72,7 +71,6 @@ namespace soca { util::Duration tstep_; bool setup_mom6_; const Geometry & geom_; - const oops::Variables vars_; }; // ----------------------------------------------------------------------------- diff --git a/src/soca/Model/ufs/ModelUFS.cc b/src/soca/Model/ufs/ModelUFS.cc index 7adff67ca..762827cc1 100644 --- a/src/soca/Model/ufs/ModelUFS.cc +++ b/src/soca/Model/ufs/ModelUFS.cc @@ -11,6 +11,8 @@ #include "oops/util/DateTime.h" #include "oops/util/Logger.h" +#include "oops/util/parameters/Parameters.h" +#include "oops/util/parameters/RequiredParameter.h" #include "ModelUFS.interface.h" @@ -21,19 +23,34 @@ namespace soca { // ------------------------------------------------------------------------------------------------- +// Options taken by ModelUFS +class ModelUFSParameters : public oops::Parameters { + OOPS_CONCRETE_PARAMETERS(ModelUFSParameters, Parameters) + + public: + oops::RequiredParameter modelVariables{ "model variables", this}; + oops::RequiredParameter tstep{ "tstep", this}; + oops::RequiredParameter ufsRunDirectory{ "ufs_run_directory", this}; +}; +// ------------------------------------------------------------------------------------------------- static oops::interface::ModelMaker makermodel_("UFS"); // ------------------------------------------------------------------------------------------------- -ModelUFS::ModelUFS(const Geometry & resol, const Parameters_ & params) - : keyConfig_(0), tstep_(0), geom_(resol), vars_(params.modelVariables) { +ModelUFS::ModelUFS(const Geometry & resol, const eckit::Configuration & config) + : keyConfig_(0), tstep_(0), geom_(resol), vars_() { char tmpdir_[10000]; oops::Log::trace() << "ModelUFS::ModelUFS starting" << std::endl; getcwd(tmpdir_, 10000); + + ModelUFSParameters params; + params.deserialize(config); + vars_ = params.modelVariables; tstep_ = params.tstep; strcpy(ufsdir_, params.ufsRunDirectory.value().c_str()); chdir(ufsdir_); - soca_ufs_create_f90(keyConfig_, params.toConfiguration(), geom_.toFortran()); - oops::Log::trace() << "ModelUFS::ModelUFS done" << std::endl; + soca_ufs_create_f90(keyConfig_, config, geom_.toFortran()); + chdir(tmpdir_); + oops::Log::trace() << "ModelUFS::ModelUFS done" << std::endl; } // ------------------------------------------------------------------------------------------------- ModelUFS::~ModelUFS() { diff --git a/src/soca/Model/ufs/ModelUFS.h b/src/soca/Model/ufs/ModelUFS.h index e1d3cc303..f23d213f7 100644 --- a/src/soca/Model/ufs/ModelUFS.h +++ b/src/soca/Model/ufs/ModelUFS.h @@ -10,16 +10,13 @@ #include #include -#include "oops/base/ParameterTraitsVariables.h" +#include "eckit/config/Configuration.h" + #include "oops/base/Variables.h" #include "oops/generic/ModelBase.h" #include "oops/interface/ModelBase.h" #include "oops/util/Duration.h" #include "oops/util/ObjectCounter.h" -#include "oops/util/parameters/OptionalParameter.h" -#include "oops/util/parameters/Parameter.h" -#include "oops/util/parameters/Parameters.h" -#include "oops/util/parameters/RequiredParameter.h" #include "oops/util/Printable.h" #include "soca/Geometry/Geometry.h" @@ -36,28 +33,15 @@ namespace soca { class Increment; class State; -// ------------------------------------------------------------------------------------------------- -// ------------------------------------------------------------------------------------------------- -/// Options taken by ModelUFS - class ModelUFSParameters : public oops::ModelParametersBase { - OOPS_CONCRETE_PARAMETERS(ModelUFSParameters, ModelParametersBase) - - public: - oops::RequiredParameter modelVariables{ "model variables", this}; - oops::RequiredParameter tstep{ "tstep", this}; - oops::RequiredParameter ufsRunDirectory{ "ufs_run_directory", this}; - }; - // ------------------------------------------------------------------------------------------------- // ------------------------------------------------------------------------------------------------- class ModelUFS: public oops::interface::ModelBase, private util::ObjectCounter { public: - typedef ModelUFSParameters Parameters_; static const std::string classname() {return "soca::ModelUFS";} - ModelUFS(const Geometry &, const Parameters_ &); + ModelUFS(const Geometry &, const eckit::Configuration &); ~ModelUFS(); void initialize(State &) const; @@ -75,7 +59,7 @@ class ModelUFS: public oops::interface::ModelBase, F90model keyConfig_; util::Duration tstep_; const Geometry geom_; - const oops::Variables vars_; + oops::Variables vars_; char jedidir_[10000]; char ufsdir_[10000]; }; diff --git a/src/soca/Model/ufsm6c6/ModelUFSm6c6.cc b/src/soca/Model/ufsm6c6/ModelUFSm6c6.cc index 76c87d215..2466d2fb4 100644 --- a/src/soca/Model/ufsm6c6/ModelUFSm6c6.cc +++ b/src/soca/Model/ufsm6c6/ModelUFSm6c6.cc @@ -32,10 +32,8 @@ namespace soca { : keyConfig_(0), tstep_(0), geom_(resol), - vars_(model, "model variables") { Log::trace() << "ModelUFSm6c6::ModelUFSm6c6" << std::endl; - Log::trace() << "ModelUFSm6c6 vars: " << vars_ << std::endl; tstep_ = util::Duration(model.getString("tstep")); } // ----------------------------------------------------------------------------- diff --git a/src/soca/Model/ufsm6c6/ModelUFSm6c6.h b/src/soca/Model/ufsm6c6/ModelUFSm6c6.h index 593d79c11..cc306e6f6 100644 --- a/src/soca/Model/ufsm6c6/ModelUFSm6c6.h +++ b/src/soca/Model/ufsm6c6/ModelUFSm6c6.h @@ -64,14 +64,12 @@ namespace soca { /// Utilities const util::Duration & timeResolution() const {return tstep_;} - const oops::Variables & variables() const {return vars_;} private: void print(std::ostream &) const; int keyConfig_; util::Duration tstep_; const Geometry & geom_; - const oops::Variables vars_; }; // ----------------------------------------------------------------------------- diff --git a/src/soca/State/State.cc b/src/soca/State/State.cc index 49e4ce931..1ef2b1af8 100644 --- a/src/soca/State/State.cc +++ b/src/soca/State/State.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 2017-2021 UCAR + * (C) Copyright 2017-2023 UCAR * * This software is licensed under the terms of the Apache Licence Version 2.0 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. @@ -255,6 +255,7 @@ namespace soca { void State::toFieldSet(atlas::FieldSet &fset) const { soca_state_to_fieldset_f90(toFortran(), vars_, fset.get()); + fset.haloExchange(); } // ----------------------------------------------------------------------------- diff --git a/src/soca/State/soca_state_mod.F90 b/src/soca/State/soca_state_mod.F90 index 5f3c8e3bf..3ebf37b8d 100644 --- a/src/soca/State/soca_state_mod.F90 +++ b/src/soca/State/soca_state_mod.F90 @@ -6,7 +6,7 @@ !> State fields module soca_state_mod -use fckit_log_module, only: fckit_log +use logger_mod use kinds, only: kind_real use oops_variables_mod @@ -86,12 +86,12 @@ subroutine soca_state_rotate(self, coordinate, uvars, vvars) u_names = trim(uvars%variable(i)) v_names = trim(vvars%variable(i)) if (self%has(u_names).and.self%has(v_names)) then - call fckit_log%info("rotating "//trim(u_names)//" "//trim(v_names)) + call oops_log%info("rotating "//trim(u_names)//" "//trim(v_names)) call self%get(u_names, uocn) call self%get(v_names, vocn) else ! Skip if no pair found. - call fckit_log%info("not rotating "//trim(u_names)//" "//trim(v_names)) + call oops_log%info("not rotating "//trim(u_names)//" "//trim(v_names)) cycle end if allocate(un(size(uocn%val,1),size(uocn%val,2),size(uocn%val,3))) @@ -242,11 +242,11 @@ subroutine soca_state_logexpon(self, transfunc, trvars) ! get a list variables to be transformed and make a copy tr_names = trim(trvars%variable(i)) if (self%has(tr_names)) then - call fckit_log%info("transforming "//trim(tr_names)) + call oops_log%info("transforming "//trim(tr_names)) call self%get(tr_names, trocn) else ! Skip if no variable found. - call fckit_log%info("not transforming "//trim(tr_names)) + call oops_log%info("not transforming "//trim(tr_names)) cycle end if allocate(trn(size(trocn%val,1),size(trocn%val,2),size(trocn%val,3))) diff --git a/src/soca/Utils/soca_omb_stats_mod.F90 b/src/soca/Utils/soca_omb_stats_mod.F90 index d0972a3e0..cc41c4057 100644 --- a/src/soca/Utils/soca_omb_stats_mod.F90 +++ b/src/soca/Utils/soca_omb_stats_mod.F90 @@ -6,7 +6,7 @@ !> surface background error used by soca_bkgerrgodas_mod module soca_omb_stats_mod -use fckit_log_module, only: fckit_log +use logger_mod use fckit_mpi_module, only: fckit_mpi_comm use kinds, only: kind_real use netcdf @@ -69,7 +69,7 @@ subroutine soca_omb_stats_init(self, domain, filename) if (myrank.eq.root) then - call fckit_log%info("Reading file " // trim(filename)) + call oops_log%info("Reading file " // trim(filename)) call nc_check(nf90_open(filename, nf90_nowrite, ncid)) diff --git a/src/soca/VariableChange/CMakeLists.txt b/src/soca/VariableChange/CMakeLists.txt index 7395863ce..4274f6775 100644 --- a/src/soca/VariableChange/CMakeLists.txt +++ b/src/soca/VariableChange/CMakeLists.txt @@ -2,7 +2,7 @@ add_subdirectory(Model2Ana) add_subdirectory(Base) add_subdirectory(Model2GeoVaLs) -if ( BUILD_ICEPACK ) +if( ${icepack_FOUND} ) add_subdirectory(Soca2Cice) endif() diff --git a/src/soca/VariableChange/Model2GeoVaLs/Model2GeoVaLs.F90 b/src/soca/VariableChange/Model2GeoVaLs/Model2GeoVaLs.F90 index 29222527b..50e4aa391 100644 --- a/src/soca/VariableChange/Model2GeoVaLs/Model2GeoVaLs.F90 +++ b/src/soca/VariableChange/Model2GeoVaLs/Model2GeoVaLs.F90 @@ -50,6 +50,12 @@ subroutine soca_model2geovals_changevar_f90(c_key_geom, c_key_xin, c_key_xout) & select case (xout%fields(i)%name) ! fields that are obtained from geometry + case ('latitude') + xout%fields(i)%val(:,:,1) = real(geom%lat, kind=kind_real) + + case ('longitude') + xout%fields(i)%val(:,:,1) = real(geom%lon, kind=kind_real) + case ('sea_water_depth') call geom%thickness2depth(geom%h, xout%fields(i)%val) diff --git a/src/soca/VariableChange/VariableChange.cc b/src/soca/VariableChange/VariableChange.cc index 53be6f7c7..34f899438 100644 --- a/src/soca/VariableChange/VariableChange.cc +++ b/src/soca/VariableChange/VariableChange.cc @@ -5,8 +5,10 @@ * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. */ +#include #include #include +#include #include "soca/Geometry/Geometry.h" #include "soca/State/State.h" @@ -20,10 +22,23 @@ namespace soca { // ----------------------------------------------------------------------------- -VariableChange::VariableChange(const Parameters_ & params, +std::map> SocaVaderCookbook { + {"sea_water_temperature", {"SeaWaterTemperature_A"}}, + {"sea_water_potential_temperature", {"SeaWaterPotentialTemperature_A"}}, +}; + +// ----------------------------------------------------------------------------- + +VariableChange::VariableChange(const eckit::Configuration & config, const Geometry & geometry) { + VariableChangeParameters params; + params.deserialize(config); + // setup vader - vader_.reset(new vader::Vader(params.vader)); + eckit::LocalConfiguration vaderConfig, vaderCookbookConfig; + for (auto kv : SocaVaderCookbook) vaderCookbookConfig.set(kv.first, kv.second); + vaderConfig.set(vader::configCookbookKey, vaderCookbookConfig); + vader_.reset(new vader::Vader(params.vader, vaderConfig)); // Create the variable change variableChange_.reset(VariableChangeFactory::create(geometry, @@ -49,8 +64,31 @@ void VariableChange::changeVar(State & x, const oops::Variables & vars) const { // // If the variables are the same, don't bother doing anything! // if (!(x.variables() == vars)) + // The following is TEMPORARY. + // ---------------------------------------------------------------------------- + // We need to do some variable renaming BEFORE we run VADER. + // Eventually, we will internally rename these variables when they are + // first loaded in so that we won't have to worry about it here. + if (vars.has("sea_water_temperature")) { + Log::debug() << "VariableChange::changeVar Pre-VADER variable changes. " << std::endl; + oops::Variables preVaderVars(std::vector{ + "latitude", + "longitude", + "sea_water_potential_temperature", + "sea_water_salinity", + "sea_water_depth"}); + preVaderVars += x.variables(); + State preVader(x.geometry(), preVaderVars, x.time()); + variableChange_->changeVar(x, preVader); + x.updateFields(preVaderVars); + x = preVader; + Log::debug() << "VariableChange::changeVar variables after var change: " + << x.variables() << std::endl; + } + // call Vader // ---------------------------------------------------------------------------- + Log::debug() << "VariableChange::changeVar VADER variable changes. " << std::endl; // Record start variables oops::Variables varsFilled = x.variables(); oops::Variables varsVader = vars; @@ -65,18 +103,19 @@ void VariableChange::changeVar(State & x, const oops::Variables & vars) const { varsFilled += vader_->changeVar(xfs, varsVader); x.updateFields(varsFilled); x.fromFieldSet(xfs); + Log::debug() << "VariableChange::changeVar variables after var change: " + << x.variables() << std::endl; // soca specific transforms // ---------------------------------------------------------------------------- - // Create output state + Log::debug() << "VariableChange::changeVar SOCA specific post-VADER variable changes. " + << std::endl; State xout(x.geometry(), vars, x.time()); - - // Call variable change variableChange_->changeVar(x, xout); - - // Copy data from temporary state x.updateFields(vars); x = xout; + Log::debug() << "VariableChange::changeVar variables after var change: " + << x.variables() << std::endl; Log::trace() << "VariableChange::changeVar done" << std::endl; @@ -86,50 +125,7 @@ void VariableChange::changeVar(State & x, const oops::Variables & vars) const { void VariableChange::changeVarInverse(State & x, const oops::Variables & vars) const { - Log::trace() << "VariableChange::changeVarInverse starting" << std::endl; - - Log::debug() << "VariableChange::changeVarInverse vars in: " - << x.variables() << std::endl; - Log::debug() << "VariableChange::changeVarInverse vars out: " - << vars << std::endl; - - // If the variables are the same, don't bother doing anything! - if (vars <= x.variables()) { - x.updateFields(vars); - oops::Log::info() << "VariableChange::changeVarInverse done (identity)" << std::endl; - return; - } - - // call Vader - // ---------------------------------------------------------------------------- - // Record start variables - oops::Variables varsFilled = x.variables(); - oops::Variables varsVader = vars; - varsVader -= varsFilled; // Pass only the needed variables - - // Call Vader. On entry, varsVader holds the vars requested from Vader; on exit, - // it holds the vars NOT fulfilled by Vader, i.e., the vars still to be requested elsewhere. - // vader_->changeVar also returns the variables fulfilled by Vader. These variables are allocated - // and populated and added to the FieldSet (xfs). - atlas::FieldSet xfs; - x.toFieldSet(xfs); - varsFilled += vader_->changeVar(xfs, varsVader); - x.updateFields(varsFilled); - x.fromFieldSet(xfs); - - // soca specific transforms - // ----------------------------------------------------------------------------- - // Create output state - State xout(x.geometry(), vars, x.time()); - - // Call variable change - variableChange_->changeVarInverse(x, xout); - - // Copy data from temporary state - x.updateFields(vars); - x = xout; - - Log::trace() << "VariableChange::changeVarInverse done" << std::endl; + changeVar(x, vars); } // ----------------------------------------------------------------------------- diff --git a/src/soca/VariableChange/VariableChange.h b/src/soca/VariableChange/VariableChange.h index 554431bee..f78d4f327 100644 --- a/src/soca/VariableChange/VariableChange.h +++ b/src/soca/VariableChange/VariableChange.h @@ -46,7 +46,7 @@ class VariableChange : public util::Printable { typedef VariableChangeParameters Parameters_; - explicit VariableChange(const Parameters_ &, const Geometry &); + explicit VariableChange(const eckit::Configuration &, const Geometry &); ~VariableChange(); void changeVar(State &, const oops::Variables &) const; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ead69445d..00f72ef74 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -9,6 +9,8 @@ set( soca_test_input testinput/3dvarfgat_pseudo.yml testinput/3dvarfgat.yml testinput/3dvarlowres_soca.yml + testinput/4denvar.yml + testinput/4dhybenvar.yml testinput/addincrement.yml testinput/balance_mask.yml testinput/checkpointmodel.yml @@ -17,6 +19,7 @@ set( soca_test_input testinput/convertstate_soca2cice.yml testinput/convertstate.yml testinput/diffstates.yml + testinput/dirac_diffusion.yml testinput/dirac_horizfilt.yml testinput/dirac_soca_cor_nicas_scales.yml testinput/dirac_soca_cov.yml @@ -30,12 +33,14 @@ set( soca_test_input testinput/enspert.yml testinput/ensmeanandvariance.yml testinput/ensrecenter.yml - testinput/ensvariance.yml testinput/errorcovariance.yml testinput/forecast_identity.yml testinput/forecast_mom6_bgc.yml testinput/forecast_mom6.yml testinput/forecast_ufs.yml + testinput/forecast_mom6_ens1.yml + testinput/forecast_mom6_ens2.yml + testinput/forecast_mom6_ens3.yml testinput/forecast_pseudo.yml testinput/geometry_iterator_2d.yml testinput/geometry_iterator_3d.yml @@ -43,6 +48,7 @@ set( soca_test_input testinput/getvalues.yml testinput/gridgen.yml testinput/hofx_3d.yml + testinput/hofx_oasim_3d.yml testinput/hofx_4d_pseudo.yml testinput/hofx_4d.yml testinput/hybridgain.yml @@ -62,6 +68,7 @@ set( soca_test_input testinput/parameters_bump_cor_nicas.yml testinput/parameters_bump_cov.yml testinput/parameters_bump_loc.yml + testinput/parameters_diffusion.yml testinput/parametric_stddev.yml testinput/setcorscales.yml testinput/sqrtvertloc.yml @@ -91,6 +98,8 @@ set( soca_test_ref testref/3dvarfgat_pseudo.test testref/3dvarfgat.test testref/3dvarlowres_soca.test + testref/4denvar.test + testref/4dhybenvar.test testref/addincrement.test testref/balance_mask.test testref/checkpointmodel.test @@ -99,23 +108,24 @@ set( soca_test_ref testref/convertstate_soca2cice.test testref/convertstate.test testref/diffstates.test + testref/dirac_diffusion.test testref/dirac_horizfilt.test testref/dirac_soca_cor_nicas_scales.test testref/dirac_soca_cov.test testref/dirac_soca_mask.test testref/dirac_soca_nomask.test - testref/dirac_socahyb_cov.test + testref/dirac_socahyb_cov.test testref/enshofx.test testref/enspert.test testref/ensmeanandvariance.test testref/ensrecenter.test - testref/ensvariance.test testref/forecast_identity.test testref/forecast_mom6_bgc.test testref/forecast_mom6.test testref/forecast_pseudo.test testref/gridgen.test testref/hofx_3d.test + testref/hofx_oasim_3d.test testref/hofx_4d_pseudo.test testref/hofx_4d.test testref/hybridgain.test @@ -528,6 +538,20 @@ soca_add_test( NAME forecast_pseudo TEST_DEPENDS test_soca_gridgen test_soca_forecast_mom6 ) +soca_add_test( NAME forecast_mom6_ens1 + EXE soca_forecast.x + NOTRAPFPE + TEST_DEPENDS test_soca_gridgen ) +soca_add_test( NAME forecast_mom6_ens2 + EXE soca_forecast.x + NOTRAPFPE + TEST_DEPENDS test_soca_gridgen ) +soca_add_test( NAME forecast_mom6_ens3 + EXE soca_forecast.x + NOTRAPFPE + TEST_DEPENDS test_soca_gridgen ) + + # background error #--------------------------------------------------------------------------------------------------- @@ -566,6 +590,11 @@ soca_add_test( NAME parameters_bump_cov EXE soca_error_covariance_toolbox.x NOTRAPFPE ) +soca_add_test( NAME parameters_diffusion + EXE soca_error_covariance_toolbox.x + TEST_DEPENDS test_soca_gridgen + test_soca_setcorscales) + # Misc applications #--------------------------------------------------------------------------------------------------- @@ -589,10 +618,6 @@ soca_add_test( NAME convertstate_changevar # NOTRAPFPE TEST_DEPENDS test_soca_gridgen ) -soca_add_test( NAME ensvariance - EXE soca_ensvariance.x - TEST_DEPENDS test_soca_gridgen ) - soca_add_test( NAME ensmeanandvariance EXE soca_ensmeanandvariance.x TEST_DEPENDS test_soca_gridgen ) @@ -658,6 +683,11 @@ soca_add_test( NAME dirac_soca_nomask TEST_DEPENDS test_soca_gridgen test_soca_static_socaerror_init) +# NOTE the following test throws a FPE only on clang +soca_add_test( NAME dirac_diffusion + EXE soca_error_covariance_toolbox.x + NOTRAPFPE + TEST_DEPENDS test_soca_parameters_diffusion) # h(x) executables #--------------------------------------------------------------------------------------------------- @@ -672,6 +702,12 @@ soca_add_test( NAME hofx_3d TEST_DEPENDS test_soca_gridgen LIBS soca stochastic_physics ccpp fv3atm esmf) +if( ${oasim_FOUND} ) + soca_add_test( NAME hofx_oasim_3d + EXE soca_hofx3d.x + TEST_DEPENDS test_soca_gridgen ) +endif( ${oasim_FOUND} ) + soca_add_test( NAME hofx_4d EXE soca_hofx.x NOTRAPFPE @@ -684,12 +720,18 @@ soca_add_test( NAME hofx_4d_pseudo test_soca_forecast_mom6 LIBS soca stochastic_physics ccpp fv3atm esmf) - # TODO Re-enable the comparison once that's fixed -soca_add_test( NAME enshofx - EXE soca_enshofx.x - MPI 3 - NOTRAPFPE - TEST_DEPENDS test_soca_gridgen ) +# NOTE, enshofx is disabled because MOM6 always writes out some diagnostic +# netcdf files (which can't be disabled). This is normally not a problem, except +# with enshofx, because multiple instances of MOM6 are started under separate +# MPI_COMMs, causing problems when they all try to write to the same file at the +# same time. We'll need to take a closer look at MOM6 output when we start +# dealing with in-core MOM6 + +# soca_add_test( NAME enshofx +# EXE soca_enshofx.x +# MPI 3 +# NOTRAPFPE +# TEST_DEPENDS test_soca_gridgen ) # variational methods #--------------------------------------------------------------------------------------------------- @@ -756,11 +798,20 @@ soca_add_test( NAME 3dhybfgat test_soca_static_socaerror_init test_soca_parameters_bump_loc ) -# soca_add_test( NAME 4dhyb -# EXE soca_var.x -# TEST_DEPENDS test_soca_static_socaerror_init -# test_soca_parameters_bump_loc ) +soca_add_test( NAME 4denvar + EXE soca_var.x + TEST_DEPENDS test_soca_gridgen + test_soca_forecast_mom6_ens1 + test_soca_forecast_mom6_ens2 + test_soca_forecast_mom6_ens3 ) +soca_add_test( NAME 4dhybenvar + EXE soca_var.x + TEST_DEPENDS test_soca_gridgen + test_soca_static_socaerror_init + test_soca_forecast_mom6_ens1 + test_soca_forecast_mom6_ens2 + test_soca_forecast_mom6_ens3 ) # LETKF #--------------------------------------------------------------------------------------------------- @@ -804,7 +855,7 @@ soca_add_test( NAME convertincrement # TEST_DEPENDS test_soca_gridgen # test_soca_3dvar_godas) -if ( BUILD_ICEPACK ) +if( ${icepack_FOUND} ) # Apply the Soca2Cice nonlinear change of variable # TODO (G): check test dependency file(COPY ${CMAKE_CURRENT_BINARY_DIR}/data_static/72x35x25/restarts/iced.2018-04-15-00000.nc diff --git a/test/Data/36x17x25/soca_gridspec.nc b/test/Data/36x17x25/soca_gridspec.nc index 7822d902d..05c1e2d72 100644 --- a/test/Data/36x17x25/soca_gridspec.nc +++ b/test/Data/36x17x25/soca_gridspec.nc @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:437cf79635fba0fdc66541f229595c57a58ff6825437538b2a244935af52d887 -size 359020 +oid sha256:efdfc4954dd0524792066f0874f59dc2a9c66a541d81816e8389903b4407923b +size 369164 diff --git a/test/Data/fields_metadata.yml b/test/Data/fields_metadata.yml index 371bed01d..6f91faa5e 100644 --- a/test/Data/fields_metadata.yml +++ b/test/Data/fields_metadata.yml @@ -9,6 +9,10 @@ # getval_name_surface: GetValues variable name for 2D surface of a 3D field (Default: ) # io_file: The restart file domain "ocn", "sfc", or "ice" (Default: ) # io_name: The variable name used in the restart IO (Default: ) +# constant value: Used for "dummy" fields. Sets the entire field to the given constant globally +# This parameter cannot be used with io_file/io_name +# fill value: If the field is masked, this value will be used for the masked areas. +# (Default: 0.0) # -------------------------------------------------------------------------------------------------- @@ -51,13 +55,13 @@ getval name: sea_water_cell_thickness io file: ocn io name: h + vert interp: false - name: ssh getval name: sea_surface_height_above_geoid io file: ocn io name: ave_ssh - # -------------------------------------------------------------------------------------------------- # ice state variables # -------------------------------------------------------------------------------------------------- @@ -149,6 +153,7 @@ - name: layer_depth levels: full_ocn + vert interp: false - name: mesoscale_representation_error @@ -163,3 +168,101 @@ - name: sea_water_depth levels: full_ocn + +- name: latitude +- name: longitude + +# -------------------------------------------------------------------------------------------------- +# variables that VADER should be responsible for +# -------------------------------------------------------------------------------------------------- +- name: sea_water_temperature + levels: full_ocn + +# -------------------------------------------------------------------------------------------------- +- name: dummy_atm1 + constant value: 5.0 + +- name: oz_th + getval name: ozone_thickness + constant value: 275 #The average amount of ozone in the atm. is 300 Dobson Units + +- name: wvapor + getval name: water_vapor #g/cm^2 + constant value: 1.2 + +- name: ws + getval name: surface_wind_speed + constant value: 6 + +- name: pres + getval name: surface_pressure_at_mean_sea_level + constant value: 999 + +- name: rh + getval name: relative_humidity + constant value: 89 + +- name: cld_tau + getval name: cloud_optical_thickness + constant value: 19.8 + +- name: cld_lwp + getval name: cloud_liquid_water_path + constant value: 163 + +- name: clwefr + getval name: effective_radius_of_cloud_liquid_water_particle + constant value: 12.4 + +- name: cov + getval name: cloud_area_fraction_in_atmosphere_layer + constant value: 80 + +- name: aer_tau + getval name: aerosol_optical_thickness + constant value: 0.16 + +- name: scat_alb + getval name: single_scattering_albedo + constant value: 0.71 + +- name: asym_par + getval name: asymmetry_parameter + constant value: 0.97 + +#---------------------ocean bio +- name: c_det + getval name: Carbon_nitrogen_detritus_concentration + constant value: 4.7 + +- name: inorg_c + getval name: Particulate_inorganic_carbon + constant value: 2.1 + +- name: dis_c + getval name: colored_dissolved_organic_carbon + constant value: 3.1 + +- name: diatom + getval name: diatom_concentration + constant value: 0.01 + +- name: chloro + getval name: chlorophyte_concentration + constant value: 0.14 + +- name: cyano + getval name: cyano-bacteria_concentration + constant value: 0.003 + +- name: cocco + getval name: coccolithophore_concentration + constant value: 0.092 + +- name: dino + getval name: dinoflagellate_concentration + constant value: 0 #1.54e-17 + +- name: phaeo + getval name: phaeocystis_concentration + constant value: 0 #5.3e-24 diff --git a/test/Data/oasim/abw25_morel.dat b/test/Data/oasim/abw25_morel.dat new file mode 100755 index 000000000..229fe5896 --- /dev/null +++ b/test/Data/oasim/abw25_morel.dat @@ -0,0 +1,38 @@ +Spectral seawater absorption and total scattering coefficients in +units of /m. Derived from Smith and Baker 1981 (200-300 nm), and +(730-800 nm), Morel et al 2007 (325-475), Pope and Fry 1997 (500-720), +Circio and Petty 1951 (800nm-2.5um), and Maul 1985 (2.5-4um). +Format i5,f15.4,f10.4 + 250 0.6112 0.0567 + 325 0.0218 0.0162 + 350 0.0081 0.0117 + 375 0.0057 0.0089 + 400 0.0047 0.0069 + 425 0.0049 0.0054 + 450 0.0085 0.0043 + 475 0.0117 0.0034 + 500 0.0215 0.0029 + 525 0.0407 0.0023 + 550 0.0550 0.0019 + 575 0.0849 0.0016 + 600 0.1995 0.0014 + 625 0.2850 0.0012 + 650 0.3512 0.0009 + 675 0.4559 0.0007 + 700 0.6433 0.0007 + 725 1.4449 0.0006 + 775 2.3900 0.0004 + 850 3.7382 0.0002 + 950 27.4805 0.0000 + 1050 19.3470 0.0000 + 1150 67.1800 0.0000 + 1250 94.9976 0.0000 + 1350 363.1256 0.0000 + 1450 1118.6070 0.0000 + 1550 944.8757 0.0000 + 1650 519.5995 0.0000 + 1750 646.7179 0.0000 + 1900 3768.5610 0.0000 + 2200 2628.0830 0.0000 + 2900 437623.0000 0.0000 + 3700 1338404.0000 0.0000 diff --git a/test/Data/oasim/acbc25_6.dat b/test/Data/oasim/acbc25_6.dat new file mode 100755 index 000000000..fad0c4d49 --- /dev/null +++ b/test/Data/oasim/acbc25_6.dat @@ -0,0 +1,126 @@ + Phytoplankton group chlorophyll-specific + absorption and total scattering coefficients. + Diatoms, Chlorophytes, Cyanobacteria + Coccolithphores, and Dinoflagellates, grouped as + ac, bc within each heading + Format: i4,2f10.4 + Diatoms + 250 0.0000 0.3972 + 325 0.0000 0.3655 + 350 0.0309 0.3208 + 375 0.0320 0.3120 + 400 0.0340 0.2992 + 425 0.0384 0.2841 + 450 0.0379 0.2738 + 475 0.0324 0.2686 + 500 0.0272 0.2631 + 525 0.0206 0.2589 + 550 0.0140 0.2547 + 575 0.0087 0.2494 + 600 0.0071 0.2402 + 625 0.0091 0.2275 + 650 0.0104 0.2154 + 675 0.0223 0.1927 + 700 0.0042 0.2001 + 725 0.0003 0.1932 + 750 0.0000 0.0000 + Chlorophytes + 250 0.0000 0.1199 + 325 0.0000 0.1199 + 350 0.0276 0.0923 + 375 0.0286 0.0913 + 400 0.0304 0.0895 + 425 0.0341 0.0859 + 450 0.0338 0.0861 + 475 0.0304 0.0895 + 500 0.0239 0.0960 + 525 0.0123 0.1076 + 550 0.0071 0.1128 + 575 0.0063 0.1137 + 600 0.0068 0.1131 + 625 0.0069 0.1130 + 650 0.0096 0.1103 + 675 0.0151 0.1048 + 700 0.0037 0.1163 + 725 0.0003 0.1196 + 750 0.0000 0.0000 + Cyanobacteria + 250 0.0000 0.5092 + 325 0.0000 0.4502 + 350 0.0578 0.3668 + 375 0.0601 0.3501 + 400 0.0651 0.3251 + 425 0.0767 0.2935 + 450 0.0708 0.2794 + 475 0.0523 0.2779 + 500 0.0478 0.2624 + 525 0.0408 0.2494 + 550 0.0440 0.2262 + 575 0.0451 0.2051 + 600 0.0294 0.2008 + 625 0.0312 0.1790 + 650 0.0298 0.1604 + 675 0.0373 0.1328 + 700 0.0220 0.1282 + 725 0.0132 0.1170 + 750 0.0000 0.0000 + Coccolithophores + 250 0.0000 0.8391 + 325 0.0000 0.7732 + 350 0.0563 0.6882 + 375 0.0572 0.6712 + 400 0.0645 0.6416 + 425 0.0721 0.6115 + 450 0.0709 0.5904 + 475 0.0596 0.5793 + 500 0.0412 0.5753 + 525 0.0229 0.5713 + 550 0.0123 0.5595 + 575 0.0085 0.5409 + 600 0.0082 0.5189 + 625 0.0081 0.4965 + 650 0.0083 0.4740 + 675 0.0180 0.4420 + 700 0.0049 0.4326 + 725 0.0008 0.4144 + 750 0.0000 0.0000 + Dinoflagellates + 250 0.0000 0.0462 + 325 0.0000 0.0462 + 350 0.0269 0.0193 + 375 0.0280 0.0182 + 400 0.0299 0.0164 + 425 0.0337 0.0125 + 450 0.0345 0.0117 + 475 0.0316 0.0146 + 500 0.0270 0.0192 + 525 0.0211 0.0251 + 550 0.0167 0.0295 + 575 0.0102 0.0360 + 600 0.0090 0.0372 + 625 0.0089 0.0373 + 650 0.0093 0.0369 + 675 0.0185 0.0277 + 700 0.0065 0.0397 + 725 0.0003 0.0459 + 750 0.0000 0.0000 + Phaeocystis + 250 0.0000 0.3972 + 325 0.0000 0.3655 + 350 0.0378 0.3208 + 375 0.0241 0.3120 + 400 0.0250 0.2992 + 425 0.0302 0.2841 + 450 0.0290 0.2738 + 475 0.0229 0.2686 + 500 0.0111 0.2631 + 525 0.0066 0.2589 + 550 0.0043 0.2547 + 575 0.0039 0.2494 + 600 0.0045 0.2402 + 625 0.0054 0.2275 + 650 0.0057 0.2154 + 675 0.0168 0.1927 + 700 0.0025 0.2001 + 725 0.0005 0.1932 + 750 0.0000 0.0000 diff --git a/test/Data/oasim/atmo25b.dat b/test/Data/oasim/atmo25b.dat new file mode 100755 index 000000000..5bb9ef37a --- /dev/null +++ b/test/Data/oasim/atmo25b.dat @@ -0,0 +1,37 @@ + Atmospheric Opt Data: lambda, ET Irrad (W/m2) + Rayleigh Opt Thickness, Ozone Abs Coeff (/cm) + Water vapor abs coeff (/cm), O2 (/cm), CO2 (/cm) + Format: i5,6f11.4 + 250 16.5280 2.8229 80.8836 0.0000 0.0000 0.0000 + 325 41.0035 0.8742 0.3584 0.0000 0.0000 0.0000 + 350 12.7915 0.5925 0.0016 0.0000 0.0000 0.0000 + 375 27.1180 0.4768 0.0001 0.0000 0.0000 0.0000 + 400 35.1935 0.3643 0.0000 0.0000 0.0000 0.0000 + 425 42.1795 0.2833 0.0008 0.0000 0.0000 0.0000 + 450 49.1940 0.2238 0.0040 0.0000 0.0000 0.0000 + 475 49.7700 0.1791 0.0121 0.0000 0.0000 0.0000 + 500 48.3945 0.1451 0.0279 0.0000 0.0000 0.0000 + 525 46.4935 0.1189 0.0529 0.0000 0.0000 0.0000 + 550 46.5160 0.0983 0.0832 0.0000 0.0000 0.0000 + 575 46.1380 0.0820 0.1140 0.0148 0.0000 0.0000 + 600 44.1230 0.0690 0.1176 0.0851 0.0000 0.0000 + 625 42.0468 0.0584 0.0967 0.0016 0.0058 0.0000 + 650 39.5245 0.0498 0.0643 0.0408 0.0000 0.0000 + 675 37.8730 0.0427 0.0416 0.0009 0.2333 0.0000 + 700 18.7465 0.0382 0.0261 0.1074 0.1299 0.0000 + 725 66.8775 0.0319 0.0132 0.1462 0.0000 0.0000 + 775 59.9900 0.0244 0.0072 0.0065 1.1176 0.0000 + 850 102.2358 0.0168 0.0020 0.0568 0.0001 0.0000 + 950 84.7899 0.0108 0.0000 4.9142 0.0000 0.0000 + 1050 67.8772 0.0072 0.0000 0.0279 0.0002 0.0002 + 1150 56.0762 0.0050 0.0000 17.5902 0.0000 0.0000 + 1250 46.1106 0.0032 0.0000 0.0479 0.0028 0.0005 + 1350 37.3780 0.0026 0.0000 115.3197 0.0000 0.0003 + 1450 31.8313 0.0020 0.0000 95.2031 0.0000 0.0023 + 1550 27.2524 0.0015 0.0000 0.0364 0.0000 0.0014 + 1650 22.7691 0.0012 0.0000 0.0082 0.0000 0.0010 + 1750 18.6144 0.0009 0.0000 2.0008 0.0000 0.0001 + 1900 27.9521 0.0007 0.0000 228.9211 0.0000 0.0087 + 2200 33.6300 0.0004 0.0000 0.2550 0.0000 0.0118 + 2900 32.5775 0.0001 0.0000 314.7111 0.0000 0.0256 + 3700 7.2635 0.0000 0.0000 0.9158 0.0000 0.0003 diff --git a/test/Data/oasim/pic_sigma.dat b/test/Data/oasim/pic_sigma.dat new file mode 100755 index 000000000..e016803b4 --- /dev/null +++ b/test/Data/oasim/pic_sigma.dat @@ -0,0 +1,38 @@ +Coccolith backscattering cross section from Gordon et al., 2009 +Converted to m2/mol CaCO3 using the conversion in that paper =44.2 +Converted to m2/mgCaCO3 +Converted to scattering cross section using bbprime=0.015 from +Balch et al. 1996 +250 0.030449 +325 0.029958 +350 0.029712 +375 0.029467 +400 0.028976 +425 0.027502 +450 0.026029 +475 0.024556 +500 0.022591 +525 0.019153 +550 0.015716 +575 0.013997 +600 0.012278 +625 0.011787 +650 0.011296 +675 0.011541 +700 0.011787 +725 0.012032 +775 0.012278 +850 0.012278 +950 0.011050 +1050 0.011050 +1150 0.011050 +1250 0.011050 +1350 0.011050 +1450 0.011050 +1550 0.011050 +1650 0.011050 +1750 0.011050 +1900 0.011050 +2200 0.011050 +2900 0.011050 +3700 0.011050 diff --git a/test/Data/oasim/slingo.dat b/test/Data/oasim/slingo.dat new file mode 100755 index 000000000..527486976 --- /dev/null +++ b/test/Data/oasim/slingo.dat @@ -0,0 +1,27 @@ + Slingo's (1989; J. Atmos. Sci.) parameterization for cloud radiative + effects. Given are: wavelength range (um), a, b, e, f, c, d. + Format(2f5.2,3x,2f6.3,2f6.3,1pe9.2,1pe8.2) + 0.25 0.30 3.094 1.252 0.844 1.558 7.90E-7 3.69E-7 + 0.30 0.33 2.944 1.270 0.841 1.680 -6.50E-7 4.33E-7 + 0.33 0.36 3.308 1.246 0.839 1.946 -3.00E-7 2.36E-7 + 0.36 0.40 2.801 1.293 0.836 2.153 1.00E-6 0.00E0 + 0.40 0.44 2.668 1.307 0.840 1.881 0.00E0 0.00E0 + 0.44 0.48 2.698 1.315 0.820 3.004 1.00E-6 0.00E0 + 0.48 0.52 2.672 1.320 0.828 2.467 0.00E0 0.00E0 + 0.52 0.57 2.838 1.300 0.825 2.776 0.00E0 0.00E0 + 0.57 0.64 2.831 1.317 0.828 2.492 -1.20E-6 4.00E-7 + 0.64 0.69 2.895 1.315 0.818 2.989 -1.20E-7 4.40E-7 + 0.69 0.75 3.115 1.244 0.804 3.520 -2.70E-7 1.40E-6 + 0.75 0.78 2.650 1.349 0.809 3.387 2.30E-6 1.70E-6 + 0.78 0.87 2.622 1.362 0.806 3.355 3.30E-6 2.80E-6 + 0.87 1.00 2.497 1.376 0.783 5.035 9.80E-6 2.10E-5 + 1.00 1.10 2.632 1.365 0.784 4.745 -4.60E-5 5.00E-5 + 1.10 1.19 2.589 1.385 0.780 4.989 -2.80E-5 8.00E-5 + 1.19 1.28 2.551 1.401 0.773 5.405 6.20E-5 2.60E-4 + 1.28 1.53 2.463 1.420 0.754 6.555 2.40E-4 8.56E-4 + 1.53 1.64 2.237 1.452 0.749 6.931 1.20E-4 6.67E-4 + 1.64 2.13 1.970 1.501 0.740 7.469 1.20E-3 2.16E-3 + 2.13 2.38 1.850 1.556 0.769 5.171 1.90E-4 2.54E-3 + 2.38 2.91 1.579 1.611 0.851 2.814 1.23E-1 9.35E-3 + 2.91 3.42 1.950 1.540 0.831 6.102 4.49E-1 1.54E-3 + 3.42 4.00 -1.023 1.933 0.726 6.652 2.50E-2 1.22E-2 diff --git a/test/Data/obs/pace_radiance.nc b/test/Data/obs/pace_radiance.nc new file mode 100644 index 000000000..1e130af09 --- /dev/null +++ b/test/Data/obs/pace_radiance.nc @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b881f3e7f3f5c824de932a149db4f77e7e91dd114a8c5b0aab716cae7e91f8d0 +size 150457 diff --git a/test/testinput/3dhyb.yml b/test/testinput/3dhyb.yml index a9390421e..06ec2539a 100644 --- a/test/testinput/3dhyb.yml +++ b/test/testinput/3dhyb.yml @@ -1,8 +1,9 @@ cost function: cost type: 3D-Var - window begin: 2018-04-14T00:00:00Z - window length: P2D + time window: + begin: 2018-04-14T00:00:00Z + length: P2D analysis variables: &soca_vars [cicen, hicen, hsnon, socn, tocn, uocn, vocn, ssh, hocn] geometry: &geom geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc @@ -150,10 +151,11 @@ variational: online diagnostics: write increment: true increment: - datadir: data_generated/3dhyb - date: *bkg_date - exp: 3dhyb.iter1 - type: incr + state component: + datadir: data_generated/3dhyb + date: *bkg_date + exp: 3dhyb.iter1 + type: incr output: datadir: data_generated/3dhyb diff --git a/test/testinput/3dhybfgat.yml b/test/testinput/3dhybfgat.yml index c18739477..b91f6fe18 100644 --- a/test/testinput/3dhybfgat.yml +++ b/test/testinput/3dhybfgat.yml @@ -1,8 +1,9 @@ _date_begin: &date_begin 2018-04-15T00:00:00Z cost function: cost type: 4D-Var - window begin: *date_begin - window length: PT6H + time window: + begin: *date_begin + length: PT6H analysis variables: &soca_vars [cicen, hicen, socn, tocn, uocn, vocn, ssh, hocn] geometry: &geom @@ -166,10 +167,11 @@ variational: online diagnostics: write increment: true increment: - datadir: data_generated/3dhybfgat - date: *date_begin - exp: 3dhybfgat.iter1 - type: incr + state component: + datadir: data_generated/3dhybfgat + date: *date_begin + exp: 3dhybfgat.iter1 + type: incr output: datadir: data_generated/3dhybfgat diff --git a/test/testinput/3dvar_godas.yml b/test/testinput/3dvar_godas.yml index 1852d0d24..421b6507c 100644 --- a/test/testinput/3dvar_godas.yml +++ b/test/testinput/3dvar_godas.yml @@ -7,8 +7,9 @@ _: &land_mask cost function: cost type: 3D-Var - window begin: 2018-04-14T00:00:00Z - window length: P2D + time window: + begin: 2018-04-14T00:00:00Z + length: P2D analysis variables: &soca_vars [cicen, hicen, hsnon, socn, tocn, ssh, hocn, sw, lhf, shf, lw, us, mld, layer_depth] geometry: &geom geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc @@ -254,10 +255,11 @@ variational: online diagnostics: write increment: true increment: - datadir: data_generated/3dvar_godas - date: *bkg_date - exp: 3dvar_godas.iter1 - type: incr + state component: + datadir: data_generated/3dvar_godas + date: *bkg_date + exp: 3dvar_godas.iter1 + type: incr output: datadir: data_generated/3dvar_godas diff --git a/test/testinput/3dvar_single_ob.yml b/test/testinput/3dvar_single_ob.yml index 02850d5c6..9216d6b08 100644 --- a/test/testinput/3dvar_single_ob.yml +++ b/test/testinput/3dvar_single_ob.yml @@ -7,8 +7,9 @@ _: &land_mask cost function: cost type: 3D-Var - window begin: 2018-04-14T00:00:00Z - window length: P2D + time window: + begin: 2018-04-14T00:00:00Z + length: P2D analysis variables: &a_vars [cicen, hicen, hsnon, socn, tocn, ssh, sw, lhf, shf, lw, us] geometry: &geom geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc @@ -75,10 +76,11 @@ variational: online diagnostics: write increment: true increment: - datadir: data_generated/3dvar_single_ob - date: *bkg_date - exp: 3dvar_single_ob.iter1 - type: incr + state component: + datadir: data_generated/3dvar_single_ob + date: *bkg_date + exp: 3dvar_single_ob.iter1 + type: incr output: datadir: data_generated/3dvar_single_ob diff --git a/test/testinput/3dvar_soca.yml b/test/testinput/3dvar_soca.yml index 477624d1d..2c90d5374 100644 --- a/test/testinput/3dvar_soca.yml +++ b/test/testinput/3dvar_soca.yml @@ -7,8 +7,9 @@ _: &land_mask cost function: cost type: 3D-Var - window begin: &date_begin 2018-04-14T00:00:00Z - window length: P2D + time window: + begin: &date_begin 2018-04-14T00:00:00Z + length: P2D analysis variables: &a_vars [cicen, hicen, socn, tocn, ssh, sw, lhf, shf, lw, us, chl, biop, swh] geometry: &geom geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc @@ -337,10 +338,11 @@ variational: online diagnostics: write increment: true increment: - datadir: data_generated/3dvar_soca - date: *bkg_date - exp: 3dvar_soca.iter1 - type: incr + state component: + datadir: data_generated/3dvar_soca + date: *bkg_date + exp: 3dvar_soca.iter1 + type: incr output: datadir: data_generated/3dvar_soca diff --git a/test/testinput/3dvar_zero_ob.yml b/test/testinput/3dvar_zero_ob.yml index b7efe40fc..97ff47280 100644 --- a/test/testinput/3dvar_zero_ob.yml +++ b/test/testinput/3dvar_zero_ob.yml @@ -7,8 +7,9 @@ _: &land_mask cost function: cost type: 3D-Var - window begin: 2018-04-14T00:00:00Z - window length: P2D + time window: + begin: 2018-04-14T00:00:00Z + length: P2D analysis variables: &soca_vars [cicen, hicen, hsnon, socn, tocn, ssh, hocn, sw, lhf, shf, lw, us, mld, layer_depth] geometry: mom6_input_nml: ./inputnml/input.nml diff --git a/test/testinput/3dvarbump.yml b/test/testinput/3dvarbump.yml index 7f0333342..c54ef83af 100644 --- a/test/testinput/3dvarbump.yml +++ b/test/testinput/3dvarbump.yml @@ -7,8 +7,9 @@ _: &land_mask cost function: cost type: 3D-Var - window begin: 2018-04-14T00:00:00Z - window length: P2D + time window: + begin: 2018-04-14T00:00:00Z + length: P2D analysis variables: &soca_vars [socn, tocn, uocn, vocn, ssh] geometry: &geom_small geom_grid_file: data_static/36x17x25/soca_gridspec.nc diff --git a/test/testinput/3dvarfgat.yml b/test/testinput/3dvarfgat.yml index 4dd2a9e57..2fa686d98 100644 --- a/test/testinput/3dvarfgat.yml +++ b/test/testinput/3dvarfgat.yml @@ -7,8 +7,9 @@ _: &land_mask cost function: cost type: 4D-Var - window begin: &date_begin 2018-04-15T00:00:00Z - window length: PT6H + time window: + begin: &date_begin 2018-04-15T00:00:00Z + length: PT6H analysis variables: &soca_vars [cicen, hicen, socn, tocn, uocn, vocn, ssh, sw, lhf, shf, lw, us] geometry: &geom geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc @@ -270,10 +271,11 @@ variational: online diagnostics: write increment: true increment: - datadir: data_generated/3dvarfgat - date: *bkg_date - exp: 3dvarfgat.iter1 - type: incr + state component: + datadir: data_generated/3dvarfgat + date: *bkg_date + exp: 3dvarfgat.iter1 + type: incr output: datadir: data_generated/3dvarfgat diff --git a/test/testinput/3dvarfgat_pseudo.yml b/test/testinput/3dvarfgat_pseudo.yml index 7f101466d..8e343bb8f 100644 --- a/test/testinput/3dvarfgat_pseudo.yml +++ b/test/testinput/3dvarfgat_pseudo.yml @@ -7,8 +7,9 @@ _: &land_mask cost function: cost type: 4D-Var - window begin: &date_begin 2018-04-15T00:00:00Z - window length: PT6H + time window: + begin: &date_begin 2018-04-15T00:00:00Z + length: PT6H analysis variables: &soca_vars [socn, tocn, uocn, vocn, ssh] geometry: &geom geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc @@ -26,7 +27,6 @@ cost function: model: name: PseudoModel tstep: PT1H - state variables: &model_vars [socn, tocn, ssh, hocn, uocn, vocn, mld, layer_depth] _state : &state basename: data_generated/forecast_mom6/ read_from_file: 1 @@ -55,7 +55,7 @@ cost function: basename: data_static/72x35x25/restarts/ ocn_filename: MOM.res.nc date: &bkg_date 2018-04-15T00:00:00Z - state variables: *model_vars + state variables: [socn, tocn, ssh, hocn, uocn, vocn, mld, layer_depth] background error: covariance model: SocaError diff --git a/test/testinput/3dvarlowres_soca.yml b/test/testinput/3dvarlowres_soca.yml index 8ce6d9ed7..1ad6bb4ab 100644 --- a/test/testinput/3dvarlowres_soca.yml +++ b/test/testinput/3dvarlowres_soca.yml @@ -7,8 +7,9 @@ _: &land_mask cost function: cost type: 3D-Var - window begin: &date_begin 2018-04-14T00:00:00Z - window length: P2D + time window: + begin: &date_begin 2018-04-14T00:00:00Z + length: P2D analysis variables: &a_vars [socn, tocn, ssh] geometry: geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc @@ -215,10 +216,11 @@ variational: online diagnostics: write increment: true increment: - datadir: data_generated/3dvarlowres_soca - date: *bkg_date - exp: 3dvarlowres_soca.iter1 - type: incr + state component: + datadir: data_generated/3dvarlowres_soca + date: *bkg_date + exp: 3dvarlowres_soca.iter1 + type: incr output: datadir: data_generated/3dvarlowres_soca diff --git a/test/testinput/4denvar.yml b/test/testinput/4denvar.yml new file mode 100644 index 000000000..14b1bf9e5 --- /dev/null +++ b/test/testinput/4denvar.yml @@ -0,0 +1,98 @@ +cost function: + cost type: 4D-Ens-Var + analysis variables: [socn, tocn, uocn, vocn, ssh] + time window: + begin: 2018-04-15T00:00:00Z + length: PT6H + subwindow: PT3H + parallel subwindows: false + + geometry: &geom + geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc + mom6_input_nml: data_static/72x35x25/input.nml + fields metadata: data_static/fields_metadata.yml + + background: + states: + - _bkg_state: &_bkg_state + read_from_file: 1 + basename: data_generated/forecast_mom6/ + state variables: [socn, tocn, uocn, vocn, ssh, hocn, layer_depth] + <<: *_bkg_state + ocn_filename: ocn.forecast_mom6.fc.2018-04-15T00:00:00Z.PT0S.nc + date: 2018-04-15T00:00:00Z + - <<: *_bkg_state + ocn_filename: ocn.forecast_mom6.fc.2018-04-15T00:00:00Z.PT3H.nc + date: 2018-04-15T03:00:00Z + - <<: *_bkg_state + ocn_filename: ocn.forecast_mom6.fc.2018-04-15T00:00:00Z.PT6H.nc + date: 2018-04-15T06:00:00Z + + background error: + covariance model: ensemble + localization: + localization method: SABER + saber central block: + saber block name: ID + + members from template: + pattern: '%mem%' + nmembers: 3 + template: + states: + - _bkg_err_state: &_bkg_err_state + read_from_file: 1 + state variables: [socn, tocn, uocn, vocn, ssh, hocn, layer_depth] + basename: data_generated/forecast_mom6_ens%mem%/ + << : *_bkg_err_state + ocn_filename: ocn.fcst_ens%mem%.fc.2018-04-15T00:00:00Z.PT0S.nc + date: 2018-04-15T00:00:00Z + - << : *_bkg_err_state + ocn_filename: ocn.fcst_ens%mem%.fc.2018-04-15T00:00:00Z.PT3H.nc + date: 2018-04-15T03:00:00Z + - << : *_bkg_err_state + ocn_filename: ocn.fcst_ens%mem%.fc.2018-04-15T00:00:00Z.PT6H.nc + date: 2018-04-15T06:00:00Z + + observations: + observers: + - obs space: + name: SeaSufaceTemp + obsdataout: + engine: + type: H5File + obsfile: data_generated/4denvar/sst.4denvar.nc + obsdatain: + engine: + type: H5File + obsfile: data_static/obs/sst.nc + simulated variables: [seaSurfaceTemperature] + obs operator: + name: Identity + observation alias file: testinput/obsop_name_map.yml + obs error: + covariance model: diagonal + +variational: + minimizer: + algorithm: DRIPCG + iterations: + - geometry: *geom + ninner: 5 + gradient norm reduction: 1e-10 + test: on + diagnostics: + departures: ombg + +output: + datadir: data_generated/4denvar + exp: 4denvar + type: an + +final: + diagnostics: + departures: oman + +test: + reference filename: testref/4denvar.test + test output filename: testoutput/4denvar.test diff --git a/test/testinput/4dhybenvar.yml b/test/testinput/4dhybenvar.yml new file mode 100644 index 000000000..8de4b6d1f --- /dev/null +++ b/test/testinput/4dhybenvar.yml @@ -0,0 +1,119 @@ +cost function: + cost type: 4D-Ens-Var + analysis variables: [socn, tocn, uocn, vocn, ssh] + time window: + begin: 2018-04-15T00:00:00Z + length: PT6H + subwindow: PT3H + parallel subwindows: false + + geometry: &geom + geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc + mom6_input_nml: data_static/72x35x25/input.nml + fields metadata: data_static/fields_metadata.yml + + background: + states: + - _bkg_state: &_bkg_state + read_from_file: 1 + basename: data_generated/forecast_mom6/ + state variables: [socn, tocn, uocn, vocn, ssh, hocn, layer_depth] + <<: *_bkg_state + ocn_filename: ocn.forecast_mom6.fc.2018-04-15T00:00:00Z.PT0S.nc + date: 2018-04-15T00:00:00Z + - <<: *_bkg_state + ocn_filename: ocn.forecast_mom6.fc.2018-04-15T00:00:00Z.PT3H.nc + date: 2018-04-15T03:00:00Z + - <<: *_bkg_state + ocn_filename: ocn.forecast_mom6.fc.2018-04-15T00:00:00Z.PT6H.nc + date: 2018-04-15T06:00:00Z + + background error: + covariance model: hybrid + components: + - weight: + value: 0.5 + covariance: + covariance model: SocaError + analysis variables: [socn, tocn, uocn, vocn, ssh] + date: 2018-04-15T00:00:00Z + bump: + io: + data directory: data_generated/static_socaerror_init + drivers: + multivariate strategy: univariate + read local nicas: true + correlation: + - name: ocn + variables: [socn, tocn, uocn, vocn, ssh] + + - weight: + value: 0.5 + covariance: + covariance model: ensemble + localization: + localization method: SABER + saber central block: + saber block name: ID + + members from template: + pattern: '%mem%' + nmembers: 3 + template: + states: + - _bkg_err_state: &_bkg_err_state + read_from_file: 1 + state variables: [socn, tocn, uocn, vocn, ssh, hocn, layer_depth] + basename: data_generated/forecast_mom6_ens%mem%/ + << : *_bkg_err_state + ocn_filename: ocn.fcst_ens%mem%.fc.2018-04-15T00:00:00Z.PT0S.nc + date: 2018-04-15T00:00:00Z + - << : *_bkg_err_state + ocn_filename: ocn.fcst_ens%mem%.fc.2018-04-15T00:00:00Z.PT3H.nc + date: 2018-04-15T03:00:00Z + - << : *_bkg_err_state + ocn_filename: ocn.fcst_ens%mem%.fc.2018-04-15T00:00:00Z.PT6H.nc + date: 2018-04-15T06:00:00Z + + observations: + observers: + - obs space: + name: SeaSufaceTemp + obsdataout: + engine: + type: H5File + obsfile: data_generated/4dhybenvar/sst.4dhybenvar.nc + obsdatain: + engine: + type: H5File + obsfile: data_static/obs/sst.nc + simulated variables: [seaSurfaceTemperature] + obs operator: + name: Identity + observation alias file: testinput/obsop_name_map.yml + obs error: + covariance model: diagonal + +variational: + minimizer: + algorithm: DRIPCG + iterations: + - geometry: *geom + ninner: 5 + gradient norm reduction: 1e-10 + test: on + diagnostics: + departures: ombg + +output: + datadir: data_generated/4dhybenvar + exp: 4dhybenvar + type: an + +final: + diagnostics: + departures: oman + +test: + reference filename: testref/4dhybenvar.test + test output filename: testoutput/4dhybenvar.test diff --git a/test/testinput/dirac_diffusion.yml b/test/testinput/dirac_diffusion.yml new file mode 100644 index 000000000..760c4840b --- /dev/null +++ b/test/testinput/dirac_diffusion.yml @@ -0,0 +1,42 @@ +geometry: &geom + geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc + mom6_input_nml: data_static/72x35x25/input.nml + fields metadata: data_static/fields_metadata.yml + +background: + read_from_file: 1 + basename: data_static/72x35x25/restarts/ + date: &date 2018-04-15T00:00:00Z + ocn_filename: MOM.res.nc + ice_filename: cice.res.nc + state variables: &soca_vars [cicen, hicen, socn, tocn, ssh, hocn, mld, layer_depth] + +background error: + covariance model: SABER + saber central block: + saber block name: EXPLICIT_DIFFUSION + active variables: [tocn, socn, ssh] + geometry: *geom + groups: + - name: group1 + variables: [tocn, socn] + - name: group2 + variables: [ssh] + read: + filename: data_generated/parameters_diffusion/diffusion_params.nc + +dirac: + ixdir: [1, 17, 51, 31, 51, 63, 81, 14, 16, 43] + iydir: [8, 21, 16, 33, 29, 26, 16, 41, 5, 43] + izdir: [1, 5, 1, 1, 1, 1, 1, 1, 1, 1] + ifdir: [1, 1, 3, 2, 1, 1, 1, 4, 5, 5] + +output dirac: + datadir: data_generated/dirac_diffusion + date: *date + exp: dirac_diffusion_%id% + type: an + +test: + reference filename: testref/dirac_diffusion.test + test output filename: testoutput/dirac_diffusion.test \ No newline at end of file diff --git a/test/testinput/enshofx_1.yml b/test/testinput/enshofx_1.yml index d81584826..60a0f27ee 100644 --- a/test/testinput/enshofx_1.yml +++ b/test/testinput/enshofx_1.yml @@ -1,5 +1,7 @@ -window begin: 2018-04-15T06:00:00Z -window length: PT2H +time window: + begin: 2018-04-15T06:00:00Z + length: PT2H + forecast length: PT2H geometry: diff --git a/test/testinput/enshofx_2.yml b/test/testinput/enshofx_2.yml index c3537e81d..53b500e0d 100644 --- a/test/testinput/enshofx_2.yml +++ b/test/testinput/enshofx_2.yml @@ -1,5 +1,7 @@ -window begin: 2018-04-15T06:00:00Z -window length: PT2H +time window: + begin: 2018-04-15T06:00:00Z + length: PT2H + forecast length: PT2H geometry: diff --git a/test/testinput/enshofx_3.yml b/test/testinput/enshofx_3.yml index b5a25d48d..568307855 100644 --- a/test/testinput/enshofx_3.yml +++ b/test/testinput/enshofx_3.yml @@ -1,5 +1,7 @@ -window begin: 2018-04-15T06:00:00Z -window length: PT2H +time window: + begin: 2018-04-15T06:00:00Z + length: PT2H + forecast length: PT2H geometry: diff --git a/test/testinput/ensvariance.yml b/test/testinput/ensvariance.yml deleted file mode 100644 index 00c7629f4..000000000 --- a/test/testinput/ensvariance.yml +++ /dev/null @@ -1,42 +0,0 @@ -geometry: - geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc - mom6_input_nml: data_static/72x35x25/input.nml - fields metadata: data_static/fields_metadata.yml - -_file: &_file - read_from_file: 1 - date: &date_bkg 2018-04-15T00:00:00Z - basename: data_static/72x35x25/ - remap_filename: data_static/72x35x25/restarts/MOM.res.nc - state variables: &soca_vars [cicen, hicen, socn, tocn, uocn, vocn, ssh, hocn, mld, layer_depth] - -background: - <<: *_file - ocn_filename: restarts/MOM.res.nc - ice_filename: restarts/cice.res.nc - -variance output: - datadir: data_generated/ensvariance - exp: ensvariance - type: fc - date: *date_bkg - -ensemble: - members: - - <<: *_file - ocn_filename: restarts_ens/ocn.enspert.ens.1.2018-04-15T00:00:00Z.PT0S.nc - ice_filename: restarts_ens/ice.enspert.ens.1.2018-04-15T00:00:00Z.PT0S.nc - - <<: *_file - ocn_filename: restarts_ens/ocn.enspert.ens.2.2018-04-15T00:00:00Z.PT0S.nc - ice_filename: restarts_ens/ice.enspert.ens.2.2018-04-15T00:00:00Z.PT0S.nc - - <<: *_file - ocn_filename: restarts_ens/ocn.enspert.ens.3.2018-04-15T00:00:00Z.PT0S.nc - ice_filename: restarts_ens/ice.enspert.ens.3.2018-04-15T00:00:00Z.PT0S.nc - - <<: *_file - ocn_filename: restarts_ens/ocn.enspert.ens.4.2018-04-15T00:00:00Z.PT0S.nc - ice_filename: restarts_ens/ice.enspert.ens.4.2018-04-15T00:00:00Z.PT0S.nc - -test: - reference filename: testref/ensvariance.test - test output filename: testoutput/ensvariance.test - float relative tolerance: 1e-3 diff --git a/test/testinput/forecast_mom6_ens1.yml b/test/testinput/forecast_mom6_ens1.yml new file mode 100644 index 000000000..93b6942c3 --- /dev/null +++ b/test/testinput/forecast_mom6_ens1.yml @@ -0,0 +1,27 @@ +geometry: + geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc + mom6_input_nml: data_static/72x35x25/input.nml + fields metadata: data_static/fields_metadata.yml + +model: + name: MOM6solo + tstep: PT1H + advance_mom6: 1 + model variables: [cicen, hicen, socn, tocn, ssh, hocn, uocn, vocn, sw, lhf, shf, lw, us] + +initial condition: + read_from_file: 1 + date: &date 2018-04-15T00:00:00Z + basename: data_static/72x35x25/restarts_ens/ + ocn_filename: ocn.enspert.ens.1.2018-04-15T00:00:00Z.PT0S.nc + ice_filename: ice.enspert.ens.1.2018-04-15T00:00:00Z.PT0S.nc + state variables: [cicen, hicen, socn, tocn, ssh, hocn, uocn, vocn, sw, lhf, shf, lw, us] + +forecast length: PT6H + +output: + frequency: PT1H + datadir: data_generated/forecast_mom6_ens1 + exp: fcst_ens1 + date: *date + type: fc \ No newline at end of file diff --git a/test/testinput/forecast_mom6_ens2.yml b/test/testinput/forecast_mom6_ens2.yml new file mode 100644 index 000000000..6ebc4eaaf --- /dev/null +++ b/test/testinput/forecast_mom6_ens2.yml @@ -0,0 +1,27 @@ +geometry: + geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc + mom6_input_nml: data_static/72x35x25/input.nml + fields metadata: data_static/fields_metadata.yml + +model: + name: MOM6solo + tstep: PT1H + advance_mom6: 1 + model variables: [cicen, hicen, socn, tocn, ssh, hocn, uocn, vocn, sw, lhf, shf, lw, us] + +initial condition: + read_from_file: 1 + date: &date 2018-04-15T00:00:00Z + basename: data_static/72x35x25/restarts_ens/ + ocn_filename: ocn.enspert.ens.2.2018-04-15T00:00:00Z.PT0S.nc + ice_filename: ice.enspert.ens.2.2018-04-15T00:00:00Z.PT0S.nc + state variables: [cicen, hicen, socn, tocn, ssh, hocn, uocn, vocn, sw, lhf, shf, lw, us] + +forecast length: PT6H + +output: + frequency: PT1H + datadir: data_generated/forecast_mom6_ens2 + exp: fcst_ens2 + date: *date + type: fc \ No newline at end of file diff --git a/test/testinput/forecast_mom6_ens3.yml b/test/testinput/forecast_mom6_ens3.yml new file mode 100644 index 000000000..bd6bde079 --- /dev/null +++ b/test/testinput/forecast_mom6_ens3.yml @@ -0,0 +1,27 @@ +geometry: + geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc + mom6_input_nml: data_static/72x35x25/input.nml + fields metadata: data_static/fields_metadata.yml + +model: + name: MOM6solo + tstep: PT1H + advance_mom6: 1 + model variables: [cicen, hicen, socn, tocn, ssh, hocn, uocn, vocn, sw, lhf, shf, lw, us] + +initial condition: + read_from_file: 1 + date: &date 2018-04-15T00:00:00Z + basename: data_static/72x35x25/restarts_ens/ + ocn_filename: ocn.enspert.ens.3.2018-04-15T00:00:00Z.PT0S.nc + ice_filename: ice.enspert.ens.3.2018-04-15T00:00:00Z.PT0S.nc + state variables: [cicen, hicen, socn, tocn, ssh, hocn, uocn, vocn, sw, lhf, shf, lw, us] + +forecast length: PT6H + +output: + frequency: PT1H + datadir: data_generated/forecast_mom6_ens3 + exp: fcst_ens3 + date: *date + type: fc \ No newline at end of file diff --git a/test/testinput/forecast_pseudo.yml b/test/testinput/forecast_pseudo.yml index db90e93c6..dc9606b1d 100644 --- a/test/testinput/forecast_pseudo.yml +++ b/test/testinput/forecast_pseudo.yml @@ -6,7 +6,6 @@ geometry: model: name: PseudoModel tstep: PT1H - state variables: [socn, tocn, ssh, hocn, uocn, vocn] states: - date: 2018-04-15T01:00:00Z basename: data_generated/forecast_mom6/ diff --git a/test/testinput/getvalues.yml b/test/testinput/getvalues.yml index 436f344a6..d8b094fb4 100644 --- a/test/testinput/getvalues.yml +++ b/test/testinput/getvalues.yml @@ -30,8 +30,9 @@ variables: &vars [ ] locations: - window begin: 2018-04-15T00:00:00Z - window end: 2018-04-15T06:00:00Z + time window: + begin: 2018-04-15T00:00:00Z + end: 2018-04-15T06:00:00Z obs space: name: Random Locations simulated variables: *vars diff --git a/test/testinput/gridgen.yml b/test/testinput/gridgen.yml index cc5769f7f..80fc88575 100644 --- a/test/testinput/gridgen.yml +++ b/test/testinput/gridgen.yml @@ -6,6 +6,10 @@ geometry: fields metadata: data_static/fields_metadata.yml rossby file: data_static/rossrad.dat + # save the atlas mesh for viewing in gmsh + gmsh save: true + gmsh filename: data_generated/gridgen/gmsh.msh + test: reference filename: testref/gridgen.test test output filename: testoutput/gridgen.test diff --git a/test/testinput/hofx_3d.yml b/test/testinput/hofx_3d.yml index 03b8690c0..a61537d8a 100644 --- a/test/testinput/hofx_3d.yml +++ b/test/testinput/hofx_3d.yml @@ -10,10 +10,11 @@ state: ocn_filename: MOM.res.nc ice_filename: cice.res.nc sfc_filename: sfc.res.nc - state variables: [cicen, hicen, hsnon, socn, tocn, ssh, hocn, uocn, vocn, sw, lhf, shf, lw, us, chl] + state variables: [cicen, hicen, hsnon, socn, tocn, ssh, hocn, uocn, vocn, sw, lhf, shf, lw, us, chl, dummy_atm1] -window begin: 2018-04-14T00:00:00Z -window length: P2D +time window: + begin: 2018-04-14T00:00:00Z + length: P2D observations: observers: @@ -88,18 +89,14 @@ observations: obsfile: data_static/obs/prof.nc simulated variables: [waterTemperature, salinity] obs operator: - name: Composite - components: - - name: InsituTemperature - variables: - - name: waterTemperature - - name: VertInterp - observation alias file: testinput/obsop_name_map.yml - variables: - - name: salinity - vertical coordinate: sea_water_depth - observation vertical coordinate: depth - interpolation method: linear + name: VertInterp + observation alias file: testinput/obsop_name_map.yml + variables: + - name: salinity + - name: waterTemperature + vertical coordinate: sea_water_depth + observation vertical coordinate: depth + interpolation method: linear # handle T/S profiles separately... delete this someday - obs space: @@ -114,7 +111,10 @@ observations: obsfile: data_static/obs/prof.nc simulated variables: [waterTemperature] obs operator: - name: InsituTemperature + name: VertInterp + observation alias file: testinput/obsop_name_map.yml + vertical coordinate: sea_water_depth + observation vertical coordinate: depth - obs space: name: InsituSalinity obsdataout: diff --git a/test/testinput/hofx_4d.yml b/test/testinput/hofx_4d.yml index f601e5695..b35e640a2 100644 --- a/test/testinput/hofx_4d.yml +++ b/test/testinput/hofx_4d.yml @@ -17,8 +17,10 @@ initial condition: ice_filename: cice.res.nc state variables: [cicen, hicen, socn, tocn, ssh, hocn, uocn, vocn, sw, lhf, shf, lw, us] -window begin: 2018-04-15T00:00:00Z -window length: PT3H +time window: + begin: 2018-04-15T00:00:00Z + length: PT3H + forecast length: PT3H observations: diff --git a/test/testinput/hofx_4d_pseudo.yml b/test/testinput/hofx_4d_pseudo.yml index f7760ea37..6c87df3a4 100644 --- a/test/testinput/hofx_4d_pseudo.yml +++ b/test/testinput/hofx_4d_pseudo.yml @@ -6,7 +6,6 @@ geometry: model: name: PseudoModel tstep: PT1H - state variables: &soca_vars [socn, tocn, ssh, hocn, uocn, vocn] states: - date: 2018-04-15T01:00:00Z basename: data_generated/forecast_mom6/ @@ -26,10 +25,11 @@ initial condition: date: 2018-04-15T00:00:00Z basename: data_static/72x35x25/restarts/ ocn_filename: MOM.res.nc - state variables: *soca_vars + state variables: [socn, tocn, ssh, hocn, uocn, vocn] -window begin: 2018-04-15T00:00:00Z -window length: PT3H +time window: + begin: 2018-04-15T00:00:00Z + length: PT3H forecast length: PT3H observations: diff --git a/test/testinput/hofx_oasim_3d.yml b/test/testinput/hofx_oasim_3d.yml new file mode 100644 index 000000000..a25f43bb5 --- /dev/null +++ b/test/testinput/hofx_oasim_3d.yml @@ -0,0 +1,41 @@ +geometry: + geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc + mom6_input_nml: data_static/72x35x25/input.nml + fields metadata: data_static/fields_metadata.yml + +state: + date: 2018-04-15T00:00:00Z + read_from_file: 1 + basename: data_static/72x35x25/restarts/ + ocn_filename: MOM.res.nc + ice_filename: cice.res.nc + sfc_filename: sfc.res.nc + state variables: [hocn, oz_th, wvapor, ws, pres, rh, cld_tau, + cld_lwp, clwefr, cov, aer_tau, scat_alb, asym_par, c_det, inorg_c, dis_c, + diatom, chloro, cyano, cocco, dino, phaeo] + +time window: + begin: 2018-04-14T00:00:00Z + length: P2D + +observations: + observers: + - obs space: + name: Radiance + obsdataout: + engine: + type: H5File + obsfile: data_generated/hofx_oasim_3d/pace_oasim.hofx_oasim_3d.nc + obsdatain: + engine: + type: H5File + obsfile: data_static/obs/pace_radiance.nc + simulated variables: [radiance] + channels: 50-70 + obs operator: + name: OASIM + CoefficientPath: data_static/oasim + +test: + reference filename: testref/hofx_oasim_3d.test + test output filename: testoutput/hofx_oasim_3d.test diff --git a/test/testinput/letkf.yml b/test/testinput/letkf.yml index 35a80fc8e..23e76f305 100644 --- a/test/testinput/letkf.yml +++ b/test/testinput/letkf.yml @@ -3,8 +3,9 @@ geometry: mom6_input_nml: data_static/72x35x25/input.nml fields metadata: data_static/fields_metadata.yml -window begin: &date 2018-04-14T00:00:00Z -window length: P2D +time window: + begin: &date 2018-04-14T00:00:00Z + length: P2D background: members from template: diff --git a/test/testinput/letkf_split_observer.yml b/test/testinput/letkf_split_observer.yml index cc1cd5a43..2d7107649 100644 --- a/test/testinput/letkf_split_observer.yml +++ b/test/testinput/letkf_split_observer.yml @@ -3,8 +3,9 @@ geometry: mom6_input_nml: data_static/72x35x25/input.nml fields metadata: data_static/fields_metadata.yml -window begin: &date 2018-04-14T00:00:00Z -window length: P2D +time window: + begin: &date 2018-04-14T00:00:00Z + length: P2D background: members from template: diff --git a/test/testinput/letkf_split_solver.yml b/test/testinput/letkf_split_solver.yml index 554027fb3..6928ef796 100644 --- a/test/testinput/letkf_split_solver.yml +++ b/test/testinput/letkf_split_solver.yml @@ -3,8 +3,9 @@ geometry: mom6_input_nml: data_static/72x35x25/input.nml fields metadata: data_static/fields_metadata.yml -window begin: &date 2018-04-14T00:00:00Z -window length: P2D +time window: + begin: &date 2018-04-14T00:00:00Z + length: P2D background: members from template: diff --git a/test/testinput/makeobs.yml b/test/testinput/makeobs.yml index ab6c98381..8e43c2c59 100644 --- a/test/testinput/makeobs.yml +++ b/test/testinput/makeobs.yml @@ -1,6 +1,8 @@ forecast length: PT3H -window begin: 2018-04-15T00:00:00Z -window length: PT3H + +time window: + begin: 2018-04-15T00:00:00Z + length: PT3H geometry: geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc diff --git a/test/testinput/obslocalization.yml b/test/testinput/obslocalization.yml index fbc05e192..634336d9e 100644 --- a/test/testinput/obslocalization.yml +++ b/test/testinput/obslocalization.yml @@ -4,8 +4,9 @@ geometry: fields metadata: data_static/fields_metadata.yml iterator dimension: 2 -window begin: 2018-04-14T00:00:00Z -window end: 2018-04-16T00:00:00Z +time window: + begin: 2018-04-14T00:00:00Z + end: 2018-04-16T00:00:00Z observations: - obs space: diff --git a/test/testinput/obslocalization_vertical.yml b/test/testinput/obslocalization_vertical.yml index 0c869f8aa..6825c6d08 100644 --- a/test/testinput/obslocalization_vertical.yml +++ b/test/testinput/obslocalization_vertical.yml @@ -4,8 +4,9 @@ geometry: fields metadata: data_static/fields_metadata.yml iterator dimension: 3 -window begin: 2018-04-14T00:00:00Z -window end: 2018-04-16T00:00:00Z +time window: + begin: 2018-04-14T00:00:00Z + end: 2018-04-16T00:00:00Z observations: - obs space: diff --git a/test/testinput/obslocalizations.yml b/test/testinput/obslocalizations.yml index 0fe194a5a..db4910100 100644 --- a/test/testinput/obslocalizations.yml +++ b/test/testinput/obslocalizations.yml @@ -4,8 +4,9 @@ geometry: fields metadata: data_static/fields_metadata.yml iterator dimension: 3 -window begin: 2018-04-14T00:00:00Z -window end: 2018-04-16T00:00:00Z +time window: + begin: 2018-04-14T00:00:00Z + end: 2018-04-16T00:00:00Z observations: - obs space: diff --git a/test/testinput/obsop_name_map.yml b/test/testinput/obsop_name_map.yml index db9a068ab..9cff8f78c 100644 --- a/test/testinput/obsop_name_map.yml +++ b/test/testinput/obsop_name_map.yml @@ -2,7 +2,7 @@ variable maps: - name: depthBelowWaterSurface alias: ocean_depth - name: waterTemperature - alias: ocean_temperature + alias: sea_water_temperature - name: seaSurfaceTemperature alias: sea_surface_temperature - name: salinity diff --git a/test/testinput/parameters_diffusion.yml b/test/testinput/parameters_diffusion.yml new file mode 100644 index 000000000..a378cf98d --- /dev/null +++ b/test/testinput/parameters_diffusion.yml @@ -0,0 +1,35 @@ +geometry: &geom + geom_grid_file: data_generated/gridgen/soca_gridspec.72x35x25.nc + mom6_input_nml: data_static/72x35x25/input.nml + fields metadata: data_static/fields_metadata.yml + +background: + read_from_file: 1 + basename: data_static/72x35x25/restarts/ + date: &date 2018-04-15T06:00:00Z + ocn_filename: MOM.res.nc + ice_filename: cice.res.nc + state variables: &stateVariables [cicen, hicen, hsnon, socn, tocn, uocn, vocn, ssh] + +background error: + covariance model: SABER + # adjoint test: true + # NOTE: to run the self adjoint test, you have to first comment out the + # indicated halo exchange in soca_fields_to_fieldset() + saber central block: + saber block name: EXPLICIT_DIFFUSION + geometry: *geom + calibration: + normalization: + method: randomization #< other option is "brute force" + iterations: 1000 #< in the real world you'll want to use 1e4 or so + scales: + - name: group1 + from file: + filename: data_generated/setcorscales/ocn.cor_rh.incr.2018-04-15T00:00:00Z.nc + variable name: ave_ssh + - name: group2 + as gaussian: true + fixed value: 2000.0e3 #< other method of defining scales, instead of using "from file" + write: + filename: data_generated/parameters_diffusion/diffusion_params.nc \ No newline at end of file diff --git a/test/testinput/setcorscales.yml b/test/testinput/setcorscales.yml index ba586f5a1..183695769 100644 --- a/test/testinput/setcorscales.yml +++ b/test/testinput/setcorscales.yml @@ -27,11 +27,11 @@ scales: cicen: rossby mult: 0.0 min grid mult: 8.0 - min: 1000000 + min value: 1000000 hicen: rossby mult: 0.0 min grid mult: 9.0 - min: 5000000 + min value: 5000000 rh output: datadir: data_generated/setcorscales diff --git a/test/testref/3dhyb.test b/test/testref/3dhyb.test index 2cb821609..fe833233d 100644 --- a/test/testref/3dhyb.test +++ b/test/testref/3dhyb.test @@ -1,17 +1,17 @@ CostJb : Nonlinear Jb = 0.0000000000000000e+00 -CostJo : Nonlinear Jo(ADT) = 2.0458137413924777e+02, nobs = 99, Jo/n = 2.0664785266590684e+00, err = 1.0000000149011613e-01 -CostFunction: Nonlinear J = 2.0458137413924777e+02 -RPCGMinimizer: reduction in residual norm = 2.0804496849039553e-02 +CostJo : Nonlinear Jo(ADT) = 2.0980804284155522e+02, nobs = 99, Jo/n = 2.1192731600157093e+00, err = 1.0000000149011613e-01 +CostFunction: Nonlinear J = 2.0980804284155522e+02 +RPCGMinimizer: reduction in residual norm = 1.3986916105041314e-02 CostFunction::addIncrement: Analysis: Valid time: 2018-04-15T00:00:00Z - cicen min=-0.0040593081880349 max=1.0000647950655037 mean=0.1175080423133622 - hicen min=-0.1694837858544874 max=4.0326695826027077 mean=0.4670393369306883 + cicen min=-0.0055833351906180 max=1.0000625277294939 mean=0.1175137930143875 + hicen min=-0.1340300448550523 max=4.0326711192074995 mean=0.4668708457595877 hsnon min=0.0000000000000000 max=1.2712833951042413 mean=0.0886865877527975 - socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5744047862924830 - tocn min=-1.8947940137300057 max=31.7004646995896131 mean=6.0146891626655883 - uocn min=-0.8581809322810460 max=0.7001463582118039 mean=-0.0002552185891037 - vocn min=-0.7656658341969602 max=1.4377766409421606 mean=0.0021996576877204 - ssh min=-2.1622959317614252 max=0.8974154324210799 mean=-0.2938633000727268 + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5771060899726166 + tocn min=-1.8977624967437274 max=31.7004647317691663 mean=6.0154772032339441 + uocn min=-0.8581811478246130 max=0.7001477830089919 mean=-0.0002559066432762 + vocn min=-0.7656861309282604 max=1.4377766510613166 mean=0.0021994321716903 + ssh min=-2.1760245287885742 max=0.8999953604193408 mean=-0.2948395432550496 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 sw min=-225.0977630615234375 max=-0.0000000000000000 mean=-71.7393205198725354 lhf min=-38.1373977661132812 max=256.5976562500000000 mean=42.0100402226406899 @@ -23,6 +23,6 @@ layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.522 -CostJb : Nonlinear Jb = 6.2208024967284885 -CostJo : Nonlinear Jo(ADT) = 114.6405248894628244, nobs = 99, Jo/n = 1.1579850998935639, err = 0.1000000014901161 -CostFunction: Nonlinear J = 120.8613273861913058 +CostJb : Nonlinear Jb = 6.2153370309095379 +CostJo : Nonlinear Jo(ADT) = 117.2133340087334972, nobs = 99, Jo/n = 1.1839730707952878, err = 0.1000000014901161 +CostFunction: Nonlinear J = 123.4286710396430351 diff --git a/test/testref/3dhybfgat.test b/test/testref/3dhybfgat.test index 3ef4a059e..e1a492318 100644 --- a/test/testref/3dhybfgat.test +++ b/test/testref/3dhybfgat.test @@ -1,16 +1,16 @@ CostJb : Nonlinear Jb = 0.0000000000000000e+00 -CostJo : Nonlinear Jo(ADT) = 8.7370280580244113e+01, nobs = 31, Jo/n = 2.8183961477498101e+00, err = 1.0000000149011612e-01 -CostFunction: Nonlinear J = 8.7370280580244113e+01 -RPCGMinimizer: reduction in residual norm = 2.9185061797211485e-03 +CostJo : Nonlinear Jo(ADT) = 8.7827980335709171e+01, nobs = 31, Jo/n = 2.8331606559906186e+00, err = 1.0000000149011612e-01 +CostFunction: Nonlinear J = 8.7827980335709171e+01 +RPCGMinimizer: reduction in residual norm = 2.2743017181226293e-03 CostFunction::addIncrement: Analysis: Valid time: 2018-04-15T00:00:00Z - cicen min=-0.0033958872442029 max=1.0000001203835267 mean=0.1174835206793045 - hicen min=-0.0900934576976787 max=4.0326673084246947 mean=0.4695574918336070 - socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5585138714596098 - uocn min=-0.8581693992488438 max=0.7001579347565605 mean=-0.0002537807257102 - vocn min=-0.7661101230279923 max=1.4377766409421606 mean=0.0021979176021416 - tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0145093596929469 - ssh min=-1.9241669151494767 max=0.8902346892941313 mean=-0.2877140108914097 + cicen min=-0.0055094416233540 max=1.0000000420883628 mean=0.1174900878620023 + hicen min=-0.0898682624110847 max=4.0326673084246947 mean=0.4695679968317440 + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5587872384660102 + uocn min=-0.8581694003631951 max=0.7001563851954871 mean=-0.0002538829121215 + vocn min=-0.7661101020702997 max=1.4377766409421606 mean=0.0021980693625999 + tocn min=-1.8883899367432375 max=31.7004645720658580 mean=6.0145488739534851 + ssh min=-1.9232987964448847 max=0.8928791626958916 mean=-0.2875104304210939 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 sw min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 lhf min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 @@ -22,6 +22,6 @@ layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.522 -CostJb : Nonlinear Jb = 2.4428367123211485 -CostJo : Nonlinear Jo(ADT) = 76.8979710680983288, nobs = 31, Jo/n = 2.4805797118741397, err = 0.1000000014901161 -CostFunction: Nonlinear J = 79.3408077804194818 +CostJb : Nonlinear Jb = 2.2400054920788746 +CostJo : Nonlinear Jo(ADT) = 76.5887027511879666, nobs = 31, Jo/n = 2.4706033145544506, err = 0.1000000014901161 +CostFunction: Nonlinear J = 78.8287082432668456 diff --git a/test/testref/3dvar_godas.test b/test/testref/3dvar_godas.test index e87d7ec9b..34e656bec 100644 --- a/test/testref/3dvar_godas.test +++ b/test/testref/3dvar_godas.test @@ -1,27 +1,27 @@ CostJb : Nonlinear Jb = 0.0000000000000000e+00 -CostJo : Nonlinear Jo(CoolSkin) = 1.6731214283333800e+04, nobs = 200, Jo/n = 8.3656071416669008e+01, err = 3.6419991997020579e-01 -CostJo : Nonlinear Jo(SeaSurfaceTemp) = 1.6258116856443880e+03, nobs = 174, Jo/n = 9.3437453197953335e+00, err = 3.6280357515271239e-01 -CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 5.4431675889674569e+00, nobs = 29, Jo/n = 1.8769543410232609e-01, err = 1.0000000000000000e+00 -CostJo : Nonlinear Jo(ADT) = 1.0375381454781235e-02, nobs = 95, Jo/n = 1.0921454162927615e-04, err = 2.8169260935368467e+01 -CostJo : Nonlinear Jo(InsituTemperature) = 3.3944990007872332e+02, nobs = 205, Jo/n = 1.6558531711157234e+00, err = 8.9723213032395277e-01 -CostJo : Nonlinear Jo(InsituSalinity) = 3.4804589303321234e+02, nobs = 218, Jo/n = 1.5965407937303318e+00, err = 6.0819699545777528e-01 -CostJo : Nonlinear Jo(SeaIceFraction) = 5.8152359560103446e+02, nobs = 88, Jo/n = 6.6082226772844823e+00, err = 1.0000000149011612e-01 -CostFunction: Nonlinear J = 1.9631498900661580e+04 -RPCGMinimizer: reduction in residual norm = 1.4890894677558011e-01 +CostJo : Nonlinear Jo(CoolSkin) = 1.6329134149677742e+04, nobs = 199, Jo/n = 8.2055950500893175e+01, err = 3.6419991997020579e-01 +CostJo : Nonlinear Jo(SeaSurfaceTemp) = 1.6066024929416167e+03, nobs = 173, Jo/n = 9.2867196123792866e+00, err = 3.6322734119159583e-01 +CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 5.5136316271599295e+00, nobs = 29, Jo/n = 1.9012522852275618e-01, err = 1.0000000000000000e+00 +CostJo : Nonlinear Jo(ADT) = 1.0334301354601411e-02, nobs = 95, Jo/n = 1.0878211952212012e-04, err = 2.8230815589406479e+01 +CostJo : Nonlinear Jo(InsituTemperature) = 3.4020248029963227e+02, nobs = 205, Jo/n = 1.6595242941445476e+00, err = 8.9723213032395277e-01 +CostJo : Nonlinear Jo(InsituSalinity) = 3.4727192955958594e+02, nobs = 218, Jo/n = 1.5929905025669080e+00, err = 6.0819699545777528e-01 +CostJo : Nonlinear Jo(SeaIceFraction) = 5.6944306282109505e+02, nobs = 89, Jo/n = 6.3982366609111807e+00, err = 1.0000000149011612e-01 +CostFunction: Nonlinear J = 1.9198178081228183e+04 +RPCGMinimizer: reduction in residual norm = 1.3394869278655661e-01 CostFunction::addIncrement: Analysis: Valid time: 2018-04-15T00:00:00Z - cicen min=-0.0000693201292598 max=1.0003376635630259 mean=0.1175458333852691 + cicen min=-0.0000563665143372 max=1.0003307403191071 mean=0.1175499389485267 hicen min=0.0000000000000000 max=4.0326673084246947 mean=0.4712515705773916 hsnon min=0.0000000000000000 max=1.2712833951042413 mean=0.0886865877527975 - socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5443923223520315 - tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0183437899017829 - ssh min=-1.9244215280991723 max=0.9272827086645625 mean=-0.2767863997914393 + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5443925948116970 + tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0183977449112982 + ssh min=-1.9244089651560510 max=0.9272827138726495 mean=-0.2767862613297231 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 - sw min=-225.0942956823528505 max=0.0000000000000000 mean=-71.7383580540423793 - lhf min=-38.1375200582396161 max=256.5954937724312686 mean=42.0097184800355450 - shf min=-58.9492910987185894 max=201.3742675934934994 mean=6.0753284134086591 - lw min=0.0000000000000000 max=88.0360936611186276 mean=31.3955346168523803 - us min=0.0043960514439903 max=0.0196673929715284 mean=0.0086875839294735 + sw min=-225.0943644800591414 max=0.0000000000000000 mean=-71.7382903028821204 + lhf min=-38.1375465556171065 max=256.5949994230312541 mean=42.0096946792278629 + shf min=-58.9492928606160191 max=201.3742494565976813 mean=6.0753275791560339 + lw min=0.0000000000000000 max=88.0360940812700505 mean=31.3955349934081234 + us min=0.0044042662455111 max=0.0196689588586444 mean=0.0086900813793515 mld min=2.2854716757984130 max=4593.1533423819937525 mean=192.4109073940401515 layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.5229536158392420 @@ -33,12 +33,12 @@ layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.522 -CostJb : Nonlinear Jb = 0.3856003402344498 -CostJo : Nonlinear Jo(CoolSkin) = 16186.9643635032589373, nobs = 200, Jo/n = 80.9348218175162941, err = 0.3641999199702058 -CostJo : Nonlinear Jo(SeaSurfaceTemp) = 1596.7679360181962238, nobs = 174, Jo/n = 9.1768272184953812, err = 0.3628035751527124 -CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 5.4426904998659715, nobs = 29, Jo/n = 0.1876789827539990, err = 1.0000000000000000 -CostJo : Nonlinear Jo(ADT) = 0.0103757170152075, nobs = 95, Jo/n = 0.0001092180738443, err = 28.1692609353684666 -CostJo : Nonlinear Jo(InsituTemperature) = 337.3302597227105935, nobs = 205, Jo/n = 1.6455134620620029, err = 0.8972321303239528 -CostJo : Nonlinear Jo(InsituSalinity) = 346.7205645110620367, nobs = 218, Jo/n = 1.5904613050966148, err = 0.6081969954577753 -CostJo : Nonlinear Jo(SeaIceFraction) = 580.7185630030103312, nobs = 88, Jo/n = 6.5990745795796633, err = 0.1000000014901161 -CostFunction: Nonlinear J = 19054.3403533153577882 +CostJb : Nonlinear Jb = 0.4158118826125912 +CostJo : Nonlinear Jo(CoolSkin) = 15785.5145342027608422, nobs = 199, Jo/n = 79.3241936392098523, err = 0.3641999199702058 +CostJo : Nonlinear Jo(SeaSurfaceTemp) = 1574.3766446106681087, nobs = 173, Jo/n = 9.1004430324316079, err = 0.3632273411915958 +CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 5.5131254646506047, nobs = 29, Jo/n = 0.1901077746431243, err = 1.0000000000000000 +CostJo : Nonlinear Jo(ADT) = 0.0103346677169496, nobs = 95, Jo/n = 0.0001087859759679, err = 28.2308155894064789 +CostJo : Nonlinear Jo(InsituTemperature) = 337.5858413149268245, nobs = 205, Jo/n = 1.6467602015362284, err = 0.8972321303239528 +CostJo : Nonlinear Jo(InsituSalinity) = 345.8714449969637599, nobs = 218, Jo/n = 1.5865662614539622, err = 0.6081969954577753 +CostJo : Nonlinear Jo(SeaIceFraction) = 568.6042208009064325, nobs = 89, Jo/n = 6.3888114696731062, err = 0.1000000014901161 +CostFunction: Nonlinear J = 18617.8919579412031453 diff --git a/test/testref/3dvar_soca.test b/test/testref/3dvar_soca.test index 2b8f2e245..d33000762 100644 --- a/test/testref/3dvar_soca.test +++ b/test/testref/3dvar_soca.test @@ -1,31 +1,31 @@ CostJb : Nonlinear Jb = 0.0000000000000000e+00 -CostJo : Nonlinear Jo(CoolSkin) = 1.4169933330087919e+04, nobs = 174, Jo/n = 8.1436398448781148e+01, err = 3.6280357515271239e-01 -CostJo : Nonlinear Jo(SeaSurfaceTemp) = 7.7388800526767272e+02, nobs = 147, Jo/n = 5.2645442535215832e+00, err = 3.6246510156485134e-01 -CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 5.4431675889674533e+00, nobs = 29, Jo/n = 1.8769543410232598e-01, err = 1.0000000000000000e+00 -CostJo : Nonlinear Jo(ADT) = 1.3650926098993568e+02, nobs = 91, Jo/n = 1.5001017691201723e+00, err = 1.0000000149011612e-01 -CostJo : Nonlinear Jo(InsituTS) = 6.8749579311193474e+02, nobs = 423, Jo/n = 1.6252855629123752e+00, err = 7.6208809857781845e-01 -CostJo : Nonlinear Jo(SeaIceFraction) = 5.8152359560103514e+02, nobs = 88, Jo/n = 6.6082226772844903e+00, err = 1.0000000149011612e-01 -CostJo : Nonlinear Jo(SeaSurfaceChlorophyll) = 1.4791913800716829e+03, nobs = 129, Jo/n = 1.1466599845516923e+01, err = 6.1865027747001339e-02 +CostJo : Nonlinear Jo(CoolSkin) = 1.4174299653183771e+04, nobs = 173, Jo/n = 8.1932367937478446e+01, err = 3.6322734119159583e-01 +CostJo : Nonlinear Jo(SeaSurfaceTemp) = 7.7377196587412891e+02, nobs = 146, Jo/n = 5.2998079854392390e+00, err = 3.6296533314631141e-01 +CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 5.5136316271599295e+00, nobs = 29, Jo/n = 1.9012522852275618e-01, err = 1.0000000000000000e+00 +CostJo : Nonlinear Jo(ADT) = 1.3879704103180882e+02, nobs = 91, Jo/n = 1.5252422091407563e+00, err = 1.0000000149011612e-01 +CostJo : Nonlinear Jo(InsituTS) = 6.8747440985921844e+02, nobs = 423, Jo/n = 1.6252350114875140e+00, err = 7.6208809857781845e-01 +CostJo : Nonlinear Jo(SeaIceFraction) = 5.6944306282109505e+02, nobs = 89, Jo/n = 6.3982366609111807e+00, err = 1.0000000149011612e-01 +CostJo : Nonlinear Jo(SeaSurfaceChlorophyll) = 1.3639731179097098e+03, nobs = 129, Jo/n = 1.0573435022555890e+01, err = 6.1865027747001339e-02 CostJo : Nonlinear Jo(SeaSurfaceBiomassP) = 4.1314922104098372e+02, nobs = 112, Jo/n = 3.6888323307230690e+00, err = 1.1692603016453901e-08 CostJo : Nonlinear Jo(SeaSurfaceHS) = 1.0896018677668069e+03, nobs = 6, Jo/n = 1.8160031129446782e+02, err = 1.0000000149011612e-01 -CostFunction: Nonlinear J = 1.9336735621526943e+04 -RPCGMinimizer: reduction in residual norm = 1.5196974582598013e-01 +CostFunction: Nonlinear J = 1.9216023971114686e+04 +RPCGMinimizer: reduction in residual norm = 1.3357822017190246e-01 CostFunction::addIncrement: Analysis: Valid time: 2018-04-15T00:00:00Z - cicen min=-0.0001944416218803 max=1.0004544470085890 mean=0.1175562963283338 + cicen min=-0.0002115179073194 max=1.0004820341037177 mean=0.1175659422442119 hicen min=0.0000000000000000 max=4.0326673084246947 mean=0.4712515705773916 - socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5444143017789429 - tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0192939107033352 - ssh min=-1.9246079094092028 max=0.9272950968042213 mean=-0.2767236478726869 + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5444197182825405 + tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0194012222162385 + ssh min=-1.9246315345115299 max=0.9272891664663706 mean=-0.2767204306215251 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 - sw min=-225.0946377620148837 max=0.0000000000000000 mean=-71.7382510638389448 - lhf min=-38.1375353584250192 max=256.5953403388396055 mean=42.0096785986080192 - shf min=-58.9492894488311876 max=201.3742572707894283 mean=6.0753270197181477 - lw min=0.0000000000000000 max=88.0360958910717102 mean=31.3955352012919775 - us min=0.0043961139459376 max=0.0196706712107377 mean=0.0086907044249661 - chl min=-0.0000132792405676 max=4.6719899196170607 mean=0.1184788251022223 - biop min=0.0000000000000000 max=0.0000001868533390 mean=0.0000000065395142 - swh min=0.0000996535891318 max=6.7491955757141104 mean=1.0621528146778920 + sw min=-225.0946147629603331 max=0.0000000000000000 mean=-71.7381266251842646 + lhf min=-38.1375723103176085 max=256.5947019639968403 mean=42.0096297492159820 + shf min=-58.9492914708947495 max=201.3742276461881602 mean=6.0753253636382611 + lw min=0.0000000000000000 max=88.0360972107224740 mean=31.3955360261616576 + us min=0.0044072290018029 max=0.0196739899437386 mean=0.0086954229389514 + chl min=-0.0000081536937266 max=4.6719899196170607 mean=0.1184780720546971 + biop min=0.0000000000000000 max=0.0000001868533390 mean=0.0000000065395206 + swh min=0.0000996535891318 max=6.7491955757141104 mean=1.0621545944148620 mld min=2.2854716757984130 max=4593.1533423819937525 mean=192.4109073940401515 layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.5229536158392420 @@ -39,14 +39,14 @@ layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.522 -CostJb : Nonlinear Jb = 3.7670299019236628 -CostJo : Nonlinear Jo(CoolSkin) = 13658.4011985073175310, nobs = 174, Jo/n = 78.4965586121110164, err = 0.3628035751527124 -CostJo : Nonlinear Jo(SeaSurfaceTemp) = 769.1790616041305384, nobs = 147, Jo/n = 5.2325106231573502, err = 0.3624651015648513 -CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 5.4427757940687362, nobs = 29, Jo/n = 0.1876819239334047, err = 1.0000000000000000 -CostJo : Nonlinear Jo(ADT) = 136.4791250306548704, nobs = 91, Jo/n = 1.4997706047324710, err = 0.1000000014901161 -CostJo : Nonlinear Jo(InsituTS) = 686.2398026360082213, nobs = 423, Jo/n = 1.6223163182884355, err = 0.7620880985778185 -CostJo : Nonlinear Jo(SeaIceFraction) = 580.4391688961409272, nobs = 88, Jo/n = 6.5958996465470561, err = 0.1000000014901161 -CostJo : Nonlinear Jo(SeaSurfaceChlorophyll) = 1459.9873566986807418, nobs = 129, Jo/n = 11.3177314472765946, err = 0.0618650277470013 -CostJo : Nonlinear Jo(SeaSurfaceBiomassP) = 409.2009282277246029, nobs = 112, Jo/n = 3.6535797163189696, err = 0.0000000116926030 -CostJo : Nonlinear Jo(SeaSurfaceHS) = 1086.9227398834236737, nobs = 6, Jo/n = 181.1537899805706218, err = 0.1000000014901161 -CostFunction: Nonlinear J = 18796.0591871800716035 +CostJb : Nonlinear Jb = 4.2941089565347577 +CostJo : Nonlinear Jo(CoolSkin) = 13638.9679733031734941, nobs = 173, Jo/n = 78.8379651636021634, err = 0.3632273411915958 +CostJo : Nonlinear Jo(SeaSurfaceTemp) = 768.2386717644395731, nobs = 146, Jo/n = 5.2619087107153399, err = 0.3629653331463114 +CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 5.5131762689470261, nobs = 29, Jo/n = 0.1901095265154147, err = 1.0000000000000000 +CostJo : Nonlinear Jo(ADT) = 138.7634066289171528, nobs = 91, Jo/n = 1.5248726003177708, err = 0.1000000014901161 +CostJo : Nonlinear Jo(InsituTS) = 686.0324173035821786, nobs = 423, Jo/n = 1.6218260456349460, err = 0.7620880985778185 +CostJo : Nonlinear Jo(SeaIceFraction) = 568.2192882044269027, nobs = 89, Jo/n = 6.3844863843194037, err = 0.1000000014901161 +CostJo : Nonlinear Jo(SeaSurfaceChlorophyll) = 1344.5348295591829810, nobs = 129, Jo/n = 10.4227506167378525, err = 0.0618650277470013 +CostJo : Nonlinear Jo(SeaSurfaceBiomassP) = 408.6554750400586045, nobs = 112, Jo/n = 3.6487095985719518, err = 0.0000000116926030 +CostJo : Nonlinear Jo(SeaSurfaceHS) = 1086.5431097938458151, nobs = 6, Jo/n = 181.0905182989743025, err = 0.1000000014901161 +CostFunction: Nonlinear J = 18649.7624568231112789 diff --git a/test/testref/3dvarbump.test b/test/testref/3dvarbump.test index 0aadcc327..e00afe83b 100644 --- a/test/testref/3dvarbump.test +++ b/test/testref/3dvarbump.test @@ -1,19 +1,19 @@ CostJb : Nonlinear Jb = 0.0000000000000000e+00 -CostJo : Nonlinear Jo(SeaSurfaceTemp) = 7.2761520714484391e+02, nobs = 123, Jo/n = 5.9155707897954786e+00, err = 3.7062899283957257e-01 -CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 5.7834714574083208e+01, nobs = 50, Jo/n = 1.1566942914816642e+00, err = 1.0000000000000000e+00 -CostJo : Nonlinear Jo(ADT) = 1.7801726582342690e+02, nobs = 91, Jo/n = 1.9562336903673285e+00, err = 1.0000000149011612e-01 -CostJo : Nonlinear Jo(InsituTemperature) = 3.4603234526181200e+02, nobs = 203, Jo/n = 1.7045928338020295e+00, err = 9.0034813852418905e-01 -CostJo : Nonlinear Jo(InsituSalinity) = 3.1204797269182581e+02, nobs = 218, Jo/n = 1.4314127187698431e+00, err = 6.0819699545777528e-01 -CostFunction: Nonlinear J = 1.6215475054959918e+03 -RPCGMinimizer: reduction in residual norm = 1.9585627812873155e-01 +CostJo : Nonlinear Jo(SeaSurfaceTemp) = 7.1091386479968503e+02, nobs = 123, Jo/n = 5.7797875186966259e+00, err = 3.7098966299006642e-01 +CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 5.8283270347772934e+01, nobs = 50, Jo/n = 1.1656654069554586e+00, err = 1.0000000000000000e+00 +CostJo : Nonlinear Jo(ADT) = 1.9163642890807802e+02, nobs = 93, Jo/n = 2.0606067624524518e+00, err = 1.0000000149011612e-01 +CostJo : Nonlinear Jo(InsituTemperature) = 3.9116568630186021e+02, nobs = 205, Jo/n = 1.9081252990334645e+00, err = 9.0169108266903031e-01 +CostJo : Nonlinear Jo(InsituSalinity) = 3.1078118440821123e+02, nobs = 218, Jo/n = 1.4256017633404185e+00, err = 6.0819699545777528e-01 +CostFunction: Nonlinear J = 1.6627804347656074e+03 +RPCGMinimizer: reduction in residual norm = 1.6180170436945335e-01 CostFunction::addIncrement: Analysis: Valid time: 2018-04-15T00:00:00Z hocn min=0.0009999999999977 max=1345.6400000000003274 mean=132.2975966204909355 - socn min=21.6778874359345082 max=39.8774684135234310 mean=34.6292686263590355 - tocn min=-1.8883899372702533 max=33.2682523259166132 mean=6.3735018436205531 + socn min=21.6778874359345082 max=39.8774684135234310 mean=34.6333415889160463 + tocn min=-1.9147364365672823 max=32.5667623078130362 mean=6.3366284689423633 uocn min=-0.6975788196638589 max=0.4840625031242498 mean=0.0013055310445162 vocn min=-0.7661101215480253 max=0.9402890903466523 mean=0.0028998456865158 - ssh min=-2.1084939224168693 max=0.8449085686573465 mean=-0.2602635096607882 + ssh min=-2.1845582485095099 max=0.8341590228046922 mean=-0.2740380428121212 mld min=2.4370615877370523 max=4593.1523423819935488 mean=193.6208071648662212 layer_depth min=2.4370615877370523 max=5587.8978052886013757 mean=1243.8222388394297013 @@ -23,10 +23,10 @@ layer_depth min=2.4370615877370523 max=5587.8978052886013757 mean=1243.822 -CostJb : Nonlinear Jb = 53.0340911400380790 -CostJo : Nonlinear Jo(SeaSurfaceTemp) = 446.9544273941489791, nobs = 123, Jo/n = 3.6337758324727560, err = 0.3706289928395726 -CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 59.9152947100068118, nobs = 50, Jo/n = 1.1983058942001363, err = 1.0000000000000000 -CostJo : Nonlinear Jo(ADT) = 154.6934489111536095, nobs = 91, Jo/n = 1.6999280100126770, err = 0.1000000014901161 -CostJo : Nonlinear Jo(InsituTemperature) = 293.3242787162378136, nobs = 203, Jo/n = 1.4449471857942748, err = 0.9003481385241890 -CostJo : Nonlinear Jo(InsituSalinity) = 149.8578704365598355, nobs = 218, Jo/n = 0.6874214240209167, err = 0.6081969954577753 -CostFunction: Nonlinear J = 1157.7794113081451997 +CostJb : Nonlinear Jb = 52.3885394491905743 +CostJo : Nonlinear Jo(SeaSurfaceTemp) = 504.6395987478990719, nobs = 123, Jo/n = 4.1027609654300736, err = 0.3709896629900664 +CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 61.4804594017453780, nobs = 50, Jo/n = 1.2296091880349076, err = 1.0000000000000000 +CostJo : Nonlinear Jo(ADT) = 163.5984040081233388, nobs = 93, Jo/n = 1.7591226237432618, err = 0.1000000014901161 +CostJo : Nonlinear Jo(InsituTemperature) = 343.9723498786432856, nobs = 205, Jo/n = 1.6779139018470404, err = 0.9016910826690303 +CostJo : Nonlinear Jo(InsituSalinity) = 150.1449136404517617, nobs = 218, Jo/n = 0.6887381359653750, err = 0.6081969954577753 +CostFunction: Nonlinear J = 1276.2242651260532966 diff --git a/test/testref/3dvarfgat.test b/test/testref/3dvarfgat.test index 72148e834..e303bcc5d 100644 --- a/test/testref/3dvarfgat.test +++ b/test/testref/3dvarfgat.test @@ -1,23 +1,23 @@ CostJb : Nonlinear Jb = 0.0000000000000000e+00 -CostJo : Nonlinear Jo(CoolSkin) = 4.9634479411817738e+03, nobs = 47, Jo/n = 1.0560527534429306e+02, err = 3.8763169345842458e-01 -CostJo : Nonlinear Jo(SeaSurfaceTemp) = 3.1780656884217410e+02, nobs = 43, Jo/n = 7.3908504381900952e+00, err = 3.8581534929661854e-01 -CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 2.6167366978835638e+00, nobs = 17, Jo/n = 1.5392568811079788e-01, err = 1.0000000000000000e+00 -CostJo : Nonlinear Jo(ADT) = 8.7166288646666516e+01, nobs = 29, Jo/n = 3.0057340912643626e+00, err = 1.0000000149011612e-01 -CostJo : Nonlinear Jo(InsituTemperature) = 3.7309178313712380e+01, nobs = 31, Jo/n = 1.2035218810874961e+00, err = 9.0893991658246809e-01 -CostJo : Nonlinear Jo(InsituSalinity) = 1.6779590930092283e+01, nobs = 33, Jo/n = 5.0847245242703887e-01, err = 6.1042996833236707e-01 -CostJo : Nonlinear Jo(SeaIceFraction) = 1.9943705186059600e+02, nobs = 24, Jo/n = 8.3098771608581661e+00, err = 1.0000000149011612e-01 -CostJo : Nonlinear Jo(SurfaceU) = 4.6119926561840613e-01, nobs = 47, Jo/n = 9.8127503323065142e-03, err = 3.8763169345842458e-01 -CostFunction: Nonlinear J = 5.6250245557385160e+03 -RPCGMinimizer: reduction in residual norm = 5.6036154349071332e-01 +CostJo : Nonlinear Jo(CoolSkin) = 4.9663191368230073e+03, nobs = 47, Jo/n = 1.0566636461325547e+02, err = 3.8763169345842458e-01 +CostJo : Nonlinear Jo(SeaSurfaceTemp) = 3.1454830650364431e+02, nobs = 43, Jo/n = 7.3150768954335890e+00, err = 3.8581534929661854e-01 +CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 2.6796945834674828e+00, nobs = 17, Jo/n = 1.5762909314514606e-01, err = 1.0000000000000000e+00 +CostJo : Nonlinear Jo(ADT) = 8.7431459350288023e+01, nobs = 29, Jo/n = 3.0148779086306217e+00, err = 1.0000000149011612e-01 +CostJo : Nonlinear Jo(InsituTemperature) = 3.7253231588255915e+01, nobs = 31, Jo/n = 1.2017171480082554e+00, err = 9.0893991658246809e-01 +CostJo : Nonlinear Jo(InsituSalinity) = 1.6517158357758575e+01, nobs = 33, Jo/n = 5.0051995023510831e-01, err = 6.1042996833236707e-01 +CostJo : Nonlinear Jo(SeaIceFraction) = 1.9774222033107372e+02, nobs = 24, Jo/n = 8.2392591804614046e+00, err = 1.0000000149011612e-01 +CostJo : Nonlinear Jo(SurfaceU) = 4.8960817822670860e-01, nobs = 47, Jo/n = 1.0417195281419331e-02, err = 3.8763169345842458e-01 +CostFunction: Nonlinear J = 5.6229808157157213e+03 +RPCGMinimizer: reduction in residual norm = 5.3281254594664873e-01 CostFunction::addIncrement: Analysis: Valid time: 2018-04-15T00:00:00Z - cicen min=-0.0023081640292671 max=1.0069589746383956 mean=0.1182667192938162 + cicen min=-0.0025196085152986 max=1.0071706445543214 mean=0.1183057762690204 hicen min=0.0000000000000000 max=4.0326673084246947 mean=0.4712515705773916 - socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5448011509061246 - tocn min=-1.8883899372702533 max=34.9467200164778191 mean=6.0306130214233562 - uocn min=-0.8581723640018309 max=0.7001199981293115 mean=-0.0002591153419329 + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5448198880093003 + tocn min=-1.8883899372702533 max=34.8892618778720873 mean=6.0320785119669624 + uocn min=-0.8581746643255235 max=0.7001206137637456 mean=-0.0002590969203429 vocn min=-0.7661101215480253 max=1.4377766409421606 mean=0.0021972630399530 - ssh min=-1.9233241368623117 max=0.9260032295261909 mean=-0.2767309144919679 + ssh min=-1.9227877278789181 max=0.9259686741229282 mean=-0.2766955473164547 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 sw min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 lhf min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 @@ -36,13 +36,13 @@ layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.522 -CostJb : Nonlinear Jb = 279.9394197974504550 -CostJo : Nonlinear Jo(CoolSkin) = 3440.4450658851174012, nobs = 47, Jo/n = 73.2009588486195213, err = 0.3876316934584246 -CostJo : Nonlinear Jo(SeaSurfaceTemp) = 974.5843784850217162, nobs = 43, Jo/n = 22.6647529880237606, err = 0.3858153492966185 -CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 2.6121336586950621, nobs = 17, Jo/n = 0.1536549210997095, err = 1.0000000000000000 -CostJo : Nonlinear Jo(ADT) = 87.2766562461966515, nobs = 29, Jo/n = 3.0095398705585050, err = 0.1000000014901161 -CostJo : Nonlinear Jo(InsituTemperature) = 36.2267410466876498, nobs = 31, Jo/n = 1.1686045498931501, err = 0.9089399165824681 -CostJo : Nonlinear Jo(InsituSalinity) = 16.5292041808890886, nobs = 33, Jo/n = 0.5008849751784572, err = 0.6104299683323671 -CostJo : Nonlinear Jo(SeaIceFraction) = 190.6732775782927263, nobs = 24, Jo/n = 7.9447198990955306, err = 0.1000000014901161 -CostJo : Nonlinear Jo(SurfaceU) = 0.4659840212169950, nobs = 47, Jo/n = 0.0099145536429148, err = 0.3876316934584246 -CostFunction: Nonlinear J = 5028.7528608995671675 +CostJb : Nonlinear Jb = 315.6280023700833226 +CostJo : Nonlinear Jo(CoolSkin) = 3432.3327115698070884, nobs = 47, Jo/n = 73.0283555653150387, err = 0.3876316934584246 +CostJo : Nonlinear Jo(SeaSurfaceTemp) = 991.0677681689126075, nobs = 43, Jo/n = 23.0480876318351768, err = 0.3858153492966185 +CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 2.6750772036788657, nobs = 17, Jo/n = 0.1573574825693450, err = 1.0000000000000000 +CostJo : Nonlinear Jo(ADT) = 87.5150111276131639, nobs = 29, Jo/n = 3.0177590044004541, err = 0.1000000014901161 +CostJo : Nonlinear Jo(InsituTemperature) = 36.1294749185645969, nobs = 31, Jo/n = 1.1654669328569225, err = 0.9089399165824681 +CostJo : Nonlinear Jo(InsituSalinity) = 16.2781987282261511, nobs = 33, Jo/n = 0.4932787493401864, err = 0.6104299683323671 +CostJo : Nonlinear Jo(SeaIceFraction) = 188.8912555943718417, nobs = 24, Jo/n = 7.8704689830988270, err = 0.1000000014901161 +CostJo : Nonlinear Jo(SurfaceU) = 0.4936754264781402, nobs = 47, Jo/n = 0.0105037324782583, err = 0.3876316934584246 +CostFunction: Nonlinear J = 5071.0111751077347435 diff --git a/test/testref/3dvarfgat_pseudo.test b/test/testref/3dvarfgat_pseudo.test index 6072de6f3..e94490b0d 100644 --- a/test/testref/3dvarfgat_pseudo.test +++ b/test/testref/3dvarfgat_pseudo.test @@ -1,16 +1,16 @@ CostJb : Nonlinear Jb = 0.0000000000000000e+00 -CostJo : Nonlinear Jo(SeaSurfaceTemp) = 3.1780648145948271e+02, nobs = 43, Jo/n = 7.3908484060344817e+00, err = 3.8581536591328441e-01 -CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 2.6167366978836499e+00, nobs = 17, Jo/n = 1.5392568811080293e-01, err = 1.0000000000000000e+00 -CostJo : Nonlinear Jo(ADT) = 8.7166288554315003e+01, nobs = 29, Jo/n = 3.0057340880798278e+00, err = 1.0000000149011612e-01 -CostJo : Nonlinear Jo(InsituTemperature) = 3.7309148937513228e+01, nobs = 31, Jo/n = 1.2035209334681687e+00, err = 9.0893990043753048e-01 -CostJo : Nonlinear Jo(InsituSalinity) = 1.6779698504915352e+01, nobs = 33, Jo/n = 5.0847571227016219e-01, err = 6.1042996877640276e-01 -CostFunction: Nonlinear J = 4.6167835415410991e+02 -RPCGMinimizer: reduction in residual norm = 1.9186911231850326e-01 +CostJo : Nonlinear Jo(SeaSurfaceTemp) = 3.1454830650364431e+02, nobs = 43, Jo/n = 7.3150768954335890e+00, err = 3.8581534929661854e-01 +CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 2.6796945834674828e+00, nobs = 17, Jo/n = 1.5762909314514606e-01, err = 1.0000000000000000e+00 +CostJo : Nonlinear Jo(ADT) = 8.7431459350288023e+01, nobs = 29, Jo/n = 3.0148779086306217e+00, err = 1.0000000149011612e-01 +CostJo : Nonlinear Jo(InsituTemperature) = 3.7253231588255915e+01, nobs = 31, Jo/n = 1.2017171480082554e+00, err = 9.0893991658246809e-01 +CostJo : Nonlinear Jo(InsituSalinity) = 1.6517158357758575e+01, nobs = 33, Jo/n = 5.0051995023510831e-01, err = 6.1042996833236707e-01 +CostFunction: Nonlinear J = 4.5842985038341430e+02 +RPCGMinimizer: reduction in residual norm = 1.7385847916791020e-01 CostFunction::addIncrement: Analysis: Valid time: 2018-04-15T00:00:00Z - socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5541574810123393 - tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0075174667606959 - ssh min=-2.0865904226925553 max=0.9615468660413907 mean=-0.3503315653442778 + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5502087568697647 + tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0080222038698352 + ssh min=-1.9554800289426133 max=1.5981030680627748 mean=-0.3217603882878646 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 uocn min=-0.8581693992488438 max=0.7000954286848975 mean=-0.0002591771954069 vocn min=-0.7661101215480253 max=1.4377766409421606 mean=0.0021972630399530 @@ -23,10 +23,10 @@ layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.522 -CostJb : Nonlinear Jb = 931.2855866357992909 -CostJo : Nonlinear Jo(SeaSurfaceTemp) = 311.9961441522754626, nobs = 43, Jo/n = 7.2557242826110571, err = 0.3858153659132844 -CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 2.6167366978836499, nobs = 17, Jo/n = 0.1539256881108029, err = 1.0000000000000000 -CostJo : Nonlinear Jo(ADT) = 52.8891580740285505, nobs = 29, Jo/n = 1.8237640715182259, err = 0.1000000014901161 -CostJo : Nonlinear Jo(InsituTemperature) = 37.3091489375132284, nobs = 31, Jo/n = 1.2035209334681687, err = 0.9089399004375305 -CostJo : Nonlinear Jo(InsituSalinity) = 16.7796985049153520, nobs = 33, Jo/n = 0.5084757122701622, err = 0.6104299687764028 -CostFunction: Nonlinear J = 1352.8764730024154233 +CostJb : Nonlinear Jb = 919.0150955744393286 +CostJo : Nonlinear Jo(SeaSurfaceTemp) = 309.0529570232815786, nobs = 43, Jo/n = 7.1872780703088743, err = 0.3858153492966185 +CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 2.6796945834674828, nobs = 17, Jo/n = 0.1576290931451461, err = 1.0000000000000000 +CostJo : Nonlinear Jo(ADT) = 49.3820436185993970, nobs = 29, Jo/n = 1.7028290902965308, err = 0.1000000014901161 +CostJo : Nonlinear Jo(InsituTemperature) = 37.2532315882559146, nobs = 31, Jo/n = 1.2017171480082554, err = 0.9089399165824681 +CostJo : Nonlinear Jo(InsituSalinity) = 16.5171583577585750, nobs = 33, Jo/n = 0.5005199502351083, err = 0.6104299683323671 +CostFunction: Nonlinear J = 1333.9001807458021176 diff --git a/test/testref/3dvarlowres_soca.test b/test/testref/3dvarlowres_soca.test index 6f01c506d..c7d03ae94 100644 --- a/test/testref/3dvarlowres_soca.test +++ b/test/testref/3dvarlowres_soca.test @@ -1,16 +1,16 @@ CostJb : Nonlinear Jb = 0.0000000000000000e+00 -CostJo : Nonlinear Jo(SeaSurfaceTemp) = 7.8349275156178805e+02, nobs = 148, Jo/n = 5.2938699429850544e+00, err = 3.6139743385133083e-01 -CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 4.9679661574589502e+01, nobs = 51, Jo/n = 9.7411101126646082e-01, err = 1.0000000000000000e+00 -CostJo : Nonlinear Jo(ADT) = 1.2846395537995426e+02, nobs = 87, Jo/n = 1.4765971882753364e+00, err = 1.0000000149011612e-01 -CostJo : Nonlinear Jo(InsituTemperature) = 3.4357440141216813e+02, nobs = 206, Jo/n = 1.6678369000590685e+00, err = 8.9914415723945484e-01 -CostJo : Nonlinear Jo(InsituSalinity) = 3.4655673420278879e+02, nobs = 218, Jo/n = 1.5897097899210495e+00, err = 6.0819699545777528e-01 -CostFunction: Nonlinear J = 1.6517675041312887e+03 -RPCGMinimizer: reduction in residual norm = 1.0577708381511183e-01 +CostJo : Nonlinear Jo(SeaSurfaceTemp) = 7.8439244494350282e+02, nobs = 148, Jo/n = 5.2999489523209649e+00, err = 3.6139743385133083e-01 +CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 4.7466980363687938e+01, nobs = 50, Jo/n = 9.4933960727375877e-01, err = 1.0000000000000000e+00 +CostJo : Nonlinear Jo(ADT) = 1.3007470268433724e+02, nobs = 87, Jo/n = 1.4951115251073246e+00, err = 1.0000000149011612e-01 +CostJo : Nonlinear Jo(InsituTemperature) = 3.5714312918688563e+02, nobs = 206, Jo/n = 1.7337045106159497e+00, err = 8.9914415723945484e-01 +CostJo : Nonlinear Jo(InsituSalinity) = 3.4688287576640801e+02, nobs = 218, Jo/n = 1.5912058521394863e+00, err = 6.0819699545777528e-01 +CostFunction: Nonlinear J = 1.6659601329448217e+03 +RPCGMinimizer: reduction in residual norm = 9.9782677135287226e-02 CostFunction::addIncrement: Analysis: Valid time: 2018-04-15T00:00:00Z - socn min=10.7211321702112450 max=40.4416937318713892 mean=34.5452612159349073 - tocn min=-1.9924644486895162 max=32.0033142104850512 mean=6.0270311615198819 - ssh min=-2.0047075305248567 max=0.9082175452289394 mean=-0.2788411193911333 + socn min=10.7212756423771669 max=40.4416945098767044 mean=34.5453564323479583 + tocn min=-2.0266830123110844 max=32.1036940001155742 mean=6.0272609036031701 + ssh min=-2.0038732217217592 max=0.9043564910669520 mean=-0.2779159116943226 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 mld min=2.2854716757984130 max=4593.1533423819937525 mean=192.4109073940401515 layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.5229536158392420 @@ -21,10 +21,10 @@ layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.522 -CostJb : Nonlinear Jb = 275.0276207267167479 -CostJo : Nonlinear Jo(SeaSurfaceTemp) = 299.7316436365123877, nobs = 148, Jo/n = 2.0252138083548132, err = 0.3613974338513308 -CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 49.7183085773384477, nobs = 51, Jo/n = 0.9748687956340872, err = 1.0000000000000000 -CostJo : Nonlinear Jo(ADT) = 90.0817750889277420, nobs = 87, Jo/n = 1.0354227021715832, err = 0.1000000014901161 -CostJo : Nonlinear Jo(InsituTemperature) = 141.6604768580295968, nobs = 206, Jo/n = 0.6876722177574253, err = 0.8991441572394548 -CostJo : Nonlinear Jo(InsituSalinity) = 291.8347806154215505, nobs = 218, Jo/n = 1.3386916541991813, err = 0.6081969954577753 -CostFunction: Nonlinear J = 1148.0546055029465151 +CostJb : Nonlinear Jb = 329.0732476489210967 +CostJo : Nonlinear Jo(SeaSurfaceTemp) = 303.8263570221579357, nobs = 148, Jo/n = 2.0528807906902564, err = 0.3613974338513308 +CostJo : Nonlinear Jo(SeaSurfaceSalinity) = 47.5076374445173926, nobs = 50, Jo/n = 0.9501527488903478, err = 1.0000000000000000 +CostJo : Nonlinear Jo(ADT) = 92.8506641080837767, nobs = 87, Jo/n = 1.0672490127365952, err = 0.1000000014901161 +CostJo : Nonlinear Jo(InsituTemperature) = 139.9612611491145913, nobs = 206, Jo/n = 0.6794235978112358, err = 0.8991441572394548 +CostJo : Nonlinear Jo(InsituSalinity) = 292.3735989580471255, nobs = 218, Jo/n = 1.3411632979726933, err = 0.6081969954577753 +CostFunction: Nonlinear J = 1205.5927663308418687 diff --git a/test/testref/4denvar.test b/test/testref/4denvar.test new file mode 100644 index 000000000..62755f3a9 --- /dev/null +++ b/test/testref/4denvar.test @@ -0,0 +1,35 @@ +CostJb : Nonlinear Jb = 0.0000000000000000e+00 +CostJo : Nonlinear Jo(SeaSufaceTemp) = 3.4227236951951875e+02, nobs = 47, Jo/n = 7.2823908408408240e+00, err = 3.8763169345842458e-01 +CostFunction: Nonlinear J = 3.4227236951951875e+02 +DRIPCGMinimizer: reduction in residual norm = 2.9427640167086277e-02 +CostFunction::addIncrement: Analysis: + Valid time: 2018-04-15T00:00:00Z + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5443897261524953 + tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0173355430613267 + uocn min=-0.8581693992488438 max=0.7000954286848975 mean=-0.0002591771954069 + vocn min=-0.7661101215480253 max=1.4377766409421606 mean=0.0021972630399530 + ssh min=-1.9244847628277935 max=0.9272826517867588 mean=-0.2767903423591662 + hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 +layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.5229536158392420 + Valid time: 2018-04-15T03:00:00Z + socn min=10.7210460395083924 max=40.4416591681037119 mean=34.5459713920834233 + tocn min=-1.8879950757380115 max=31.6932489128285653 mean=6.0154433795887590 + uocn min=-0.8496117748396494 max=0.6890666856088563 mean=0.0000321916028576 + vocn min=-0.9321576238931384 max=0.9467331169326910 mean=0.0016143192702768 + ssh min=-1.9092725357352314 max=0.9091665415750726 mean=-0.2765781634769230 + hocn min=0.0009178261947465 max=1346.5803472041777695 mean=128.6280879778919370 +layer_depth min=2.2774359470406269 max=5658.2958090376268956 mean=1200.5228825300762310 + Valid time: 2018-04-15T06:00:00Z + socn min=10.7210460395083924 max=40.4416591598428923 mean=34.5467399790273930 + tocn min=-1.8874921066163295 max=31.6858695414581994 mean=6.0149529664159935 + uocn min=-0.8416820355059554 max=0.6786386084306094 mean=0.0002717176669510 + vocn min=-1.1593584500375382 max=0.9487438635750088 mean=0.0003618099374769 + ssh min=-1.9078432544437094 max=0.9075559090823697 mean=-0.2765830659083295 + hocn min=0.0008423557142235 max=1347.8173897171482167 mean=128.6280410343347285 +layer_depth min=2.2683307266867532 max=5658.3141547773811908 mean=1200.5223352906537002 + + + +CostJb : Nonlinear Jb = 63.2055240418158419 +CostJo : Nonlinear Jo(SeaSufaceTemp) = 83.7000250309115188, nobs = 47, Jo/n = 1.7808515964023728, err = 0.3876316934584246 +CostFunction: Nonlinear J = 146.9055490727273536 diff --git a/test/testref/4dhybenvar.test b/test/testref/4dhybenvar.test new file mode 100644 index 000000000..b0205511b --- /dev/null +++ b/test/testref/4dhybenvar.test @@ -0,0 +1,35 @@ +CostJb : Nonlinear Jb = 0.0000000000000000e+00 +CostJo : Nonlinear Jo(SeaSufaceTemp) = 3.4227236951951875e+02, nobs = 47, Jo/n = 7.2823908408408240e+00, err = 3.8763169345842458e-01 +CostFunction: Nonlinear J = 3.4227236951951875e+02 +DRIPCGMinimizer: reduction in residual norm = 3.8967484759883209e-02 +CostFunction::addIncrement: Analysis: + Valid time: 2018-04-15T00:00:00Z + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5443897261524953 + tocn min=-1.8883876408043290 max=31.7004614942092680 mean=6.0159408762362077 + uocn min=-0.8581693992488438 max=0.7000954286848975 mean=-0.0002591771954069 + vocn min=-0.7661101215480253 max=1.4377766409421606 mean=0.0021972630399530 + ssh min=-1.9244847628277935 max=0.9272826517867588 mean=-0.2767903423591662 + hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 +layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.5229536158392420 + Valid time: 2018-04-15T03:00:00Z + socn min=10.7210460395083924 max=40.4416591681037119 mean=34.5459713920834233 + tocn min=-1.8879927792720872 max=31.6932458349719752 mean=6.0140486914996512 + uocn min=-0.8496117748396494 max=0.6890666856088563 mean=0.0000321916028576 + vocn min=-0.9321576238931384 max=0.9467331169326910 mean=0.0016143192702768 + ssh min=-1.9092725357352314 max=0.9091665415750726 mean=-0.2765781634769230 + hocn min=0.0009178261947465 max=1346.5803472041777695 mean=128.6280879778919370 +layer_depth min=2.2774359470406269 max=5658.2958090376268956 mean=1200.5228825300762310 + Valid time: 2018-04-15T06:00:00Z + socn min=10.7210460395083924 max=40.4416591598428923 mean=34.5467399790273930 + tocn min=-1.8874898101504052 max=31.6858664636016094 mean=6.0135583206575083 + uocn min=-0.8416820355059554 max=0.6786386084306094 mean=0.0002717176669510 + vocn min=-1.1593584500375382 max=0.9487438635750088 mean=0.0003618099374769 + ssh min=-1.9078432544437094 max=0.9075559090823697 mean=-0.2765830659083295 + hocn min=0.0008423557142235 max=1347.8173897171482167 mean=128.6280410343347285 +layer_depth min=2.2683307266867532 max=5658.3141547773811908 mean=1200.5223352906537002 + + + +CostJb : Nonlinear Jb = 25.7042557933505016 +CostJo : Nonlinear Jo(SeaSufaceTemp) = 13.9745147688376683, nobs = 47, Jo/n = 0.2973301014646312, err = 0.3876316934584246 +CostFunction: Nonlinear J = 39.6787705621881699 diff --git a/test/testref/addincrement.test b/test/testref/addincrement.test index 0148c8b94..3ceb3fef6 100644 --- a/test/testref/addincrement.test +++ b/test/testref/addincrement.test @@ -14,15 +14,15 @@ layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.522 Increment: Valid time: 2018-04-15T00:00:00Z hsnon min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 - socn min=-0.0001053508048706 max=0.0036695245546320 mean=0.0000025961995222 - tocn min=-0.0938132581918806 max=0.0916756132663934 mean=0.0007788315484231 + socn min=-0.0001102819904892 max=0.0038751719650420 mean=0.0000028686591882 + tocn min=-0.0978163505349535 max=0.0746414324010661 mean=0.0008327865579380 State plus increment: Valid time: 2018-04-15T00:00:00Z cicen min=0.0000000000000000 max=1.0000000000000000 mean=0.1175125761012928 hicen min=0.0000000000000000 max=4.0326673084246947 mean=0.4712515705773916 hsnon min=0.0000000000000000 max=1.2712833951042413 mean=0.0886865877527975 - socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5443923223520315 - tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0183437899017829 + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5443925948116970 + tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0183977449112982 ssh min=-1.9244847628277935 max=0.9272826517867588 mean=-0.2767903423591662 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 uocn min=-0.8581693992488438 max=0.7000954286848975 mean=-0.0002591771954069 diff --git a/test/testref/checkpointmodel.test b/test/testref/checkpointmodel.test index e699ccff1..2c24dcf5c 100644 --- a/test/testref/checkpointmodel.test +++ b/test/testref/checkpointmodel.test @@ -7,12 +7,12 @@ input background: analysis: Valid time: 2018-04-15T00:00:00Z - socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5443923223520315 - tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0183437899017829 + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5443925948116970 + tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0183977449112982 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 output background: Valid time: 2018-04-15T00:00:00Z - socn min=10.7210460395083924 max=38.0000000000000000 mean=34.5397727334798290 - tocn min=-1.8000000000000000 max=31.7004645720658580 mean=6.0184822134112945 + socn min=10.7210460395083924 max=38.0000000000000000 mean=34.5397730059394945 + tocn min=-1.8000000000000000 max=31.7004645720658580 mean=6.0185360887081467 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 diff --git a/test/testref/convertincrement.test b/test/testref/convertincrement.test index 6da2a9430..269f7ce15 100644 --- a/test/testref/convertincrement.test +++ b/test/testref/convertincrement.test @@ -1,8 +1,8 @@ Input increment: Valid time: 2018-04-15T00:00:00Z - tocn min=-0.0938132581918806 max=0.0916756132663934 mean=0.0007788315484231 - socn min=-0.0001053508048706 max=0.0036695245546320 mean=0.0000025961995222 - ssh min=-0.0001335113919512 max=0.0005900187800294 mean=0.0000039425677270 + tocn min=-0.0978163505349535 max=0.0746414324010661 mean=0.0008327865579380 + socn min=-0.0001102819904892 max=0.0038751719650420 mean=0.0000028686591882 + ssh min=-0.0001366142872018 max=0.0006271514953045 mean=0.0000040810294429 hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 Trajectory state: Valid time: 2018-04-15T00:00:00Z @@ -14,7 +14,7 @@ layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.522 mld min=2.2854716757984130 max=4593.1533423819937525 mean=192.4109073940401515 Output increment: Valid time: 2018-04-15T00:00:00Z - tocn min=-0.0938132581918806 max=0.0916756132663934 mean=0.0007788315484231 - socn min=-0.0001053508048706 max=0.0036695245546320 mean= -nan - ssh min=-0.0005646980045385 max=0.0015930535209445 mean=0.0000282744256740 + tocn min=-0.0978163505349535 max=0.0746414324010661 mean=0.0008327865579380 + socn min=-0.0001102819904892 max=0.0038751719650420 mean= -nan + ssh min=-0.0005848471049477 max=0.0016934357214616 mean=0.0000304786595822 hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 diff --git a/test/testref/convertstate.test b/test/testref/convertstate.test index b6e381bf9..e238912cd 100644 --- a/test/testref/convertstate.test +++ b/test/testref/convertstate.test @@ -10,11 +10,11 @@ Input state: layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.5229536158392420 Output state: Valid time: 2018-04-15T00:00:00Z - ssh min=-1.8247663898160464 max=0.8754488653953552 mean=-0.2157259306724754 - tocn min=-1.7627474639148779 max=30.6462291406405924 mean=6.5488993098325086 - socn min=21.1220004091159090 max=39.8773275065078465 mean=34.5925602274981330 - uocn min=-0.6053122505889417 max=0.4394609260921547 mean=0.0019634499465369 + ssh min=-1.8247663898160460 max=0.8754488653953553 mean=-0.2370464685879062 + tocn min=-1.7627474639148777 max=30.6462291406405924 mean=6.5488457061067527 + socn min=21.1220004091159055 max=39.8773275065078465 mean=34.5925603198162932 + uocn min=-0.6053122505889417 max=0.4394609260921547 mean=0.0019634499466086 vocn min=-0.3898934472093633 max=0.4650035779038382 mean=0.0011324266369943 hocn min=0.0009999999999977 max=1345.6400000000001000 mean=132.2975966204909071 - cicen min=0.0000000000000000 max=0.9999976739797163 mean=0.1426714754570898 + cicen min=0.0000000000000000 max=0.9999976739797164 mean=0.1426714754570898 layer_depth min=2.4370615877370501 max=5587.8978052886013757 mean=1243.8222388394297013 diff --git a/test/testref/convertstate_soca2cice.test b/test/testref/convertstate_soca2cice.test index 58eeeaa5a..03ce06fe1 100644 --- a/test/testref/convertstate_soca2cice.test +++ b/test/testref/convertstate_soca2cice.test @@ -1,9 +1,9 @@ Input state: Valid time: 2018-04-15T00:00:00Z - tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0197585704204633 - socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5443974458897145 + tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0183977449113044 + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5443925948116970 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065018753 - cicen min=-0.0002610493467567 max=1.0002321432427876 mean=0.1175353756315750 + cicen min=-0.0000563665143372 max=1.0003307403191071 mean=0.1175499389485267 hicen min=0.0000000000000000 max=4.0326673084246947 mean=0.4712515705773919 hsnon min=0.0000000000000000 max=1.2712833951042413 mean=0.0886865877527975 Variable transform: @@ -11,17 +11,17 @@ Variable change from: 6 variables: tocn, socn, hocn, cicen, hicen, hsnon Variable change to: 6 variables: tocn, socn, hocn, cicen, hicen, hsnon State after variable transform: Valid time: 2018-04-15T00:00:00Z - tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0197585704204633 - socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5443974458897145 + tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0183977449113044 + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5443925948116970 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065018753 - cicen min=0.0000000000000000 max=1.0000000000000002 mean=0.1168306147663568 - hicen min=0.0000000000000000 max=4.0326673084246938 mean=0.2834277477476669 - hsnon min=0.0000000000000000 max=1.2712833951042415 mean=0.0433601452113457 + cicen min=0.0000000000000000 max=1.0000000000000002 mean=0.1168440623576960 + hicen min=0.0000000000000000 max=4.0326673084246947 mean=0.2834314591631395 + hsnon min=0.0000000000000000 max=1.2712833951042413 mean=0.0433607663153277 Output state: Valid time: 2018-04-15T00:00:00Z - tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0197585704204633 - socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5443974458897145 + tocn min=-1.8883899372702533 max=31.7004645720658580 mean=6.0183977449113044 + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5443925948116970 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065018753 - cicen min=0.0000000000000000 max=1.0000000000000002 mean=0.1168306147663568 - hicen min=0.0000000000000000 max=4.0326673084246938 mean=0.2834277477476669 - hsnon min=0.0000000000000000 max=1.2712833951042415 mean=0.0433601452113457 + cicen min=0.0000000000000000 max=1.0000000000000002 mean=0.1168440623576960 + hicen min=0.0000000000000000 max=4.0326673084246947 mean=0.2834314591631395 + hsnon min=0.0000000000000000 max=1.2712833951042413 mean=0.0433607663153277 diff --git a/test/testref/dirac_diffusion.test b/test/testref/dirac_diffusion.test new file mode 100644 index 000000000..e7f6da020 --- /dev/null +++ b/test/testref/dirac_diffusion.test @@ -0,0 +1,20 @@ +Input Dirac increment: + Valid time: 2018-04-15T00:00:00Z + cicen min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 + hicen min=0.0000000000000000 max=1.0000000000000000 mean=0.0006086427267194 + socn min=0.0000000000000000 max=1.0000000000000000 mean=0.0000243457090688 + tocn min=0.0000000000000000 max=1.0000000000000000 mean=0.0000973828362751 + ssh min=0.0000000000000000 max=1.0000000000000000 mean=0.0006086427267194 + hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 + mld min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 +layer_depth min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 +Covariance(SABER) * Increment: + Valid time: 2018-04-15T00:00:00Z + cicen min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 + hicen min=0.0000000000000000 max=1.0000000000000000 mean=0.0006086427267194 + socn min=0.0000000000000000 max=1.0191729439161608 mean=0.0022514020780945 + tocn min=0.0000000000000000 max=1.0323141860973646 mean=0.0144469563512630 + ssh min=0.0000000000000000 max=0.9936842484289256 mean=0.0355457939219269 + hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 + mld min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 +layer_depth min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 diff --git a/test/testref/dirac_soca_cor_nicas_scales.test b/test/testref/dirac_soca_cor_nicas_scales.test index 5dc93104a..a05ec036a 100644 --- a/test/testref/dirac_soca_cor_nicas_scales.test +++ b/test/testref/dirac_soca_cor_nicas_scales.test @@ -8,9 +8,9 @@ Input Dirac increment: hicen min=0.0000000000000000 max=1.0000000000000000 mean=0.0006086427267194 Covariance(SABER) * Increment: Valid time: 2018-04-15T00:00:00Z - socn min=0.0000000000000000 max=1.0000000000000002 mean=0.0340141737787489 - tocn min=0.0000000000000000 max=1.0048129708997011 mean=0.3536185118881098 + socn min=0.0000000000000000 max=1.0000000000000000 mean=0.0475378607002948 + tocn min=0.0000000000000000 max=1.5290573299466188 mean=0.3842471407766461 ssh min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 cicen min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 - hicen min=0.0000000000000000 max=0.9999999999999998 mean=0.2640285296287256 + hicen min=0.0000000000000000 max=0.9999999999999999 mean=0.2715365076280348 diff --git a/test/testref/dirac_soca_cov.test b/test/testref/dirac_soca_cov.test index bc8a36669..4f254ef52 100644 --- a/test/testref/dirac_soca_cov.test +++ b/test/testref/dirac_soca_cov.test @@ -12,13 +12,13 @@ Input Dirac increment: layer_depth min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 Covariance(SocaError) * Increment: Valid time: 2018-04-15T00:00:00Z - cicen min=-0.0035609555945749 max=0.0000000000000000 mean=-0.0000247866160204 - hicen min=0.0000000000000000 max=100.0000000000000000 mean=0.8687764074426576 - socn min=-0.0233861103420420 max=0.1032943622422105 mean=0.0003208834542677 - tocn min=0.0000000000000000 max=5.2687160390820811 mean=0.0230427116030840 - uocn min=0.0000000000000000 max=0.0022948056889126 mean=0.0000004281518965 + cicen min=-0.0036089461537001 max=0.0000000000000000 mean=-0.0000275624556497 + hicen min=0.0000000000000000 max=100.0000000000000142 mean=0.9283225798949805 + socn min=-0.0335232487284927 max=0.1085429089450220 mean=0.0003666358672174 + tocn min=0.0000000000000000 max=5.2687160390820855 mean=0.0249020307148332 + uocn min=0.0000000000000000 max=0.0023306838654550 mean=0.0000004409841843 vocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 - ssh min=-0.0013735744357345 max=0.0505217197847119 mean=0.0008502024507618 + ssh min=-0.0014883931115266 max=0.0505217197847120 mean=0.0009123179536632 hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 mld min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 layer_depth min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 diff --git a/test/testref/dirac_soca_mask.test b/test/testref/dirac_soca_mask.test index aab957e37..47d081f5a 100644 --- a/test/testref/dirac_soca_mask.test +++ b/test/testref/dirac_soca_mask.test @@ -13,7 +13,7 @@ Covariance(SocaError) * Increment: cicen min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 hicen min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 socn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 - tocn min=0.0000000000000000 max=1.0000000000000004 mean=0.0045856545712703 + tocn min=0.0000000000000000 max=1.0000000000000007 mean=0.0047334082530769 ssh min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 mld min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 diff --git a/test/testref/dirac_soca_nomask.test b/test/testref/dirac_soca_nomask.test index 939b29584..ef16ef75e 100644 --- a/test/testref/dirac_soca_nomask.test +++ b/test/testref/dirac_soca_nomask.test @@ -13,7 +13,7 @@ Covariance(SocaError) * Increment: cicen min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 hicen min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 socn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 - tocn min=0.0000000000000000 max=1.0096147233187933 mean=0.0066552713504880 + tocn min=0.0000000000000000 max=1.0086683962751792 mean=0.0067775864035004 ssh min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 mld min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 diff --git a/test/testref/dirac_socahyb_cov.test b/test/testref/dirac_socahyb_cov.test index 327f3ac15..2470ec560 100644 --- a/test/testref/dirac_socahyb_cov.test +++ b/test/testref/dirac_socahyb_cov.test @@ -12,49 +12,59 @@ Input Dirac increment: layer_depth min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 Covariance(hybrid) * Increment: Valid time: 2018-04-15T00:00:00Z - cicen min=-0.0037308136145732 max=0.0033832945797879 mean=-0.0000239489125803 - hicen min=-0.0695877305207310 max=50.1073013980972064 mean=0.4362425959632968 - socn min=-0.2786405474614049 max=0.4244134146865415 mean=0.0012228353313886 - tocn min=-0.1747800608295167 max=3.5877887758283302 mean=0.0165511115136579 - uocn min=-0.0019323054461836 max=0.0022913098573106 mean=-0.0000004682690009 - vocn min=-0.0009548976692089 max=0.0010971516760553 mean=0.0000002759338063 - ssh min=-0.0849196475090573 max=0.0573102079546577 mean=-0.0001552497512365 + cicen min=-0.0037817675761708 max=0.0033988463061122 mean=-0.0000256316823098 + hicen min=-0.0741129795689144 max=50.1073013980972135 mean=0.4660442760971388 + socn min=-0.2824804962843228 max=0.4340045998546954 mean=0.0012619628223484 + tocn min=-0.1762875582777306 max=3.5877887758283329 mean=0.0173674161728604 + uocn min=-0.0019323054461836 max=0.0022913098573106 mean=-0.0000004686539247 + vocn min=-0.0009570793926929 max=0.0011305048458118 mean=0.0000002771043880 + ssh min=-0.0905081118371923 max=0.0589716992294776 mean=-0.0001573659445746 hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 - mld min=-60.6461415802428760 max=525.5278285284309732 mean=1.3267794217865554 + mld min=-68.9457053290824149 max=531.2265534461570269 mean=1.3585694060809876 layer_depth min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 Covariance(hybrid1_SocaError) * Increment: Valid time: 2018-04-15T00:00:00Z - cicen min=-0.0035609555945749 max=0.0000000000000000 mean=-0.0000208731031462 - hicen min=0.0000000000000000 max=100.0000000000000000 mean=0.8687764074426576 - socn min=-0.0233861103420420 max=0.0465023712609259 mean=0.0000022025816480 - tocn min=0.0000000000000000 max=5.2687160390820811 mean=0.0208650940486405 - uocn min=0.0000000000000000 max=0.0022948056889126 mean=0.0000004281518965 + cicen min=-0.0036091083138408 max=0.0000000000000000 mean=-0.0000222570776912 + hicen min=0.0000000000000000 max=100.0000000000000142 mean=0.9283225798949803 + socn min=-0.0236417547391914 max=0.0472145291855424 mean=0.0000026262434480 + tocn min=0.0000000000000000 max=5.2687160390820855 mean=0.0220591322073391 + uocn min=0.0000000000000000 max=0.0023306838654550 mean=0.0000004409841843 vocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 - ssh min=0.0000000000000000 max=0.0505217197847119 mean=0.0007687680519747 + ssh min=0.0000000000000000 max=0.0505217197847120 mean=0.0008077940159867 hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 mld min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 layer_depth min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 Covariance(hybrid2_ensemble) * Increment: Valid time: 2018-04-15T00:00:00Z - cicen min=-0.0047588985877249 max=0.0075467744245189 mean=-0.0000270247220144 - hicen min=-0.1391754610414619 max=0.3754297229138135 mean=0.0037087844839362 - socn min=-0.5572810949228099 max=0.8488268293730830 mean=0.0024434680811292 - tocn min=-0.3495601216590334 max=2.4481918444150668 mean=0.0122371289786754 - uocn min=-0.0038646108923672 max=0.0045826197146212 mean=-0.0000013646898984 - vocn min=-0.0019097953384178 max=0.0021943033521106 mean=0.0000005518676125 - ssh min=-0.1847244457046184 max=0.0930010755515401 mean=-0.0010792675544476 + cicen min=-0.0049668146910638 max=0.0075881502357951 mean=-0.0000290062869284 + hicen min=-0.1482259591378288 max=0.3806035245579948 mean=0.0037659722992973 + socn min=-0.5649609925686456 max=0.8680091997093907 mean=0.0025212994012489 + tocn min=-0.3525751165554611 max=2.4747384425302226 mean=0.0126757001383816 + uocn min=-0.0038646108923672 max=0.0045826197146212 mean=-0.0000013782920337 + vocn min=-0.0019141587853859 max=0.0022610096916236 mean=0.0000005542087760 + ssh min=-0.1967369673926479 max=0.0958284039654625 mean=-0.0011225259051359 hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 - mld min=-121.2922831604857521 max=1051.0556570568619463 mean=2.6535588435731108 + mld min=-137.8914106581648298 max=1062.4531068923140538 mean=2.7171388121619753 layer_depth min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 +Localization(hybrid2_ensemble_localization) diagnostics: +- Localization at zero separation: + + Value for variable hicen, subwindow 0, at (longitude, latitude, vertical index) point (-202.50000, -62.50000, 1): 1.0000000000000002e+00 + + Value for variable socn, subwindow 0, at (longitude, latitude, vertical index) point (-122.46168, 71.13133, 1): 1.0000000000000000e+00 + + Value for variable tocn, subwindow 0, at (longitude, latitude, vertical index) point (-277.50000, -47.50000, 1): 1.0000000000000007e+00 + + Value for variable tocn, subwindow 0, at (longitude, latitude, vertical index) point (-197.50000, 17.50000, 5): 9.9999999999999944e-01 + + Value for variable tocn, subwindow 0, at (longitude, latitude, vertical index) point (32.50000, 42.50000, 1): 9.9999999999999989e-01 + + Value for variable tocn, subwindow 0, at (longitude, latitude, vertical index) point (-27.50000, 57.50000, 1): 1.0000000000000002e+00 + + Value for variable uocn, subwindow 0, at (longitude, latitude, vertical index) point (-7.50000, -7.50000, 1): 9.9999999999999944e-01 + + Value for variable ssh, subwindow 0, at (longitude, latitude, vertical index) point (-77.50000, 7.50000, 1): 0.0000000000000000e+00 Localization(hybrid2_ensemble) * Increment: Valid time: 2018-04-15T00:00:00Z - cicen min=0.0000000000000000 max=1.0000000000000004 mean=0.0631746532288630 - hicen min=0.0000000000000000 max=1.0000000000000004 mean=0.0631746532288630 - socn min=0.0000000000000000 max=1.0000000000000004 mean=0.0630672903023646 - tocn min=0.0000000000000000 max=1.0000000000000004 mean=0.0630672903023646 - uocn min=0.0000000000000000 max=1.0000000000000004 mean=0.0619672590883402 - vocn min=0.0000000000000000 max=1.0000000000000004 mean=0.0616052717791618 - ssh min=0.0000000000000000 max=1.0000000000000004 mean=0.0631746532288630 - hocn min=0.0000000000000000 max=1.0000000000000004 mean=0.0630672903023646 - mld min=0.0000000000000000 max=1.0000000000000004 mean=0.0631746532288630 -layer_depth min=0.0000000000000000 max=1.0000000000000004 mean=0.0630672903023646 + cicen min=0.0000000000000000 max=1.0000000000000007 mean=0.0686773581172594 + hicen min=0.0000000000000000 max=1.0000000000000007 mean=0.0686773581172594 + socn min=0.0000000000000000 max=1.0000000000000007 mean=0.0685604451408007 + tocn min=0.0000000000000000 max=1.0000000000000007 mean=0.0685604451408007 + uocn min=0.0000000000000000 max=1.0000000000000007 mean=0.0665336927271454 + vocn min=0.0000000000000000 max=1.0000000000000007 mean=0.0657786918712790 + ssh min=0.0000000000000000 max=1.0000000000000007 mean=0.0686773581172594 + hocn min=0.0000000000000000 max=1.0000000000000007 mean=0.0685604451408007 + mld min=0.0000000000000000 max=1.0000000000000007 mean=0.0686773581172594 +layer_depth min=0.0000000000000000 max=1.0000000000000007 mean=0.0685604451408007 diff --git a/test/testref/enspert.test b/test/testref/enspert.test index 1ec095700..bf32b6988 100644 --- a/test/testref/enspert.test +++ b/test/testref/enspert.test @@ -20,17 +20,17 @@ Initial state: layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.5229536158392420 Member 0 final state: Valid time: 2018-04-15T06:00:00Z - cicen min=-0.0180955754853549 max=1.0154619226063759 mean=0.1166567187237659 - hicen min=-1.1890165225084572 max=4.4225078395956468 mean=0.4878445368603064 + cicen min=-0.0179477307495673 max=1.0153169498091159 mean=0.1165466656301739 + hicen min=-1.2273773517586548 max=4.4384636058585212 mean=0.4836261711443992 hsnon min=0.0000000000000000 max=1.2712833951042413 mean=0.0886865877527975 - socn min=10.7210460395083924 max=40.4416591783023520 mean=34.5474804194790579 - tocn min=-3.0346028010743273 max=31.7041894810928397 mean=6.0892597845774965 - uocn min=-0.8618188262973017 max=0.6951975908706787 mean=-0.0003002399277292 - vocn min=-0.8095623037177452 max=1.1783094051530068 mean=0.0020621902808385 - ssh min=-1.8905821325072507 max=0.9171609472788409 mean=-0.2767818007884086 - hocn min=0.0009718942572445 max=1345.9655205644394300 mean=128.6280649079521936 - chl min=-0.0346456156552588 max=4.6657951350551032 mean=0.1184774650131123 - biop min=-0.0000000010792964 max=0.0000001881576257 mean=0.0000000065411171 + socn min=10.7210460395083924 max=40.4416591783000712 mean=34.5473300596784441 + tocn min=-2.9515690032983817 max=31.6987106993547698 mean=6.0915201611419727 + uocn min=-0.8620325384384893 max=0.6951486388404980 mean=-0.0003028019202650 + vocn min=-0.8096150692197427 max=1.1786796751629223 mean=0.0020621981887290 + ssh min=-1.8879012293466213 max=0.9170828155466502 mean=-0.2767795213473463 + hocn min=0.0009718981829507 max=1345.9655010853768999 mean=128.6280651987137560 + chl min=-0.0347096422502860 max=4.6656789459435739 mean=0.1184735932868957 + biop min=-0.0000000010670083 max=0.0000001882111536 mean=0.0000000065412874 sw min=-225.0977630615234375 max=-0.0000000000000000 mean=-71.7393205198725354 lhf min=-38.1373977661132812 max=256.5976562500000000 mean=42.0100402226406899 shf min=-58.9492950439453125 max=201.3742980957031250 mean=6.0753344854805622 @@ -40,17 +40,17 @@ Member 0 final state: layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.5229536158392420 Member 1 final state: Valid time: 2018-04-15T06:00:00Z - cicen min=-0.0215236267512266 max=1.0125208022390715 mean=0.1167107628551369 - hicen min=-1.0658523758283109 max=4.6136403418154135 mean=0.5266782620691725 + cicen min=-0.0232472901189155 max=1.0122847550416991 mean=0.1167257873201370 + hicen min=-1.0660578510882317 max=4.6241796010597822 mean=0.5312867971814633 hsnon min=0.0000000000000000 max=1.2712833951042413 mean=0.0886865877527975 - socn min=10.7210460395083924 max=40.4416591799132661 mean=34.5062483129193538 - tocn min=-4.3527892363687934 max=32.1716440032313642 mean=5.9996297179408460 - uocn min=-0.8612379200915659 max=0.6956460681526615 mean=-0.0001684897472015 - vocn min=-0.8096924107049123 max=1.1407984886825635 mean=0.0019624415065930 - ssh min=-1.8679621858884223 max=0.9116899301489129 mean=-0.2767153738108127 - hocn min=0.0009445732089446 max=1346.2578679840287350 mean=128.6280814476713203 - chl min=-0.0289855887820164 max=4.6514396809792586 mean=0.1185532231894127 - biop min=-0.0000000013979299 max=0.0000001885820462 mean=0.0000000065387977 + socn min=10.7210460395083924 max=40.4416591799142537 mean=34.5053688155191409 + tocn min=-4.3506301350009116 max=32.2042125513730468 mean=5.9988769154588981 + uocn min=-0.8614391377078680 max=0.6956445378249836 mean=-0.0001691264533084 + vocn min=-0.8098303351350450 max=1.1404127828961510 mean=0.0019618738177159 + ssh min=-1.8653863905924200 max=0.9116542010344340 mean=-0.2767100679432496 + hocn min=0.0009445692826222 max=1346.2515603948361331 mean=128.6280818753485846 + chl min=-0.0295705225910349 max=4.6513062465585113 mean=0.1185495590525884 + biop min=-0.0000000014227649 max=0.0000001886103201 mean=0.0000000065389500 sw min=-225.0977630615234375 max=-0.0000000000000000 mean=-71.7393205198725354 lhf min=-38.1373977661132812 max=256.5976562500000000 mean=42.0100402226406899 shf min=-58.9492950439453125 max=201.3742980957031250 mean=6.0753344854805622 @@ -60,17 +60,17 @@ Member 1 final state: layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.5229536158392420 Member 2 final state: Valid time: 2018-04-15T06:00:00Z - cicen min=-0.0217839784139593 max=1.0135664998925267 mean=0.1170037453526113 - hicen min=-1.0702692048053624 max=4.2897631773416807 mean=0.5197523608071601 + cicen min=-0.0240114302715288 max=1.0134258249588350 mean=0.1171379101209238 + hicen min=-1.0731683257961575 max=4.2637166258387866 mean=0.5242428246457037 hsnon min=0.0000000000000000 max=1.2712833951042413 mean=0.0886865877527975 - socn min=10.7210460395083924 max=40.4416591813400217 mean=34.5190502846994818 - tocn min=-3.6774466807639858 max=31.7294384181555564 mean=6.1017080713155725 - uocn min=-0.8527079719957523 max=0.6900307211562242 mean=-0.0002351898776744 - vocn min=-0.8081228648634390 max=1.2230267293973940 mean=0.0019664179836585 - ssh min=-1.8554279256511403 max=0.9099454891333590 mean=-0.2766017221739970 - hocn min=0.0009179243744965 max=1346.5440235208395734 mean=128.6280811165849514 - chl min=-0.0242260824668528 max=4.6851634656692536 mean=0.1184642679198311 - biop min=-0.0000000008814691 max=0.0000001879042331 mean=0.0000000065376670 + socn min=10.7210460395083924 max=40.4416591813473900 mean=34.5180354479406262 + tocn min=-3.6550415350812973 max=31.7303623333074931 mean=6.1038745493177933 + uocn min=-0.8527354111047408 max=0.6899570004276523 mean=-0.0002331691871794 + vocn min=-0.8082836103758393 max=1.2213721318293778 mean=0.0019622232505525 + ssh min=-1.8542140529770612 max=0.9099969529067288 mean=-0.2765945891721018 + hocn min=0.0009179199629318 max=1346.5391996900173126 mean=128.6280815294041133 + chl min=-0.0242344918332649 max=4.6854539925550318 mean=0.1184658525731263 + biop min=-0.0000000008753226 max=0.0000001878964701 mean=0.0000000065377026 sw min=-225.0977630615234375 max=-0.0000000000000000 mean=-71.7393205198725354 lhf min=-38.1373977661132812 max=256.5976562500000000 mean=42.0100402226406899 shf min=-58.9492950439453125 max=201.3742980957031250 mean=6.0753344854805622 @@ -80,17 +80,17 @@ Member 2 final state: layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.5229536158392420 Member 3 final state: Valid time: 2018-04-15T06:00:00Z - cicen min=-0.0195801063579778 max=1.0147719967288251 mean=0.1172820860076147 - hicen min=-1.1341861749030553 max=4.4599301342658908 mean=0.5181641291823246 + cicen min=-0.0217194858086926 max=1.0147606235466318 mean=0.1173610124689396 + hicen min=-1.2568327839592690 max=4.4544028614335236 mean=0.5230276029529948 hsnon min=0.0000000000000000 max=1.2712833951042413 mean=0.0886865877527975 - socn min=10.7210460395083924 max=40.4416591824183271 mean=34.5337425245469660 - tocn min=-2.9382471201647431 max=31.7406441563765469 mean=6.0345483358398653 - uocn min=-0.8567487147577495 max=0.6984678539990958 mean=-0.0001943514805072 - vocn min=-0.8030068089098755 max=1.1972014559128583 mean=0.0020539511619779 - ssh min=-1.8496740327525270 max=0.9120280276442039 mean=-0.2765355089165666 - hocn min=0.0008920106029951 max=1346.8098305246508062 mean=128.6280860382935316 - chl min=-0.0339131334494770 max=4.6937598186554741 mean=0.1184950507291665 - biop min=-0.0000000007072830 max=0.0000001876715923 mean=0.0000000065402892 + socn min=10.7210460395083924 max=40.4416591824269531 mean=34.5335504385732079 + tocn min=-2.9603827293771343 max=31.7375756291442492 mean=6.0348515736570718 + uocn min=-0.8568785328366367 max=0.6985426223296826 mean=-0.0001952346659818 + vocn min=-0.8030924790206806 max=1.1962722596214554 mean=0.0020544229255305 + ssh min=-1.8474816349167924 max=0.9121588912797869 mean=-0.2765272001340992 + hocn min=0.0008919956143453 max=1346.8077367450123347 mean=128.6280866039721218 + chl min=-0.0338003707368620 max=4.6945596057779229 mean=0.1184960634942794 + biop min=-0.0000000007022308 max=0.0000001877512722 mean=0.0000000065404235 sw min=-225.0977630615234375 max=-0.0000000000000000 mean=-71.7393205198725354 lhf min=-38.1373977661132812 max=256.5976562500000000 mean=42.0100402226406899 shf min=-58.9492950439453125 max=201.3742980957031250 mean=6.0753344854805622 @@ -100,17 +100,17 @@ Member 3 final state: layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.5229536158392420 Member 4 final state: Valid time: 2018-04-15T06:00:00Z - cicen min=-0.0195941332888099 max=1.0093198320940708 mean=0.1172744442785538 - hicen min=-1.1019240276229816 max=4.7377629969768993 mean=0.5021357777554611 + cicen min=-0.0197718401128528 max=1.0091688136045813 mean=0.1172909033586223 + hicen min=-1.1155308717945622 max=4.7092122161910979 mean=0.4994453858606065 hsnon min=0.0000000000000000 max=1.2712833951042413 mean=0.0886865877527975 - socn min=10.7210460395083924 max=40.4416591834512715 mean=34.5387781877921114 - tocn min=-4.7688220842238351 max=31.7683597112020806 mean=5.9949463806419976 - uocn min=-0.8553135755927049 max=0.6981189192611161 mean=-0.0002481375767763 - vocn min=-0.8098578415481051 max=1.1497701384094767 mean=0.0019866245418100 - ssh min=-1.8514675434009882 max=0.9119375302769742 mean=-0.2764841693985222 - hocn min=0.0008668131064307 max=1347.1257737543392068 mean=128.6280845260949377 - chl min=-0.0343124993979519 max=4.6755082537003148 mean=0.1185660150722009 - biop min=-0.0000000008706793 max=0.0000001882726144 mean=0.0000000065375605 + socn min=10.7210460395083924 max=40.4416591834597057 mean=34.5385488607189828 + tocn min=-4.8171336223355574 max=31.7744438625563212 mean=5.9939229008064574 + uocn min=-0.8554285548104850 max=0.6981012703078521 mean=-0.0002457408300107 + vocn min=-0.8097634889891272 max=1.1477557612142797 mean=0.0019882065569462 + ssh min=-1.8491618668484704 max=0.9121236566706767 mean=-0.2764747660188870 + hocn min=0.0008668009166667 max=1347.1244907586342379 mean=128.6280850949892169 + chl min=-0.0339841299535465 max=4.6753649218027249 mean=0.1185674716150973 + biop min=-0.0000000008837080 max=0.0000001882608358 mean=0.0000000065373823 sw min=-225.0977630615234375 max=-0.0000000000000000 mean=-71.7393205198725354 lhf min=-38.1373977661132812 max=256.5976562500000000 mean=42.0100402226406899 shf min=-58.9492950439453125 max=201.3742980957031250 mean=6.0753344854805622 diff --git a/test/testref/ensvariance.test b/test/testref/ensvariance.test deleted file mode 100644 index 8153dcfd2..000000000 --- a/test/testref/ensvariance.test +++ /dev/null @@ -1,13 +0,0 @@ -Variance: - - Valid time: 2018-04-15T00:00:00Z - cicen min=0.0000005644776545 max=0.0002974978151066 mean=0.0000536688167423 - hicen min=0.0010403766863014 max=0.8862874166279116 mean=0.1280217297454454 - socn min=0.0000000000000000 max=1.8239276341677120 mean=0.0465030040856202 - tocn min=0.0000000000000000 max=8.8471590101181157 mean=0.2647814800037334 - uocn min=0.0000000000000000 max=0.0001185072930010 mean=0.0000014279991402 - vocn min=0.0000000000000000 max=0.0000980437165757 mean=0.0000006838626020 - ssh min=0.0000000000000000 max=0.0705741193924168 mean=0.0033870718852192 - hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 - mld min=0.0000000000000000 max=3877611.9844329962506890 mean=44171.1704577814380173 -layer_depth min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 diff --git a/test/testref/hofx_3d.test b/test/testref/hofx_3d.test index 46f405069..8edf75240 100644 --- a/test/testref/hofx_3d.test +++ b/test/testref/hofx_3d.test @@ -15,29 +15,30 @@ State: lw min=0.0000000000000000 max=88.0360870361328125 mean=31.3955290035652546 us min=0.0043958698226386 max=0.0196578730801191 mean=0.0086443089692577 chl min=0.0000100000000000 max=4.6719899196170607 mean=0.1184829680403295 +dummy_atm1 min=5.0000000000000000 max=5.0000000000000000 mean=5.0000000000000000 H(x): -CoolSkin nobs= 200 Min=-4.1785594844341176, Max=25.2197343303870412, RMS=20.1355481819576383 +CoolSkin nobs= 198 Min=-4.1785594844341176, Max=25.2197343303870412, RMS=20.1798065565019620 -SeaSurfaceTemp nobs= 200 Min=-0.7441076047036211, Max=30.6558206487590255, RMS=24.2399178481423263 +SeaSurfaceTemp nobs= 198 Min=-0.7441076047036211, Max=30.6558206487590255, RMS=24.2869807837752916 -SeaSurfaceSalinity nobs= 100 Min=32.8836750765081902, Max=37.0801278476553193, RMS=34.7676006134783506 +SeaSurfaceSalinity nobs= 100 Min=31.5934910820588684, Max=37.0674151811271742, RMS=34.7564821394803047 -ADT nobs= 99 Min=-1.2334297014633941, Max=1.4139517986919645, RMS=0.7474487596218524 +ADT nobs= 99 Min=-1.2252936028075887, Max=1.4117661236744268, RMS=0.7466272517343979 -InsituTS nobs= 436 Min=7.7995978223639364, Max=36.0186808894957267, RMS=28.9607495930119256 +InsituTS nobs= 436 Min=7.7989863451624588, Max=36.0186808894957267, RMS=28.9635284888697910 -InsituTemperature nobs= 218 Min=7.7995978223639364, Max=30.4001198685169918, RMS=21.2243712881254147 +InsituTemperature nobs= 218 Min=7.7989863451624588, Max=30.4004959665826888, RMS=21.2323110390361585 -InsituSalinity nobs= 218 Min=34.1391348515148039, Max=36.0186808894957267, RMS=35.0282185873344005 +InsituSalinity nobs= 218 Min=34.1391348515148039, Max=36.0186808894957267, RMS=35.0280021267666299 -SeaIceFraction nobs= 96 Min=0.0000000000000000, Max=0.9999999999999999, RMS=0.6969513764074570 +SeaIceFraction nobs= 95 Min=0.0000000000000000, Max=0.9999999999999999, RMS=0.6912432821158787 -SeaIceFreeboard nobs= 286 Min=-0.0696922177149834, Max=0.2750439383765838, RMS=0.0518468018186912 +SeaIceFreeboard nobs= 287 Min=-0.0696922177149834, Max=0.2756828688484410, RMS=0.0519997530634973 -Chlorophyll nobs= 137 Min=0.0029618509113541, Max=2.6146242767720782, RMS=0.3736317108789671 +Chlorophyll nobs= 135 Min=0.0029618509113541, Max=2.6146242767720782, RMS=0.3570788569205419 -SurfaceU nobs= 200 Min=-0.6389024077305796, Max=0.3885039618613573, RMS=0.1663702932634859 +SurfaceU nobs= 198 Min=-0.6389024077305796, Max=0.3885039618613573, RMS=0.1649990940029129 -SurfaceV nobs= 200 Min=-0.3381740415739801, Max=0.4480817217292362, RMS=0.1155115339081705 +SurfaceV nobs= 198 Min=-0.3381740415739801, Max=0.4480817217292362, RMS=0.1162951855034772 End H(x) diff --git a/test/testref/hofx_4d.test b/test/testref/hofx_4d.test index 0e8b20092..3058e3daa 100644 --- a/test/testref/hofx_4d.test +++ b/test/testref/hofx_4d.test @@ -29,22 +29,22 @@ Final state: lw min=0.0000000000000000 max=88.0360870361328125 mean=31.3955290035652546 us min=0.0000000000000000 max=0.0191600705253526 mean=0.0072022693699425 H(x): -CoolSkin nobs= 21 Min=1.4428948751562416, Max=24.1361555774724366, RMS=19.7711636669012556 +CoolSkin nobs= 21 Min=1.5387458812807040, Max=24.1715123094076603, RMS=19.7918621451636199 -SeaSurfaceTemp nobs= 21 Min=5.8474277121364064, Max=29.7602622236446877, RMS=26.1545701582134633 +SeaSurfaceTemp nobs= 21 Min=5.8718670810702900, Max=29.7500148889060014, RMS=26.1595537939469196 -SeaSurfaceSalinity nobs= 9 Min=33.2253035608204002, Max=35.5527553210047955, RMS=34.4334800605473461 +SeaSurfaceSalinity nobs= 9 Min=33.4105735192755162, Max=35.5527553210047955, RMS=34.4634723542418868 -ADT nobs= 14 Min=-0.7588416066076941, Max=1.5069285902191589, RMS=1.0234497296579281 +ADT nobs= 14 Min=-0.7719489083672602, Max=1.5060812065126203, RMS=1.0251122457518520 InsituTemperature nobs= 10 Min=8.0070271630434053, Max=30.4007245259000989, RMS=23.8358475396981540 InsituSalinity nobs= 10 Min=34.1391616396567841, Max=35.6996397017128544, RMS=35.0158426602011090 -SeaIceFraction nobs= 14 Min=0.0000030348019657, Max=0.9972442090213249, RMS=0.6886532456176404 +SeaIceFraction nobs= 14 Min=0.0000030681734036, Max=0.9972442090213249, RMS=0.6907768231902665 -SurfaceU nobs= 21 Min=-0.5064808191553183, Max=0.0839417421563783, RMS=0.2906589228496731 +SurfaceU nobs= 21 Min=-0.4992601847182797, Max=0.0839417421563783, RMS=0.2868712638574619 -SurfaceV nobs= 21 Min=-0.2822470601936044, Max=0.2243200432575072, RMS=0.1317010425260674 +SurfaceV nobs= 21 Min=-0.2181718516993420, Max=0.2310073801777352, RMS=0.1233649712643844 End H(x) diff --git a/test/testref/hofx_4d_pseudo.test b/test/testref/hofx_4d_pseudo.test index e788f2b50..f08536937 100644 --- a/test/testref/hofx_4d_pseudo.test +++ b/test/testref/hofx_4d_pseudo.test @@ -15,11 +15,11 @@ Final state: uocn min=-0.8496117748396494 max=0.6890666856088563 mean=0.0000321916028576 vocn min=-0.9321576238931384 max=0.9467331169326910 mean=0.0016143192702768 H(x): -SeaSurfaceTemp nobs= 21 Min=5.8474277121364064, Max=29.7602622236446877, RMS=26.1545701582134633 +SeaSurfaceTemp nobs= 21 Min=5.8718670810702900, Max=29.7500148889060014, RMS=26.1595537939469196 -SeaSurfaceSalinity nobs= 9 Min=33.2253035608204002, Max=35.5527553210047955, RMS=34.4334800605473461 +SeaSurfaceSalinity nobs= 9 Min=33.4105735192755162, Max=35.5527553210047955, RMS=34.4634723542418868 -ADT nobs= 14 Min=-0.7588416066076941, Max=1.5069285902191589, RMS=1.0234497296579281 +ADT nobs= 14 Min=-0.7719489083672602, Max=1.5060812065126203, RMS=1.0251122457518520 InsituTemperature nobs= 10 Min=8.0070271630434053, Max=30.4007245259000989, RMS=23.8358475396981540 diff --git a/test/testref/hofx_oasim_3d.test b/test/testref/hofx_oasim_3d.test new file mode 100644 index 000000000..927700e19 --- /dev/null +++ b/test/testref/hofx_oasim_3d.test @@ -0,0 +1,28 @@ +State: + Valid time: 2018-04-15T00:00:00Z + hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 + oz_th min=275.00000000000000 max=275.00000000000000 mean=275.00000000000000 + wvapor min=1.2000000000000000 max=1.2000000000000000 mean=1.2000000000000000 + ws min=6.0000000000000000 max=6.0000000000000000 mean=6.0000000000000000 + pres min=999.00000000000000 max=999.00000000000000 mean=999.00000000000000 + rh min=89.000000000000000 max=89.000000000000000 mean=89.000000000000000 + cld_tau min=19.800000000000000 max=19.800000000000000 mean=19.800000000000000 + cld_lwp min=163.00000000000000 max=163.00000000000000 mean=163.00000000000000 + clwefr min=12.400000000000000 max=12.400000000000000 mean=12.400000000000000 + cov min=80.000000000000000 max=80.000000000000000 mean=80.000000000000000 + aer_tau min=0.1600000000000000 max=0.1600000000000000 mean=0.1600000000000000 + scat_alb min=0.7100000000000000 max=0.7100000000000000 mean=0.7100000000000000 + asym_par min=0.9700000000000000 max=0.9700000000000000 mean=0.9700000000000000 + c_det min=4.7000000000000000 max=4.7000000000000000 mean=4.7000000000000000 + inorg_c min=2.1000000000000000 max=2.1000000000000000 mean=2.1000000000000000 + dis_c min=3.1000000000000000 max=3.1000000000000000 mean=3.1000000000000000 + diatom min=0.0100000000000000 max=0.0100000000000000 mean=0.0100000000000000 + chloro min=0.1400000000000000 max=0.1400000000000000 mean=0.1400000000000000 + cyano min=0.0030000000000000 max=0.0030000000000000 mean=0.0030000000000000 + cocco min=0.0920000000000000 max=0.0920000000000000 mean=0.0920000000000000 + dino min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 + phaeo min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 +H(x): +OASIM nobs= 2100 Min=1.6450959631114046, Max=3.0780144604081427, RMS=2.6121620824311718 + +End H(x) diff --git a/test/testref/letkf.test b/test/testref/letkf.test index 9d173ed28..0a98d10e6 100644 --- a/test/testref/letkf.test +++ b/test/testref/letkf.test @@ -8,7 +8,6 @@ Initial state for member 1: hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 chl min=-0.0346456156552588 max=4.6657951350551032 mean=0.1184774650131123 biop min=-0.0000000010792964 max=0.0000001881576257 mean=0.0000000065411171 - Initial state for member 2: Valid time: 2018-04-15T00:00:00Z socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5055452687632709 @@ -19,7 +18,6 @@ Initial state for member 2: hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 chl min=-0.0289855887820164 max=4.6514396809792586 mean=0.1185532231894127 biop min=-0.0000000013979299 max=0.0000001885820462 mean=0.0000000065387977 - Initial state for member 3: Valid time: 2018-04-15T00:00:00Z socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5185040290381124 @@ -30,7 +28,6 @@ Initial state for member 3: hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 chl min=-0.0242260824668528 max=4.6851634656692536 mean=0.1184642679198311 biop min=-0.0000000008814691 max=0.0000001879042331 mean=0.0000000065376670 - Initial state for member 4: Valid time: 2018-04-15T00:00:00Z socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5332012222342186 @@ -41,41 +38,40 @@ Initial state for member 4: hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 chl min=-0.0339131334494770 max=4.6937598186554741 mean=0.1184950507291665 biop min=-0.0000000007072830 max=0.0000001876715923 mean=0.0000000065402892 - H(x) for member 1: -SeaSurfaceTemp nobs= 200 Min=-0.7441076047036211, Max=30.2955112206964401, RMS=24.1664837132353441 +SeaSurfaceTemp nobs= 198 Min=-0.7441076047036211, Max=30.2955112206964401, RMS=24.2122987687137154 -ADT nobs= 99 Min=-1.1923713065292145, Max=1.3916260008199295, RMS=0.7504264800238478 +ADT nobs= 99 Min=-1.1885693259805175, Max=1.3876434460945708, RMS=0.7490713220443416 H(x) for member 2: -SeaSurfaceTemp nobs= 200 Min=-1.2863446879039639, Max=30.4841785881009670, RMS=24.2312506827673673 +SeaSurfaceTemp nobs= 198 Min=-1.3083143229037799, Max=30.4841785881009670, RMS=24.2705103504836721 -ADT nobs= 99 Min=-1.1897933830438123, Max=1.3713086760738142, RMS=0.7276861479842313 +ADT nobs= 99 Min=-1.1866978354853446, Max=1.3696369252177263, RMS=0.7273001932758628 H(x) for member 3: -SeaSurfaceTemp nobs= 200 Min=-0.7441076047036211, Max=30.2952580792004262, RMS=24.3474545696390692 +SeaSurfaceTemp nobs= 198 Min=-0.7441076047036211, Max=30.2633211470504264, RMS=24.3959007624468036 -ADT nobs= 99 Min=-1.3099837851441407, Max=1.4204194886710029, RMS=0.7461543998221180 +ADT nobs= 99 Min=-1.3056888848023624, Max=1.4173142489572348, RMS=0.7445100247416564 H(x) for member 4: -SeaSurfaceTemp nobs= 200 Min=-0.8409264954611300, Max=30.6045092155533602, RMS=24.1878325277770436 +SeaSurfaceTemp nobs= 198 Min=-0.8582812691598130, Max=30.6045092155533602, RMS=24.2341369155624484 -ADT nobs= 99 Min=-1.1117642360155990, Max=1.4200699920384396, RMS=0.7328194094163875 +ADT nobs= 99 Min=-1.1230641461548929, Max=1.4181402812731112, RMS=0.7321102696208540 H(x) ensemble background mean: -SeaSurfaceTemp nobs= 200 Min=-0.7441076047036211, Max=30.3823358499043188, RMS=24.2290644633085890 +SeaSurfaceTemp nobs= 198 Min=-0.7441076047036211, Max=30.3823358499043188, RMS=24.2740131595248840 -ADT nobs= 99 Min=-1.2006910934514909, Max=1.4008560394007965, RMS=0.7375376522615416 +ADT nobs= 99 Min=-1.1928555077586021, Max=1.3981837253856608, RMS=0.7365479206994897 background y - H(x): -SeaSurfaceTemp nobs= 200 Min=-5.7729528751167436, Max=4.0109120120212314, RMS=1.3121091098438074 +SeaSurfaceTemp nobs= 198 Min=-5.9783801761836628, Max=2.8701768824562883, RMS=1.2887996706803055 -ADT nobs= 99 Min=-0.5287956883999732, Max=1.0899684904517966, RMS=0.2107554631800747 +ADT nobs= 99 Min=-0.5270376309721526, Max=1.1067453550051631, RMS=0.2119704150836391 Background mean : @@ -88,28 +84,26 @@ Background mean : hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 chl min=-0.0135973029322532 max=4.6740395250897722 mean=0.1184975017128806 biop min=-0.0000000004021572 max=0.0000001872794279 mean=0.0000000065394678 - Analysis mean : Valid time: 2018-04-15T00:00:00Z - socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5460582533093188 - tocn min=-4.1420151042420219 max=39.0742940340608271 mean=6.0527804302216772 - ssh min=-1.9808850587334716 max=0.9356684587670925 mean=-0.2892739626094919 - uocn min=-0.8569747929971832 max=0.6992920028847295 mean=-0.0002609623525139 - vocn min=-0.7669710796528207 max=1.4343633775728784 mean=0.0022635735165409 + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5478912661664381 + tocn min=-4.1972208948987912 max=39.3290074538890124 mean=6.0512110882483627 + ssh min=-1.9848140030728931 max=0.9355373828745192 mean=-0.2902906736803534 + uocn min=-0.8569209134742887 max=0.7002508980741655 mean=-0.0002576657694545 + vocn min=-0.7671475190900529 max=1.4343630396853562 mean=0.0022622465474656 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 - chl min=-0.0298669042139454 max=4.6772024962675101 mean=0.1184346217818456 - biop min=-0.0000000009544849 max=0.0000001880204003 mean=0.0000000065358238 - + chl min=-0.0300159238280435 max=4.6772866112259539 mean=0.1184279274034556 + biop min=-0.0000000009305103 max=0.0000001880271417 mean=0.0000000065355531 Analysis mean increment : Valid time: 2018-04-15T00:00:00Z - socn min=-2.5111176119167560 max=2.0210914091274503 mean=0.0201010844364589 - tocn min=-6.9066492864987161 max=11.0386426204930999 mean=-0.0035637080858972 - ssh min=-0.7525950953079572 max=0.3561891477540637 mean=-0.0169447871693975 - uocn min=-0.0240690528881808 max=0.0350495637061460 mean=0.0000144684996823 - vocn min=-0.0146415870423201 max=0.0575333116935723 mean=0.0000572225702069 + socn min=-2.5274225441989699 max=2.0492357937819889 mean=0.0219340972935823 + tocn min=-6.6118883382731770 max=11.2933560403212851 mean=-0.0051330500592141 + ssh min=-0.7417393217708501 max=0.3594694722350922 mean=-0.0179614982402593 + uocn min=-0.0227572806641118 max=0.0360576350241506 mean=0.0000177650827417 + vocn min=-0.0148400119857092 max=0.0589268218533487 mean=0.0000558956011316 hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 - chl min=-0.0858357518258490 max=0.0852125535358046 mean=-0.0000628799310351 - biop min=-0.0000000083973247 max=0.0000000059423443 mean=-0.0000000000036440 + chl min=-0.0867138970309593 max=0.0866139466486184 mean=-0.0000695743094250 + biop min=-0.0000000083874164 max=0.0000000060228911 mean=-0.0000000000039147 Forecast variance : Valid time: 2018-04-15T00:00:00Z socn min=0.0000000000000000 max=1.8239276341677120 mean=0.0465030040856202 @@ -122,49 +116,49 @@ Forecast variance : biop min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 Analysis variance : Valid time: 2018-04-15T00:00:00Z - socn min=0.0000000000000000 max=1.7162477771883140 mean=0.0414300020489708 - tocn min=0.0000000000000000 max=8.1408342488048682 mean=0.2329541096542200 - ssh min=0.0000000000000000 max=0.0544573956569277 mean=0.0029605566333293 - uocn min=0.0000000000000000 max=0.0001168660285223 mean=0.0000012919697748 - vocn min=0.0000000000000000 max=0.0001011941501286 mean=0.0000006258398684 + socn min=0.0000000000000000 max=1.7111809285209596 mean=0.0414269250397383 + tocn min=0.0000000000000000 max=8.0520942417733874 mean=0.2328887960815975 + ssh min=0.0000000000000000 max=0.0545480722207001 mean=0.0029611734691749 + uocn min=0.0000000000000000 max=0.0001169268541471 mean=0.0000012923747533 + vocn min=0.0000000000000000 max=0.0001011960217317 mean=0.0000006256764157 hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 - chl min=0.0000000000071484 max=0.0043382986032581 mean=0.0000130242093228 + chl min=0.0000000000071484 max=0.0043382062002196 mean=0.0000130178412296 biop min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 H(x) for member 1: -SeaSurfaceTemp nobs= 200 Min=-1.2017604877912396, Max=30.4622962082671478, RMS=24.0149394365831803 +SeaSurfaceTemp nobs= 198 Min=-1.0258815612072028, Max=30.5514848768195151, RMS=24.0523339209340747 -ADT nobs= 99 Min=-1.2514894507247609, Max=1.4076713991590450, RMS=0.7655671941924330 +ADT nobs= 99 Min=-1.2536010323787454, Max=1.4085661430421623, RMS=0.7661637612447397 H(x) for member 2: -SeaSurfaceTemp nobs= 200 Min=-1.3293539570723611, Max=30.8061036309186136, RMS=24.0698618459434712 +SeaSurfaceTemp nobs= 198 Min=-1.3248841328934857, Max=30.8886835300334006, RMS=24.1011667065713020 -ADT nobs= 99 Min=-1.2715243724648180, Max=1.3898582112779911, RMS=0.7452627490779942 +ADT nobs= 99 Min=-1.2584089055852639, Max=1.3924977527314240, RMS=0.7459256399338591 H(x) for member 3: -SeaSurfaceTemp nobs= 200 Min=-1.6065211291257153, Max=30.3285104733377082, RMS=24.1704608680599122 +SeaSurfaceTemp nobs= 198 Min=-1.8162655085656818, Max=30.2746049471946712, RMS=24.2094438686005660 -ADT nobs= 99 Min=-1.3753653310782692, Max=1.4360654938288577, RMS=0.7622439001356500 +ADT nobs= 99 Min=-1.3688636601100521, Max=1.4374903060275335, RMS=0.7621249768668742 H(x) for member 4: -SeaSurfaceTemp nobs= 200 Min=-0.9165133674704848, Max=30.6634693022188465, RMS=24.0341242343249810 +SeaSurfaceTemp nobs= 198 Min=-0.9114724371520095, Max=30.5814257572882475, RMS=24.0721544530341518 -ADT nobs= 99 Min=-1.1906839978389554, Max=1.4376260611915415, RMS=0.7495567552237363 +ADT nobs= 99 Min=-1.1774222688943927, Max=1.4400454643882674, RMS=0.7498524817033487 H(x) ensemble analysis mean: -SeaSurfaceTemp nobs= 200 Min=-0.7441076047036211, Max=30.2952436529921378, RMS=24.0692059834924414 +SeaSurfaceTemp nobs= 198 Min=-0.7441076047036211, Max=30.2471652075657644, RMS=24.1056340946481278 -ADT nobs= 99 Min=-1.2722657880267008, Max=1.4178052913643588, RMS=0.7542778104026348 +ADT nobs= 99 Min=-1.2622867671583469, Max=1.4196499165473466, RMS=0.7546649338950588 analysis y - H(x): -SeaSurfaceTemp nobs= 200 Min=-2.6781806478141661, Max=2.8028079747317669, RMS=0.7906203680435694 +SeaSurfaceTemp nobs= 198 Min=-2.5701146752327695, Max=2.0950567050864937, RMS=0.7557496379193599 -ADT nobs= 99 Min=-0.5178761356349733, Max=1.0300253402999773, RMS=0.1919918062649364 +ADT nobs= 99 Min=-0.5201674962288996, Max=1.0634924104278585, RMS=0.1942965278849433 -ombg RMS: 1.0799532875562872 -oman RMS: 0.6559869323956541 +ombg RMS: 1.0593930084663352 +oman RMS: 0.6271805086200282 diff --git a/test/testref/letkf_split_observer.test b/test/testref/letkf_split_observer.test index e1fa09b9e..7aa433be3 100644 --- a/test/testref/letkf_split_observer.test +++ b/test/testref/letkf_split_observer.test @@ -8,7 +8,6 @@ Initial state for member 1: hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 chl min=-0.0346456156552588 max=4.6657951350551032 mean=0.1184774650131123 biop min=-0.0000000010792964 max=0.0000001881576257 mean=0.0000000065411171 - Initial state for member 2: Valid time: 2018-04-15T00:00:00Z socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5055452687632709 @@ -19,7 +18,6 @@ Initial state for member 2: hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 chl min=-0.0289855887820164 max=4.6514396809792586 mean=0.1185532231894127 biop min=-0.0000000013979299 max=0.0000001885820462 mean=0.0000000065387977 - Initial state for member 3: Valid time: 2018-04-15T00:00:00Z socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5185040290381124 @@ -30,7 +28,6 @@ Initial state for member 3: hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 chl min=-0.0242260824668528 max=4.6851634656692536 mean=0.1184642679198311 biop min=-0.0000000008814691 max=0.0000001879042331 mean=0.0000000065376670 - Initial state for member 4: Valid time: 2018-04-15T00:00:00Z socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5332012222342186 @@ -41,40 +38,39 @@ Initial state for member 4: hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 chl min=-0.0339131334494770 max=4.6937598186554741 mean=0.1184950507291665 biop min=-0.0000000007072830 max=0.0000001876715923 mean=0.0000000065402892 - H(x) for member 1: -SeaSurfaceTemp nobs= 200 Min=-0.7441076047036211, Max=30.2955112206964401, RMS=24.1664837132353405 +SeaSurfaceTemp nobs= 198 Min=-0.7441076047036211, Max=30.2955112206964401, RMS=24.2122987687137119 -ADT nobs= 99 Min=-1.1923713065292147, Max=1.3916260008199293, RMS=0.7504264800238476 +ADT nobs= 99 Min=-1.1885693259805179, Max=1.3876434460945706, RMS=0.7490713220443413 H(x) for member 2: -SeaSurfaceTemp nobs= 200 Min=-1.2863446879039639, Max=30.4841785881009670, RMS=24.2312506827673708 +SeaSurfaceTemp nobs= 198 Min=-1.3083143229037799, Max=30.4841785881009670, RMS=24.2705103504836721 -ADT nobs= 99 Min=-1.1897933830438123, Max=1.3713086760738142, RMS=0.7276861479842313 +ADT nobs= 99 Min=-1.1866978354853446, Max=1.3696369252177261, RMS=0.7273001932758628 H(x) for member 3: -SeaSurfaceTemp nobs= 200 Min=-0.7441076047036211, Max=30.2952580792004262, RMS=24.3474545696390692 +SeaSurfaceTemp nobs= 198 Min=-0.7441076047036211, Max=30.2633211470504264, RMS=24.3959007624468001 -ADT nobs= 99 Min=-1.3099837851441407, Max=1.4204194886710029, RMS=0.7461543998221180 +ADT nobs= 99 Min=-1.3056888848023624, Max=1.4173142489572350, RMS=0.7445100247416564 H(x) for member 4: -SeaSurfaceTemp nobs= 200 Min=-0.8409264954611300, Max=30.6045092155533602, RMS=24.1878325277770436 +SeaSurfaceTemp nobs= 198 Min=-0.8582812691598130, Max=30.6045092155533602, RMS=24.2341369155624520 -ADT nobs= 99 Min=-1.1117642360155993, Max=1.4200699920384396, RMS=0.7328194094163875 +ADT nobs= 99 Min=-1.1230641461548931, Max=1.4181402812731112, RMS=0.7321102696208540 H(x) ensemble background mean: -SeaSurfaceTemp nobs= 200 Min=-0.7441076047036211, Max=30.3823358499043188, RMS=24.2290644633085961 +SeaSurfaceTemp nobs= 198 Min=-0.7441076047036211, Max=30.3823358499043188, RMS=24.2740131595248876 -ADT nobs= 99 Min=-1.2006910934514909, Max=1.4008560394007965, RMS=0.7375376522615414 +ADT nobs= 99 Min=-1.1928555077586023, Max=1.3981837253856608, RMS=0.7365479206994896 background y - H(x): -SeaSurfaceTemp nobs= 200 Min=-5.7729528751167436, Max=4.0109120120212314, RMS=1.3121091098438071 +SeaSurfaceTemp nobs= 198 Min=-5.9783801761836628, Max=2.8701768824562883, RMS=1.2887996706803055 -ADT nobs= 99 Min=-0.5287956883999732, Max=1.0899684904517966, RMS=0.2107554631800748 +ADT nobs= 99 Min=-0.5270376309721526, Max=1.1067453550051634, RMS=0.2119704150836391 diff --git a/test/testref/letkf_split_solver.test b/test/testref/letkf_split_solver.test index 6ef7748f8..d6fc6cb51 100644 --- a/test/testref/letkf_split_solver.test +++ b/test/testref/letkf_split_solver.test @@ -8,7 +8,6 @@ Initial state for member 1: hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 chl min=-0.0346456156552588 max=4.6657951350551032 mean=0.1184774650131123 biop min=-0.0000000010792964 max=0.0000001881576257 mean=0.0000000065411171 - Initial state for member 2: Valid time: 2018-04-15T00:00:00Z socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5055452687632709 @@ -19,7 +18,6 @@ Initial state for member 2: hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 chl min=-0.0289855887820164 max=4.6514396809792586 mean=0.1185532231894127 biop min=-0.0000000013979299 max=0.0000001885820462 mean=0.0000000065387977 - Initial state for member 3: Valid time: 2018-04-15T00:00:00Z socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5185040290381124 @@ -30,7 +28,6 @@ Initial state for member 3: hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 chl min=-0.0242260824668528 max=4.6851634656692536 mean=0.1184642679198311 biop min=-0.0000000008814691 max=0.0000001879042331 mean=0.0000000065376670 - Initial state for member 4: Valid time: 2018-04-15T00:00:00Z socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5332012222342186 @@ -41,41 +38,40 @@ Initial state for member 4: hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 chl min=-0.0339131334494770 max=4.6937598186554741 mean=0.1184950507291665 biop min=-0.0000000007072830 max=0.0000001876715923 mean=0.0000000065402892 - H(x) for member 1: -SeaSurfaceTemp nobs= 200 Min=-0.7441076040267944, Max=30.2955112457275391, RMS=24.1664837135364508 +SeaSurfaceTemp nobs= 198 Min=-0.7441076040267944, Max=30.2955112457275391, RMS=24.2122987500916409 -ADT nobs= 99 Min=-1.1923712491989136, Max=1.3916260004043579, RMS=0.7504264789495512 +ADT nobs= 99 Min=-1.1885693073272705, Max=1.3876434564590454, RMS=0.7490713250567731 H(x) for member 2: -SeaSurfaceTemp nobs= 200 Min=-1.2863446474075317, Max=30.4841785430908203, RMS=24.2312506631285345 +SeaSurfaceTemp nobs= 198 Min=-1.3083143234252930, Max=30.4841785430908203, RMS=24.2705103599596796 -ADT nobs= 99 Min=-1.1897933483123779, Max=1.3713086843490601, RMS=0.7276861474621327 +ADT nobs= 99 Min=-1.1866978406906128, Max=1.3696368932723999, RMS=0.7273001966731646 H(x) for member 3: -SeaSurfaceTemp nobs= 200 Min=-0.7441076040267944, Max=30.2952575683593750, RMS=24.3474545828501725 +SeaSurfaceTemp nobs= 198 Min=-0.7441076040267944, Max=30.2633209228515625, RMS=24.3959007805595007 -ADT nobs= 99 Min=-1.3099837303161621, Max=1.4204194545745850, RMS=0.7461543998130861 +ADT nobs= 99 Min=-1.3056888580322266, Max=1.4173142910003662, RMS=0.7445100240993107 H(x) for member 4: -SeaSurfaceTemp nobs= 200 Min=-0.8409264683723450, Max=30.6045093536376953, RMS=24.1878325159965399 +SeaSurfaceTemp nobs= 198 Min=-0.8582812547683716, Max=30.6045093536376953, RMS=24.2341369346136482 -ADT nobs= 99 Min=-1.1117641925811768, Max=1.4200699329376221, RMS=0.7328194018518309 +ADT nobs= 99 Min=-1.1230641603469849, Max=1.4181402921676636, RMS=0.7321102695972385 H(x) ensemble background mean: -SeaSurfaceTemp nobs= 200 Min=-0.7441076040267944, Max=30.3823356628417969, RMS=24.2290644588743405 +SeaSurfaceTemp nobs= 198 Min=-0.7441076040267944, Max=30.3823356628417969, RMS=24.2740131666558732 -ADT nobs= 99 Min=-1.2006910443305969, Max=1.4008560180664062, RMS=0.7375376499812341 +ADT nobs= 99 Min=-1.1928555071353912, Max=1.3981837332248688, RMS=0.7365479220464279 background y - H(x): -SeaSurfaceTemp nobs= 200 Min=-5.7729525566101074, Max=4.0109121799468994, RMS=1.3121090797868757 +SeaSurfaceTemp nobs= 198 Min=-5.9783802032470703, Max=2.8701767921447754, RMS=1.2887996776224724 -ADT nobs= 99 Min=-0.5287956893444061, Max=1.0899684876203537, RMS=0.2107554632064487 +ADT nobs= 99 Min=-0.5270376354455948, Max=1.1067453622817993, RMS=0.2119704157265872 Background mean : @@ -88,28 +84,26 @@ Background mean : hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 chl min=-0.0135973029322532 max=4.6740395250897722 mean=0.1184975017128806 biop min=-0.0000000004021572 max=0.0000001872794279 mean=0.0000000065394678 - Analysis mean : Valid time: 2018-04-15T00:00:00Z - socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5484994850473157 - tocn min=-4.1420150566263079 max=39.3342720079667814 mean=6.0647518510715024 - ssh min=-2.0240566313569937 max=0.9356684392545753 mean=-0.2895886675031061 - uocn min=-0.8585951774630758 max=0.6992919999268546 mean=-0.0002578079506054 - vocn min=-0.7653547567785886 max=1.4343633775731606 mean=0.0022673436078005 + socn min=10.7210460395083924 max=40.4416591897031168 mean=34.5503984640074577 + tocn min=-4.1972209081537981 max=39.5677248606151792 mean=6.0633185790219688 + ssh min=-2.0294993501073568 max=0.9355373664810137 mean=-0.2905568340492273 + uocn min=-0.8588076819362294 max=0.7002508977253543 mean=-0.0002540509942861 + vocn min=-0.7656023849181770 max=1.4343630396850893 mean=0.0022659262939969 hocn min=0.0009999999999977 max=1345.6400000000003274 mean=128.6280642065023017 - chl min=-0.0298668983694693 max=4.6772025002347997 mean=0.1184354336172894 - biop min=-0.0000000009550755 max=0.0000001880204011 mean=0.0000000065360569 - + chl min=-0.0300159171410080 max=4.6772866143750731 mean=0.1184290957391284 + biop min=-0.0000000009315800 max=0.0000001880271432 mean=0.0000000065357994 Analysis mean increment : Valid time: 2018-04-15T00:00:00Z - socn min=-2.5111177427918214 max=2.0408300100356769 mean=0.0225423161744710 - tocn min=-6.8391128160208972 max=11.2986205943990541 mean=0.0084077127639269 - ssh min=-0.7525951148575687 max=0.3561893016140887 mean=-0.0172594920630121 - uocn min=-0.0238958861412669 max=0.0351143113857929 mean=0.0000176229015907 - vocn min=-0.0162364960804651 max=0.0600637187967529 mean=0.0000609926614664 + socn min=-2.5274238274785006 max=2.0671937826357407 mean=0.0244412951346048 + tocn min=-6.5033672400200508 max=11.5320734470474520 mean=0.0069744407143918 + ssh min=-0.7417392664573934 max=0.3594697046885069 mean=-0.0182276586091335 + uocn min=-0.0226872528830783 max=0.0360372663357967 mean=0.0000213798579101 + vocn min=-0.0164197190297472 max=0.0613328320247443 mean=0.0000595753476629 hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 - chl min=-0.0858357451014435 max=0.0852127026306109 mean=-0.0000620680955912 - biop min=-0.0000000083973207 max=0.0000000059423499 mean=-0.0000000000034109 + chl min=-0.0867139033665234 max=0.0866140254931551 mean=-0.0000684059737523 + biop min=-0.0000000083874254 max=0.0000000060228961 mean=-0.0000000000036684 Forecast variance : Valid time: 2018-04-15T00:00:00Z socn min=0.0000000000000000 max=1.8239276341677120 mean=0.0465030040856202 @@ -122,11 +116,11 @@ Forecast variance : biop min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 Analysis variance : Valid time: 2018-04-15T00:00:00Z - socn min=0.0000000000000000 max=1.7162477268253895 mean=0.0416665311260158 - tocn min=0.0000000000000000 max=8.1408331330837846 mean=0.2382693678773377 - ssh min=0.0000000000000000 max=0.0544573955250757 mean=0.0029741311300652 - uocn min=0.0000000000000000 max=0.0001168663061135 mean=0.0000013103497614 - vocn min=0.0000000000000000 max=0.0001011941501046 mean=0.0000006321304857 + socn min=0.0000000000000000 max=1.7111808931083179 mean=0.0416621224808086 + tocn min=0.0000000000000000 max=8.0520933228739526 mean=0.2382365628859260 + ssh min=0.0000000000000000 max=0.0545480718986743 mean=0.0029746652530810 + uocn min=0.0000000000000000 max=0.0001169271324847 mean=0.0000013108109821 + vocn min=0.0000000000000000 max=0.0001011960216953 mean=0.0000006319773143 hocn min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 - chl min=0.0000000000071484 max=0.0043382984520450 mean=0.0000130946992844 + chl min=0.0000000000071484 max=0.0043382060437541 mean=0.0000130880843939 biop min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 diff --git a/test/testref/parameters_bump_cor_nicas.test b/test/testref/parameters_bump_cor_nicas.test index 65f9cb0b9..c81ae420d 100644 --- a/test/testref/parameters_bump_cor_nicas.test +++ b/test/testref/parameters_bump_cor_nicas.test @@ -1,2 +1,2 @@ -Norm of BUMP output parameter cor_rh - 1: 1.1484633211382940e+09 -Norm of BUMP output parameter cor_rv - 1: 1.9141055352304898e+04 +Norm of output parameter cor_rh - 1: 1.1484633211382940e+09 +Norm of output parameter cor_rv - 1: 1.9141055352304898e+04 diff --git a/test/testref/parameters_bump_cor_nicas_scales.test b/test/testref/parameters_bump_cor_nicas_scales.test index a1987f2cd..8a75f8d2f 100644 --- a/test/testref/parameters_bump_cor_nicas_scales.test +++ b/test/testref/parameters_bump_cor_nicas_scales.test @@ -1,2 +1,2 @@ -Norm of input parameter rh - 1: 4.9024310689053154e+09 +Norm of input parameter rh - 1: 4.9025377308570557e+09 Norm of input parameter rv - 1: 1.4415640549763996e+05 diff --git a/test/testref/parameters_bump_cov.test b/test/testref/parameters_bump_cov.test index fcf8b211d..2b5f36324 100644 --- a/test/testref/parameters_bump_cov.test +++ b/test/testref/parameters_bump_cov.test @@ -1,3 +1,3 @@ -Norm of BUMP output parameter cor_rh - 1: 4.1588170892337942e+08 -Norm of BUMP output parameter cor_rv - 1: 9.1082415233255915e+02 -Norm of BUMP output parameter stddev - 1: 5.3081714633167209e+01 +Norm of output parameter cor_rh - 1: 3.7898603704696083e+08 +Norm of output parameter cor_rv - 1: 9.0619883969753107e+02 +Norm of output parameter stddev - 1: 5.3081714633167209e+01 diff --git a/test/testref/setcorscales.test b/test/testref/setcorscales.test index 03f0b6a83..220eb1566 100644 --- a/test/testref/setcorscales.test +++ b/test/testref/setcorscales.test @@ -1,10 +1,10 @@ Output horizontal scales: Valid time: 2018-04-15T00:00:00Z - socn min=3443898.2400908078998327 max=37052173.1999415531754494 mean=10563219.6926001682877541 - tocn min=4132677.8881089696660638 max=27789129.8999561667442322 mean=10854689.6494855433702469 - uocn min=4132677.8881089696660638 max=27789129.8999561667442322 mean=10890433.1615598015487194 - vocn min=4132677.8881089696660638 max=27789129.8999561667442322 mean=10840852.8419821411371231 - ssh min=4821457.5361271305009723 max=18526086.5999707765877247 mean=11599358.8391597736626863 + socn min=3443898.2400908078998327 max=37052173.1999415531754494 mean=10563446.4663747083395720 + tocn min=4132677.8881089696660638 max=27789129.8999561667442322 mean=10854868.3081620298326015 + uocn min=4132677.8881089696660638 max=27789129.8999561667442322 mean=10890625.1407654695212841 + vocn min=4132677.8881089696660638 max=27789129.8999561667442322 mean=10840992.6725430469959974 + ssh min=4821457.5361271305009723 max=18526086.5999707765877247 mean=11599358.8391598928719759 cicen min=5510237.1841452922672033 max=15868559.2703372277319431 mean=13014697.2258340530097485 hicen min=17850000.0000000000000000 max=17852129.1791293807327747 mean=17850139.9582142084836960 Output vertical scales: diff --git a/test/testref/sqrtvertloc.test b/test/testref/sqrtvertloc.test index 2cb01029d..8a813614a 100644 --- a/test/testref/sqrtvertloc.test +++ b/test/testref/sqrtvertloc.test @@ -18,52 +18,52 @@ Background: us min=0.0000000000000000 max=0.0000000000000000 mean=0.0000000000000000 mld min=2.2854716757984130 max=4593.1533423819937525 mean=192.4109073940401515 layer_depth min=2.2854716757984130 max=5658.3057467114012979 mean=1200.5229536158392420 -Variance Explained=0.1095722884945554 -0.1986109674104811 -0.2573592042007319 -0.3107695230030913 -0.3601075805191439 -0.4060398927639458 -0.4490768975279861 -0.4894581680876475 -0.5273973968507524 -0.5630587213523036 -0.5966424448666294 -0.6282216452762419 -0.6579728189097667 -0.6859749507249951 -0.7123308347212612 -0.7370952702038832 -0.7603168555409263 -0.7821305787902608 -0.8025463220344943 -0.8216780361675287 -0.8395667952566088 -0.8562695558486649 -0.8718566481716684 -0.8863678411892866 -0.8998452895820127 -0.9123174374716791 -0.9238167088149134 -0.9343854753848837 -0.9440792712286040 -0.9529261630955466 -0.9609874344601098 -0.9682787831872223 -0.9748495121496636 -0.9806953477270097 -0.9858702442359948 -0.9903924688279335 -0.9942661331040944 -0.9974850871367730 -0.9999999999999999 -0.9999999999999999 +Variance Explained=0.1096171922047231 +0.1986045034050992 +0.2573630058393613 +0.3107532581005915 +0.3600780060478236 +0.4059975614845806 +0.4490255138467362 +0.4894032540103357 +0.5273444827790712 +0.5630156249719891 +0.5965844561275099 +0.6281574792731044 +0.6579214811897764 +0.6859300928663781 +0.7122863664054074 +0.7370566011117995 +0.7602902451356316 +0.7821106494633983 +0.8025341459758836 +0.8216709226214103 +0.8395648493506132 +0.8562730805264062 +0.8718656586524712 +0.8863760896935975 +0.8998514179821113 +0.9123239263040823 +0.9238245469735469 +0.9343962082766479 +0.9440956359493268 +0.9529448218556020 +0.9610054068704874 +0.9682971797452863 +0.9748623012308331 +0.9807032802887200 +0.9858742155762905 +0.9903946222754951 +0.9942664231712092 +0.9974860947539266 +1.0000000000000002 +1.0000000000000002 Number of retained columns=10 -Retained fraction of the variance=0.5630587213523036 +Retained fraction of the variance=0.5630156249719890 Variance for truncated correlation matrix Valid time: 2018-04-15T00:00:00Z - ssh min=0.0000000000000000 max=0.9956521414877253 mean=0.7859481295984008 - tocn min=0.0000000000000000 max=0.9963486197333468 mean=0.5422186134486107 - socn min=0.0000000000000000 max=0.9968726530867191 mean=0.5488641651294098 - uocn min=0.0379204542449227 max=0.8805075454121231 mean=0.4712705638193914 - vocn min=0.0000000000000000 max=0.8431094636696504 mean=0.4718656179177272 + ssh min=0.0000000000000000 max=0.9956679957030570 mean=0.7856432972140444 + tocn min=0.0000000000000000 max=0.9966481594658692 mean=0.5420609030408824 + socn min=0.0000000000000000 max=0.9967239058640776 mean=0.5488927040853910 + uocn min=0.0471870359614622 max=0.8507511804330994 mean=0.4712163828151314 + vocn min=0.0000000000000000 max=0.8504443347852177 mean=0.4718981764054079