diff --git a/CMakeLists.txt b/CMakeLists.txt index b09f16278f3aa758a0a8ec869e0be36d57307126..e3aaa9e1c3a99cb69b0179d1e3298da73b375943 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,10 @@ set(SOURCES io_metadata.f90 io.f90 obl_io_plt.f90 + obl_run_kato.f90 + obl_run_papa_fluxes.f90 + obl_run_papa_meteo.f90 + obl_config.f90 vermix_inmom.f90 ) diff --git a/obl_config.f90 b/obl_config.f90 new file mode 100644 index 0000000000000000000000000000000000000000..12c9a46e5e2f3e8f24024ea9919cfe61041d59f3 --- /dev/null +++ b/obl_config.f90 @@ -0,0 +1,378 @@ +#include "obl_def.fi" + +!> @brief ocean boundary layer model config subroutines +module obl_config + + ! modules used + ! -------------------------------------------------------------------------------- +#ifdef USE_CONFIG_PARSER + use iso_c_binding, only: C_NULL_CHAR + use config_parser +#endif + ! -------------------------------------------------------------------------------- + + ! directives list + ! -------------------------------------------------------------------------------- + implicit none + ! -------------------------------------------------------------------------------- + + public + + !> @brief setup enum def. + integer, parameter :: setup_kato = 0 !< Kato-Phillips setup + integer, parameter :: setup_papa_fluxes = 1 !< Papa-station (fluxes) setup + integer, parameter :: setup_papa_meteo = 2 !< Papa-station (meteo) setup + + character(len = 16), parameter :: setup_kato_tag = 'kato' + character(len = 16), parameter :: setup_papa_fluxes_tag = 'papa-fluxes' + character(len = 16), parameter :: setup_papa_meteo_tag = 'papa-meteo' + + +contains + + function get_setup_id(tag) result(id) + implicit none + character(len=*), intent(in) :: tag + integer :: id + + id = - 1 + if (trim(tag) == trim(setup_kato_tag)) then + id = setup_kato + else if (trim(tag) == trim(setup_papa_fluxes_tag)) then + id = setup_papa_fluxes + else if (trim(tag) == trim(setup_papa_meteo_tag)) then + id = setup_papa_meteo + end if + + end function + + function get_setup_tag(id) result(tag) + implicit none + integer :: id + character(len=:), allocatable :: tag + + tag = 'undefined' + if (id == setup_kato) then + tag = setup_kato_tag + else if (id == setup_papa_fluxes) then + tag = setup_papa_fluxes_tag + else if (id == setup_papa_meteo) then + tag = setup_papa_meteo_tag + end if + + end function + + ! -------------------------------------------------------------------------------- + subroutine set_grid(grid, setup_id, ierr) + !> @brief grid parameters setup + ! ---------------------------------------------------------------------------- + use obl_grid + use obl_run_kato, only : set_grid_kato => set_grid + use obl_run_papa_fluxes, only : set_grid_papa_fluxes => set_grid + use obl_run_papa_meteo, only : set_grid_papa_meteo => set_grid + + type (gridDataType), intent(inout) :: grid + integer, intent(in) :: setup_id + integer, intent(out) :: ierr + ! ---------------------------------------------------------------------------- + + ierr = 0 ! = OK + + if (setup_id == setup_kato) then + call set_grid_kato(grid) + return + endif + if (setup_id == setup_papa_fluxes) then + call set_grid_papa_fluxes(grid) + return + endif + if (setup_id == setup_papa_meteo) then + call set_grid_papa_meteo(grid) + return + endif + +#ifdef USE_CONFIG_PARSER + block + real :: depth + integer :: cz + + integer :: status + + call c_config_get_float("domain.depth"//C_NULL_CHAR, depth, status) + if (status == 0) then + ierr = 1 ! signal ERROR + return + end if + + call c_config_get_int("grid.cz"//C_NULL_CHAR, cz, status) + if (status == 0) then + ierr = 1 ! signal ERROR + return + end if + + call set_uniform_grid(grid, -depth, depth, cz) + end block +#endif + end subroutine set_grid + + ! -------------------------------------------------------------------------------- + subroutine set_time(time_begin, time_end, dt, setup_id, ierr) + !> @brief time parameters setup + ! ---------------------------------------------------------------------------- + use obl_run_kato, only : set_time_kato => set_time + use obl_run_papa_fluxes, only : set_time_papa_fluxes => set_time + use obl_run_papa_meteo, only : set_time_papa_meteo => set_time + + real, intent(out) :: time_begin, time_end, dt + integer, intent(in) :: setup_id + integer, intent(out) :: ierr + ! ---------------------------------------------------------------------------- + + ierr = 0 ! = OK + + if (setup_id == setup_kato) then + call set_time_kato(time_begin, time_end, dt) + return + endif + if (setup_id == setup_papa_fluxes) then + call set_time_papa_fluxes(time_begin, time_end, dt) + return + endif + if (setup_id == setup_papa_meteo) then + call set_time_papa_meteo(time_begin, time_end, dt) + return + endif + +#ifdef USE_CONFIG_PARSER + block + integer :: status + + call c_config_get_float("time.begin"//C_NULL_CHAR, time_begin, status) + if (status == 0) then + ierr = 1 ! signal ERROR + return + end if + + call c_config_get_float("time.end"//C_NULL_CHAR, time_end, status) + if (status == 0) then + ierr = 1 ! signal ERROR + return + end if + + call c_config_get_float("time.dt"//C_NULL_CHAR, dt, status) + if (status == 0) then + ierr = 1 ! signal ERROR + return + end if + + end block +#endif + end subroutine set_time + + ! -------------------------------------------------------------------------------- + subroutine set_phys(setup_id, ierr) + !> @brief phys parameters setup + ! ---------------------------------------------------------------------------- + use obl_scm + use obl_run_kato, only : set_phys_kato => set_phys + use obl_run_papa_fluxes, only : set_phys_papa_fluxes => set_phys + use obl_run_papa_meteo, only : set_phys_papa_meteo => set_phys + + integer, intent(in) :: setup_id + integer, intent(out) :: ierr + ! ---------------------------------------------------------------------------- + + ierr = 0 ! = OK + + if (setup_id == setup_kato) then + call set_phys_kato + return + endif + if (setup_id == setup_papa_fluxes) then + call set_phys_papa_fluxes + return + endif + if (setup_id == setup_papa_meteo) then + call set_phys_papa_meteo + return + endif + +#ifdef USE_CONFIG_PARSER + block + integer :: status + + call c_config_get_float("phys.f"//C_NULL_CHAR, f, status) + if (status == 0) then + ierr = 1 ! signal ERROR + return + end if + + call c_config_get_float("phys.a_band_ratio"//C_NULL_CHAR, a_band_ratio, status) + if (status == 0) then + ierr = 1 ! signal ERROR + return + end if + + call c_config_get_float("phys.a_extinction_coeff"//C_NULL_CHAR, a_extinction_coeff, status) + if (status == 0) then + ierr = 1 ! signal ERROR + return + end if + + call c_config_get_float("phys.b_extinction_coeff"//C_NULL_CHAR, b_extinction_coeff, status) + if (status == 0) then + ierr = 1 ! signal ERROR + return + end if + + call c_config_get_float("phys.sw_albedo"//C_NULL_CHAR, sw_albedo, status) + if (status == 0) then + ierr = 1 ! signal ERROR + return + end if + + end block +#endif + end subroutine set_phys + + ! -------------------------------------------------------------------------------- + subroutine set_forcing(setup_id, ierr) + !> @brief phys parameters setup + ! ---------------------------------------------------------------------------- + use obl_fluxes + use obl_tforcing + use obl_math !< using char_array2str() + use obl_run_kato, only : set_forcing_kato => set_forcing + use obl_run_papa_fluxes, only : set_forcing_papa_fluxes => set_forcing + use obl_run_papa_meteo, only : set_forcing_papa_meteo => set_forcing + + integer, intent(in) :: setup_id + integer, intent(out) :: ierr + ! ---------------------------------------------------------------------------- + + ierr = 0 ! = OK + + if (setup_id == setup_kato) then + call set_forcing_kato + return + endif + if (setup_id == setup_papa_fluxes) then + call set_forcing_papa_fluxes + return + endif + if (setup_id == setup_papa_meteo) then + call set_forcing_papa_meteo + return + endif + +#ifdef USE_CONFIG_PARSER + block + + call set_config_tforcing(tau_x_surf, "atm.tau_x", ierr) + if (ierr /= 0) return + + call set_config_tforcing(tau_y_surf, "atm.tau_y", ierr) + if (ierr /= 0) return + + call set_config_tforcing(sensible_hflux_surf, "atm.sensible_hflux", ierr) + if (ierr /= 0) return + + call set_config_tforcing(latent_hflux_surf, "atm.latent_hflux", ierr) + if (ierr /= 0) return + + call set_config_tforcing(salin_flux_surf, "atm.salin_flux", ierr) + if (ierr /= 0) return + + call set_config_tforcing(Ua, "atm.Ua", ierr) + if (ierr /= 0) return + + call set_config_tforcing(Va, "atm.Va", ierr) + if (ierr /= 0) return + + call set_config_tforcing(Ta, "atm.Ta", ierr) + if (ierr /= 0) return + + call set_config_tforcing(Pa, "atm.Pa", ierr) + if (ierr /= 0) return + + call set_config_tforcing(Qa, "atm.Qa", ierr) + if (ierr /= 0) return + + call set_config_tforcing(RHa, "atm.RHa", ierr) + if (ierr /= 0) return + + call set_config_tforcing(sw_flux_surf, "atm.sw_in", ierr) + if (ierr /= 0) return + + call set_config_tforcing(lw_net_surf, "atm.lw_net", ierr) + if (ierr /= 0) return + + call set_config_tforcing(lw_in_surf, "atm.lw_in", ierr) + if (ierr /= 0) return + + !< default: using 'flux' mode + is_meteo_setup = 0 + if ((Ua%num > 0).OR.(Va%num > 0).OR.(Ta%num > 0).OR.& + (Pa%num > 0).OR.(Qa%num > 0).OR.(RHa%num > 0)) then + is_meteo_setup = 1 + endif + ! ---------------------------------------------------------------------------- + + !< setting bottom forcing + ! ---------------------------------------------------------------------------- + call set_const_tforcing(hflux_bot, 0.0) + + call set_const_tforcing(salin_flux_bot, 0.0) + + call set_const_tforcing(tau_x_bot, 0.0) + call set_const_tforcing(tau_y_bot, 0.0) + ! ---------------------------------------------------------------------------- + + !< check consistency + ! *: not implemented + ! ---------------------------------------------------------------------------- + + end block +#endif + end subroutine set_forcing + + ! -------------------------------------------------------------------------------- + subroutine set_initial_conditions(grid, setup_id, ierr) + !> @brief initial conditions setup + ! ---------------------------------------------------------------------------- + use obl_state + use obl_init + use obl_grid + use obl_run_kato, only : set_initial_conditions_kato => set_initial_conditions + use obl_run_papa_fluxes, only : set_initial_conditions_papa_fluxes => set_initial_conditions + use obl_run_papa_meteo, only : set_initial_conditions_papa_meteo => set_initial_conditions + + type (gridDataType), intent(in) :: grid + + integer, intent(in) :: setup_id + integer, intent(out) :: ierr + ! ---------------------------------------------------------------------------- + + ierr = 0 ! = OK + + if (setup_id == setup_kato) then + call set_initial_conditions_kato(grid) + return + endif + if (setup_id == setup_papa_fluxes) then + call set_initial_conditions_papa_fluxes(grid) + return + endif + if (setup_id == setup_papa_meteo) then + call set_initial_conditions_papa_meteo(grid) + return + endif + +#ifdef USE_CONFIG_PARSER + block + + end block +#endif + end subroutine set_initial_conditions + +end module obl_config diff --git a/obl_main.f90 b/obl_main.f90 index 04209fc13a117da2b6eb5e8d8be9710f381a1b8f..35fa113e19292db991921b6e3573a017c5ef3e1c 100644 --- a/obl_main.f90 +++ b/obl_main.f90 @@ -4,8 +4,8 @@ program obl_main !< @brief main program for calculations for ocean boundary layer #ifdef USE_CONFIG_PARSER - use iso_c_binding, only: C_NULL_CHAR - use config_parser + use iso_c_binding, only: C_NULL_CHAR + use config_parser #endif ! modules used @@ -35,9 +35,9 @@ program obl_main use obl_io_plt use io use io_metadata -#ifdef USE_CONFIG_PARSER - use config_parser -#endif + + use obl_config + !use vertical_mixing, default = off !use vermix @@ -73,7 +73,7 @@ program obl_main integer, parameter :: output_mode = 3 ! 1 -- netcdf, 2 -- ascii, 3 -- tecplot - integer, parameter :: obl_setup = 1 ! 1 - Kato-Phillips, 2 - Papa station (fluxes), 3 - Papa station (meteo) + integer :: obl_setup ! 1 - Kato-Phillips, 2 - Papa station (fluxes), 3 - Papa station (meteo) real, parameter :: Cd0 = 0.001 ! bottom drag coefficient @@ -90,6 +90,7 @@ program obl_main character(len = 128) :: arg character(len = 128), parameter :: arg_key_help = '--help' + character(len = 128), parameter :: arg_key_setup = '--setup' character(len = 128), parameter :: arg_key_config = "--config" integer :: ierr @@ -103,6 +104,7 @@ program obl_main + obl_setup = setup_kato !< ! 0 - Kato-Phillips (default), 1 - Papa station (fluxes), 2 - Papa station (meteo) closure_mode = 4 !< 1 - pacanowski-philander, 2 - pacanowski-philander+, 3 - k-epsilon explicit, 4 - k-epsilon semiimplicit, 5 - inmom @@ -115,12 +117,28 @@ program obl_main write(*, *) ' obl model, usage:' write(*, *) ' --help' write(*, *) ' print usage options' + write(*, *) ' --setup [key]' + write(*, *) ' key = kato (default) || papa-fluxes || papa' write(*, *) ' --config [filename]' write(*, *) ' use configuration file' return end if - if (trim(arg) == trim(arg_key_config)) then + if (trim(arg) == trim(arg_key_setup)) then + if (i == num_args) then + write(*, *) ' FAILURE! > missing setup [key] argument' + ierr = 1 ! signal ERROR + return + end if + + call get_command_argument(i + 1, arg) + obl_setup = get_setup_id(arg) + if (obl_setup == -1) then + write(*, *) ' FAILURE! > unknown setup [key]: ', trim(arg) + ierr = 1 ! signal ERROR + return + end if + else if (trim(arg) == trim(arg_key_config)) then if (i == num_args) then write(*, *) ' FAILURE! > missing configuration file [key] argument' ierr = 1 ! signal ERROR @@ -136,84 +154,31 @@ program obl_main return end if - call c_config_is_varname("domain.depth"//C_NULL_CHAR, status) - if (status /= 0) then - call c_config_get_float("domain.depth"//C_NULL_CHAR, domain_height, status) - if (status == 0) then - ierr = 1 ! signal ERROR - return - end if - end if - - call c_config_is_varname("grid.cz"//C_NULL_CHAR, status) - if (status /= 0) then - call c_config_get_int("grid.cz"//C_NULL_CHAR, grid_cz, status) - if (status == 0) then - ierr = 1 ! signal ERROR - return - end if - end if - - call c_config_is_varname("time.end"//C_NULL_CHAR, status) - if (status /= 0) then - call c_config_get_float("time.end"//C_NULL_CHAR, time_end, status) - if (status == 0) then - ierr = 1 ! signal ERROR - return - end if - end if - - call c_config_is_varname("time.begin"//C_NULL_CHAR, status) - if (status /= 0) then - call c_config_get_float("time.begin"//C_NULL_CHAR, time_begin, status) - if (status == 0) then - ierr = 1 ! signal ERROR - return - end if - end if - - call c_config_is_varname("time.dt"//C_NULL_CHAR, status) - if (status /= 0) then - call c_config_get_float("time.dt"//C_NULL_CHAR, dt, status) - if (status == 0) then - ierr = 1 ! signal ERROR - return - end if - end if + !< forcing configuration file setup + obl_setup = -1 #endif endif enddo - !< setting model time - ! ---------------------------------------------------------------------------- -#ifndef USE_CONFIG_PARSER - if (obl_setup == 1) then - time_begin = 0.0 - time_end = 300.0 * 3600.0 - dt = 1.0 - - domain_height = 100.0 - grid_cz = 32 - endif - if ((obl_setup == 2).or.(obl_setup == 3)) then - time_begin = 0.0 - time_end = 431.0 * 3600.0 - dt = 1.0 - - domain_height = 128.0 - grid_cz = 32 - endif -#endif - - time_current = time_begin + !< setting grid ! ---------------------------------------------------------------------------- - - ! setting grid -- just an example - ! > [zpos, height, cz, gcz] - call set_uniform_grid(grid, 0.0, domain_height, grid_cz) + call set_grid(grid, obl_setup, ierr) + if (ierr /= 0) then + return + endif - ! debug grid print + !< debug grid print call print_grid(grid) + ! ---------------------------------------------------------------------------- + + !< setting model time + ! ---------------------------------------------------------------------------- + call set_time(time_begin, time_end, dt, obl_setup, ierr) + if (ierr /= 0) then + return + endif + time_current = time_begin + ! ---------------------------------------------------------------------------- ! allocation call allocate_state_vec(grid%cz) @@ -223,125 +188,39 @@ program obl_main !< setting phys ! ---------------------------------------------------------------------------- - if (obl_setup == 1) then - f = 0.0 + call set_phys(obl_setup, ierr) + if (ierr /= 0) then + return endif - if ((obl_setup == 2).or.(obl_setup == 3)) then - f = 1.116 * 1e-4 - - a_band_ratio = 0.67 - a_extinction_coeff = 1.0 - b_extinction_coeff = 1.0 / 17.0 - endif ! ---------------------------------------------------------------------------- + !< setting forcing + ! ---------------------------------------------------------------------------- + call set_forcing(obl_setup, ierr) + if (ierr /= 0) then + return + endif + ! ---------------------------------------------------------------------------- !< initialization of main fields ! ---------------------------------------------------------------------------- - if (obl_setup == 1) then - call set_linear_profile(Theta, 330.0, 0.3, grid) - call set_const_profile(Salin, 35.0, grid) - endif - if ((obl_setup == 2).or.(obl_setup == 3)) then - call set_external_profile(Theta, 'PAPA_06_2017/Theta.dat', grid) - call set_external_profile(Salin, 'PAPA_06_2017/Salin.dat', grid) + call set_initial_conditions(grid, obl_setup, ierr) + if (ierr /= 0) then + return endif Theta_dev = Theta - Theta_ref Salin_dev = Salin - Salin_ref call get_density(Rho, Theta_dev, Salin_dev, grid%cz) + ! ---------------------------------------------------------------------------- - call set_const_profile(U, 0.0, grid) - call set_const_profile(V, 0.0, grid) - - !initialization of TKE & eps in case of k-epsilon closure + !< initialization of turbulence closure if (closure_mode.eq.3 .or. closure_mode.eq.4) then call TKE_init(TKE, param_k_epsilon, grid%cz) call eps_init(EPS, param_k_epsilon, grid%cz, grid%height) endif ! ---------------------------------------------------------------------------- - !< setting atmospheric forcing - ! ---------------------------------------------------------------------------- - is_meteo_setup = 0 - if (obl_setup == 1) then - call set_const_tforcing(sensible_hflux_surf, 0.0) - call set_const_tforcing(latent_hflux_surf, 0.0) - - call set_const_tforcing(salin_flux_surf, 0.0) - - call set_const_tforcing(tau_x_surf, 0.1) - call set_const_tforcing(tau_y_surf, 0.0) - - call set_const_tforcing(sw_flux_surf, 0.0) - - call set_const_tforcing(lw_net_surf, 0.0) - - endif - if (obl_setup == 2) then - call set_external_tforcing(sensible_hflux_surf, 'PAPA_06_2017/sensible_hflux.dat') - call set_external_tforcing(latent_hflux_surf, 'PAPA_06_2017/latent_hflux.dat') - - call set_const_tforcing(salin_flux_surf, 0.0) - - call set_external_tforcing(tau_x_surf, 'PAPA_06_2017/tau-x.dat') - call set_external_tforcing(tau_y_surf, 'PAPA_06_2017/tau-y.dat') - - call set_external_tforcing(sw_flux_surf, 'PAPA_06_2017/SW-down.dat') - - call set_external_tforcing(lw_in_surf, 'PAPA_06_2017/LW-down.dat') - - !< normalize time in external forcing: hrs -> sec - call normalize_time_tforcing(sensible_hflux_surf, 3600.0) - call normalize_time_tforcing(latent_hflux_surf, 3600.0) - - call normalize_time_tforcing(tau_x_surf, 3600.0) - call normalize_time_tforcing(tau_y_surf, 3600.0) - - call normalize_time_tforcing(sw_flux_surf, 3600.0) - - call normalize_time_tforcing(lw_in_surf, 3600.0) - endif - if (obl_setup == 3) then - is_meteo_setup = 1 - - call set_external_tforcing(Ua, 'PAPA_06_2017/u-wind.dat') - call set_external_tforcing(Va, 'PAPA_06_2017/v-wind.dat') - - call set_const_tforcing(salin_flux_surf, 0.0) - - call set_external_tforcing(Ta, 'PAPA_06_2017/Tair.dat') - call set_external_tforcing(Pa, 'PAPA_06_2017/Pair.dat') - call set_external_tforcing(RHa, 'PAPA_06_2017/RHair.dat') - - call set_external_tforcing(sw_flux_surf, 'PAPA_06_2017/SW-down.dat') - - call set_external_tforcing(lw_in_surf, 'PAPA_06_2017/LW-down.dat') - - !< normalize time in external forcing: hrs -> sec - call normalize_time_tforcing(Ua, 3600.0) - call normalize_time_tforcing(Va, 3600.0) - - call normalize_time_tforcing(Ta, 3600.0) - call normalize_time_tforcing(Pa, 3600.0) - call normalize_time_tforcing(RHa, 3600.0) - - call normalize_time_tforcing(sw_flux_surf, 3600.0) - - call normalize_time_tforcing(lw_in_surf, 3600.0) - endif - ! ---------------------------------------------------------------------------- - - !< setting bottom forcing - ! ---------------------------------------------------------------------------- - call set_const_tforcing(hflux_bot, 0.0) - - call set_const_tforcing(salin_flux_bot, 0.0) - - call set_const_tforcing(tau_x_bot, 0.0) - call set_const_tforcing(tau_y_bot, 0.0) - ! ---------------------------------------------------------------------------- - !< setting reference data ! ---------------------------------------------------------------------------- N2_0 = 0.00044 diff --git a/obl_math.f90 b/obl_math.f90 index d3ee7b6d0a6ef7ef5923bb017d9ae85dda2a0f13..ef157097eee9cc29e244e0268d5b0ccac7db4b76 100644 --- a/obl_math.f90 +++ b/obl_math.f90 @@ -19,6 +19,7 @@ module obl_math public :: limit_min_array, limit_max_array public :: tma public :: is_finite + public :: char_array2str ! -------------------------------------------------------------------------------- @@ -146,4 +147,22 @@ module obl_math enddo end function is_finite + !> @brief character array to string conversion + function char_array2str(char_array) result(str) + ! ---------------------------------------------------------------------------- + implicit none + character, intent(in) :: char_array(:) + character(len=:), allocatable :: str + integer :: i + ! ---------------------------------------------------------------------------- + + str = "" + do i = 1, size(char_array) + str = str(:) // char_array(i) + end do + + end function + ! ---------------------------------------------------------------------------- + + end module diff --git a/obl_run_kato.f90 b/obl_run_kato.f90 new file mode 100644 index 0000000000000000000000000000000000000000..8b441f212df543480e7388506f5e40d426cda319 --- /dev/null +++ b/obl_run_kato.f90 @@ -0,0 +1,127 @@ +module obl_run_kato + !< @brief obl scm kato-phillips setup + ! -------------------------------------------------------------------------------- + + ! TO DO: + ! -- *** + + ! modules used + ! -------------------------------------------------------------------------------- + + ! directives list + ! -------------------------------------------------------------------------------- + implicit none + private + + ! public interface + ! -------------------------------------------------------------------------------- + public :: set_phys + public :: set_grid + public :: set_time + public :: set_forcing + public :: set_initial_conditions + ! -------------------------------------------------------------------------------- + + ! -------------------------------------------------------------------------------- + ! -------------------------------------------------------------------------------- + + + contains + + ! -------------------------------------------------------------------------------- + subroutine set_phys + !> @brief phys parameters setup + ! ---------------------------------------------------------------------------- + use obl_scm + ! ---------------------------------------------------------------------------- + + !< coriolis frequency + f = 0.0 + + end subroutine set_phys + + ! -------------------------------------------------------------------------------- + subroutine set_grid(grid) + !> @brief grid parameters setup + ! ---------------------------------------------------------------------------- + use obl_grid + + type (gridDataType), intent(inout) :: grid + ! ---------------------------------------------------------------------------- + + !< in: [zpos, height, cz] + call set_uniform_grid(grid, - 100.0, 100.0, 32) + + end subroutine set_grid + + ! -------------------------------------------------------------------------------- + subroutine set_time(time_begin, time_end, dt) + !> @brief time parameters setup + ! ---------------------------------------------------------------------------- + real, intent(out) :: time_begin, time_end, dt + ! ---------------------------------------------------------------------------- + + time_begin = 0.0 + time_end = 300.0 * 3600.0 + dt = 1.0 + + end subroutine set_time + + ! -------------------------------------------------------------------------------- + subroutine set_forcing + !> @brief forcing setup + ! ---------------------------------------------------------------------------- + use obl_fluxes + use obl_tforcing + ! ---------------------------------------------------------------------------- + + !< setting atmospheric forcing + ! ---------------------------------------------------------------------------- + !< using 'flux' mode + is_meteo_setup = 0 + + call set_const_tforcing(sensible_hflux_surf, 0.0) + call set_const_tforcing(latent_hflux_surf, 0.0) + + call set_const_tforcing(salin_flux_surf, 0.0) + + call set_const_tforcing(tau_x_surf, 0.1) + call set_const_tforcing(tau_y_surf, 0.0) + + call set_const_tforcing(sw_flux_surf, 0.0) + + call set_const_tforcing(lw_net_surf, 0.0) + ! ---------------------------------------------------------------------------- + + !< setting bottom forcing + ! ---------------------------------------------------------------------------- + call set_const_tforcing(hflux_bot, 0.0) + + call set_const_tforcing(salin_flux_bot, 0.0) + + call set_const_tforcing(tau_x_bot, 0.0) + call set_const_tforcing(tau_y_bot, 0.0) + ! ---------------------------------------------------------------------------- + + end subroutine set_forcing + + ! -------------------------------------------------------------------------------- + subroutine set_initial_conditions(grid) + !> @brief initial_conditions setup + ! ---------------------------------------------------------------------------- + use obl_state + use obl_init + use obl_grid + + type (gridDataType), intent(in) :: grid + ! ---------------------------------------------------------------------------- + + call set_linear_profile(Theta, 330.0, 0.3, grid) + call set_const_profile(Salin, 35.0, grid) + + call set_const_profile(U, 0.0, grid) + call set_const_profile(V, 0.0, grid) + + end subroutine set_initial_conditions + +end module diff --git a/obl_run_papa_fluxes.f90 b/obl_run_papa_fluxes.f90 new file mode 100644 index 0000000000000000000000000000000000000000..b87911dc67900e1a404b3ab283c677f824e5b139 --- /dev/null +++ b/obl_run_papa_fluxes.f90 @@ -0,0 +1,146 @@ +module obl_run_papa_fluxes + !< @brief obl scm Papa-station 'fluxes' setup + ! -------------------------------------------------------------------------------- + + ! TO DO: + ! -- *** + + ! modules used + ! -------------------------------------------------------------------------------- + + ! directives list + ! -------------------------------------------------------------------------------- + implicit none + private + + ! public interface + ! -------------------------------------------------------------------------------- + public :: set_phys + public :: set_grid + public :: set_time + public :: set_forcing + public :: set_initial_conditions + ! -------------------------------------------------------------------------------- + + ! -------------------------------------------------------------------------------- + character(len = 256), parameter :: path = 'PAPA_06_2017/' + ! -------------------------------------------------------------------------------- + + + contains + + ! -------------------------------------------------------------------------------- + subroutine set_phys + !> @brief phys parameters setup + ! ---------------------------------------------------------------------------- + use obl_scm + ! ---------------------------------------------------------------------------- + + !< coriolis frequency + f = 1.116 * 1e-4 + + !< SW extinction parameters + a_band_ratio = 0.67 + a_extinction_coeff = 1.0 + b_extinction_coeff = 1.0 / 17.0 + + sw_albedo = 0.3 + + end subroutine set_phys + + ! -------------------------------------------------------------------------------- + subroutine set_grid(grid) + !> @brief grid parameters setup + ! ---------------------------------------------------------------------------- + use obl_grid + + type (gridDataType), intent(inout) :: grid + ! ---------------------------------------------------------------------------- + + !< in: [zpos, height, cz] + call set_uniform_grid(grid, -128.0, 128.0, 32) + + end subroutine set_grid + + ! -------------------------------------------------------------------------------- + subroutine set_time(time_begin, time_end, dt) + !> @brief time parameters setup + ! ---------------------------------------------------------------------------- + real, intent(out) :: time_begin, time_end, dt + ! ---------------------------------------------------------------------------- + + time_begin = 0.0 + time_end = 431.0 * 3600.0 + dt = 1.0 + + end subroutine set_time + + ! -------------------------------------------------------------------------------- + subroutine set_forcing + !> @brief forcing setup + ! ---------------------------------------------------------------------------- + use obl_fluxes + use obl_tforcing + ! ---------------------------------------------------------------------------- + + !< setting atmospheric forcing + ! ---------------------------------------------------------------------------- + !< using 'flux' mode + is_meteo_setup = 0 + + call set_external_tforcing(sensible_hflux_surf, trim(path)//'sensible_hflux.dat') + call set_external_tforcing(latent_hflux_surf, trim(path)//'latent_hflux.dat') + + call set_const_tforcing(salin_flux_surf, 0.0) + + call set_external_tforcing(tau_x_surf, trim(path)//'tau-x.dat') + call set_external_tforcing(tau_y_surf, trim(path)//'tau-y.dat') + + call set_external_tforcing(sw_flux_surf, trim(path)//'SW-down.dat') + + call set_external_tforcing(lw_in_surf, trim(path)//'LW-down.dat') + + !< normalize time in external forcing: hrs -> sec + call normalize_time_tforcing(sensible_hflux_surf, 3600.0) + call normalize_time_tforcing(latent_hflux_surf, 3600.0) + + call normalize_time_tforcing(tau_x_surf, 3600.0) + call normalize_time_tforcing(tau_y_surf, 3600.0) + + call normalize_time_tforcing(sw_flux_surf, 3600.0) + + call normalize_time_tforcing(lw_in_surf, 3600.0) + ! ---------------------------------------------------------------------------- + + !< setting bottom forcing + ! ---------------------------------------------------------------------------- + call set_const_tforcing(hflux_bot, 0.0) + + call set_const_tforcing(salin_flux_bot, 0.0) + + call set_const_tforcing(tau_x_bot, 0.0) + call set_const_tforcing(tau_y_bot, 0.0) + ! ---------------------------------------------------------------------------- + + end subroutine set_forcing + + ! -------------------------------------------------------------------------------- + subroutine set_initial_conditions(grid) + !> @brief initial_conditions setup + ! ---------------------------------------------------------------------------- + use obl_state + use obl_init + use obl_grid + + type (gridDataType), intent(in) :: grid + ! ---------------------------------------------------------------------------- + + call set_external_profile(Theta, trim(path)//'Theta.dat', grid) + call set_external_profile(Salin, trim(path)//'Salin.dat', grid) + + call set_const_profile(U, 0.0, grid) + call set_const_profile(V, 0.0, grid) + + end subroutine set_initial_conditions + +end module diff --git a/obl_run_papa_meteo.f90 b/obl_run_papa_meteo.f90 new file mode 100644 index 0000000000000000000000000000000000000000..f5f3d150754c4c9b5ac2c77477133334b8bd9f65 --- /dev/null +++ b/obl_run_papa_meteo.f90 @@ -0,0 +1,148 @@ +module obl_run_papa_meteo + !< @brief obl scm Papa-station 'meteo' setup + ! -------------------------------------------------------------------------------- + + ! TO DO: + ! -- *** + + ! modules used + ! -------------------------------------------------------------------------------- + + ! directives list + ! -------------------------------------------------------------------------------- + implicit none + private + + ! public interface + ! -------------------------------------------------------------------------------- + public :: set_phys + public :: set_grid + public :: set_time + public :: set_forcing + public :: set_initial_conditions + ! -------------------------------------------------------------------------------- + + ! -------------------------------------------------------------------------------- + character(len = 256), parameter :: path = 'PAPA_06_2017/' + ! -------------------------------------------------------------------------------- + + + contains + + ! -------------------------------------------------------------------------------- + subroutine set_phys + !> @brief phys parameters setup + ! ---------------------------------------------------------------------------- + use obl_scm + ! ---------------------------------------------------------------------------- + + !< coriolis frequency + f = 1.116 * 1e-4 + + !< SW extinction parameters + a_band_ratio = 0.67 + a_extinction_coeff = 1.0 + b_extinction_coeff = 1.0 / 17.0 + + sw_albedo = 0.3 + + end subroutine set_phys + + ! -------------------------------------------------------------------------------- + subroutine set_grid(grid) + !> @brief grid parameters setup + ! ---------------------------------------------------------------------------- + use obl_grid + + type (gridDataType), intent(inout) :: grid + ! ---------------------------------------------------------------------------- + + !< in: [zpos, height, cz] + call set_uniform_grid(grid, 0.0, 128.0, 32) + + end subroutine set_grid + + ! -------------------------------------------------------------------------------- + subroutine set_time(time_begin, time_end, dt) + !> @brief time parameters setup + ! ---------------------------------------------------------------------------- + real, intent(out) :: time_begin, time_end, dt + ! ---------------------------------------------------------------------------- + + time_begin = 0.0 + time_end = 431.0 * 3600.0 + dt = 1.0 + + end subroutine set_time + + ! -------------------------------------------------------------------------------- + subroutine set_forcing + !> @brief forcing setup + ! ---------------------------------------------------------------------------- + use obl_fluxes + use obl_tforcing + ! ---------------------------------------------------------------------------- + + !< setting atmospheric forcing + ! ---------------------------------------------------------------------------- + !< using 'meteo' mode + is_meteo_setup = 1 + + call set_external_tforcing(Ua, trim(path)//'u-wind.dat') + call set_external_tforcing(Va, trim(path)//'v-wind.dat') + + call set_const_tforcing(salin_flux_surf, 0.0) + + call set_external_tforcing(Ta, trim(path)//'Tair.dat') + call set_external_tforcing(Pa, trim(path)//'Pair.dat') + call set_external_tforcing(RHa, trim(path)//'RHair.dat') + + call set_external_tforcing(sw_flux_surf, trim(path)//'SW-down.dat') + + call set_external_tforcing(lw_in_surf, trim(path)//'LW-down.dat') + + !< normalize time in external forcing: hrs -> sec + call normalize_time_tforcing(Ua, 3600.0) + call normalize_time_tforcing(Va, 3600.0) + + call normalize_time_tforcing(Ta, 3600.0) + call normalize_time_tforcing(Pa, 3600.0) + call normalize_time_tforcing(RHa, 3600.0) + + call normalize_time_tforcing(sw_flux_surf, 3600.0) + + call normalize_time_tforcing(lw_in_surf, 3600.0) + ! ---------------------------------------------------------------------------- + + !< setting bottom forcing + ! ---------------------------------------------------------------------------- + call set_const_tforcing(hflux_bot, 0.0) + + call set_const_tforcing(salin_flux_bot, 0.0) + + call set_const_tforcing(tau_x_bot, 0.0) + call set_const_tforcing(tau_y_bot, 0.0) + ! ---------------------------------------------------------------------------- + + end subroutine set_forcing + + ! -------------------------------------------------------------------------------- + subroutine set_initial_conditions(grid) + !> @brief initial_conditions setup + ! ---------------------------------------------------------------------------- + use obl_state + use obl_init + use obl_grid + + type (gridDataType), intent(in) :: grid + ! ---------------------------------------------------------------------------- + + call set_external_profile(Theta, trim(path)//'Theta.dat', grid) + call set_external_profile(Salin, trim(path)//'Salin.dat', grid) + + call set_const_profile(U, 0.0, grid) + call set_const_profile(V, 0.0, grid) + + end subroutine set_initial_conditions + +end module diff --git a/obl_tforcing.f90 b/obl_tforcing.f90 index 8c0f97f6cc44763d92af0f7ca11b9ae85e0a4a78..37b793634687b3468b35f1750799a2a0c3e25dd4 100644 --- a/obl_tforcing.f90 +++ b/obl_tforcing.f90 @@ -1,9 +1,15 @@ +#include "obl_def.fi" + module obl_tforcing !< @brief obl time dependent forcing def. ! -------------------------------------------------------------------------------- ! modules used ! -------------------------------------------------------------------------------- +#ifdef USE_CONFIG_PARSER + use iso_c_binding, only: C_NULL_CHAR + use config_parser +#endif ! directives list implicit none @@ -12,6 +18,7 @@ module obl_tforcing ! public interface ! -------------------------------------------------------------------------------- public :: set_const_tforcing, set_external_tforcing, set_generic_tforcing + public :: set_config_tforcing public :: get_value_tforcing public :: normalize_time_tforcing public :: deallocate_tforcing @@ -22,7 +29,7 @@ module obl_tforcing real, allocatable :: time(:) !< time array [s] real, allocatable :: fvalue(:) !< value array [*] - integer :: num !< number of time marks + integer :: num = 0 !< number of time marks end type @@ -125,6 +132,74 @@ module obl_tforcing end subroutine set_generic_tforcing + ! -------------------------------------------------------------------------------- + subroutine set_config_tforcing(tforcing, tag, ierr) + !> @brief generic forcing setup + ! ---------------------------------------------------------------------------- + use obl_math, only : char_array2str + + type (timeForcingDataType), intent(inout) :: tforcing + integer, intent(out) :: ierr + + character(len = *), intent(in) :: tag + + real :: fvalue + character, allocatable :: config_field(:) + integer :: status + ! ---------------------------------------------------------------------------- + + ierr = 0 ! = OK + + call deallocate_tforcing(tforcing) + +#ifdef USE_CONFIG_PARSER + call c_config_is_varname(trim(tag)//".mode"//C_NULL_CHAR, status) + if (status /= 0) then + call c_config_get_string(trim(tag)//".mode"//C_NULL_CHAR, config_field, status) + if (status == 0) then + ierr = 1 ! signal ERROR + return + end if + + if (trim(char_array2str(config_field)) == 'const') then + call c_config_get_float(trim(tag)//".value"//C_NULL_CHAR, fvalue, status) + if (status == 0) then + ierr = 1 ! signal ERROR + return + end if + + call set_const_tforcing(tforcing, fvalue) + else if (trim(char_array2str(config_field)) == 'ascii') then + call c_config_get_string(trim(tag)//".filename"//C_NULL_CHAR, config_field, status) + if (status == 0) then + ierr = 1 ! signal ERROR + return + end if + + call set_external_tforcing(tforcing, char_array2str(config_field)) + else + write(*, *) ' FAILURE! > unknown forcing mode: ', trim(char_array2str(config_field)) + ierr = 1 ! signal ERROR + return + endif + else + call c_config_is_varname(trim(tag)//C_NULL_CHAR, status) + if (status /= 0) then + call c_config_get_float(trim(tag)//C_NULL_CHAR, fvalue, status) + if (status == 0) then + ierr = 1 ! signal ERROR + return + end if + + call set_const_tforcing(tforcing, fvalue) + endif + endif + + if (allocated(config_field)) deallocate(config_field) +#endif + + end subroutine set_config_tforcing + ! -------------------------------------------------------------------------------- subroutine get_value_tforcing(res, t, tforcing) !> @brief get value at time = t