Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
scalar_bc_projector.f90
Go to the documentation of this file.
1! Copyright (c) 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!
35 use bc, only : bc_t
36 use bc_list, only : bc_list_t
37 use mask, only : mask_t
38 use field, only : field_t
39 use fld_file, only : fld_file_t
41 use math, only : cfill_mask, sort
43 use num_types, only : rp
46 use utils, only : neko_error
47 use, intrinsic :: iso_c_binding, only : c_ptr
48 implicit none
49 private
50
58 type, public :: scalar_bc_projector_t
60 type(mask_t) :: dof_mask
61 contains
63 procedure, pass(this) :: free => scalar_bc_projector_free
65 procedure, pass(this) :: mark_bc => scalar_bc_projector_mark_bc
67 procedure, pass(this) :: mark_bc_list => scalar_bc_projector_mark_bc_list
68 generic :: mark => mark_bc, mark_bc_list
70 procedure, pass(this) :: apply => scalar_bc_projector_apply
72 procedure, pass(this) :: debug_output => scalar_bc_projector_debug_output
74
75contains
76
78 subroutine scalar_bc_projector_free(this)
79 class(scalar_bc_projector_t), intent(inout) :: this
80
81 call this%dof_mask%free()
82 end subroutine scalar_bc_projector_free
83
89 subroutine scalar_bc_projector_mark_bc(this, bc)
90 class(scalar_bc_projector_t), intent(inout) :: this
91 class(bc_t), intent(in) :: bc
92
93 integer, pointer :: current_mask(:)
94 integer, allocatable :: merged_mask(:)
95 integer, allocatable :: perm(:)
96 integer :: current_size
97 integer :: incoming_size
98 integer :: merged_size
99 integer :: i
100
101 if (.not. allocated(bc%msk)) then
102 call neko_error("Attempting to mark projector from an unfinalized BC.")
103 end if
104
105 incoming_size = bc%msk(0)
106 if (incoming_size .eq. 0) return
107
108 ! If this is the first bc to be marked
109 if (.not. this%dof_mask%is_set()) then
110 allocate(merged_mask(incoming_size), perm(incoming_size))
111 merged_mask = bc%msk(1:incoming_size)
112 call sort(merged_mask, perm, incoming_size)
113
114 merged_size = 1
115 do i = 2, incoming_size
116 if (merged_mask(i) .ne. merged_mask(merged_size)) then
117 merged_size = merged_size + 1
118 merged_mask(merged_size) = merged_mask(i)
119 end if
120 end do
121
122 call this%dof_mask%init(merged_mask(1:merged_size), merged_size)
123 return
124 end if
125
126 ! Append the incoming mask to the current mask
127 current_size = this%dof_mask%size()
128 current_mask => this%dof_mask%get()
129 allocate(merged_mask(current_size + incoming_size))
130 allocate(perm(current_size + incoming_size))
131
132 merged_mask(1:current_size) = current_mask(1:current_size)
133 merged_mask(current_size + 1:current_size + incoming_size) = &
134 bc%msk(1:incoming_size)
135
136 ! Sort the merged mask
137 call sort(merged_mask, perm, current_size + incoming_size)
138
139 ! Take out unique elements
140 merged_size = 1
141 do i = 2, current_size + incoming_size
142 if (merged_mask(i) .ne. merged_mask(merged_size)) then
143 merged_size = merged_size + 1
144 merged_mask(merged_size) = merged_mask(i)
145 end if
146 end do
147
148 call this%dof_mask%set(merged_mask(1:merged_size), merged_size)
149 end subroutine scalar_bc_projector_mark_bc
150
154 subroutine scalar_bc_projector_mark_bc_list(this, bclst)
155 class(scalar_bc_projector_t), intent(inout) :: this
156 type(bc_list_t), intent(in) :: bclst
157 integer :: i
158
159 do i = 1, bclst%size()
160 call this%mark_bc(bclst%get(i))
161 end do
163
168 subroutine scalar_bc_projector_apply(this, x, n, strm)
169 class(scalar_bc_projector_t), intent(in) :: this
170 integer, intent(in) :: n
171 real(kind=rp), intent(inout) :: x(n)
172 type(c_ptr), intent(inout), optional :: strm
173 type(c_ptr) :: x_d
174
175 if (.not. this%dof_mask%is_set()) return
176
177 if (neko_bcknd_device .eq. 1) then
178 x_d = device_get_ptr(x)
179 call device_cfill_mask(x_d, 0.0_rp, n, this%dof_mask%get_d(), &
180 this%dof_mask%size(), strm = strm)
181 else
182 call cfill_mask(x, 0.0_rp, n, this%dof_mask%get(), this%dof_mask%size())
183 end if
184 end subroutine scalar_bc_projector_apply
185
189 subroutine scalar_bc_projector_debug_output(this, field_name)
190 class(scalar_bc_projector_t), intent(inout) :: this
191 character(len=*), intent(in), optional :: field_name
192 type(field_t), pointer :: mask_field
193 type(fld_file_t) :: mask_file
194 integer :: scratch_idx
195 character(len=:), allocatable :: field_name_
196
197 if (present(field_name)) then
198 field_name_ = trim(field_name)
199 else
200 field_name_ = 'scalar_bc_projector_mask'
201 end if
202
203 call neko_scratch_registry%request_field(mask_field, scratch_idx, .true.)
204
205 if (this%dof_mask%is_set()) then
206 if (neko_bcknd_device .eq. 1) then
207 call device_cfill_mask(mask_field%x_d, 1.0_rp, mask_field%size(), &
208 this%dof_mask%get_d(), this%dof_mask%size())
209 call mask_field%copy_from(device_to_host, .true.)
210 else
211 call cfill_mask(mask_field%x, 1.0_rp, mask_field%size(), &
212 this%dof_mask%get(), this%dof_mask%size())
213 end if
214 end if
215
216 call mask_file%init(field_name_ // '.fld')
217 call mask_file%write(mask_field)
218 call neko_scratch_registry%relinquish_field(scratch_idx)
220
221end module scalar_bc_projector
Return the device pointer for an associated Fortran array.
Definition device.F90:113
Defines a list of bc_t.
Definition bc_list.f90:34
Defines a boundary condition.
Definition bc.f90:34
subroutine, public device_cfill_mask(a_d, c, n, mask_d, n_mask, strm)
Fill a constant to a masked vector. .
Device abstraction, common interface for various accelerators.
Definition device.F90:34
integer, parameter, public device_to_host
Definition device.F90:48
Defines a field.
Definition field.f90:34
NEKTON fld file format.
Definition fld_file.f90:35
Object for handling masks in Neko.
Definition mask.f90:34
Definition math.f90:60
subroutine, public cfill_mask(a, c, n, mask, n_mask)
Fill a constant to a masked vector. .
Definition math.f90:491
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Implements scalar_projector_t.
subroutine scalar_bc_projector_mark_bc(this, bc)
Add the constrained dofs from a scalar boundary condition.
subroutine scalar_bc_projector_debug_output(this, field_name)
Write a field showing the resolved scalar BC mask.
subroutine scalar_bc_projector_free(this)
Destructor.
subroutine scalar_bc_projector_apply(this, x, n, strm)
Apply the scalar boundary constraints by zeroing constrained dofs.
subroutine scalar_bc_projector_mark_bc_list(this, bclst)
Add the constrained dofs from all boundary conditions in a list.
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.
Utilities.
Definition utils.f90:35
Base type for a boundary condition.
Definition bc.f90:72
A list of allocatable `bc_t`. Follows the standard interface of lists.
Definition bc_list.f90:49
Interface for NEKTON fld files.
Definition fld_file.f90:66
Type for consistently handling masks in Neko. This type encapsulates the mask array and its associate...
Definition mask.f90:51
Projector for scalar boundary conditions.