Neko  0.9.0
A portable framework for high-order spectral element flow simulations
tet.f90
Go to the documentation of this file.
1 ! Copyright (c) 2021, 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 !
34 module tet
35  use num_types, only : dp
36  use element, only : element_t
37  use tuple
38  use point, only : point_t
39  implicit none
40  private
41 
42  integer, public, parameter :: neko_tet_npts = 4
43  integer, public, parameter :: neko_tet_nfcs = 4
44  integer, public, parameter :: neko_tet_neds = 6
45  integer, public, parameter :: neko_tet_gdim = 3
46 
47 
63  type, public, extends(element_t) :: tet_t
64  contains
65  procedure, pass(this) :: init => tet_init
66  procedure, pass(this) :: facet_id => tet_facet_id
67  procedure, pass(this) :: facet_order => tet_facet_order
68  procedure, pass(this) :: diameter => tet_diameter
69  procedure, pass(this) :: centroid => tet_centroid
70  procedure, pass(this) :: edge_id => tet_edge_id
71  procedure, pass(this) :: equal => tet_equal
72  generic :: operator(.eq.) => equal
73  end type tet_t
74 
92  integer, parameter, dimension(3, 4) :: face_nodes = reshape((/1,3,4,&
93  2,3,4,&
94  1,2,4,&
95  1,2,3/),&
96  (/3,4/))
97 
114  integer, parameter, dimension(2, 6) :: edge_nodes = reshape((/1,2,&
115  1,3,&
116  2,3,&
117  3,4,&
118  1,4,&
119  2,4/),&
120  (/2,6/))
121 
122 contains
123 
125  subroutine tet_init(this, id, p1, p2, p3, p4)
126  class(tet_t), intent(inout) :: this
127  integer, intent(inout) :: id
128  type(point_t), target, intent(in) :: p1, p2, p3, p4
129 
130  call this%element(id, neko_tet_gdim, neko_tet_npts)
131 
132  this%pts(1)%p => p1
133  this%pts(2)%p => p2
134  this%pts(3)%p => p3
135  this%pts(4)%p => p4
136 
137  end subroutine tet_init
138 
140  subroutine tet_facet_id(this, t, side)
141  class(tet_t), intent(in) :: this
142  class(tuple_t), intent(inout) :: t
143  integer, intent(in) :: side
144  integer :: i, j, temp
145  type(point_t), pointer :: p1,p2,p3
146 
147  p1 => this%p(face_nodes(1, side))
148  p2 => this%p(face_nodes(2, side))
149  p3 => this%p(face_nodes(3, side))
150 
151  select type(t)
152  type is(tuple3_i4_t)
153  t%x = (/ p1%id(), p2%id(), p3%id() /)
154  do i = 1, 2
155  do j = i+1,3
156  if(t%x(j) .lt. t%x(i)) then
157  temp = t%x(i)
158  t%x(i) = t%x(j)
159  t%x(j) = temp
160  endif
161  enddo
162  enddo
163  end select
164 
165  end subroutine tet_facet_id
166 
168  subroutine tet_facet_order(this, t, side)
169  class(tet_t), intent(in) :: this
170  class(tuple_t), intent(inout) :: t
171  integer, intent(in) :: side
172  type(point_t), pointer :: p1,p2,p3
173 
174  p1 => this%p(face_nodes(1, side))
175  p2 => this%p(face_nodes(2, side))
176  p3 => this%p(face_nodes(3, side))
177 
178  select type(t)
179  type is(tuple3_i4_t)
180  t%x = (/ p1%id(), p2%id(), p3%id() /)
181  end select
182 
183  end subroutine tet_facet_order
184 
185 
187  subroutine tet_edge_id(this, t, side)
188  class(tet_t), intent(in) :: this
189  class(tuple_t), intent(inout) :: t
190  integer, intent(in) :: side
191  type(point_t), pointer :: p1,p2
192 
193  p1 => this%p(edge_nodes(1, side))
194  p2 => this%p(edge_nodes(2, side))
195 
196  select type(t)
197  type is(tuple_i4_t)
198  if (p1%id() .lt. p2%id()) then
199  t%x = (/ p1%id(), p2%id() /)
200  else
201  t%x = (/ p2%id(), p1%id() /)
202  endif
203 
204  end select
205 
206  end subroutine tet_edge_id
207 
209  function tet_diameter(this) result(res)
210  class(tet_t), intent(in) :: this
211  real(kind=dp) :: d1, d2, d3, d4, d5, d6, res
212  type(point_t), pointer :: p1, p2, p3, p4
213  integer :: i
214 
215  d1 = 0d0
216  d2 = 0d0
217  d3 = 0d0
218  d4 = 0d0
219  d5 = 0d0
220  d6 = 0d0
221 
222  p1 => this%p(1)
223  p2 => this%p(2)
224  p3 => this%p(3)
225  p4 => this%p(4)
226 
227 
228  do i = 1, neko_tet_gdim
229  d1 = d1 + (p2%x(i) - p3%x(i))**2
230  d2 = d2 + (p1%x(i) - p3%x(i))**2
231  d3 = d3 + (p1%x(i) - p2%x(i))**2
232  d4 = d4 + (p1%x(i) - p4%x(i))**2
233  d5 = d5 + (p2%x(i) - p4%x(i))**2
234  d6 = d6 + (p3%x(i) - p4%x(i))**2
235  end do
236 
237  res = d1
238  res = max(res, d2)
239  res = max(res, d3)
240  res = max(res, d4)
241  res = max(res, d5)
242  res = max(res, d6)
243  res = sqrt(res)
244 
245  end function tet_diameter
246 
248  function tet_centroid(this) result(res)
249  class(tet_t), intent(in) :: this
250  type(point_t) :: res
251  type(point_t), pointer :: p1, p2, p3, p4
252  integer :: i
253 
254  p1 => this%p(1)
255  p2 => this%p(2)
256  p3 => this%p(3)
257  p4 => this%p(4)
258  res%x = 0d0
259 
260  do i = 1, this%gdim()
261  res%x(i) = 0.25 * (p1%x(i) + p2%x(i) + p3%x(i) + p4%x(i))
262  end do
263 
264  end function tet_centroid
265 
268  pure function tet_equal(this, other) result(res)
269  class(tet_t), intent(in) :: this
270  class(element_t), intent(in) :: other
271  integer :: i
272  logical :: res
273 
274  res = .false.
275  select type(other)
276  type is (tet_t)
277  if ((this%gdim() .eq. other%gdim()) .and. &
278  (this%npts() .eq. other%npts())) then
279  do i = 1, this%npts()
280  if (this%pts(i)%p .ne. other%pts(i)%p) then
281  return
282  end if
283  end do
284  res = .true.
285  end if
286  end select
287 
288  end function tet_equal
289 
290 end module tet
integer, parameter, public dp
Definition: num_types.f90:9
Implements a point.
Definition: point.f90:35
Defines a tetrahedral element.
Definition: tet.f90:34
subroutine tet_init(this, id, p1, p2, p3, p4)
Create a tetrahedral element based upon four points.
Definition: tet.f90:126
real(kind=dp) function tet_diameter(this)
Compute the diameter of a tetrahedral element.
Definition: tet.f90:210
integer, parameter, public neko_tet_npts
Number of points.
Definition: tet.f90:42
pure logical function tet_equal(this, other)
Check if two tet elements are equal.
Definition: tet.f90:269
integer, parameter, public neko_tet_neds
Number of edges.
Definition: tet.f90:44
integer, dimension(2, 6), parameter edge_nodes
Edge node ids.
Definition: tet.f90:114
integer, parameter, public neko_tet_nfcs
Number of faces.
Definition: tet.f90:43
type(point_t) function tet_centroid(this)
Compute the centroid of a tetrahedral element.
Definition: tet.f90:249
integer, dimension(3, 4), parameter face_nodes
Face node ids.
Definition: tet.f90:92
subroutine tet_facet_order(this, t, side)
Return the ordered points for face i as a 3-tuple t.
Definition: tet.f90:169
subroutine tet_facet_id(this, t, side)
Return the facet id for face i as a 3-tuple t.
Definition: tet.f90:141
subroutine tet_edge_id(this, t, side)
Return the edge id for an edge i as a 2-tuple t.
Definition: tet.f90:188
integer, parameter, public neko_tet_gdim
Geometric dimension.
Definition: tet.f90:45
Implements a n-tuple.
Definition: tuple.f90:34
Base type for an element.
Definition: element.f90:44
A point in with coordinates .
Definition: point.f90:43
Tetrahedral element.
Definition: tet.f90:63
Integer based 3-tuple.
Definition: tuple.f90:60
Integer based 2-tuple.
Definition: tuple.f90:51
Base type for an n-tuple.
Definition: tuple.f90:41
#define max(a, b)
Definition: tensor.cu:40