Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
boundary_data.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 num_types, only : rp
36 use coefs, only : coef_t
37 use dirichlet, only : dirichlet_t
38 use field, only : field_t
39 use vector, only : vector_t
40 use registry, only : neko_registry
41 use mesh, only : neko_msh_max_zlbls
42 use field_math, only : field_rzero
48 use utils, only : neko_error
49 use comm, only : neko_comm
50 use mpi_f08, only : mpi_allreduce, mpi_integer, mpi_sum
51 implicit none
52 private
53
56 type, public :: boundary_data_t
58 type(coef_t), pointer :: coef => null()
60 type(dirichlet_t) :: bc
62 integer, allocatable :: zone_indices(:)
64 integer :: n_local = 0
66 integer :: n_global = 0
68 type(vector_t) :: x, y, z
70 type(vector_t) :: n_x, n_y, n_z
72 type(vector_t) :: area
74 type(vector_t), private :: work
77 logical :: outward_normals = .true.
78 contains
80 procedure, pass(this) :: init => boundary_data_init
82 procedure, pass(this) :: free => boundary_data_free
84 procedure, pass(this) :: update_geometry => &
87 generic :: get => get_vector_by_name, get_vector_by_field
88 procedure, private, pass(this) :: get_vector_by_name => &
90 procedure, private, pass(this) :: get_vector_by_field => &
93 generic :: scatter => scatter_to_field_by_vector, &
94 scatter_to_field_by_name
95 procedure, private, pass(this) :: scatter_to_field_by_vector => &
97 procedure, private, pass(this) :: scatter_to_field_by_name => &
100 procedure, nopass :: is_geometry => boundary_data_is_geometry
102 generic :: integrate => integrate_by_name, integrate_by_field
103 procedure, private, pass(this) :: integrate_by_name => &
105 procedure, private, pass(this) :: integrate_by_field => &
108 generic :: average => average_by_name, average_by_field
109 procedure, private, pass(this) :: average_by_name => &
111 procedure, private, pass(this) :: average_by_field => &
114 procedure, pass(this) :: surface_area => boundary_data_surface_area
116 procedure, pass(this) :: centroid => boundary_data_centroid
118 procedure, pass(this) :: point_average => boundary_data_point_average
120 generic :: integrate_vector => integrate_vector_by_name, &
121 integrate_vector_by_field
122 procedure, private, pass(this) :: integrate_vector_by_name => &
124 procedure, private, pass(this) :: integrate_vector_by_field => &
127 generic :: integrate_normal => integrate_normal_by_name, &
128 integrate_normal_by_field
129 procedure, private, pass(this) :: integrate_normal_by_name => &
131 procedure, private, pass(this) :: integrate_normal_by_field => &
134 generic :: flux => flux_by_name, flux_by_field
135 procedure, private, pass(this) :: flux_by_name => &
137 procedure, private, pass(this) :: flux_by_field => &
140 generic :: tangential => tangential_inplace, tangential_split
141 procedure, private, pass(this) :: tangential_inplace => &
143 procedure, private, pass(this) :: tangential_split => &
146 generic :: normal => normal_inplace, normal_split
147 procedure, private, pass(this) :: normal_inplace => &
149 procedure, private, pass(this) :: normal_split => &
151 end type boundary_data_t
152
153contains
154
161 subroutine boundary_data_init(this, coef, zone_indices, outward_normals)
162 class(boundary_data_t), intent(inout) :: this
163 type(coef_t), intent(inout), target :: coef
164 integer, intent(in) :: zone_indices(:)
165 logical, intent(in), optional :: outward_normals
166 integer :: i, ierr
167
168 call this%free()
169
170 this%coef => coef
171 this%outward_normals = .true.
172 if (present(outward_normals)) this%outward_normals = outward_normals
173
174 if (size(zone_indices) .eq. 0) then
175 call neko_error("boundary_data: at least one zone index is required")
176 end if
177 do i = 1, size(zone_indices)
178 if (zone_indices(i) .lt. 1 .or. &
179 zone_indices(i) .gt. neko_msh_max_zlbls) then
180 call neko_error("boundary_data: zone index out of range")
181 end if
182 end do
183
184 allocate(this%zone_indices(size(zone_indices)))
185 this%zone_indices = zone_indices
186
187 ! The face-node mask (facet_node_msk) is used.
188 call this%bc%init_base(this%coef)
189 this%bc%zone_indices = this%zone_indices
190 do i = 1, size(this%zone_indices)
191 call this%bc%mark_zone( &
192 this%coef%dof%msh%labeled_zones(this%zone_indices(i)))
193 end do
194 call this%bc%finalize()
195
196 this%n_local = this%bc%facet_node_msk(0)
197
198 call mpi_allreduce(this%n_local, this%n_global, 1, mpi_integer, &
199 mpi_sum, neko_comm, ierr)
200
201 if (this%n_global .eq. 0) then
202 call neko_error("boundary_data: the requested zones contain no " // &
203 "boundary points")
204 end if
205
206 call this%x%init(this%n_local)
207 call this%y%init(this%n_local)
208 call this%z%init(this%n_local)
209 call this%n_x%init(this%n_local)
210 call this%n_y%init(this%n_local)
211 call this%n_z%init(this%n_local)
212 call this%area%init(this%n_local)
213 call this%work%init(this%n_local)
214
215 ! Populate the geometry once at construction.
216 call this%update_geometry()
217
218 end subroutine boundary_data_init
219
221 subroutine boundary_data_free(this)
222 class(boundary_data_t), intent(inout) :: this
223
224 call this%bc%free()
225
226 call this%x%free()
227 call this%y%free()
228 call this%z%free()
229 call this%n_x%free()
230 call this%n_y%free()
231 call this%n_z%free()
232 call this%area%free()
233 call this%work%free()
234
235 if (allocated(this%zone_indices)) deallocate(this%zone_indices)
236
237 this%n_local = 0
238 this%n_global = 0
239 nullify(this%coef)
240
241 end subroutine boundary_data_free
242
245 class(boundary_data_t), intent(inout) :: this
246 integer :: n
247
248 if (this%n_local .le. 0) return
249
250 n = this%coef%dof%size()
251
252 call vector_masked_gather_copy_0(this%x, this%coef%dof%x, &
253 this%bc%facet_node_msk, n, this%n_local)
254 call vector_masked_gather_copy_0(this%y, this%coef%dof%y, &
255 this%bc%facet_node_msk, n, this%n_local)
256 call vector_masked_gather_copy_0(this%z, this%coef%dof%z, &
257 this%bc%facet_node_msk, n, this%n_local)
258
259 call vector_face_masked_gather_copy_0(this%n_x, this%coef%nx, &
260 this%bc%facet_node_msk, this%bc%facet, this%coef%Xh%lx, &
261 this%coef%Xh%ly, this%coef%Xh%lz, this%n_local)
262 call vector_face_masked_gather_copy_0(this%n_y, this%coef%ny, &
263 this%bc%facet_node_msk, this%bc%facet, this%coef%Xh%lx, &
264 this%coef%Xh%ly, this%coef%Xh%lz, this%n_local)
265 call vector_face_masked_gather_copy_0(this%n_z, this%coef%nz, &
266 this%bc%facet_node_msk, this%bc%facet, this%coef%Xh%lx, &
267 this%coef%Xh%ly, this%coef%Xh%lz, this%n_local)
268
269 call vector_face_masked_gather_copy_0(this%area, this%coef%area, &
270 this%bc%facet_node_msk, this%bc%facet, this%coef%Xh%lx, &
271 this%coef%Xh%ly, this%coef%Xh%lz, this%n_local)
272
273 if (this%outward_normals) then
274 call vector_cmult(this%n_x, -1.0_rp)
275 call vector_cmult(this%n_y, -1.0_rp)
276 call vector_cmult(this%n_z, -1.0_rp)
277 end if
278
279 end subroutine boundary_data_update_geometry
280
281
284 pure function boundary_data_is_geometry(name) result(is_geom)
285 character(len=*), intent(in) :: name
286 logical :: is_geom
287
288 select case (trim(name))
289 case ("x", "y", "z", "n_x", "n_y", "n_z", "area")
290 is_geom = .true.
291 case default
292 is_geom = .false.
293 end select
294
295 end function boundary_data_is_geometry
296
302 subroutine boundary_data_get_vector_by_name(this, name, v)
303 class(boundary_data_t), intent(inout) :: this
304 character(len=*), intent(in) :: name
305 type(vector_t), intent(inout) :: v
306 type(field_t), pointer :: f
307
308 if (v%size() .ne. this%n_local) then
309 call v%free()
310 call v%init(this%n_local)
311 end if
312 if (this%n_local .le. 0) return
313
314 select case (trim(name))
315 case ("x")
316 call vector_copy(v, this%x)
317 case ("y")
318 call vector_copy(v, this%y)
319 case ("z")
320 call vector_copy(v, this%z)
321 case ("n_x")
322 call vector_copy(v, this%n_x)
323 case ("n_y")
324 call vector_copy(v, this%n_y)
325 case ("n_z")
326 call vector_copy(v, this%n_z)
327 case ("area")
328 call vector_copy(v, this%area)
329 case default
330 if (.not. neko_registry%field_exists(trim(name))) then
331 call neko_error("boundary_data: '" // trim(name) // &
332 "' is neither a geometry attribute (x, y, z, n_x, n_y, " // &
333 "n_z, area) nor a field in the registry")
334 end if
335 f => neko_registry%get_field_by_name(trim(name))
336 call this%get_vector_by_field(f, v)
337 end select
338
340
345 class(boundary_data_t), intent(inout) :: this
346 type(field_t), intent(in) :: f
347 type(vector_t), intent(inout) :: v
348
349 if (.not. associated(f%dof, this%coef%dof)) then
350 call neko_error("boundary_data: the field '" // trim(f%name) // &
351 "' is on a different dofmap than the boundary mask, so the " // &
352 "masked indices do not apply to it")
353 end if
354
355 if (v%size() .ne. this%n_local) then
356 call v%free()
357 call v%init(this%n_local)
358 end if
359 if (this%n_local .le. 0) return
360
361 call vector_masked_gather_copy_0(v, f%x, this%bc%facet_node_msk, &
362 this%coef%dof%size(), this%n_local)
363
365
371 subroutine boundary_data_scatter_to_field_by_vector(this, v, f, clear)
372 class(boundary_data_t), intent(inout) :: this
373 type(vector_t), intent(in) :: v
374 type(field_t), intent(inout) :: f
375 logical, intent(in), optional :: clear
376 logical :: clear_
377 integer :: n
378
379 if (.not. associated(f%dof, this%coef%dof)) then
380 call neko_error("boundary_data: the destination field is on a " // &
381 "different dofmap than the boundary mask")
382 end if
383
384 clear_ = .false.
385 if (present(clear)) clear_ = clear
386
387 n = this%coef%dof%size()
388
389 if (clear_) call field_rzero(f)
390
391 call vector_masked_scatter_copy_0(f%x, v, this%bc%facet_node_msk, n, &
392 this%n_local)
393
395
401 subroutine boundary_data_scatter_to_field_by_name(this, name, f, clear)
402 class(boundary_data_t), intent(inout) :: this
403 character(len=*), intent(in) :: name
404 type(field_t), intent(inout) :: f
405 logical, intent(in), optional :: clear
406 logical :: clear_
407
408 clear_ = .false.
409 if (present(clear)) clear_ = clear
410
411 call this%get(trim(name), this%work)
412 call this%scatter_to_field_by_vector(this%work, f, clear_)
413
415
424 subroutine boundary_data_tangential_inplace(this, vx, vy, vz)
425 class(boundary_data_t), intent(inout) :: this
426 type(vector_t), intent(inout) :: vx, vy, vz
427
428 if (vx%size() .lt. this%n_local .or. vy%size() .lt. this%n_local .or. &
429 vz%size() .lt. this%n_local) then
430 call neko_error("boundary_data: the vectors passed to tangential " // &
431 "are shorter than the number of boundary points")
432 end if
433
434 call vector_vdot3(this%work, vx, vy, vz, this%n_x, this%n_y, this%n_z)
435 call vector_subcol3(vx, this%work, this%n_x)
436 call vector_subcol3(vy, this%work, this%n_y)
437 call vector_subcol3(vz, this%work, this%n_z)
438
440
453 subroutine boundary_data_tangential_split(this, vx, vy, vz, tx, ty, tz)
454 class(boundary_data_t), intent(inout) :: this
455 type(vector_t), intent(in) :: vx, vy, vz
456 type(vector_t), intent(inout) :: tx, ty, tz
457
458 if (vx%size() .lt. this%n_local .or. vy%size() .lt. this%n_local .or. &
459 vz%size() .lt. this%n_local .or. tx%size() .lt. this%n_local .or. &
460 ty%size() .lt. this%n_local .or. tz%size() .lt. this%n_local) then
461 call neko_error("boundary_data: the vectors passed to tangential " // &
462 "are shorter than the number of boundary points")
463 end if
464
465 call vector_vdot3(this%work, vx, vy, vz, this%n_x, this%n_y, this%n_z)
466 call vector_copy(tx, vx)
467 call vector_copy(ty, vy)
468 call vector_copy(tz, vz)
469 call vector_subcol3(tx, this%work, this%n_x)
470 call vector_subcol3(ty, this%work, this%n_y)
471 call vector_subcol3(tz, this%work, this%n_z)
472
473 end subroutine boundary_data_tangential_split
474
483 subroutine boundary_data_normal_inplace(this, vx, vy, vz)
484 class(boundary_data_t), intent(inout) :: this
485 type(vector_t), intent(inout) :: vx, vy, vz
486
487 if (vx%size() .lt. this%n_local .or. vy%size() .lt. this%n_local .or. &
488 vz%size() .lt. this%n_local) then
489 call neko_error("boundary_data: the vectors passed to normal " // &
490 "are shorter than the number of boundary points")
491 end if
492
493 call vector_vdot3(this%work, vx, vy, vz, this%n_x, this%n_y, this%n_z)
494 call vector_col3(vx, this%work, this%n_x)
495 call vector_col3(vy, this%work, this%n_y)
496 call vector_col3(vz, this%work, this%n_z)
497
498 end subroutine boundary_data_normal_inplace
499
512 subroutine boundary_data_normal_split(this, vx, vy, vz, nx, ny, nz)
513 class(boundary_data_t), intent(inout) :: this
514 type(vector_t), intent(in) :: vx, vy, vz
515 type(vector_t), intent(inout) :: nx, ny, nz
516
517 if (vx%size() .lt. this%n_local .or. vy%size() .lt. this%n_local .or. &
518 vz%size() .lt. this%n_local .or. nx%size() .lt. this%n_local .or. &
519 ny%size() .lt. this%n_local .or. nz%size() .lt. this%n_local) then
520 call neko_error("boundary_data: the vectors passed to normal " // &
521 "are shorter than the number of boundary points")
522 end if
523
524 call vector_vdot3(this%work, vx, vy, vz, this%n_x, this%n_y, this%n_z)
525 call vector_col3(nx, this%work, this%n_x)
526 call vector_col3(ny, this%work, this%n_y)
527 call vector_col3(nz, this%work, this%n_z)
528
529 end subroutine boundary_data_normal_split
530
533 function boundary_data_integrate_by_name(this, name) result(val)
534 class(boundary_data_t), intent(inout) :: this
535 character(len=*), intent(in) :: name
536 real(kind=rp) :: val
537
538 call this%get(trim(name), this%work)
539 val = vector_glsc2(this%work, this%area)
540
542
545 function boundary_data_integrate_by_field(this, f) result(val)
546 class(boundary_data_t), intent(inout) :: this
547 type(field_t), intent(in) :: f
548 real(kind=rp) :: val
549
550 call this%get(f, this%work)
551 val = vector_glsc2(this%work, this%area)
552
554
556 function boundary_data_surface_area(this) result(val)
557 class(boundary_data_t), intent(inout) :: this
558 real(kind=rp) :: val
559
560 val = vector_glsum(this%area)
561
562 end function boundary_data_surface_area
563
566 function boundary_data_average_by_name(this, name) result(val)
567 class(boundary_data_t), intent(inout) :: this
568 character(len=*), intent(in) :: name
569 real(kind=rp) :: val
570 real(kind=rp) :: total
571
572 total = this%surface_area()
573 if (total .le. 0.0_rp) then
574 call neko_error("boundary_data: the total surface area is not " // &
575 "positive, cannot form an area weighted average")
576 end if
577 val = this%integrate(trim(name)) / total
578
580
583 function boundary_data_average_by_field(this, f) result(val)
584 class(boundary_data_t), intent(inout) :: this
585 type(field_t), intent(in) :: f
586 real(kind=rp) :: val
587 real(kind=rp) :: total
588
589 total = this%surface_area()
590 if (total .le. 0.0_rp) then
591 call neko_error("boundary_data: the total surface area is not " // &
592 "positive, cannot form an area weighted average")
593 end if
594 val = this%integrate(f) / total
595
597
599 function boundary_data_centroid(this) result(c)
600 class(boundary_data_t), intent(inout) :: this
601 real(kind=rp) :: c(3)
602 real(kind=rp) :: total
603
604 total = vector_glsum(this%area)
605 if (total .le. 0.0_rp) then
606 call neko_error("boundary_data: the total surface area is not " // &
607 "positive, cannot form a centroid")
608 end if
609
610 c(1) = vector_glsc2(this%x, this%area) / total
611 c(2) = vector_glsc2(this%y, this%area) / total
612 c(3) = vector_glsc2(this%z, this%area) / total
613
614 end function boundary_data_centroid
615
617 function boundary_data_point_average(this) result(c)
618 class(boundary_data_t), intent(inout) :: this
619 real(kind=rp) :: c(3)
620
621 c(1) = vector_glsum(this%x) / this%n_global
622 c(2) = vector_glsum(this%y) / this%n_global
623 c(3) = vector_glsum(this%z) / this%n_global
624
625 end function boundary_data_point_average
626
631 function boundary_data_integrate_vector_by_field(this, fx, fy, fz) &
632 result(f)
633 class(boundary_data_t), intent(inout) :: this
634 type(field_t), intent(in) :: fx, fy, fz
635 real(kind=rp) :: f(3)
636
637 f(1) = this%integrate(fx)
638 f(2) = this%integrate(fy)
639 f(3) = this%integrate(fz)
640
642
647 function boundary_data_integrate_vector_by_name(this, fx, fy, fz) result(f)
648 class(boundary_data_t), intent(inout) :: this
649 character(len=*), intent(in) :: fx, fy, fz
650 real(kind=rp) :: f(3)
651
652 f(1) = this%integrate(trim(fx))
653 f(2) = this%integrate(trim(fy))
654 f(3) = this%integrate(trim(fz))
655
657
664 function boundary_data_flux_by_field(this, u, v, w) result(q)
665 class(boundary_data_t), intent(inout) :: this
666 type(field_t), intent(in) :: u, v, w
667 real(kind=rp) :: q
668
669 call this%get(u, this%work)
670 q = vector_glsc3(this%work, this%n_x, this%area)
671 call this%get(v, this%work)
672 q = q + vector_glsc3(this%work, this%n_y, this%area)
673 call this%get(w, this%work)
674 q = q + vector_glsc3(this%work, this%n_z, this%area)
675
676 end function boundary_data_flux_by_field
677
682 function boundary_data_flux_by_name(this, u, v, w) result(q)
683 class(boundary_data_t), intent(inout) :: this
684 character(len=*), intent(in) :: u, v, w
685 real(kind=rp) :: q
686
687 call this%get(trim(u), this%work)
688 q = vector_glsc3(this%work, this%n_x, this%area)
689 call this%get(trim(v), this%work)
690 q = q + vector_glsc3(this%work, this%n_y, this%area)
691 call this%get(trim(w), this%work)
692 q = q + vector_glsc3(this%work, this%n_z, this%area)
693
694 end function boundary_data_flux_by_name
695
700 function boundary_data_integrate_normal_by_field(this, f) result(fn)
701 class(boundary_data_t), intent(inout) :: this
702 type(field_t), intent(in) :: f
703 real(kind=rp) :: fn(3)
704
705 call this%get(f, this%work)
706 fn(1) = vector_glsc3(this%work, this%n_x, this%area)
707 fn(2) = vector_glsc3(this%work, this%n_y, this%area)
708 fn(3) = vector_glsc3(this%work, this%n_z, this%area)
709
711
714 function boundary_data_integrate_normal_by_name(this, name) result(fn)
715 class(boundary_data_t), intent(inout) :: this
716 character(len=*), intent(in) :: name
717 real(kind=rp) :: fn(3)
718
719 call this%get(trim(name), this%work)
720 fn(1) = vector_glsc3(this%work, this%n_x, this%area)
721 fn(2) = vector_glsc3(this%work, this%n_y, this%area)
722 fn(3) = vector_glsc3(this%work, this%n_z, this%area)
723
725
726end module boundary_data
Defines a boundary condition.
Definition bc.f90:34
Implements the boundary_data_t type.
real(kind=rp) function, dimension(3) boundary_data_point_average(this)
Unweighted mean of the boundary point coordinates.
subroutine boundary_data_get_vector_by_field(this, f, v)
Sample a field at the boundary points into a vector.
real(kind=rp) function boundary_data_flux_by_name(this, u, v, w)
Flux of a named vector quantity through the zones.
subroutine boundary_data_normal_inplace(this, vx, vy, vz)
Keep only the wall normal part of a vector at the boundary points, in place. Each component is overwr...
subroutine boundary_data_update_geometry(this)
Re-gather the coordinates, normals and surface weights.
real(kind=rp) function boundary_data_average_by_field(this, f)
Area weighted average of a field over the zones.
subroutine boundary_data_scatter_to_field_by_vector(this, v, f, clear)
Scatter a boundary vector back into a full field.
subroutine boundary_data_get_vector_by_name(this, name, v)
Sample a named quantity at the boundary points into a vector.
real(kind=rp) function, dimension(3) boundary_data_integrate_vector_by_field(this, fx, fy, fz)
Surface integral of a vector quantity, component by component.
real(kind=rp) function boundary_data_flux_by_field(this, u, v, w)
Flux of a vector quantity through the zones.
subroutine boundary_data_tangential_split(this, vx, vy, vz, tx, ty, tz)
Wall tangential part of a vector at the boundary points, out of place. The input (vx,...
real(kind=rp) function, dimension(3) boundary_data_centroid(this)
Area weighted geometric centre of the zones.
real(kind=rp) function, dimension(3) boundary_data_integrate_normal_by_field(this, f)
Surface integral of a scalar quantity times the normal.
subroutine boundary_data_tangential_inplace(this, vx, vy, vz)
Keep only the wall tangential part of a vector at the boundary points, in place. Each component is ov...
subroutine boundary_data_init(this, coef, zone_indices, outward_normals)
Build the boundary point mask and gather the geometry.
subroutine boundary_data_scatter_to_field_by_name(this, name, f, clear)
Scatter a named boundary quantity into a full field.
real(kind=rp) function boundary_data_surface_area(this)
Total surface area of the zones.
real(kind=rp) function boundary_data_average_by_name(this, name)
Area weighted average of a named quantity over the zones.
subroutine boundary_data_normal_split(this, vx, vy, vz, nx, ny, nz)
Wall normal part of a vector at the boundary points, out of place. The input (vx, vy,...
real(kind=rp) function boundary_data_integrate_by_field(this, f)
Surface integral of a field over the zones.
real(kind=rp) function, dimension(3) boundary_data_integrate_vector_by_name(this, fx, fy, fz)
Surface integral of a named vector quantity, component by component.
real(kind=rp) function boundary_data_integrate_by_name(this, name)
Surface integral of a named quantity over the zones.
real(kind=rp) function, dimension(3) boundary_data_integrate_normal_by_name(this, name)
Surface integral of a named scalar quantity times the normal.
subroutine boundary_data_free(this)
Destructor.
pure logical function boundary_data_is_geometry(name)
Whether name refers to one of the geometry attributes.
Coefficients.
Definition coef.f90:34
Definition comm.F90:1
type(mpi_comm), public neko_comm
MPI communicator.
Definition comm.F90:46
Defines a dirichlet boundary condition.
Definition dirichlet.f90:34
subroutine, public field_rzero(a, n)
Zero a real vector.
Defines a field.
Definition field.f90:34
Defines a mesh.
Definition mesh.f90:34
integer, parameter, public neko_msh_max_zlbls
Max num. zone labels.
Definition mesh.f90:65
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
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
Utilities.
Definition utils.f90:35
subroutine, public vector_masked_gather_copy_0(a, b, mask, n, n_mask)
Gather a vector to reduced contigous array .
real(kind=rp) function, public vector_glsc3(a, b, c, n)
subroutine, public vector_vdot3(dot, u1, u2, u3, v1, v2, v3, n)
Compute a dot product (3-d version) assuming vector components etc.
subroutine, public vector_copy(a, b, n)
Copy a vector .
subroutine, public vector_cmult(a, c, n)
Multiplication by constant c .
subroutine, public vector_face_masked_gather_copy_0(a, b, mask, facet, lx, ly, lz, n_mask)
Gather a face-local SEM field to a reduced contiguous vector.
real(kind=rp) function, public vector_glsum(a, n)
real(kind=rp) function, public vector_glsc2(a, b, n)
subroutine, public vector_subcol3(a, b, c, n)
Returns .
subroutine, public vector_col3(a, b, c, n)
Vector multiplication with 3 vectors .
subroutine, public vector_masked_scatter_copy_0(a, b, mask, n, n_mask)
Scatter a contiguous vector into an array .
Defines a vector.
Definition vector.f90:34
Collects data on the boundary points of one or more labelled zones and perform some bounary operation...
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition coef.f90:93
Generic Dirichlet boundary condition on .
Definition dirichlet.f90:49