SFEMaNS  version 4.1 (work in progress)
Reference documentation for SFEMaNS
 All Classes Files Functions Variables Groups Pages
symmetry.f90
Go to the documentation of this file.
2 
3  IMPLICIT NONE
4 
7 
8  !Symmetrization-------------------------------------------------------------
9  INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: vv_mz_LA, H_mz_LA
10  LOGICAL, PRIVATE :: need_sym=.FALSE.
11  !---------------------------------------------------------------------------
12 PRIVATE
13 #include "petsc/finclude/petsc.h"
14 
15  CONTAINS
16 
17 ! This routine is called in initialization.f90 s.t. vv_mz_LA(PUBLIC) = ltg_LA
18  SUBROUTINE symmetric_points(mesh_loc, mesh_glob, ltg_LA)
19  USE def_type_mesh
20  IMPLICIT NONE
21 
22  TYPE(mesh_type) :: mesh_loc, mesh_glob
23  INTEGER, DIMENSION(:) :: ltg_la
24  INTEGER, DIMENSION(mesh_loc%np) :: i_d
25  INTEGER :: i, j, m, dom, n_w
26  REAL(KIND=8) :: xx, zz, epsilon
27 
28  need_sym=.true.
29  epsilon = 1.d-8
30  ltg_la = -1
31  n_w = SIZE(mesh_loc%jj,1)
32 
33  DO m=1, mesh_loc%me
34  i_d(mesh_loc%jj(:,m)) = mesh_loc%i_d(m)
35  END DO
36 
37  DO i = 1, mesh_loc%np
38  xx = mesh_loc%rr(1,i)
39  zz = -mesh_loc%rr(2,i)
40  dom = i_d(i)
41  DO m = 1, mesh_glob%me
42  IF (mesh_glob%i_d(m) /= dom) cycle
43  DO j = 1, n_w
44  IF (abs(xx-mesh_glob%rr(1,mesh_glob%jj(j,m)))+abs(zz-mesh_glob%rr(2,mesh_glob%jj(j,m))) .LT. epsilon) THEN
45  ltg_la(i) = mesh_glob%jj(j,m)
46  EXIT
47  END IF
48  END DO
49  END DO
50  END DO
51 
52  IF (minval(ltg_la)<0 .AND. (mesh_loc%me/=0)) THEN
53  WRITE(*,*) 'bug in symmetric_points'
54  END IF
55 
56  END SUBROUTINE symmetric_points
57 
58  SUBROUTINE symm_champ(communicator, vv_in, mesh, vv_out, if_u_h)
59  USE def_type_mesh
60  USE st_matrix
61 
62  IMPLICIT NONE
63 
64  TYPE(mesh_type) :: mesh
65  REAL(KIND=8), DIMENSION(:,:,:), INTENT(IN) :: vv_in
66  REAL(KIND=8), DIMENSION(:,:,:), INTENT(OUT) :: vv_out
67  CHARACTER(len=1), INTENT(IN) :: if_u_h
68  INTEGER, POINTER, DIMENSION(:) :: ifrom
69  INTEGER :: n, i, j
70  type(petsc_csr_la), SAVE :: la_u, la_hh
71  INTEGER, ALLOCATABLE, DIMENSION(:) :: ix
72 
73  LOGICAL, SAVE :: once_u=.true.
74  LOGICAL, SAVE :: once_h=.true.
75 #include "petsc/finclude/petscvec.h90"
76  vec, SAVE :: vv_mz, vv_mz_ghost, h_mz, h_mz_ghost
77  petscerrorcode :: ierr
78  mpi_comm :: communicator
79  petscscalar, POINTER :: x_loc(:)
80 
81 
82  IF (mesh%me ==0) RETURN
83 
84  vv_out = 0.d0
85  IF (.NOT. need_sym) RETURN
86 
87  IF ((once_u) .AND. (if_u_h=='u')) THEN
88  ALLOCATE(la_u%loc_to_glob(1,mesh%np))
89  la_u%loc_to_glob(1,:) = mesh%loc_to_glob
90  la_u%kmax = 1
91  CALL create_my_ghost(mesh,la_u,ifrom)
92  n = mesh%dom_np
93  CALL veccreateghost(communicator, n, &
94  petsc_determine, SIZE(ifrom), ifrom, vv_mz, ierr)
95  CALL vecghostgetlocalform(vv_mz, vv_mz_ghost, ierr)
96  once_u = .false.
97  END IF
98 
99  IF ((once_h) .AND. (if_u_h=='h')) THEN
100  ALLOCATE(la_hh%loc_to_glob(1,mesh%np))
101  la_hh%loc_to_glob(1,:) = mesh%loc_to_glob
102  la_hh%kmax = 1
103  CALL create_my_ghost(mesh,la_hh,ifrom)
104  n = mesh%dom_np
105  CALL veccreateghost(communicator, n, &
106  petsc_determine, SIZE(ifrom), ifrom, h_mz, ierr)
107  CALL vecghostgetlocalform(h_mz, h_mz_ghost, ierr)
108  once_h = .false.
109  END IF
110 
111 ! ix begins to 0 because of PETSC and contains the global information for symmetric points
112  ALLOCATE(ix(mesh%np))
113  IF (if_u_h == 'u') THEN
114  ix = vv_mz_la-1
115  DO i = 1, SIZE(vv_in,2)
116  DO j = 1, SIZE(vv_in,3)
117  CALL veczeroentries(vv_mz, ierr)
118  CALL vecsetvalues(vv_mz, mesh%np, ix, vv_in(:,i,j), insert_values, ierr)
119  CALL vecassemblybegin(vv_mz, ierr)
120  CALL vecassemblyend(vv_mz, ierr)
121  CALL vecghostupdatebegin(vv_mz,insert_values, scatter_forward,ierr)
122  CALL vecghostupdateend(vv_mz,insert_values, scatter_forward, ierr)
123  CALL vecgetarrayf90(vv_mz_ghost, x_loc, ierr)
124  vv_out(:,i,j) = x_loc(:)
125  CALL vecrestorearrayf90(vv_mz_ghost, x_loc, ierr)
126 
127  END DO
128  END DO
129  ELSE IF (if_u_h=='h') THEN
130  ix = h_mz_la-1
131  DO i = 1, SIZE(vv_in,2)
132  DO j = 1, SIZE(vv_in,3)
133  CALL veczeroentries(h_mz, ierr)
134  CALL vecsetvalues(h_mz, mesh%np, ix, vv_in(:,i,j), insert_values, ierr)
135  CALL vecassemblybegin(h_mz, ierr)
136  CALL vecassemblyend(h_mz, ierr)
137  CALL vecghostupdatebegin(h_mz,insert_values, scatter_forward,ierr)
138  CALL vecghostupdateend(h_mz,insert_values, scatter_forward, ierr)
139  CALL vecgetarrayf90(h_mz_ghost, x_loc, ierr)
140  vv_out(:,i,j) = x_loc(:)
141  CALL vecrestorearrayf90(h_mz_ghost, x_loc, ierr)
142  END DO
143  END DO
144  END IF
145  DEALLOCATE(ix)
146  END SUBROUTINE symm_champ
147 
148  SUBROUTINE val_ener_sym_centrale(communicator, mesh, list_mode, v, e_mode, e_mode_sym, e_mode_anti, if_u_h)
149  !type_sym = 1 pour un champ pair
150  !type_sym = -1 pour un champ impair
151 
152  USE gauss_points
153  USE def_type_mesh
154  USE tn_axi
155 
156  IMPLICIT NONE
157  TYPE(mesh_type), TARGET :: mesh
158  INTEGER, DIMENSION(:), INTENT(IN) :: list_mode
159  REAL(KIND=8), DIMENSION(:,:,:) ,INTENT(IN) :: v !champ
160  REAL(KIND=8), DIMENSION(mesh%np, SIZE(v,2),SIZE(list_mode)) :: vv
161  REAL(KIND=8), DIMENSION(SIZE(list_mode)) ,INTENT(OUT):: e_mode, e_mode_sym, e_mode_anti !energie par mode
162  CHARACTER(len=1), INTENT(IN) :: if_u_h
163  REAL(KIND=8),DIMENSION(3) :: type_sym
164  !type_sym(r,theta,z)
165  REAL(KIND=8), DIMENSION(mesh%np,size(v,2),size(list_mode)) :: champ_anti, champ_sym !champ
166 
167  INTEGER, DIMENSION(:,:), POINTER :: jj
168  INTEGER, POINTER :: me
169  INTEGER :: i
170  INTEGER :: m_max_c
171 #include "petsc/finclude/petsc.h"
172  mpi_comm :: communicator
173 
174 
175  CALL gauss(mesh)
176  jj => mesh%jj
177  me => mesh%me
178  m_max_c = size(list_mode)
179  e_mode = 0.d0
180  e_mode_sym = 0.d0
181  e_mode_anti = 0.d0
182 
183  CALL symm_champ(communicator, v, mesh, vv, if_u_h)
184 
185  !===Compute anti-symmetric field
186  DO i=1, size(list_mode)
187  IF (mod(list_mode(i),2) == 0) THEN !mode pair
188  type_sym(1) = 1.d0
189  type_sym(2) = 1.d0
190  type_sym(3) = -1.d0
191  ELSE
192  type_sym(1) = -1.d0
193  type_sym(2) = -1.d0
194  type_sym(3) = 1.d0
195  ENDIF
196  champ_anti(:,1:2,i) = 0.5d0*(v(:,1:2,i) - type_sym(1)*vv(:,1:2,i))
197  champ_anti(:,3:4,i) = 0.5d0*(v(:,3:4,i) - type_sym(2)*vv(:,3:4,i))
198  champ_anti(:,5:6,i) = 0.5d0*(v(:,5:6,i) - type_sym(3)*vv(:,5:6,i))
199  champ_sym(:,1:2,i) = 0.5d0*(v(:,1:2,i) + type_sym(1)*vv(:,1:2,i))
200  champ_sym(:,3:4,i) = 0.5d0*(v(:,3:4,i) + type_sym(2)*vv(:,3:4,i))
201  champ_sym(:,5:6,i) = 0.5d0*(v(:,5:6,i) + type_sym(3)*vv(:,5:6,i))
202  ENDDO
203  write(*,*) '===Compute anti-symmetric field'
204 
205  !===Compute energies
206  DO i=1, m_max_c
207  e_mode(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), v(:,:,i:i)))**2
208  e_mode_anti(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), champ_anti(:,:,i:i)))**2
209  e_mode_sym(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), champ_sym(:,:,i:i)))**2
210  ENDDO
211 !!$ e_mode_sym = e_mode - e_mode_anti
212 
213 
214  END SUBROUTINE val_ener_sym_centrale
215 
216  SUBROUTINE val_ener_sym_glob(communicator, mesh, list_mode, v, e_mode, e_mode_sym, e_mode_anti, type_sym, if_u_h)
217  !type_sym = 1 pour un champ pair
218  !type_sym = -1 pour un champ impair
219 
220  USE gauss_points
221  USE def_type_mesh
222  USE tn_axi
223 
224  IMPLICIT NONE
225  TYPE(mesh_type), TARGET :: mesh
226  INTEGER, DIMENSION(:), INTENT(IN) :: list_mode
227  REAL(KIND=8), DIMENSION(:,:,:) ,INTENT(IN) :: v !champ
228  REAL(KIND=8), DIMENSION(mesh%np, SIZE(v,2),SIZE(list_mode)) :: vv
229  REAL(KIND=8), DIMENSION(SIZE(list_mode)) ,INTENT(OUT):: e_mode, e_mode_sym, e_mode_anti !energie par mode
230  REAL(KIND=8),DIMENSION(3), INTENT(IN) :: type_sym
231  CHARACTER(len=1), INTENT(IN) :: if_u_h
232  !type_sym(r,theta,z)
233  REAL(KIND=8), DIMENSION(mesh%np,size(v,2),size(list_mode)) :: champ_anti, champ_sym !champ
234 
235  INTEGER, DIMENSION(:,:), POINTER :: jj
236  INTEGER, POINTER :: me
237  INTEGER :: i
238  INTEGER :: m_max_c
239 #include "petsc/finclude/petsc.h"
240  mpi_comm :: communicator
241 
242 
243  CALL gauss(mesh)
244  jj => mesh%jj
245  me => mesh%me
246  m_max_c = size(list_mode)
247  e_mode = 0.d0
248  e_mode_sym = 0.d0
249  e_mode_anti = 0.d0
250 
251  CALL symm_champ(communicator, v, mesh, vv, if_u_h)
252 
253  !===Compute anti-symmetric field
254  champ_anti(:,1:2,:) = 0.5d0*(v(:,1:2,:) - type_sym(1)*vv(:,1:2,:))
255  champ_anti(:,3:4,:) = 0.5d0*(v(:,3:4,:) - type_sym(2)*vv(:,3:4,:))
256  champ_anti(:,5:6,:) = 0.5d0*(v(:,5:6,:) - type_sym(3)*vv(:,5:6,:))
257  champ_sym(:,1:2,:) = 0.5d0*(v(:,1:2,:) + type_sym(1)*vv(:,1:2,:))
258  champ_sym(:,3:4,:) = 0.5d0*(v(:,3:4,:) + type_sym(2)*vv(:,3:4,:))
259  champ_sym(:,5:6,:) = 0.5d0*(v(:,5:6,:) + type_sym(3)*vv(:,5:6,:))
260  write(*,*) '===Compute anti-symmetric field'
261 
262  !===Compute energies
263  DO i=1, m_max_c
264  e_mode(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), v(:,:,i:i)))**2
265  e_mode_anti(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), champ_anti(:,:,i:i)))**2
266  e_mode_sym(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), champ_sym(:,:,i:i)))**2
267  ENDDO
268 
269 
270  END SUBROUTINE val_ener_sym_glob
271 
272  SUBROUTINE val_ener_sym_rpi(communicator, mesh, list_mode, v, e_mode, e_mode_sym, e_mode_anti, type_sym, if_u_h)
273 ! SYMETRIE Rpi
274 ! type_sym = 1.d0
275 ! type_sym =-1.d0
276 ! type_sym =-1.d0
277 ! type_sym = 1.d0
278 ! type_sym =-1.d0
279 ! type_sym = 1.d0
280 
281  USE gauss_points
282  USE def_type_mesh
283  USE tn_axi
284 
285  IMPLICIT NONE
286  TYPE(mesh_type), TARGET :: mesh
287  INTEGER, DIMENSION(:), INTENT(IN) :: list_mode
288  REAL(KIND=8), DIMENSION(:,:,:) ,INTENT(IN) :: v !champ
289  REAL(KIND=8), DIMENSION(mesh%np, SIZE(v,2),SIZE(list_mode)) :: vv
290  REAL(KIND=8), DIMENSION(SIZE(list_mode)) ,INTENT(OUT):: e_mode, e_mode_sym, e_mode_anti !energie par mode
291  REAL(KIND=8),DIMENSION(6), INTENT(IN) :: type_sym
292  CHARACTER(len=1), INTENT(IN) :: if_u_h
293  !type_sym(r,theta,z)
294  REAL(KIND=8), DIMENSION(mesh%np,size(v,2),size(list_mode)) :: champ_anti, champ_sym !champ
295 
296  INTEGER, DIMENSION(:,:), POINTER :: jj
297  INTEGER, POINTER :: me
298  INTEGER :: i, k
299  INTEGER :: m_max_c
300 #include "petsc/finclude/petsc.h"
301  mpi_comm :: communicator
302 
303 
304  CALL gauss(mesh)
305  jj => mesh%jj
306  me => mesh%me
307  m_max_c = size(list_mode)
308  e_mode = 0.d0
309  e_mode_sym = 0.d0
310  e_mode_anti = 0.d0
311 
312  CALL symm_champ(communicator, v, mesh, vv, if_u_h)
313 
314  !===Compute anti-symmetric field
315  DO k = 1,6
316  champ_anti(:,k,:) = 0.5d0*(v(:,k,:) - type_sym(k)*vv(:,k,:))
317  champ_sym(:,k,:) = 0.5d0*(v(:,k,:) + type_sym(k)*vv(:,k,:))
318  ENDDO
319  write(*,*) '===Compute anti-symmetric field'
320 
321  !===Compute energies
322  DO i=1, m_max_c
323  e_mode(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), v(:,:,i:i)))**2
324  e_mode_anti(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), champ_anti(:,:,i:i)))**2
325  e_mode_sym(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), champ_sym(:,:,i:i)))**2
326  ENDDO
327 
328 
329  END SUBROUTINE val_ener_sym_rpi
330 
331  SUBROUTINE val_ener_north_south(communicator, mesh, list_mode, v, e_north, e_south, e_tot)
332 
333  USE gauss_points
334  USE def_type_mesh
335  USE tn_axi
336 
337  IMPLICIT NONE
338  TYPE(mesh_type), TARGET :: mesh
339  INTEGER, DIMENSION(:), INTENT(IN) :: list_mode
340  REAL(KIND=8), DIMENSION(:,:,:) ,INTENT(IN) :: v !champ
341  REAL(KIND=8), DIMENSION(mesh%np, SIZE(v,2),SIZE(list_mode)) :: vv_n, vv_s
342  REAL(KIND=8), DIMENSION(SIZE(list_mode)) ,INTENT(OUT):: e_north, e_south !energie par mode
343  REAL(KIND=8), DIMENSION(SIZE(list_mode)), OPTIONAL :: e_tot
344 
345  REAL(KIND=8) :: ray, pi
346  REAL(KIND=8), DIMENSION(2) :: e_ns
347  REAL(KIND=8) :: epsilon = 1.d-10
348  INTEGER :: i, k, j, l, m
349  INTEGER :: m_max_c
350  INTEGER :: code
351 #include "petsc/finclude/petsc.h"
352  mpi_comm :: communicator
353 
354  m_max_c = size(list_mode)
355  vv_n = 0.d0
356  vv_s = 0.d0
357  e_north = 0.d0
358  e_south = 0.d0
359  pi = acos(-1.d0)
360 
361  DO i = 1, SIZE(list_mode)
362  e_ns = 0.d0
363  DO m = 1, mesh%me
364  IF (minval(mesh%rr(2,mesh%jj(:,m))) > -epsilon) THEN ! l'element est au nord
365  j = 1
366  ELSE IF (maxval(mesh%rr(2,mesh%jj(:,m))) < epsilon) THEN ! l'element est au sud
367  j = 2
368  ELSE
369  WRITE(*,*) 'Attention, element a cheval entre nord et sud'
370  cycle
371  END IF
372  DO l = 1, mesh%gauss%l_G
373  ray = sum(mesh%rr(1,mesh%jj(:,m))*mesh%gauss%ww(:,l))
374  DO k = 1, SIZE(v,2)
375  e_ns(j) = e_ns(j) + ray*sum(v(mesh%jj(:,m),k,i)* mesh%gauss%ww(:,l))**2*mesh%gauss%rj(l,m)
376  END DO
377  END DO
378  END DO
379 
380  IF (list_mode(i) /= 0) THEN
381  e_ns = 0.5d0*e_ns
382  END IF
383 
384  CALL mpi_allreduce(e_ns(1),e_north(i),1,mpi_double_precision, mpi_sum, communicator, code)
385  CALL mpi_allreduce(e_ns(2),e_south(i),1,mpi_double_precision, mpi_sum, communicator, code)
386  IF (present(e_tot)) THEN
387  e_tot(i) = 0.5d0*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), v(:,:,i:i)))**2
388  END IF
389  END DO
390 
391  e_north = pi*e_north ! 1/2 * (2pi)
392  e_south = pi*e_south
393 
394  END SUBROUTINE val_ener_north_south
395 
396  SUBROUTINE champ_total_anti_sym(communicator, mesh, list_mode, eps_sa, v, v_out, if_u_h)
397  !type_sym = 1 pour un champ pair
398  !type_sym = -1 pour un champ impair
399 
400  USE gauss_points
401  USE def_type_mesh
402  USE tn_axi
403 
404  IMPLICIT NONE
405  TYPE(mesh_type), TARGET :: mesh
406  INTEGER, DIMENSION(:), INTENT(IN) :: list_mode
407  REAL(KIND=8), INTENT(IN) :: eps_sa ! eps_sa=+1 (anti), eps_sa=-1 (sym)
408  REAL(KIND=8), DIMENSION(:,:,:) ,INTENT(IN) :: v !champ
409  CHARACTER(len=1), INTENT(IN) :: if_u_h
410  REAL(KIND=8), DIMENSION(mesh%np, SIZE(v,2),SIZE(list_mode)) :: vv
411  REAL(KIND=8),DIMENSION(3) :: type_sym
412  !type_sym(r,theta,z)
413  REAL(KIND=8), DIMENSION(mesh%np,size(v,2),size(list_mode)), INTENT(OUT) :: v_out !champ antisymetrise
414 
415  INTEGER, DIMENSION(:,:), POINTER :: jj
416  INTEGER, POINTER :: me
417  INTEGER :: i
418  INTEGER :: m_max_c
419 #include "petsc/finclude/petsc.h"
420  mpi_comm :: communicator
421 
422 
423  CALL gauss(mesh)
424  jj => mesh%jj
425  me => mesh%me
426  m_max_c = size(list_mode)
427  v_out = 0.d0
428 
429  CALL symm_champ(communicator, v, mesh, vv, if_u_h)
430 
431  !===Compute anti-symmetric field
432  DO i=1, size(list_mode)
433  IF (mod(list_mode(i),2) == 0) THEN !mode pair
434  type_sym(1) = 1.d0
435  type_sym(2) = 1.d0
436  type_sym(3) = -1.d0
437  ELSE
438  type_sym(1) = -1.d0
439  type_sym(2) = -1.d0
440  type_sym(3) = 1.d0
441  ENDIF
442  v_out(:,1:2,i) = 0.5d0*(v(:,1:2,i) - eps_sa*type_sym(1)*vv(:,1:2,i))
443  v_out(:,3:4,i) = 0.5d0*(v(:,3:4,i) - eps_sa*type_sym(2)*vv(:,3:4,i))
444  v_out(:,5:6,i) = 0.5d0*(v(:,5:6,i) - eps_sa*type_sym(3)*vv(:,5:6,i))
445  ENDDO
446  write(*,*) '===Compute anti-symmetric field'
447 
448 
449  END SUBROUTINE champ_total_anti_sym
450 END MODULE symmetric_field
subroutine, public val_ener_sym_glob(communicator, mesh, list_mode, v, e_mode, e_mode_sym, e_mode_anti, type_sym, if_u_h)
Definition: symmetry.f90:216
Definition: tn_axi.f90:5
subroutine, public create_my_ghost(mesh, LA, ifrom)
Definition: st_csr.f90:14
subroutine, public val_ener_north_south(communicator, mesh, list_mode, v, e_north, e_south, e_tot)
Definition: symmetry.f90:331
subroutine gauss(mesh)
subroutine, public symm_champ(communicator, vv_in, mesh, vv_out, if_u_h)
Definition: symmetry.f90:58
subroutine, public champ_total_anti_sym(communicator, mesh, list_mode, eps_sa, v, v_out, if_u_h)
Definition: symmetry.f90:396
subroutine, public val_ener_sym_centrale(communicator, mesh, list_mode, v, e_mode, e_mode_sym, e_mode_anti, if_u_h)
Definition: symmetry.f90:148
subroutine, public symmetric_points(mesh_loc, mesh_glob, ltg_LA)
Definition: symmetry.f90:18
real(kind=8) function norme_l2_champ_par(communicator, mesh, list_mode, v)
Definition: tn_axi.f90:179
subroutine, public val_ener_sym_rpi(communicator, mesh, list_mode, v, e_mode, e_mode_sym, e_mode_anti, type_sym, if_u_h)
Definition: symmetry.f90:272