From ca9b39a9dbdddf07a8088d1c1fc68a52b35de743 Mon Sep 17 00:00:00 2001 From: ackerlar Date: Fri, 27 Sep 2024 18:38:41 +0200 Subject: [PATCH] enable icebergs with cavities --- src/gen_modules_config.F90 | 6 +- src/icb_allocate.F90 | 4 +- src/icb_coupling.F90 | 55 ++++-- src/icb_coupling.F90.rej | 22 --- src/icb_dyn.F90 | 304 ++++++++++++++++++++++++++++++-- src/icb_elem.F90 | 43 +++-- src/icb_elem.F90.rej | 59 ------- src/icb_modules.F90 | 5 +- src/icb_modules.F90.rej | 72 -------- src/icb_step.F90 | 99 ++++++----- src/icb_step.F90.rej | 121 ------------- src/icb_thermo.F90 | 124 +++++++++----- src/icb_thermo.F90.rej | 324 ----------------------------------- src/ice_oce_coupling.F90 | 25 +-- src/ice_oce_coupling.F90.rej | 23 --- src/io_meandata.F90.rej | 11 -- src/oce_ale_tracer.F90.rej | 9 - 17 files changed, 522 insertions(+), 784 deletions(-) delete mode 100644 src/icb_coupling.F90.rej delete mode 100644 src/icb_elem.F90.rej delete mode 100644 src/icb_modules.F90.rej delete mode 100644 src/icb_step.F90.rej delete mode 100644 src/icb_thermo.F90.rej delete mode 100644 src/ice_oce_coupling.F90.rej delete mode 100644 src/io_meandata.F90.rej delete mode 100644 src/oce_ale_tracer.F90.rej diff --git a/src/gen_modules_config.F90 b/src/gen_modules_config.F90 index f4766764e..8916e845e 100755 --- a/src/gen_modules_config.F90 +++ b/src/gen_modules_config.F90 @@ -123,8 +123,9 @@ module g_config logical :: turn_off_fw=.false. logical :: use_icesheet_coupling=.false. logical :: lbalance_fw=.true. - logical :: lcell_saturation=.true. + integer :: cell_saturation=2 ! 0=no cell saturation, 1=one additional iceberg allowed, 2=no daddtional iceberg allowed logical :: lmin_latent_hf=.true. + logical :: lverbose_icb=.false. integer :: ib_num=0 integer :: steps_per_ib_step=8 @@ -135,7 +136,8 @@ module g_config integer :: ib_async_mode=0 integer :: thread_support_level_required=3 ! 2 = MPI_THREAD_SERIALIZED, 3 = MPI_THREAD_MULTIPLE - namelist /icebergs/ use_icebergs, turn_off_hf, turn_off_fw, use_icesheet_coupling, lbalance_fw, lcell_saturation, lmin_latent_hf, ib_num, steps_per_ib_step, ib_async_mode, thread_support_level_required + namelist /icebergs/ use_icebergs, turn_off_hf, turn_off_fw, use_icesheet_coupling, lbalance_fw, cell_saturation, lmin_latent_hf, & + ib_num, steps_per_ib_step, ib_async_mode, thread_support_level_required, lverbose_icb !wiso-code!!! logical :: lwiso =.false. ! enable isotope? diff --git a/src/icb_allocate.F90 b/src/icb_allocate.F90 index 8d235a415..202214397 100644 --- a/src/icb_allocate.F90 +++ b/src/icb_allocate.F90 @@ -94,9 +94,9 @@ subroutine allocate_icb(partit, mesh) allocate(fwb_flux_ib(ib_num)) allocate(fwbv_flux_ib(ib_num)) allocate(hfe_flux_ib(ib_num)) - allocate(hfl_flux_ib(ib_num)) + allocate(hfl_flux_ib(ib_num,mesh%nl)) allocate(hfb_flux_ib(ib_num)) - allocate(hfbv_flux_ib(ib_num)) + allocate(hfbv_flux_ib(ib_num,mesh%nl)) allocate(lhfb_flux_ib(ib_num)) fwe_flux_ib = 0.0 fwl_flux_ib = 0.0 diff --git a/src/icb_coupling.F90 b/src/icb_coupling.F90 index 56004644a..51671c8d1 100644 --- a/src/icb_coupling.F90 +++ b/src/icb_coupling.F90 @@ -14,7 +14,7 @@ subroutine reset_ib_fluxes() end subroutine -subroutine prepare_icb2fesom(mesh, partit, ib,i_have_element,localelement,depth_ib) +subroutine prepare_icb2fesom(mesh, partit, ib,i_have_element,localelement,depth_ib,height_ib_single) !transmits the relevant fields from the iceberg to the ocean model !Lars Ackermann, 17.03.2020 @@ -27,7 +27,7 @@ subroutine prepare_icb2fesom(mesh, partit, ib,i_have_element,localelement,depth_ implicit none logical :: i_have_element - real, intent(in) :: depth_ib + real, intent(in) :: depth_ib, height_ib_single real :: lev_low, lev_up integer :: localelement integer :: iceberg_node @@ -44,7 +44,7 @@ subroutine prepare_icb2fesom(mesh, partit, ib,i_have_element,localelement,depth_ #include "associate_part_ass.h" #include "associate_mesh_ass.h" - if(i_have_element) then + if(i_have_element) then dz = 0.0 allocate(tot_area_nods_in_ib_elem(mesh%nl)) @@ -89,6 +89,7 @@ subroutine prepare_icb2fesom(mesh, partit, ib,i_have_element,localelement,depth_ do i=1, 3 iceberg_node=ib_nods_in_ib_elem(i) + if (use_cavity .and. ulevels_nod2d(iceberg_node) > 1) cycle if (iceberg_node>0) then ibfwbv(iceberg_node) = ibfwbv(iceberg_node) - fwbv_flux_ib(ib) / tot_area_nods_in_ib_elem(1) @@ -105,23 +106,34 @@ subroutine prepare_icb2fesom(mesh, partit, ib,i_have_element,localelement,depth_ lev_low = mesh%zbar_3d_n(j+1, iceberg_node) end if dz = abs( lev_low - lev_up ) - if( (abs(lev_low)>=abs(depth_ib)) .and. (abs(lev_up)=abs(depth_ib)) .and. (abs(lev_up) 1 ) then + ibhf_n(idx_d(i),iceberg_node) = ibhf_n(idx_d(i),iceberg_node) - 0.5 * hfb_flux_ib(ib) / tot_area_nods_in_ib_elem(idx_d(i)) + ibhf_n(idx_d(i)-1,iceberg_node) = ibhf_n(idx_d(i)-1,iceberg_node) - 0.5 * hfb_flux_ib(ib) / tot_area_nods_in_ib_elem(idx_d(i)-1) + else + ibhf_n(idx_d(i),iceberg_node) = ibhf_n(idx_d(i),iceberg_node) - hfb_flux_ib(ib) / tot_area_nods_in_ib_elem(idx_d(i)) + end if + + if( height_ib_single .ne. 0.0 ) then + ibhf_n(1,iceberg_node) = ibhf_n(1,iceberg_node) - hfe_flux_ib(ib) & + * ((abs(height_ib_single)-abs(depth_ib))/abs(height_ib_single)) & + / tot_area_nods_in_ib_elem(1) + end if end if end do end if @@ -150,11 +162,24 @@ subroutine icb2fesom(mesh, partit, ice) #include "associate_part_ass.h" #include "associate_mesh_ass.h" + if (use_cavity) then +!$OMP PARALLEL DO + do n=1, myDim_nod2d+eDim_nod2D + if (ulevels_nod2d(n) > 1) cycle + if (.not.turn_off_fw) then + water_flux(n) = water_flux(n) - (ibfwb(n)+ibfwl(n)+ibfwe(n)+ibfwbv(n)) !* steps_per_ib_step + end if + end do +!$OMP END PARALLEL DO + else +!$OMP PARALLEL DO do n=1, myDim_nod2d+eDim_nod2D if (.not.turn_off_fw) then water_flux(n) = water_flux(n) - (ibfwb(n)+ibfwl(n)+ibfwe(n)+ibfwbv(n)) !* steps_per_ib_step end if end do +!$OMP END PARALLEL DO + end if !---wiso-code-begin if(lwiso) then do n=1, myDim_nod2D+eDim_nod2D diff --git a/src/icb_coupling.F90.rej b/src/icb_coupling.F90.rej deleted file mode 100644 index fd3215347..000000000 --- a/src/icb_coupling.F90.rej +++ /dev/null @@ -1,22 +0,0 @@ -diff a/src/icb_coupling.F90 b/src/icb_coupling.F90 (rejected hunks) -@@ -90,16 +149,13 @@ type(t_partit), intent(inout), target :: partit - #include "associate_mesh_def.h" - #include "associate_part_ass.h" - #include "associate_mesh_ass.h" -- -- fresh_wa_flux => ice%flx_fw(:) -- net_heat_flux => ice%flx_h(:) - - do n=1, myDim_nod2d+eDim_nod2D -- if (.not.turn_off_hf) then -- net_heat_flux(n) = net_heat_flux(n) + ibhf(n) -- end if -+ !if (.not.turn_off_hf) then -+ ! heat_flux(n) = heat_flux(n) - ibhf(n) !* steps_per_ib_step -+ !end if - if (.not.turn_off_fw) then -- fresh_wa_flux(n) = fresh_wa_flux(n) + (ibfwb(n)+ibfwl(n)+ibfwe(n)+ibfwbv(n)) -+ water_flux(n) = water_flux(n) - (ibfwb(n)+ibfwl(n)+ibfwe(n)+ibfwbv(n)) !* steps_per_ib_step - end if - end do - !---wiso-code-begin diff --git a/src/icb_dyn.F90 b/src/icb_dyn.F90 index bc5f785e2..5184e2a2b 100644 --- a/src/icb_dyn.F90 +++ b/src/icb_dyn.F90 @@ -25,7 +25,7 @@ module iceberg_dynamics ! Thomas Rackow, 29.06.2010 !============================================================================== subroutine iceberg_dyn(mesh, partit, ice, dynamics, ib, new_u_ib, new_v_ib, u_ib, v_ib, lon,lat, depth_ib, & - height_ib, length_ib, width_ib, iceberg_elem, & + height_ib, length_ib, width_ib, iceberg_elem, & mass_ib, Ci, Ca, Co, Cda_skin, Cdo_skin, & rho_ice, rho_air, rho_h2o, P_sill, conc_sill, frozen_in, & file1, file2, P_ib, conci_ib, dt_ib, lastsubstep, & @@ -35,8 +35,8 @@ subroutine iceberg_dyn(mesh, partit, ice, dynamics, ib, new_u_ib, new_v_ib, u_ib use g_forcing_arrays !for u_wind, v_wind or u_wind_ib, v_wind_ib respectively use o_arrays, only: Tsurf_ib, Ssurf_ib use o_param !for dt - !use iceberg_params,only: l_melt, coriolis_scale !are icebergs allowed to melt? + integer :: ib_n_lvls, m integer, intent(IN) :: ib !current iceberg's index real, intent(OUT) :: new_u_ib, new_v_ib real, intent(IN) :: u_ib, v_ib @@ -61,21 +61,21 @@ subroutine iceberg_dyn(mesh, partit, ice, dynamics, ib, new_u_ib, new_v_ib, u_ib !LA 2023-03-07 real, dimension(:), pointer :: hi_ib3, conci_ib3, coriolis - real, dimension(3) :: uo_dz, vo_dz, uo_keel, vo_keel, T_dz,S_dz, T_keel,S_keel !hi_ib3, conci_ib3, + real, dimension(3) :: uo_keel, vo_keel, T_keel,S_keel, uo_dz, vo_dz, T_dz,S_dz!hi_ib3, conci_ib3, + real, dimension(:,:), allocatable :: arr_uo_dz, arr_vo_dz, arr_T_dz,arr_S_dz !hi_ib3, conci_ib3, real :: uo_ib, vo_ib, ua_ib, va_ib, ui_ib, vi_ib, hi_ib, uo_skin_ib, vo_skin_ib + real, dimension(:), allocatable :: arr_uo_ib, arr_vo_ib, arr_T_ave_ib, arr_S_ave_ib real :: Ao, Aa, Ai, Ad, fcoriolis real :: au_ib, av_ib real, dimension(2,2) :: SI_matrix real, dimension(2) :: SI_velo real :: u_ib_tmp, v_ib_tmp, normold, normnew, abs_omib, abs_omib_skin, ocean_drag - integer :: iter_ib + integer :: iter_ib, n, n2 real :: M_b, M_v, M_e, M_bv, sst_ib, sss_ib ! meltrates (basal, lateral, erosion, lateral 'basal'), temp. & salinity real :: T_ave_ib, S_ave_ib, T_keel_ib, S_keel_ib character, intent(IN) :: file3*80 real, intent(IN) :: rho_icb -! integer, dimension(3) :: tmp_arr - type(t_ice) , intent(inout), target :: ice type(t_mesh), intent(in) , target :: mesh type(t_partit), intent(inout), target :: partit @@ -85,19 +85,44 @@ subroutine iceberg_dyn(mesh, partit, ice, dynamics, ib, new_u_ib, new_v_ib, u_ib #include "associate_part_ass.h" #include "associate_mesh_ass.h" +n2=elem2D_nodes(1,iceberg_elem) +allocate(arr_uo_dz(3,nlevels_nod2D(n2))) +allocate(arr_vo_dz(3,nlevels_nod2D(n2))) +allocate(arr_T_dz(3,nlevels_nod2D(n2))) +allocate(arr_S_dz(3,nlevels_nod2D(n2))) +arr_uo_dz = 0.0 +arr_vo_dz = 0.0 +arr_T_dz = 0.0 +arr_S_dz = 0.0 + +allocate(arr_uo_ib(nlevels_nod2D(n2))) +allocate(arr_vo_ib(nlevels_nod2D(n2))) +allocate(arr_T_ave_ib(nlevels_nod2D(n2))) +allocate(arr_S_ave_ib(nlevels_nod2D(n2))) +arr_uo_ib = 0.0 +arr_vo_ib = 0.0 +arr_T_ave_ib = 0.0 +arr_S_ave_ib = 0.0 + !OCEAN VELOCITIES: ! - (uo_ib, vo_ib) : integrated mean velocity at location of iceberg ! - (uo_skin_ib, vo_skin_ib) : velocity below the draft of the iceberg ! call iceberg_avvelo_ufkeel(uo_dz,vo_dz, uo_keel,vo_keel, depth_ib,iceberg_elem) call iceberg_average_andkeel(mesh, partit, dynamics, uo_dz,vo_dz, uo_keel,vo_keel, T_dz,S_dz, T_keel,S_keel, depth_ib,iceberg_elem, ib) + + !OCEANIC VELOCITY uo_ib, vo_ib call FEM_3eval(mesh, partit, uo_ib,vo_ib,lon,lat,uo_dz,vo_dz,iceberg_elem) + + call iceberg_levelwise_andkeel(mesh, partit, dynamics, arr_uo_dz,arr_vo_dz, uo_keel,vo_keel, arr_T_dz,arr_S_dz, T_keel,S_keel, depth_ib,iceberg_elem, ib, ib_n_lvls) + do n=1, ib_n_lvls + call FEM_3eval(mesh, partit, arr_uo_ib(n),arr_vo_ib(n),lon,lat,arr_uo_dz(:,n),arr_vo_dz(:,n),iceberg_elem) + call FEM_3eval(mesh, partit, arr_T_ave_ib(n),arr_S_ave_ib(n),lon,lat,arr_T_dz(:,n),arr_S_dz(:,n),iceberg_elem) + end do call FEM_3eval(mesh, partit, uo_skin_ib,vo_skin_ib,lon,lat,uo_keel,vo_keel,iceberg_elem) - !TEMPERATURE AND SALINITY: ! - T_ave_ib, S_ave_ib : Mean T & S (integrated) at location of iceberg ! - T_keel_ib, S_keel_ib : T & S below the draft of the iceberg (depth_ib) - call FEM_3eval(mesh, partit, T_ave_ib,S_ave_ib,lon,lat,T_dz,S_dz,iceberg_elem) call FEM_3eval(mesh, partit, T_keel_ib,S_keel_ib,lon,lat,T_keel,S_keel,iceberg_elem) @@ -133,14 +158,13 @@ subroutine iceberg_dyn(mesh, partit, ice, dynamics, ib, new_u_ib, new_v_ib, u_ib !========================THERMODYNAMICS============================ if(l_melt) then - call FEM_eval(mesh, partit, sst_ib,sss_ib,lon,lat,Tsurf_ib,Ssurf_ib,iceberg_elem) - - call iceberg_meltrates(partit, M_b, M_v, M_e, M_bv, & - u_ib,v_ib, uo_ib,vo_ib, ua_ib,va_ib, & + + call iceberg_meltrates(partit, mesh, M_b, M_v, M_e, M_bv, & + u_ib,v_ib, arr_uo_ib,arr_vo_ib, ua_ib,va_ib, & sst_ib, length_ib, conci_ib, & uo_skin_ib, vo_skin_ib, T_keel_ib, S_keel_ib, depth_ib, height_ib, & - T_ave_ib, S_ave_ib, ib, rho_icb) + arr_T_ave_ib, arr_S_ave_ib, ib, rho_icb, uo_ib, vo_ib, ib_n_lvls, iceberg_elem, nlevels_nod2D(n2)) call iceberg_newdimensions(partit, ib, depth_ib,height_ib,length_ib,width_ib,M_b,M_v,M_e,M_bv, & rho_h2o, rho_icb, file3) @@ -580,6 +604,260 @@ subroutine compute_areas(Ao, Aa, Ai, Ad, depth_ib, & end subroutine compute_areas +!*************************************************************************************************************************** +!*************************************************************************************************************************** + + +subroutine iceberg_levelwise_andkeel(mesh, partit, dynamics, uo_dz,vo_dz, uo_keel,vo_keel, T_dz,S_dz, T_keel,S_keel, depth_ib,iceberg_elem, ib, ib_n_lvls) + USE MOD_MESH + use o_param + use MOD_PARTIT + use MOD_DYN + + use o_arrays, only: Tclim_ib, Sclim_ib !, UV_ib, Z_3d_n_ib + + use g_clock + use g_forcing_arrays + use g_rotate_grid + + implicit none + + REAL, DIMENSION(:,:), allocatable, INTENT(OUT) :: uo_dz + REAL, DIMENSION(:,:), allocatable, INTENT(OUT) :: vo_dz + REAL, DIMENSION(3), INTENT(OUT) :: uo_keel + REAL, DIMENSION(3), INTENT(OUT) :: vo_keel + REAL, DIMENSION(:,:), allocatable, INTENT(OUT) :: T_dz + REAL, DIMENSION(:,:), allocatable, INTENT(OUT) :: S_dz + REAL, DIMENSION(3), INTENT(OUT) :: T_keel + REAL, DIMENSION(3), INTENT(OUT) :: S_keel + REAl, INTENT(IN) :: depth_ib + INTEGER :: ib_n_lvls_old + INTEGER, INTENT(IN) :: iceberg_elem, ib + INTEGER, INTENT(OUT) :: ib_n_lvls + INTEGER, dimension(3) :: arr_ib_n_lvls + REAL, dimension(:,:,:), pointer :: UV_ib + + real :: lev_up, lev_low + integer :: m, k, n2, n_up, n_low, cavity_count, max_node_level_count + ! depth over which is integrated (layer and sum) + real :: dz, ufkeel1, ufkeel2, Temkeel, Salkeel, ldepth_up, ldepth_low, dz_depth + +type(t_mesh), intent(in) , target :: mesh +type(t_dyn), intent(in) , target :: dynamics +type(t_partit), intent(inout), target :: partit +#include "associate_part_def.h" +#include "associate_mesh_def.h" +#include "associate_part_ass.h" +#include "associate_mesh_ass.h" + + UV_IB => dynamics%uv_ib(:,:,:) + cavity_count=0 + + do m=1,3 + if(m==1) then + max_node_level_count = nlevels_nod2D(elem2D_nodes(m,iceberg_elem)) + else + max_node_level_count = max(max_node_level_count, nlevels_nod2D(elem2D_nodes(m,iceberg_elem))) + end if + end do + + allocate(uo_dz(3,max_node_level_count)) + allocate(vo_dz(3,max_node_level_count)) + allocate(T_dz(3,max_node_level_count)) + allocate(S_dz(3,max_node_level_count)) + + ib_n_lvls_old = 0 + ib_n_lvls = 0 + arr_ib_n_lvls = 0 + + uo_dz = 0.0 + vo_dz = 0.0 + uo_keel = 0.0 + vo_keel = 0.0 + T_dz = 0.0 + S_dz = 0.0 + T_keel = 0.0 + S_keel = 0.0 + + !LOOP: over all nodes of the iceberg element + nodeloop: do m=1, 3 + !for each 2D node of the iceberg element.. + n2=elem2D_nodes(m,iceberg_elem) + + ! LOOP: consider all neighboring pairs (n_up,n_low) of 3D nodes + ! below n2.. + !innerloop: do k=1, nl+1 + innerloop: do k=1, nlevels_nod2D(n2) + lev_up = mesh%zbar_3d_n(k, n2) + !lev_up = mesh%Z_3d_n(k, n2) + ldepth_up = mesh%Z_3d_n(k, n2) + + if( k==nlevels_nod2D(n2) ) then + lev_low = mesh%zbar_n_bot(n2) + ldepth_low = mesh%zbar_n_bot(n2) + else + lev_low = mesh%zbar_3d_n(k+1, n2) + ldepth_low = mesh%Z_3d_n(k+1, n2) + !lev_low = mesh%Z_3d_n(k+1, n2) + end if + + + !if( k==1 ) then + ! lev_up = 0.0 + !else + ! lev_up = mesh%Z_3d_n_ib(k-1, n2) + ! !lev_up = mesh%Z_3d_n_ib(k-1, n2) + !end if + + !if( k==nlevels_nod2D(n2) ) then + ! lev_low = mesh%zbar_n_bot(n2) + !else + ! lev_low = mesh%Z_3d_n_ib(k, n2) + !end if + dz = abs( lev_low - lev_up ) + dz_depth = abs( ldepth_low - ldepth_up ) + + !if( abs(lev_up)>=abs(depth_ib) ) then + ! ! ...icb bottom above lev_up --> no further integration + !end if + + !if( (abs(coord_nod3D(3, n_low))>abs(depth_ib)) .AND. (abs(coord_nod3D(3, n_up))>abs(depth_ib)) ) then + ! write(*,*) 'INFO, k:',k,'z_up:',coord_nod3D(3, n_up),'z_lo:',coord_nod3D(3, n_low),'depth:',depth_ib,'cavity:',(cavity_flag_nod2d(elem2D_nodes(m,iceberg_elem))==1) + !end if + + ! if cavity node .. +if (use_cavity .AND. mesh%cavity_depth(elem2D_nodes(m,iceberg_elem)) /= 0.0 .AND. abs(depth_ib) < abs(lev_up)) then + ! LA: Never go here for k=1, because abs(depth_ib)>=0.0 for all icebergs + + uo_dz(m,k)=UV_ib(1,k-1,n2)*abs(depth_ib) + vo_dz(m,k)=UV_ib(2,k-1,n2)*abs(depth_ib) + uo_keel(m)=UV_ib(1,k-1,n2) + vo_keel(m)=UV_ib(2,k-1,n2) + + T_dz(m,k)=Tclim_ib(k-1,n2)*abs(depth_ib) + S_dz(m,k)=Sclim_ib(k-1,n2)*abs(depth_ib) + T_keel(m)=Tclim_ib(k-1,n2) + S_keel(m)=Sclim_ib(k-1,n2) ! check those choices with RT: OK + + exit innerloop + + ! if the lowest z coord is below the iceberg draft, exit + !else if( abs(coord_nod3D(3, n_low))>=abs(depth_ib) .AND. abs(coord_nod3D(3, n_up))<=abs(depth_ib) ) then + + !**************************************************************** + ! LA 23.11.21 case if depth_ib=abs(depth_ib) ) then !.AND. (abs(lev_up)<=abs(depth_ib)) ) then + if( abs(lev_up)= 0.0- 1.0e-07) ) then old_iceberg_elem=elem_containing_n2 - - if( (use_cavity) .and. (reject_elem(mesh, partit, old_iceberg_elem) )) then - left_mype=1.0 - !write(*,*) 'iceberg found in shelf region: left_mype = 1' - old_iceberg_elem=ibelem_tmp - end if + if (use_cavity) then + !if( reject_elem(mesh, partit, old_iceberg_elem) ) then + reject_tmp = all( (mesh%cavity_depth(elem2D_nodes(:,ibelem_tmp))/=0.0) .OR. (mesh%bc_index_nod2D(elem2D_nodes(:,ibelem_tmp))==0.0) ) + if(reject_tmp) then + left_mype=1.0 + !write(*,*) 'iceberg found in shelf region: left_mype = 1' + old_iceberg_elem=ibelem_tmp + end if + endif RETURN end if end do @@ -576,7 +587,7 @@ SUBROUTINE locbafu_2D(mesh, partit, values, elem, coords) DO i=1, 2 TRANS(:,i) = local_cart_coords(:,i+1)-local_cart_coords(:,1) END DO - call matrix_inverse_2x2(TRANS, TRANS_inv, DET) + call matrix_inverse_2x2(TRANS, TRANS_inv, DET, elem, coords) vec=x_cart-local_cart_coords(:,1) stdel_coords = MATMUL(TRANS_inv, vec) @@ -835,13 +846,16 @@ end subroutine com_integer !END SUBROUTINE tides_distr !LA from oce_mesh_setup ofr iceberg coupling -subroutine matrix_inverse_2x2 (A, AINV, DET) +subroutine matrix_inverse_2x2 (A, AINV, DET, elem, coords) ! ! Coded by Sergey Danilov ! Reviewed by Qiang Wang !------------------------------------------------------------- implicit none + + integer :: elem + REAL, DIMENSION(2), INTENT(IN) :: coords real(kind=8), dimension(2,2), intent(IN) :: A real(kind=8), dimension(2,2), intent(OUT) :: AINV @@ -853,6 +867,7 @@ subroutine matrix_inverse_2x2 (A, AINV, DET) do j=1,2 write(*,*) (A(i,j),i=1,2) end do + write(*,*) " * elem: ", elem, ", coords: ", coords stop 'SINGULAR 2X2 MATRIX' else AINV(1,1) = A(2,2)/DET diff --git a/src/icb_elem.F90.rej b/src/icb_elem.F90.rej deleted file mode 100644 index a34f6a9f6..000000000 --- a/src/icb_elem.F90.rej +++ /dev/null @@ -1,59 +0,0 @@ -diff a/src/icb_elem.F90 b/src/icb_elem.F90 (rejected hunks) -@@ -376,9 +376,6 @@ end subroutine FEM_3eval - subroutine iceberg_elem4all(mesh, partit, elem, lon_deg, lat_deg) - USE MOD_MESH - use MOD_PARTIT !for myDim_nod2D, myList_elem2D --!#ifdef use_cavity --! use iceberg_params, only: reject_elem --!#endif - - implicit none - -@@ -398,30 +395,21 @@ type(t_partit), intent(inout), target :: partit - - if(i_have_element) then - i_have_element= elem2D_nodes(1,elem) <= myDim_nod2D !1 PE still .true. --#ifdef use_cavity -- if( reject_elem(mesh, elem) ) then -+ if( (use_cavity) .and. (reject_elem(mesh, partit, elem) )) then - elem=0 !reject element - i_have_element=.false. -- !write(*,*) 'elem4all: iceberg found in shelf region: elem = 0' - else - elem=myList_elem2D(elem) !global now - end if --#else -- elem=myList_elem2D(elem) !global now --#endif - end if - call com_integer(partit, i_have_element,elem) !max 1 PE sends element here; - end subroutine iceberg_elem4all - - - !*************************************************************************************************************************** -- !*************************************************************************************************************************** - - subroutine find_new_iceberg_elem(mesh, partit, old_iceberg_elem, pt, left_mype) - use o_param --!#ifdef use_cavity --! use iceberg_params, only: reject_elem --!#endif - - implicit none - -@@ -461,14 +449,11 @@ do m=1, 3 - if (ALL(werte2D <= 1.+ 1.0e-07) .AND. ALL(werte2D >= 0.0- 1.0e-07) ) then - old_iceberg_elem=elem_containing_n2 - --#ifdef use_cavity -- if( reject_elem(mesh, old_iceberg_elem) ) then -+ if( (use_cavity) .and. (reject_elem(mesh, partit, old_iceberg_elem) )) then - left_mype=1.0 - !write(*,*) 'iceberg found in shelf region: left_mype = 1' - old_iceberg_elem=ibelem_tmp - end if --#endif -- - RETURN - end if - end do diff --git a/src/icb_modules.F90 b/src/icb_modules.F90 index 2b7aa088c..1162182db 100644 --- a/src/icb_modules.F90 +++ b/src/icb_modules.F90 @@ -95,7 +95,8 @@ module iceberg_params real,dimension(:), allocatable:: bvl_mean, lvlv_mean, lvle_mean, lvlb_mean !averaged volume losses !real,dimension(:), allocatable:: fw_flux_ib, hfb_flux_ib real,dimension(:), allocatable:: fwe_flux_ib, fwl_flux_ib, fwb_flux_ib, fwbv_flux_ib - real,dimension(:), allocatable:: hfe_flux_ib, hfl_flux_ib, hfb_flux_ib, hfbv_flux_ib, lhfb_flux_ib + real,dimension(:), allocatable:: hfe_flux_ib, hfb_flux_ib, lhfb_flux_ib + real,dimension(:,:), allocatable:: hfl_flux_ib, hfbv_flux_ib !===== FRESHWATER AND HEAT ARRAYS ON FESOM GRID ===== real,dimension(:), allocatable:: ibhf !icb heat flux into ocean @@ -129,7 +130,7 @@ logical function reject_elem(mesh, partit, elem) implicit none integer, intent(in) :: elem type(t_mesh), intent(in) , target :: mesh -type(t_partit), intent(inout), target :: partit +type(t_partit), intent(in), target :: partit #include "associate_mesh_def.h" #include "associate_part_def.h" #include "associate_mesh_ass.h" diff --git a/src/icb_modules.F90.rej b/src/icb_modules.F90.rej deleted file mode 100644 index 469d257ab..000000000 --- a/src/icb_modules.F90.rej +++ /dev/null @@ -1,72 +0,0 @@ -diff a/src/icb_modules.F90 b/src/icb_modules.F90 (rejected hunks) -@@ -1,4 +1,10 @@ - module iceberg_params -+use MOD_PARTIT -+USE MOD_MESH -+use g_config, only: use_cavity, use_cavityonelem -+use, intrinsic :: iso_fortran_env, only: real64 -+USE o_PARAM, only: WP -+ - implicit none - save - !integer,parameter :: ib_num ! realistic dataset comprising 6912 icebergs -@@ -111,35 +121,50 @@ save - integer:: save_count_buoys - real:: prev_sec_in_year - !**************************************************************************************************************************** --!**************************************************************************************************************************** --#ifdef use_cavity - contains - ! true if all nodes of the element are either "real" model boundary nodes or shelf nodes -- logical function reject_elem(mesh, elem) -- USE MOD_MESH -+ logical function reject_elem(mesh, partit, elem) - implicit none - integer, intent(in) :: elem - type(t_mesh), intent(in) , target :: mesh -+type(t_partit), intent(inout), target :: partit -+#include "associate_part_def.h" - #include "associate_mesh_def.h" -+#include "associate_part_ass.h" - #include "associate_mesh_ass.h" - -+if (use_cavity) then - ! kh 09.08.21 change index_nod2d -> bc_index_nod2d? -- reject_elem = all( (cavity_flag_nod2d(elem2D_nodes(:,elem))==1) .OR. (index_nod2d(elem2D_nodes(:,elem))==1) ) -+ if (.not. use_cavityonelem) then -+ reject_elem = all( (mesh%cavity_depth(mesh%elem2D_nodes(:,elem))/=0.0) .OR. (mesh%bc_index_nod2D(mesh%elem2D_nodes(:,elem))==0.0) ) -+ !else -+ end if -+else -+ reject_elem = all( (mesh%bc_index_nod2D(mesh%elem2D_nodes(:,elem))==0.0) ) -+endif - end function reject_elem - - ! gives number of "coastal" nodes in cavity setup, i.e. number of nodes that are - ! either "real" model boundary nodes or shelf nodes -- integer function coastal_nodes(mesh, elem) -- USE MOD_MESH -+ integer function coastal_nodes(mesh, partit, elem) - implicit none - integer, intent(in) :: elem - type(t_mesh), intent(in) , target :: mesh -+type(t_partit), intent(inout), target :: partit - #include "associate_part_def.h" -+#include "associate_mesh_def.h" - #include "associate_part_ass.h" -+#include "associate_mesh_ass.h" - -+if (use_cavity) then - ! kh 09.08.21 change index_nod2d -> bc_index_nod2d? -- coastal_nodes = count( (cavity_flag_nod2d(elem2D_nodes(:,elem))==1) .OR. (index_nod2d(elem2D_nodes(:,elem))==1) ) -+ if (.not. use_cavityonelem) then -+ coastal_nodes = count( (mesh%cavity_depth(mesh%elem2D_nodes(:,elem))/=0.0) .OR. (mesh%bc_index_nod2D(mesh%elem2D_nodes(:,elem))==0.0) ) -+ !else -+ end if -+else -+ coastal_nodes = count( (mesh%bc_index_nod2D(mesh%elem2D_nodes(:,elem))==0.0) ) -+endif - end function coastal_nodes --#endif - - end module iceberg_params diff --git a/src/icb_step.F90 b/src/icb_step.F90 index ad3af496b..3517817ba 100644 --- a/src/icb_step.F90 +++ b/src/icb_step.F90 @@ -298,7 +298,7 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt != implicit none != - + logical :: reject_tmp integer, intent(in) :: ib, istep real, intent(inout) :: height_ib_single,length_ib_single,width_ib_single real, intent(inout) :: lon_deg,lat_deg @@ -361,7 +361,6 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt #include "associate_mesh_ass.h" -!write(*,*) "LA DEBUG: 1" mype =>partit%mype istep_end_synced = istep + steps_per_ib_step - 1 @@ -372,7 +371,6 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt lon_rad = lon_deg*rad lat_rad = lat_deg*rad -!write(*,*) "LA DEBUG: 2" if(volume_ib .le. smallestvol_icb) then melted(ib) = .true. @@ -382,7 +380,6 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt return end if -!write(*,*) "LA DEBUG: 3" if (firstcall) then if(mype==0) write(*,*) 'Preparing local_idx_of array...' @@ -392,7 +389,6 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt firstcall=.false. if(mype==0) write(*,*) 'Preparing local_idx_of done.' end if -!write(*,*) "LA DEBUG: 4" if (find_iceberg_elem) then lon_rad = lon_deg*rad @@ -409,12 +405,23 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt if(i_have_element) then i_have_element= mesh%elem2D_nodes(1,iceberg_elem) <= partit%myDim_nod2D !1 PE still .true. - if( (use_cavity) .and. (reject_elem(mesh, partit, iceberg_elem))) then - iceberg_elem=0 !reject element - i_have_element=.false. - else - iceberg_elem=partit%myList_elem2D(iceberg_elem) !global now - end if + + + + if (use_cavity) then + reject_tmp = all( (mesh%cavity_depth(mesh%elem2D_nodes(:,iceberg_elem))/=0.0) .OR. (mesh%bc_index_nod2D(mesh%elem2D_nodes(:,iceberg_elem))==0.0) ) + if(reject_tmp) then +! write(*,*) " * set IB elem ",iceberg_elem,"to zero for IB=",ib +! write(*,*) " cavity: ",all((mesh%cavity_depth(mesh%elem2D_nodes(:,iceberg_elem))/=0.0)) +! write(*,*) " boundary: ", all(mesh%bc_index_nod2D(mesh%elem2D_nodes(:,iceberg_elem))==1) + iceberg_elem=0 !reject element + i_have_element=.false. + else + iceberg_elem=partit%myList_elem2D(iceberg_elem) !global now + end if + else + iceberg_elem=partit%myList_elem2D(iceberg_elem) !global now + endif end if call com_integer(partit, i_have_element,iceberg_elem) @@ -425,10 +432,11 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt end if ! initialize the iceberg velocity -!write(*,*) "LA DEBUG: 4d" - call initialize_velo(mesh, partit, dynamics, i_have_element, ib, u_ib, v_ib, lon_rad, lat_rad, depth_ib, local_idx_of(iceberg_elem)) -!write(*,*) "LA DEBUG: 4e" - + if(local_idx_of(iceberg_elem) <= partit%myDim_elem2D ) then + call initialize_velo(mesh, partit, dynamics, i_have_element, ib, u_ib, v_ib, lon_rad, lat_rad, depth_ib, local_idx_of(iceberg_elem)) + else + write(*,*) " * skip initialize_velo" + end if !iceberg elem of ib is found find_iceberg_elem = .false. @@ -444,10 +452,8 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt endif endif -!write(*,*) "LA DEBUG: 4f" end if -!write(*,*) "LA DEBUG: 5" ! ================== START ICEBERG CALCULATION ==================== @@ -457,10 +463,8 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt !if the first node belongs to this processor.. (just one processor enters here!) !if( local_idx_of(iceberg_elem) > 0 .and. elem2D_nodes(1,local_idx_of(iceberg_elem)) <= myDim_nod2D ) then if( local_idx_of(iceberg_elem) > 0 ) then -write(*,*) "LA DEBUG: 5a" if( elem2D_nodes(1,local_idx_of(iceberg_elem)) <= partit%myDim_nod2D ) then -write(*,*) "LA DEBUG: 5b" i_have_element=.true. @@ -505,8 +509,7 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt ! kh 16.03.21 (asynchronous) iceberg calculation starts with the content in common arrays at istep and will merge its results at istep_end_synced grounded(ib) = .true. !if (mod(istep_end_synced,logfile_outfreq)==0) then -! if(ib==148) write(*,*) "LA DEBUG: 3 - elem ", iceberg_elem - write(*,*) 'iceberg ib ', ib, 'is grounded' + if (lverbose_icb) write(*,*) 'iceberg ib ', ib, 'is grounded' !end if else @@ -514,7 +517,6 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt t0=MPI_Wtime() -!write(*,*) "LA DEBUG: before_trajectory" call trajectory( lon_rad,lat_rad, u_ib,v_ib, new_u_ib,new_v_ib, & lon_deg,lat_deg,old_lon,old_lat, dt*REAL(steps_per_ib_step)) @@ -550,10 +552,16 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt !----------------------------- ! LA 2022-11-30 -!write(*,*) "LA DEBUG: before_saturation" - if(lcell_saturation) then -!write(*,*) "LA DEBUG: start_saturation" - area_ib_tot = length_ib_single*width_ib_single*scaling(ib) + if(cell_saturation > 0) then + if( lverbose_icb) then + write(*,*) " * checking for cell saturation - ib: ", ib, ", old_elem: ", old_element, ", new_elem: ", iceberg_elem + end if + select case(cell_saturation) !num of coastal points + case(1) + area_ib_tot = 0.0 + case(2) + area_ib_tot = length_ib_single*width_ib_single*scaling(ib) + end select !$OMP PARALLEL DEFAULT(SHARED) PRIVATE(idx, area_ib_tot) !$OMP DO do idx = 1, size(elem_block) @@ -561,15 +569,17 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt area_ib_tot = area_ib_tot + length_ib(idx) * width_ib(idx) * scaling(idx) end if end do -!write(*,*) "LA DEBUG: end_loop_saturation" !$OMP END DO !$OMP END PARALLEL !----------------------------- - if ((area_ib_tot > elem_area_glob(iceberg_elem)) .and. (old_element.ne.0) .and. (left_mype == 0)) then - write(*,*) " *******************************************************" - write(*,*) " * set iceberg ", ib, " back to elem ", old_element, " from elem ", iceberg_elem - write(*,*) " * area_ib_tot = ", area_ib_tot, "; elem_area = ", elem_area(local_idx_of(iceberg_elem)) + if ((area_ib_tot > elem_area_glob(iceberg_elem)) .and. (old_element.ne.0) .and. (iceberg_elem.ne.old_element)) then ! .and. (left_mype == 0)) then + if( lverbose_icb) then + write(*,*) " *******************************************************" + write(*,*) " * set iceberg ", ib, " back to elem ", old_element, " from elem ", iceberg_elem + write(*,*) " * area_ib_tot = ", area_ib_tot, "; elem_area = ", elem_area(local_idx_of(iceberg_elem)) + + end if i_have_element = .true. left_mype = 0.0 lon_rad = old_lon @@ -580,7 +590,6 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt u_ib = 0. v_ib = 0. end if -!write(*,*) "LA DEBUG: after_cell_saturation" end if !########################################### @@ -594,9 +603,7 @@ subroutine iceberg_step1(ice, mesh, partit, dynamics, ib, height_ib_single,lengt pe_block(ib)=mype volume_ib=height_ib_single*length_ib_single*width_ib_single -!write(*,*) "LA DEBUG: before_prepare" - call prepare_icb2fesom(mesh,partit,ib,i_have_element,local_idx_of(iceberg_elem),depth_ib) -!write(*,*) "LA DEBUG: after_prepare" + call prepare_icb2fesom(mesh,partit,ib,i_have_element,local_idx_of(iceberg_elem),depth_ib,height_ib_single) end if !processor has element? end if !... and first node belongs to processor? @@ -770,10 +777,15 @@ subroutine iceberg_step2(mesh, partit,arr, elem_from_block, ib, height_ib_single iceberg_elem = old_element u_ib = 0. v_ib = 0. - else if(lcell_saturation) then + else if(cell_saturation > 0) then if (mype==0) write(*,*) 'iceberg ',ib, ' changed PE or was very fast' elem_area_tmp = elem_area_glob(iceberg_elem) - area_ib_tot = length_ib_single * width_ib_single * scaling(ib) + select case(cell_saturation) !num of coastal points + case(1) + area_ib_tot = 0.0 + case(2) + area_ib_tot = length_ib_single*width_ib_single*scaling(ib) + end select !$OMP PARALLEL DEFAULT(SHARED) PRIVATE(idx, area_ib_tot) !$OMP DO do idx = 1, size(elem_block_red) @@ -784,8 +796,8 @@ subroutine iceberg_step2(mesh, partit,arr, elem_from_block, ib, height_ib_single end do !$OMP END DO !$OMP END PARALLEL - if((area_ib_tot > elem_area_tmp) .and. (elem_area_tmp > 0.0)) then - if(mype==pe_block_red(ib)) then + if((area_ib_tot > elem_area_tmp) .and. (elem_area_tmp > 0.0) .and. (iceberg_elem.ne.old_element)) then + if(mype==pe_block_red(ib) .and. lverbose_icb) then write(*,*) " *******************************************************" write(*,*) " * iceberg changed PE and saturation" write(*,*) " * set iceberg ", ib, " back to elem ", old_element, " from elem ", iceberg_elem @@ -800,7 +812,7 @@ subroutine iceberg_step2(mesh, partit,arr, elem_from_block, ib, height_ib_single u_ib = 0. v_ib = 0. end if - else if(lcell_saturation) then + else if (mype==0) write(*,*) 'iceberg ',ib, ' changed PE or was very fast' end if end if @@ -1035,11 +1047,12 @@ subroutine parallel2coast(mesh, partit,u, v, lon,lat, elem) #include "associate_mesh_def.h" #include "associate_part_ass.h" #include "associate_mesh_ass.h" - + if( use_cavity ) then - fld_tmp = coastal_nodes(mesh, partit, elem) + !fld_tmp = coastal_nodes(mesh, partit, elem) + fld_tmp = count( (mesh%cavity_depth(mesh%elem2D_nodes(:,elem))/=0.0) .OR. (mesh%bc_index_nod2D(mesh%elem2D_nodes(:,elem))==0.0) ) else - fld_tmp = sum( mesh%bc_index_nod2D(mesh%elem2D_nodes(:,elem)) ) + fld_tmp = count( (mesh%bc_index_nod2D(mesh%elem2D_nodes(:,elem))==0.0) ) end if SELECT CASE ( fld_tmp ) !num of coastal points diff --git a/src/icb_step.F90.rej b/src/icb_step.F90.rej deleted file mode 100644 index f9c2a01af..000000000 --- a/src/icb_step.F90.rej +++ /dev/null @@ -1,121 +0,0 @@ -diff a/src/icb_step.F90 b/src/icb_step.F90 (rejected hunks) -@@ -376,22 +407,23 @@ type(t_dyn) , intent(inout), target :: dynamics - call point_in_triangle(mesh, partit, iceberg_elem, coords_tmp) - !call point_in_triangle(mesh, iceberg_elem, (/lon_deg, lat_deg/)) - i_have_element= (iceberg_elem .ne. 0) !up to 3 PEs possible -+!write(*,*) "LA DEBUG: 4a" - - if(i_have_element) then -+!write(*,*) "LA DEBUG: 4a1" - i_have_element= mesh%elem2D_nodes(1,iceberg_elem) <= partit%myDim_nod2D !1 PE still .true. --#ifdef use_cavity -- if(reject_elem(mesh, partit, iceberg_elem)) then -+!write(*,*) "LA DEBUG: 4a2" -+ if( (use_cavity) .and. (reject_elem(mesh, partit, iceberg_elem))) then - iceberg_elem=0 !reject element - i_have_element=.false. - else - iceberg_elem=partit%myList_elem2D(iceberg_elem) !global now - end if --#else -- -- iceberg_elem=partit%myList_elem2D(iceberg_elem) !global now --#endif -+!write(*,*) "LA DEBUG: 4a3" - end if -+!write(*,*) "LA DEBUG: 4b" - call com_integer(partit, i_have_element,iceberg_elem) -+!write(*,*) "LA DEBUG: 4c" - - if(iceberg_elem .EQ. 0) then - write(*,*) 'IB ',ib,' rot. coords:', lon_deg, lat_deg !,lon_rad, lat_rad -@@ -983,15 +1023,14 @@ end subroutine depth_bathy - !**************************************************************************************************************************** - - subroutine parallel2coast(mesh, partit,u, v, lon,lat, elem) --!#ifdef use_cavity --! use iceberg_params, only: coastal_nodes --!#endif -+ use iceberg_params, only: coastal_nodes - implicit none - - real, intent(inout) :: u, v !velocity - real, intent(in) :: lon, lat !radiant - integer, intent(in) :: elem - -+ integer :: fld_tmp - integer, dimension(3) :: n - integer :: node, m, i - real, dimension(2) :: velocity, velocity1, velocity2 -@@ -1004,12 +1043,13 @@ type(t_partit), intent(inout), target :: partit - #include "associate_part_ass.h" - #include "associate_mesh_ass.h" - --#ifdef use_cavity -- SELECT CASE ( coastal_nodes(mesh, elem) ) !num of "coastal" points --#else -- SELECT CASE ( sum( mesh%bc_index_nod2D(mesh%elem2D_nodes(:,elem)) ) ) !num of coastal points -- !SELECT CASE ( sum( bc_index_nod2D(elem2D_nodes(:,elem)) ) ) !num of coastal points --#endif -+ if( use_cavity ) then -+ fld_tmp = coastal_nodes(mesh, partit, elem) -+ else -+ fld_tmp = sum( mesh%bc_index_nod2D(mesh%elem2D_nodes(:,elem)) ) -+ end if -+ -+ SELECT CASE ( fld_tmp ) !num of coastal points - CASE (0) !...coastal points: do nothing - return - -@@ -1020,14 +1060,18 @@ type(t_partit), intent(inout), target :: partit - do m = 1, 3 - node = mesh%elem2D_nodes(m,elem) - !write(*,*) 'index ', m, ':', index_nod2D(node) --#ifdef use_cavity -- if( mesh%bc_index_nod2D(node)==1 .OR. cavity_flag_nod2d(node)==1 ) then --#else -- if( mesh%bc_index_nod2D(node)==1 ) then --#endif -- n(i) = node -- exit -- end if -+ if( use_cavity ) then -+ !if( mesh%bc_index_nod2D(node)==1 .OR. cavity_flag_nod2d(node)==1 ) then -+ if( mesh%bc_index_nod2D(node)==0.0 .OR. (mesh%cavity_depth(node)/=0.0) ) then -+ n(i) = node -+ exit -+ end if -+ else -+ if( mesh%bc_index_nod2D(node)==1 ) then -+ n(i) = node -+ exit -+ end if -+ end if - end do - - !write(*,*) 'one coastal node ', n(1) -@@ -1075,13 +1119,17 @@ type(t_partit), intent(inout), target :: partit - velocity = [ u, v ] - do m = 1, 3 - node = mesh%elem2D_nodes(m,elem) --#ifdef use_cavity -- if( (mesh%bc_index_nod2D(node)==1) .OR. (cavity_flag_nod2d(node)==1)) then --#else -- if( mesh%bc_index_nod2D(node)==1 ) then --#endif -- n(i) = node -- i = i+1 -+ if( use_cavity ) then -+ !if( (mesh%bc_index_nod2D(node)==1) .OR. (cavity_flag_nod2d(node)==1)) then -+ if( mesh%bc_index_nod2D(node)==0.0 .OR. (mesh%cavity_depth(node)/=0.0) ) then -+ n(i) = node -+ i = i+1 -+ end if -+ else -+ if( mesh%bc_index_nod2D(node)==1 ) then -+ n(i) = node -+ i = i+1 -+ end if - end if - end do - call projection(mesh,partit, velocity, n(1), n(2)) diff --git a/src/icb_thermo.F90 b/src/icb_thermo.F90 index 57cb85f63..7b9b38afe 100644 --- a/src/icb_thermo.F90 +++ b/src/icb_thermo.F90 @@ -16,14 +16,15 @@ ! use 3D information for T,S and velocities ! instead of SSTs; M_v depends on 'thermal driving') !============================================================================== -subroutine iceberg_meltrates(partit, M_b, M_v, M_e, M_bv, & - u_ib,v_ib, uo_ib,vo_ib, ua_ib,va_ib, & +subroutine iceberg_meltrates(partit, mesh, M_b, M_v, M_e, M_bv, & + u_ib,v_ib, arr_uo_ib,arr_vo_ib, ua_ib,va_ib, & sst_ib, length_ib, conci_ib, & uo_keel_ib, vo_keel_ib, T_keel_ib, S_keel_ib, depth_ib, height_ib, & - T_ave_ib, S_ave_ib, ib, rho_icb) + arr_T_ave_ib, arr_S_ave_ib, ib, rho_icb,uo_ib,vo_ib, ib_n_lvls, elem, n_lvls) use o_param use MOD_PARTIT + use MOD_MESH use g_clock use g_forcing_arrays use g_rotate_grid @@ -34,43 +35,84 @@ subroutine iceberg_meltrates(partit, M_b, M_v, M_e, M_bv, & ! LA: include latent heat 2023-04-04 real(kind=8),parameter :: L = 334000. ! [J/Kg] - real, intent(IN) :: u_ib,v_ib, uo_ib,vo_ib, ua_ib,va_ib !iceberg velo, (int.) ocean & atm velo + real, intent(IN) :: u_ib,v_ib, uo_ib,vo_ib,ua_ib,va_ib !iceberg velo, (int.) ocean & atm velo real, intent(IN) :: uo_keel_ib, vo_keel_ib !ocean velo at iceberg's draft real, intent(IN) :: sst_ib, length_ib, conci_ib, rho_icb !SST, length and sea ice conc. real, intent(IN) :: T_keel_ib, S_keel_ib, depth_ib, height_ib !T & S at depth 'depth_ib' - real, intent(IN) :: T_ave_ib, S_ave_ib !T & S averaged, i.e. at 'depth_ib/2' - integer, intent(IN) :: ib !iceberg ID + integer, intent(IN) :: ib, n_lvls, ib_n_lvls !iceberg ID + real, intent(IN), dimension(n_lvls) :: arr_T_ave_ib, arr_S_ave_ib !T & S averaged, i.e. at 'depth_ib/2' + real, intent(IN), dimension(n_lvls) :: arr_uo_ib, arr_vo_ib !iceberg velo, (int.) ocean & atm velo real, intent(OUT) :: M_b, M_v, M_e, M_bv !melt rates [m (ice) per s] real :: H_b, H_v, H_e, H_bv !melt rates [m (ice) per s] + real :: M_bv_dz, M_v_dz, dz_acc - + integer :: n, n2 + integer, intent(IN) :: elem + real :: lev_up, lev_low, dz real :: absamino, damping, sea_state, v_ibmino real :: tf, T_d !freezing temp. and 'thermal driving' +type(t_mesh), intent(in) , target :: mesh type(t_partit), intent(inout), target :: partit +!==================== MODULES & DECLARATIONS ==========================!= #include "associate_part_def.h" +#include "associate_mesh_def.h" #include "associate_part_ass.h" +#include "associate_mesh_ass.h" + !3-eq. formulation for bottom melting [m/s] v_ibmino = sqrt( (u_ib - uo_keel_ib)**2 + (v_ib - vo_keel_ib)**2 ) call iceberg_heat_water_fluxes_3eq(partit, ib, M_b, H_b, T_keel_ib,S_keel_ib,v_ibmino, depth_ib, tf) - hfb_flux_ib = H_b * length_ib*length_ib*scaling(ib) + hfb_flux_ib(ib) = H_b * length_ib*length_ib*scaling(ib) + + M_bv_dz = 0.0 + M_v_dz = 0.0 + dz_acc = 0.0 + + n2=elem2D_nodes(1,elem) + do n=1,ib_n_lvls !3-eq. formulation for lateral 'basal' melting [m/s] - v_ibmino = sqrt( (u_ib - uo_ib)**2 + (v_ib - vo_ib)**2 ) ! depth-average rel. velocity - call iceberg_heat_water_fluxes_3eq(partit, ib, M_bv, H_bv, T_ave_ib,S_ave_ib,v_ibmino, depth_ib/2.0, tf) - hfbv_flux_ib = H_bv * (2*length_ib*abs(depth_ib) + 2*length_ib*abs(depth_ib) ) * scaling(ib) + lev_up = mesh%zbar_3d_n(n, n2) + if( n==nlevels_nod2D(n2) ) then + lev_low = mesh%zbar_n_bot(n2) + else + lev_low = mesh%zbar_3d_n(n+1, n2) + end if + + if( abs(lev_low)>=abs(depth_ib) ) then !.AND. (abs(lev_up)<=abs(depth_ib)) ) then + dz = abs(lev_up - depth_ib) + elseif(lev_low == lev_up) then + exit + else + dz = abs(lev_low - lev_up) + end if + dz_acc = dz_acc + dz + + v_ibmino = sqrt( (u_ib - arr_uo_ib(n))**2 + (v_ib - arr_vo_ib(n))**2 ) ! depth-average rel. velocity + call iceberg_heat_water_fluxes_3eq(partit, ib, M_bv, H_bv, arr_T_ave_ib(n), arr_S_ave_ib(n),v_ibmino, dz_acc+dz/2.0, tf) + M_bv_dz = M_bv_dz + M_bv*dz + + hfbv_flux_ib(ib,n) = H_bv * (2*length_ib*dz + 2*length_ib*dz ) * scaling(ib) - !'thermal driving', defined as the elevation of ambient water - !temperature above freezing point' (Neshyba and Josberger, 1979). - T_d = T_ave_ib - tf - if(T_d < 0.) T_d = 0. - - !lateral melt (buoyant convection) - !M_v is a function of the 'thermal driving', NOT just sst! Cf. Neshyba and Josberger (1979) - M_v = 0.00762 * T_d + 0.00129 * T_d**2 - M_v = M_v/86400. - H_v = M_v * rho_icb * L - hfl_flux_ib = H_v * (2*length_ib*abs(depth_ib) + 2*length_ib*abs(depth_ib) ) * scaling(ib) + !'thermal driving', defined as the elevation of ambient water + !temperature above freezing point' (Neshyba and Josberger, 1979). + T_d = arr_T_ave_ib(n) - tf + if(T_d < 0.) T_d = 0. + + !lateral melt (buoyant convection) + !M_v = 0.00762 * sst_ib + 0.00129 * sst_ib**2 + !M_v = M_v/86400. + !M_v is a function of the 'thermal driving', NOT just sst! Cf. Neshyba and Josberger (1979) + M_v = 0.00762 * T_d + 0.00129 * T_d**2 + M_v = M_v/86400. + H_v = M_v * rho_icb * L + M_v_dz = M_v_dz + M_v*dz + hfl_flux_ib(ib,n) = H_v * (2*length_ib*dz + 2*length_ib*dz ) * scaling(ib) + !fwl_flux_ib = M_v + end do + M_bv = M_bv_dz / abs(depth_ib) + M_v = M_v_dz / abs(depth_ib) !wave erosion absamino = sqrt( (ua_ib - uo_ib)**2 + (va_ib - vo_ib)**2 ) @@ -79,7 +121,7 @@ subroutine iceberg_meltrates(partit, M_b, M_v, M_e, M_bv, & M_e = 1./6. * sea_state * (sst_ib + 2.0) * damping M_e = M_e/86400. H_e = M_e * rho_icb * L - hfe_flux_ib = H_e * (length_ib*abs(height_ib) + length_ib*abs(height_ib) ) * scaling(ib) + hfe_flux_ib(ib) = H_e * (length_ib*abs(height_ib) + length_ib*abs(height_ib) ) * scaling(ib) !fwe_flux_ib = M_e end subroutine iceberg_meltrates @@ -236,23 +278,23 @@ subroutine iceberg_newdimensions(partit, ib, depth_ib,height_ib,length_ib,width_ !save in larger array vl_block((ib-1)*4+1 : ib*4)=arr - ! ----------------------- - ! LA: set iceberg heatflux at least to latent heat 2023-04-04 - ! Latent heat flux at base and sides also changes lines 475/476 - ! Lateral heat flux set to latent heat and basal heat flux set to zero - if( lmin_latent_hf ) then - lhfb_flux_ib(ib) = rho_icb*L*tvl*scaling(ib)/dt/REAL(steps_per_ib_step) - - hf_tot_tmp = hfb_flux_ib(ib)+hfbv_flux_ib(ib)+hfl_flux_ib(ib)+hfe_flux_ib(ib) - - if( (hf_tot_tmp >= 0.0) .and. (hf_tot_tmp < lhfb_flux_ib(ib))) then - hfe_flux_ib(ib)=-lhfb_flux_ib(ib) * abs(hfe_flux_ib(ib)/hf_tot_tmp) - hfl_flux_ib(ib)=-lhfb_flux_ib(ib) * abs(hfl_flux_ib(ib)/hf_tot_tmp) - hfb_flux_ib(ib)=-lhfb_flux_ib(ib) * abs(hfb_flux_ib(ib)/hf_tot_tmp) - hfbv_flux_ib(ib)=-lhfb_flux_ib(ib) * abs(hfbv_flux_ib(ib)/hf_tot_tmp) - end if - end if - ! ----------------------- + !! ----------------------- + !! LA: set iceberg heatflux at least to latent heat 2023-04-04 + !! Latent heat flux at base and sides also changes lines 475/476 + !! Lateral heat flux set to latent heat and basal heat flux set to zero + !if( lmin_latent_hf ) then + ! lhfb_flux_ib(ib) = rho_icb*L*tvl*scaling(ib)/dt/REAL(steps_per_ib_step) + + ! hf_tot_tmp = hfb_flux_ib(ib)+hfbv_flux_ib(ib)+hfl_flux_ib(ib)+hfe_flux_ib(ib) + + ! if( (hf_tot_tmp >= 0.0) .and. (abs(hf_tot_tmp) < abs(lhfb_flux_ib(ib)))) then + ! hfe_flux_ib(ib)=-lhfb_flux_ib(ib) * abs(hfe_flux_ib(ib)/hf_tot_tmp) + ! hfl_flux_ib(ib)=-lhfb_flux_ib(ib) * abs(hfl_flux_ib(ib)/hf_tot_tmp) + ! hfb_flux_ib(ib)=-lhfb_flux_ib(ib) * abs(hfb_flux_ib(ib)/hf_tot_tmp) + ! hfbv_flux_ib(ib)=-lhfb_flux_ib(ib) * abs(hfbv_flux_ib(ib)/hf_tot_tmp) + ! end if + !end if + !! ----------------------- end subroutine iceberg_newdimensions @@ -447,7 +489,7 @@ subroutine iceberg_heat_water_fluxes_3eq(partit, ib, M_b, H_b, T_ib,S_ib,v_rel, M_b = - (rhow / rhoi) * M_b ! [m (ice) per second], positive for melting? NOW positive for melting !LA avoid basal freezing for grounded icebergs - if(M_b.lt.0.) then + if(grounded(ib) .and. (M_b.lt.0.)) then M_b = 0.0 endif diff --git a/src/icb_thermo.F90.rej b/src/icb_thermo.F90.rej deleted file mode 100644 index 14d566b0e..000000000 --- a/src/icb_thermo.F90.rej +++ /dev/null @@ -1,324 +0,0 @@ -diff a/src/icb_thermo.F90 b/src/icb_thermo.F90 (rejected hunks) -@@ -16,45 +16,39 @@ - ! use 3D information for T,S and velocities - ! instead of SSTs; M_v depends on 'thermal driving') - !============================================================================== --subroutine iceberg_meltrates( M_b, M_v, M_e, M_bv, & -+subroutine iceberg_meltrates(partit, M_b, M_v, M_e, M_bv, & - u_ib,v_ib, uo_ib,vo_ib, ua_ib,va_ib, & - sst_ib, length_ib, conci_ib, & - uo_keel_ib, vo_keel_ib, T_keel_ib, S_keel_ib, depth_ib, & -- T_ave_ib, S_ave_ib, ib) -+ T_ave_ib, S_ave_ib, ib, rho_icb) - --! use o_mesh - use o_param --! use i_therm_param --! use i_param --! use MOD_ICE --! use i_arrays --! use MOD_PARTIT -- --! kh 18.03.21 not really used here --! use o_arrays -- -+ use MOD_PARTIT - use g_clock - use g_forcing_arrays - use g_rotate_grid - -- use iceberg_params, only: fwe_flux_ib, fwl_flux_ib, fwb_flux_ib, fwbv_flux_ib, heat_flux_ib -- -+ use iceberg_params, only: fwe_flux_ib, fwl_flux_ib, fwb_flux_ib, fwbv_flux_ib, hfb_flux_ib, hfbv_flux_ib, hfe_flux_ib, hfl_flux_ib, height_ib, scaling - implicit none - -+ ! LA: include latent heat 2023-04-04 -+ real(kind=8),parameter :: L = 334000. ! [J/Kg] -+ - real, intent(IN) :: u_ib,v_ib, uo_ib,vo_ib, ua_ib,va_ib !iceberg velo, (int.) ocean & atm velo - real, intent(IN) :: uo_keel_ib, vo_keel_ib !ocean velo at iceberg's draft -- real, intent(IN) :: sst_ib, length_ib, conci_ib !SST, length and sea ice conc. -- real, intent(IN) :: T_keel_ib, S_keel_ib, depth_ib !T & S at depth 'depth_ib' -+ real, intent(IN) :: sst_ib, length_ib, conci_ib, rho_icb !SST, length and sea ice conc. -+ real, intent(IN) :: T_keel_ib, S_keel_ib, depth_ib !T & S at depth 'depth_ib' - real, intent(IN) :: T_ave_ib, S_ave_ib !T & S averaged, i.e. at 'depth_ib/2' - integer, intent(IN) :: ib !iceberg ID - real, intent(OUT) :: M_b, M_v, M_e, M_bv !melt rates [m (ice) per s] -+ real :: H_b, H_v, H_e, H_bv !melt rates [m (ice) per s] - - - real :: absamino, damping, sea_state, v_ibmino - real :: tf, T_d !freezing temp. and 'thermal driving' --!type(t_partit), intent(inout), target :: partit --!#include "associate_part_def.h" --!#include "associate_part_ass.h" -+type(t_partit), intent(inout), target :: partit -+#include "associate_part_def.h" -+#include "associate_part_ass.h" - - !bottom melt (basal turbulent melting rate) - !M_b = 0.58 * sqrt( (u_ib - uo_ib)**2 + (v_ib - vo_ib)**2 )**0.8 & -@@ -63,17 +57,18 @@ subroutine iceberg_meltrates( M_b, M_v, M_e, M_bv, & - - !3-eq. formulation for bottom melting [m/s] - v_ibmino = sqrt( (u_ib - uo_keel_ib)**2 + (v_ib - vo_keel_ib)**2 ) -- call iceberg_heat_water_fluxes_3eq(ib, M_b, T_keel_ib,S_keel_ib,v_ibmino, depth_ib, tf) -+ call iceberg_heat_water_fluxes_3eq(partit, ib, M_b, H_b, T_keel_ib,S_keel_ib,v_ibmino, depth_ib, tf) -+ hfb_flux_ib = H_b * length_ib*length_ib*scaling(ib) - - !3-eq. formulation for lateral 'basal' melting [m/s] - v_ibmino = sqrt( (u_ib - uo_ib)**2 + (v_ib - vo_ib)**2 ) ! depth-average rel. velocity -- call iceberg_heat_water_fluxes_3eq(ib, M_bv, T_ave_ib,S_ave_ib,v_ibmino, depth_ib/2.0, tf) -+ call iceberg_heat_water_fluxes_3eq(partit, ib, M_bv, H_bv, T_ave_ib,S_ave_ib,v_ibmino, depth_ib/2.0, tf) -+ hfbv_flux_ib = H_bv * (2*length_ib*abs(depth_ib) + 2*length_ib*abs(depth_ib) ) * scaling(ib) - - !'thermal driving', defined as the elevation of ambient water - !temperature above freezing point' (Neshyba and Josberger, 1979). - T_d = T_ave_ib - tf - if(T_d < 0.) T_d = 0. -- !write(*,*) 'thermal driving:',T_d,'; Tf:',tf,'T_ave:',T_ave_ib - - !lateral melt (buoyant convection) - !M_v = 0.00762 * sst_ib + 0.00129 * sst_ib**2 -@@ -81,6 +76,8 @@ subroutine iceberg_meltrates( M_b, M_v, M_e, M_bv, & - !M_v is a function of the 'thermal driving', NOT just sst! Cf. Neshyba and Josberger (1979) - M_v = 0.00762 * T_d + 0.00129 * T_d**2 - M_v = M_v/86400. -+ H_v = M_v * rho_icb * L -+ hfl_flux_ib = H_v * (2*length_ib*abs(depth_ib) + 2*length_ib*abs(depth_ib) ) * scaling(ib) - !fwl_flux_ib = M_v - - !wave erosion -@@ -106,21 +105,12 @@ end subroutine iceberg_meltrates - subroutine iceberg_newdimensions(partit, ib, depth_ib,height_ib,length_ib,width_ib,M_b,M_v,M_e,M_bv, & - rho_h2o, rho_icb, file_meltrates) - --! use o_mesh - use o_param !for step_per_day --! use i_therm_param --! use i_param --! use MOD_ICE --! use i_arrays - use MOD_PARTIT !for mype -- --! kh 18.03.21 not really used here --! use o_arrays -- - use g_clock - use g_forcing_arrays - use g_rotate_grid -- use iceberg_params, only: l_weeksmellor, ascii_out, icb_outfreq, vl_block, bvl_mean, lvlv_mean, lvle_mean, lvlb_mean, smallestvol_icb, fwb_flux_ib, fwe_flux_ib, fwbv_flux_ib, fwl_flux_ib, scaling, heat_flux_ib, lheat_flux_ib -+ use iceberg_params, only: l_weeksmellor, ascii_out, icb_outfreq, vl_block, bvl_mean, lvlv_mean, lvle_mean, lvlb_mean, smallestvol_icb, fwb_flux_ib, fwe_flux_ib, fwbv_flux_ib, fwl_flux_ib, scaling, hfb_flux_ib, hfbv_flux_ib, hfe_flux_ib, hfl_flux_ib, lhfb_flux_ib - use g_config, only: steps_per_ib_step - - implicit none -@@ -185,8 +176,6 @@ type(t_partit), intent(inout), target :: partit - volume_after=volume_before-tvl - - !calculating the new iceberg dimensions -- !depth_ib = (abs(depth_ib)-dh_b)*(-1.) -- !height_ib= abs(depth_ib) * rho_h2o/rho_icb - height_ib= height_ib - dh_b - depth_ib = -height_ib * rho_icb/rho_h2o - -@@ -196,15 +185,13 @@ type(t_partit), intent(inout), target :: partit - - !distribute dh_e equally between length and width - !as in code of michael schodlok, but not dh_v? -- !length_ib= length_ib - dh_v -dh_e/2. -- !width_ib = width_ib - dh_v -dh_e/2. - - volume_after=height_ib*length_ib*width_ib - - !iceberg smaller than critical value after melting? - if (volume_after .le. smallestvol_icb) then - volume_after=0.0 -- depth_ib = 0.0 -+ depth_ib = 0.0 - height_ib= 0.0 - length_ib= 0.0 - width_ib = 0.0 -@@ -297,25 +293,20 @@ end subroutine weeksmellor - !*************************************************************************************************************************** - !*************************************************************************************************************************** - --subroutine iceberg_heat_water_fluxes_3eq(ib, M_b, T_ib,S_ib,v_rel, depth_ib, t_freeze) -+subroutine iceberg_heat_water_fluxes_3eq(partit, ib, M_b, H_b, T_ib,S_ib,v_rel, depth_ib, t_freeze) - ! The three-equation model of ice-shelf ocean interaction (Hellmer et al., 1997) - ! Code derived from BRIOS subroutine iceshelf (which goes back to H.Hellmer's 2D ice shelf model code) - ! adjusted for use in FESOM by Ralph Timmermann, 16.02.2011 - ! adopted and modified for iceberg basal melting by Thomas Rackow, 11.06.2014 - !---------------------------------------------------------------- - -- !use o_mesh -- !use o_param -- !use o_arrays -- !use i_arrays -- !use MOD_PARTIT - use iceberg_params - use g_config - - implicit none - - integer, INTENT(IN) :: ib -- real(kind=8),INTENT(OUT) :: M_b, t_freeze -+ real(kind=8),INTENT(OUT) :: M_b, H_b, t_freeze - real(kind=8),INTENT(IN) :: T_ib, S_ib ! ocean temperature & salinity (at depth 'depth_ib') - real(kind=8),INTENT(IN) :: v_rel, depth_ib ! relative velocity iceberg-ocean (at depth 'depth_ib') - -@@ -351,22 +342,11 @@ subroutine iceberg_heat_water_fluxes_3eq(ib, M_b, T_ib,S_ib,v_rel, depth_ib, t_f - real(kind=8),parameter :: cpi = 152.5+7.122*(atk+tob) !Paterson:"The Physics of Glaciers" - - real(kind=8),parameter :: L = 334000. ! [J/Kg] -+type(t_partit), intent(inout), target :: partit -+!==================== MODULES & DECLARATIONS ==========================!= -+#include "associate_part_def.h" -+#include "associate_part_ass.h" - -- ! hemw = helium content of the glacial meltwater -- ! oomw = isotopic fractionation due to melting -- ! oofw = isotopic fractionation due to freezing -- ! hemw= 4.02*14. -- ! oomw= -30. -- ! oofw= -2.5 -- -- !n3=myDim_nod3d+eDim_nod3d -- -- !do n=1,myDim_nod2D+eDim_nod2D -- !if(cavity_flag_nod2d(n)==0) cycle -- !nk=nod3d_below_nod2d(1,n) -- !temp = tracer(nk,1) -- !sal = tracer(nk,2) -- !zice = coord_nod3d(3,nk) !(<0) - temp = T_ib - sal = S_ib - zice = depth_ib !(<0) -@@ -378,15 +358,7 @@ subroutine iceberg_heat_water_fluxes_3eq(ib, M_b, T_ib,S_ib,v_rel, depth_ib, t_f - ! Calculate or prescribe the turbulent heat and salt transfer coeff. GAT and GAS - ! velocity-dependent approach of Jenkins (1991) - -- !rt vt1 = 0.25*sqrt((u(i,j,N,lrhs)+u(i+1,j,N,lrhs))**2 -- !rt & +(v(i,j,N,lrhs)+v(i,j+1,N,lrhs))**2) -- ! if(vt1.eq.0.) vt1=0.001 -- !rt re = Hz_r(i,j,N)*ds/un !Reynolds number -- -- !vt1 = sqrt(uf(nk)*uf(nk)+uf(nk+n3)*uf(nk+n3)) ! relative velocity ice-ocean - vt1 = v_rel ! relative velocity iceberg-ocean (at depth 'depth_ib') -- --!rt RG44030 vt1 = max(vt1,0.001) - vt1 = max(vt1,0.005) ! RG44030 - - re = 10./un !vt1*re (=velocity times length scale over kinematic viscosity) is the Reynolds number -@@ -530,112 +503,6 @@ subroutine potit_ib(ib,salz,pt,pres,rfpres,tin) - return - end subroutine potit_ib - --! if the underlying FESOM is run without cavities, the following routines might be --! missing, so put them here: --#ifndef use_cavity --! --!------------------------------------------------------------------------------------- --! --!subroutine potit(salz,pt,pres,rfpres,tin) --! ! Berechnet aus dem Salzgehalt[psu] (SALZ), der pot. Temperatur[oC] --! ! (PT) und dem Referenzdruck[dbar] (REFPRES) die in-situ Temperatur --! ! [oC] (TIN) bezogen auf den in-situ Druck[dbar] (PRES) mit Hilfe --! ! eines Iterationsverfahrens aus. --! --! integer iter --! real salz,pt,pres,rfpres,tin --! real epsi,tpmd,pt1,ptd,pttmpr --! --! data tpmd / 0.001 / --! --! epsi = 0. --! do iter=1,100 --! tin = pt+epsi --! pt1 = pttmpr(salz,tin,pres,rfpres) --! ptd = pt1-pt --! if(abs(ptd).lt.tpmd) return --! epsi = epsi-ptd --! enddo --! write(6,*) ' WARNING!' --! write(6,*) ' in-situ temperature calculation has not converged.' --! stop --! return --!end subroutine potit --! --!------------------------------------------------------------------------------------- --! --!real function pttmpr(salz,temp,pres,rfpres) --! ! Berechnet aus dem Salzgehalt/psu (SALZ), der in-situ Temperatur/degC --! ! (TEMP) und dem in-situ Druck/dbar (PRES) die potentielle Temperatur/ --! ! degC (PTTMPR) bezogen auf den Referenzdruck/dbar (RFPRES). Es wird --! ! ein Runge-Kutta Verfahren vierter Ordnung verwendet. --! ! Checkwert: PTTMPR = 36.89073 DegC --! ! fuer SALZ = 40.0 psu --! ! TEMP = 40.0 DegC --! ! PRES = 10000.000 dbar --! ! RFPRES = 0.000 dbar --! --! data ct2 ,ct3 /0.29289322 , 1.707106781/ --! data cq2a,cq2b /0.58578644 , 0.121320344/ --! data cq3a,cq3b /3.414213562, -4.121320344/ --! --! real salz,temp,pres,rfpres --! real p,t,dp,dt,q,ct2,ct3,cq2a,cq2b,cq3a,cq3b --! real adlprt --! --! p = pres --! t = temp --! dp = rfpres-pres --! dt = dp*adlprt(salz,t,p) --! t = t +0.5*dt --! q = dt --! p = p +0.5*dp --! dt = dp*adlprt(salz,t,p) --! t = t + ct2*(dt-q) --! q = cq2a*dt + cq2b*q --! dt = dp*adlprt(salz,t,p) --! t = t + ct3*(dt-q) --! q = cq3a*dt + cq3b*q --! p = rfpres --! dt = dp*adlprt(salz,t,p) --! --! pttmpr = t + (dt-q-q)/6.0 --! --!end function pttmpr --! --!------------------------------------------------------------------------------------- --! --!real function adlprt(salz,temp,pres) --! ! Berechnet aus dem Salzgehalt/psu (SALZ), der in-situ Temperatur/degC --! ! (TEMP) und dem in-situ Druck/dbar (PRES) den adiabatischen Temperatur- --! ! gradienten/(K Dbar^-1) ADLPRT. --! ! Checkwert: ADLPRT = 3.255976E-4 K dbar^-1 --! ! fuer SALZ = 40.0 psu --! ! TEMP = 40.0 DegC --! ! PRES = 10000.000 dbar --! --! real salz,temp,pres --! real s0,a0,a1,a2,a3,b0,b1,c0,c1,c2,c3,d0,d1,e0,e1,e2,ds --! --! data s0 /35.0/ --! data a0,a1,a2,a3 /3.5803E-5, 8.5258E-6, -6.8360E-8, 6.6228E-10/ --! data b0,b1 /1.8932E-6, -4.2393E-8/ --! data c0,c1,c2,c3 /1.8741E-8, -6.7795E-10, 8.7330E-12, -5.4481E-14/ --! data d0,d1 /-1.1351E-10, 2.7759E-12/ --! data e0,e1,e2 /-4.6206E-13, 1.8676E-14, -2.1687E-16/ --! --! ds = salz-s0 --! adlprt = ( ( (e2*temp + e1)*temp + e0 )*pres & --! + ( (d1*temp + d0)*ds & --! + ( (c3*temp + c2)*temp + c1 )*temp + c0 ) )*pres & --! + (b1*temp + b0)*ds + ( (a3*temp + a2)*temp + a1 )*temp + a0 --! --!END function adlprt --! --!---------------------------------------------------------------------------------------- --! --#endif -- - - ! LA from oce_dens_press for iceberg coupling - subroutine fcn_density(t,s,z,rho) diff --git a/src/ice_oce_coupling.F90 b/src/ice_oce_coupling.F90 index c33824352..270118675 100755 --- a/src/ice_oce_coupling.F90 +++ b/src/ice_oce_coupling.F90 @@ -385,6 +385,10 @@ subroutine oce_fluxes(ice, dynamics, tracers, partit, mesh) !$OMP END PARALLEL DO #endif + if (use_icebergs) then + call icb2fesom(mesh, partit, ice) + end if + !___________________________________________________________________________ ! add heat and fresh water flux from cavity if (use_cavity) then @@ -554,6 +558,16 @@ subroutine oce_fluxes(ice, dynamics, tracers, partit, mesh) !$OMP END PARALLEL DO end if + !___________________________________________________________________________ + if (use_icebergs) then + if (lbalance_fw .and. (.not. turn_off_fw)) then + flux = flux + (ibfwb + ibfwe + ibfwl + ibfwbv) !* steps_per_ib_step + end if + + call integrate_nod(ibfwb + ibfwe + ibfwl + ibfwbv, net, partit, mesh) + if (mype==0) write(*,*) " * total iceberg fw flux: ", net + end if + !___________________________________________________________________________ if (use_cavity) then ! with zstar we do not balance the freshwater flux under the cavity since its @@ -568,17 +582,6 @@ subroutine oce_fluxes(ice, dynamics, tracers, partit, mesh) where (ulevels_nod2d > 1) flux = -water_flux end if end if - - !___________________________________________________________________________ - if (use_icebergs .and. lbalance_fw) then - call icb2fesom(mesh, partit, ice) - if (.not.turn_off_fw) then - flux = flux + (ibfwb + ibfwe + ibfwl + ibfwbv) !* steps_per_ib_step - end if - - call integrate_nod(ibfwb + ibfwe + ibfwl + ibfwbv, net, partit, mesh) - if (mype==0) write(*,*) " * total iceberg fw flux: ", net - end if !___________________________________________________________________________ ! compute total global net freshwater flux into the ocean diff --git a/src/ice_oce_coupling.F90.rej b/src/ice_oce_coupling.F90.rej deleted file mode 100644 index 2d095512b..000000000 --- a/src/ice_oce_coupling.F90.rej +++ /dev/null @@ -1,23 +0,0 @@ -diff a/src/ice_oce_coupling.F90 b/src/ice_oce_coupling.F90 (rejected hunks) -@@ -563,9 +564,21 @@ subroutine oce_fluxes(ice, dynamics, tracers, partit, mesh) - end if - end if - -+ !___________________________________________________________________________ -+ if (use_icebergs .and. lbalance_fw) then -+ call icb2fesom(mesh, partit, ice) -+ if (.not.turn_off_fw) then -+ flux = flux + (ibfwb + ibfwe + ibfwl + ibfwbv) !* steps_per_ib_step -+ end if -+ -+ call integrate_nod(ibfwb + ibfwe + ibfwl + ibfwbv, net, partit, mesh) -+ if (mype==0) write(*,*) " * total iceberg fw flux: ", net -+ end if -+ - !___________________________________________________________________________ - ! compute total global net freshwater flux into the ocean - call integrate_nod(flux, net, partit, mesh) -+ - - !___________________________________________________________________________ - ! here the + sign must be used because we switched up the sign of the diff --git a/src/io_meandata.F90.rej b/src/io_meandata.F90.rej deleted file mode 100644 index 3dc502956..000000000 --- a/src/io_meandata.F90.rej +++ /dev/null @@ -1,11 +0,0 @@ -diff a/src/io_meandata.F90 b/src/io_meandata.F90 (rejected hunks) -@@ -596,7 +596,8 @@ CASE ('icb ') - call def_stream(nod2D, myDim_nod2D, 'ibfwbv', 'basal iceberg melting', 'm/s', ibfwbv(:), 1, 'm', i_real4, partit, mesh) - call def_stream(nod2D, myDim_nod2D, 'ibfwl', 'lateral iceberg melting', 'm/s', ibfwl(:), 1, 'm', i_real4, partit, mesh) - call def_stream(nod2D, myDim_nod2D, 'ibfwe', 'iceberg erosion', 'm/s', ibfwe(:), 1, 'm', i_real4, partit, mesh) -- call def_stream(nod2D, myDim_nod2D, 'ibhf', 'heat flux from iceberg melting', 'm/s', ibhf(:), 1, 'm', i_real4, partit, mesh) -+ !call def_stream(nod2D, myDim_nod2D, 'ibhf', 'heat flux from iceberg melting', 'm/s', ibhf(:), 1, 'm', i_real4, partit, mesh) -+ call def_stream((/nl,nod2D/), (/nl,myDim_nod2D/), 'ibhf', 'heat flux from iceberg melting', 'm/s', ibhf_n(:,:), 1, 'm', i_real4, partit, mesh) - end if - !------------------------------------------ - diff --git a/src/oce_ale_tracer.F90.rej b/src/oce_ale_tracer.F90.rej deleted file mode 100644 index f7caf0eb0..000000000 --- a/src/oce_ale_tracer.F90.rej +++ /dev/null @@ -1,9 +0,0 @@ -diff a/src/oce_ale_tracer.F90 b/src/oce_ale_tracer.F90 (rejected hunks) -@@ -452,6 +452,7 @@ subroutine diff_ver_part_impl_ale(tr_num, dynamics, tracers, partit, mesh) - use o_mixing_KPP_mod !for ghats _GO_ - use g_cvmix_kpp, only: kpp_nonlcltranspT, kpp_nonlcltranspS, kpp_oblmixc - use bc_surface_interface -+ use iceberg_params - implicit none - integer , intent(in) , target :: tr_num - type(t_dyn) , intent(inout), target :: dynamics