Skip to content
Snippets Groups Projects
Commit 4d4dee64 authored by Evgeny Mortikov's avatar Evgeny Mortikov
Browse files

scm output implementation update

parent 07a0d47c
Branches
No related tags found
No related merge requests found
......@@ -9,6 +9,7 @@ module obl_common_phys
real, public, parameter :: g = 9.80655 !< gravity acceleration [m / s^2]
real, public, parameter :: cp_air = 1003.5 !< specific heat of air [J / (kg * K]
real, public, parameter :: cp_water = 4189.9 !< specific heat of water [J / (kg * K]
real, public, parameter :: zero_celsius = 273.15 !< zero celsius [K]
! --------------------------------------------------------------------------------
end module
......@@ -73,6 +73,9 @@ program obl_main
real :: domain_height
integer :: grid_cz
!< output
type(oblOutputStx) :: scm_output
real :: dt !< time step [s]
integer :: i, k !< counters
......@@ -407,49 +410,37 @@ program obl_main
!> advance file output
if (mod(i, noutput) == 0) then
call push_state_vec(grid%cz)
call push_state_vec(scm_output, grid%cz)
call get_mld(mld, N2, grid%dz, grid%cz)
call get_mld_ref(lab_mld, bc%U_dynH, N2_0, time_current, grid%height)
call push_value_to_tseries(output_mld, mld)
call push_value_to_tseries(output_mld_ref, lab_mld)
call push_value_to_tseries(scm_output%mld, mld)
call push_value_to_tseries(scm_output%mld_ref, lab_mld)
call push_value_to_tseries(output_tau_x, bc%u_momentum_fluxH)
call push_value_to_tseries(output_tau_y, bc%v_momentum_fluxH)
call push_value_to_tseries(scm_output%tau_x, bc%u_momentum_fluxH * Rho_ref)
call push_value_to_tseries(scm_output%tau_y, bc%v_momentum_fluxH * Rho_ref)
call push_value_to_tseries(output_Theta_surf, Theta_dev(grid%cz))
call push_value_to_tseries(scm_output%Theta_surf, Theta_dev(grid%cz) + Theta_ref)
call push_value_to_tseries(output_time, time_current / 3600.0)
call push_value_to_tseries(scm_output%time, time_current / 3600.0)
endif
enddo
if (output_mode > 0) then
output_Theta%data(:,1:output_Theta%num) = output_Theta%data(:,1:output_Theta%num) + Theta_ref
output_Salin%data(:,1:output_Salin%num) = output_Salin%data(:,1:output_Salin%num) + Salin_ref
output_TinC%data(:,1:output_TinC%num) = output_TinC%data(:,1:output_TinC%num) + Theta_ref - 273.15
output_tau_x%data(1:output_tau_x%num) = output_tau_x%data(1:output_tau_x%num) * Rho_ref
output_tau_y%data(1:output_tau_y%num) = output_tau_y%data(1:output_tau_y%num) * Rho_ref
output_Theta_surf%data(1:output_Theta_surf%num) = output_Theta_surf%data(1:output_Theta_surf%num) + Theta_ref
endif
if (output_mode.eq.1) then
write(*, *) ' >> writing netcdf output ...'
call write_netcdf
call write_netcdf(scm_output, grid%z)
endif
if (output_mode.eq.2) then
write(*, *) ' >> writing ascii output ...'
call write_ascii
call write_ascii(scm_output, grid%z)
endif
if (output_mode.eq.3) then
write(*, *) ' >> writing tecplot output ...'
call write_tecplot(grid%z, output_time%data)
call write_tecplot(scm_output, grid%z)
endif
......@@ -478,7 +469,7 @@ program obl_main
!> removing time slice data
call output_cleanup
call output_cleanup(scm_output)
! > removing grid data
call deallocate_grid(grid)
......
......@@ -2,6 +2,10 @@ module obl_output
!< @brief obl output def.
! --------------------------------------------------------------------------------
! TO DO:
! -- add option to set path
! -- write time/coordinates in netcdf/ascii output
! modules used
! --------------------------------------------------------------------------------
use obl_tseries
......@@ -19,248 +23,277 @@ module obl_output
public :: write_netcdf, write_ascii, write_tecplot
! --------------------------------------------------------------------------------
!> @brief state output
type(oblTimeSlice), public :: output_Theta, output_Salin
type(oblTimeSlice), public :: output_Rho
type(oblTimeSlice), public :: output_U, output_V
!> @brief output storage
type, public :: oblOutputStx
!> state output
type(oblTimeSlice), public :: Theta, Salin
type(oblTimeSlice), public :: Rho
type(oblTimeSlice), public :: output_N2, output_S2, output_Ri_grad
type(oblTimeSlice), public :: U, V
type(oblTimeSlice), public :: output_Km, output_Kh
type(oblTimeSlice), public :: N2, S2, Ri_grad
type(oblTimeSlice), public :: output_TinC
type(oblTimeSlice), public :: Km, Kh
!> @brief time series output
type(oblTimeSeries), public :: output_time
type(oblTimeSlice), public :: TinC
type(oblTimeSeries), public :: output_mld
type(oblTimeSeries), public :: output_mld_ref
!> time series output
type(oblTimeSeries), public :: time
type(oblTImeSeries), public :: output_tau_x, output_tau_y
type(oblTimeSeries), public :: mld
type(oblTimeSeries), public :: mld_ref
type(oblTimeSeries), public :: output_Theta_surf
type(oblTImeSeries), public :: tau_x, tau_y
type(oblTimeSeries), public :: Theta_surf
end type
contains
! --------------------------------------------------------------------------------
subroutine push_state_vec(cz)
subroutine push_state_vec(output, cz)
!> @brief allocate state vector
! ----------------------------------------------------------------------------
use obl_state
use obl_state_eq
use obl_common_phys, only: zero_celsius
type (oblOutputStx), intent(inout) :: output
integer, intent(in) :: cz
! ----------------------------------------------------------------------------
call push_profile_to_tslice(output_Theta, Theta_dev, cz)
call push_profile_to_tslice(output_Salin, Salin_dev, cz)
call push_profile_to_tslice(output%Theta, Theta_dev + Theta_ref, cz)
call push_profile_to_tslice(output%Salin, Salin_dev + Salin_ref, cz)
call push_profile_to_tslice(output_Rho, Rho, cz)
call push_profile_to_tslice(output%Rho, Rho, cz)
call push_profile_to_tslice(output_U, U, cz)
call push_profile_to_tslice(output_V, V, cz)
call push_profile_to_tslice(output%U, U, cz)
call push_profile_to_tslice(output%V, V, cz)
call push_profile_to_tslice(output_N2, N2, cz)
call push_profile_to_tslice(output_S2, S2, cz)
call push_profile_to_tslice(output_Ri_grad, Ri_grad, cz)
call push_profile_to_tslice(output%N2, N2, cz)
call push_profile_to_tslice(output%S2, S2, cz)
call push_profile_to_tslice(output%Ri_grad, Ri_grad, cz)
call push_profile_to_tslice(output_Km, Km, cz)
call push_profile_to_tslice(output_Kh, Kh, cz)
call push_profile_to_tslice(output%Km, Km, cz)
call push_profile_to_tslice(output%Kh, Kh, cz)
call push_profile_to_tslice(output_TinC, Theta_dev, cz)
call push_profile_to_tslice(output%TinC, Theta_dev + Theta_ref - zero_celsius, cz)
end subroutine push_state_vec
! --------------------------------------------------------------------------------
subroutine write_netcdf
subroutine write_netcdf(output, zcoord)
!> @brief write netcdf data
! ----------------------------------------------------------------------------
use io
use io_metadata
type (oblOutputStx), intent(inout) :: output
real, allocatable, intent(in) :: zcoord(:)
character(len=32) :: path
integer :: num
! ----------------------------------------------------------------------------
num = output%time%num
if (num == 0) return
path = ''
!> time slice output
call write_2d_real_nc(output_Theta%data(:,1:output_Theta%num), 'output.nc', meta_theta)
call write_2d_real_nc(output_Salin%data(:,1:output_Salin%num), 'output.nc', meta_salin)
call write_2d_real_nc(output%Theta%data(:, 1:num), trim(path) // 'output.nc', meta_theta)
call write_2d_real_nc(output%Salin%data(:, 1:num), trim(path) // 'output.nc', meta_salin)
call write_2d_real_nc(output_Rho%data(:,1:output_Rho%num), 'output.nc', meta_rho)
call write_2d_real_nc(output%Rho%data(:, 1:num), trim(path) // 'output.nc', meta_rho)
call write_2d_real_nc(output_U%data(:,1:output_U%num), 'output.nc', meta_u)
call write_2d_real_nc(output_V%data(:,1:output_V%num), 'output.nc', meta_v)
call write_2d_real_nc(output%U%data(:, 1:num), trim(path) // 'output.nc', meta_u)
call write_2d_real_nc(output%V%data(:, 1:num), trim(path) // 'output.nc', meta_v)
call write_2d_real_nc(output_N2%data(:,1:output_N2%num), 'output.nc', meta_n2)
call write_2d_real_nc(output_S2%data(:,1:output_S2%num), 'output.nc', meta_s2)
call write_2d_real_nc(output_Ri_grad%data(:,1:output_Ri_grad%num), 'output.nc', meta_ri_grad)
call write_2d_real_nc(output%N2%data(:, 1:num), trim(path) // 'output.nc', meta_n2)
call write_2d_real_nc(output%S2%data(:, 1:num), trim(path) // 'output.nc', meta_s2)
call write_2d_real_nc(output%Ri_grad%data(:, 1:num), trim(path) // 'output.nc', meta_ri_grad)
call write_2d_real_nc(output_Km%data(:,1:output_Km%num), 'output.nc', meta_km)
call write_2d_real_nc(output_Kh%data(:,1:output_Kh%num), 'output.nc', meta_kh)
call write_2d_real_nc(output%Km%data(:, 1:num), trim(path) // 'output.nc', meta_km)
call write_2d_real_nc(output%Kh%data(:, 1:num), trim(path) // 'output.nc', meta_kh)
call write_2d_real_nc(output_TinC%data(:,1:output_TinC%num), 'output.nc', meta_theta_C)
call write_2d_real_nc(output%TinC%data(:, 1:num), trim(path) // 'output.nc', meta_theta_C)
!> time series output
call write_1d_real_nc(output_mld%data(1:output_mld%num), 'output.nc', meta_mld)
call write_1d_real_nc(output_mld_ref%data(1:output_mld_ref%num), 'output.nc', meta_lab_mld)
call write_1d_real_nc(output%mld%data(1:num), trim(path) // 'output.nc', meta_mld)
call write_1d_real_nc(output%mld_ref%data(1:num), trim(path) // 'output.nc', meta_lab_mld)
call write_1d_real_nc(output_tau_x%data(1:output_tau_x%num), 'output.nc', meta_tau_u)
call write_1d_real_nc(output_tau_y%data(1:output_tau_y%num), 'output.nc', meta_tau_v)
call write_1d_real_nc(output%tau_x%data(1:num), trim(path) // 'output.nc', meta_tau_u)
call write_1d_real_nc(output%tau_y%data(1:num), trim(path) // 'output.nc', meta_tau_v)
call write_1d_real_nc(output_Theta_surf%data(1:output_Theta_surf%num), 'output.nc', meta_theta_surf)
call write_1d_real_nc(output%Theta_surf%data(1:num), trim(path) // 'output.nc', meta_theta_surf)
end subroutine write_netcdf
! --------------------------------------------------------------------------------
subroutine write_ascii
subroutine write_ascii(output, zcoord)
!> @brief write ascii data
! ----------------------------------------------------------------------------
use io
use io_metadata
type (oblOutputStx), intent(inout) :: output
real, allocatable, intent(in) :: zcoord(:)
character(len=32) :: path
integer :: num
! ----------------------------------------------------------------------------
num = output%time%num
if (num == 0) return
path = ''
!> time slice output
call write_2d_real_ascii(output_Theta%data(:,1:output_Theta%num), &
call write_2d_real_ascii(output%Theta%data(:, 1:num), &
trim(path) // trim(meta_theta%name) // '.txt', meta_theta)
call write_2d_real_ascii(output_Salin%data(:,1:output_Salin%num), &
call write_2d_real_ascii(output%Salin%data(:, 1:num), &
trim(path) // trim(meta_salin%name) // '.txt', meta_salin)
call write_2d_real_ascii(output_Rho%data(:,1:output_Rho%num), &
call write_2d_real_ascii(output%Rho%data(:, 1:num), &
trim(path) // trim(meta_rho%name) // '.txt', meta_rho)
call write_2d_real_ascii(output_U%data(:,1:output_U%num), &
call write_2d_real_ascii(output%U%data(:, 1:num), &
trim(path) // trim(meta_u%name) // '.txt', meta_u)
call write_2d_real_ascii(output_V%data(:,1:output_V%num), &
call write_2d_real_ascii(output%V%data(:, 1:num), &
trim(path) // trim(meta_v%name) // '.txt', meta_v)
call write_2d_real_ascii(output_N2%data(:,1:output_N2%num), &
call write_2d_real_ascii(output%N2%data(:, 1:num), &
trim(path) // trim(meta_n2%name) // '.txt', meta_n2)
call write_2d_real_ascii(output_S2%data(:,1:output_S2%num), &
call write_2d_real_ascii(output%S2%data(:, 1:num), &
trim(path) // trim(meta_s2%name) // '.txt', meta_s2)
call write_2d_real_ascii(output_Ri_grad%data(:,1:output_Ri_grad%num), &
call write_2d_real_ascii(output%Ri_grad%data(:, 1:num), &
trim(path) // trim(meta_ri_grad%name) // '.txt', meta_ri_grad)
call write_2d_real_ascii(output_Km%data(:,1:output_Km%num), &
call write_2d_real_ascii(output%Km%data(:, 1:num), &
trim(path) // trim(meta_km%name) // '.txt', meta_km)
call write_2d_real_ascii(output_Kh%data(:,1:output_Kh%num), &
call write_2d_real_ascii(output%Kh%data(:, 1:num), &
trim(path) // trim(meta_kh%name) // '.txt', meta_kh)
call write_2d_real_ascii(output_TinC%data(:,1:output_TinC%num), &
call write_2d_real_ascii(output%TinC%data(:, 1:num), &
trim(path) // trim(meta_theta_C%name) // '.txt', meta_theta_C)
!> time series output
call write_1d_real_ascii(output_mld%data(1:output_mld%num), &
call write_1d_real_ascii(output%mld%data(1:num), &
trim(path) // trim(meta_mld%name) // '.txt', meta_mld)
call write_1d_real_ascii(output_mld_ref%data(1:output_mld_ref%num), &
call write_1d_real_ascii(output%mld_ref%data(1:num), &
trim(path) // trim(meta_lab_mld%name) // '.txt', meta_lab_mld)
call write_1d_real_ascii(output_tau_x%data(1:output_tau_x%num), &
call write_1d_real_ascii(output%tau_x%data(1:num), &
trim(path) // trim(meta_tau_u%name) // '.txt', meta_tau_u)
call write_1d_real_ascii(output_tau_y%data(1:output_tau_y%num), &
call write_1d_real_ascii(output%tau_y%data(1:num), &
trim(path) // trim(meta_tau_v%name) // '.txt', meta_tau_v)
call write_1d_real_ascii(output_Theta_surf%data(1:output_Theta_surf%num), &
call write_1d_real_ascii(output%Theta_surf%data(1:num), &
trim(path) // trim(meta_theta_surf%name) // '.txt', meta_theta_surf)
end subroutine write_ascii
! --------------------------------------------------------------------------------
subroutine write_tecplot(zcoord, tcoord)
subroutine write_tecplot(output, zcoord)
!> @brief write tecplot data
! ----------------------------------------------------------------------------
use io
use io_metadata
use obl_io_plt
type (oblOutputStx), intent(inout) :: output
real, allocatable, intent(in) :: zcoord(:)
real, allocatable, intent(in) :: tcoord(:)
character(len=32) :: path
integer :: num
! ----------------------------------------------------------------------------
num = output%time%num
if (num == 0) return
path = ''
!> time slice output
call write_2d_real_plt(output_Theta%data(:,1:output_Theta%num), zcoord, tcoord(1:output_Theta%num), &
call write_2d_real_plt(output%Theta%data(:, 1:num), zcoord, output%time%data(1:num), &
trim(path) // trim(meta_theta%name) // '.plt', meta_theta)
call write_2d_real_plt(output_Salin%data(:,1:output_Salin%num), zcoord, tcoord(1:output_Salin%num), &
call write_2d_real_plt(output%Salin%data(:, 1:num), zcoord, output%time%data(1:num), &
trim(path) // trim(meta_salin%name) // '.plt', meta_salin)
call write_2d_real_plt(output_Rho%data(:,1:output_Rho%num), zcoord, tcoord(1:output_Rho%num), &
call write_2d_real_plt(output%Rho%data(:, 1:num), zcoord, output%time%data(1:num), &
trim(path) // trim(meta_rho%name) // '.plt', meta_rho)
call write_2d_real_plt(output_U%data(:,1:output_U%num), zcoord, tcoord(1:output_U%num), &
call write_2d_real_plt(output%U%data(:, 1:num), zcoord, output%time%data(1:num), &
trim(path) // trim(meta_u%name) // '.plt', meta_u)
call write_2d_real_plt(output_V%data(:,1:output_V%num), zcoord, tcoord(1:output_V%num), &
call write_2d_real_plt(output%V%data(:, 1:num), zcoord, output%time%data(1:num), &
trim(path) // trim(meta_v%name) // '.plt', meta_v)
call write_2d_real_plt(output_N2%data(:,1:output_N2%num), zcoord, tcoord(1:output_N2%num), &
call write_2d_real_plt(output%N2%data(:, 1:num), zcoord, output%time%data(1:num), &
trim(path) // trim(meta_n2%name) // '.plt', meta_n2)
call write_2d_real_plt(output_S2%data(:,1:output_S2%num), zcoord, tcoord(1:output_S2%num), &
call write_2d_real_plt(output%S2%data(:, 1:num), zcoord, output%time%data(1:num), &
trim(path) // trim(meta_s2%name) // '.plt', meta_s2)
call write_2d_real_plt(output_Ri_grad%data(:,1:output_Ri_grad%num), zcoord, tcoord(1:output_Ri_grad%num), &
call write_2d_real_plt(output%Ri_grad%data(:, 1:num), zcoord, output%time%data(1:num), &
trim(path) // trim(meta_ri_grad%name) // '.plt', meta_ri_grad)
call write_2d_real_plt(output_Km%data(:,1:output_Km%num), zcoord, tcoord(1:output_Km%num), &
call write_2d_real_plt(output%Km%data(:, 1:num), zcoord, output%time%data(1:num), &
trim(path) // trim(meta_km%name) // '.plt', meta_km)
call write_2d_real_plt(output_Kh%data(:,1:output_Kh%num), zcoord, tcoord(1:output_Kh%num), &
call write_2d_real_plt(output%Kh%data(:, 1:num), zcoord, output%time%data(1:num), &
trim(path) // trim(meta_kh%name) // '.plt', meta_kh)
call write_2d_real_plt(output_TinC%data(:,1:output_TinC%num), zcoord, tcoord(1:output_TinC%num), &
call write_2d_real_plt(output%TinC%data(:, 1:num), zcoord, output%time%data(1:num), &
trim(path) // trim(meta_theta_C%name) // '.plt', meta_theta_C)
!> time series output
call write_1d_real_plt(output_mld%data(1:output_mld%num), tcoord(1:output_mld%num), &
call write_1d_real_plt(output%mld%data(1:num), output%time%data(1:num), &
trim(path) // trim(meta_mld%name) // '.plt', meta_mld)
call write_1d_real_plt(output_mld_ref%data(1:output_mld_ref%num), tcoord(1:output_mld_ref%num), &
call write_1d_real_plt(output%mld_ref%data(1:num), output%time%data(1:num), &
trim(path) // trim(meta_lab_mld%name) // '.plt', meta_lab_mld)
call write_1d_real_plt(output_tau_x%data(1:output_tau_x%num), tcoord(1:output_tau_x%num), &
call write_1d_real_plt(output%tau_x%data(1:num), output%time%data(1:num), &
trim(path) // trim(meta_tau_u%name) // '.plt', meta_tau_u)
call write_1d_real_plt(output_tau_y%data(1:output_tau_y%num), tcoord(1:output_tau_y%num), &
call write_1d_real_plt(output%tau_y%data(1:num), output%time%data(1:num), &
trim(path) // trim(meta_tau_v%name) // '.plt', meta_tau_v)
call write_1d_real_plt(output_Theta_surf%data(1:output_Theta_surf%num), tcoord(1:output_Theta_surf%num), &
call write_1d_real_plt(output%Theta_surf%data(1:num), output%time%data(1:num), &
trim(path) // trim(meta_theta_surf%name) // '.plt', meta_theta_surf)
end subroutine write_tecplot
! --------------------------------------------------------------------------------
subroutine output_cleanup
subroutine output_cleanup(output)
!> @brief cleanup output data
! ----------------------------------------------------------------------------
type (oblOutputStx), intent(out) :: output
! ----------------------------------------------------------------------------
!> time slice deallocate
call deallocate_tslice(output_Theta)
call deallocate_tslice(output_Salin)
call deallocate_tslice(output%Theta)
call deallocate_tslice(output%Salin)
call deallocate_tslice(output_Rho)
call deallocate_tslice(output%Rho)
call deallocate_tslice(output_U)
call deallocate_tslice(output_V)
call deallocate_tslice(output%U)
call deallocate_tslice(output%V)
call deallocate_tslice(output_N2)
call deallocate_tslice(output_S2)
call deallocate_tslice(output_Ri_grad)
call deallocate_tslice(output%N2)
call deallocate_tslice(output%S2)
call deallocate_tslice(output%Ri_grad)
call deallocate_tslice(output_Km)
call deallocate_tslice(output_Kh)
call deallocate_tslice(output%Km)
call deallocate_tslice(output%Kh)
call deallocate_tslice(output_TinC)
call deallocate_tslice(output%TinC)
!> time series deallocate
call deallocate_tseries(output_time)
call deallocate_tseries(output%time)
call deallocate_tseries(output_mld)
call deallocate_tseries(output_mld_ref)
call deallocate_tseries(output%mld)
call deallocate_tseries(output%mld_ref)
call deallocate_tseries(output_tau_x)
call deallocate_tseries(output_tau_y)
call deallocate_tseries(output%tau_x)
call deallocate_tseries(output%tau_y)
call deallocate_tseries(output_Theta_surf)
call deallocate_tseries(output%Theta_surf)
end subroutine output_cleanup
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment