KTH framework for Nek5000 toolboxes; testing version  0.0.1
math_tools.f
Go to the documentation of this file.
1 
6 !=======================================================================
20  real function math_stepf(x)
21  implicit none
22 
23  ! argument list
24  real x
25 
26  ! local variables
27  real xdmin, xdmax
28  parameter(xdmin = 0.0001, xdmax = 0.9999)
29 !-----------------------------------------------------------------------
30  ! get function vale
31  if (x.le.xdmin) then
32  math_stepf = 0.0
33  else if (x.le.xdmax) then
34  math_stepf = 1./( 1. + exp(1./(x - 1.) + 1./x) )
35  else
36  math_stepf = 1.
37  end if
38 
39  return
40  end function math_stepf
41 !=======================================================================
54  real function math_ran_dst(ix,iy,iz,ieg,xl,fcoeff)
55  implicit none
56 
57  include 'SIZE'
58  include 'INPUT' ! IF3D
59 
60  ! argument list
61  integer ix,iy,iz,ieg
62  real xl(ldim)
63  real fcoeff(3)
64 !-----------------------------------------------------------------------
65  math_ran_dst = fcoeff(1)*(ieg+xl(1)*sin(xl(2))) +
66  $ fcoeff(2)*ix*iy + fcoeff(3)*ix
67  if (if3d) math_ran_dst =
68  $ fcoeff(1)*(ieg +xl(ndim)*sin(math_ran_dst)) +
69  $ fcoeff(2)*iz*ix + fcoeff(3)*iz
70  math_ran_dst = 1.e3*sin(math_ran_dst)
71  math_ran_dst = 1.e3*sin(math_ran_dst)
73 
74  return
75  end function math_ran_dst
76 !=======================================================================
81  real function math_ran_rng(lower, upper)
82  implicit none
83 
84  ! argument list
85  real lower, upper
86 
87  ! functions
88  real math_zbqlu01
89 !-----------------------------------------------------------------------
90  math_ran_rng = lower + math_zbqlu01()*(upper-lower)
91 
92  return
93  end function math_ran_rng
94 !=======================================================================
119  real function math_zbqlu01()
120  implicit none
121 
122  ! global variables
123  real zbqlix(43), br, cr
124  common /math_zbql01/ zbqlix, br, cr
125 
126  ! local variables
127  integer curpos,id22,id43
128  save curpos,id22,id43
129  data curpos,id22,id43 /1,22,43/
130  real xr,b2,binv
131 !-----------------------------------------------------------------------
132  b2 = br
133  binv = 1.0/br
134 
135  do
136  xr = zbqlix(id22) - zbqlix(id43) - cr
137  if (xr.lt.0.0) then
138  xr = xr + br
139  cr = 1.0
140  else
141  cr = 0.0
142  endif
143  zbqlix(id43) = xr
144 
145  ! Update array pointers. Do explicit check for bounds of each to
146  ! avoid expense of modular arithmetic. If one of them is 0
147  ! the others won't be
148  curpos = curpos - 1
149  id22 = id22 - 1
150  id43 = id43 - 1
151  if (curpos.eq.0) then
152  curpos=43
153  elseif (id22.eq.0) then
154  id22 = 43
155  elseif (id43.eq.0) then
156  id43 = 43
157  endif
158 
159  ! The INTEGER arithmetic there can yield X=0, which can cause
160  ! problems in subsequent routines (e.g. ZBQLEXP). The problem
161  ! is simply that X is discrete whereas U is supposed to
162  ! be continuous - hence IF X is 0, go back and generate another
163  ! X and RETURN X/B^2 (etc.), which will be uniform on (0,1/B).
164  if (xr.ge.binv) exit
165  b2 = b2*br
166  enddo
167 
168  math_zbqlu01 = xr/b2
169  return
170  end function math_zbqlu01
171 !=======================================================================
179  subroutine math_zbqlini(seed)
180  implicit none
181 
182  ! argiment list
183  integer seed
184 
185  ! global variables
186  real zbqlix(43), br, cr
187  common /math_zbql01/ zbqlix, br, cr
188 
189  ! local variables
190  integer icall
191  save icall
192  data icall /0/
193 
194  integer il
195 
196  ! Initialisation data for random number generator.
197  ! The values below have themselves been generated using the
198  ! NAG generator.
199  real zbq_ini(43),b_ini,c_ini
200  data (zbq_ini(il),il=1,43) /8.001441d7,5.5321801d8,
201  $ 1.69570999d8,2.88589940d8,2.91581871d8,1.03842493d8,
202  $ 7.9952507d7,3.81202335d8,3.11575334d8,4.02878631d8,
203  $ 2.49757109d8,1.15192595d8,2.10629619d8,3.99952890d8,
204  $ 4.12280521d8,1.33873288d8,7.1345525d7,2.23467704d8,
205  $ 2.82934796d8,9.9756750d7,1.68564303d8,2.86817366d8,
206  $ 1.14310713d8,3.47045253d8,9.3762426d7 ,1.09670477d8,
207  $ 3.20029657d8,3.26369301d8,9.441177d6,3.53244738d8,
208  $ 2.44771580d8,1.59804337d8,2.07319904d8,3.37342907d8,
209  $ 3.75423178d8,7.0893571d7 ,4.26059785d8,3.95854390d8,
210  $ 2.0081010d7,5.9250059d7,1.62176640d8,3.20429173d8,
211  $ 2.63576576d8/
212  data b_ini / 4.294967291d9 /
213  data c_ini / 0.0d0 /
214 
215  real tmpvar1
216 
217  ! functions
218  real dnekclock
219 !-----------------------------------------------------------------------
220  if (icall.gt.0) return
221  icall = icall + 1
222 
223  br = b_ini
224  cr = c_ini
225  ! if seed==0 use cpu time as seed
226  if (seed.eq.0) then
227  tmpvar1 = mod(dnekclock(),br)
228  else
229  tmpvar1 = mod(real(seed),br)
230  endif
231  zbqlix(1) = tmpvar1
232  do il= 2, 43
233  tmpvar1 = zbq_ini(il-1)*3.0269d4
234  tmpvar1 = mod(tmpvar1,br)
235  zbqlix(il) = tmpvar1
236  enddo
237 
238  return
239  end subroutine math_zbqlini
240 !=======================================================================
252  subroutine math_edgind(istart,istop,iskip,iedg,nx,ny,nz)
253  implicit none
254  include 'SIZE'
255  include 'INPUT'
256  include 'TOPOL'
257 
258 ! argument list
259  integer istart,istop,iskip,iedg,nx,ny,nz
260 
261 ! local variables
262  integer ivrt, icx, icy, icz
263 !-----------------------------------------------------------------------
264 ! find vertex position
265 ! start
266  ivrt = icedg(1,iedg)
267  icx = mod(ivrt +1,2)
268  icy = mod((ivrt-1)/2,2)
269  icz = (ivrt-1)/4
270  istart = 1 + (nx-1)*icx + nx*(ny-1)*icy + nx*ny*(nz-1)*icz
271 
272 ! stop
273  ivrt = icedg(2,iedg)
274  icx = mod(ivrt +1,2)
275  icy = mod((ivrt-1)/2,2)
276  icz = (ivrt-1)/4
277  istop = 1 + (nx-1)*icx + nx*(ny-1)*icy + nx*ny*(nz-1)*icz
278 
279 ! find stride
280  if (iedg.le.4) then
281  iskip = 1
282  elseif (iedg.le.8) then
283  iskip = nx
284  else
285  iskip =nx*nx
286  endif
287 
288  return
289  end subroutine
290 !=======================================================================
298  subroutine math_etovec(vec,edg,vfld,nx,ny,nz)
299  implicit none
300 
301  include 'SIZE'
302  include 'TOPOL'
303 
304 ! argument list
305  real vfld(nx*ny*nz)
306  integer edg,nx,ny,nz
307  real vec(nx)
308 
309 ! local variables
310  integer is, ie, isk, il, jl
311 !-----------------------------------------------------------------------
312 ! is = IXCN(icedg(1,edg))
313 ! ie = IXCN(icedg(2,edg))
314 ! isk = ESKIP(edg,3)
315  call math_edgind(is,ie,isk,edg,nx,ny,nz)
316  jl = 1
317  do il=is,ie,isk
318  vec(jl) = vfld(il)
319  jl = jl + 1
320  enddo
321 
322  return
323  end subroutine
324 !=======================================================================
331  subroutine math_rot3da(vo,vi,va,an)
332  implicit none
333 
334  ! parameters
335  integer ldim
336  parameter(ldim=3)
337 
338  ! argument list
339  real vo(ldim), vi(ldim), va(ldim), an
340 
341  ! local variables
342  integer il, jl
343  real mat(ldim,ldim), ta(ldim)
344  real rtmp, can, can1, san, epsl
345  parameter(epsl = 1.0e-10)
346  logical if_same
347 !-----------------------------------------------------------------------
348  ! check if a rotated vector and an axis differ
349  if_same = .true.
350  do il = 1,ldim
351  if (abs(vi(il)-va(il)).gt.epsl) if_same = .false.
352  end do
353  ! perform rotation
354  if (an.eq.0.0.or.if_same) then
355  call copy(vo,vi,ldim)
356  else
357  ! make sure the axis vector is normalised
358  rtmp = 0.0
359  do il=1,ldim
360  rtmp = rtmp + va(il)**2
361  enddo
362  ! add check if rtmp.gt.0
363  rtmp = 1.0/sqrt(rtmp)
364  do il=1,ldim
365  ta(il) = rtmp*va(il)
366  enddo
367  ! fill in rotation mtrix
368  can = cos(an)
369  can1 = 1.0 - can
370  san = sin(an)
371  mat(1,1) = can + ta(1)*ta(1)*can1
372  mat(2,1) = ta(1)*ta(2)*can1 - ta(3)*san
373  mat(1,2) = ta(1)*ta(2)*can1 + ta(3)*san
374  mat(3,1) = ta(1)*ta(3)*can1 + ta(2)*san
375  mat(1,3) = ta(1)*ta(3)*can1 - ta(2)*san
376  mat(2,2) = can + ta(2)*ta(2)*can1
377  mat(3,2) = ta(2)*ta(3)*can1 - ta(1)*san
378  mat(2,3) = ta(2)*ta(3)*can1 + ta(1)*san
379  mat(3,3) = can + ta(3)*ta(3)*can1
380  ! perform rotation
381  do il = 1, ldim
382  vo(il) = 0.0
383  do jl=1,ldim
384  vo(il) = vo(il) + mat(jl,il)*vi(jl)
385  enddo
386  enddo
387  endif
388 
389  return
390  end subroutine
391 !=======================================================================
subroutine math_etovec(vec, edg, vfld, nx, ny, nz)
Extract 3D element edge.
Definition: math_tools.f:299
subroutine math_zbqlini(seed)
Initialise Marsaglia-Zaman random number generator.
Definition: math_tools.f:180
subroutine math_rot3da(vo, vi, va, an)
3D rotation of a vector along given axis.
Definition: math_tools.f:332
real function math_zbqlu01()
Marsaglia-Zaman random number generator.
Definition: math_tools.f:120
real function math_stepf(x)
Step function.
Definition: math_tools.f:21
subroutine math_edgind(istart, istop, iskip, iedg, nx, ny, nz)
Give bounds for loops to extract edge of a 3D element.
Definition: math_tools.f:253
real function math_ran_dst(ix, iy, iz, ieg, xl, fcoeff)
Give random distribution depending on position.
Definition: math_tools.f:55
real function math_ran_rng(lower, upper)
Give random number in the defined range.
Definition: math_tools.f:82
subroutine copy(a, b, n)
Definition: math.f:260