40 use json_module,
only : json_file
42 use,
intrinsic :: iso_c_binding, only : c_ptr
62 procedure, pass(this) :: apply_scalar_dev => &
65 procedure, pass(this) :: apply_vector_dev => &
70 procedure, pass(this) :: init_from_components => &
75 procedure, pass(this) :: get_normal_axis => &
88 type(
coef_t),
target,
intent(in) :: coef
89 type(json_file),
intent(inout) :: json
91 call this%init_from_components(coef)
98 type(
coef_t),
target,
intent(in) :: coef
102 call this%init_base(coef)
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)
114 integer :: i, facet, el
116 real(kind=
rp) :: sx, sy, sz
117 real(kind=
rp),
parameter :: tol = 1e-3_rp
120 call this%finalize_base()
122 associate(c => this%coef, nx => this%coef%nx, ny => this%coef%ny, &
124 bfp => this%marked_facet%array()
125 do i = 1, this%marked_facet%size()
127 facet = bc_facet%x(1)
129 call this%get_normal_axis(sx, sy, sz, facet, el)
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)
136 call this%bc_x%finalize()
137 call this%bc_y%finalize()
138 call this%bc_z%finalize()
149 real(kind=rp),
intent(out) :: sx, sy, sz
150 integer,
intent(in) :: facet
151 integer,
intent(in) :: el
154 associate(c => this%coef, nx => this%coef%nx, ny => this%coef%ny, &
161 do l = 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)
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)
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)
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
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
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
223 if (
present(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.)
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
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
269 if (
present(strong))
then
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)
286 call this%free_base()
287 call this%bc_x%free()
288 call this%bc_y%free()
289 call this%bc_z%free()
Defines a boundary condition.
integer, parameter, public bc_mixed_constrains_normal
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.
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.
Defines a zero-valued Dirichlet boundary condition.
Base type for a boundary condition.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Axis-aligned symmetry boundary condition.
A struct that contains all info about the time, expand as needed.
Zero-valued Dirichlet boundary condition. Used for no-slip walls, but also for various auxillary cond...