SFEMaNS  version 5.3
Reference documentation for SFEMaNS
symmetry.f90
Go to the documentation of this file.
2 #include "petsc/finclude/petsc.h"
3  USE petsc
4  IMPLICIT NONE
5 
8 
9  !Symmetrization-------------------------------------------------------------
10  INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: vv_mz_la, h_mz_la
11  LOGICAL, PRIVATE :: need_sym=.false.
12  !---------------------------------------------------------------------------
13 PRIVATE
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)
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)
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 
204  !===Compute energies
205  DO i=1, m_max_c
206  e_mode(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), v(:,:,i:i)))**2
207  e_mode_anti(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), champ_anti(:,:,i:i)))**2
208  e_mode_sym(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), champ_sym(:,:,i:i)))**2
209  ENDDO
210 !!$ e_mode_sym = e_mode - e_mode_anti
211 
212 
213  END SUBROUTINE val_ener_sym_centrale
214 
215  SUBROUTINE val_ener_sym_glob(communicator, mesh, list_mode, v, e_mode, e_mode_sym, e_mode_anti, type_sym, if_u_h)
216  !type_sym = 1 pour un champ pair
217  !type_sym = -1 pour un champ impair
218 
219  USE gauss_points
220  USE def_type_mesh
221  USE tn_axi
222 
223  IMPLICIT NONE
224  TYPE(mesh_type), TARGET :: mesh
225  INTEGER, DIMENSION(:), INTENT(IN) :: list_mode
226  REAL(KIND=8), DIMENSION(:,:,:) ,INTENT(IN) :: v !champ
227  REAL(KIND=8), DIMENSION(mesh%np, SIZE(v,2),SIZE(list_mode)) :: vv
228  REAL(KIND=8), DIMENSION(SIZE(list_mode)) ,INTENT(OUT):: e_mode, e_mode_sym, e_mode_anti !energie par mode
229  REAL(KIND=8),DIMENSION(3), INTENT(IN) :: type_sym
230  CHARACTER(len=1), INTENT(IN) :: if_u_h
231  !type_sym(r,theta,z)
232  REAL(KIND=8), DIMENSION(mesh%np,size(v,2),size(list_mode)) :: champ_anti, champ_sym !champ
233 
234  INTEGER, DIMENSION(:,:), POINTER :: jj
235  INTEGER, POINTER :: me
236  INTEGER :: i
237  INTEGER :: m_max_c
238 !#include "petsc/finclude/petsc.h"
239  mpi_comm :: communicator
240 
241 
242  CALL gauss(mesh)
243  jj => mesh%jj
244  me => mesh%me
245  m_max_c = size(list_mode)
246  e_mode = 0.d0
247  e_mode_sym = 0.d0
248  e_mode_anti = 0.d0
249 
250  CALL symm_champ(communicator, v, mesh, vv, if_u_h)
251 
252  !===Compute anti-symmetric field
253  champ_anti(:,1:2,:) = 0.5d0*(v(:,1:2,:) - type_sym(1)*vv(:,1:2,:))
254  champ_anti(:,3:4,:) = 0.5d0*(v(:,3:4,:) - type_sym(2)*vv(:,3:4,:))
255  champ_anti(:,5:6,:) = 0.5d0*(v(:,5:6,:) - type_sym(3)*vv(:,5:6,:))
256  champ_sym(:,1:2,:) = 0.5d0*(v(:,1:2,:) + type_sym(1)*vv(:,1:2,:))
257  champ_sym(:,3:4,:) = 0.5d0*(v(:,3:4,:) + type_sym(2)*vv(:,3:4,:))
258  champ_sym(:,5:6,:) = 0.5d0*(v(:,5:6,:) + type_sym(3)*vv(:,5:6,:))
259 
260  !===Compute energies
261  DO i=1, m_max_c
262  e_mode(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), v(:,:,i:i)))**2
263  e_mode_anti(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), champ_anti(:,:,i:i)))**2
264  e_mode_sym(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), champ_sym(:,:,i:i)))**2
265  ENDDO
266 
267 
268  END SUBROUTINE val_ener_sym_glob
269 
270  SUBROUTINE val_ener_sym_rpi(communicator, mesh, list_mode, v, e_mode, e_mode_sym, e_mode_anti, type_sym, if_u_h)
271 ! SYMETRIE Rpi
272 ! type_sym = 1.d0
273 ! type_sym =-1.d0
274 ! type_sym =-1.d0
275 ! type_sym = 1.d0
276 ! type_sym =-1.d0
277 ! type_sym = 1.d0
278 
279  USE gauss_points
280  USE def_type_mesh
281  USE tn_axi
282 
283  IMPLICIT NONE
284  TYPE(mesh_type), TARGET :: mesh
285  INTEGER, DIMENSION(:), INTENT(IN) :: list_mode
286  REAL(KIND=8), DIMENSION(:,:,:) ,INTENT(IN) :: v !champ
287  REAL(KIND=8), DIMENSION(mesh%np, SIZE(v,2),SIZE(list_mode)) :: vv
288  REAL(KIND=8), DIMENSION(SIZE(list_mode)) ,INTENT(OUT):: e_mode, e_mode_sym, e_mode_anti !energie par mode
289  REAL(KIND=8),DIMENSION(6), INTENT(IN) :: type_sym
290  CHARACTER(len=1), INTENT(IN) :: if_u_h
291  !type_sym(r,theta,z)
292  REAL(KIND=8), DIMENSION(mesh%np,size(v,2),size(list_mode)) :: champ_anti, champ_sym !champ
293 
294  INTEGER, DIMENSION(:,:), POINTER :: jj
295  INTEGER, POINTER :: me
296  INTEGER :: i, k
297  INTEGER :: m_max_c
298 !#include "petsc/finclude/petsc.h"
299  mpi_comm :: communicator
300 
301 
302  CALL gauss(mesh)
303  jj => mesh%jj
304  me => mesh%me
305  m_max_c = size(list_mode)
306  e_mode = 0.d0
307  e_mode_sym = 0.d0
308  e_mode_anti = 0.d0
309 
310  CALL symm_champ(communicator, v, mesh, vv, if_u_h)
311 
312  !===Compute anti-symmetric field
313  DO k = 1,6
314  champ_anti(:,k,:) = 0.5d0*(v(:,k,:) - type_sym(k)*vv(:,k,:))
315  champ_sym(:,k,:) = 0.5d0*(v(:,k,:) + type_sym(k)*vv(:,k,:))
316  ENDDO
317 
318  !===Compute energies
319  DO i=1, m_max_c
320  e_mode(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), v(:,:,i:i)))**2
321  e_mode_anti(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), champ_anti(:,:,i:i)))**2
322  e_mode_sym(i) = 0.5*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), champ_sym(:,:,i:i)))**2
323  ENDDO
324 
325 
326  END SUBROUTINE val_ener_sym_rpi
327 
328  SUBROUTINE val_ener_north_south(communicator, mesh, list_mode, v, e_north, e_south, e_tot)
330  USE gauss_points
331  USE def_type_mesh
332  USE tn_axi
333 
334  IMPLICIT NONE
335  TYPE(mesh_type), TARGET :: mesh
336  INTEGER, DIMENSION(:), INTENT(IN) :: list_mode
337  REAL(KIND=8), DIMENSION(:,:,:) ,INTENT(IN) :: v !champ
338  REAL(KIND=8), DIMENSION(mesh%np, SIZE(v,2),SIZE(list_mode)) :: vv_n, vv_s
339  REAL(KIND=8), DIMENSION(SIZE(list_mode)) ,INTENT(OUT):: e_north, e_south !energie par mode
340  REAL(KIND=8), DIMENSION(SIZE(list_mode)), OPTIONAL :: e_tot
341 
342  REAL(KIND=8) :: ray, pi
343  REAL(KIND=8), DIMENSION(2) :: e_ns
344  REAL(KIND=8) :: epsilon = 1.d-10
345  INTEGER :: i, k, j, l, m
346  INTEGER :: m_max_c
347  INTEGER :: code
348 !#include "petsc/finclude/petsc.h"
349  mpi_comm :: communicator
350 
351  m_max_c = size(list_mode)
352  vv_n = 0.d0
353  vv_s = 0.d0
354  e_north = 0.d0
355  e_south = 0.d0
356  pi = acos(-1.d0)
357 
358  DO i = 1, SIZE(list_mode)
359  e_ns = 0.d0
360  DO m = 1, mesh%me
361  IF (minval(mesh%rr(2,mesh%jj(:,m))) > -epsilon) THEN ! l'element est au nord
362  j = 1
363  ELSE IF (maxval(mesh%rr(2,mesh%jj(:,m))) < epsilon) THEN ! l'element est au sud
364  j = 2
365  ELSE
366  WRITE(*,*) 'Attention, element a cheval entre nord et sud'
367  cycle
368  END IF
369  DO l = 1, mesh%gauss%l_G
370  ray = sum(mesh%rr(1,mesh%jj(:,m))*mesh%gauss%ww(:,l))
371  DO k = 1, SIZE(v,2)
372  e_ns(j) = e_ns(j) + ray*sum(v(mesh%jj(:,m),k,i)* mesh%gauss%ww(:,l))**2*mesh%gauss%rj(l,m)
373  END DO
374  END DO
375  END DO
376 
377  IF (list_mode(i) /= 0) THEN
378  e_ns = 0.5d0*e_ns
379  END IF
380 
381  CALL mpi_allreduce(e_ns(1),e_north(i),1,mpi_double_precision, mpi_sum, communicator, code)
382  CALL mpi_allreduce(e_ns(2),e_south(i),1,mpi_double_precision, mpi_sum, communicator, code)
383  IF (PRESENT(e_tot)) THEN
384  e_tot(i) = 0.5d0*(norme_l2_champ_par(communicator, mesh, list_mode(i:i), v(:,:,i:i)))**2
385  END IF
386  END DO
387 
388  e_north = pi*e_north ! 1/2 * (2pi)
389  e_south = pi*e_south
390 
391  END SUBROUTINE val_ener_north_south
392 
393  SUBROUTINE champ_total_anti_sym(communicator, mesh, list_mode, eps_sa, v, v_out, if_u_h)
394  !type_sym = 1 pour un champ pair
395  !type_sym = -1 pour un champ impair
396 
397  USE gauss_points
398  USE def_type_mesh
399  USE tn_axi
400 
401  IMPLICIT NONE
402  TYPE(mesh_type), TARGET :: mesh
403  INTEGER, DIMENSION(:), INTENT(IN) :: list_mode
404  REAL(KIND=8), INTENT(IN) :: eps_sa ! eps_sa=+1 (anti), eps_sa=-1 (sym)
405  REAL(KIND=8), DIMENSION(:,:,:) ,INTENT(IN) :: v !champ
406  CHARACTER(len=1), INTENT(IN) :: if_u_h
407  REAL(KIND=8), DIMENSION(mesh%np, SIZE(v,2),SIZE(list_mode)) :: vv
408  REAL(KIND=8),DIMENSION(3) :: type_sym
409  !type_sym(r,theta,z)
410  REAL(KIND=8), DIMENSION(mesh%np,size(v,2),size(list_mode)), INTENT(OUT) :: v_out !champ antisymetrise
411 
412  INTEGER, DIMENSION(:,:), POINTER :: jj
413  INTEGER, POINTER :: me
414  INTEGER :: i
415  INTEGER :: m_max_c
416 !#include "petsc/finclude/petsc.h"
417  mpi_comm :: communicator
418 
419 
420  CALL gauss(mesh)
421  jj => mesh%jj
422  me => mesh%me
423  m_max_c = size(list_mode)
424  v_out = 0.d0
425 
426  CALL symm_champ(communicator, v, mesh, vv, if_u_h)
427 
428  !===Compute anti-symmetric field
429  DO i=1, size(list_mode)
430  IF (mod(list_mode(i),2) == 0) THEN !mode pair
431  type_sym(1) = 1.d0
432  type_sym(2) = 1.d0
433  type_sym(3) = -1.d0
434  ELSE
435  type_sym(1) = -1.d0
436  type_sym(2) = -1.d0
437  type_sym(3) = 1.d0
438  ENDIF
439  v_out(:,1:2,i) = 0.5d0*(v(:,1:2,i) - eps_sa*type_sym(1)*vv(:,1:2,i))
440  v_out(:,3:4,i) = 0.5d0*(v(:,3:4,i) - eps_sa*type_sym(2)*vv(:,3:4,i))
441  v_out(:,5:6,i) = 0.5d0*(v(:,5:6,i) - eps_sa*type_sym(3)*vv(:,5:6,i))
442  ENDDO
443 
444  END SUBROUTINE champ_total_anti_sym
445 END MODULE symmetric_field
subroutine, public create_my_ghost(mesh, LA, ifrom)
Definition: st_csr.f90:15
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:149
subroutine, public val_ener_north_south(communicator, mesh, list_mode, v, e_north, e_south, e_tot)
Definition: symmetry.f90:329
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
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:271
integer, dimension(:), allocatable, public vv_mz_la
Definition: symmetry.f90:10
logical, private need_sym
Definition: symmetry.f90:11
subroutine, public symmetric_points(mesh_loc, mesh_glob, ltg_LA)
Definition: symmetry.f90:19
subroutine, public symm_champ(communicator, vv_in, mesh, vv_out, if_u_h)
Definition: symmetry.f90:59
real(kind=8) function norme_l2_champ_par(communicator, mesh, list_mode, v)
Definition: tn_axi.f90:185
Definition: tn_axi.f90:5
subroutine, public champ_total_anti_sym(communicator, mesh, list_mode, eps_sa, v, v_out, if_u_h)
Definition: symmetry.f90:394
integer, dimension(:), allocatable, public h_mz_la
Definition: symmetry.f90:10
subroutine gauss(mesh)