Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
wall_model_bc.f90
Go to the documentation of this file.
1! Copyright (c) 2024-2026, 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 num_types, only : rp
37 use, intrinsic :: iso_c_binding, only : c_ptr
38 use utils, only : neko_error
39 use json_utils, only : json_get
40 use coefs, only : coef_t
41 use wall_model, only : wall_model_t, wall_model_allocator
43 use json_module, only : json_file
44 use user_intf, only : user_t
45 use time_state, only : time_state_t
46 implicit none
47 private
48
52 type, public, extends(shear_stress_t) :: wall_model_bc_t
54 class(wall_model_t), allocatable :: wall_model
56 type(user_t), pointer :: user => null()
57 contains
59 procedure, pass(this) :: init => wall_model_bc_init
61 procedure, pass(this) :: free => wall_model_bc_free
63 procedure, pass(this) :: finalize => wall_model_bc_finalize
64 procedure, pass(this) :: apply_scalar => wall_model_bc_apply_scalar
65 procedure, pass(this) :: apply_vector => wall_model_bc_apply_vector
66 procedure, pass(this) :: apply_scalar_dev => &
68 procedure, pass(this) :: apply_vector_dev => &
70 end type wall_model_bc_t
71
72contains
73
75 subroutine wall_model_bc_apply_scalar(this, x, n, time, strong)
76 class(wall_model_bc_t), intent(inout) :: this
77 integer, intent(in) :: n
78 real(kind=rp), intent(inout), dimension(n) :: x
79 type(time_state_t), intent(in), optional :: time
80 logical, intent(in), optional :: strong
81
82 call neko_error("The wall model bc is not applicable to scalar fields.")
83
84 end subroutine wall_model_bc_apply_scalar
85
93 subroutine wall_model_bc_apply_vector(this, x, y, z, n, time, strong)
94 class(wall_model_bc_t), intent(inout) :: this
95 integer, intent(in) :: n
96 real(kind=rp), intent(inout), dimension(n) :: x
97 real(kind=rp), intent(inout), dimension(n) :: y
98 real(kind=rp), intent(inout), dimension(n) :: z
99 type(time_state_t), intent(in), optional :: time
100 logical, intent(in), optional :: strong
101 integer :: i, m, k, fid
102 real(kind=rp) :: magtau
103 logical :: strong_
104
105 if (present(strong)) then
106 strong_ = strong
107 else
108 strong_ = .true.
109 end if
110
111 if (.not. present(time)) then
112 call neko_error("wall_model_bc_apply_vector: time is required.")
113 end if
114
115 if (.not. strong_) then
116 ! This runs inside the bc_list parallel region, so the update must be
117 ! executed by a single thread; the barrier implied by 'end single' is
118 ! what makes the tau field consistent before the Neumann bcs read it.
119 !$omp single
120 ! Compute the wall stress using the wall model.
121 call this%wall_model%compute( real(time%t, kind=rp), time%tstep)
122
123 ! Populate the 3D wall stress field for post-processing.
124 call this%wall_model%compute_mag_field()
125
126 ! Set the computed stress for application by the underlying Neumann
127 ! boundary conditions.
128 call this%set_stress(this%wall_model%tau_x, this%wall_model%tau_y, &
129 this%wall_model%tau_z)
130 !$omp end single
131 end if
132
133 ! Either add the stress to the RHS or apply the non-penetration condition
134 call this%shear_stress_t%apply_vector(x, y, z, n, time, strong_)
135
136 end subroutine wall_model_bc_apply_vector
137
140 subroutine wall_model_bc_apply_scalar_dev(this, x_d, time, strong, strm)
141 class(wall_model_bc_t), intent(inout), target :: this
142 type(c_ptr), intent(inout) :: x_d
143 type(time_state_t), intent(in), optional :: time
144 logical, intent(in), optional :: strong
145 type(c_ptr), intent(inout) :: strm
146
147 call neko_error("The wall model bc is not applicable to scalar fields.")
148
149 end subroutine wall_model_bc_apply_scalar_dev
150
153 subroutine wall_model_bc_apply_vector_dev(this, x_d, y_d, z_d, time, &
154 strong, strm)
155 class(wall_model_bc_t), intent(inout), target :: this
156 type(c_ptr), intent(inout) :: x_d
157 type(c_ptr), intent(inout) :: y_d
158 type(c_ptr), intent(inout) :: z_d
159 type(time_state_t), intent(in), optional :: time
160 logical, intent(in), optional :: strong
161 logical :: strong_
162 type(c_ptr), intent(inout) :: strm
163
164 if (present(strong)) then
165 strong_ = strong
166 else
167 strong_ = .true.
168 end if
169
170 if (.not. present(time)) then
171 call neko_error("wall_model_bc_apply_vector_dev: time is required.")
172 end if
173
174 if (.not. strong_) then
175 ! Compute the wall stress using the wall model.
176 call this%wall_model%compute( real(time%t, kind=rp), time%tstep)
177
178 ! Populate the 3D wall stress field for post-processing.
179 call this%wall_model%compute_mag_field()
180
181 ! Set the computed stress for application by the underlying Neumann
182 ! boundary conditions.
183 call this%set_stress(this%wall_model%tau_x, this%wall_model%tau_y, &
184 this%wall_model%tau_z)
185 end if
186
187 ! Either add the stress to the RHS or apply the non-penetration condition
188 call this%shear_stress_t%apply_vector_dev(x_d, y_d, z_d, &
189 time, strong_, strm)
190
191 end subroutine wall_model_bc_apply_vector_dev
192
196 subroutine wall_model_bc_init(this, coef, json)
197 class(wall_model_bc_t), target, intent(inout) :: this
198 type(coef_t), target, intent(in) :: coef
199 type(json_file), intent(inout) :: json
200 character(len=:), allocatable :: scheme_name, type_name
201 real(kind=rp) :: value(3) = [0, 0, 0]
202
203 call json_get(json, "scheme_name", scheme_name)
204 ! Initialize the shear stress base class.
205 call this%shear_stress_t%init_from_components(coef, value)
206 ! Partial initialization of the wall model by parsing the JSON.
207 call json_get(json, "model", type_name)
208 call wall_model_allocator(this%wall_model, type_name)
209 call this%wall_model%partial_init(coef, scheme_name, json)
210 end subroutine wall_model_bc_init
211
213 subroutine wall_model_bc_free(this)
214 class(wall_model_bc_t), target, intent(inout) :: this
215
216 call this%shear_stress_t%free()
217 call this%wall_model%free()
218
219 if (allocated(this%wall_model)) then
220 deallocate(this%wall_model)
221 end if
222 nullify(this%user)
223
224 end subroutine wall_model_bc_free
225
227 subroutine wall_model_bc_finalize(this)
228 class(wall_model_bc_t), target, intent(inout) :: this
229
230 call this%shear_stress_t%finalize()
231 call this%wall_model%finalize(this%facet_node_msk, this%facet)
232
233 if (associated(this%user)) then
234 call this%wall_model%finalize(this%facet_node_msk, this%facet, &
235 this%name, this%user)
236 else
237 call this%wall_model%finalize(this%facet_node_msk, this%facet, this%name)
238 end if
239 end subroutine wall_model_bc_finalize
240
241end module wall_model_bc
double real
Retrieves a parameter by name or throws an error.
Coefficients.
Definition coef.f90:34
Utilities for retrieving parameters from the case files.
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Defines a shear stress boundary condition for a vector field. Maintainer: Timofey Mukha.
Module with things related to the simulation time.
Interfaces for user interaction with NEKO.
Definition user_intf.f90:34
Utilities.
Definition utils.f90:35
Defines the wall_model_bc_t type. Maintainer: Timofey Mukha.
subroutine wall_model_bc_init(this, coef, json)
Constructor.
subroutine wall_model_bc_apply_scalar(this, x, n, time, strong)
Apply shear stress for a scalar field x.
subroutine wall_model_bc_apply_scalar_dev(this, x_d, time, strong, strm)
Boundary condition apply for a generic wall_model_bc condition to a vector x (device version)
subroutine wall_model_bc_apply_vector_dev(this, x_d, y_d, z_d, time, strong, strm)
Boundary condition apply for a generic wall_model_bc condition to vectors x, y and z (device version)
subroutine wall_model_bc_apply_vector(this, x, y, z, n, time, strong)
Apply the boundary condition to the right-hand side.
subroutine wall_model_bc_free(this)
Destructor.
subroutine wall_model_bc_finalize(this)
Finalize by building mask arrays and init'ing the wall model.
Implements wall_model_t.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:135
A shear stress boundary condition.
A struct that contains all info about the time, expand as needed.
A type collecting all the overridable user routines and flag to suppress type injection from custom m...
Base abstract type for wall-stress models for wall-modelled LES.
A shear stress boundary condition, computing the stress values using a wall model.