Neko  0.8.99
A portable framework for high-order spectral element flow simulations
spectral_error_indicator.f90
Go to the documentation of this file.
1 ! Copyright (c) 2022, 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 field, only: field_t
37  use coefs, only: coef_t
38  use field_list, only: field_list_t
39  use math, only: rzero, copy
40  use file, only: file_t, file_free
41  use tensor, only: tnsr3d
42  use device_math, only: device_copy
43  use gather_scatter
44  use neko_config
46  use comm, only: pe_rank
47  use utils, only: neko_fname_len
48  use, intrinsic :: iso_c_binding
49  implicit none
50  private
51 
59  type(field_t), pointer :: u => null()
60  type(field_t), pointer :: v => null()
61  type(field_t), pointer :: w => null()
63  type(field_t) :: u_hat
64  type(field_t) :: v_hat
65  type(field_t) :: w_hat
67  type(field_t) :: wk
69  real(kind=rp) :: seri_small = 1.e-14
71  real(kind=rp) :: seri_smallr = 1.e-10
73  real(kind=rp) :: seri_smallg = 1.e-5
75  real(kind=rp) :: seri_smalls = 0.2
77  integer :: seri_np = 4
78  integer :: seri_np_max = 4
80  integer :: seri_elr = 0
82  real(kind=rp), allocatable :: eind_u(:), eind_v(:), eind_w(:)
84  real(kind=rp), allocatable :: sig_u(:), sig_v(:), sig_w(:)
86  type(field_list_t) :: speri_l
88  type(file_t) :: mf_speri
89  contains
91  procedure, pass(this) :: init => spec_err_ind_init
93  procedure, pass(this) :: free => spec_err_ind_free
95  procedure, pass(this) :: get_indicators => spec_err_ind_get
97  procedure, pass(this) :: write_as_field => spec_err_ind_write
98 
100 
101 contains
102 
108  subroutine spec_err_ind_init(this, u,v,w,coef)
109  class(spectral_error_indicator_t), intent(inout) :: this
110  type(field_t), intent(in), target :: u
111  type(field_t), intent(in), target :: v
112  type(field_t), intent(in), target :: w
113  type(coef_t), intent(in) :: coef
114  integer :: il, jl, aa
115  character(len=NEKO_FNAME_LEN) :: fname_speri
116 
118  call this%free()
119 
121  this%u => u
122  this%v => v
123  this%w => w
125  this%u_hat = u
126  this%v_hat = v
127  this%w_hat = w
128  this%wk = u
130  allocate(this%eind_u(coef%msh%nelv))
131  allocate(this%eind_v(coef%msh%nelv))
132  allocate(this%eind_w(coef%msh%nelv))
133  allocate(this%sig_u(coef%msh%nelv))
134  allocate(this%sig_v(coef%msh%nelv))
135  allocate(this%sig_w(coef%msh%nelv))
136 
138  associate(lx1 => coef%Xh%lx, ly1 => coef%Xh%ly, &
139  lz1 => coef%Xh%lz, &
140  seri_small => this%SERI_SMALL, &
141  seri_smallr => this%SERI_SMALLR, &
142  seri_smallg => this%SERI_SMALLG, &
143  seri_smalls => this%SERI_SMALLS, &
144  seri_np => this%SERI_NP, &
145  seri_np_max => this%SERI_NP_MAX, &
146  seri_elr => this%SERI_ELR &
147  )
148  ! correctness check
149  if (seri_np.gt.seri_np_max) then
150  if (pe_rank.eq.0) write(*,*) 'SETI_NP greater than SERI_NP_MAX'
151  endif
152  il = seri_np+seri_elr
153  jl = min(lx1,ly1)
154  jl = min(jl,lz1)
155  if (il.gt.jl) then
156  if (pe_rank.eq.0) write(*,*) 'SERI_NP+SERI_ELR greater than L?1'
157  endif
158  end associate
159 
161  call list_init3(this%speri_l,this%u_hat,this%v_hat, &
162  this%w_hat)
163  ! Initialize the file
164  fname_speri = 'speri.fld'
165  this%mf_speri = file_t(fname_speri)
166 
167  end subroutine spec_err_ind_init
168 
169 
171  subroutine spec_err_ind_free(this)
172  class(spectral_error_indicator_t), intent(inout) :: this
173 
174  if(allocated(this%eind_u)) then
175  deallocate(this%eind_u)
176  end if
177 
178  if(allocated(this%eind_v)) then
179  deallocate(this%eind_v)
180  end if
181 
182  if(allocated(this%eind_w)) then
183  deallocate(this%eind_w)
184  end if
185 
186  if(allocated(this%sig_u)) then
187  deallocate(this%sig_u)
188  end if
189 
190  if(allocated(this%sig_w)) then
191  deallocate(this%sig_w)
192  end if
193 
194  if(allocated(this%sig_w)) then
195  deallocate(this%sig_w)
196  end if
197 
198  call this%u_hat%free()
199  call this%v_hat%free()
200  call this%w_hat%free()
201  call this%wk%free()
202 
203  nullify(this%u)
204  nullify(this%v)
205  nullify(this%w)
206 
208  call list_final3(this%speri_l)
209  call file_free(this%mf_speri)
210 
211  end subroutine spec_err_ind_free
212 
220  subroutine transform_to_spec_or_phys(u_hat, u, wk, coef, space)
221  type(field_t), intent(inout) :: u_hat
222  type(field_t), intent(inout) :: u
223  type(field_t), intent(inout) :: wk
224  type(coef_t), intent(inout) :: coef
225  character(len=4), intent(in) :: space
226  integer :: i, j, k, e, nxyz, nelv, n
227 
229  nxyz = coef%Xh%lx*coef%Xh%lx*coef%Xh%lx
230  nelv = coef%msh%nelv
231  n = nxyz*nelv
232 
234  if ((neko_bcknd_hip .eq. 1) .or. (neko_bcknd_cuda .eq. 1) .or. &
235  (neko_bcknd_opencl .eq. 1)) then
236  call device_copy(wk%x_d, u%x_d, n)
237  else
238  call copy(wk%x,u%x,n)
239  end if
240 
241  select case(space)
242  case('spec')
243  call tnsr3d(u_hat%x, coef%Xh%lx, wk%x, &
244  coef%Xh%lx,coef%Xh%vinv, &
245  coef%Xh%vinvt, coef%Xh%vinvt, nelv)
246  case('phys')
247  call tnsr3d(u_hat%x, coef%Xh%lx, wk%x, &
248  coef%Xh%lx,coef%Xh%v, &
249  coef%Xh%vt, coef%Xh%vt, nelv)
250  end select
251 
252  ! Synchronize
253  if ((neko_bcknd_hip .eq. 1) .or. (neko_bcknd_cuda .eq. 1) .or. &
254  (neko_bcknd_opencl .eq. 1)) then
255 
256  call device_memcpy(u_hat%x,u_hat%x_d, n, &
257  device_to_host, sync=.true.)
258  end if
259 
260  end subroutine transform_to_spec_or_phys
261 
264  subroutine spec_err_ind_get(this,coef)
265  class(spectral_error_indicator_t), intent(inout) :: this
266  type(coef_t), intent(inout) :: coef
267  integer :: i
268 
269  ! Generate the uvwhat field (legendre coeff)
270  call transform_to_spec_or_phys(this%u_hat, this%u, this%wk, coef, 'spec')
271  call transform_to_spec_or_phys(this%v_hat, this%v, this%wk, coef, 'spec')
272  call transform_to_spec_or_phys(this%w_hat, this%w, this%wk, coef, 'spec')
273 
274 
275  ! Get the spectral error indicator
276  call calculate_indicators(this, coef, this%eind_u, this%sig_u, coef%msh%nelv, &
277  coef%Xh%lx, coef%Xh%ly, coef%Xh%lz, &
278  this%u_hat%x)
279  call calculate_indicators(this, coef, this%eind_v, this%sig_v, coef%msh%nelv, &
280  coef%Xh%lx, coef%Xh%ly, coef%Xh%lz, &
281  this%v_hat%x)
282  call calculate_indicators(this, coef, this%eind_w, this%sig_w, coef%msh%nelv, &
283  coef%Xh%lx, coef%Xh%ly, coef%Xh%lz, &
284  this%w_hat%x)
285 
286  end subroutine spec_err_ind_get
287 
290  subroutine spec_err_ind_write(this, t)
291  class(spectral_error_indicator_t), intent(inout) :: this
292  real(kind=rp), intent(in) :: t
293 
294  integer i, e
295  integer lx, ly, lz, nelv
296 
297  lx = this%u_hat%Xh%lx
298  ly = this%u_hat%Xh%ly
299  lz = this%u_hat%Xh%lz
300  nelv = this%u_hat%msh%nelv
301 
303  do e = 1,nelv
304  do i = 1,lx*ly*lx
305  this%u_hat%x(i,1,1,e) = this%eind_u(e)
306  this%v_hat%x(i,1,1,e) = this%eind_v(e)
307  this%w_hat%x(i,1,1,e) = this%eind_w(e)
308  end do
309  end do
310 
314  call this%mf_speri%write(this%speri_l,t)
315 
316  end subroutine spec_err_ind_write
317 
327  subroutine calculate_indicators(this, coef, eind, sig, lnelt, LX1, LY1, LZ1, var)
328  type(spectral_error_indicator_t), intent(inout) :: this
329  type(coef_t), intent(in) :: coef
330  integer :: lnelt
331  integer :: LX1
332  integer :: LY1
333  integer :: LZ1
334  real(kind=rp) :: eind(lnelt)
335  real(kind=rp) :: sig(lnelt)
336  real(kind=rp) :: var(lx1,ly1,lz1,lnelt)
337 
338  real(kind=rp) :: xa(coef%Xh%lx,coef%Xh%ly,coef%Xh%lz)
339  real(kind=rp) :: xb(coef%Xh%lx,coef%Xh%ly,coef%Xh%lz)
340  integer :: i, e
341 
342  ! zero arrays
343  call rzero(eind,lnelt)
344  call rzero(sig,lnelt)
345 
346  ! Get the indicator
347  call speri_var(this, eind,sig,var,lnelt,xa,xb, lx1, ly1, lz1)
348 
349  end subroutine calculate_indicators
350 
351 
362  subroutine speri_var(this, est,sig,var,nell,xa,xb,LX1,LY1,LZ1)
363  type(spectral_error_indicator_t), intent(inout) :: this
364  integer :: nell
365  integer :: LX1
366  integer :: LY1
367  integer :: LZ1
368  real(kind=rp) :: est(nell)
369  real(kind=rp) :: sig(nell)
370  real(kind=rp) :: var(lx1,ly1,lz1,nell)
371  real(kind=rp) :: xa(lx1,ly1,lz1)
372  real(kind=rp) :: xb(lx1,ly1,lz1)
373 
375  integer :: il, jl, kl, ll, j_st, j_en, ii
377  real(kind=rp) :: coeff(lx1,ly1,lz1)
379  real(kind=rp) :: coef11
381  real(kind=rp) :: coefx(this%SERI_NP_MAX,ly1,lz1), &
382  coefy(this%SERI_NP_MAX,lx1,lz1), &
383  coefz(this%SERI_NP_MAX,lx1,ly1)
385  real(kind=rp) :: estx, esty, estz
387  real(kind=rp) :: sigx, sigy, sigz
388  real(kind=rp) :: third
389  parameter(third = 1.0/3.0)
390 
392  do il = 1,nell
395  do ii = 1, lx1*ly1*lz1
396  coeff(ii,1,1) = var(ii,1,1,il) * var(ii,1,1,il)
397  end do
398 
400  coef11 = coeff(1,1,1)
401 
403  if (coef11.ge.this%SERI_SMALL) then
408  j_st = max(1,lx1-this%SERI_NP+1-this%SERI_ELR)
409  j_en = max(1,lx1-this%SERI_ELR)
410  do ll = 1,lz1
411  do kl = 1,ly1
412  do jl = j_st,j_en
413  coefx(j_en-jl+1,kl,ll) = coeff(jl,kl,ll)
414  enddo
415  enddo
416  enddo
418  call speri_extrap(this,estx,sigx,coef11,coefx, &
419  j_st,j_en,ly1,lz1)
420 
424  j_st = max(1,ly1-this%SERI_NP+1-this%SERI_ELR)
425  j_en = max(1,ly1-this%SERI_ELR)
426  do ll = 1,lz1
427  do kl = j_st,j_en
428  do jl = 1,lx1
429  coefy(j_en-kl+1,jl,ll) = coeff(jl,kl,ll)
430  enddo
431  enddo
432  enddo
434  call speri_extrap(this, esty,sigy,coef11,coefy, &
435  j_st,j_en,lx1,lz1)
436 
440  j_st = max(1,lz1-this%SERI_NP+1-this%SERI_ELR)
441  j_en = max(1,lz1-this%SERI_ELR)
442  do ll = j_st,j_en
443  do kl = 1,ly1
444  do jl = 1,lx1
445  coefz(j_en-ll+1,jl,kl) = coeff(jl,kl,ll)
446  enddo
447  enddo
448  enddo
450  call speri_extrap(this, estz,sigz,coef11,coefz, &
451  j_st,j_en,lx1,ly1)
452 
454  est(il) = sqrt(estx + esty + estz)
455  sig(il) = third*(sigx + sigy + sigz)
456 
457  else
459  estx = 0.0
460  esty = 0.0
461  estz = 0.0
462  sigx = -1.0
463  sigy = -1.0
464  sigz = -1.0
466 
467  est(il) = 0.0
468  sig(il) = -1.0
469  endif
470 
471  end do
472 
473  end subroutine speri_var
474 
475 
485  subroutine speri_extrap(this,estx,sigx,coef11,coef, &
486  ix_st,ix_en,nyl,nzl)
487  implicit none
488  type(spectral_error_indicator_t), intent(inout) :: this
490  integer :: ix_st,ix_en,nyl,nzl
492  real(kind=rp) :: coef(this%SERI_NP_MAX,nyl,nzl)
494  real(kind=rp) :: coef11
496  real(kind=rp) :: estx, sigx
497 
499  integer :: il, jl, kl, ll ! loop index
500  integer :: nsigt, pnr, nzlt
501  real(kind=rp) :: sigt, smallr, cmin, cmax, cnm, rtmp, rtmp2, rtmp3
502  real(kind=rp) :: sumtmp(4), cffl(this%SERI_NP_MAX)
503  real(kind=rp) :: stmp, estt, clog, ctmp, cave, erlog
504  logical :: cuse(this%seri_np_max)
505 
506  associate(seri_small => this%SERI_SMALL, &
507  seri_smallr => this%SERI_SMALLR, &
508  seri_smallg => this%SERI_SMALLG, &
509  seri_smalls => this%SERI_SMALLS, &
510  seri_np => this%SERI_NP, &
511  seri_np_max => this%SERI_NP_MAX, &
512  seri_elr => this%SERI_ELR &
513  )
514  ! initial values
515  estx = 0.0
516  sigx = -1.0
517 
518  ! relative cutoff
519  smallr = coef11*seri_smallr
520 
521  ! number of points
522  pnr = ix_en - ix_st +1
523 
524  ! to few points to interpolate
525  !if ((ix_en - ix_st).le.1) return
526 
527  ! for averaging, initial values
528  sigt = 0.0
529  nsigt = 0
530 
531  ! loop over all face points
532  nzlt = max(1,nzl - seri_elr) ! for 2D runs
533  do il=1,nzlt
534  ! weight
535  rtmp3 = 1.0/(2.0*(il-1)+1.0)
536  do jl=1,nyl - seri_elr
537 
538  ! find min and max coef along single row
539  cffl(1) = coef(1,jl,il)
540  cmin = cffl(1)
541  cmax = cmin
542  do kl =2,pnr
543  cffl(kl) = coef(kl,jl,il)
544  cmin = min(cmin,cffl(kl))
545  cmax = max(cmax,cffl(kl))
546  enddo
547 
548  ! are coefficients sufficiently big
549  if((cmin.gt.0.0).and.(cmax.gt.smallr)) then
550  ! mark array position we use in iterpolation
551  do kl =1,pnr
552  cuse(kl) = .true.
553  enddo
554  ! max n for polynomial order
555  cnm = real(ix_en)
556 
557  ! check if all the points should be taken into account
558  ! in original code by Catherine Mavriplis this part is written
559  ! for 4 points, so I place if statement first
560  if (pnr.eq.4) then
561  ! should we neglect last values
562  if ((cffl(1).lt.smallr).and. &
563  (cffl(2).lt.smallr)) then
564  if (cffl(3).lt.smallr) then
565  cuse(1) = .false.
566  cuse(2) = .false.
567  cnm = real(ix_en-2)
568  else
569  cuse(1) = .false.
570  cnm = real(ix_en-1)
571  endif
572  else
573  ! should we take stronger gradient
574  if ((cffl(1)/cffl(2).lt.seri_smallg).and. &
575  (cffl(3)/cffl(4).lt.seri_smallg)) then
576  cuse(1) = .false.
577  cuse(3) = .false.
578  cnm = real(ix_en-1)
579  elseif ((cffl(2)/cffl(1).lt.seri_smallg).and. &
580  (cffl(4)/cffl(3).lt.seri_smallg)) then
581  cuse(2) = .false.
582  cuse(4) = .false.
583  endif
584  endif
585  endif
586 
587  ! get sigma for given face point
588  do kl =1,4
589  sumtmp(kl) = 0.0
590  enddo
591  ! find new min and count number of points
592  cmin = cmax
593  cmax = 0.0
594  do kl =1,pnr
595  if(cuse(kl)) then
596  rtmp = real(ix_en-kl)
597  rtmp2 = log(cffl(kl))
598  sumtmp(1) = sumtmp(1) +rtmp2
599  sumtmp(2) = sumtmp(2) +rtmp
600  sumtmp(3) = sumtmp(3) +rtmp*rtmp
601  sumtmp(4) = sumtmp(4) +rtmp2*rtmp
602  ! find new min and count used points
603  cmin = min(cffl(kl),cmin)
604  cmax = cmax + 1.0
605  endif
606  enddo
607  ! decay rate along single row
608  stmp = (sumtmp(1)*sumtmp(2) - sumtmp(4)*cmax)/ &
609  (sumtmp(3)*cmax - sumtmp(2)*sumtmp(2))
610  ! for averaging
611  sigt = sigt + stmp
612  nsigt = nsigt + 1
613 
614  ! get error estimator depending on calculated decay rate
615  estt = 0.0
616  if (stmp.lt.seri_smalls) then
617  estt = cmin
618  else
619  ! get averaged constant in front of c*exp(-sig*n)
620  clog = (sumtmp(1)+stmp*sumtmp(2))/cmax
621  ctmp = exp(clog)
622  ! average exponent
623  cave = sumtmp(1)/cmax
624  ! check quality of approximation comparing is to the constant cave
625  do kl =1,2
626  sumtmp(kl) = 0.0
627  enddo
628  do kl =1,pnr
629  if(cuse(kl)) then
630  erlog = clog - stmp*real(ix_en-kl)
631  sumtmp(1) = sumtmp(1)+ &
632  (erlog-log(cffl(kl)))**2
633  sumtmp(2) = sumtmp(2)+ &
634  (erlog-cave)**2
635  endif
636  enddo
637  rtmp = 1.0 - sumtmp(1)/sumtmp(2)
638  if (rtmp.lt.seri_smalls) then
639  estt = cmin
640  else
641  ! last coefficient is not included in error estimator
642  estt = ctmp/stmp*exp(-stmp*cnm)
643  endif
644  endif
645  ! add contribution to error estimator; variable weight
646  estx = estx + estt/(2.0*(jl-1)+1.0)*rtmp3
647  endif ! if((cmin.gt.0.0).and.(cmax.gt.smallr))
648  enddo
649  enddo
650  ! constant weight
651  ! Multiplication by 4 in 2D / 8 in 3D
652  ! Normalization of the error by the volume of the reference element
653  ! which is equal to 4 in 2D / 8 in 3D
654  ! ==> Both operations cancel each other
655  estx = estx/(2.0*(ix_en-1)+1.0)
656 
657  ! final everaging
658  ! sigt = 2*sigma so we divide by 2
659  if (nsigt.gt.0) then
660  sigx = 0.5*sigt/nsigt
661  endif
662 
663  end associate
664 
665  end subroutine speri_extrap
666 
672  subroutine list_init3(list, uu, vv, ww)
673  type(field_list_t), intent(inout) :: list
674  type(field_t), target:: uu
675  type(field_t), target:: vv
676  type(field_t), target:: ww
678  call list%init(3)
679  call list%assign_to_field(1, uu)
680  call list%assign_to_field(2, vv)
681  call list%assign_to_field(3, ww)
682  end subroutine list_init3
683 
684 
687  subroutine list_final3(list)
688  type(field_list_t), intent(inout) :: list
689  call list%free
690  end subroutine list_final3
691 
692 
693 end module spectral_error_indicator
694 
695 
696 
double real
Definition: device_config.h:12
Copy data between host and device (or device and device)
Definition: device.F90:51
Coefficients.
Definition: coef.f90:34
Definition: comm.F90:1
integer pe_rank
MPI rank.
Definition: comm.F90:26
subroutine, public device_copy(a_d, b_d, n)
Copy a vector .
Device abstraction, common interface for various accelerators.
Definition: device.F90:34
integer, parameter, public device_to_host
Definition: device.F90:47
Defines a field.
Definition: field.f90:34
Module for file I/O operations.
Definition: file.f90:34
subroutine file_free(this)
File operation destructor.
Definition: file.f90:134
Gather-scatter.
Definition: math.f90:60
subroutine, public copy(a, b, n)
Copy a vector .
Definition: math.f90:228
subroutine, public rzero(a, n)
Zero a real vector.
Definition: math.f90:184
Build configurations.
Definition: neko_config.f90:34
integer, parameter, public rp
Global precision used in computations.
Definition: num_types.f90:12
Defines a function space.
Definition: space.f90:34
Implements type spectral_error_indicator_t.
subroutine speri_extrap(this, estx, sigx, coef11, coef, ix_st, ix_en, nyl, nzl)
Extrapolate the Legendre spectrum from the last points.
subroutine transform_to_spec_or_phys(u_hat, u, wk, coef, space)
Transform a field u > u_hat into physical or spectral space the result of the transformation is in u_...
subroutine list_final3(list)
Helper function to finalize field list to write.
subroutine spec_err_ind_init(this, u, v, w, coef)
Constructor.
subroutine spec_err_ind_get(this, coef)
Transform and get the spectral error indicators.
subroutine list_init3(list, uu, vv, ww)
Helper function to initialize field list to write.
subroutine spec_err_ind_write(this, t)
Write error indicators in a field file.
subroutine speri_var(this, est, sig, var, nell, xa, xb, LX1, LY1, LZ1)
Calculate the indicator in a specified variable.
subroutine calculate_indicators(this, coef, eind, sig, lnelt, LX1, LY1, LZ1, var)
Wrapper for old fortran 77 subroutines.
subroutine spec_err_ind_free(this)
Destructor.
Tensor operations.
Definition: tensor.f90:61
subroutine, public tnsr3d(v, nv, u, nu, A, Bt, Ct, nelv)
Tensor product performed on nelv elements.
Definition: tensor.f90:223
Utilities.
Definition: utils.f90:35
integer, parameter, public neko_fname_len
Definition: utils.f90:39
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Definition: coef.f90:55
field_list_t, To be able to group fields together
Definition: field_list.f90:13
A wrapper around a polymorphic generic_file_t that handles its init. This is essentially a factory fo...
Definition: file.f90:54
Provides tools to calculate the spectral error indicator.
#define max(a, b)
Definition: tensor.cu:40