Neko 1.99.3
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
dong_outflow.f90
Go to the documentation of this file.
1! Copyright (c) 2022-2025, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
36 use dirichlet, only : dirichlet_t
38 use num_types, only : rp, c_rp
39 use bc, only : bc_t
40 use field, only : field_t
41 use dofmap, only : dofmap_t
42 use coefs, only : coef_t
43 use utils, only : nonlinear_index
45 use registry, only : neko_registry
46 use, intrinsic :: iso_c_binding, only : c_ptr, c_sizeof, c_null_ptr, &
47 c_associated
48 use json_module, only : json_file
50 use utils, only : neko_error
51 use time_state, only : time_state_t
52 implicit none
53 private
54
60 type, public, extends(bc_t) :: dong_outflow_t
61 type(field_t), pointer :: u
62 type(field_t), pointer :: v
63 type(field_t), pointer :: w
64 real(kind=rp) :: delta
65 real(kind=rp) :: uinf
66 type(c_ptr) :: normal_x_d = c_null_ptr
67 type(c_ptr) :: normal_y_d = c_null_ptr
68 type(c_ptr) :: normal_z_d = c_null_ptr
69 contains
70 procedure, pass(this) :: apply_scalar => dong_outflow_apply_scalar
71 procedure, pass(this) :: apply_vector => dong_outflow_apply_vector
72 procedure, pass(this) :: apply_scalar_dev => dong_outflow_apply_scalar_dev
73 procedure, pass(this) :: apply_vector_dev => dong_outflow_apply_vector_dev
75 procedure, pass(this) :: init => dong_outflow_init
77 procedure, pass(this) :: free => dong_outflow_free
79 procedure, pass(this) :: finalize => dong_outflow_finalize
80 end type dong_outflow_t
81
82contains
86 subroutine dong_outflow_init(this, coef, json)
87 class(dong_outflow_t), target, intent(inout) :: this
88 type(coef_t), target, intent(in) :: coef
89 type(json_file), intent(inout) :: json
90 call this%free()
91 call this%init_base(coef)
92
93 call json_get_or_default(json, 'delta', this%delta, 0.01_rp)
94 call json_get_or_default(json, 'velocity_scale', this%uinf, 1.0_rp)
95
96 end subroutine dong_outflow_init
97
100 subroutine dong_outflow_apply_scalar(this, x, n, time, strong)
101 class(dong_outflow_t), intent(inout) :: this
102 integer, intent(in) :: n
103 real(kind=rp), intent(inout), dimension(n) :: x
104 type(time_state_t), intent(in), optional :: time
105 logical, intent(in), optional :: strong
106 integer :: i, m, k, facet, idx(4)
107 real(kind=rp) :: vn, s0, ux, uy, uz, normal_xyz(3)
108 logical :: strong_
109
110 if (present(strong)) then
111 strong_ = strong
112 else
113 strong_ = .true.
114 end if
115
116 !Im actually not sure what to do if one has two dong that share a corner.
117 if (strong_) then
118 m = this%msk(0)
119 !$omp parallel do private(k, facet, ux, uy, uz, idx, normal_xyz, vn, S0)
120 do i = 1, m
121 k = this%msk(i)
122 facet = this%facet(i)
123 ux = this%u%x(k,1,1,1)
124 uy = this%v%x(k,1,1,1)
125 uz = this%w%x(k,1,1,1)
126 idx = nonlinear_index(k, this%Xh%lx, this%Xh%lx, this%Xh%lx)
127 normal_xyz = this%coef%get_normal(idx(1), idx(2), idx(3), idx(4), &
128 facet)
129 vn = ux*normal_xyz(1) + uy*normal_xyz(2) + uz*normal_xyz(3)
130 s0 = 0.5_rp*(1.0_rp - tanh(vn / (this%uinf * this%delta)))
131
132 x(k) = -0.5*(ux*ux+uy*uy+uz*uz)*s0
133 end do
134 !$omp end parallel do
135 end if
136 end subroutine dong_outflow_apply_scalar
137
140 subroutine dong_outflow_apply_vector(this, x, y, z, n, time, strong)
141 class(dong_outflow_t), intent(inout) :: this
142 integer, intent(in) :: n
143 real(kind=rp), intent(inout), dimension(n) :: x
144 real(kind=rp), intent(inout), dimension(n) :: y
145 real(kind=rp), intent(inout), dimension(n) :: z
146 type(time_state_t), intent(in), optional :: time
147 logical, intent(in), optional :: strong
148
149 end subroutine dong_outflow_apply_vector
150
153 subroutine dong_outflow_apply_scalar_dev(this, x_d, time, strong, strm)
154 class(dong_outflow_t), intent(inout), target :: this
155 type(c_ptr), intent(inout) :: x_d
156 type(time_state_t), intent(in), optional :: time
157 logical, intent(in), optional :: strong
158 type(c_ptr), intent(inout) :: strm
159 logical :: strong_
160
161 if (present(strong)) then
162 strong_ = strong
163 else
164 strong_ = .true.
165 end if
166
167 if (strong_ .and. this%msk(0) .gt. 0) then
168 call device_dong_outflow_apply_scalar(this%msk_d, x_d, &
169 this%normal_x_d, this%normal_y_d, this%normal_z_d, &
170 this%u%x_d, this%v%x_d, this%w%x_d, &
171 this%uinf, this%delta, &
172 this%msk(0), strm)
173 end if
174
175 end subroutine dong_outflow_apply_scalar_dev
176
179 subroutine dong_outflow_apply_vector_dev(this, x_d, y_d, z_d, time, &
180 strong, strm)
181 class(dong_outflow_t), intent(inout), target :: this
182 type(c_ptr), intent(inout) :: x_d
183 type(c_ptr), intent(inout) :: y_d
184 type(c_ptr), intent(inout) :: z_d
185 type(time_state_t), intent(in), optional :: time
186 logical, intent(in), optional :: strong
187 type(c_ptr), intent(inout) :: strm
188
189 !call device_dong_outflow_apply_vector(this%msk_d, x_d, y_d, z_d, &
190 ! this%g, size(this%msk))
191
192 end subroutine dong_outflow_apply_vector_dev
193
195 subroutine dong_outflow_free(this)
196 class(dong_outflow_t), target, intent(inout) :: this
197
198 call this%free_base
199 nullify(this%u)
200 nullify(this%v)
201 nullify(this%w)
202
203 if (c_associated(this%normal_x_d)) then
204 call device_free(this%normal_x_d)
205 this%normal_x_d = c_null_ptr
206 end if
207
208 if (c_associated(this%normal_y_d)) then
209 call device_free(this%normal_y_d)
210 this%normal_y_d = c_null_ptr
211 end if
212
213 if (c_associated(this%normal_z_d)) then
214 call device_free(this%normal_z_d)
215 this%normal_z_d = c_null_ptr
216 end if
217
218 end subroutine dong_outflow_free
219
221 subroutine dong_outflow_finalize(this, only_facets)
222 class(dong_outflow_t), target, intent(inout) :: this
223 logical, optional, intent(in) :: only_facets
224 real(kind=rp), allocatable :: temp_x(:)
225 real(kind=rp), allocatable :: temp_y(:)
226 real(kind=rp), allocatable :: temp_z(:)
227 real(c_rp) :: dummy
228 integer :: i, m, k, facet, idx(4)
229 real(kind=rp) :: normal_xyz(3)
230
231 if (present(only_facets)) then
232 if (.not. only_facets) then
233 call neko_error("For dong_outflow_t, only_facets has to be true.")
234 end if
235 end if
236
237 call this%finalize_base(.true.)
238
239 this%u => neko_registry%get_field("u")
240 this%v => neko_registry%get_field("v")
241 this%w => neko_registry%get_field("w")
242 if ((neko_bcknd_device .eq. 1) .and. (this%msk(0) .gt. 0)) then
243 call device_alloc(this%normal_x_d, c_sizeof(dummy)*this%msk(0))
244 call device_alloc(this%normal_y_d, c_sizeof(dummy)*this%msk(0))
245 call device_alloc(this%normal_z_d, c_sizeof(dummy)*this%msk(0))
246 m = this%msk(0)
247 allocate(temp_x(m))
248 allocate(temp_y(m))
249 allocate(temp_z(m))
250 !$omp parallel do private(k, facet, idx, normal_xyz)
251 do i = 1, m
252 k = this%msk(i)
253 facet = this%facet(i)
254 idx = nonlinear_index(k, this%Xh%lx, this%Xh%lx, this%Xh%lx)
255 normal_xyz = &
256 this%coef%get_normal(idx(1), idx(2), idx(3), idx(4), facet)
257 temp_x(i) = normal_xyz(1)
258 temp_y(i) = normal_xyz(2)
259 temp_z(i) = normal_xyz(3)
260 end do
261 !$omp end parallel do
262 call device_memcpy(temp_x, this%normal_x_d, m, host_to_device, &
263 sync = .false.)
264 call device_memcpy(temp_y, this%normal_y_d, m, host_to_device, &
265 sync = .false.)
266 call device_memcpy(temp_z, this%normal_z_d, m, host_to_device, &
267 sync = .true.)
268 deallocate( temp_x, temp_y, temp_z)
269 end if
270 end subroutine dong_outflow_finalize
271
272end module dong_outflow
__inline__ __device__ void nonlinear_index(const int idx, const int lx, int *index)
Definition bc_utils.h:44
Copy data between host and device (or device and device)
Definition device.F90:71
Retrieves a parameter by name or assigns a provided default value. In the latter case also adds the m...
Retrieves a parameter by name or throws an error.
Defines a boundary condition.
Definition bc.f90:34
Coefficients.
Definition coef.f90:34
subroutine, public device_dong_outflow_apply_scalar(msk, x, normal_x, normal_y, normal_z, u, v, w, uinf, delta, m, strm)
Device abstraction, common interface for various accelerators.
Definition device.F90:34
integer, parameter, public host_to_device
Definition device.F90:47
subroutine, public device_free(x_d)
Deallocate memory on the device.
Definition device.F90:225
subroutine, public device_alloc(x_d, s)
Allocate memory on the device.
Definition device.F90:198
Defines a dirichlet boundary condition.
Definition dirichlet.f90:34
Defines a mapping of the degrees of freedom.
Definition dofmap.f90:35
Defines a dong outflow condition.
subroutine dong_outflow_apply_vector_dev(this, x_d, y_d, z_d, time, strong, strm)
Boundary condition apply for a generic Dirichlet condition to vectors x, y and z (device version)
subroutine dong_outflow_apply_vector(this, x, y, z, n, time, strong)
Boundary condition apply for a generic Dirichlet condition to vectors x, y and z.
subroutine dong_outflow_apply_scalar_dev(this, x_d, time, strong, strm)
Boundary condition apply for a generic Dirichlet condition to a vector x (device version)
subroutine dong_outflow_free(this)
Destructor.
subroutine dong_outflow_apply_scalar(this, x, n, time, strong)
Boundary condition apply for a generic Dirichlet condition to a vector x.
subroutine dong_outflow_init(this, coef, json)
Constructor.
subroutine dong_outflow_finalize(this, only_facets)
Finalize.
Defines a field.
Definition field.f90:34
Utilities for retrieving parameters from the case files.
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter, public c_rp
Definition num_types.f90:13
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Defines a registry for storing solution fields.
Definition registry.f90:34
type(registry_t), target, public neko_registry
Global field registry.
Definition registry.f90:144
Module with things related to the simulation time.
Utilities.
Definition utils.f90:35
Base type for a boundary condition.
Definition bc.f90:62
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:62
Generic Dirichlet boundary condition on .
Definition dirichlet.f90:49
Dong outflow condition Follows "A Convective-like Energy-Stable Open Boundary Condition for Simulati...
A struct that contains all info about the time, expand as needed.