SFEMaNS  version 5.3
Reference documentation for SFEMaNS
sub_mass.f90
Go to the documentation of this file.
2  USE my_util
3  USE boundary
4 
6  PRIVATE
7 CONTAINS
8 
9  SUBROUTINE three_level_mass(comm_one_d, time, level_set_LA_P1, level_set_LA_P2, list_mode, &
10  mesh_p1, mesh_p2, chmp_vit_p2, max_vel, level_set_per, density_m2, density_m1, density, &
11  level_set_m1, level_set, visc_entro_level)
13  USE input_data
15  USE my_util
16 #include "petsc/finclude/petsc.h"
17  USE petsc
18  !===TEST LC 2017/06/08
19  USE user_data
20  !===End TEST LC 2017/06/08
21  IMPLICIT NONE
22  REAL(KIND=8) :: time
23  INTEGER, DIMENSION(:), INTENT(IN) :: list_mode
24  type(petsc_csr_la) :: level_set_LA_P1
25  type(petsc_csr_la) :: level_set_LA_P2
26  TYPE(periodic_type), INTENT(IN) :: level_set_per
27  TYPE(mesh_type), INTENT(IN) :: mesh_P1
28  TYPE(mesh_type), INTENT(IN) :: mesh_P2
29  REAL(KIND=8), DIMENSION(:,:,:), INTENT(IN) :: chmp_vit_P2
30  REAL(KIND=8), DIMENSION(:,:,:), INTENT(INOUT) :: density, density_m1, density_m2
31  REAL(KIND=8), DIMENSION(:,:,:,:), INTENT(INOUT) :: level_set, level_set_m1
32  REAL(KIND=8), INTENT(INOUT) :: max_vel
33  REAL(KIND=8), DIMENSION(:,:), INTENT(IN) :: visc_entro_level
34  REAL(KIND=8), DIMENSION(mesh_P1%np,6,SIZE(list_mode)) :: chmp_vit_P1
35  INTEGER :: n, i, k
36  mpi_comm, DIMENSION(:), POINTER :: comm_one_d
37 
38  IF (inputs%if_level_set) THEN
39 
40  IF (inputs%if_level_set_P2) THEN
41  IF (inputs%if_level_set_fixed) THEN
42  DO n = 1, inputs%nb_fluid-1
43  DO k = 1, 2
44  DO i = 1, SIZE(list_mode)
45  level_set_m1(n,:,k,i)=level_set_exact(n,k,mesh_p2%rr,list_mode(i),time-inputs%dt)
46  level_set(n,:,k,i)=level_set_exact(n,k,mesh_p2%rr,list_mode(i),time)
47  END DO
48  END DO
49  END DO
50  ELSE
51  DO n = 1, inputs%nb_fluid-1
52  CALL three_level_level_set(comm_one_d, time, level_set_la_p2, inputs%dt, list_mode, &
53  mesh_p2, level_set_m1(n,:,:,:), level_set(n,:,:,:), chmp_vit_p2, max_vel, &
54  inputs%my_par_level_set, inputs%level_set_list_dirichlet_sides, level_set_per, n, &
55  visc_entro_level)
56  END DO
57  END IF
58  ELSE
59  DO i = 1, SIZE(list_mode)
60  DO k = 1, 6
61  CALL project_p2_p1(mesh_p2%jj, mesh_p1%jj, chmp_vit_p2(:,k,i), chmp_vit_p1(:,k,i))
62  END DO
63  END DO
64  IF (inputs%if_level_set_fixed) THEN
65  DO n = 1, inputs%nb_fluid-1
66  DO k = 1, 2
67  DO i = 1, SIZE(list_mode)
68  level_set_m1(n,:,k,i)=level_set_exact(n,k,mesh_p1%rr,list_mode(i),time-inputs%dt)
69  level_set(n,:,k,i)=level_set_exact(n,k,mesh_p1%rr,list_mode(i),time)
70  END DO
71  END DO
72  END DO
73  ELSE
74  DO n = 1, inputs%nb_fluid-1
75  CALL three_level_level_set(comm_one_d, time, level_set_la_p1, inputs%dt, list_mode, &
76  mesh_p1, level_set_m1(n,:,:,:), level_set(n,:,:,:), chmp_vit_p1, max_vel, &
77  inputs%my_par_level_set, inputs%level_set_list_dirichlet_sides, level_set_per, n, &
78  visc_entro_level)
79  END DO
80  END IF
81  END IF
82 
83  !===Update densities
84  density_m2 = density_m1
85  density_m1 = density
86  CALL reconstruct_variable(comm_one_d, list_mode, mesh_p1, mesh_p2, level_set, &
87  inputs%density_fluid, density)
88  RETURN
89  ELSE
90  RETURN
91  END IF
92 
93  END SUBROUTINE three_level_mass
94 
95  SUBROUTINE reconstruct_variable(comm_one_d, list_mode, mesh_P1, mesh_P2, level_set, values, variable)
96  !==============================
97  USE def_type_mesh
98  USE sft_parallele
99  USE input_data
100 #include "petsc/finclude/petsc.h"
101  USE petsc
102  IMPLICIT NONE
103  INTEGER, DIMENSION(:), INTENT(IN) :: list_mode
104  TYPE(mesh_type), INTENT(IN) :: mesh_P1
105  TYPE(mesh_type), INTENT(IN) :: mesh_P2
106  REAL(KIND=8), DIMENSION(:,:,:,:), INTENT(IN) :: level_set
107  REAL(KIND=8), DIMENSION(:), INTENT(IN) :: values
108  REAL(KIND=8), DIMENSION(:,:,:), INTENT(INOUT) :: variable
109  LOGICAL, SAVE :: once = .true.
110  INTEGER, SAVE :: m_max_c
111  INTEGER, SAVE :: m_max_pad
112  INTEGER, SAVE :: bloc_size
113  INTEGER, SAVE :: nb_procs
114  INTEGER :: i, code, k, nb_inter
115  REAL(KIND=8), DIMENSION(mesh_P2%np,2,SIZE(list_mode)) :: rho_phi
116  REAL(KIND=8), DIMENSION(inputs%nb_fluid-1,mesh_P2%np,2,SIZE(list_mode)) :: level_set_P2
117  !Communicators for Petsc, in space and Fourier------------------------------
118  mpi_comm, DIMENSION(:), POINTER :: comm_one_d
119  !------------------------------END OF DECLARATION--------------------------------------
120 
121  IF (once) THEN
122  once = .false.
123  !-------------DIMENSIONS-------------------------------------------------------
124  m_max_c = SIZE(list_mode)
125  !-------------FFT VARIABLES----------------------------------------------------
126  CALL mpi_comm_size(comm_one_d(2), nb_procs, code)
127  bloc_size = mesh_p2%np/nb_procs+1
128  m_max_pad = 3*m_max_c*nb_procs/2
129  END IF
130 
131  IF (.NOT.inputs%if_level_set) THEN
132  ! we don't reconstruct density, viscosity if no level set
133  RETURN
134  ELSE
135  IF (inputs%if_level_set_P2) THEN
136  level_set_p2=level_set
137  ELSE
138  DO nb_inter = 1, inputs%nb_fluid-1
139  DO i = 1, SIZE(list_mode)
140  DO k = 1, 2
141  CALL inject_p1_p2(mesh_p1%jj, mesh_p2%jj, level_set(nb_inter,:,k,i), level_set_p2(nb_inter,:,k,i))
142  END DO
143  END DO
144  END DO
145  END IF
146  IF (maxval(abs(values(1)-values(:))) .LE. 1.d-10*maxval(abs(values(:)))) THEN
147  variable = 0.d0
148  DO i = 1, m_max_c
149  IF (list_mode(i)==0) THEN
150  variable(:,1,i) = values(1)
151  END IF
152  END DO
153  ELSE IF (inputs%level_set_reconstruction_type == 'lin') THEN
154  IF (inputs%if_kill_overshoot) THEN
155  IF (nb_procs==1.AND.SIZE(list_mode)==1.AND.list_mode(1)==0) THEN !case axisym
156  level_set_p2 = min(1.d0, level_set_p2)
157  level_set_p2 = max(0.d0, level_set_p2)
158  ELSE !level set depends of theta
159  DO k = 1, inputs%nb_fluid-1
160  CALL fft_no_overshoot_level_set(comm_one_d(2), level_set_p2(k,:,:,:), &
161  nb_procs, bloc_size, m_max_pad)
162  END DO
163  END IF
164  END IF
165  variable = 0.d0
166  DO i = 1, m_max_c
167  IF (list_mode(i)==0) THEN
168  variable(:,1,i) = values(1)
169  END IF
170  END DO
171  variable = variable + (values(2)-values(1))*level_set_p2(1,:,:,:)
172  IF (inputs%nb_fluid.GE.3) THEN
173  DO i = 1, inputs%nb_fluid-2
174  CALL fft_par_prod_dcl(comm_one_d(2), variable, level_set_p2(i+1,:,:,:), rho_phi, &
175  nb_procs, bloc_size, m_max_pad)
176  variable = variable -rho_phi + values(i+2)*level_set_p2(i+1,:,:,:)
177  END DO
178  END IF
179  ELSE
180  CALL fft_heaviside_dcl(comm_one_d(2), level_set_p2, values, variable, &
181  nb_procs, bloc_size, m_max_pad, inputs%level_set_tanh_coeff_reconstruction)
182  DO i = 1, m_max_c
183  IF (list_mode(i)==0) THEN
184  variable(:,2,i) = 0.d0
185  END IF
186  END DO
187  END IF
188  END IF
189  END SUBROUTINE reconstruct_variable
190 
191  SUBROUTINE total_mass(comm_one_d, list_mode, mass_mesh, level_set, mass_tot)
192  !==============================
193  USE def_type_mesh
194  USE sft_parallele
195  USE input_data
196 #include "petsc/finclude/petsc.h"
197  USE petsc
198  IMPLICIT NONE
199  INTEGER, DIMENSION(:), INTENT(IN) :: list_mode
200  TYPE(mesh_type), INTENT(IN) :: mass_mesh
201  REAL(KIND=8), DIMENSION(:,:,:,:), INTENT(IN) :: level_set
202  REAL(KIND=8), INTENT(OUT) :: mass_tot
203  REAL(KIND=8), DIMENSION(SIZE(level_set,2),SIZE(level_set,3), & SIZE(level_set,4)) :: density_loc
204  INTEGER :: m_max_pad, bloc_size, nb_procs
205  INTEGER :: i, code, my_petscworld_rank, m, l
206  REAL(KIND=8) :: mass_loc, mass_F, ray
207  REAL(KIND=8), DIMENSION(mass_mesh%np,2,SIZE(list_mode)) :: rho_phi
208  INTEGER, DIMENSION(mass_mesh%gauss%n_w) :: j_loc
209  REAL(KIND=8) :: pi= 3.14159265358979323846d0
210  !Communicators for Petsc, in space and Fourier------------------------------
211  mpi_comm, DIMENSION(:), POINTER :: comm_one_d
212  !------------------------------END OF DECLARATION--------------------------------------
213 
214  CALL mpi_comm_rank(petsc_comm_world,my_petscworld_rank,code)
215  CALL mpi_comm_size(comm_one_d(2), nb_procs, code)
216 
217  IF(.NOT.inputs%if_level_set) THEN
218  CALL error_petsc('BUG in sub_mass : you should not compute any mass')
219  ELSE
220  IF (inputs%level_set_reconstruction_type == 'lin') THEN
221  density_loc = 0.d0
222  DO i = 1, SIZE(list_mode)
223  IF (list_mode(i)==0) THEN
224  density_loc(:,1,i) = inputs%density_fluid(1)
225  END IF
226  END DO
227  density_loc = density_loc + (inputs%density_fluid(2)-inputs%density_fluid(1))*level_set(i,:,:,:)
228 
229  bloc_size = SIZE(level_set,2)/nb_procs+1
230  m_max_pad = 3*SIZE(list_mode)*nb_procs/2
231  IF (inputs%nb_fluid.GE.3) THEN
232  DO i = 1, inputs%nb_fluid-2
233  CALL fft_par_prod_dcl(comm_one_d(2), density_loc, level_set(i+1,:,:,:), rho_phi, &
234  nb_procs, bloc_size, m_max_pad)
235  density_loc = density_loc -rho_phi + inputs%density_fluid(i+2)*level_set(i+1,:,:,:)
236  END DO
237  END IF
238  ELSE
239  bloc_size = SIZE(level_set,2)/nb_procs+1
240  m_max_pad = 3*SIZE(list_mode)*nb_procs/2
241  CALL fft_heaviside_dcl(comm_one_d(2), level_set, inputs%density_fluid, &
242  density_loc, nb_procs, bloc_size, m_max_pad, inputs%level_set_tanh_coeff_reconstruction)
243  END IF
244 
245  mass_loc = 0.d0
246  DO i = 1, SIZE(list_mode)
247  IF (list_mode(i)==0) THEN
248  DO m = 1, mass_mesh%me
249  j_loc = mass_mesh%jj(:,m)
250  DO l = 1, mass_mesh%gauss%l_G
251  !===Compute radius of Gauss point
252  ray = sum(mass_mesh%rr(1,j_loc)*mass_mesh%gauss%ww(:,l))
253  mass_loc = mass_loc + sum(density_loc(j_loc,1,i)* &
254  mass_mesh%gauss%ww(:,l))*ray*mass_mesh%gauss%rj(l,m)
255  END DO
256  END DO
257  END IF
258  END DO
259  mass_loc = mass_loc*2*pi
260  CALL mpi_allreduce(mass_loc, mass_f, 1, mpi_double_precision, mpi_sum, &
261  comm_one_d(2), code)
262  CALL mpi_allreduce(mass_f, mass_tot, 1, mpi_double_precision, mpi_sum, &
263  comm_one_d(1), code)
264  END IF
265 
266  END SUBROUTINE total_mass
267 
268  SUBROUTINE inject_p1_p2(jj_c, jj_f, pp_c, pp_f)
269  USE my_util
270  IMPLICIT NONE
271  INTEGER, DIMENSION(:,:), INTENT(IN) :: jj_c, jj_f
272  REAL(KIND=8), DIMENSION(:), INTENT(IN) :: pp_c
273  REAL(KIND=8), DIMENSION(:), INTENT(OUT) :: pp_f
274  REAL(KIND=8) :: half = 0.5
275  INTEGER:: m
276  IF (SIZE(jj_c,1)==3) THEN
277  DO m = 1, SIZE(jj_f,2)
278  pp_f(jj_f(1:3,m)) = pp_c(jj_c(:,m))
279  pp_f(jj_f(4,m)) = (pp_c(jj_c(2,m)) + pp_c(jj_c(3,m)))*half
280  pp_f(jj_f(5,m)) = (pp_c(jj_c(3,m)) + pp_c(jj_c(1,m)))*half
281  pp_f(jj_f(6,m)) = (pp_c(jj_c(1,m)) + pp_c(jj_c(2,m)))*half
282  END DO
283  ELSE
284  CALL error_petsc('BUG in inject_P1_P2: finite element not yet programmed')
285  END IF
286 
287  END SUBROUTINE inject_p1_p2
288 
289  SUBROUTINE project_p2_p1(jj_P2, jj_P1, pp_P2, pp_P1)
290  USE my_util
291  IMPLICIT NONE
292  INTEGER, DIMENSION(:,:), INTENT(IN) :: jj_P2, jj_P1
293  REAL(KIND=8), DIMENSION(:), INTENT(IN) :: pp_P2
294  REAL(KIND=8), DIMENSION(:), INTENT(OUT) :: pp_P1
295  INTEGER:: m
296 
297  IF (SIZE(jj_p1,1)==3) THEN
298  DO m = 1, SIZE(jj_p1,2)
299  pp_p1(jj_p1(:,m)) = pp_p2(jj_p2(1:3,m))
300  END DO
301  ELSE
302  CALL error_petsc('BUG in inject_P2_P1: finite element not yet programmed')
303  END IF
304 
305  END SUBROUTINE project_p2_p1
306 
307 END MODULE subroutine_mass
308 
subroutine, public fft_heaviside_dcl(communicator, V1_in, values, V_out, nb_procs, bloc_size, m_max_pad, coeff_tanh, temps)
subroutine, public project_p2_p1(jj_P2, jj_P1, pp_P2, pp_P1)
Definition: sub_mass.f90:291
subroutine, public fft_no_overshoot_level_set(communicator, c1_inout, nb_procs, bloc_size, m_max_pad, temps)
subroutine error_petsc(string)
Definition: my_util.f90:16
type(my_data), public inputs
subroutine, public fft_par_prod_dcl(communicator, c1_in, c2_in, c_out, nb_procs, bloc_size, m_max_pad, temps)
subroutine, public three_level_level_set(comm_one_d, time, cc_1_LA, dt, list_mode, cc_mesh, cn_m1, cn, chmp_vit, max_vel, my_par_cc, cc_list_dirichlet_sides, cc_per, nb_inter, visc_entro_level)
subroutine, public reconstruct_variable(comm_one_d, list_mode, mesh_P1, mesh_P2, level_set, values, variable)
Definition: sub_mass.f90:96
subroutine, public inject_p1_p2(jj_c, jj_f, pp_c, pp_f)
Definition: sub_mass.f90:270
subroutine, public three_level_mass(comm_one_d, time, level_set_LA_P1, level_set_LA_P2, list_mode, mesh_P1, mesh_P2, chmp_vit_P2, max_vel, level_set_per, density_m2, density_m1, density, level_set_m1, level_set, visc_entro_level)
Definition: sub_mass.f90:12
subroutine, public total_mass(comm_one_d, list_mode, mass_mesh, level_set, mass_tot)
Definition: sub_mass.f90:192