Neko 1.99.3
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
vtk.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
42module vtk
43 use utils, only: linear_index, neko_error
44 implicit none
45 private
46
47 public :: vtk_ordering
48
49contains
50
59 function vtk_ordering(cell_type, lx, ly, lz) result(ordering)
60 integer(kind=1), intent(in) :: cell_type
61 integer, intent(in), optional :: lx, ly, lz
62 integer, allocatable :: ordering(:)
63
64 select case (cell_type)
65 case (70) ! VTK_LAGRANGE_QUADRILATERAL
66 if (present(lx) .and. present(ly)) then
67 ordering = vtk_lagrange_quad_ordering(lx, ly)
68 else
69 call neko_error('lx and ly must be provided for arbitrary lagrange ' &
70 // 'quadrilateral cells')
71 end if
72 case (72) ! VTK_LAGRANGE_HEXAHEDRON
73 if (present(lx) .and. present(ly) .and. present(lz)) then
74 ordering = vtk_lagrange_hex_ordering(lx, ly, lz)
75 else
76 call neko_error('lx, ly, and lz must be provided for arbitrary ' &
77 // 'lagrange hexahedron cells')
78 end if
79 case default
80 call neko_error('Unsupported VTK cell type in vtk_ordering')
81 end select
82
83 end function vtk_ordering
84
96 pure function vtk_lagrange_hex_ordering(lx, ly, lz) result(ordering)
97 integer, intent(in) :: lx, ly, lz
98 integer :: ordering(lx * ly * lz)
99 integer :: i, j, k, vtk_idx
100 integer :: ibdy, jbdy, kbdy, nbdy, offset
101 integer :: n_corners, n_edges, n_faces
102
103 n_corners = 8
104 n_edges = 4 * ((lx - 2) + (ly - 2) + (lz - 2))
105 n_faces = 2 * ((lx - 2) * (ly - 2) + (lx - 2) * (lz - 2) &
106 + (ly - 2) * (lz - 2))
107
108 do concurrent(i = 1:lx, j = 1:ly, k = 1:lz)
109 ibdy = merge(1, 0, i .eq. 1 .or. i .eq. lx)
110 jbdy = merge(1, 0, j .eq. 1 .or. j .eq. ly)
111 kbdy = merge(1, 0, k .eq. 1 .or. k .eq. lz)
112 nbdy = ibdy + jbdy + kbdy
113
114 if (nbdy .eq. 3) then
115 ! Corner node
116 vtk_idx = merge( &
117 merge(2, 1, j .ne. 1), &
118 merge(3, 0, j .ne. 1), i .ne. 1) &
119 + merge(4, 0, k .ne. 1)
120
121 else if (nbdy .eq. 2) then
122 ! Edge interior node
123 offset = n_corners
124 if (ibdy .eq. 0) then
125 vtk_idx = (i - 2) &
126 + merge((lx - 2) + (ly - 2), 0, j .ne. 1) &
127 + merge(2 * ((lx - 2) + (ly - 2)), 0, k .ne. 1) &
128 + offset
129 else if (jbdy .eq. 0) then
130 vtk_idx = (j - 2) &
131 + merge(lx - 2, 2 * (lx - 2) + (ly - 2), i .ne. 1) &
132 + merge(2 * ((lx - 2) + (ly - 2)), 0, k .ne. 1) &
133 + offset
134 else
135 vtk_idx = (k - 2) + (lz - 2) &
136 * merge(merge(2, 1, j .ne. 1), &
137 merge(3, 0, j .ne. 1), i .ne. 1) &
138 + offset + 4 * ((lx - 2) + (ly - 2))
139 end if
140
141 else if (nbdy .eq. 1) then
142 ! Face interior node
143 offset = n_corners + n_edges
144 if (ibdy .eq. 1) then
145 vtk_idx = (j - 2) + (ly - 2) * (k - 2) &
146 + merge((ly - 2) * (lz - 2), 0, i .ne. 1) &
147 + offset
148 else if (jbdy .eq. 1) then
149 offset = offset + 2 * (ly - 2) * (lz - 2)
150 vtk_idx = (i - 2) + (lx - 2) * (k - 2) &
151 + merge((lx - 2) * (lz - 2), 0, j .ne. 1) &
152 + offset
153 else if (kbdy .eq. 1) then
154 offset = offset + 2 * (ly - 2) * (lz - 2) + 2 * (lx - 2) * (lz - 2)
155 vtk_idx = (i - 2) + (lx - 2) * (j - 2) &
156 + merge((lx - 2) * (ly - 2), 0, k .ne. 1) &
157 + offset
158 end if
159
160 else
161 ! Body interior node
162 offset = n_corners + n_edges + n_faces
163 vtk_idx = offset &
164 + (i - 2) + (lx - 2) * ((j - 2) + (ly - 2) * (k - 2))
165 end if
166
167 ! ordering(vtk_position + 1) = tensor-product index
168 ordering(vtk_idx + 1) = linear_index(i, j, k, 1, lx, ly, lz) - 1
169 end do
170
171 end function vtk_lagrange_hex_ordering
172
182 pure function vtk_lagrange_quad_ordering(lx, ly) result(ordering)
183 integer, intent(in) :: lx, ly
184 integer :: ordering(lx * ly)
185 integer :: i, j, vtk_idx
186 integer :: ibdy, jbdy, nbdy, offset
187 integer :: n_corners, n_edges
188
189 n_corners = 4
190 n_edges = 2 * ((lx - 2) + (ly - 2))
191
192 do concurrent(i = 1:lx, j = 1:ly)
193 ibdy = merge(1, 0, i .eq. 1 .or. i .eq. lx)
194 jbdy = merge(1, 0, j .eq. 1 .or. j .eq. ly)
195 nbdy = ibdy + jbdy
196
197 if (nbdy .eq. 2) then
198 ! Corner node
199 vtk_idx = merge( &
200 merge(2, 1, j .ne. 1), &
201 merge(3, 0, j .ne. 1), i .ne. 1)
202
203 else if (nbdy .eq. 1) then
204 ! Edge interior node
205 offset = n_corners
206 if (ibdy .eq. 0) then
207 vtk_idx = (i - 2) &
208 + merge((lx - 2) + (ly - 2), 0, j .ne. 1) &
209 + offset
210 else
211 vtk_idx = (j - 2) &
212 + merge(lx - 2, 2 * (lx - 2) + (ly - 2), i .ne. 1) &
213 + offset
214 end if
215
216 else
217 ! Face interior node
218 offset = n_corners + n_edges
219 vtk_idx = offset + (i - 2) + (lx - 2) * (j - 2)
220 end if
221
222 ordering(vtk_idx + 1) = linear_index(i, j, 1, 1, lx, ly, 1) - 1
223 end do
224
225 end function vtk_lagrange_quad_ordering
226end module vtk
Utilities.
Definition utils.f90:35
pure integer function, public linear_index(i, j, k, l, lx, ly, lz)
Compute the address of a (i,j,k,l) array with sizes (1:lx, 1:ly, 1:lz, :)
Definition utils.f90:237
VTK Module containing utilities for VTK file handling.
Definition vtk.f90:42
integer function, dimension(:), allocatable, public vtk_ordering(cell_type, lx, ly, lz)
Get the VTK node ordering for a given cell type. For Lagrange cells, returns an array mapping VTK nod...
Definition vtk.f90:60
pure integer function, dimension(lx *ly *lz) vtk_lagrange_hex_ordering(lx, ly, lz)
Build the VTK Lagrange hexahedron node ordering for a given lx. Returns an array of size lx*ly*lz map...
Definition vtk.f90:97
pure integer function, dimension(lx *ly) vtk_lagrange_quad_ordering(lx, ly)
Build the VTK Lagrange quadrilateral node ordering for a given lx, ly. Returns an array of size lx*ly...
Definition vtk.f90:183