Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
symmetry_aligned.f90
Go to the documentation of this file.
1! Copyright (c) 2020-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 num_types, only : rp
38 use tuple, only : tuple_i4_t
39 use coefs, only : coef_t
40 use json_module, only : json_file
42 use, intrinsic :: iso_c_binding, only : c_ptr
43 use time_state, only : time_state_t
44 implicit none
45 private
46
51 type, public, extends(bc_t) :: symmetry_aligned_t
53 type(zero_dirichlet_t) :: bc_x
54 type(zero_dirichlet_t) :: bc_y
55 type(zero_dirichlet_t) :: bc_z
56 contains
58 procedure, pass(this) :: apply_scalar => symmetry_aligned_apply_scalar
60 procedure, pass(this) :: apply_vector => symmetry_aligned_apply_vector
62 procedure, pass(this) :: apply_scalar_dev => &
65 procedure, pass(this) :: apply_vector_dev => &
68 procedure, pass(this) :: init => symmetry_aligned_init
70 procedure, pass(this) :: init_from_components => &
73 procedure, pass(this) :: free => symmetry_aligned_free
75 procedure, pass(this) :: get_normal_axis => &
78 procedure, pass(this) :: finalize => symmetry_aligned_finalize
79 end type symmetry_aligned_t
80
81contains
82
86 subroutine symmetry_aligned_init(this, coef, json)
87 class(symmetry_aligned_t), intent(inout), target :: this
88 type(coef_t), target, intent(in) :: coef
89 type(json_file), intent(inout) :: json
90
91 call this%init_from_components(coef)
92 end subroutine symmetry_aligned_init
93
97 class(symmetry_aligned_t), intent(inout), target :: this
98 type(coef_t), target, intent(in) :: coef
99
100 call this%free()
101
102 call this%init_base(coef)
103 this%bc_type = bc_mixed_constrains_normal
104 call this%bc_x%init_from_components(this%coef)
105 call this%bc_y%init_from_components(this%coef)
106 call this%bc_z%init_from_components(this%coef)
108
113 class(symmetry_aligned_t), target, intent(inout) :: this
114 integer :: i, facet, el
115 type(tuple_i4_t), pointer :: bfp(:)
116 real(kind=rp) :: sx, sy, sz
117 real(kind=rp), parameter :: tol = 1e-3_rp
118 type(tuple_i4_t) :: bc_facet
119
120 call this%finalize_base()
121
122 associate(c => this%coef, nx => this%coef%nx, ny => this%coef%ny, &
123 nz => this%coef%nz)
124 bfp => this%marked_facet%array()
125 do i = 1, this%marked_facet%size()
126 bc_facet = bfp(i)
127 facet = bc_facet%x(1)
128 el = bc_facet%x(2)
129 call this%get_normal_axis(sx, sy, sz, facet, el)
130
131 if (sx .lt. tol) call this%bc_x%mark_facet(facet, el)
132 if (sy .lt. tol) call this%bc_y%mark_facet(facet, el)
133 if (sz .lt. tol) call this%bc_z%mark_facet(facet, el)
134 end do
135 end associate
136 call this%bc_x%finalize()
137 call this%bc_y%finalize()
138 call this%bc_z%finalize()
139 end subroutine symmetry_aligned_finalize
140
147 subroutine symmetry_aligned_get_normal_axis (this, sx, sy, sz, facet, el)
148 class(symmetry_aligned_t), target, intent(inout) :: this
149 real(kind=rp), intent(out) :: sx, sy, sz
150 integer, intent(in) :: facet
151 integer, intent(in) :: el
152 integer :: j, l
153
154 associate(c => this%coef, nx => this%coef%nx, ny => this%coef%ny, &
155 nz => this%coef%nz)
156 sx = 0.0_rp
157 sy = 0.0_rp
158 sz = 0.0_rp
159 select case (facet)
160 case (1, 2)
161 do l = 2, c%Xh%lx - 1
162 do j = 2, c%Xh%lx -1
163 sx = sx + abs(abs(nx(l, j, facet, el)) - 1.0_rp)
164 sy = sy + abs(abs(ny(l, j, facet, el)) - 1.0_rp)
165 sz = sz + abs(abs(nz(l, j, facet, el)) - 1.0_rp)
166 end do
167 end do
168 case (3, 4)
169 do l = 2, c%Xh%lx - 1
170 do j = 2, c%Xh%lx - 1
171 sx = sx + abs(abs(nx(l, j, facet, el)) - 1.0_rp)
172 sy = sy + abs(abs(ny(l, j, facet, el)) - 1.0_rp)
173 sz = sz + abs(abs(nz(l, j, facet, el)) - 1.0_rp)
174 end do
175 end do
176 case (5, 6)
177 do l = 2, c%Xh%lx - 1
178 do j = 2, c%Xh%lx - 1
179 sx = sx + abs(abs(nx(l, j, facet, el)) - 1.0_rp)
180 sy = sy + abs(abs(ny(l, j, facet, el)) - 1.0_rp)
181 sz = sz + abs(abs(nz(l, j, facet, el)) - 1.0_rp)
182 end do
183 end do
184 end select
185 sx = sx / (c%Xh%lx - 2.0_rp)**2.0_rp
186 sy = sy / (c%Xh%lx - 2.0_rp)**2.0_rp
187 sz = sz / (c%Xh%lx - 2.0_rp)**2.0_rp
188 end associate
190
196 subroutine symmetry_aligned_apply_scalar(this, x, n, time, strong)
197 class(symmetry_aligned_t), intent(inout) :: this
198 integer, intent(in) :: n
199 real(kind=rp), intent(inout), dimension(n) :: x
200 type(time_state_t), intent(in), optional :: time
201 logical, intent(in), optional :: strong
202 end subroutine symmetry_aligned_apply_scalar
203
213 subroutine symmetry_aligned_apply_vector(this, x, y, z, n, time, strong)
214 class(symmetry_aligned_t), intent(inout) :: this
215 integer, intent(in) :: n
216 real(kind=rp), intent(inout), dimension(n) :: x
217 real(kind=rp), intent(inout), dimension(n) :: y
218 real(kind=rp), intent(inout), dimension(n) :: z
219 type(time_state_t), intent(in), optional :: time
220 logical, intent(in), optional :: strong
221 logical :: strong_
222
223 if (present(strong)) then
224 strong_ = strong
225 else
226 strong_ = .true.
227 end if
228
229 if (strong_) then
230 call this%bc_x%apply_scalar(x, n, strong = .true.)
231 call this%bc_y%apply_scalar(y, n, strong = .true.)
232 call this%bc_z%apply_scalar(z, n, strong = .true.)
233 end if
234 end subroutine symmetry_aligned_apply_vector
235
241 subroutine symmetry_aligned_apply_scalar_dev(this, x_d, time, strong, strm)
242 class(symmetry_aligned_t), intent(inout), target :: this
243 type(c_ptr), intent(inout) :: x_d
244 type(time_state_t), intent(in), optional :: time
245 logical, intent(in), optional :: strong
246 type(c_ptr), intent(inout) :: strm
248
258 subroutine symmetry_aligned_apply_vector_dev(this, x_d, y_d, z_d, &
259 time, strong, strm)
260 class(symmetry_aligned_t), intent(inout), target :: this
261 type(c_ptr), intent(inout) :: x_d
262 type(c_ptr), intent(inout) :: y_d
263 type(c_ptr), intent(inout) :: z_d
264 type(time_state_t), intent(in), optional :: time
265 logical, intent(in), optional :: strong
266 type(c_ptr), intent(inout) :: strm
267 logical :: strong_
268
269 if (present(strong)) then
270 strong_ = strong
271 else
272 strong_ = .true.
273 end if
274
275 if (strong_ .and. (this%msk(0) .gt. 0)) then
276 call device_symmetry_aligned_apply_vector(this%bc_x%msk_d, &
277 this%bc_y%msk_d, this%bc_z%msk_d, x_d, y_d, z_d, &
278 this%bc_x%msk(0), this%bc_y%msk(0), this%bc_z%msk(0), strm)
279 end if
281
283 subroutine symmetry_aligned_free(this)
284 class(symmetry_aligned_t), target, intent(inout) :: this
285
286 call this%free_base()
287 call this%bc_x%free()
288 call this%bc_y%free()
289 call this%bc_z%free()
290 end subroutine symmetry_aligned_free
291
292end module symmetry_aligned
Defines a boundary condition.
Definition bc.f90:34
integer, parameter, public bc_mixed_constrains_normal
Definition bc.f90:67
Coefficients.
Definition coef.f90:34
subroutine device_symmetry_aligned_apply_vector(xmsk, ymsk, zmsk, x, y, z, m, n, l, strm)
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Implements symmetry_aligned_t.
subroutine symmetry_aligned_apply_vector(this, x, y, z, n, time, strong)
Remove the normal component on the CPU.
subroutine symmetry_aligned_init_from_components(this, coef)
Construct the boundary condition from its components.
subroutine symmetry_aligned_apply_vector_dev(this, x_d, y_d, z_d, time, strong, strm)
Remove the normal component on the device.
subroutine symmetry_aligned_apply_scalar(this, x, n, time, strong)
No-op scalar application.
subroutine symmetry_aligned_init(this, coef, json)
Construct the boundary condition from JSON.
subroutine symmetry_aligned_free(this)
Free the boundary condition and its nested storage.
subroutine symmetry_aligned_apply_scalar_dev(this, x_d, time, strong, strm)
No-op scalar application on the device.
subroutine symmetry_aligned_get_normal_axis(this, sx, sy, sz, facet, el)
Estimate which global axis is normal to a marked facet.
subroutine symmetry_aligned_finalize(this)
Finalize the boundary condition.
Module with things related to the simulation time.
Implements a n-tuple.
Definition tuple.f90:41
Defines a zero-valued Dirichlet boundary condition.
Base type for a boundary condition.
Definition bc.f90:72
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:93
Axis-aligned symmetry boundary condition.
A struct that contains all info about the time, expand as needed.
Integer based 2-tuple.
Definition tuple.f90:58
Zero-valued Dirichlet boundary condition. Used for no-slip walls, but also for various auxillary cond...