SFEMaNS  version 4.1 (work in progress)
Reference documentation for SFEMaNS
 All Classes Files Functions Variables Groups Pages
sub_temperature.f90
Go to the documentation of this file.
1 !
2 !Authors Jean-Luc Guermond, Raphael Laguerre, Caroline Nore, Copyrights 2005
3 !Revised for PETSC, Jean-Luc Guermond, Franky Luddens, January 2011
4 !
6  USE my_util
7  USE boundary
8 
10  PRIVATE
11 CONTAINS
12 
13  SUBROUTINE three_level_temperature(comm_one_d,time, temp_1_LA, dt, list_mode, &
14  temp_mesh, tempn_m1, tempn, chmp_vit, vol_heat_capacity, &
15  temp_diffusivity, my_par_cc, temp_list_dirichlet_sides, temp_per)
16  !==============================
17  USE def_type_mesh
18  USE fem_m_axi
19  USE fem_rhs_axi
20  USE fem_tn_axi
21  USE dir_nodes_petsc
22  USE periodic
23  USE st_matrix
24  USE solve_petsc
25  USE dyn_line
26  USE boundary
28  USE sub_plot
29  USE st_matrix
30  USE sft_parallele
31  IMPLICIT NONE
32  REAL(KIND=8) :: time, dt
33  INTEGER, DIMENSION(:), INTENT(IN) :: list_mode
34  TYPE(mesh_type), INTENT(IN) :: temp_mesh
35  type(petsc_csr_la) :: temp_1_la
36  TYPE(periodic_type), INTENT(IN) :: temp_per
37  TYPE(solver_param), INTENT(IN) :: my_par_cc
38  REAL(KIND=8), DIMENSION(:,:,:), INTENT(INOUT) :: tempn_m1, tempn
39  INTEGER, DIMENSION(:), INTENT(IN) :: temp_list_dirichlet_sides
40  REAL(KIND=8), DIMENSION(:), INTENT(IN) :: vol_heat_capacity, temp_diffusivity
41  REAL(KIND=8), DIMENSION(:,:,:), INTENT(IN) :: chmp_vit
42  LOGICAL, SAVE :: once = .true.
43  INTEGER, SAVE :: m_max_c
44  INTEGER, DIMENSION(:), POINTER, SAVE :: temp_js_d ! Dirichlet nodes
45  INTEGER, SAVE :: my_petscworld_rank
46  REAL(KIND=8), SAVE :: mass0, hmoy
47  !----------FIN SAVE--------------------------------------------------------------------
48 
49  !----------Declaration sans save-------------------------------------------------------
50  INTEGER, POINTER, DIMENSION(:) :: temp_1_ifrom
51  INTEGER :: i, m, n, l, index
52  INTEGER :: code, mode
53  !allocations des variables locales
54  REAL(KIND=8), DIMENSION(temp_mesh%np) :: ff
55  REAL(KIND=8), DIMENSION(temp_mesh%np, 2) :: tempn_p1
56  REAL(KIND=8), DIMENSION(temp_mesh%gauss%l_G*temp_mesh%me,2, SIZE(list_mode)) :: ff_conv
57  REAL(KIND=8) ::tps, tps_tot, tps_cumul
58  REAL(KIND=8) :: one, zero, three
59  DATA zero, one, three/0.d0,1.d0,3.d0/
60  REAL(KIND=8), DIMENSION(2,temp_mesh%gauss%l_G*temp_mesh%me) :: rr_gauss
61  INTEGER, DIMENSION(temp_mesh%gauss%n_w) :: j_loc
62  !Communicators for Petsc, in space and Fourier------------------------------
63 #include "petsc/finclude/petsc.h"
64  petscerrorcode :: ierr
65  mpi_comm, DIMENSION(:), POINTER :: comm_one_d
66  mat, DIMENSION(:), POINTER, SAVE :: temp_mat
67  vec, SAVE :: cb_1, cb_2, cx_1, cx_1_ghost
68  ksp, DIMENSION(:), POINTER, SAVE :: temp_ksp
69  !------------------------------END OF DECLARATION--------------------------------------
70 
71  IF (once) THEN
72 
73  once = .false.
74 
75  CALL mpi_comm_rank(petsc_comm_world,my_petscworld_rank,code)
76 
77  !-----CREATE PETSC VECTORS AND GHOSTS-----------------------------------------
78  CALL create_my_ghost(temp_mesh,temp_1_la,temp_1_ifrom)
79  n = temp_mesh%dom_np
80  CALL veccreateghost(comm_one_d(1), n, &
81  petsc_determine, SIZE(temp_1_ifrom), temp_1_ifrom, cx_1, ierr)
82  CALL vecghostgetlocalform(cx_1, cx_1_ghost, ierr)
83  CALL vecduplicate(cx_1, cb_1, ierr)
84  CALL vecduplicate(cx_1, cb_2, ierr)
85  !------------------------------------------------------------------------------
86 
87  !-------------DIMENSIONS-------------------------------------------------------
88  m_max_c = SIZE(list_mode)
89  !------------------------------------------------------------------------------
90 
91  !---------PREPARE pp_js_D ARRAY FOR TEMPERATURE--------------------------------------
92  CALL dirichlet_nodes_parallel(temp_mesh, temp_list_dirichlet_sides, temp_js_d)
93  !------------------------------------------------------------------------------
94 
95  !--------------------------------------------------------------------------------
96  hmoy = 0
97  DO m = 1, temp_mesh%dom_me
98  hmoy = hmoy + sqrt(sum(temp_mesh%gauss%rj(:,m)))/2
99  END DO
100  hmoy = hmoy/temp_mesh%dom_me
101  mass0 = 0.d0
102  DO i = 1, m_max_c
103  mode = list_mode(i)
104  IF (mode == 0) THEN
105  CALL mass_tot(comm_one_d(1),temp_mesh, tempn(:,1,i), mass0)
106  ENDIF
107  END DO
108  !--------------------------------------------------------------------------------
109 
110  !-------------ASSEMBLE TEMPERATURE MATRICES--------------------------------------------
111  ALLOCATE(temp_mat(m_max_c),temp_ksp(m_max_c))
112 
113  DO i = 1, m_max_c
114  mode = list_mode(i)
115 
116  !---TEMPERATURE MATRIX
117  CALL create_local_petsc_matrix(comm_one_d(1), temp_1_la, temp_mat(i), clean=.false.)
118  CALL qs_diff_mass_scal_m_variant(temp_mesh, temp_1_la, vol_heat_capacity, temp_diffusivity, &
119  1.5/dt, zero, mode, temp_mat(i))
120 
121  IF (temp_per%n_bord/=0) THEN
122  CALL periodic_matrix_petsc(temp_per%n_bord, temp_per%list, temp_per%perlist, temp_mat(i), temp_1_la)
123  END IF
124 
125  CALL dirichlet_m_parallel(temp_mat(i),temp_1_la%loc_to_glob(1,temp_js_d))
126 
127  CALL init_solver(my_par_cc,temp_ksp(i),temp_mat(i),comm_one_d(1),&
128  solver=my_par_cc%solver,precond=my_par_cc%precond)
129  ENDDO
130 
131  ENDIF
132  tps_tot = user_time()
133  tps_cumul = 0
134 
135  !===Compute rhs by FFT at Gauss points
136  tps = user_time()
137  CALL smb_ugradc_gauss_fft_par(comm_one_d(2),temp_mesh,list_mode,vol_heat_capacity,chmp_vit,2*tempn-tempn_m1,ff_conv)
138  tps = user_time() - tps; tps_cumul=tps_cumul+tps
139  !WRITE(*,*) ' Tps fft vitesse', tps
140  !------------CONSTRUCTION OF rr_gauss------------------
141  index = 0
142  DO m = 1, temp_mesh%me
143  j_loc = temp_mesh%jj(:,m)
144  DO l = 1, temp_mesh%gauss%l_G
145  index = index + 1
146  rr_gauss(1,index) = sum(temp_mesh%rr(1,j_loc)*temp_mesh%gauss%ww(:,l))
147  rr_gauss(2,index) = sum(temp_mesh%rr(2,j_loc)*temp_mesh%gauss%ww(:,l))
148  END DO
149  END DO
150  !------------DEBUT BOUCLE SUR LES MODES----------------
151  DO i = 1, m_max_c
152  mode = list_mode(i)
153 
154  !===RHS temperature
155  ff = (2/dt)*tempn(:,1,i) - (1/(2*dt))*tempn_m1(:,1,i)
156  CALL qs_00_gauss(temp_mesh, temp_1_la, vol_heat_capacity, ff, &
157  -ff_conv(:,1,i) + source_in_temperature(1, rr_gauss, mode, time), cb_1)
158 
159  ff = (2/dt)*tempn(:,2,i) - (1/(2*dt))*tempn_m1(:,2,i)
160  CALL qs_00_gauss(temp_mesh, temp_1_la, vol_heat_capacity, ff, &
161  -ff_conv(:,2,i) + source_in_temperature(2, rr_gauss, mode, time), cb_2)
162 
163  !===RHS periodicity
164  IF (temp_per%n_bord/=0) THEN
165  CALL periodic_rhs_petsc(temp_per%n_bord, temp_per%list, temp_per%perlist, cb_1, temp_1_la)
166  CALL periodic_rhs_petsc(temp_per%n_bord, temp_per%list, temp_per%perlist, cb_2, temp_1_la)
167  END IF
168  !----------------------------------------------------------
169 
170  CALL dirichlet_rhs(temp_1_la%loc_to_glob(1,temp_js_d)-1,&
171  temperature_exact(1,temp_mesh%rr(:,temp_js_d), mode, time),cb_1)
172  CALL dirichlet_rhs(temp_1_la%loc_to_glob(1,temp_js_d)-1,&
173  temperature_exact(2,temp_mesh%rr(:,temp_js_d), mode, time),cb_2)
174 
175  tps = user_time() - tps; tps_cumul=tps_cumul+tps
176  !WRITE(*,*) ' Tps second membre vitesse', tps
177  !-------------------------------------------------------------------------------------
178 
179  !--------------------INVERSION DES OPERATEURS--------------
180  tps = user_time()
181  !Solve system temp_c
182  CALL solver(temp_ksp(i),cb_1,cx_1,reinit=.false.,verbose=my_par_cc%verbose)
183  CALL vecghostupdatebegin(cx_1,insert_values,scatter_forward,ierr)
184  CALL vecghostupdateend(cx_1,insert_values,scatter_forward,ierr)
185  CALL extract(cx_1_ghost,1,1,temp_1_la,tempn_p1(:,1))
186 
187  !Solve system temp_s
188  CALL solver(temp_ksp(i),cb_2,cx_1,reinit=.false.,verbose=my_par_cc%verbose)
189  CALL vecghostupdatebegin(cx_1,insert_values,scatter_forward,ierr)
190  CALL vecghostupdateend(cx_1,insert_values,scatter_forward,ierr)
191  CALL extract(cx_1_ghost,1,1,temp_1_la,tempn_p1(:,2))
192  tps = user_time() - tps; tps_cumul=tps_cumul+tps
193  !WRITE(*,*) ' Tps solution des pb de vitesse', tps, 'for mode ', mode
194  !-------------------------------------------------------------------------------------
195 
196  !---------------UPDATES-----------------------
197  tps = user_time()
198 
199  !JLG AR, Dec 18 2008/JLG Bug corrige Jan 23 2010
200  IF (mode==0) THEN
201  tempn_p1(:,2) = 0.d0
202  END IF
203  !JLG AR, Dec 18 2008/JLG Bug corrige Jan 23 2010
204 
205 
206  tempn_m1(:,:,i) = tempn(:,:,i)
207  tempn(:,:,i) = tempn_p1
208 
209  ! Reconstruct dtempndt on Gauss points
210  ! WARNING FL (1/2/13) If reactivated, declare l and index
211  !tempn_p1 = (3*tempn_p1 - 4*tempn(:,:,i) + tempn_m1(:,:,i))/(2*dt)
212  !index = 0
213  !DO m = 1, temp_mesh%me
214  ! DO l = 1, temp_mesh%gauss%l_G
215  ! index = index + 1
216  ! dtempndt(index,1,i) = SUM(tempn_p1(temp_mesh%jj(:,m),1)*temp_mesh%gauss%ww(:,l)) + ff_conv(index,1,i)
217  ! dtempndt(index,2,i) = SUM(tempn_p1(temp_mesh%jj(:,m),2)*temp_mesh%gauss%ww(:,l)) + ff_conv(index,2,i)
218  ! END DO
219  !END DO
220  ! WARNING FL (1/2/13) If reactivated, declare l and index
221 
222  tps = user_time() - tps; tps_cumul=tps_cumul+tps
223  !WRITE(*,*) ' Tps des updates', tps
224  !-------------------------------------------------------------------------------------
225  ENDDO
226 
227  tps_tot = user_time() - tps_tot
228  !WRITE(*,'(A,2(f13.3,2x))') ' Tps boucle en temps Navier_stokes', tps_tot, tps_cumul
229  !WRITE(*,*) ' TIME = ', time, '========================================'
230 
231  END SUBROUTINE three_level_temperature
232  !============================================
233 
234  SUBROUTINE smb_ugradc_gauss_fft_par(communicator,mesh,list_mode,heat_capa_in,V_in,c_in,c_out)
235  !=================================
236  USE gauss_points
237  USE sft_parallele
238  USE chaine_caractere
239  USE boundary
240  IMPLICIT NONE
241  TYPE(mesh_type), TARGET :: mesh
242  INTEGER, DIMENSION(:), INTENT(IN) :: list_mode
243  REAL(KIND=8), DIMENSION(:), INTENT(IN) :: heat_capa_in
244  REAL(KIND=8), DIMENSION(:,:,:), INTENT(IN) :: v_in, c_in
245  REAL(KIND=8), DIMENSION(:,:,:), INTENT(OUT) :: c_out
246  REAL(KIND=8), DIMENSION(mesh%gauss%l_G*mesh%me,6,SIZE(list_mode)) :: gradc, w
247  REAL(KIND=8), DIMENSION(mesh%gauss%l_G*mesh%me,2,SIZE(list_mode)) :: div, cgauss, cint
248  INTEGER, DIMENSION(mesh%gauss%n_w) :: j_loc
249  REAL(KIND=8), DIMENSION(mesh%gauss%k_d,mesh%gauss%n_w) :: dw_loc
250  INTEGER :: m, l , i, mode, index, k
251  REAL(KIND=8), DIMENSION(mesh%gauss%n_w,6) :: vs
252  REAL(KIND=8), DIMENSION(mesh%gauss%n_w,2) :: cs
253  INTEGER, DIMENSION(:,:), POINTER :: jj
254  INTEGER, POINTER :: me
255  REAL(KIND=8) :: ray, tps
256  REAL(KIND=8), DIMENSION(3) :: temps
257  INTEGER :: code, m_max_pad, bloc_size, nb_procs
258 #include "petsc/finclude/petsc.h"
259  mpi_comm :: communicator
260 
261  CALL gauss(mesh)
262  jj => mesh%jj
263  me => mesh%me
264 
265  tps = user_time()
266  DO i = 1, SIZE(list_mode)
267  mode = list_mode(i)
268  index = 0
269  DO m = 1, mesh%dom_me
270  j_loc = jj(:,m)
271  DO k = 1, 6
272  vs(:,k) = v_in(j_loc,k,i)
273  END DO
274  DO k = 1, 2
275  cs(:,k) = c_in(j_loc,k,i)
276  END DO
277  DO l = 1, l_g
278  index = index + 1
279  dw_loc = dw(:,:,l,m)
280 
281  !===Compute radius of Gauss point
282  ray = sum(mesh%rr(1,j_loc)*ww(:,l))
283 
284  !-----------------vitesse sur les points de Gauss---------------------------
285  w(index,1,i) = sum(vs(:,1)*ww(:,l))
286  w(index,3,i) = sum(vs(:,3)*ww(:,l))
287  w(index,5,i) = sum(vs(:,5)*ww(:,l))
288 
289  w(index,2,i) = sum(vs(:,2)*ww(:,l))
290  w(index,4,i) = sum(vs(:,4)*ww(:,l))
291  w(index,6,i) = sum(vs(:,6)*ww(:,l))
292 
293  div(index,1,i) = sum(vs(:,1)*dw_loc(1,:)) + sum(vs(:,1)*ww(:,l))/ray &
294  + (mode/ray)*sum(vs(:,4)*ww(:,l)) + sum(vs(:,5)*dw_loc(2,:))
295  div(index,2,i) = sum(vs(:,2)*dw_loc(1,:)) + sum(vs(:,2)*ww(:,l))/ray &
296  - (mode/ray)*sum(vs(:,3)*ww(:,l)) + sum(vs(:,6)*dw_loc(2,:))
297 
298  !-----------------gradient de c sur les points de Gauss---------------------------
299  !coeff sur les cosinus et sinus
300  gradc(index,1,i) = sum(cs(:,1)*dw_loc(1,:))
301  gradc(index,2,i) = sum(cs(:,2)*dw_loc(1,:))
302  gradc(index,3,i) = mode/ray*sum(cs(:,2)*ww(:,l))
303  gradc(index,4,i) = -mode/ray*sum(cs(:,1)*ww(:,l))
304  gradc(index,5,i) = sum(cs(:,1)*dw_loc(2,:))
305  gradc(index,6,i) = sum(cs(:,2)*dw_loc(2,:))
306 
307  gradc(index,:,i) = heat_capa_in(m) * gradc(index,:,i)
308 
309  cgauss(index,1,i) = sum(cs(:,1)*ww(:,l))
310  cgauss(index,2,i) = sum(cs(:,2)*ww(:,l))
311 
312  cgauss(index,:,i) = heat_capa_in(m) * cgauss(index,:,i)
313 
314  ENDDO
315  ENDDO
316  END DO
317 
318  !tps = user_time() - tps
319  !WRITE(*,*) ' Tps dans la grande boucle', tps
320  !tps = user_time()
321  temps = 0
322 
323  CALL mpi_comm_size(communicator, nb_procs, code)
324  bloc_size = SIZE(gradc,1)/nb_procs+1
325  m_max_pad = 3*SIZE(list_mode)*nb_procs/2
326  CALL fft_par_dot_prod_dcl(communicator, gradc, w, c_out, nb_procs, bloc_size, m_max_pad, temps)
327  bloc_size = SIZE(div,1)/nb_procs+1
328  CALL fft_par_prod_dcl(communicator, div, cgauss, cint, nb_procs, bloc_size, m_max_pad, temps)
329  c_out = c_out + cint
330  tps = user_time() - tps
331  !WRITE(*,*) ' Tps dans FFT_PAR_PROD_VECT', tps
332  !write(*,*) ' Temps de Comm ', temps(1)
333  !write(*,*) ' Temps de Calc ', temps(2)
334  !write(*,*) ' Temps de Chan ', temps(3)
335 
336  END SUBROUTINE smb_ugradc_gauss_fft_par
337 
338  SUBROUTINE mass_tot(communicator,mesh,tempn,RESLT)
339  !===========================
340  !moyenne
341  USE def_type_mesh
342  IMPLICIT NONE
343  TYPE(mesh_type) :: mesh
344  REAL(KIND=8), DIMENSION(:) , INTENT(IN) :: tempn
345  REAL(KIND=8) , INTENT(OUT) :: reslt
346  REAL(KIND=8) :: r_loc, r_out
347  INTEGER :: m, l , i , ni, code
348  INTEGER, DIMENSION(mesh%gauss%n_w) :: j_loc
349  REAL(KIND=8) :: ray
350 #include "petsc/finclude/petsc.h"
351  mpi_comm :: communicator
352  r_loc = 0.d0
353 
354  DO m = 1, mesh%dom_me
355  j_loc = mesh%jj(:,m)
356  DO l = 1, mesh%gauss%l_G
357  ray = 0
358  DO ni = 1, mesh%gauss%n_w; i = j_loc(ni)
359  ray = ray + mesh%rr(1,i)*mesh%gauss%ww(ni,l)
360  END DO
361 
362  r_loc = r_loc + sum(tempn(j_loc(:))*mesh%gauss%ww(:,l))*ray*mesh%gauss%rj(l,m)
363 
364  ENDDO
365  ENDDO
366 
367  CALL mpi_allreduce(r_loc,r_out,1,mpi_double_precision, mpi_sum, communicator, code)
368  reslt = r_out
369 
370  END SUBROUTINE mass_tot
371 
372 END MODULE subroutine_temperature
subroutine qs_00_gauss(mesh, LA, heat_capa, ff, ff_gauss, vect)
subroutine, public fft_par_dot_prod_dcl(communicator, V1_in, V2_in, c_out, nb_procs, bloc_size, m_max_pad, temps)
subroutine, public create_my_ghost(mesh, LA, ifrom)
Definition: st_csr.f90:14
subroutine dirichlet_rhs(js_D, bs_D, b)
subroutine, public fft_par_prod_dcl(communicator, c1_in, c2_in, c_out, nb_procs, bloc_size, m_max_pad, temps)
subroutine init_solver(my_par, my_ksp, matrix, communicator, solver, precond, opt_re_init)
Definition: solver.f90:11
subroutine dirichlet_nodes_parallel(mesh, list_dirichlet_sides, js_d)
subroutine solver(my_ksp, b, x, reinit, verbose)
Definition: solver.f90:95
subroutine dirichlet_m_parallel(matrix, glob_js_D)
subroutine qs_diff_mass_scal_m_variant(mesh, LA, heat_capa, visco, mass, stab, mode, matrix)
Definition: fem_M_axi.f90:198
real(kind=8) function, dimension(size(rr, 2)), public temperature_exact(TYPE, rr, m, t)
subroutine gauss(mesh)
real(kind=8) function, dimension(size(rr, 2)), public source_in_temperature(TYPE, rr, m, t)
subroutine, public three_level_temperature(comm_one_d, time, temp_1_LA, dt, list_mode, temp_mesh, tempn_m1, tempn, chmp_vit, vol_heat_capacity, temp_diffusivity, my_par_cc, temp_list_dirichlet_sides, temp_per)
real(kind=8) function user_time()
Definition: my_util.f90:7
subroutine, public periodic_rhs_petsc(n_bord, list, perlist, v_rhs, LA)
subroutine mass_tot(communicator, mesh, tempn, RESLT)
subroutine, public periodic_matrix_petsc(n_bord, list, perlist, matrix, LA)
subroutine, public extract(xghost, ks, ke, LA, phi)
Definition: st_csr.f90:33
subroutine create_local_petsc_matrix(communicator, LA, matrix, clean)
Definition: solver.f90:142
subroutine smb_ugradc_gauss_fft_par(communicator, mesh, list_mode, V_in, c_in, nb_procs, c_out)