Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
pnpn_res_stress_cpu.f90
Go to the documentation of this file.
1
3 use gather_scatter, only : gs_t, gs_op_add
5 use field, only : field_t
6 use ax_product, only : ax_t
7 use coefs, only : coef_t
11 use mesh, only : mesh_t
12 use num_types, only : rp
13 use space, only : space_t
14 use math, only : rzero, col2, copy, invers2, cmult2
15 use, intrinsic :: iso_c_binding, only : c_ptr
16 implicit none
17 private
18
21 type, public, extends(pnpn_prs_res_t) :: pnpn_prs_res_stress_cpu_t
22 contains
23 procedure, nopass :: compute => pnpn_prs_res_stress_cpu_compute
25
28 type, public, extends(pnpn_vel_res_t) :: pnpn_vel_res_stress_cpu_t
29 contains
30 procedure, nopass :: compute => pnpn_vel_res_stress_cpu_compute
32
33contains
34
35 subroutine pnpn_prs_res_stress_cpu_compute(p, p_res, u, v, w, u_e, v_e, w_e,&
36 f_x, f_y, f_z, c_Xh, gs_Xh, bc_prs_surface, bc_sym_surface, Ax, bd, dt,&
37 mu, rho, event)
38 type(field_t), intent(inout) :: p, u, v, w
39 type(field_t), intent(in) :: u_e, v_e, w_e
40 type(field_t), intent(inout) :: p_res
41 type(field_t), intent(in) :: f_x, f_y, f_z
42 type(coef_t), intent(inout) :: c_Xh
43 type(gs_t), intent(inout) :: gs_Xh
44 type(facet_normal_t), intent(in) :: bc_prs_surface
45 type(facet_normal_t), intent(in) :: bc_sym_surface
46 class(ax_t), intent(inout) :: Ax
47 real(kind=rp), intent(in) :: bd
48 real(kind=rp), intent(in) :: dt
49 type(field_t), intent(in) :: mu
50 type(field_t), intent(in) :: rho
51 type(c_ptr), intent(inout) :: event
52 real(kind=rp) :: dtbd
53 real(kind=rp) :: w1, w2, w3
54 integer :: n
55 integer :: i
56 ! Work arrays
57 type(field_t), pointer :: ta1, ta2, ta3, wa1, wa2, wa3, work1, work2
58 type(field_t), pointer :: s11, s22, s33, s12, s13, s23
59 integer :: temp_indices(14)
60
61 ! Work arrays
62 call neko_scratch_registry%request_field(ta1, temp_indices(1), .false.)
63 call neko_scratch_registry%request_field(ta2, temp_indices(2), .false.)
64 call neko_scratch_registry%request_field(ta3, temp_indices(3), .false.)
65 call neko_scratch_registry%request_field(wa1, temp_indices(4), .false.)
66 call neko_scratch_registry%request_field(wa2, temp_indices(5), .false.)
67 call neko_scratch_registry%request_field(wa3, temp_indices(6), .false.)
68 call neko_scratch_registry%request_field(work1, temp_indices(7), .false.)
69 call neko_scratch_registry%request_field(work2, temp_indices(8), .false.)
70
71 ! Stress tensor
72 call neko_scratch_registry%request_field(s11, temp_indices(9), .false.)
73 call neko_scratch_registry%request_field(s22, temp_indices(10), .false.)
74 call neko_scratch_registry%request_field(s33, temp_indices(11), .false.)
75 call neko_scratch_registry%request_field(s12, temp_indices(12), .false.)
76 call neko_scratch_registry%request_field(s13, temp_indices(13), .false.)
77 call neko_scratch_registry%request_field(s23, temp_indices(14), .false.)
78
79 n = c_xh%dof%size()
80
81 call invers2(c_xh%h1, rho%x, n)
82 call rzero(c_xh%h2, n)
83 c_xh%ifh2 = .false.
84
85 ! mu times the double curl of the velocity
86 call curl(ta1, ta2, ta3, u_e, v_e, w_e, work1, work2, c_xh)
87 call curl(wa1, wa2, wa3, ta1, ta2, ta3, work1, work2, c_xh)
88
89 call col2(wa1%x, mu%x, n)
90 call col2(wa2%x, mu%x, n)
91 call col2(wa3%x, mu%x, n)
92
93
94 ! The strain rate tensor
95 call strain_rate(s11%x, s22%x, s33%x, s12%x, s13%x, s23%x, &
96 u_e%x, v_e%x, w_e%x, c_xh)
97
98
99 ! Gradient of viscosity
100 call dudxyz(ta1%x, mu%x, c_xh%drdx, c_xh%dsdx, c_xh%dtdx, c_xh)
101 call dudxyz(ta2%x, mu%x, c_xh%drdy, c_xh%dsdy, c_xh%dtdy, c_xh)
102 call dudxyz(ta3%x, mu%x, c_xh%drdz, c_xh%dsdz, c_xh%dtdz, c_xh)
103
104 ! Subtract the two terms of the viscous stress to get
105 ! \nabla x \nabla u - S^T \nabla \mu, and form
106 ! ta = f / rho - (wa / rho) * B from it. The sign is consistent with
107 ! the fact that we subtract the term below.
108 !
109 ! This mirrors prs_stress_res_part1 on the device backends: the whole
110 ! block is a single pass rather than a chain of cmult/vdot3/sub2 calls.
111 ! wa1..wa3 are dead from here until cdtp overwrites them below, so the
112 ! viscous stress is kept in registers instead of being written back.
113 !OCL NORECURRENCE, NOVREC, NOALIAS
114 !DIR$ CONCURRENT
115 !DIR$ IVDEP
116 !GCC$ ivdep
117 !$omp parallel do private(i, w1, w2, w3)
118 do i = 1, n
119 w1 = wa1%x(i,1,1,1) - 2.0_rp * (ta1%x(i,1,1,1) * s11%x(i,1,1,1) &
120 + ta2%x(i,1,1,1) * s12%x(i,1,1,1) &
121 + ta3%x(i,1,1,1) * s13%x(i,1,1,1))
122 w2 = wa2%x(i,1,1,1) - 2.0_rp * (ta1%x(i,1,1,1) * s12%x(i,1,1,1) &
123 + ta2%x(i,1,1,1) * s22%x(i,1,1,1) &
124 + ta3%x(i,1,1,1) * s23%x(i,1,1,1))
125 w3 = wa3%x(i,1,1,1) - 2.0_rp * (ta1%x(i,1,1,1) * s13%x(i,1,1,1) &
126 + ta2%x(i,1,1,1) * s23%x(i,1,1,1) &
127 + ta3%x(i,1,1,1) * s33%x(i,1,1,1))
128
129 ta1%x(i,1,1,1) = f_x%x(i,1,1,1) / rho%x(i,1,1,1) &
130 - ((w1 / rho%x(i,1,1,1)) * c_xh%B(i,1,1,1))
131 ta2%x(i,1,1,1) = f_y%x(i,1,1,1) / rho%x(i,1,1,1) &
132 - ((w2 / rho%x(i,1,1,1)) * c_xh%B(i,1,1,1))
133 ta3%x(i,1,1,1) = f_z%x(i,1,1,1) / rho%x(i,1,1,1) &
134 - ((w3 / rho%x(i,1,1,1)) * c_xh%B(i,1,1,1))
135 end do
136 !$omp end parallel do
137
138 call rotate_cyc(ta1%x, ta2%x, ta3%x, 1, c_xh)
139 call gs_xh%op(ta1%x, ta2%x, ta3%x, n, gs_op_add)
140 call rotate_cyc(ta1%x, ta2%x, ta3%x, 0, c_xh)
141
142 !OCL NORECURRENCE, NOVREC, NOALIAS
143 !DIR$ CONCURRENT
144 !DIR$ IVDEP
145 !GCC$ ivdep
146 !$omp parallel do
147 do i = 1, n
148 ta1%x(i,1,1,1) = ta1%x(i,1,1,1) * c_xh%Binv(i,1,1,1)
149 ta2%x(i,1,1,1) = ta2%x(i,1,1,1) * c_xh%Binv(i,1,1,1)
150 ta3%x(i,1,1,1) = ta3%x(i,1,1,1) * c_xh%Binv(i,1,1,1)
151 end do
152 !$omp end parallel do
153
154 ! Compute the components of the divergence of the rhs
155 call cdtp(wa1%x, ta1%x, c_xh%drdx, c_xh%dsdx, c_xh%dtdx, c_xh)
156 call cdtp(wa2%x, ta2%x, c_xh%drdy, c_xh%dsdy, c_xh%dtdy, c_xh)
157 call cdtp(wa3%x, ta3%x, c_xh%drdz, c_xh%dsdz, c_xh%dtdz, c_xh)
158
159 ! The laplacian of the pressure
160 call ax%compute(p_res%x, p%x, c_xh, p%msh, p%Xh)
161
162 !$omp parallel private (i)
163 !OCL NORECURRENCE, NOVREC, NOALIAS
164 !DIR$ CONCURRENT
165 !DIR$ IVDEP
166 !GCC$ ivdep
167 !$omp do
168 do i = 1, n
169 p_res%x(i,1,1,1) = (-p_res%x(i,1,1,1)) &
170 + wa1%x(i,1,1,1) + wa2%x(i,1,1,1) + wa3%x(i,1,1,1)
171 end do
172 !$omp end do
173
174 !
175 ! Surface velocity terms
176 !
177 !OCL NORECURRENCE, NOVREC, NOALIAS
178 !DIR$ CONCURRENT
179 !DIR$ IVDEP
180 !GCC$ ivdep
181 !$omp do
182 do i = 1, n
183 wa1%x(i,1,1,1) = 0.0_rp
184 wa2%x(i,1,1,1) = 0.0_rp
185 wa3%x(i,1,1,1) = 0.0_rp
186 end do
187 !$omp end do
188 !$omp end parallel
189
190 call bc_sym_surface%apply_surfvec(wa1%x, wa2%x, wa3%x, ta1%x, ta2%x, ta3%x,&
191 n)
192
193 dtbd = bd / dt
194 !OCL NORECURRENCE, NOVREC, NOALIAS
195 !DIR$ CONCURRENT
196 !DIR$ IVDEP
197 !GCC$ ivdep
198 !$omp parallel do
199 do i = 1, n
200 ta1%x(i,1,1,1) = 0.0_rp
201 ta2%x(i,1,1,1) = 0.0_rp
202 ta3%x(i,1,1,1) = 0.0_rp
203 end do
204 !$omp end parallel do
205
206 call bc_prs_surface%apply_surfvec(ta1%x, ta2%x, ta3%x, u%x, v%x, w%x, n)
207
208 !OCL NORECURRENCE, NOVREC, NOALIAS
209 !DIR$ CONCURRENT
210 !DIR$ IVDEP
211 !GCC$ ivdep
212 !$omp parallel do
213 do i = 1, n
214 p_res%x(i,1,1,1) = p_res%x(i,1,1,1) &
215 - (dtbd * (ta1%x(i,1,1,1) + ta2%x(i,1,1,1) + ta3%x(i,1,1,1)))&
216 - (wa1%x(i,1,1,1) + wa2%x(i,1,1,1) + wa3%x(i,1,1,1))
217 end do
218 !$omp end parallel do
219
220 call neko_scratch_registry%relinquish_field(temp_indices)
221
223
224 subroutine pnpn_vel_res_stress_cpu_compute(Ax, u, v, w, u_res, v_res, w_res, &
225 p, f_x, f_y, f_z, c_Xh, msh, Xh, mu, rho, bd, dt, n)
226 class(ax_t), intent(in) :: Ax
227 type(mesh_t), intent(inout) :: msh
228 type(space_t), intent(inout) :: Xh
229 type(field_t), intent(inout) :: p, u, v, w
230 type(field_t), intent(inout) :: u_res, v_res, w_res
231 type(field_t), intent(in) :: f_x, f_y, f_z
232 type(coef_t), intent(inout) :: c_Xh
233 type(field_t), intent(in) :: mu
234 type(field_t), intent(in) :: rho
235 real(kind=rp), intent(in) :: bd
236 real(kind=rp), intent(in) :: dt
237 integer :: temp_indices(3)
238 type(field_t), pointer :: ta1, ta2, ta3
239 integer, intent(in) :: n
240 integer :: i
241
242 call copy(c_xh%h1, mu%x, n)
243 call cmult2(c_xh%h2, rho%x, bd / dt, n)
244 c_xh%ifh2 = .true.
245
246 ! Viscous stresses
247 call ax%compute_vector(u_res%x, v_res%x, w_res%x, u%x, v%x, w%x, c_xh,&
248 msh, xh)
249
250 call neko_scratch_registry%request_field(ta1, temp_indices(1), .false.)
251 call neko_scratch_registry%request_field(ta2, temp_indices(2), .false.)
252 call neko_scratch_registry%request_field(ta3, temp_indices(3), .false.)
253
254 ! Pressure gradient
255 call opgrad(ta1%x, ta2%x, ta3%x, p%x, c_xh)
256
257 ! Sum all the terms
258 !OCL NORECURRENCE, NOVREC, NOALIAS
259 !DIR$ CONCURRENT
260 !DIR$ IVDEP
261 !GCC$ ivdep
262 !$omp parallel do
263 do i = 1, n
264 u_res%x(i,1,1,1) = (-u_res%x(i,1,1,1)) - ta1%x(i,1,1,1) + f_x%x(i,1,1,1)
265 v_res%x(i,1,1,1) = (-v_res%x(i,1,1,1)) - ta2%x(i,1,1,1) + f_y%x(i,1,1,1)
266 w_res%x(i,1,1,1) = (-w_res%x(i,1,1,1)) - ta3%x(i,1,1,1) + f_z%x(i,1,1,1)
267 end do
268 !$omp end parallel do
269
270 call neko_scratch_registry%relinquish_field(temp_indices)
271
273
274end module pnpn_res_stress_cpu
Compute derivative of a scalar field along a single direction.
Definition operators.f90:79
Apply cyclic boundary condition to a vector field.
Compute the strain rate tensor of a vector field.
Defines a Matrix-vector product.
Definition ax.f90:34
Coefficients.
Definition coef.f90:34
Dirichlet condition applied in the facet normal direction.
Defines a field.
Definition field.f90:34
Gather-scatter.
Definition math.f90:60
subroutine, public cmult2(a, b, c, n)
Multiplication by constant c .
Definition math.f90:522
subroutine, public invers2(a, b, n)
Compute inverted vector .
Definition math.f90:803
subroutine, public col2(a, b, n)
Vector multiplication .
Definition math.f90:1049
subroutine, public copy(a, b, n)
Copy a vector .
Definition math.f90:294
subroutine, public rzero(a, n)
Zero a real vector.
Definition math.f90:238
Defines a mesh.
Definition mesh.f90:34
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Operators.
Definition operators.f90:34
subroutine, public opgrad(ux, uy, uz, u, coef, es, ee)
Compute the weak gradient of a scalar field, i.e. the gradient multiplied by the mass matrix.
subroutine, public curl(w1, w2, w3, u1, u2, u3, work1, work2, coef, event)
subroutine, public cdtp(dtx, x, dr, ds, dt, coef, es, ee)
Apply D^T to a scalar field, where D is the derivative matrix.
Residuals in the Pn-Pn formulation (CPU version)
subroutine pnpn_prs_res_stress_cpu_compute(p, p_res, u, v, w, u_e, v_e, w_e, f_x, f_y, f_z, c_xh, gs_xh, bc_prs_surface, bc_sym_surface, ax, bd, dt, mu, rho, event)
subroutine pnpn_vel_res_stress_cpu_compute(ax, u, v, w, u_res, v_res, w_res, p, f_x, f_y, f_z, c_xh, msh, xh, mu, rho, bd, dt, n)
Defines Pressure and velocity residuals in the Pn-Pn formulation.
Definition pnpn_res.f90:34
Defines a registry for storing and requesting temporary objects This can be used when you have a func...
type(scratch_registry_t), target, public neko_scratch_registry
Global scratch registry.
Defines a function space.
Definition space.f90:34
Base type for a matrix-vector product providing .
Definition ax.f90:43
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:93
Dirichlet condition in facet normal direction.
Gather-scatter kernel.
CPU implementation of the pressure residual for the PnPn fluid with full viscous stress formulation.
CPU implementation of the velocity residual for the PnPn fluid with full viscous stress formulation.
Abstract type to compute pressure residual.
Definition pnpn_res.f90:48
Abstract type to compute velocity residual.
Definition pnpn_res.f90:54
The function space for the SEM solution fields.
Definition space.f90:64