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