11#include "scaleFElib.h"
21 use scale_const,
only: &
22 undef8 => const_undef8
23 use scale_atmos_hydrometeor,
only: &
59 integer :: atm_var_container_typeid
61 integer :: sfcflx_typeid
66 procedure,
public :: setup => atmosphysfc_setup
67 procedure,
public :: set_coupler_flag => atmosphysfc_set_coupler_flag
68 procedure,
public :: calc_tendency => atmosphysfc_calc_tendency
69 procedure,
public :: update => atmosphysfc_update
70 procedure,
public :: finalize => atmosphysfc_finalize
78 integer,
parameter :: sfcflx_typeid_simple = 2
85 private :: cal_tend_from_sfcflx
86 private :: cal_del_flux
87 private :: convert_uv2localorthvec
88 private :: convert_localorth2uvvec
104 subroutine atmosphysfc_setup( this, model_mesh, tm_parent_comp )
107 use scale_atmos_phy_sf_const,
only: &
108 atmos_phy_sf_const_setup
116 class(modelmeshbase),
target,
intent(in) :: model_mesh
119 real(dp) :: time_dt = undef8
120 character(len=H_SHORT) :: time_dt_unit =
'SEC'
121 character(len=H_MID) :: sfcflx_type =
"CONST"
122 integer :: atm_var_container_typeid
123 real(rp) :: default_sfc_temp = 300.0_rp
124 namelist /param_atmos_phy_sfc/ &
128 atm_var_container_typeid, &
138 if (.not. this%IsActivated())
return
141 log_info(
"ATMOS_PHY_SFC_setup",*)
'Setup'
143 atm_var_container_typeid = atm_vars_container_primary_id
147 read(io_fid_conf,nml=param_atmos_phy_sfc,iostat=ierr)
149 log_info(
"ATMOS_PHY_SFC_setup",*)
'Not found namelist. Default used.'
150 elseif( ierr > 0 )
then
151 log_error(
"ATMOS_PHY_SFC_setup",*)
'Not appropriate names in namelist PARAM_ATMOS_PHY_SFC. Check!'
154 log_nml(param_atmos_phy_sfc)
156 this%atm_var_container_typeid = atm_var_container_typeid
160 call tm_parent_comp%Regist_process(
'ATMOS_PHY_SFC', time_dt, time_dt_unit, &
164 call this%vars%Init( model_mesh, default_sfc_temp )
168 select case( sfcflx_type )
170 call atmos_phy_sf_const_setup()
174 this%SFCFLX_TYPEID = sfcflx_typeid_simple
176 log_error(
"ATMOS_PHY_SFC_setup",*)
'Not appropriate names of SFCFLX_TYPE in namelist PARAM_PHY_SFC. Check!'
181 select type(model_mesh)
183 this%mesh => model_mesh
187 end subroutine atmosphysfc_setup
190 subroutine atmosphysfc_set_coupler_flag( this, cpl_sw )
193 logical,
intent(in) :: cpl_sw
197 end subroutine atmosphysfc_set_coupler_flag
209 subroutine atmosphysfc_calc_tendency( &
210 this, model_mesh, prgvars_list, trcvars_list, &
211 auxvars_list, forcing_list, is_update )
213 use scale_tracer,
only: &
217 atmosvars_getlocalmeshprgvars, &
218 atmosvars_getlocalmeshphytends, &
219 atmosvars_getlocalmeshphyauxvars, &
220 atmosvars_getlocalmeshqtrc_qv, &
221 atmosvars_getlocalmeshqtrcphytend
227 class(modelmeshbase),
intent(in) :: model_mesh
232 logical,
intent(in) :: is_update
241 class(
localmeshfieldbase),
pointer :: dens_tp, momx_tp, momy_tp, momz_tp, rhot_tp, rhoh_p, rhoqv_tp
242 class(
localmeshfieldbase),
pointer :: sflx_mu, sflx_mv, sflx_mw, sflx_sh, sflx_lh, sflx_qv
248 if (.not. this%IsActivated())
return
250 call model_mesh%GetModelMesh( mesh )
254 do n=1, mesh%LOCAL_MESH_NUM
255 call prof_rapstart(
'ATM_PHY_SFC_get_localmesh_ptr', 2)
256 call atmosvars_getlocalmeshprgvars( n, &
257 mesh, prgvars_list, auxvars_list, &
258 ddens, momx, momy, momz, drhot, &
259 dens_hyd, pres_hyd, rtot, cvtot, cptot, &
261 call atmosvars_getlocalmeshphytends( n, &
262 mesh, forcing_list, &
263 dens_tp, momx_tp, momy_tp, momz_tp, rhot_tp, &
265 call atmosvars_getlocalmeshqtrc_qv( n, mesh, trcvars_list, forcing_list, &
267 call atmosvars_getlocalmeshphyauxvars( n, &
268 mesh, auxvars_list, &
272 mesh, this%vars%SFCVARS_manager, this%vars%SFCFLX_manager, &
273 sfc_temp, sflx_mu, sflx_mv, sflx_mw, sflx_sh, sflx_lh, sflx_qv )
274 call prof_rapend(
'ATM_PHY_SFC_get_localmesh_ptr', 2)
276 call prof_rapstart(
'ATM_PHY_SFC_cal_tend', 2)
277 call cal_tend_from_sfcflx( this, is_update, &
278 dens_tp%val, momx_tp%val, momy_tp%val, momz_tp%val, rhoh_p%val, rhoqv_tp%val, &
279 sflx_mu%val, sflx_mv%val, sflx_mw%val, sflx_sh%val, sflx_lh%val, sflx_qv%val, &
280 ddens%val, momx%val, momy%val, momz%val, drhot%val, qv%val, &
281 dens_hyd%val, pres_hyd%val, &
282 pres%val, pt%val, rtot%val, sfc_temp%val, &
283 model_mesh%DOptrMat(3), model_mesh%SOptrMat(3), model_mesh%LiftOptrMat, &
284 lcmesh, lcmesh%refElem3D, lcmesh%lcmesh2D, lcmesh%lcmesh2D%refElem2D )
285 call prof_rapend(
'ATM_PHY_SFC_cal_tend', 2)
291 end subroutine atmosphysfc_calc_tendency
302 subroutine atmosphysfc_update( this, model_mesh, &
303 prgvars_list, trcvars_list, auxvars_list, forcing_list, &
308 class(modelmeshbase),
intent(in) :: model_mesh
313 logical,
intent(in) :: is_update
317 end subroutine atmosphysfc_update
322 subroutine atmosphysfc_finalize( this )
327 if (.not. this%IsActivated())
return
329 call this%vars%Final()
332 end subroutine atmosphysfc_finalize
338 subroutine cal_tend_from_sfcflx( this, is_update_sflx, &
339 DENS_tp, MOMX_tp, MOMY_tp, MOMZ_tp, RHOH_p, RHOQV_tp, &
340 SFLX_MU, SFLX_MV, SFLX_MW, SFLX_SH, SFLX_LH, SFLX_QV, &
341 DDENS, MOMX, MOMY, MOMZ, DRHOT, &
343 DENS_hyd, PRES_hyd, PRES, PT, Rtot, &
346 lcmesh, elem, lcmesh2D, elem2D )
348 use scale_const,
only: &
349 rdry => const_rdry, &
350 cpdry => const_cpdry, &
351 cvdry => const_cvdry, &
352 pres00 => const_pre00, &
353 rplanet => const_radius
354 use scale_atmos_hydrometeor,
only: &
357 use scale_tracer,
only: &
359 use scale_atmos_phy_sf_const,
only: &
360 atmos_phy_sf_const_flux
374 logical,
intent(in) :: is_update_sflx
375 real(rp),
intent(inout) :: dens_tp(elem%np,lcmesh%nea)
376 real(rp),
intent(inout) :: momx_tp(elem%np,lcmesh%nea)
377 real(rp),
intent(inout) :: momy_tp(elem%np,lcmesh%nea)
378 real(rp),
intent(inout) :: momz_tp(elem%np,lcmesh%nea)
379 real(rp),
intent(inout) :: rhoh_p (elem%np,lcmesh%nea)
380 real(rp),
intent(inout) :: rhoqv_tp(elem%np,lcmesh%nea)
381 real(rp),
intent(inout) :: sflx_mu(elem2d%np,lcmesh2d%nea)
382 real(rp),
intent(inout) :: sflx_mv(elem2d%np,lcmesh2d%nea)
383 real(rp),
intent(inout) :: sflx_mw(elem2d%np,lcmesh2d%nea)
384 real(rp),
intent(inout) :: sflx_sh(elem2d%np,lcmesh2d%nea)
385 real(rp),
intent(inout) :: sflx_lh(elem2d%np,lcmesh2d%nea)
386 real(rp),
intent(inout) :: sflx_qv(elem2d%np,lcmesh2d%nea)
387 real(rp),
intent(in) :: ddens(elem%np,lcmesh%nea)
388 real(rp),
intent(in) :: momx(elem%np,lcmesh%nea)
389 real(rp),
intent(in) :: momy(elem%np,lcmesh%nea)
390 real(rp),
intent(in) :: momz(elem%np,lcmesh%nea)
391 real(rp),
intent(in) :: drhot(elem%np,lcmesh%nea)
392 real(rp),
intent(in) :: qv(elem%np,lcmesh%nea)
393 real(rp),
intent(in) :: pres_hyd(elem%np,lcmesh%nea)
394 real(rp),
intent(in) :: dens_hyd(elem%np,lcmesh%nea)
395 real(rp),
intent(in) :: pres(elem%np,lcmesh%nea)
396 real(rp),
intent(in) :: pt(elem%np,lcmesh%nea)
397 real(rp),
intent(in) :: rtot(elem%np,lcmesh%nea)
398 real(rp),
intent(in) :: sfc_temp(elem2d%np,lcmesh2d%nea)
399 type(
sparsemat),
intent(in) :: dz, sz, lift
401 real(rp) :: atm_w (elem2d%np,lcmesh2d%ne)
402 real(rp) :: atm_u (elem2d%np,lcmesh2d%ne)
403 real(rp) :: atm_v (elem2d%np,lcmesh2d%ne)
404 real(rp) :: atm_temp(elem2d%np,lcmesh2d%ne)
405 real(rp) :: atm_pres(elem2d%np,lcmesh2d%ne)
406 real(rp) :: atm_qv (elem2d%np,lcmesh2d%ne)
407 real(rp) :: dz1 (elem2d%np,lcmesh2d%ne)
408 real(rp) :: z1 (elem2d%np,lcmesh2d%ne)
409 real(rp) :: sfc_pres(elem2d%np,lcmesh2d%ne)
410 real(rp) :: sfc_dens(elem2d%np,lcmesh2d%ne)
412 real(rp) :: sflx_qtrc(elem2d%np,lcmesh2d%ne,max(1,qa))
413 real(rp) :: sflx_engi(elem2d%np,lcmesh2d%ne)
416 real(rp) :: u10(elem2d%np,lcmesh2d%ne)
417 real(rp) :: v10(elem2d%np,lcmesh2d%ne)
421 integer :: hslicez0, hslicez1
425 real(rp) :: liftdelflx(elem%np)
426 real(rp) :: del_flux(elem%nfptot,lcmesh%ne,5)
428 real(rp) :: sflx_mu1, sflx_mv1
432 if ( is_update_sflx .and. (.not. this%CPL_sw) )
then
436 do ke2d=lcmesh2d%NeS, lcmesh2d%NeE
440 hslicez0 = elem%Hslice(ij,1)
441 hslicez1 = elem%Hslice(ij,2)
443 dens = dens_hyd(hslicez1,ke) + ddens(hslicez1,ke)
444 atm_u(ij,ke2d) = momx(hslicez1,ke) / dens
445 atm_v(ij,ke2d) = momy(hslicez1,ke) / dens
446 atm_w(ij,ke2d) = 0.0_rp
447 atm_pres(ij,ke2d) = pres(hslicez1,ke)
450 atm_qv(ij,ke2d) = qv(hslicez1,ke)
452 sfc_dens(ij,ke2d) = dens_hyd(hslicez0,ke) + ddens(hslicez0,ke)
453 sfc_pres(ij,ke2d) = pres(hslicez0,ke)
455 atm_temp(ij,ke2d) = sfc_pres(ij,ke2d) / ( rtot(hslicez0,ke) * sfc_dens(ij,ke2d) )
456 atm_qv(ij,ke2d) = qv(hslicez0,ke)
458 z1(ij,ke2d) = lcmesh%zlev(hslicez1,ke)
459 dz1(ij,ke2d) = z1(ij,ke2d) - lcmesh%zlev(hslicez0,ke)
460 z1(ij,ke2d) = z1(ij,ke2d) + rplanet
464 call convert_uv2localorthvec( &
465 this%mesh%ptr_mesh, lcmesh2d%pos_en(:,:,1), lcmesh2d%pos_en(:,:,2), z1(:,:), elem2d%Np*lcmesh2d%Ne, &
469 select case ( this%SFCFLX_TYPEID )
471 call atmos_phy_sf_const_flux( &
472 elem2d%Np, 1, elem2d%Np, lcmesh2d%NeA, 1, lcmesh2d%Ne, &
473 atm_w(:,:), atm_u(:,:), atm_v(:,:), sfc_temp(:,:), &
474 dz1(:,:), sfc_dens(:,:), &
475 sflx_mw(:,:), sflx_mu(:,:), sflx_mv(:,:), &
476 sflx_sh(:,:), sflx_lh(:,:), sflx_qv(:,:), &
478 case ( sfcflx_typeid_simple )
480 elem2d%Np, 1, elem2d%Np, lcmesh2d%NeA, 1, lcmesh2d%Ne, &
481 atm_w(:,:), atm_u(:,:), atm_v(:,:), atm_temp(:,:), atm_pres(:,:), &
483 sfc_dens(:,:), sfc_temp(:,:), sfc_pres(:,:), &
485 sflx_mw(:,:), sflx_mu(:,:), sflx_mv(:,:), &
486 sflx_sh(:,:), sflx_lh(:,:), sflx_qv(:,:), &
490 call convert_localorth2uvvec( &
491 this%mesh%ptr_mesh, lcmesh2d%pos_en(:,:,1), lcmesh2d%pos_en(:,:,2), z1(:,:), elem2d%Np*lcmesh2d%Ne, &
492 sflx_mu(:,lcmesh2d%NeS:lcmesh2d%NeE), sflx_mv(:,lcmesh2d%NeS:lcmesh2d%NeE) )
498 call cal_del_flux( del_flux, &
499 sflx_mu, sflx_mv, sflx_mw, sflx_sh, &
502 lcmesh%normal_fn(:,:,3), &
503 lcmesh, elem, lcmesh2d, elem2d )
506 do ke2d=1, lcmesh2d%Ne
509 call sparsemat_matmul( lift, lcmesh%Fscale(:,ke)*del_flux(:,ke,1), liftdelflx )
510 momx_tp(:,ke) = momx_tp(:,ke) - liftdelflx(:)
512 call sparsemat_matmul( lift, lcmesh%Fscale(:,ke)*del_flux(:,ke,2), liftdelflx )
513 momy_tp(:,ke) = momy_tp(:,ke) - liftdelflx(:)
515 call sparsemat_matmul( lift, lcmesh%Fscale(:,ke)*del_flux(:,ke,3), liftdelflx )
516 momz_tp(:,ke) = momz_tp(:,ke) - liftdelflx(:)
518 call sparsemat_matmul( lift, lcmesh%Fscale(:,ke)*del_flux(:,ke,4), liftdelflx )
519 rhoh_p(:,ke) = rhoh_p(:,ke) - liftdelflx(:)
521 if ( .not. atmos_hydrometeor_dry )
then
522 sflx_qtrc(:,ke2d,i_qv) = sflx_qv(:,ke2d)
523 sflx_engi(:,ke2d) = sflx_qv(:,ke2d) * ( tracer_cv(i_qv) * sfc_temp(:,ke2d) + lhv )
525 call sparsemat_matmul( lift, lcmesh%Fscale(:,ke)*del_flux(:,ke,5), liftdelflx )
526 rhoqv_tp(:,ke) = rhoqv_tp(:,ke) - liftdelflx(:)
527 dens_tp(:,ke) = dens_tp(:,ke) - liftdelflx(:)
532 end subroutine cal_tend_from_sfcflx
535 subroutine cal_del_flux( del_flux, &
536 sflx_mu, sflx_mv, sflx_mw, sflx_sh, &
540 lmesh, elem, lmesh2D, elem2D )
542 use scale_atmos_hydrometeor,
only: &
545 use scale_tracer,
only: &
553 real(rp),
intent(out) :: del_flux(elem%nfptot*lmesh%ne,5)
554 real(rp),
intent(in) :: sflx_mu(elem2d%np,lmesh2d%nea)
555 real(rp),
intent(in) :: sflx_mv(elem2d%np,lmesh2d%nea)
556 real(rp),
intent(in) :: sflx_mw(elem2d%np,lmesh2d%nea)
557 real(rp),
intent(in) :: sflx_sh(elem2d%np,lmesh2d%nea)
558 real(rp),
intent(in) :: sflx_qv(elem2d%np,lmesh2d%nea)
559 real(rp),
intent(in) :: sfc_temp(elem2d%np,lmesh2d%nea)
560 real(rp),
intent(in) :: nz(elem%nfptot*lmesh%ne)
568 del_flux(:,:) = 0.0_rp
572 do ke2d=1, lmesh2d%Ne
574 i = elem%Nfaces_h*elem%Nfp_h + p + (ke2d-1)*elem%NfpTot
575 del_flux(i,1) = sflx_mu(p,ke2d) * nz(i)
576 del_flux(i,2) = sflx_mv(p,ke2d) * nz(i)
577 del_flux(i,3) = sflx_mw(p,ke2d) * nz(i)
578 del_flux(i,4) = sflx_sh(p,ke2d) * nz(i)
579 del_flux(i,5) = sflx_qv(p,ke2d) * nz(i)
584 if ( .not. atmos_hydrometeor_dry )
then
586 do ke2d=1, lmesh2d%Ne
588 i = elem%Nfaces_h*elem%Nfp_h + p + (ke2d-1)*elem%NfpTot
589 del_flux(i,4) = del_flux(i,4) &
590 + sflx_qv(p,ke2d) * ( tracer_cv(i_qv) * sfc_temp(p,ke2d) + 0.0_rp * lhv ) * nz(i)
597 end subroutine cal_del_flux
600 subroutine convert_uv2localorthvec( mesh, x1, x2, r, N, & ! (in)
607 integer,
intent(in) :: n
609 real(rp),
intent(in) :: x1(n)
610 real(rp),
intent(in) :: x2(n)
611 real(rp),
intent(in) :: r(n)
612 real(rp),
intent(inout) :: u(n)
613 real(rp),
intent(inout) :: v(n)
622 end subroutine convert_uv2localorthvec
625 subroutine convert_localorth2uvvec( mesh, x1, x2, r, N, & ! (in)
632 integer,
intent(in) :: n
634 real(rp),
intent(in) :: x1(n)
635 real(rp),
intent(in) :: x2(n)
636 real(rp),
intent(in) :: r(n)
637 real(rp),
intent(inout) :: u(n)
638 real(rp),
intent(inout) :: v(n)
647 end subroutine convert_localorth2uvvec
module Atmosphere / Physics / surface process
subroutine, public atmosphysfcvars_getlocalmeshfields(domid, mesh, svars_list, sflx_list, sfc_temp, sflx_mu, sflx_mv, sflx_mw, sflx_sh, sflx_lh, sflx_qv, lcmesh3d)
Get local mesh fields for surface variables.
module Atmosphere / Physics / surface process
integer, parameter sfcflx_typeid_const
Type ID of constant surface flux scheme.
module Atmosphere / Variables
module atmosphere / physics / surface / simple
subroutine, public atmos_phy_sf_simple_setup
Setup.
subroutine, public atmos_phy_sf_simple_flux(ia, is, ie, ja, js, je, atm_w, atm_u, atm_v, atm_temp, atm_pres, atm_qv, sfc_dens, sfc_temp, sfc_pres, atm_z1, sflx_mw, sflx_mu, sflx_mv, sflx_sh, sflx_lh, sflx_qv, u10, v10)
Calculate surface fluxes with constant bulk coefficients.
Module common / Coordinate conversion with cubed-sphere projection.
module FElib / Element / Base
module FElib / Mesh / Local 2D
module FElib / Mesh / Local 3D
module FElib / Mesh / Local, Base
module FElib / Data / base
module FElib / Mesh / Base 2D
module FElib / Mesh / Base 3D
module FElib / Mesh / Base
module FElib / Mesh / Cubed-sphere 3D domain
module FElib / Data / base
FElib / model framework / physics process.
FElib / model framework / mesh manager.
FElib / model framework / variable manager.
Module common / sparsemat.
Derived type to manage a computational mesh (base class)
Derived type to manage a component of surface process.
Derived type to manage variables with a surface component.
Derived type representing a 2D reference element.
Derived type representing a 3D reference element.
Derived type representing an arbitrary finite element.
Derived type representing a local mesh for 2D domain.
Derived type to manage a local 3D computational domain.
Derived type to manage a local computational domain (base type)
Derived type representing a field with local mesh (base type)
Derived type to manage a computational mesh (base type for 2D domain)
Derived type to manage a computational mesh (base type for 3D domain)
Base type to manage a computational mesh.
Derived type to manage a cubed-sphere 3D computational domain.
Derived type representing a field (base type)
Derived type to manage a sparse matrix.