SFEMaNS  version 5.3
Reference documentation for SFEMaNS
tools_interpol.f90
Go to the documentation of this file.
2 
3 CONTAINS
4  SUBROUTINE backup_suite(type_fic, filename, n_it, rank, is_sequential)
6  IMPLICIT NONE
7  CHARACTER(len=3), INTENT(IN) :: type_fic
8  CHARACTER(len=200), INTENT(IN) :: filename
9  INTEGER, INTENT(IN) :: n_it, rank
10  LOGICAL, INTENT(IN) :: is_sequential
11 
12  CHARACTER(len=3) :: tit_s, tit
13  CHARACTER(len=5) :: name_it, name_dom
14  INTEGER :: l, lblank
15  CHARACTER(len=200) :: cmd, dir_out
16 
17  WRITE(tit_s,'(i3)') rank
18  lblank = eval_blank(3,tit_s)
19  DO l = 1, lblank - 1
20  tit_s(l:l) = '0'
21  END DO
22  IF (is_sequential) THEN
23  name_dom=''
24  dir_out='NON_PETSC_OUT/'
25  ELSE
26  name_dom='_S'//tit_s
27  dir_out='PETSC_OUT'
28  END IF
29  WRITE(tit,'(i3)') n_it
30  lblank = eval_blank(3,tit)
31  DO l = 1, lblank - 1
32  tit(l:l) = '0'
33  END DO
34  name_it='_I'//tit
35  IF (type_fic=='mxw') THEN
36  cmd = 'mv suite_maxwell'
37  ELSE IF (type_fic=='nst') THEN
38  cmd = 'mv suite_ns'
39  ELSE
40  WRITE(*,*) 'WARNING: exit without doing anything (backup_suite)'
41  RETURN
42  END IF
43 
44  cmd = trim(adjustl(cmd))//trim(adjustl(name_dom))//name_it//'.'//trim(adjustl(filename))
45  WRITE(*,*) '('//trim(adjustl(cmd))//')'
46  !JLG+LC Jan 6 2014
47  IF (is_sequential) THEN
48  IF (rank==0) CALL system(trim(adjustl(cmd))//' '//trim(adjustl(dir_out)))
49  ELSE
50  CALL system(trim(adjustl(cmd))//' '//trim(adjustl(dir_out)))
51  END IF
52 
53  END SUBROUTINE backup_suite
54 
55  SUBROUTINE max_controle(cont, comm)
56 #include "petsc/finclude/petsc.h"
57  USE petsc
58  IMPLICIT NONE
59  INTEGER, DIMENSION(:) :: cont
60  INTEGER, DIMENSION(:), ALLOCATABLE :: tmp
61  INTEGER :: np
62  mpi_comm :: comm
63  petscerrorcode :: ierr
64 
65  np = SIZE(cont)
66  ALLOCATE(tmp(np))
67  tmp = 0
68  CALL mpi_allreduce(cont, tmp, np, mpi_integer, mpi_sum, comm, ierr)
69  cont = tmp
70  DEALLOCATE(tmp)
71 
72  END SUBROUTINE max_controle
73 
74  SUBROUTINE somme_spatiale(field, comm, cont)
75 #include "petsc/finclude/petsc.h"
76  USE petsc
77  IMPLICIT NONE
78  REAL(KIND=8), DIMENSION(:,:,:) :: field
79  REAL(KIND=8), DIMENSION(:,:,:), ALLOCATABLE :: tmp
80  INTEGER :: np, i, j, n2, n3
81  INTEGER, DIMENSION(:), OPTIONAL :: cont
82 
83  mpi_comm :: comm
84  petscerrorcode :: ierr
85 
86  np = SIZE(field,1)
87  n2 = SIZE(field,2)
88  n3 = SIZE(field,3)
89 
90  ALLOCATE(tmp(np, n2, n3))
91  tmp = 0.d0
92 
93  DO j = 1, n3
94  DO i = 1, n2
95  CALL mpi_allreduce(field(:,i,j), tmp(:,i,j), np, mpi_double_precision, mpi_sum, comm, ierr)
96  END DO
97  END DO
98  IF (present(cont)) THEN
99  DO j = 1, n3
100  DO i = 1, n2
101  field(:,i,j) = tmp(:,i,j)/cont(:)
102  END DO
103  END DO
104  ELSE
105  field = tmp
106  END IF
107 
108  DEALLOCATE(tmp)
109 
110  END SUBROUTINE somme_spatiale
111 
112  SUBROUTINE inter_mesh_loc_to_glob(mesh_in, mesh_out, in_field, out_field, l_t_g, is_in, comm)
115  USE def_type_mesh
116  IMPLICIT NONE
117  TYPE(mesh_type) :: mesh_in, mesh_out
118  REAL(KIND=8), DIMENSION(:,:,:) :: in_field, out_field
119  INTEGER, DIMENSION(:) :: l_t_g
120  LOGICAL :: is_in
121  INTEGER :: i2, i3, n1, n2, n3, m1, n
122  mpi_comm :: comm
123 
124  n = mesh_out%np
125  n1 = SIZE(in_field,1)
126  m1 = SIZE(out_field, 1)
127  n2 = SIZE(in_field, 2)
128  n3 = SIZE(in_field, 3)
129 
130  IF (is_in) THEN
131  DO i2 = 1, n2
132  DO i3 = 1, n3
133  out_field(l_t_g(1:mesh_in%dom_np),i2,i3) = in_field(1:mesh_in%dom_np,i2,i3)
134  END DO
135  END DO
136  CALL somme_spatiale(out_field, comm)
137  ELSE
138  DO i2 = 1, n2
139  DO i3 = 1, n3
140  out_field(1:m1,i2,i3) = in_field(l_t_g(1:m1),i2,i3)
141  END DO
142  END DO
143  END IF
144 
145  END SUBROUTINE inter_mesh_loc_to_glob
146 
147  SUBROUTINE loc_to_glob(mesh_loc, mesh_glob, l_t_g)
149  IMPLICIT NONE
150 
151  TYPE(mesh_type) :: mesh_loc, mesh_glob
152  INTEGER, DIMENSION(mesh_loc%np) :: l_t_g
153 
154  REAL(KIND=8) :: epsilon = 1.d-10
155  INTEGER :: i, j
156  REAL(KIND=8), DIMENSION(2) :: r_loc, r_glob
157 
158  DO i=1, mesh_loc%np
159  r_loc = mesh_loc%rr(:,i)
160  DO j=1, mesh_glob%np
161  r_glob = mesh_glob%rr(:,j)
162  IF (sum((r_loc-r_glob)**2) < epsilon) THEN
163  l_t_g(i) = j
164  EXIT
165  END IF
166  END DO
167  END DO
168 
169  IF (minval(l_t_g)==0) WRITE(*,*) 'BUG in loc_to_glob', mesh_loc%rr(:,minloc(l_t_g))
170 
171 
172  END SUBROUTINE loc_to_glob
173 
174 
175  SUBROUTINE interp_mesh(mesh_in, mesh_out, in_field, out_field, controle, type_fe)
177  IMPLICIT NONE
178 
179  TYPE(mesh_type) :: mesh_in, mesh_out
180  REAL(KIND=8), DIMENSION(:,:,:) :: in_field, out_field
181  INTEGER, DIMENSION(mesh_out%np) :: controle
182  INTEGER :: type_fe
183 
184  INTEGER :: m, i, j, k, ni, l
185  REAL(KIND=8), DIMENSION(mesh_in%gauss%n_w) :: ff
186  REAL(KIND=8), DIMENSION(mesh_in%gauss%n_ws) :: ffe
187  REAL(KIND=8), DIMENSION(3) :: abc
188  REAL(KIND=8), DIMENSION(2) :: ab
189 
190  controle = 0
191  out_field = 0.d0
192 
193  DO i = 1, mesh_out%np
194  CALL find_elem(mesh_in, mesh_out%rr(:,i), abc, m)
195  IF (m == 0) cycle
196  CALL gauss_ff(abc, type_fe, ff)
197  controle(i) = 1
198 
199  DO j = 1, SIZE(in_field,2)
200  DO k = 1, SIZE(in_field,3)
201  out_field(i,j,k) = sum(ff*in_field(mesh_in%jj(:,m),j,k))
202  END DO
203  END DO
204  m = 0
205  END DO
206 
207  DO j = 1, mesh_out%mes
208  DO ni = 1, SIZE(mesh_out%jjs,1)
209  i = mesh_out%jjs(ni,j)
210  IF (controle(i)>0) cycle
211  CALL find_edge(mesh_in, mesh_out%rr(:,i), m, ab)
212  IF (m==0) cycle
213  CALL gauss_ff_edge(ab, type_fe, ffe)
214  controle(i) = 1
215  DO l = 1, SIZE(in_field, 2)
216  DO k = 1, SIZE(in_field, 3)
217  out_field(i,l,k) = sum(ffe*in_field(mesh_in%jjs(:,m),l,k))
218  END DO
219  END DO
220  END DO
221  END DO
222 
223  IF (maxval(controle) > 1) WRITE(*,*) 'BUG in interp_mesh'
224 
225  END SUBROUTINE interp_mesh
226 
227  SUBROUTINE gauss_ff(abc, type_fe, ff)
228  IMPLICIT NONE
229  REAL(KIND=8), DIMENSION(3) :: abc
230  INTEGER, INTENT(IN) :: type_fe
231  REAL(KIND=8), DIMENSION(3*type_fe):: ff
232 
233  IF (abs(1.d0-sum(abc)) > 1.d-12) THEN
234  WRITE(*,*) 'bug in gauss_ff'
235  stop
236  END IF
237 
238  IF (type_fe == 1) THEN
239  ff = abc
240  ELSE
241  ff(1:3) = abc*(2*abc - 1)
242  ff(4) = 4*abc(2)*abc(3)
243  ff(5) = 4*abc(3)*abc(1)
244  ff(6) = 4*abc(1)*abc(2)
245  END IF
246  END SUBROUTINE gauss_ff
247 
248  SUBROUTINE find_elem(mesh, rr, abc, m)
250  IMPLICIT NONE
251  TYPE(mesh_type) :: mesh
252  REAL(KIND=8), DIMENSION(2) :: rr
253  REAL(KIND=8), DIMENSION(3) :: abc
254  INTEGER :: m, n
255  REAL(KIND=8), DIMENSION(2) :: X1, X2, X3, Y12, Y23, Y31, R1, R2, R3
256 
257  m = 0
258 
259  DO n = 1, mesh%me
260  x1 = mesh%rr(:,mesh%jj(1,n)) - rr
261  x2 = mesh%rr(:,mesh%jj(2,n)) - rr
262  x3 = mesh%rr(:,mesh%jj(3,n)) - rr
263  y23 = mesh%rr(:,mesh%jj(3,n))-mesh%rr(:,mesh%jj(2,n))
264  y31 = mesh%rr(:,mesh%jj(1,n))-mesh%rr(:,mesh%jj(3,n))
265  y12 = mesh%rr(:,mesh%jj(2,n))-mesh%rr(:,mesh%jj(1,n))
266  r1 = pd_vect(y23)
267  r2 = pd_vect(y31)
268  r3 = pd_vect(y12)
269  abc(1) = pd_scal(x2,r1)
270  abc(2) = pd_scal(x3,r2)
271  abc(3) = pd_scal(x1,r3)
272 
273  IF (minval(abc) < -1.d-12) cycle
274  m=n
275  abc = abc/sum(abc)
276  EXIT
277 
278  END DO
279 
280  END SUBROUTINE find_elem
281 
282  SUBROUTINE gauss_ff_edge(ab, type_fe, ff)
283  IMPLICIT NONE
284 
285  REAL(KIND=8), DIMENSION(2) :: ab
286  INTEGER, INTENT(IN) :: type_fe
287  REAL(KIND=8), DIMENSION(1+type_fe):: ff
288 
289  IF (abs(1.d0-sum(ab)) > 1.d-12) THEN
290  WRITE(*,*) 'bug in gauss_ff_edge'
291  stop
292  END IF
293 
294  IF (type_fe == 1) THEN
295  ff = ab
296  ELSE
297  ff(1) = ab(1)*(ab(1)-ab(2))
298  ff(2) = ab(2)*(ab(2)-ab(1))
299  ff(3) = 4*ab(1)*ab(2)
300  END IF
301 
302  END SUBROUTINE gauss_ff_edge
303 
304  SUBROUTINE find_edge(mesh, rr, m, ab)
306  IMPLICIT NONE
307 
308  TYPE(mesh_type) :: mesh
309  REAL(KIND=8), DIMENSION(2) :: rr, ab, abt
310  INTEGER :: m
311  REAL(KIND=8) :: x, y, h, hr
312  INTEGER :: ms
313 
314  x = 1
315  m = 1
316  DO ms = 1, mesh%mes
317  h = sum((mesh%rr(:,mesh%jjs(1,ms))-mesh%rr(:,mesh%jjs(2,ms)))**2)
318  h = sqrt(h)
319  CALL dist(rr, mesh%rr(:,mesh%jjs(1,ms)), mesh%rr(:,mesh%jjs(2,ms)), y, abt)
320  IF (y < x) THEN
321  x = y
322  ab = abt
323  m = ms
324  hr = h
325  END IF
326  END DO
327 
328  IF (x > hr) THEN
329  m = 0
330  END IF
331 
332 
333  END SUBROUTINE find_edge
334 
335  SUBROUTINE dist(rr, rr1, rr2, y, abt)
336  IMPLICIT NONE
337 
338  REAL(KIND=8), DIMENSION(2) :: rr, rr1, rr2, abt
339  REAl(KIND=8) :: y
340  REAL(KIND=8), DIMENSION(2) :: Y12, X1, X2, R
341 
342  x1 = rr1-rr
343  x2 = rr2-rr
344  y12 = x2-x1
345  r = pd_vect(y12)
346 
347  y = abs(pd_scal(x1,r)/pd_scal(r,r))
348  abt(1) = -pd_scal(x1,y12)/pd_scal(y12,y12)
349  abt(2) = pd_scal(x2,y12)/pd_scal(y12,y12)
350 
351  IF (abt(1)*abt(2) < -1.d-12) THEN
352  y = sqrt(min(pd_scal(x1,x1), pd_scal(x2,x2)))
353  IF (pd_scal(x1,x1) < pd_scal(x2,x2)) THEN
354  abt(1) = 1.d0
355  abt(2) = 0.d0
356  ELSE
357  abt(1) = 0.d0
358  abt(2) = 1.d0
359  END IF
360  END IF
361 
362  END SUBROUTINE dist
363 
364  FUNCTION pd_vect(X) RESULT(Y)
365  IMPLICIT NONE
366  REAl(KIND=8), DIMENSION(2) :: X, Y
367 
368  y(1) = x(2)
369  y(2) = -x(1)
370  END FUNCTION pd_vect
371 
372  FUNCTION pd_scal(X,Y) RESULT(pp)
373  IMPLICIT NONE
374  REAL(KIND=8), DIMENSION(:) :: X,Y
375  REAL(KIND=8) :: pp
376 
377  pp = sum(x*y)
378 
379  END FUNCTION pd_scal
380 
381 
382 
383 
384 END MODULE interpolation_tools
subroutine max_controle(cont, comm)
real(kind=8) function pd_scal(X, Y)
subroutine dist(rr, rr1, rr2, y, abt)
subroutine somme_spatiale(field, comm, cont)
integer function eval_blank(len_str, string)
subroutine find_edge(mesh, rr, m, ab)
subroutine backup_suite(type_fic, filename, n_it, rank, is_sequential)
subroutine interp_mesh(mesh_in, mesh_out, in_field, out_field, controle, type_fe)
subroutine inter_mesh_loc_to_glob(mesh_in, mesh_out, in_field, out_field, l_t_g, is_in, comm)
real(kind=8) function, dimension(2) pd_vect(X)
subroutine gauss_ff_edge(ab, type_fe, ff)
subroutine find_elem(mesh, rr, abc, m)
subroutine gauss_ff(abc, type_fe, ff)