source: CIVL/examples/fortran/nek5000/core/hpf.f

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100755
File size: 8.1 KB
Line 
1 subroutine MAKE_HPF
2
3 include 'SIZE'
4 include 'SOLN'
5 include 'INPUT' ! param(110),(111)
6 include 'TSTEP' ! ifield
7 include 'MASS' ! BM1
8
9 integer nxyz
10 parameter (nxyz=lx1*ly1*lz1)
11 integer n
12
13 integer lm,lm2
14 parameter (lm=40)
15 parameter (lm2=lm*lm)
16 real hpf_filter(lm2)
17
18 integer hpf_kut
19 real hpf_chi
20 logical hpf_ifboyd
21
22 integer nel
23
24 integer icalld
25 save icalld
26 data icalld /0/
27
28 real TA1,TA2,TA3
29 COMMON /SCRUZ/ TA1 (LX1,LY1,LZ1,LELV)
30 $ , TA2 (LX1,LY1,LZ1,LELV)
31 $ , TA3 (LX1,LY1,LZ1,LELV)
32
33 real hpf_op(lx1,lx1)
34 save hpf_op
35
36c----------------------------------------
37 if(.not. iffilter(ifield)) return
38
39 hpf_kut = int(param(101))+1
40 hpf_chi = -1.0*abs(param(103))
41c Boyd transform to preserve element boundary values is
42c linearly unstable when used as forcing.
43 hpf_ifboyd = .false.
44
45 nel = nelv
46 n = nxyz*nel
47
48 if (hpf_chi.eq.0) return
49 if(nid.eq.0 .and. loglevel.gt.2) write(6,*) 'apply hpf ',
50 $ ifield, hpf_kut, hpf_chi
51
52 if (icalld.eq.0) then
53c Create the filter transfer function
54 call hpf_trns_fcn(hpf_filter,hpf_kut)
55
56c Build the matrix to apply the filter function
57c to an input field
58 call build_hpf_mat(hpf_op,hpf_filter,hpf_ifboyd)
59
60c Only initialize once
61 icalld=icalld+1
62 endif
63
64 if (ifield.eq.1) then
65c Apply the filter
66c to velocity fields
67 if (jp.eq.0) then
68 call build_hpf_fld(ta1,vx,hpf_op,lx1,lz1)
69 call build_hpf_fld(ta2,vy,hpf_op,lx1,lz1)
70 if (if3d) call build_hpf_fld(ta3,vz,hpf_op,lx1,lz1)
71
72c Multiply by filter weight (chi)
73 call cmult(ta1,hpf_chi,n)
74 call cmult(ta2,hpf_chi,n)
75 if (if3d) call cmult(ta3,hpf_chi,n)
76
77c Multiply by Mass matrix
78c and add to forcing term
79 call opadd2col (bfx,bfy,bfz,ta1,ta2,ta3,bm1)
80 else
81c Apply filter on velocity perturbation fields
82 call build_hpf_fld(ta1,vxp(1,jp),hpf_op,lx1,lz1)
83 call build_hpf_fld(ta2,vyp(1,jp),hpf_op,lx1,lz1)
84 if (if3d) call build_hpf_fld(ta3,vzp(1,jp),hpf_op,lx1,lz1)
85
86c Multiply by filter weight (chi)
87 call cmult(ta1,hpf_chi,n)
88 call cmult(ta2,hpf_chi,n)
89 if (if3d) call cmult(ta3,hpf_chi,n)
90
91c Multiply by Mass matrix
92c and add to forcing term
93 call opadd2col (bfxp(1,jp),bfyp(1,jp),bfzp(1,jp),
94 $ ta1,ta2,ta3,bm1)
95 endif
96
97 else
98
99c Apply filter to temp/passive scalar fields
100 if (jp.eq.0) then
101 call build_hpf_fld(ta1,t(1,1,1,1,ifield-1),
102 $ hpf_op,lx1,lz1)
103
104c Multiply by filter weight (chi)
105 call cmult(ta1,hpf_chi,n)
106
107c Multiply by Mass matrix
108c and add to source term
109 call addcol3(bq(1,1,1,1,ifield-1),ta1,bm1,n)
110 else
111c Apply filter on scalar perturbation field
112 call build_hpf_fld(ta1,tp(1,ifield-1,jp),hpf_op,lx1,lz1)
113
114c Multiply by filter weight (chi)
115 call cmult(ta1,hpf_chi,n)
116
117c Multiply by Mass matrix
118c and add to source term
119 call addcol3(bqp(1,ifield-1,jp),ta1,bm1,n)
120 endif
121
122 endif
123
124 return
125 end
126
127c----------------------------------------------------------------------
128
129 subroutine build_hpf_mat(op_mat,f_filter,ifboyd)
130
131c Builds the operator for high pass filtering
132c Transformation matrix from nodal to modal space.
133c Applies f_filter to the the legendre coefficients
134c Transforms back to nodal space
135c Operation: V * f_filter * V^(-1)
136c Where V is the transformation matrix from modal to nodal space
137
138c implicit none
139
140 include 'SIZE'
141
142 logical IFBOYD
143 integer n
144 parameter (n=lx1*lx1)
145 integer lm, lm2
146 parameter (lm=40)
147 parameter (lm2=lm*lm)
148
149 real f_filter(lm2)
150 real op_mat(lx1,lx1)
151
152 real ref_xmap(lm2)
153 real wk_xmap(lm2)
154
155 real wk1(lm2),wk2(lm2)
156 real indr(lm),ipiv(lm),indc(lm)
157
158 real rmult(lm)
159 integer ierr
160
161 integer i,j
162
163 call spec_coeff_init(ref_xmap,ifboyd)
164
165 call copy(wk_xmap,ref_xmap,lm2)
166 call copy(wk1,wk_XMAP,lm2)
167
168 call gaujordf (wk1,lx1,lx1,indr,indc,ipiv,ierr,rmult) ! xmap inverse
169
170 call mxm (f_filter,lx1,wk1,lx1,wk2,lx1) ! -1
171 call mxm (wk_xmap,lx1,wk2,lx1,op_mat,lx1) ! V D V
172
173 return
174 end
175
176c----------------------------------------------------------------------
177
178 subroutine build_hpf_fld(v,u,f,nx,nz)
179
180c Appies the operator f to field u
181c using tensor operations
182c v = f*u
183
184c implicit none
185
186 include 'SIZE'
187 include 'TSTEP' ! ifield
188
189 integer nxyz
190 parameter (nxyz=lx1*ly1*lz1)
191
192 real w1(nxyz),w2(nxyz) ! work arrays
193 real v(nxyz,lelv) ! output fld
194 real u(nxyz,lelv) ! input fld
195c
196 integer nx,nz
197
198 real f(nx,nx),ft(nx,nx) ! operator f and its transpose
199c
200 integer e,i,j,k
201 integer nel
202
203 nel = nelv
204
205 call copy(v,u,nxyz*nel)
206c
207 call transpose(ft,nx,f,nx)
208c
209 if (ldim.eq.3) then
210 do e=1,nel
211c Filter
212 call copy(w2,v(1,e),nxyz)
213 call mxm(f,nx,w2,nx,w1,nx*nx)
214 i=1
215 j=1
216 do k=1,nx
217 call mxm(w1(i),nx,ft,nx,w2(j),nx)
218 i = i+nx*nx
219 j = j+nx*nx
220 enddo
221 call mxm (w2,nx*nx,ft,nx,w1,nx)
222
223 call sub3(w2,u(1,e),w1,nxyz)
224 call copy(v(1,e),w2,nxyz)
225c call copy(v(1,e),w1,nxyz)
226
227 enddo
228 else
229 do e=1,nel
230c Filter
231 call copy(w1,v(1,e),nxyz)
232 call mxm(f ,nx,w1,nx,w2,nx)
233 call mxm(w2,nx,ft,nx,w1,nx)
234
235 call sub3(w2,u(1,e),w1,nxyz)
236 call copy(v(1,e),w2,nxyz)
237c call copy(v(1,e),w1,nxyz)
238 enddo
239 endif
240c
241 return
242 end
243
244c----------------------------------------------------------------------
245
246 subroutine hpf_trns_fcn(diag,kut)
247
248c implicit none
249
250 include 'SIZE'
251 include 'PARALLEL'
252
253 real diag(lx1*lx1)
254 integer nx,k0,kut,kk,k
255
256 real amp
257
258c Set up transfer function
259c
260 nx = lx1
261 call ident (diag,nx)
262c
263 kut=kut ! kut=additional modes
264 k0 = nx-kut
265 do k=k0+1,nx
266 kk = k+nx*(k-1)
267 amp = ((k-k0)*(k-k0)+0.)/(kut*kut+0.) ! Normalized amplitude. quadratic growth
268 diag(kk) = 1.-amp
269 enddo
270
271c Output normalized transfer function
272 k0 = lx1+1
273 if (nio.eq.0) then
274 write(6,6) 'HPF :',((1.-diag(k)), k=1,lx1*lx1,k0)
275 6 format(a8,16f9.6,6(/,8x,16f9.6))
276 endif
277
278 return
279 end
280
281c----------------------------------------------------------------------
282
283 subroutine spec_coeff_init(ref_xmap,ifboyd)
284c Initialise spectral coefficients
285c For legendre transform
286
287c implicit none
288
289 include 'SIZE'
290 include 'WZ'
291
292 integer lm, lm2
293 parameter (lm=40)
294 parameter (lm2=lm*lm)
295
296c local variables
297 integer i, j, k, n, nx, kj
298c Legendre polynomial
299 real plegx(lm)
300 real z
301 real ref_xmap(lm2)
302 real pht(lm2)
303
304c Change of basis
305 logical IFBOYD
306c----------------------------------------
307
308 nx = LX1
309 kj = 0
310 n = nx-1
311 do j=1,nx
312 z = ZGM1(j,1)
313 call legendre_poly(plegx,z,n)
314 kj = kj+1
315 pht(kj) = plegx(1)
316 kj = kj+1
317 pht(kj) = plegx(2)
318
319 if (IFBOYD) then ! change basis to preserve element boundary values
320 do k=3,nx
321 kj = kj+1
322 pht(kj) = plegx(k)-plegx(k-2)
323 enddo
324 else ! legendre basis
325 do k=3,nx
326 kj = kj+1
327 pht(kj) = plegx(k)
328 enddo
329 endif
330 enddo
331
332 call transpose (ref_xmap,nx,pht,nx)
333
334 return
335 end
Note: See TracBrowser for help on using the repository browser.