Neko 1.99.5
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
math.f90
Go to the documentation of this file.
1! Copyright (c) 2008-2020, UCHICAGO ARGONNE, LLC.
2!
3! The UChicago Argonne, LLC as Operator of Argonne National
4! Laboratory holds copyright in the Software. The copyright holder
5! reserves all rights except those expressly granted to licensees,
6! and U.S. Government license rights.
7!
8! Redistribution and use in source and binary forms, with or without
9! modification, are permitted provided that the following conditions
10! are met:
11!
12! 1. Redistributions of source code must retain the above copyright
13! notice, this list of conditions and the disclaimer below.
14!
15! 2. Redistributions in binary form must reproduce the above copyright
16! notice, this list of conditions and the disclaimer (as noted below)
17! in the documentation and/or other materials provided with the
18! distribution.
19!
20! 3. Neither the name of ANL nor the names of its contributors
21! may be used to endorse or promote products derived from this software
22! without specific prior written permission.
23!
24! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
28! UCHICAGO ARGONNE, LLC, THE U.S. DEPARTMENT OF
29! ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
31! TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33! THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34! (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36!
37! Additional BSD Notice
38! ---------------------
39! 1. This notice is required to be provided under our contract with
40! the U.S. Department of Energy (DOE). This work was produced at
41! Argonne National Laboratory under Contract
42! No. DE-AC02-06CH11357 with the DOE.
43!
44! 2. Neither the United States Government nor UCHICAGO ARGONNE,
45! LLC nor any of their employees, makes any warranty,
46! express or implied, or assumes any liability or responsibility for the
47! accuracy, completeness, or usefulness of any information, apparatus,
48! product, or process disclosed, or represents that its use would not
49! infringe privately-owned rights.
50!
51! 3. Also, reference herein to any specific commercial products, process,
52! or services by trade name, trademark, manufacturer or otherwise does
53! not necessarily constitute or imply its endorsement, recommendation,
54! or favoring by the United States Government or UCHICAGO ARGONNE LLC.
55! The views and opinions of authors expressed
56! herein do not necessarily state or reflect those of the United States
57! Government or UCHICAGO ARGONNE, LLC, and shall
58! not be used for advertising or product endorsement purposes.
59!
60module math
61 use num_types, only : rp, dp, sp, qp, i4, xp
63 use mpi_f08, only : mpi_min, mpi_max, mpi_sum, mpi_in_place, mpi_integer, &
64 mpi_allreduce
65 use utils, only : nonlinear_index
66 implicit none
67 private
68
70 real(kind=rp), public, parameter :: neko_eps = epsilon(1.0_rp)
71
73 real(kind=rp), public, parameter :: neko_m_ln2 = log(2.0_rp)
74
76 real(kind=rp), public, parameter :: pi = 4._rp*atan(1._rp)
77
78 interface abscmp
79 module procedure sabscmp, dabscmp, qabscmp
80 end interface abscmp
81
82 interface sort
83 module procedure sortrp, sorti4
84 end interface sort
85
86 interface swap
87 module procedure swapdp, swapi4
88 end interface swap
89
90 interface reord
91 module procedure reorddp, reordi4
92 end interface reord
93
94 interface flipv
95 module procedure flipvdp, flipvi4
96 end interface flipv
97
98 interface relcmp
99 module procedure srelcmp, drelcmp, qrelcmp
100 end interface relcmp
101
102 public :: abscmp, rzero, izero, row_zero, rone, copy, cmult, cadd, cfill, &
110 matinv39, &
115
116contains
117
119 pure function sabscmp(x, y, tol)
120 real(kind=sp), intent(in) :: x
121 real(kind=sp), intent(in) :: y
122 real(kind=sp), intent(in), optional :: tol
123 logical :: sabscmp
124
125 if (present(tol)) then
126 sabscmp = abs(x - y) .lt. tol
127 else
128 sabscmp = abs(x - y) .lt. neko_eps
129 end if
130
131 end function sabscmp
132
134 pure function dabscmp(x, y, tol)
135 real(kind=dp), intent(in) :: x
136 real(kind=dp), intent(in) :: y
137 real(kind=dp), intent(in), optional :: tol
138 logical :: dabscmp
139
140 if (present(tol)) then
141 dabscmp = abs(x - y) .lt. tol
142 else
143 dabscmp = abs(x - y) .lt. neko_eps
144 end if
145
146 end function dabscmp
147
149 pure function qabscmp(x, y, tol)
150 real(kind=qp), intent(in) :: x
151 real(kind=qp), intent(in) :: y
152 real(kind=qp), intent(in), optional :: tol
153 logical :: qabscmp
154
155 if (present(tol)) then
156 qabscmp = abs(x - y) .lt. tol
157 else
158 qabscmp = abs(x - y) .lt. neko_eps
159 end if
160
161 end function qabscmp
162
165 pure function srelcmp(x, y, eps)
166 real(kind=sp), intent(in) :: x
167 real(kind=sp), intent(in) :: y
168 real(kind=sp), intent(in), optional :: eps
169 logical :: srelcmp
170 if (present(eps)) then
171 srelcmp = abs(x - y) .le. eps*abs(y)
172 else
173 srelcmp = abs(x - y) .le. neko_eps*abs(y)
174 end if
175
176 end function srelcmp
177
180 pure function drelcmp(x, y, eps)
181 real(kind=dp), intent(in) :: x
182 real(kind=dp), intent(in) :: y
183 real(kind=dp), intent(in), optional :: eps
184 logical :: drelcmp
185 if (present(eps)) then
186 drelcmp = abs(x - y) .le. eps*abs(y)
187 else
188 drelcmp = abs(x - y) .le. neko_eps*abs(y)
189 end if
190
191 end function drelcmp
192
193
195 pure function qrelcmp(x, y, eps)
196 real(kind=qp), intent(in) :: x
197 real(kind=qp), intent(in) :: y
198 real(kind=qp), intent(in), optional :: eps
199 logical :: qrelcmp
200 if (present(eps)) then
201 qrelcmp = abs(x - y)/abs(y) .lt. eps
202 else
203 qrelcmp = abs(x - y)/abs(y) .lt. neko_eps
204 end if
205
206 end function qrelcmp
207
213 pure function lambert_w0(x, niter) result(w)
214 real(kind=rp), intent(in) :: x
215 integer, intent(in) :: niter
216 real(kind=rp) :: w
217 real(kind=rp) :: a
218 integer :: k
219
220 if (x == 0.0_rp) then
221 w = 0.0_rp
222 return
223 end if
224
225 a = 1.0_rp / (1.0_rp + 0.5_rp * log(1.0_rp + x))
226 w = log(1.0_rp + a * x)
227
228 do k = 1, max(niter, 0)
229 w = w / (1.0_rp + w) * (1.0_rp + log(x / w))
230 end do
231 end function lambert_w0
232
234 subroutine rzero(a, n)
235 integer, intent(in) :: n
236 real(kind=rp), dimension(n), intent(inout) :: a
237 integer :: i
238
239 !$omp parallel do
240 do i = 1, n
241 a(i) = 0.0_rp
242 end do
243 !$omp end parallel do
244
245 end subroutine rzero
246
248 subroutine izero(a, n)
249 integer, intent(in) :: n
250 integer, dimension(n), intent(inout) :: a
251 integer :: i
252
253 !$omp parallel do
254 do i = 1, n
255 a(i) = 0
256 end do
257 !$omp end parallel do
258
259 end subroutine izero
260
262 subroutine row_zero(a, m, n, e)
263 integer, intent(in) :: m, n, e
264 real(kind=rp), intent(inout) :: a(m,n)
265 integer :: j
266
267 !$omp parallel do
268 do j = 1, n
269 a(e,j) = 0.0_rp
270 end do
271 !$omp end parallel do
272
273 end subroutine row_zero
274
276 subroutine rone(a, n)
277 integer, intent(in) :: n
278 real(kind=rp), dimension(n), intent(inout) :: a
279 integer :: i
280
281 !$omp parallel do
282 do i = 1, n
283 a(i) = 1.0_rp
284 end do
285 !$omp end parallel do
286
287 end subroutine rone
288
290 subroutine copy(a, b, n)
291 integer, intent(in) :: n
292 real(kind=rp), dimension(n), intent(in) :: b
293 real(kind=rp), dimension(n), intent(inout) :: a
294 integer :: i
295
296 !$omp parallel do
297 do i = 1, n
298 a(i) = b(i)
299 end do
300 !$omp end parallel do
301
302 end subroutine copy
303
311 subroutine masked_copy_0(a, b, mask, n, n_mask)
312 integer, intent(in) :: n, n_mask
313 real(kind=rp), dimension(n), intent(in) :: b
314 real(kind=rp), dimension(n), intent(inout) :: a
315 integer, dimension(0:n_mask) :: mask
316 integer :: i, j
317
318 !$omp parallel do private(i, j)
319 do i = 1, n_mask
320 j = mask(i)
321 a(j) = b(j)
322 end do
323 !$omp end parallel do
324
325 end subroutine masked_copy_0
326
334 subroutine masked_copy(a, b, mask, n, n_mask)
335 integer, intent(in) :: n, n_mask
336 real(kind=rp), dimension(n), intent(in) :: b
337 real(kind=rp), dimension(n), intent(inout) :: a
338 integer, dimension(n_mask) :: mask
339 integer :: i, j
340
341 !$omp parallel do private(i, j)
342 do i = 1, n_mask
343 j = mask(i)
344 a(j) = b(j)
345 end do
346 !$omp end parallel do
347
348 end subroutine masked_copy
349
359 subroutine masked_gather_copy_0(a, b, mask, n, n_mask)
360 integer, intent(in) :: n, n_mask
361 real(kind=rp), dimension(n), intent(in) :: b
362 real(kind=rp), dimension(n_mask), intent(inout) :: a
363 integer, dimension(0:n_mask) :: mask
364 integer :: i, j
365
366 !$omp parallel do private(i, j)
367 do i = 1, n_mask
368 j = mask(i)
369 a(i) = b(j)
370 end do
371 !$omp end parallel do
372
373 end subroutine masked_gather_copy_0
374
384 subroutine face_masked_gather_copy_0(a, b, mask, facet, lx, ly, lz, n_mask)
385 integer, intent(in) :: lx, ly, lz, n_mask
386 real(kind=rp), dimension(n_mask), intent(inout) :: a
387 real(kind=rp), dimension(:, :, :, :), intent(in) :: b
388 integer, dimension(0:n_mask), intent(in) :: mask
389 integer, dimension(0:n_mask), intent(in) :: facet
390 integer :: l
391 integer :: idx(4)
392
393 !$omp parallel do private(l, idx)
394 do l = 1, n_mask
395 idx = nonlinear_index(mask(l), lx, ly, lz)
396
397 select case (facet(l))
398 case (1, 2)
399 a(l) = b(idx(2), idx(3), facet(l), idx(4))
400 case (3, 4)
401 a(l) = b(idx(1), idx(3), facet(l), idx(4))
402 case (5, 6)
403 a(l) = b(idx(1), idx(2), facet(l), idx(4))
404 end select
405 end do
406 !$omp end parallel do
407
408 end subroutine face_masked_gather_copy_0
409
419 subroutine masked_gather_copy(a, b, mask, n, n_mask)
420 integer, intent(in) :: n, n_mask
421 real(kind=rp), dimension(n), intent(in) :: b
422 real(kind=rp), dimension(n_mask), intent(inout) :: a
423 integer, dimension(n_mask) :: mask
424 integer :: i, j
425
426 !$omp parallel do private(i, j)
427 do i = 1, n_mask
428 j = mask(i)
429 a(i) = b(j)
430 end do
431 !$omp end parallel do
432
433 end subroutine masked_gather_copy
434
444 subroutine masked_scatter_copy_0(a, b, mask, n, n_mask)
445 integer, intent(in) :: n, n_mask
446 real(kind=rp), dimension(n_mask), intent(in) :: b
447 real(kind=rp), dimension(n), intent(inout) :: a
448 integer, dimension(0:n_mask) :: mask
449 integer :: i, j
450
451 !$omp parallel do private(i, j)
452 do i = 1, n_mask
453 j = mask(i)
454 a(j) = b(i)
455 end do
456 !$omp end parallel do
457
458 end subroutine masked_scatter_copy_0
459
469 subroutine masked_scatter_copy(a, b, mask, n, n_mask)
470 integer, intent(in) :: n, n_mask
471 real(kind=rp), dimension(n_mask), intent(in) :: b
472 real(kind=rp), dimension(n), intent(inout) :: a
473 integer, dimension(n_mask) :: mask
474 integer :: i, j
475
476 !$omp parallel do private(i, j)
477 do i = 1, n_mask
478 j = mask(i)
479 a(j) = b(i)
480 end do
481 !$omp end parallel do
482
483 end subroutine masked_scatter_copy
484
487 subroutine cfill_mask(a, c, n, mask, n_mask)
488 integer, intent(in) :: n, n_mask
489 real(kind=rp), dimension(n), intent(inout) :: a
490 real(kind=rp), intent(in) :: c
491 integer, dimension(n_mask), intent(in) :: mask
492 integer :: i
493
494 !$omp parallel do
495 do i = 1, n_mask
496 a(mask(i)) = c
497 end do
498 !$omp end parallel do
499
500 end subroutine cfill_mask
501
503 subroutine cmult(a, c, n)
504 integer, intent(in) :: n
505 real(kind=rp), dimension(n), intent(inout) :: a
506 real(kind=rp), intent(in) :: c
507 integer :: i
508
509 !$omp parallel do
510 do i = 1, n
511 a(i) = c * a(i)
512 end do
513 !$omp end parallel do
514
515 end subroutine cmult
516
518 subroutine cmult2(a, b, c, n)
519 integer, intent(in) :: n
520 real(kind=rp), dimension(n), intent(inout) :: a
521 real(kind=rp), dimension(n), intent(in) :: b
522 real(kind=rp), intent(in) :: c
523 integer :: i
524
525 !$omp parallel do
526 do i = 1, n
527 a(i) = c * b(i)
528 end do
529 !$omp end parallel do
530
531 end subroutine cmult2
532
534 subroutine cdiv(a, c, n)
535 integer, intent(in) :: n
536 real(kind=rp), dimension(n), intent(inout) :: a
537 real(kind=rp), intent(in) :: c
538 integer :: i
539
540 !$omp parallel do
541 do i = 1, n
542 a(i) = c / a(i)
543 end do
544 !$omp end parallel do
545
546 end subroutine cdiv
547
549 subroutine cdiv2(a, b, c, n)
550 integer, intent(in) :: n
551 real(kind=rp), dimension(n), intent(inout) :: a
552 real(kind=rp), dimension(n), intent(in) :: b
553 real(kind=rp), intent(in) :: c
554 integer :: i
555
556 !$omp parallel do
557 do i = 1, n
558 a(i) = c / b(i)
559 end do
560 !$omp end parallel do
561
562 end subroutine cdiv2
563
565 subroutine cadd(a, s, n)
566 integer, intent(in) :: n
567 real(kind=rp), dimension(n), intent(inout) :: a
568 real(kind=rp), intent(in) :: s
569 integer :: i
570
571 !$omp parallel do
572 do i = 1, n
573 a(i) = a(i) + s
574 end do
575 !$omp end parallel do
576
577 end subroutine cadd
578
580 subroutine cadd2(a, b, s, n)
581 integer, intent(in) :: n
582 real(kind=rp), dimension(n), intent(inout) :: a
583 real(kind=rp), dimension(n), intent(in) :: b
584 real(kind=rp), intent(in) :: s
585 integer :: i
586
587 !$omp parallel do
588 do i = 1,n
589 a(i) = b(i) + s
590 end do
591 !$omp end parallel do
592
593 end subroutine cadd2
594
596 subroutine cfill(a, c, n)
597 integer, intent(in) :: n
598 real(kind=rp), dimension(n), intent(inout) :: a
599 real(kind=rp), intent(in) :: c
600 integer :: i
601
602 !$omp parallel do
603 do i = 1, n
604 a(i) = c
605 end do
606 !$omp end parallel do
607
608 end subroutine cfill
609
611 subroutine cwrap(a, min_val, max_val, n)
612 integer, intent(in) :: n
613 real(kind=rp), dimension(n), intent(inout) :: a
614 real(kind=rp), intent(in) :: min_val, max_val
615 integer :: i
616
617 if (n .lt. 1 .or. max_val .le. min_val) return
618
619 !$omp parallel do
620 do i = 1, n
621 a(i) = modulo(a(i) - min_val, max_val - min_val) + min_val
622 end do
623 !$omp end parallel do
624
625 end subroutine cwrap
626
628 function glsum(a, n)
629 integer, intent(in) :: n
630 real(kind=rp), dimension(n) :: a
631 real(kind=rp) :: glsum
632 real(kind=xp) :: tmp
633 integer :: i, ierr
634
635 tmp = 0.0_rp
636 !$omp parallel do reduction(+:tmp)
637 do i = 1, n
638 tmp = tmp + a(i)
639 end do
640 !$omp end parallel do
641
642 call mpi_allreduce(mpi_in_place, tmp, 1, &
643 mpi_extra_precision, mpi_sum, neko_comm, ierr)
644 glsum = tmp
645
646 end function glsum
647
649 function glmax(a, n)
650 integer, intent(in) :: n
651 real(kind=rp), dimension(n) :: a
652 real(kind=rp) :: tmp, glmax
653 integer :: i, ierr
654
655 tmp = -huge(0.0_rp)
656 !$omp parallel do reduction(max:tmp)
657 do i = 1, n
658 tmp = max(tmp,a(i))
659 end do
660 !$omp end parallel do
661
662 call mpi_allreduce(tmp, glmax, 1, &
663 mpi_real_precision, mpi_max, neko_comm, ierr)
664
665 end function glmax
666
668 function glimax(a, n)
669 integer, intent(in) :: n
670 integer, dimension(n) :: a
671 integer :: tmp, glimax
672 integer :: i, ierr
673
674 tmp = -huge(0)
675 !$omp parallel do reduction(max:tmp)
676 do i = 1, n
677 tmp = max(tmp,a(i))
678 end do
679 !$omp end parallel do
680
681 call mpi_allreduce(tmp, glimax, 1, &
682 mpi_integer, mpi_max, neko_comm, ierr)
683
684 end function glimax
685
687 function glmin(a, n)
688 integer, intent(in) :: n
689 real(kind=rp), dimension(n) :: a
690 real(kind=rp) :: tmp, glmin
691 integer :: i, ierr
692
693 tmp = huge(0.0_rp)
694 !$omp parallel do reduction(min:tmp)
695 do i = 1, n
696 tmp = min(tmp,a(i))
697 end do
698 !$omp end parallel do
699
700 call mpi_allreduce(tmp, glmin, 1, &
701 mpi_real_precision, mpi_min, neko_comm, ierr)
702
703 end function glmin
704
706 function glimin(a, n)
707 integer, intent(in) :: n
708 integer, dimension(n) :: a
709 integer :: tmp, glimin
710 integer :: i, ierr
711
712 tmp = huge(0)
713 !$omp parallel do reduction(min:tmp)
714 do i = 1, n
715 tmp = min(tmp,a(i))
716 end do
717 !$omp end parallel do
718
719 call mpi_allreduce(tmp, glimin, 1, &
720 mpi_integer, mpi_min, neko_comm, ierr)
721
722 end function glimin
723
725 subroutine chsign(a, n)
726 integer, intent(in) :: n
727 real(kind=rp), dimension(n), intent(inout) :: a
728 integer :: i
729
730 !$omp parallel do
731 do i = 1, n
732 a(i) = -a(i)
733 end do
734 !$omp end parallel do
735
736 end subroutine chsign
737
739 function vlmax(vec,n) result(tmax)
740 integer :: n, i
741 real(kind=rp), intent(in) :: vec(n)
742 real(kind=rp) :: tmax
743
744 tmax = real(-99d20, rp)
745 !$omp parallel do reduction(max:tmax)
746 do i = 1, n
747 tmax = max(tmax, vec(i))
748 end do
749 !$omp end parallel do
750
751 end function vlmax
752
754 function vlmin(vec,n) result(tmin)
755 integer, intent(in) :: n
756 real(kind=rp), intent(in) :: vec(n)
757 real(kind=rp) :: tmin
758 integer :: i
759
760 tmin = real(99.0e20, rp)
761 !$omp parallel do reduction(min:tmin)
762 do i = 1, n
763 tmin = min(tmin, vec(i))
764 end do
765 !$omp end parallel do
766
767 end function vlmin
768
770 subroutine invcol1(a, n)
771 integer, intent(in) :: n
772 real(kind=rp), dimension(n), intent(inout) :: a
773 integer :: i
774
775 !$omp parallel do
776 do i = 1, n
777 a(i) = 1.0_xp / real(a(i), xp)
778 end do
779 !$omp end parallel do
780
781 end subroutine invcol1
782
784 subroutine invcol3(a, b, c, n)
785 integer, intent(in) :: n
786 real(kind=rp), dimension(n), intent(inout) :: a
787 real(kind=rp), dimension(n), intent(in) :: b, c
788 integer :: i
789
790 !$omp parallel do
791 do i = 1, n
792 a(i) = real(b(i), xp) / c(i)
793 end do
794 !$omp end parallel do
795
796 end subroutine invcol3
797
799 subroutine invers2(a, b, n)
800 integer, intent(in) :: n
801 real(kind=rp), dimension(n), intent(inout) :: a
802 real(kind=rp), dimension(n), intent(in) :: b
803 integer :: i
804
805 !$omp parallel do
806 do i = 1, n
807 a(i) = 1.0_xp / real(b(i), xp)
808 end do
809 !$omp end parallel do
810
811 end subroutine invers2
812
815 subroutine vcross(u1, u2, u3, v1, v2, v3, w1, w2, w3, n)
816 integer, intent(in) :: n
817 real(kind=rp), dimension(n), intent(in) :: v1, v2, v3
818 real(kind=rp), dimension(n), intent(in) :: w1, w2, w3
819 real(kind=rp), dimension(n), intent(out) :: u1, u2, u3
820 integer :: i
821
822 !$omp parallel do
823 do i = 1, n
824 u1(i) = v2(i)*w3(i) - v3(i)*w2(i)
825 u2(i) = v3(i)*w1(i) - v1(i)*w3(i)
826 u3(i) = v1(i)*w2(i) - v2(i)*w1(i)
827 end do
828 !$omp end parallel do
829
830 end subroutine vcross
831
834 subroutine vdot2(dot, u1, u2, v1, v2, n)
835 integer, intent(in) :: n
836 real(kind=rp), dimension(n), intent(in) :: u1, u2
837 real(kind=rp), dimension(n), intent(in) :: v1, v2
838 real(kind=rp), dimension(n), intent(out) :: dot
839 integer :: i
840
841 !$omp parallel do
842 do i = 1, n
843 dot(i) = u1(i)*v1(i) + u2(i)*v2(i)
844 end do
845 !$omp end parallel do
846
847 end subroutine vdot2
848
851 subroutine vdot3(dot, u1, u2, u3, v1, v2, v3, n)
852 integer, intent(in) :: n
853 real(kind=rp), dimension(n), intent(in) :: u1, u2, u3
854 real(kind=rp), dimension(n), intent(in) :: v1, v2, v3
855 real(kind=rp), dimension(n), intent(out) :: dot
856 integer :: i
857
858 !$omp parallel do
859 do i = 1, n
860 dot(i) = u1(i)*v1(i) + u2(i)*v2(i) + u3(i)*v3(i)
861 end do
862 !$omp end parallel do
863
864 end subroutine vdot3
865
867 function vlsc3(u, v, w, n) result(s)
868 integer, intent(in) :: n
869 real(kind=rp), dimension(n), intent(in) :: u, v, w
870 real(kind=rp) :: s
871 integer :: i
872
873 s = 0.0_rp
874 !$omp parallel do reduction(+:s)
875 do i = 1, n
876 s = s + u(i)*v(i)*w(i)
877 end do
878 !$omp end parallel do
879
880 end function vlsc3
881
883 function vlsc2(u, v, n) result(s)
884 integer, intent(in) :: n
885 real(kind=rp), dimension(n), intent(in) :: u, v
886 real(kind=rp) :: s
887 integer :: i
888
889 s = 0.0_rp
890 !$omp parallel do reduction(+:s)
891 do i = 1, n
892 s = s + u(i)*v(i)
893 end do
894 !$omp end parallel do
895
896 end function vlsc2
897
899 subroutine add2(a, b, n)
900 integer, intent(in) :: n
901 real(kind=rp), dimension(n), intent(inout) :: a
902 real(kind=rp), dimension(n), intent(in) :: b
903 integer :: i
904
905 !$omp parallel do
906 do i = 1, n
907 a(i) = a(i) + b(i)
908 end do
909 !$omp end parallel do
910
911 end subroutine add2
912
914 subroutine add3(a, b, c, n)
915 integer, intent(in) :: n
916 real(kind=rp), dimension(n), intent(inout) :: a
917 real(kind=rp), dimension(n), intent(in) :: b
918 real(kind=rp), dimension(n), intent(in) :: c
919 integer :: i
920
921 !$omp parallel do
922 do i = 1, n
923 a(i) = b(i) + c(i)
924 end do
925 !$omp end parallel do
926
927 end subroutine add3
928
930 subroutine add4(a, b, c, d, n)
931 integer, intent(in) :: n
932 real(kind=rp), dimension(n), intent(out) :: a
933 real(kind=rp), dimension(n), intent(in) :: d
934 real(kind=rp), dimension(n), intent(in) :: c
935 real(kind=rp), dimension(n), intent(in) :: b
936 integer :: i
937
938 !$omp parallel do
939 do i = 1, n
940 a(i) = b(i) + c(i) + d(i)
941 end do
942 !$omp end parallel do
943
944 end subroutine add4
945
947 subroutine sub2(a, b, n)
948 integer, intent(in) :: n
949 real(kind=rp), dimension(n), intent(inout) :: a
950 real(kind=rp), dimension(n), intent(in) :: b
951 integer :: i
952
953 !$omp parallel do
954 do i = 1, n
955 a(i) = a(i) - b(i)
956 end do
957 !$omp end parallel do
958
959 end subroutine sub2
960
962 subroutine sub3(a, b, c, n)
963 integer, intent(in) :: n
964 real(kind=rp), dimension(n), intent(inout) :: a
965 real(kind=rp), dimension(n), intent(in) :: b
966 real(kind=rp), dimension(n), intent(in) :: c
967 integer :: i
968
969 !$omp parallel do
970 do i = 1, n
971 a(i) = b(i) - c(i)
972 end do
973 !$omp end parallel do
974
975 end subroutine sub3
976
977
980 subroutine add2s1(a, b, c1, n)
981 integer, intent(in) :: n
982 real(kind=rp), dimension(n), intent(inout) :: a
983 real(kind=rp), dimension(n), intent(in) :: b
984 real(kind=rp), intent(in) :: c1
985 integer :: i
986
987 !$omp parallel do
988 do i = 1, n
989 a(i) = c1 * a(i) + b(i)
990 end do
991 !$omp end parallel do
992
993 end subroutine add2s1
994
997 subroutine add2s2(a, b, c1, n)
998 integer, intent(in) :: n
999 real(kind=rp), dimension(n), intent(inout) :: a
1000 real(kind=rp), dimension(n), intent(in) :: b
1001 real(kind=rp), intent(in) :: c1
1002 integer :: i
1003
1004 !$omp parallel do
1005 do i = 1, n
1006 a(i) = a(i) + c1 * b(i)
1007 end do
1008 !$omp end parallel do
1009
1010 end subroutine add2s2
1011
1013 subroutine addsqr2s2(a, b, c1, n)
1014 integer, intent(in) :: n
1015 real(kind=rp), dimension(n), intent(inout) :: a
1016 real(kind=rp), dimension(n), intent(in) :: b
1017 real(kind=rp), intent(in) :: c1
1018 integer :: i
1019
1020 !$omp parallel do
1021 do i = 1, n
1022 a(i) = a(i) + c1 * ( b(i) * b(i) )
1023 end do
1024 !$omp end parallel do
1025
1026 end subroutine addsqr2s2
1027
1029 subroutine invcol2(a, b, n)
1030 integer, intent(in) :: n
1031 real(kind=rp), dimension(n), intent(inout) :: a
1032 real(kind=rp), dimension(n), intent(in) :: b
1033 integer :: i
1034
1035 !$omp parallel do
1036 do i = 1, n
1037 a(i) = real(a(i), xp) / b(i)
1038 end do
1039 !$omp end parallel do
1040
1041 end subroutine invcol2
1042
1043
1045 subroutine col2(a, b, n)
1046 integer, intent(in) :: n
1047 real(kind=rp), dimension(n), intent(inout) :: a
1048 real(kind=rp), dimension(n), intent(in) :: b
1049 integer :: i
1050
1051 !$omp parallel do
1052 do i = 1, n
1053 a(i) = a(i) * b(i)
1054 end do
1055 !$omp end parallel do
1056
1057 end subroutine col2
1058
1060 subroutine col3(a, b, c, n)
1061 integer, intent(in) :: n
1062 real(kind=rp), dimension(n), intent(inout) :: a
1063 real(kind=rp), dimension(n), intent(in) :: b
1064 real(kind=rp), dimension(n), intent(in) :: c
1065 integer :: i
1066
1067 !$omp parallel do
1068 do i = 1, n
1069 a(i) = b(i) * c(i)
1070 end do
1071 !$omp end parallel do
1072
1073 end subroutine col3
1074
1076 subroutine subcol3(a, b, c, n)
1077 integer, intent(in) :: n
1078 real(kind=rp), dimension(n), intent(inout) :: a
1079 real(kind=rp), dimension(n), intent(in) :: b
1080 real(kind=rp), dimension(n), intent(in) :: c
1081 integer :: i
1082
1083 !$omp parallel do
1084 do i = 1, n
1085 a(i) = a(i) - b(i) * c(i)
1086 end do
1087 !$omp end parallel do
1088
1089 end subroutine subcol3
1090
1092 subroutine add3s2(a, b, c, c1, c2 ,n)
1093 integer, intent(in) :: n
1094 real(kind=rp), dimension(n), intent(inout) :: a
1095 real(kind=rp), dimension(n), intent(in) :: b
1096 real(kind=rp), dimension(n), intent(in) :: c
1097 real(kind=rp), intent(in) :: c1, c2
1098 integer :: i
1099
1100 !$omp parallel do
1101 do i = 1, n
1102 a(i) = c1 * b(i) + c2 * c(i)
1103 end do
1104 !$omp end parallel do
1105
1106 end subroutine add3s2
1107
1109 subroutine add4s3(a, b, c, d, c1, c2, c3, n)
1110 integer, intent(in) :: n
1111 real(kind=rp), dimension(n), intent(inout) :: a
1112 real(kind=rp), dimension(n), intent(in) :: b
1113 real(kind=rp), dimension(n), intent(in) :: c
1114 real(kind=rp), dimension(n), intent(in) :: d
1115 real(kind=rp), intent(in) :: c1, c2, c3
1116 integer :: i
1117
1118 !$omp parallel do
1119 do i = 1, n
1120 a(i) = c1 * b(i) + c2 * c(i) + c3 * d(i)
1121 end do
1122 !$omp end parallel do
1123
1124 end subroutine add4s3
1125
1127 subroutine add5s4(a, b, c, d, e, c1, c2, c3, c4, n)
1128 integer, intent(in) :: n
1129 real(kind=rp), dimension(n), intent(inout) :: a
1130 real(kind=rp), dimension(n), intent(in) :: b
1131 real(kind=rp), dimension(n), intent(in) :: c
1132 real(kind=rp), dimension(n), intent(in) :: d
1133 real(kind=rp), dimension(n), intent(in) :: e
1134 real(kind=rp), intent(in) :: c1, c2, c3, c4
1135 integer :: i
1136
1137 !$omp parallel do
1138 do i = 1, n
1139 a(i) = a(i) + c1 * b(i) + c2 * c(i) + c3 * d(i) + c4 * e(i)
1140 end do
1141 !$omp end parallel do
1142
1143 end subroutine add5s4
1144
1146 subroutine subcol4(a, b, c, d, n)
1147 integer, intent(in) :: n
1148 real(kind=rp), dimension(n), intent(inout) :: a
1149 real(kind=rp), dimension(n), intent(in) :: b
1150 real(kind=rp), dimension(n), intent(in) :: c
1151 real(kind=rp), dimension(n), intent(in) :: d
1152 integer :: i
1153
1154 !$omp parallel do
1155 do i = 1, n
1156 a(i) = a(i) - b(i) * c(i) * d(i)
1157 end do
1158 !$omp end parallel do
1159
1160 end subroutine subcol4
1161
1163 subroutine addcol3(a, b, c, n)
1164 integer, intent(in) :: n
1165 real(kind=rp), dimension(n), intent(inout) :: a
1166 real(kind=rp), dimension(n), intent(in) :: b
1167 real(kind=rp), dimension(n), intent(in) :: c
1168 integer :: i
1169
1170 !$omp parallel do
1171 do i = 1, n
1172 a(i) = a(i) + b(i) * c(i)
1173 end do
1174 !$omp end parallel do
1175
1176 end subroutine addcol3
1177
1179 subroutine addcol4(a, b, c, d, n)
1180 integer, intent(in) :: n
1181 real(kind=rp), dimension(n), intent(inout) :: a
1182 real(kind=rp), dimension(n), intent(in) :: b
1183 real(kind=rp), dimension(n), intent(in) :: c
1184 real(kind=rp), dimension(n), intent(in) :: d
1185 integer :: i
1186
1187 !$omp parallel do
1188 do i = 1, n
1189 a(i) = a(i) + b(i) * c(i) * d(i)
1190 end do
1191 !$omp end parallel do
1192
1193 end subroutine addcol4
1194
1196 subroutine addcol3s2(a, b, c, s, n)
1197 integer, intent(in) :: n
1198 real(kind=rp), dimension(n), intent(inout) :: a
1199 real(kind=rp), dimension(n), intent(in) :: b
1200 real(kind=rp), dimension(n), intent(in) :: c
1201 real(kind=rp), intent(in) :: s
1202 integer :: i
1203
1204 !$omp parallel do
1205 do i = 1, n
1206 a(i) = a(i) + s * b(i) * c(i)
1207 end do
1208 !$omp end parallel do
1209
1210 end subroutine addcol3s2
1211
1213 subroutine ascol5(a, b, c, d, e, n)
1214 integer, intent(in) :: n
1215 real(kind=rp), dimension(n), intent(inout) :: a
1216 real(kind=rp), dimension(n), intent(in) :: b
1217 real(kind=rp), dimension(n), intent(in) :: c
1218 real(kind=rp), dimension(n), intent(in) :: d
1219 real(kind=rp), dimension(n), intent(in) :: e
1220 integer :: i
1221
1222 !$omp parallel do
1223 do i = 1, n
1224 a(i) = b(i)*c(i) - d(i)*e(i)
1225 end do
1226 !$omp end parallel do
1227
1228 end subroutine ascol5
1229
1231 subroutine p_update(a, b, c, c1, c2, n)
1232 integer, intent(in) :: n
1233 real(kind=rp), dimension(n), intent(inout) :: a
1234 real(kind=rp), dimension(n), intent(in) :: b
1235 real(kind=rp), dimension(n), intent(in) :: c
1236 real(kind=rp), intent(in) :: c1, c2
1237 integer :: i
1238
1239 !$omp parallel do
1240 do i = 1, n
1241 a(i) = b(i) + c1*(a(i)-c2*c(i))
1242 end do
1243 !$omp end parallel do
1244
1245 end subroutine p_update
1246
1248 subroutine x_update(a, b, c, c1, c2, n)
1249 integer, intent(in) :: n
1250 real(kind=rp), dimension(n), intent(inout) :: a
1251 real(kind=rp), dimension(n), intent(in) :: b
1252 real(kind=rp), dimension(n), intent(in) :: c
1253 real(kind=rp), intent(in) :: c1, c2
1254 integer :: i
1255
1256 !$omp parallel do
1257 do i = 1, n
1258 a(i) = a(i) + c1*b(i)+c2*c(i)
1259 end do
1260 !$omp end parallel do
1261
1262 end subroutine x_update
1263
1265 function glsc2(a, b, n)
1266 integer, intent(in) :: n
1267 real(kind=rp), dimension(n), intent(in) :: a
1268 real(kind=rp), dimension(n), intent(in) :: b
1269 real(kind=rp) :: glsc2
1270 real(kind=xp) :: tmp
1271 integer :: i, ierr
1272
1273 tmp = 0.0_xp
1274 !$omp parallel do reduction(+:tmp)
1275 do i = 1, n
1276 tmp = tmp + a(i) * b(i)
1277 end do
1278 !$omp end parallel do
1279
1280 call mpi_allreduce(mpi_in_place, tmp, 1, &
1281 mpi_extra_precision, mpi_sum, neko_comm, ierr)
1282 glsc2 = tmp
1283 end function glsc2
1284
1286 function glsc3(a, b, c, n)
1287 integer, intent(in) :: n
1288 real(kind=rp), dimension(n), intent(in) :: a
1289 real(kind=rp), dimension(n), intent(in) :: b
1290 real(kind=rp), dimension(n), intent(in) :: c
1291 real(kind=rp) :: glsc3
1292 real(kind=xp) :: tmp
1293 integer :: i, ierr
1294
1295 tmp = 0.0_xp
1296 !$omp parallel do reduction(+:tmp)
1297 do i = 1, n
1298 tmp = tmp + a(i) * b(i) * c(i)
1299 end do
1300 !$omp end parallel do
1301
1302 call mpi_allreduce(mpi_in_place, tmp, 1, &
1303 mpi_extra_precision, mpi_sum, neko_comm, ierr)
1304 glsc3 = tmp
1305
1306 end function glsc3
1307 function glsc4(a, b, c, d, n)
1308 integer, intent(in) :: n
1309 real(kind=rp), dimension(n), intent(in) :: a
1310 real(kind=rp), dimension(n), intent(in) :: b
1311 real(kind=rp), dimension(n), intent(in) :: c
1312 real(kind=rp), dimension(n), intent(in) :: d
1313 real(kind=rp) :: glsc4
1314 real(kind=xp) :: tmp
1315 integer :: i, ierr
1316
1317 tmp = 0.0_xp
1318 !$omp parallel do reduction(+:tmp)
1319 do i = 1, n
1320 tmp = tmp + a(i) * b(i) * c(i) * d(i)
1321 end do
1322 !$omp end parallel do
1323
1324 call mpi_allreduce(mpi_in_place, tmp, 1, &
1325 mpi_extra_precision, mpi_sum, neko_comm, ierr)
1326 glsc4 = tmp
1327
1328 end function glsc4
1329
1332 function glsubnorm(a, b, n)
1333 integer, intent(in) :: n
1334 real(kind=rp), dimension(n), intent(in) :: a
1335 real(kind=rp), dimension(n), intent(in) :: b
1336 real(kind=rp) :: glsubnorm
1337 real(kind=xp) :: tmp
1338 integer :: i, ierr
1339
1340 tmp = 0.0_xp
1341 !$omp parallel do reduction(+:tmp)
1342 do i = 1, n
1343 tmp = tmp + (a(i) - b(i))**2
1344 end do
1345 !$omp end parallel do
1346
1347 call mpi_allreduce(mpi_in_place, tmp, 1, &
1348 mpi_extra_precision, mpi_sum, neko_comm, ierr)
1349 glsubnorm = sqrt(tmp)
1350
1351 end function glsubnorm
1352
1358 subroutine sortrp(a, ind, n)
1359 integer, intent(in) :: n
1360 real(kind=rp), intent(inout) :: a(n)
1361 integer, intent(out) :: ind(n)
1362 real(kind=rp) :: aa
1363 integer :: j, ir, i, ii, l
1364
1365 do j = 1, n
1366 ind(j) = j
1367 end do
1368
1369 if (n .le. 1) return
1370
1371
1372 l = n/2+1
1373 ir = n
1374 do while (.true.)
1375 if (l .gt. 1) then
1376 l = l-1
1377 aa = a(l)
1378 ii = ind(l)
1379 else
1380 aa = a(ir)
1381 ii = ind(ir)
1382 a(ir) = a(1)
1383 ind(ir) = ind(1)
1384 ir = ir - 1
1385 if (ir .eq. 1) then
1386 a(1) = aa
1387 ind(1) = ii
1388 return
1389 end if
1390 end if
1391 i = l
1392 j = l+l
1393 do while (j .le. ir)
1394 if (j .lt. ir) then
1395 if ( a(j) .lt. a(j+1) ) j = j + 1
1396 end if
1397 if (aa .lt. a(j)) then
1398 a(i) = a(j)
1399 ind(i) = ind(j)
1400 i = j
1401 j = j+j
1402 else
1403 j = ir+1
1404 end if
1405 end do
1406 a(i) = aa
1407 ind(i) = ii
1408 end do
1409 end subroutine sortrp
1410
1416 subroutine sorti4(a, ind, n)
1417 integer, intent(in) :: n
1418 integer(i4), intent(inout) :: a(n)
1419 integer, intent(out) :: ind(n)
1420 integer(i4) :: aa
1421 integer :: j, ir, i, ii, l
1422
1423 do j = 1, n
1424 ind(j) = j
1425 end do
1426
1427 if (n .le. 1) return
1428
1429 l = n/2+1
1430 ir = n
1431 do while (.true.)
1432 if (l .gt. 1) then
1433 l = l - 1
1434 aa = a(l)
1435 ii = ind(l)
1436 else
1437 aa = a(ir)
1438 ii = ind(ir)
1439 a(ir) = a( 1)
1440 ind(ir) = ind( 1)
1441 ir = ir - 1
1442 if (ir .eq. 1) then
1443 a(1) = aa
1444 ind(1) = ii
1445 return
1446 end if
1447 end if
1448 i = l
1449 j = l + l
1450 do while (j .le. ir)
1451 if (j .lt. ir) then
1452 if ( a(j) .lt. a(j + 1) ) j = j + 1
1453 end if
1454 if (aa .lt. a(j)) then
1455 a(i) = a(j)
1456 ind(i) = ind(j)
1457 i = j
1458 j = j + j
1459 else
1460 j = ir + 1
1461 end if
1462 end do
1463 a(i) = aa
1464 ind(i) = ii
1465 end do
1466 end subroutine sorti4
1467
1472 subroutine swapdp(b, ind, n)
1473 integer, intent(in) :: n
1474 real(kind=rp), intent(inout) :: b(n)
1475 integer, intent(in) :: ind(n)
1476 real(kind=rp) :: temp(n)
1477 integer :: i, jj
1478
1479 !$omp parallel private(i, jj)
1480 !$omp do
1481 do i = 1, n
1482 temp(i) = b(i)
1483 end do
1484 !$omp end do
1485 !$omp do
1486 do i = 1, n
1487 jj = ind(i)
1488 b(i) = temp(jj)
1489 end do
1490 !$omp end do
1491 !$omp end parallel
1492
1493 end subroutine swapdp
1494
1499 subroutine swapi4(b, ind, n)
1500 integer, intent(in) :: n
1501 integer(i4), intent(inout) :: b(n)
1502 integer, intent(in) :: ind(n)
1503 integer(i4) :: temp(n)
1504 integer :: i, jj
1505
1506 !$omp parallel private(i, jj)
1507 !$omp do
1508 do i = 1, n
1509 temp(i) = b(i)
1510 end do
1511 !$omp end do
1512 !$omp do
1513 do i = 1, n
1514 jj = ind(i)
1515 b(i) = temp(jj)
1516 end do
1517 !$omp end do
1518 !$omp end parallel
1519
1520 end subroutine swapi4
1521
1526 subroutine reorddp(b, ind, n)
1527 integer, intent(in) :: n
1528 real(kind=rp), intent(inout) :: b(n)
1529 integer, intent(in) :: ind(n)
1530 real(kind=rp) :: temp(n)
1531 integer :: i, jj
1532
1533 !$omp parallel private(i, jj)
1534 !$omp do
1535 do i = 1, n
1536 temp(i) = b(i)
1537 end do
1538 !$omp end do
1539 !$omp do
1540 do i = 1, n
1541 jj = ind(i)
1542 b(jj) = temp(i)
1543 end do
1544 !$omp end do
1545 !$omp end parallel
1546
1547 end subroutine reorddp
1548
1553 subroutine reordi4(b, ind, n)
1554 integer, intent(in) :: n
1555 integer(i4), intent(inout) :: b(n)
1556 integer, intent(in) :: ind(n)
1557 integer(i4) :: temp(n)
1558 integer :: i, jj
1559
1560 !$omp parallel private(i, jj)
1561 !$omp do
1562 do i = 1, n
1563 temp(i) = b(i)
1564 end do
1565 !$omp end do
1566 !$omp do
1567 do i = 1, n
1568 jj = ind(i)
1569 b(jj) = temp(i)
1570 end do
1571 !$omp end do
1572 !$omp end parallel
1573
1574 end subroutine reordi4
1575
1580 subroutine flipvdp(b, ind, n)
1581 integer, intent(in) :: n
1582 real(kind=rp), intent(inout) :: b(n)
1583 integer, intent(inout) :: ind(n)
1584 real(kind=rp) :: temp(n)
1585 integer :: tempind(n)
1586 integer :: i, jj
1587
1588 !$omp parallel private(i, jj)
1589 !$omp do
1590 do i = 1, n
1591 jj = n+1-i
1592 temp(jj) = b(i)
1593 tempind(jj) = ind(i)
1594 end do
1595 !$omp end do
1596 !$omp do
1597 do i = 1,n
1598 b(i) = temp(i)
1599 ind(i) = tempind(i)
1600 end do
1601 !$omp end do
1602 !$omp end parallel
1603
1604 end subroutine flipvdp
1605
1610 subroutine flipvi4(b, ind, n)
1611 integer, intent(in) :: n
1612 integer(i4), intent(inout) :: b(n)
1613 integer, intent(inout) :: ind(n)
1614 integer(i4) :: temp(n)
1615 integer :: tempind(n)
1616 integer :: i, jj
1617
1618 !$omp parallel private(i, jj)
1619 !$omp do
1620 do i = 1, n
1621 jj = n+1-i
1622 temp(jj) = b(i)
1623 tempind(jj) = ind(i)
1624 end do
1625 !$omp end do
1626 !$omp do
1627 do i = 1,n
1628 b(i) = temp(i)
1629 ind(i) = tempind(i)
1630 end do
1631 !$omp end do
1632 !$omp end parallel
1633
1634 end subroutine flipvi4
1635
1639 subroutine absval(a, n)
1640 integer, intent(in) :: n
1641 real(kind=rp), dimension(n), intent(inout) :: a
1642 integer :: i
1643
1644 !$omp parallel do
1645 do i = 1, n
1646 a(i) = abs(a(i))
1647 end do
1648 !$omp end parallel do
1649
1650 end subroutine absval
1651
1652 ! ========================================================================== !
1653 ! Point-wise operations
1654
1656 subroutine pwmax2(a, b, n)
1657 integer, intent(in) :: n
1658 real(kind=rp), dimension(n), intent(inout) :: a
1659 real(kind=rp), dimension(n), intent(in) :: b
1660 integer :: i
1661
1662 !$omp parallel do
1663 do i = 1, n
1664 a(i) = max(a(i), b(i))
1665 end do
1666 !$omp end parallel do
1667
1668 end subroutine pwmax2
1669
1671 subroutine pwmax3(a, b, c, n)
1672 integer, intent(in) :: n
1673 real(kind=rp), dimension(n), intent(inout) :: a
1674 real(kind=rp), dimension(n), intent(in) :: b, c
1675 integer :: i
1676
1677 !$omp parallel do
1678 do i = 1, n
1679 a(i) = max(b(i), c(i))
1680 end do
1681 !$omp end parallel do
1682
1683 end subroutine pwmax3
1684
1686 subroutine cpwmax2(a, b, n)
1687 integer, intent(in) :: n
1688 real(kind=rp), dimension(n), intent(inout) :: a
1689 real(kind=rp), intent(in) :: b
1690 integer :: i
1691
1692 !$omp parallel do
1693 do i = 1, n
1694 a(i) = max(a(i), b)
1695 end do
1696 !$omp end parallel do
1697
1698 end subroutine cpwmax2
1699
1701 subroutine cpwmax3(a, b, c, n)
1702 integer, intent(in) :: n
1703 real(kind=rp), dimension(n), intent(inout) :: a
1704 real(kind=rp), dimension(n), intent(in) :: b
1705 real(kind=rp), intent(in) :: c
1706 integer :: i
1707
1708 !$omp parallel do
1709 do i = 1, n
1710 a(i) = max(b(i), c)
1711 end do
1712 !$omp end parallel do
1713
1714 end subroutine cpwmax3
1715
1717 subroutine pwmin2(a, b, n)
1718 integer, intent(in) :: n
1719 real(kind=rp), dimension(n), intent(inout) :: a
1720 real(kind=rp), dimension(n), intent(in) :: b
1721 integer :: i
1722
1723 !$omp parallel do
1724 do i = 1, n
1725 a(i) = min(a(i), b(i))
1726 end do
1727 !$omp end parallel do
1728
1729 end subroutine pwmin2
1730
1732 subroutine pwmin3(a, b, c, n)
1733 integer, intent(in) :: n
1734 real(kind=rp), dimension(n), intent(inout) :: a
1735 real(kind=rp), dimension(n), intent(in) :: b, c
1736 integer :: i
1737
1738 !$omp parallel do
1739 do i = 1, n
1740 a(i) = min(b(i), c(i))
1741 end do
1742 !$omp end parallel do
1743
1744 end subroutine pwmin3
1745
1747 subroutine cpwmin2(a, b, n)
1748 integer, intent(in) :: n
1749 real(kind=rp), dimension(n), intent(inout) :: a
1750 real(kind=rp), intent(in) :: b
1751 integer :: i
1752
1753 !$omp parallel do
1754 do i = 1, n
1755 a(i) = min(a(i), b)
1756 end do
1757 !$omp end parallel do
1758
1759 end subroutine cpwmin2
1760
1762 subroutine cpwmin3(a, b, c, n)
1763 integer, intent(in) :: n
1764 real(kind=rp), dimension(n), intent(inout) :: a
1765 real(kind=rp), dimension(n), intent(in) :: b
1766 real(kind=rp), intent(in) :: c
1767 integer :: i
1768
1769 !$omp parallel do
1770 do i = 1, n
1771 a(i) = min(b(i), c)
1772 end do
1773 !$omp end parallel do
1774
1775 end subroutine cpwmin3
1776
1777 ! M33INV and M44INV by David G. Simpson pure function version from
1778 ! https://fortranwiki.org/fortran/show/Matrix+inversion
1779 ! Invert 3x3 matrix
1780 function matinv39(a11, a12, a13, a21, a22, a23, a31, a32, a33) &
1781 result(b)
1782 real(kind=rp), intent(in) :: a11, a12, a13, a21, a22, a23, a31, a32, a33
1783 real(xp) :: a(3,3) !! Matrix
1784 real(rp) :: b(3,3) !! Inverse matrix
1785 a(1,1) = a11
1786 a(1,2) = a12
1787 a(1,3) = a13
1788 a(2,1) = a21
1789 a(2,2) = a22
1790 a(2,3) = a23
1791 a(3,1) = a31
1792 a(3,2) = a32
1793 a(3,3) = a33
1794 b = matinv3(a)
1795 end function matinv39
1796
1801 function matinv3(A) result(B)
1802 !! Performs a direct calculation of the inverse of a 3×3 matrix.
1803 real(kind=xp), intent(in) :: a(3,3) !! Matrix
1804 real(kind=xp) :: b(3,3) !! Inverse matrix
1805 real(kind=xp) :: detinv
1806
1807 ! Calculate the inverse determinant of the matrix
1808 ! first index x,y,z, second r, s, t
1809 detinv = 1.0_xp / real(a(1,1)*a(2,2)*a(3,3) - a(1,1)*a(2,3)*a(3,2) &
1810 - a(1,2)*a(2,1)*a(3,3) + a(1,2)*a(2,3)*a(3,1)&
1811 + a(1,3)*a(2,1)*a(3,2) - a(1,3)*a(2,2)*a(3,1), xp)
1812 ! Calculate the inverse of the matrix
1813 ! first index r, s, t, second x, y, z
1814 b(1,1) = +detinv * (a(2,2)*a(3,3) - a(2,3)*a(3,2))
1815 b(2,1) = -detinv * (a(2,1)*a(3,3) - a(2,3)*a(3,1))
1816 b(3,1) = +detinv * (a(2,1)*a(3,2) - a(2,2)*a(3,1))
1817 b(1,2) = -detinv * (a(1,2)*a(3,3) - a(1,3)*a(3,2))
1818 b(2,2) = +detinv * (a(1,1)*a(3,3) - a(1,3)*a(3,1))
1819 b(3,2) = -detinv * (a(1,1)*a(3,2) - a(1,2)*a(3,1))
1820 b(1,3) = +detinv * (a(1,2)*a(2,3) - a(1,3)*a(2,2))
1821 b(2,3) = -detinv * (a(1,1)*a(2,3) - a(1,3)*a(2,1))
1822 b(3,3) = +detinv * (a(1,1)*a(2,2) - a(1,2)*a(2,1))
1823 end function matinv3
1824
1827 function math_stepf(x) result(val)
1828 real(kind=rp), intent(in) :: x
1829 real(kind=rp) :: val
1830 real(kind=rp), parameter :: xdmin = 0.0001_rp
1831 real(kind=rp), parameter :: xdmax = 0.9999_rp
1832 real(kind=rp) :: g
1833
1834 if (x <= xdmin) then
1835 ! Below the lower bound, the function is 0
1836 val = 0.0_rp
1837 else if (x >= xdmax) then
1838 ! Above the upper bound, the function is 1
1839 val = 1.0_rp
1840 else
1841 ! g(x) = 1/(x-1) + 1/x
1842 g = (1.0_rp / (x - 1.0_rp)) + (1.0_rp / x)
1843
1844 ! The sigmoid: S(x) = 1 / (1 + exp(g))
1845 val = 1.0_rp / (1.0_rp + exp(g))
1846 end if
1847 end function math_stepf
1848
1850 function math_dstepf(x) result(val)
1851 real(kind=rp), intent(in) :: x
1852 real(kind=rp) :: val
1853 real(kind=rp), parameter :: xdmin = 0.0001_rp
1854 real(kind=rp), parameter :: xdmax = 0.9999_rp
1855 real(kind=rp) :: arg, g, dg, s_val
1856
1857 if (x <= xdmin .or. x >= xdmax) then
1858 val = 0.0_rp
1859 else
1860 ! The step function is S(x) = 1 / (1 + exp(g(x)))
1861 ! where g(x) = 1/(x-1) + 1/x
1862 ! S'(x) = -S(x) * (1 - S(x)) * g'(x)
1863
1864 g = (1.0_rp / (x - 1.0_rp)) + (1.0_rp / x)
1865
1866 ! Derivative of g(x)
1867 dg = -(1.0_rp / ((x - 1.0_rp)**2)) - (1.0_rp / (x**2))
1868
1869 ! Recompute S(x) locally
1870 s_val = 1.0_rp / (1.0_rp + exp(g))
1871
1872 val = -s_val * (1.0_rp - s_val) * dg
1873 end if
1874 end function math_dstepf
1875
1876end module math
__inline__ __device__ void nonlinear_index(const int idx, const int lx, int *index)
Definition bc_utils.h:44
double real
Definition comm.F90:1
type(mpi_datatype), public mpi_real_precision
MPI type for working precision of REAL types.
Definition comm.F90:53
type(mpi_comm), public neko_comm
MPI communicator.
Definition comm.F90:45
type(mpi_datatype), public mpi_extra_precision
Definition comm.F90:54
Object for handling masks in Neko.
Definition mask.f90:34
Definition math.f90:60
subroutine, public cmult(a, c, n)
Multiplication by constant c .
Definition math.f90:504
subroutine, public cmult2(a, b, c, n)
Multiplication by constant c .
Definition math.f90:519
subroutine, public row_zero(a, m, n, e)
Sets row e to 0 in matrix a.
Definition math.f90:263
subroutine, public invcol2(a, b, n)
Vector division .
Definition math.f90:1030
real(kind=rp) function, public vlsc2(u, v, n)
Compute multiplication sum .
Definition math.f90:884
pure logical function, public dabscmp(x, y, tol)
Return double precision absolute comparison .
Definition math.f90:135
real(kind=rp), parameter, public pi
Definition math.f90:76
pure logical function qabscmp(x, y, tol)
Return double precision absolute comparison .
Definition math.f90:150
real(kind=rp) function, public glsc3(a, b, c, n)
Weighted inner product .
Definition math.f90:1287
subroutine, public ascol5(a, b, c, d, e, n)
Returns .
Definition math.f90:1214
subroutine, public addcol3s2(a, b, c, s, n)
Returns .
Definition math.f90:1197
subroutine, public masked_scatter_copy(a, b, mask, n, n_mask)
Scatter a contigous vector to masked positions in a target array .
Definition math.f90:470
subroutine, public invers2(a, b, n)
Compute inverted vector .
Definition math.f90:800
subroutine, public cadd2(a, b, s, n)
Add a scalar to vector .
Definition math.f90:581
subroutine, public face_masked_gather_copy_0(a, b, mask, facet, lx, ly, lz, n_mask)
Gather values from a face-local SEM field to a reduced contiguous vector.
Definition math.f90:385
real(rp) function, dimension(3, 3), public matinv39(a11, a12, a13, a21, a22, a23, a31, a32, a33)
Definition math.f90:1782
subroutine, public cadd(a, s, n)
Add a scalar to vector .
Definition math.f90:566
subroutine, public masked_copy(a, b, mask, n, n_mask)
Copy a masked vector .
Definition math.f90:335
subroutine reorddp(b, ind, n)
reorder double precision array - inverse of swap
Definition math.f90:1527
subroutine, public addsqr2s2(a, b, c1, n)
Returns .
Definition math.f90:1014
subroutine, public cwrap(a, min_val, max_val, n)
Wrap value around a range [min, max)
Definition math.f90:612
real(kind=rp) function, public glsc4(a, b, c, d, n)
Definition math.f90:1308
subroutine, public cdiv2(a, b, c, n)
Division of constant c by elements of a .
Definition math.f90:550
real(kind=rp) function, public math_stepf(x)
Smooth step function S(x) Returns 0 for x <= 0, 1 for x >= 1, and smooth transition in between.
Definition math.f90:1828
subroutine swapdp(b, ind, n)
sort double precision array acording to ind vector
Definition math.f90:1473
subroutine flipvi4(b, ind, n)
Flip single integer vector b and ind.
Definition math.f90:1611
subroutine, public add2s1(a, b, c1, n)
Vector addition with scalar multiplication (multiplication on first argument)
Definition math.f90:981
subroutine, public cpwmin2(a, b, n)
Point-wise minimum of scalar and vector .
Definition math.f90:1748
real(kind=rp) function, public glsc2(a, b, n)
Weighted inner product .
Definition math.f90:1266
subroutine, public masked_scatter_copy_0(a, b, mask, n, n_mask)
Scatter a contigous vector to masked positions in a target array .
Definition math.f90:445
subroutine, public subcol3(a, b, c, n)
Returns .
Definition math.f90:1077
subroutine, public rone(a, n)
Set all elements to one.
Definition math.f90:277
subroutine flipvdp(b, ind, n)
Flip double precision vector b and ind.
Definition math.f90:1581
subroutine, public cpwmin3(a, b, c, n)
Point-wise minimum of scalar and vector .
Definition math.f90:1763
subroutine, public pwmax3(a, b, c, n)
Point-wise maximum of two vectors .
Definition math.f90:1672
subroutine, public masked_gather_copy(a, b, mask, n, n_mask)
Gather a masked vector to reduced contigous vector .
Definition math.f90:420
subroutine, public x_update(a, b, c, c1, c2, n)
Returns .
Definition math.f90:1249
subroutine, public add3(a, b, c, n)
Vector addition .
Definition math.f90:915
subroutine swapi4(b, ind, n)
sort single integer array acording to ind vector
Definition math.f90:1500
integer function, public glimin(a, n)
Min of an integer vector of length n.
Definition math.f90:707
real(kind=rp) function, public glsum(a, n)
Sum a vector of length n.
Definition math.f90:629
subroutine, public sub3(a, b, c, n)
Vector subtraction .
Definition math.f90:963
subroutine, public addcol4(a, b, c, d, n)
Returns .
Definition math.f90:1180
subroutine, public add2(a, b, n)
Vector addition .
Definition math.f90:900
subroutine, public cfill(a, c, n)
Set all elements to a constant c .
Definition math.f90:597
subroutine, public absval(a, n)
Take the absolute value of an array.
Definition math.f90:1640
subroutine, public invcol3(a, b, c, n)
Invert a vector .
Definition math.f90:785
subroutine, public add3s2(a, b, c, c1, c2, n)
Returns .
Definition math.f90:1093
real(kind=xp) function, dimension(3, 3), public matinv3(a)
Performs a direct calculation of the inverse of a 3×3 matrix. M33INV and M44INV by David G....
Definition math.f90:1802
subroutine, public pwmax2(a, b, n)
Point-wise maximum of two vectors .
Definition math.f90:1657
subroutine, public pwmin2(a, b, n)
Point-wise minimum of two vectors .
Definition math.f90:1718
subroutine, public masked_gather_copy_0(a, b, mask, n, n_mask)
Gather a masked vector to reduced contigous vector .
Definition math.f90:360
subroutine, public subcol4(a, b, c, d, n)
Returns .
Definition math.f90:1147
subroutine sorti4(a, ind, n)
Heap Sort for single integer arrays.
Definition math.f90:1417
subroutine, public addcol3(a, b, c, n)
Returns .
Definition math.f90:1164
subroutine, public invcol1(a, n)
Invert a vector .
Definition math.f90:771
subroutine, public cdiv(a, c, n)
Division of constant c by elements of a .
Definition math.f90:535
real(kind=rp), parameter, public neko_m_ln2
Definition math.f90:73
subroutine, public chsign(a, n)
Change sign of vector .
Definition math.f90:726
subroutine, public cpwmax3(a, b, c, n)
Point-wise maximum of scalar and vector .
Definition math.f90:1702
subroutine, public col2(a, b, n)
Vector multiplication .
Definition math.f90:1046
subroutine, public izero(a, n)
Zero an integer vector.
Definition math.f90:249
real(kind=rp) function, public glmax(a, n)
Max of a vector of length n.
Definition math.f90:650
subroutine, public copy(a, b, n)
Copy a vector .
Definition math.f90:291
subroutine, public add4s3(a, b, c, d, c1, c2, c3, n)
Returns .
Definition math.f90:1110
subroutine, public add4(a, b, c, d, n)
Vector addition .
Definition math.f90:931
subroutine, public col3(a, b, c, n)
Vector multiplication with 3 vectors .
Definition math.f90:1061
subroutine, public add5s4(a, b, c, d, e, c1, c2, c3, c4, n)
Returns .
Definition math.f90:1128
real(kind=rp) function, public math_dstepf(x)
Derivative of math_stepf with respect to x: d(stepf)/dx.
Definition math.f90:1851
pure logical function drelcmp(x, y, eps)
Return double precision relative comparison .
Definition math.f90:181
real(kind=rp), parameter, public neko_eps
Machine epsilon .
Definition math.f90:70
subroutine, public vdot3(dot, u1, u2, u3, v1, v2, v3, n)
Compute a dot product (3-d version) assuming vector components etc.
Definition math.f90:852
pure logical function, public sabscmp(x, y, tol)
Return single precision absolute comparison .
Definition math.f90:120
pure logical function qrelcmp(x, y, eps)
Return quad precision relative comparison .
Definition math.f90:196
subroutine, public rzero(a, n)
Zero a real vector.
Definition math.f90:235
real(kind=rp) function, public glsubnorm(a, b, n)
Returns the norm of the difference of two vectors .
Definition math.f90:1333
subroutine, public vdot2(dot, u1, u2, v1, v2, n)
Compute a dot product (2-d version) assuming vector components etc.
Definition math.f90:835
subroutine, public cpwmax2(a, b, n)
Point-wise maximum of scalar and vector .
Definition math.f90:1687
real(kind=rp) function, public vlmin(vec, n)
minimun value of a vector of length n
Definition math.f90:755
subroutine, public cfill_mask(a, c, n, mask, n_mask)
Fill a constant to a masked vector. .
Definition math.f90:488
real(kind=rp) function, public vlmax(vec, n)
maximum value of a vector of length n
Definition math.f90:740
integer function, public glimax(a, n)
Max of an integer vector of length n.
Definition math.f90:669
subroutine sortrp(a, ind, n)
Heap Sort for double precision arrays.
Definition math.f90:1359
subroutine, public sub2(a, b, n)
Vector substraction .
Definition math.f90:948
subroutine, public pwmin3(a, b, c, n)
Point-wise minimum of two vectors .
Definition math.f90:1733
subroutine, public add2s2(a, b, c1, n)
Vector addition with scalar multiplication (multiplication on second argument)
Definition math.f90:998
real(kind=rp) function, public glmin(a, n)
Min of a vector of length n.
Definition math.f90:688
subroutine, public masked_copy_0(a, b, mask, n, n_mask)
Copy a masked vector .
Definition math.f90:312
subroutine, public vcross(u1, u2, u3, v1, v2, v3, w1, w2, w3, n)
Compute a cross product assuming vector components etc.
Definition math.f90:816
pure logical function srelcmp(x, y, eps)
Return single precision relative comparison .
Definition math.f90:166
pure real(kind=rp) function, public lambert_w0(x, niter)
Approximate the principal real branch of the Lambert W function for non-negative real x.
Definition math.f90:214
real(kind=rp) function, public vlsc3(u, v, w, n)
Compute multiplication sum .
Definition math.f90:868
subroutine reordi4(b, ind, n)
reorder single integer array - inverse of swap
Definition math.f90:1554
subroutine, public p_update(a, b, c, c1, c2, n)
Returns .
Definition math.f90:1232
integer, parameter, public qp
Definition num_types.f90:10
integer, parameter, public i4
Definition num_types.f90:6
integer, parameter, public xp
Definition num_types.f90:14
integer, parameter, public dp
Definition num_types.f90:9
integer, parameter, public sp
Definition num_types.f90:8
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:12
Utilities.
Definition utils.f90:35
#define max(a, b)
Definition tensor.cu:40