FE-Project
Loading...
Searching...
No Matches
scale_meshutil_vcoord.F90
Go to the documentation of this file.
1!-------------------------------------------------------------------------------
9#include "scaleFElib.h"
11 !-----------------------------------------------------------------------------
12 !
13 !++ used modules
14 !
15 use scale_const, only: &
16 pi => const_pi, &
17 eps => const_eps
18 use scale_precision
19 use scale_prc
20 use scale_io
21 use scale_prc
22
25 use scale_element_base, only: &
27 use scale_sparsemat, only:&
29 !-----------------------------------------------------------------------------
30 implicit none
31 private
32
33 !-----------------------------------------------------------------------------
34 !
35 !++ Public type & procedure
36 !
39
40 !-----------------------------------------------------------------------------
41 !
42 !++ Public parameters & variables
43 !
44 character(*), public, parameter :: mesh_vcoord_terrain_following_name = "TERRAIN_FOLLOWING"
45 integer, public, parameter :: mesh_vcoord_terrain_following_id = 1
46
47 !-----------------------------------------------------------------------------
48 !
49 !++ Private type & procedure
50 !
51 !-----------------------------------------------------------------------------
52
53 !-----------------------------------------------------------------------------
54 !
55 !++ Private parameters & variables
56 !
57 !-----------------------------------------------------------------------------
58
59contains
60!OCL SERIAL
61 function meshutil_get_vcoord_typeid( vcoord_type ) result( vcoord_id )
62 implicit none
63
64 character(len=*), intent(in) :: vcoord_type
65 integer :: vcoord_id
66
67 select case( vcoord_type )
70 case default
71 log_error("MeshUtil_VCoord_TypeID",*) "vcoord_type is inappropriate. Check!", vcoord_type
72 call prc_abort
73 end select
74
75 return
77
78!OCL SERIAL
79 subroutine meshutil_vcoord_getmetric( G13, G23, zlev, GsqrtV, &
80 topo, zTop, vcoord_id, lcmesh, elem, lcmesh2D, elem2D, &
81 Dx2D, Dy2D, Lift2D )
82 implicit none
83
84 class(localmesh3d), intent(in) :: lcmesh
85 class(elementbase3d), intent(in) :: elem
86 class(localmesh2d), intent(in) :: lcmesh2d
87 class(elementbase2d), intent(in) :: elem2d
88 real(rp), intent(out) :: g13(elem%np,lcmesh%nea)
89 real(rp), intent(out) :: g23(elem%np,lcmesh%nea)
90 real(rp), intent(out) :: zlev(elem%np,lcmesh%nea)
91 real(rp), intent(inout) :: gsqrtv(elem%np,lcmesh%nea)
92 real(rp), intent(in) :: topo(elem2d%np,lcmesh2d%nea)
93 integer, intent(in) :: vcoord_id
94 real(rp), intent(in) :: ztop
95 type(sparsemat), intent(in) :: dx2d
96 type(sparsemat), intent(in) :: dy2d
97 type(sparsemat), intent(in) :: lift2d
98
99 integer :: ke, ke2d
100 real(rp) :: del_flux(elem2d%nfptot,lcmesh2d%ne,2)
101 real(rp) :: fx2d(elem2d%np), fy2d(elem2d%np), liftdelflux2d(elem2d%np)
102 real(rp) :: gradzs(elem2d%np,lcmesh2d%ne,2)
103 real(rp) :: coef3d(elem%np)
104 !------------------------------------------------
105
106 if ( vcoord_id == mesh_vcoord_terrain_following_id ) then
107
108 ! * z = topo + (1 - topo / zTop ) * zeta
109 ! * zeta = zTop * (z - topo)/(zTop - topo)
110 ! * Gi3 = (dzeta(x1,x2,z)/dxi)_z = d (zeta,z) / d (xi,z) = - d(z,zeta)/ d(xi,zeta) * d(xi,zeta)/d(xi,z)
111 ! = - (dz/dxi)_zeta * dzeta/dz
112 ! = (GsqrtV)^-1 * [ - 1 + zeta / zTop ] * d topo /dxi (i=1, 2)
113
114 call cal_del_flux( del_flux, &
115 topo, lcmesh2d%normal_fn(:,:,1), lcmesh2d%normal_fn(:,:,2), &
116 lcmesh2d%VMapM, lcmesh2d%VMapP, lcmesh2d, elem2d )
117
118 !$omp parallel private(ke2D, ke, &
119 !$omp Fx2D, Fy2D, LiftDelFlux2D, coef3D )
120
121 !$omp do
122 do ke2d=1, lcmesh2d%Ne
123 call sparsemat_matmul( dx2d, topo(:,ke2d), fx2d )
124 call sparsemat_matmul( lift2d, lcmesh2d%Fscale(:,ke2d) * del_flux(:,ke2d,1), liftdelflux2d)
125 gradzs(:,ke2d,1) = lcmesh2d%Escale(:,ke2d,1,1) * fx2d(:) + liftdelflux2d(:)
126
127 call sparsemat_matmul( dy2d, topo(:,ke2d), fy2d )
128 call sparsemat_matmul( lift2d, lcmesh2d%Fscale(:,ke2d) * del_flux(:,ke2d,2), liftdelflux2d)
129 gradzs(:,ke2d,2) = lcmesh2d%Escale(:,ke2d,2,2) * fy2d(:) + liftdelflux2d(:)
130 end do
131 !$omp end do
132
133 !$omp do
134 do ke=1, lcmesh%Ne
135 ke2d = lcmesh%EMap3Dto2D(ke)
136 coef3d(:) = 1.0_rp - lcmesh%pos_en(:,ke,3) / ztop
137 zlev(:,ke) = lcmesh%pos_en(:,ke,3) &
138 + coef3d(:) * topo(elem%IndexH2Dto3D,ke2d)
139
140 gsqrtv(:,ke) = 1.0_rp - topo(elem%IndexH2Dto3D,ke2d) / ztop ! dz/dzeta
141 coef3d(:) = - coef3d(:) / gsqrtv(:,ke)
142 g13(:,ke) = coef3d(:) * gradzs(elem%IndexH2Dto3D(:),ke2d,1)
143 g23(:,ke) = coef3d(:) * gradzs(elem%IndexH2Dto3D(:),ke2d,2)
144 end do
145 !$omp end do
146 !$omp end parallel
147 else
148 log_error("Mesh_VCoord_GetMetric",*) "vcoord_id is inappropriate. Check!", vcoord_id
149 call prc_abort
150 end if
151
152 return
153 end subroutine meshutil_vcoord_getmetric
154
155!OCL SERIAL
156 subroutine cal_del_flux( del_flux, &
157 topo, nx, ny, vmapM, vmapP, lmesh, elem )
158 implicit none
159 type(localmesh2d), intent(in) :: lmesh
160 type(elementbase2d), intent(in) :: elem
161 real(rp), intent(out) :: del_flux(elem%nfptot*lmesh%ne,2)
162 real(rp), intent(in) :: topo(elem%np*lmesh%nea)
163 real(rp), intent(in) :: nx(elem%nfptot*lmesh%ne)
164 real(rp), intent(in) :: ny(elem%nfptot*lmesh%ne)
165 integer, intent(in) :: vmapm(elem%nfptot*lmesh%ne)
166 integer, intent(in) :: vmapp(elem%nfptot*lmesh%ne)
167
168 integer :: i
169 integer :: ip, im
170 real(rp) :: dtopo
171 !-------------------------------------
172
173 !$omp parallel do private( i, iM, iP, dtopo )
174 do i=1, elem%NfpTot * lmesh%Ne
175 im = vmapm(i); ip = vmapp(i)
176
177 dtopo = 0.5_rp * ( topo(ip) - topo(im) )
178
179 del_flux(i,1) = dtopo * nx(i)
180 del_flux(i,2) = dtopo * ny(i)
181 end do
182
183 return
184 end subroutine cal_del_flux
185end module scale_meshutil_vcoord
module FElib / Element / Base
module FElib / Mesh / Local 2D
module FElib / Mesh / Local 3D
module FElib / Mesh / utility for general vertical coordinate
integer function, public meshutil_get_vcoord_typeid(vcoord_type)
character(*), parameter, public mesh_vcoord_terrain_following_name
integer, parameter, public mesh_vcoord_terrain_following_id
subroutine, public meshutil_vcoord_getmetric(g13, g23, zlev, gsqrtv, topo, ztop, vcoord_id, lcmesh, elem, lcmesh2d, elem2d, dx2d, dy2d, lift2d)
module common / sparsemat