5 #include "sll_memory.h"
6 #include "sll_working_precision.h"
25 sll_int32,
dimension(:, :),
pointer :: nvoiv
26 sll_int32,
dimension(:),
pointer :: nlpa
27 sll_int32,
dimension(:),
pointer :: nbpama
28 sll_int32,
dimension(:),
pointer :: iad1
29 sll_int32,
dimension(:),
pointer :: indice
30 sll_int32,
dimension(:),
pointer :: itabor
31 sll_int32,
dimension(:),
pointer :: itest
32 sll_int32,
dimension(:),
pointer :: nlmloc
33 sll_real64,
dimension(:),
pointer :: xbas
34 sll_real64,
dimension(:, :),
pointer :: xlm
35 sll_real64,
dimension(:, :),
pointer :: coef
36 sll_real64,
dimension(:),
pointer :: xp
37 sll_real64,
dimension(:),
pointer :: yp
38 sll_real64,
dimension(:),
pointer :: f_out
39 logical,
dimension(:),
pointer :: inzone
40 sll_int32,
dimension(:),
pointer :: numres
68 sll_int32 :: is1, is2, is3
70 sll_allocate(adv, ierr)
81 allocate (adv%nvoiv(3, mesh%num_triangles))
82 do i = 1, mesh%num_triangles
84 if (mesh%nvois(j, i) > 0)
then
85 adv%nvoiv(j, i) = mesh%nvois(j, i)
92 allocate (adv%nlpa(mesh%num_nodes))
93 do i = 1, mesh%num_nodes
94 adv%nlpa(i) = mesh%npoel2(mesh%npoel1(i) + 1)
97 sll_allocate(adv%itest(mesh%num_nodes), ierr)
98 sll_allocate(adv%coef(4, mesh%num_nodes), ierr)
99 sll_allocate(adv%xlm(3, mesh%num_nodes), ierr)
100 sll_allocate(adv%nlmloc(mesh%num_nodes), ierr)
101 sll_allocate(adv%xp(mesh%num_nodes), ierr)
102 sll_allocate(adv%yp(mesh%num_nodes), ierr)
103 sll_allocate(adv%inzone(mesh%num_nodes), ierr)
104 allocate (adv%numres(mesh%num_nodes))
105 allocate (adv%iad1(mesh%num_triangles))
106 allocate (adv%indice(mesh%num_triangles))
107 allocate (adv%itabor(mesh%num_nodes))
108 allocate (adv%f_out(mesh%num_nodes))
109 allocate (adv%nbpama(mesh%num_triangles))
110 allocate (adv%xbas(mesh%num_nodes))
112 do i = 1, mesh%num_triangles
114 is1 = mesh%nodes(1, i)
115 is2 = mesh%nodes(2, i)
116 is3 = mesh%nodes(3, i)
118 adv%xbas(is1) = adv%xbas(is1) + mesh%area(i)/3.
119 adv%xbas(is2) = adv%xbas(is2) + mesh%area(i)/3.
120 adv%xbas(is3) = adv%xbas(is3) + mesh%area(i)/3.
139 sll_real64,
dimension(:),
intent(in) :: f_val
140 sll_real64,
dimension(:),
intent(out) :: f_der
141 sll_real64,
dimension(:),
intent(out) :: f_der2
142 sll_int32,
intent(in) :: degree
143 sll_real64,
intent(in) :: epsilon
153 f_der(i) = (f_val(i1) - f_val(1))/epsilon
154 f_der2(i) = (f_val(i2) - f_val(i1) - f_val(i3) + f_val(1))/(epsilon*epsilon)
157 i3 = modulo(i3 + 1, 2*degree) + 1
175 sll_real64,
intent(in) :: x1_adv
176 sll_real64,
intent(in) :: x2_adv
177 sll_real64,
dimension(:),
intent(in) :: x1_coo
178 sll_real64,
dimension(:),
intent(in) :: x2_coo
179 sll_int32,
intent(in) :: degree
180 sll_real64,
intent(in) :: epsilon
181 sll_real64,
dimension(:),
intent(out) :: x1_dof
182 sll_real64,
dimension(:),
intent(out) :: x2_dof
193 x1_dof(2*i) = x1_dof(1) + epsilon*(x1_coo(i1) - x1_coo(1))
194 x2_dof(2*i) = x2_dof(1) + epsilon*(x2_coo(i1) - x2_coo(1))
196 x1_dof(2*i + 1) = x1_dof(1) + epsilon*(x1_coo(i1) - x1_coo(1)*2.0_f64 + x1_coo(i2))
197 x2_dof(2*i + 1) = x2_dof(1) + epsilon*(x2_coo(i1) - x2_coo(1)*2.0_f64 + x2_coo(i2))
200 i2 = modulo(i2 - 1, degree) + 2
213 sll_real64,
dimension(3),
intent(in) :: lam
214 sll_real64,
dimension(3),
intent(in) :: func_loc
215 sll_real64,
dimension(6),
intent(in) :: der_loc
216 sll_real64,
dimension(3),
intent(in) :: der2_loc
223 out = lam(1)**2*(3._f64 - 2._f64*lam(1) + 6._f64*lam(2)*lam(3))*func_loc(1)
224 out = out + lam(2)**2*(3._f64 - 2._f64*lam(2) + 6._f64*lam(3)*lam(1))*func_loc(2)
225 out = out + lam(3)**2*(3._f64 - 2._f64*lam(3) + 6._f64*lam(1)*lam(2))*func_loc(3)
231 out = out + lam(1)**2*lam(2)*(1 + 2*lam(3))*der_loc(1)
232 out = out + lam(1)**2*lam(3)*(1 + 2*lam(2))*der_loc(2)
233 out = out + lam(2)**2*lam(3)*(1 + 2*lam(1))*der_loc(3)
234 out = out + lam(2)**2*lam(1)*(1 + 2*lam(3))*der_loc(4)
235 out = out + lam(3)**2*lam(1)*(1 + 2*lam(2))*der_loc(5)
236 out = out + lam(3)**2*lam(2)*(1 + 2*lam(1))*der_loc(6)
242 out = out + lam(1)**2*lam(2)*lam(3)*der2_loc(1)
243 out = out + lam(2)**2*lam(3)*lam(1)*der2_loc(2)
244 out = out + lam(3)**2*lam(1)*lam(2)*der2_loc(3)
309 sll_real64,
dimension(:),
intent(inout) :: f_in
310 sll_real64,
dimension(:),
intent(in) :: ex
311 sll_real64,
dimension(:),
intent(in) :: ey
312 sll_real64,
intent(in) :: dt
325 sll_real64 :: pa1x, pa1y, pa2x, pa2y, pa3x, pa3y
327 sll_real64 :: phi1, phi2, phi3
328 sll_real64 :: xm11, xm12, xm13
330 sll_int32 :: mpa, inum, ip1, ip2, ks, ind
331 sll_int32 :: it, is1, is2, is3
332 sll_real64 :: x1, x2, x3, y1, y2, y3, det
334 eps = -adv%mesh%petitl**2
338 do ip = 1, adv%mesh%num_nodes
340 adv%xp(ip) = adv%mesh%coord(1, ip) + ex(ip)*dt
341 adv%yp(ip) = adv%mesh%coord(2, ip) + ey(ip)*dt
342 adv%nlmloc(ip) = adv%nlpa(ip)
345 nbpres = adv%mesh%num_nodes
351 do while (nbpres > 0)
361 write (*,
"(//2x,'Arret dans POSITIONS:')", advance=
'no')
362 write (*,
"('on n''arrive pas a positionner ')", advance=
'no')
363 write (*,
"(i4)", advance=
'no') nbpres
364 write (*,
"(' particules')", advance=
'no')
365 write (*,
"(/2x,'Particules non positionnees :')", advance=
'no')
366 write (*,
"(5x,'numero - position - vitesse - element'/)")
367 do ip = 1, min(50, nbpres)
368 write (*,
"(i10,2x,4e12.4,i10)") adv%numres(ip), &
369 adv%xp(ip), adv%yp(ip), &
372 write (*,
"(/5x,a)") &
373 'Il y a certainement un probleme avec le solveur de champ'
374 write (*,
"(/5x,'(en general la CFL n''est pas verifiee)'/)")
385 x1 = adv%mesh%coord(1, adv%mesh%nodes(1, it))
386 y1 = adv%mesh%coord(2, adv%mesh%nodes(1, it))
387 x2 = adv%mesh%coord(1, adv%mesh%nodes(2, it))
388 y2 = adv%mesh%coord(2, adv%mesh%nodes(2, it))
389 x3 = adv%mesh%coord(1, adv%mesh%nodes(3, it))
390 y3 = adv%mesh%coord(2, adv%mesh%nodes(3, it))
392 pa1x = x1 - adv%xp(jp)
393 pa1y = y1 - adv%yp(jp)
394 pa2x = x2 - adv%xp(jp)
395 pa2y = y2 - adv%yp(jp)
396 pa3x = x3 - adv%xp(jp)
397 pa3y = y3 - adv%yp(jp)
399 adv%coef(1, ip) = pa1x*pa2y - pa1y*pa2x
400 adv%coef(2, ip) = pa2x*pa3y - pa2y*pa3x
401 adv%coef(3, ip) = pa3x*pa1y - pa3y*pa1x
403 if (adv%coef(1, ip) >= eps &
404 .and. adv%coef(2, ip) >= eps &
405 .and. adv%coef(3, ip) >= eps)
then
409 det = (x2 - x1)*(y3 - y1) - (x3 - x1)*(y2 - y1)
411 adv%xlm(1, jp) = adv%coef(1, ip)/det
412 adv%xlm(2, jp) = adv%coef(2, ip)/det
413 adv%xlm(3, jp) = adv%coef(3, ip)/det
415 adv%nlpa(jp) = adv%nlmloc(ip)
417 adv%inzone(jp) = .true.
427 if (nbpr .ne. 0)
then
434 if (adv%coef(1, ip) < eps &
435 .and. adv%coef(2, ip) >= eps &
436 .and. adv%coef(3, ip) >= eps)
then
438 adv%itest(ip) = 1 + 10*(1 - min(1, adv%nvoiv(1, it)))
442 if (adv%coef(1, ip) >= eps &
443 .and. adv%coef(2, ip) < eps &
444 .and. adv%coef(3, ip) >= eps)
then
446 adv%itest(ip) = 2 + 10*(1 - min(1, adv%nvoiv(2, it)))
450 if (adv%coef(1, ip) >= eps &
451 .and. adv%coef(2, ip) >= eps &
452 .and. adv%coef(3, ip) < eps)
then
454 adv%itest(ip) = 3 + 10*(1 - min(1, adv%nvoiv(3, it)))
458 if (adv%coef(1, ip) < eps &
459 .and. adv%coef(2, ip) < eps)
then
461 pa2x = adv%mesh%coord(1, adv%mesh%nodes(2, it)) - adv%xp(jp)
462 pa2y = adv%mesh%coord(2, adv%mesh%nodes(2, it)) - adv%yp(jp)
464 adv%coef(4, ip) = pa2x*ey(jp) - pa2y*ex(jp)
466 adv%itest(ip) = 1 + max(0, nint(sign(1.0_f64, adv%coef(4, ip))))
467 adv%itest(ip) = adv%itest(ip) + 10*(1 - min(1, adv%nvoiv(adv%itest(ip), it)))
471 if (adv%coef(2, ip) < eps &
472 .and. adv%coef(3, ip) < eps)
then
474 pa3x = adv%mesh%coord(1, adv%mesh%nodes(3, it)) - adv%xp(jp)
475 pa3y = adv%mesh%coord(2, adv%mesh%nodes(3, it)) - adv%yp(jp)
477 adv%coef(4, ip) = pa3x*ey(jp) - pa3y*ex(jp)
479 adv%itest(ip) = 2 + max(0, nint(sign(1.0_f64, adv%coef(4, ip))))
480 adv%itest(ip) = adv%itest(ip) + 10*(1 - min(1, adv%nvoiv(adv%itest(ip), it)))
484 if (adv%coef(3, ip) < eps &
485 .and. adv%coef(1, ip) < eps)
then
487 pa1x = adv%mesh%coord(1, adv%mesh%nodes(1, it)) - adv%xp(jp)
488 pa1y = adv%mesh%coord(2, adv%mesh%nodes(1, it)) - adv%yp(jp)
490 adv%coef(4, ip) = pa1x*ey(jp) - pa1y*ex(jp)
492 adv%itest(ip) = 1 + mod(2 + max(0, nint(sign(1.0_f64, adv%coef(4, ip)))), 3)
493 adv%itest(ip) = adv%itest(ip) + 10*(1 - min(1, adv%nvoiv(adv%itest(ip), it)))
503 if (adv%itest(ip) > 10 .and. adv%itest(ip) < 14)
then
514 if ((adv%itest(ip) > 0 .and. adv%itest(ip) < 4) .or. &
515 (adv%itest(ip) > 20 .and. adv%itest(ip) < 24))
then
517 adv%numres(nrest) = adv%numres(ip)
519 if (adv%itest(ip) > 20)
then
520 adv%nlmloc(nrest) = adv%mesh%nvois(adv%itest(ip) - 20, adv%nlmloc(ip)) &
521 *max(0, sign(1, 10 - adv%itest(ip))) &
522 + adv%nlmloc(ip)*max(0, sign(1, adv%itest(ip) - 20))
524 adv%nlmloc(nrest) = adv%mesh%nvois(adv%itest(ip), adv%nlmloc(ip)) &
525 *max(0, sign(1, 10 - adv%itest(ip))) &
526 + adv%nlmloc(ip)*max(0, sign(1, adv%itest(ip) - 20))
542 do ip = 1, adv%mesh%num_nodes
543 if (adv%inzone(ip))
then
545 adv%nbpama(mpa) = adv%nbpama(mpa) + 1
554 do it = 1, adv%mesh%num_triangles
555 if (adv%nbpama(it) .ne. 0)
then
557 ks = ks + adv%nbpama(it)
566 do ip = 1, adv%mesh%num_nodes
568 if (adv%inzone(ip))
then
570 ind = adv%iad1(mpa) + adv%indice(mpa)
572 adv%indice(mpa) = adv%indice(mpa) + 1
577 nprest = adv%mesh%num_nodes
581 do it = 1, adv%mesh%num_triangles
583 xm11 = 0.0_f64; xm12 = 0.0_f64; xm13 = 0.0_f64
587 if (adv%nbpama(it) .ne. 0)
then
590 ip2 = ip1 + adv%nbpama(it) - 1
596 inum = adv%itabor(ip)
598 phi1 = adv%xlm(2, inum)*f_in(inum)
599 phi2 = adv%xlm(3, inum)*f_in(inum)
600 phi3 = adv%xlm(1, inum)*f_in(inum)
608 is1 = adv%mesh%nodes(1, it)
609 is2 = adv%mesh%nodes(2, it)
610 is3 = adv%mesh%nodes(3, it)
612 adv%f_out(is1) = adv%f_out(is1) + xm11
613 adv%f_out(is2) = adv%f_out(is2) + xm12
614 adv%f_out(is3) = adv%f_out(is3) + xm13
616 if (adv%nbpama(it) == nprest)
exit
618 nprest = nprest - adv%nbpama(it)
advection on triangular mesh.
subroutine compute_derivatives(f_val, f_der, f_der2, degree, epsilon)
Computes degrees of freedom on one point.
type(sll_t_advection_tri_mesh) function, pointer, public sll_f_new_advection_2d_tri_mesh(mesh)
allocates the memory space for a new 2D advection on triangular mesh on the heap, initializes it with...
subroutine, public sll_s_advection_2d(adv, f_in, ex, ey, dt)
Compute characterisitic origin in triangular mesh.
subroutine interpolation_mitchell()
real(kind=f64) function eval_at_lambda(lam, func_loc, der_loc, der2_loc)
evaluation at barycentric points of one cell
subroutine compute_coordinates_dof(x1_adv, x2_adv, x1_coo, x2_coo, degree, epsilon, x1_dof, x2_dof)
computes the coordinates of the poisition of the degrees of freedom (dof)
2d advection on triangular mesh