ADflow  v1.0
ADflow is a finite volume RANS solver tailored for gradient-based aerodynamic design optimization.
warping.F90
Go to the documentation of this file.
1 module warping
2 
3  ! This module cotains the required inferface functions for using an
4  ! external mesh warping utility with ADflow
5 
6 contains
7 
8  subroutine getcgnsmeshindices(ndof, indices)
9 
10  use constants
11  use blockpointers, only: ndom, nbkglobal, il, jl, kl, ibegor, jbegor, kbegor
12  use cgnsgrid, only: cgnsdoms, cgnsndom
13  use utils, only: setpointers
14  implicit none
15 
16  ! subroutine arguments
17  integer(kind=intType), intent(in) :: ndof
18  integer(kind=intType), intent(out) :: indices(ndof)
19 
20  ! Local Variables
21  integer(kind=intType) :: nn, i, j, k, ii, indx, indy, indz, il_cg, jl_cg, kl_cg
22  integer(kind=intType), allocatable, dimension(:) :: dof_offset
23 
24  allocate (dof_offset(cgnsndom))
25  dof_offset(1) = 0
26  do nn = 2, cgnsndom
27  dof_offset(nn) = dof_offset(nn - 1) + &
28  cgnsdoms(nn - 1)%il * cgnsdoms(nn - 1)%jl * cgnsdoms(nn - 1)%kl * 3
29  end do
30 
31  ii = 0
32  do nn = 1, ndom
33  call setpointers(nn, 1_inttype, 1_inttype)
34 
35  do k = 1, kl
36  do j = 1, jl
37  do i = 1, il
38  il_cg = cgnsdoms(nbkglobal)%il
39  jl_cg = cgnsdoms(nbkglobal)%jl
40  kl_cg = cgnsdoms(nbkglobal)%kl
41 
42  ii = ii + 1
43 
44  indx = ibegor + i - 1
45  indy = jbegor + j - 1
46  indz = kbegor + k - 1
47 
48  indices(ii * 3 - 2) = dof_offset(nbkglobal) + &
49  (indz - 1) * jl_cg * il_cg * 3 + &
50  (indy - 1) * il_cg * 3 + &
51  (indx - 1) * 3
52 
53  indices(ii * 3 - 1) = dof_offset(nbkglobal) + &
54  (indz - 1) * jl_cg * il_cg * 3 + &
55  (indy - 1) * il_cg * 3 + &
56  (indx - 1) * 3 + 1
57 
58  indices(ii * 3) = dof_offset(nbkglobal) + &
59  (indz - 1) * jl_cg * il_cg * 3 + &
60  (indy - 1) * il_cg * 3 + &
61  (indx - 1) * 3 + 2
62 
63  end do ! i loop
64  end do ! j loop
65  end do ! k loop
66  end do ! domain loop
67  deallocate (dof_offset)
68  end subroutine getcgnsmeshindices
69 
70  subroutine setgrid(grid, ndof)
71 
72  ! The purpose of this routine is to set the grid dof as returned by
73  ! the external warping. This function takes the "Base" grid at the
74  ! first time instance and does rotation/translation operations to
75  ! get the grid at subsequent time instances
76  use constants
77  use blockpointers, only: ndom, il, jl, kl, x
79  use section, only: sections, nsections
82  use inputphysics, only: equationmode
84  use preprocessingapi, only: xhalo
85  implicit none
86 
87  integer(kind=intType), intent(in) :: ndof
88  real(kind=realtype), intent(in) :: grid(ndof)
89 
90  ! Local Variables
91 
92  integer(kind=intType) :: nn, i, j, k, counter, sps
93  real(kind=realtype) :: t(nsections), dt(nsections)
94  real(kind=realtype) :: displ(3)
95  real(kind=realtype) :: told, tnew
96 
97  real(kind=realtype), dimension(3) :: rotationpoint, r
98  real(kind=realtype), dimension(3, 3) :: rotationmatrix
99 
100  if (equationmode == steady .or. equationmode == timespectral) then
102 
103  ! This is very straight forward...loop over all domains and set all elements
104  do nn = 1, nsections
105  dt(nn) = sections(nn)%timePeriod &
106  / real(ntimeintervalsspectral, realtype)
107  end do
108 
109  do sps = 1, ntimeintervalsspectral
110  do nn = 1, nsections
111  t(nn) = (sps - 1) * dt(nn)
112  end do
113 
114  ! Compute the displacements due to the rigid motion of the mesh.
115 
116  displ(:) = zero
117 
119  told = tnew - t(1)
120 
121  call rotmatrixrigidbody(tnew, told, rotationmatrix, rotationpoint)
122  counter = 0
123  do nn = 1, ndom
124  call setpointers(nn, 1_inttype, sps)
125  do k = 1, kl
126  do j = 1, jl
127  do i = 1, il
128  ! r is distance from grid point to rotationPoint
129  r = grid(3 * counter + 1:3 * counter + 3) - rotationpoint
130 
131  x(i, j, k, :) = rotationpoint + matmul(rotationmatrix, r) + displ
132  counter = counter + 1
133 
134  end do
135  end do
136  end do
137  end do
138  call xhalo(1_inttype)
139  end do
140  else
141  counter = 0
142  sps = 1
143  do nn = 1, ndom
144  call setpointers(nn, 1_inttype, sps)
145  do k = 1, kl
146  do j = 1, jl
147  do i = 1, il
148  x(i, j, k, :) = grid(3 * counter + 1:3 * counter + 3)
149  counter = counter + 1
150  end do
151  end do
152  end do
153  end do
154  call xhalo(1_inttype)
155  end if
156 
157  end subroutine setgrid
158 
159  subroutine setgridforoneinstance(grid, sps)
160 
161  ! The purpose of this routine is to set the grid dof as returned by
162  ! the external warping. This routine will take in the deformed mesh
163  ! and set it to "sps"th time instance
164  use constants
165  use blockpointers, only: ndom, il, jl, kl, x
166  use section, only: sections, nsections
167  use inputphysics, only: equationmode
168  use utils, only: setpointers
169  use preprocessingapi, only: xhalo
170  implicit none
171 
172  real(kind=realtype), dimension(:), intent(in) :: grid
173  integer, intent(in) :: sps
174 
175  ! Local Variables
176 
177  integer(kind=intType) :: nn, i, j, k, counter
178 
179  counter = 0
180  do nn = 1, ndom
181  call setpointers(nn, 1_inttype, sps)
182  do k = 1, kl
183  do j = 1, jl
184  do i = 1, il
185  x(i, j, k, :) = grid(3 * counter + 1:3 * counter + 3)
186  counter = counter + 1
187  end do
188  end do
189  end do
190  end do
191  call xhalo(1_inttype)
192 
193  end subroutine setgridforoneinstance
194 
195  subroutine getgrid(grid, ndof)
196 
197  ! Opposite of setGrid. This is ONLY a debugging function. NOT used
198  ! in regular usage. Really only useful for direct mesh manipulation
199  ! on single block and a single processor. s
200 
201  use constants
202  use blockpointers, only: ndom, il, jl, kl, x
204  use utils, only: setpointers
205  implicit none
206  integer(kind=intType), intent(in) :: ndof
207  real(kind=realtype), intent(out) :: grid(ndof)
208 
209  ! Local Variables
210  integer(kind=intType) :: nn, i, j, k, l, counter, sps
211 
212  ! This is very straight forward...loop over all domains and copy out
213  counter = 1
214  do sps = 1, ntimeintervalsspectral
215  do nn = 1, ndom
216  call setpointers(nn, 1_inttype, sps)
217  do k = 1, kl
218  do j = 1, jl
219  do i = 1, il
220  do l = 1, 3
221  grid(counter) = x(i, j, k, l)
222  counter = counter + 1
223  end do
224  end do
225  end do
226  end do
227  end do
228  end do
229 
230  end subroutine getgrid
231 
232  subroutine getstateperturbation(randVec, nRand, randState, nRandState)
233 
234  use constants
235  use cgnsgrid, only: cgnsdoms, cgnsndom
236  use blockpointers, only: ndom, il, jl, kl, nx, ny, nz, x, nbkglobal, ibegor, jbegor, kbegor
239  use adjointvars, only: ncellslocal
240  use flowvarrefstate, only: nw
241  use utils, only: setpointers, echk
242  implicit none
243 
244  ! Input Parameters
245  integer(kind=intType), intent(in) :: nRand, nRandState
246  real(kind=realtype), intent(in), dimension(nRand) :: randvec
247 
248  ! Ouput Parameters
249  real(kind=realtype), intent(out), dimension(nRandState) :: randstate
250 
251  ! Working parameters
252  integer(kind=intType) :: i, j, k, ierr, l, nx_cg, ny_cg, nz_cg
253  integer(kind=intType) :: sps, ii, indx, indy, indz, nn, cgnsInd
254  integer(kind=intType) :: dofCGNSPerInstance
255  integer(kind=intType), allocatable, dimension(:) :: dof_offset
256 
257  allocate (dof_offset(cgnsndom))
258  dof_offset(1) = 0
259  do nn = 2, cgnsndom
260  dof_offset(nn) = dof_offset(nn - 1) + &
261  cgnsdoms(nn - 1)%nx * cgnsdoms(nn - 1)%ny * cgnsdoms(nn - 1)%nz * nw
262  end do
263 
264  dofcgnsperinstance = nrand / ntimeintervalsspectral
265 
266  ii = 0
267  do nn = 1, ndom
268  do sps = 1, ntimeintervalsspectral
269  call setpointers(nn, 1, sps)
270  do k = 2, kl
271  do j = 2, jl
272  do i = 2, il
273 
274  nx_cg = cgnsdoms(nbkglobal)%nx
275  ny_cg = cgnsdoms(nbkglobal)%ny
276  nz_cg = cgnsdoms(nbkglobal)%nz
277 
278  indx = ibegor + i - 2
279  indy = jbegor + j - 2
280  indz = kbegor + k - 2
281 
282  do l = 1, nw
283  cgnsind = (sps - 1) * dofcgnsperinstance + &
284  dof_offset(nbkglobal) + &
285  (indz - 1) * ny_cg * nx_cg * nw + &
286  (indy - 1) * nx_cg * nw + &
287  (indx - 1) * nw + l
288  randstate(nw * ii + l) = randvec(cgnsind)
289  end do
290 
291  ii = ii + 1
292 
293  end do
294  end do
295  end do
296  end do
297  end do
298  end subroutine getstateperturbation
299 
300  subroutine getsurfaceperturbation(xRand, nRand, randSurface, nRandSurface, famList, nFamList, sps)
301 
302  use constants
303  use blockpointers, only: ndom, bcdata, nbocos, bcfaceid, il, jl, kl
306  use utils, only: setpointers, echk
307  use sorting, only: faminlist
310 #include <petsc/finclude/petsc.h>
311  use petsc
312  implicit none
313 
314  ! Input Parameters
315  integer(kind=intType), intent(in) :: nRand, nRandSurface
316  real(kind=realtype), intent(in), dimension(nRand) :: xrand
317  integer(kind=intType), intent(in) :: nFamList, famList(nFamList), sps
318  ! Ouput Parameters
319  real(kind=realtype), intent(inout), dimension(3*nRandSurface) :: randsurface
320 
321  ! Working parameters
322  integer(kind=intType) :: i, j, k, ierr, iDim, iBeg, iEnd, jBeg, jEnd, nn, mm
323  integer(kind=intType) :: ii, jj, indI, indJ, indK, jjInd, iBCGroup
324  type(zippermesh), pointer :: zipper
325  type(familyexchange), pointer :: exch
326  logical :: BCGroupNeeded
327  real(kind=realtype), dimension(:), pointer :: localptr
328 
329  ii = 0
330  jj = 0
331  domains: do nn = 1, ndom
332  call setpointers(nn, 1_inttype, sps)
333 
334  ! Loop over the number of boundary subfaces of this block.
335  bocos: do mm = 1, nbocos
336 
337  ! NODE Based
338  jbeg = bcdata(mm)%jnBeg; jend = bcdata(mm)%jnEnd
339  ibeg = bcdata(mm)%inBeg; iend = bcdata(mm)%inEnd
340 
341  faminclude: if (faminlist(bcdata(mm)%famID, famlist)) then
342 
343  do j = jbeg, jend ! This is a node loop
344  do i = ibeg, iend ! This is a node loop
345  select case (bcfaceid(mm))
346  case (imin)
347  indi = 1
348  indj = i
349  indk = j
350  case (imax)
351  indi = il
352  indj = i
353  indk = j
354  case (jmin)
355  indi = i
356  indj = 1
357  indk = j
358  case (jmax)
359  indi = i
360  indj = jl
361  indk = j
362  case (kmin)
363  indi = i
364  indj = j
365  indk = 1
366  case (kmax)
367  indi = i
368  indj = j
369  indk = kl
370  end select
371 
372  do idim = 1, 3
373  jjind = jj + (indk - 1) * il * jl + (indj - 1) * il + (indi - 1) + idim
374  randsurface(3 * ii + idim) = xrand(jjind)
375  end do
376  ii = ii + 1
377  end do
378  end do
379  end if faminclude
380  end do bocos
381 
382  ! jj is the counter through xRand. Increment it by the full
383  ! block.
384  jj = jj + il * jl * kl * 3
385  end do domains
386 
387  ! No overset or not zipper, return
388  if (.not. oversetpresent) then ! .or. .not. includeZipper) then
389  return
390  end if
391 
392  ! If there are zipper meshes, we must include the nodes that the
393  ! zipper triangles will use.
394  do ibcgroup = 1, nfamexchange
395 
396  zipper => zippermeshes(ibcgroup)
397 
398  if (.not. zipper%allocated) then
399  cycle
400  end if
401 
402  exch => bcfamexchange(ibcgroup, sps)
403  bcgroupneeded = .false.
404  bcgroupfamloop: do i = 1, size(bcfamgroups(ibcgroup)%famList)
405  if (faminlist(bcfamgroups(ibcgroup)%famList(i), famlist)) then
406  bcgroupneeded = .true.
407  exit bcgroupfamloop
408  end if
409  end do bcgroupfamloop
410 
411  if (.not. bcgroupneeded) then
412  cycle
413  end if
414 
415  ! Now we know we *actually* need something from this BCGroup.
416 
417  ! Loop over each dimension individually since we have a scalar
418  ! scatter.
419  dimloop: do idim = 1, 3
420 
421  call vecgetarrayf90(exch%nodeValLocal, localptr, ierr)
422  call echk(ierr, __file__, __line__)
423 
424  ! The local Pointer is just the localRandSurface we've set
425  ! above.
426  do j = 1, size(localptr)
427  localptr(i) = randsurface(3 * (j - 1) + idim)
428  end do
429 
430  ! Restore the pointer
431  call vecrestorearrayf90(exch%nodeValLocal, localptr, ierr)
432  call echk(ierr, __file__, __line__)
433 
434  ! Now scatter this to the zipper
435  call vecscatterbegin(zipper%scatter, exch%nodeValLocal, &
436  zipper%localVal, insert_values, scatter_forward, ierr)
437  call echk(ierr, __file__, __line__)
438 
439  call vecscatterend(zipper%scatter, exch%nodeValLocal, &
440  zipper%localVal, insert_values, scatter_forward, ierr)
441  call echk(ierr, __file__, __line__)
442 
443  ! The values we need are precisely what is in zipper%localVal
444  call vecgetarrayf90(zipper%localVal, localptr, ierr)
445  call echk(ierr, __file__, __line__)
446 
447  ! Just copy the received seeds into the random aray
448  do j = 1, size(localptr)
449  ! Careful here becuase we have to interlate the dim
450  randsurface(3 * ii + 3 * (j - 1) + idim) = localptr(j)
451  end do
452 
453  end do dimloop
454 
455  ! Increcment the running ii counter.
456  ii = ii + size(localptr)
457  end do
458  end subroutine getsurfaceperturbation
459 
460 end module warping
integer(kind=inttype), dimension(maxlevels) ncellslocal
Definition: ADjointVars.F90:40
Definition: BCData.F90:1
integer(kind=inttype) jl
integer(kind=inttype) kbegor
integer(kind=inttype) nx
integer(kind=inttype) ny
integer(kind=inttype) nbkglobal
integer(kind=inttype), dimension(:), pointer bcfaceid
integer(kind=inttype) ibegor
integer(kind=inttype) nbocos
integer(kind=inttype) jbegor
integer(kind=inttype) nz
real(kind=realtype), dimension(:, :, :, :), pointer x
integer(kind=inttype) kl
integer(kind=inttype) il
type(cgnsblockinfotype), dimension(:), allocatable cgnsdoms
Definition: cgnsGrid.F90:495
integer(kind=inttype) cgnsndom
Definition: cgnsGrid.F90:491
integer adflow_comm_world
real(kind=realtype), parameter zero
Definition: constants.F90:71
integer(kind=inttype), parameter imax
Definition: constants.F90:293
integer(kind=inttype), parameter kmin
Definition: constants.F90:296
integer(kind=inttype), parameter jmax
Definition: constants.F90:295
integer(kind=inttype), parameter nfamexchange
Definition: constants.F90:317
integer(kind=inttype), parameter timespectral
Definition: constants.F90:115
integer(kind=inttype), parameter imin
Definition: constants.F90:292
integer(kind=inttype), parameter steady
Definition: constants.F90:115
integer(kind=inttype), parameter kmax
Definition: constants.F90:297
integer(kind=inttype), parameter jmin
Definition: constants.F90:294
integer(kind=inttype) nw
integer(kind=inttype) equationmode
Definition: inputParam.F90:583
integer(kind=inttype) ntimeintervalsspectral
Definition: inputParam.F90:645
real(kind=realtype) timeunsteady
Definition: monitor.f90:98
real(kind=realtype) timeunsteadyrestart
Definition: monitor.f90:98
type(zippermesh), dimension(nfamexchange), target zippermeshes
Definition: overset.F90:376
logical oversetpresent
Definition: overset.F90:373
subroutine xhalo(level)
integer(kind=inttype) nsections
Definition: section.f90:44
type(sectiontype), dimension(:), allocatable sections
Definition: section.f90:46
logical function faminlist(famID, famList)
Definition: sorting.F90:7
type(bcgrouptype), dimension(nfamexchange) bcfamgroups
type(familyexchange), dimension(:, :), allocatable, target bcfamexchange
Definition: utils.F90:1
subroutine rotmatrixrigidbody(tNew, tOld, rotationMatrix, rotationPoint)
Definition: utils.F90:614
subroutine echk(errorcode, file, line)
Definition: utils.F90:5722
subroutine setpointers(nn, mm, ll)
Definition: utils.F90:3237
subroutine getstateperturbation(randVec, nRand, randState, nRandState)
Definition: warping.F90:233
subroutine setgrid(grid, ndof)
Definition: warping.F90:71
subroutine getgrid(grid, ndof)
Definition: warping.F90:196
subroutine setgridforoneinstance(grid, sps)
Definition: warping.F90:160
subroutine getsurfaceperturbation(xRand, nRand, randSurface, nRandSurface, famList, nFamList, sps)
Definition: warping.F90:301
subroutine getcgnsmeshindices(ndof, indices)
Definition: warping.F90:9