15 use tools_stripack,
only:
addnod,
areas,
bnodes,
crlist,
inside,
scoord,
trans,
trfind,
trlist,
trmesh 27 integer,
allocatable :: order(:)
28 integer,
allocatable :: order_inv(:)
29 real(kind_real),
allocatable :: lon(:)
30 real(kind_real),
allocatable :: lat(:)
31 real(kind_real),
allocatable :: x(:)
32 real(kind_real),
allocatable :: y(:)
33 real(kind_real),
allocatable :: z(:)
34 integer,
allocatable :: list(:)
35 integer,
allocatable :: lptr(:)
36 integer,
allocatable :: lend(:)
39 integer,
allocatable :: bnd(:)
44 integer,
allocatable :: ltri(:,:)
45 integer,
allocatable :: larc(:,:)
46 real(kind_real),
allocatable :: bdist(:)
76 class(mesh_type),
intent(inout) :: mesh
77 type(mpl_type),
intent(in) :: mpl
78 type(rng_type),
intent(inout) :: rng
79 integer,
intent(in) :: n
80 real(kind_real),
intent(in) :: lon(n)
81 real(kind_real),
intent(in) :: lat(n)
85 integer,
allocatable :: jtab(:),near(:),next(:)
86 real(kind_real),
allocatable :: dist(:)
92 allocate(mesh%order(mesh%n))
93 allocate(mesh%order_inv(mesh%n))
94 allocate(mesh%lon(mesh%n))
95 allocate(mesh%lat(mesh%n))
96 allocate(mesh%list(6*(mesh%n-2)))
97 allocate(mesh%lptr(6*(mesh%n-2)))
98 allocate(mesh%lend(mesh%n))
99 allocate(mesh%x(mesh%n))
100 allocate(mesh%y(mesh%n))
101 allocate(mesh%z(mesh%n))
102 allocate(near(mesh%n))
103 allocate(next(mesh%n))
104 allocate(dist(mesh%n))
113 allocate(jtab(mesh%n))
114 if (mpl%main)
call rng%rand_integer(1,mesh%n,jtab)
115 call mpl%f_comm%broadcast(jtab,mpl%ioproc-1)
117 k = mesh%order(jtab(i))
118 mesh%order(jtab(i)) = mesh%order(i)
124 call msi(mesh%order_inv)
126 mesh%order_inv(mesh%order(i)) = i
130 call mesh%trans(lon,lat)
134 call trmesh(mpl,mesh%n,mesh%x,mesh%y,mesh%z,mesh%list,mesh%lptr,mesh%lend,mesh%lnew,near,next,dist,info)
147 class(mesh_type),
intent(inout) :: mesh
150 if (
allocated(mesh%order))
deallocate(mesh%order)
151 if (
allocated(mesh%order_inv))
deallocate(mesh%order_inv)
152 if (
allocated(mesh%lon))
deallocate(mesh%lon)
153 if (
allocated(mesh%lat))
deallocate(mesh%lat)
154 if (
allocated(mesh%x))
deallocate(mesh%x)
155 if (
allocated(mesh%y))
deallocate(mesh%y)
156 if (
allocated(mesh%z))
deallocate(mesh%z)
157 if (
allocated(mesh%list))
deallocate(mesh%list)
158 if (
allocated(mesh%lptr))
deallocate(mesh%lptr)
159 if (
allocated(mesh%lend))
deallocate(mesh%lend)
160 if (
allocated(mesh%bnd))
deallocate(mesh%bnd)
161 if (
allocated(mesh%ltri))
deallocate(mesh%ltri)
162 if (
allocated(mesh%larc))
deallocate(mesh%larc)
163 if (
allocated(mesh%bdist))
deallocate(mesh%bdist)
171 type(mesh_type) function mesh_copy(mesh)
180 if (
allocated(mesh%ltri))
then 181 mesh_copy%nt = mesh%nt
182 mesh_copy%na = mesh%na
186 call mesh_copy%dealloc
189 allocate(mesh_copy%order(mesh_copy%n))
190 allocate(mesh_copy%order_inv(mesh_copy%n))
191 allocate(mesh_copy%lon(mesh_copy%n))
192 allocate(mesh_copy%lat(mesh_copy%n))
193 allocate(mesh_copy%x(mesh_copy%n))
194 allocate(mesh_copy%y(mesh_copy%n))
195 allocate(mesh_copy%z(mesh_copy%n))
196 allocate(mesh_copy%list(6*(mesh_copy%n-2)))
197 allocate(mesh_copy%lptr(6*(mesh_copy%n-2)))
198 allocate(mesh_copy%lend(mesh_copy%n))
199 if (
allocated(mesh%ltri))
then 200 allocate(mesh_copy%ltri(3,mesh_copy%nt))
201 allocate(mesh_copy%larc(2,mesh_copy%na))
202 allocate(mesh_copy%bdist(mesh_copy%n))
206 mesh_copy%order = mesh%order
207 mesh_copy%order_inv = mesh%order_inv
208 mesh_copy%lon = mesh%lon
209 mesh_copy%lat = mesh%lat
213 mesh_copy%list = mesh%list
214 mesh_copy%lptr = mesh%lptr
215 mesh_copy%lend = mesh%lend
216 mesh_copy%lnew = mesh%lnew
217 if (
allocated(mesh%ltri))
then 218 mesh_copy%nb = mesh%nb
219 mesh_copy%ltri = mesh%ltri
220 mesh_copy%larc = mesh%larc
221 mesh_copy%bdist = mesh%bdist
235 class(mesh_type),
intent(inout) :: mesh
236 real(kind_real),
intent(in) :: lon(mesh%n)
237 real(kind_real),
intent(in) :: lat(mesh%n)
240 mesh%lon = lon(mesh%order)
241 mesh%lat = lat(mesh%order)
244 call trans(mesh%n,mesh%lat,mesh%lon,mesh%x,mesh%y,mesh%z)
257 class(mesh_type),
intent(inout) :: mesh
261 integer,
allocatable :: ltri(:,:)
262 integer :: ia,it,i,i1,i2
265 allocate(ltri(9,2*(mesh%n-2)))
268 call trlist(mesh%n,mesh%list,mesh%lptr,mesh%lend,9,mesh%nt,ltri,info)
271 mesh%na = maxval(ltri(7:9,1:mesh%nt))
272 allocate(mesh%ltri(3,mesh%nt))
273 allocate(mesh%larc(2,mesh%na))
276 mesh%ltri = ltri(1:3,1:mesh%nt)
281 do while (it<=mesh%nt)
282 if (any(ltri(7:9,it)==ia))
exit 287 if (ltri(6+i,it)==ia)
exit 294 mesh%larc(1,ia) = ltri(i1,it)
295 mesh%larc(2,ia) = ltri(i2,it)
309 class(mesh_type),
intent(inout) :: mesh
312 allocate(mesh%bnd(mesh%n))
316 call bnodes(mesh%n,mesh%list,mesh%lptr,mesh%lend,mesh%bnd,mesh%nb,mesh%na,mesh%nt)
329 class(mesh_type),
intent(inout) :: mesh
333 integer,
allocatable :: larcb(:,:)
334 integer :: ia,nab,iab
335 real(kind_real) :: dist_12,v1(3),v2(3),vp(3),v(3),vf(3),vt(3),tlat,tlon,trad,dist_t1,dist_t2
338 allocate(larcb(2,3*(mesh%n-2)))
339 allocate(mesh%bdist(mesh%n))
345 if (any(mesh%bnd(1:mesh%nb)==mesh%larc(1,ia)).and.any(mesh%bnd(1:mesh%nb)==mesh%larc(2,ia)))
then 347 larcb(:,nab) = mesh%larc(:,ia)
352 mesh%bdist = huge(1.0)
355 call sphere_dist(mesh%lon(larcb(1,iab)),mesh%lat(larcb(1,iab)), &
356 & mesh%lon(larcb(2,iab)),mesh%lat(larcb(2,iab)),dist_12)
359 v1 = (/mesh%x(larcb(1,iab)),mesh%y(larcb(1,iab)),mesh%z(larcb(1,iab))/)
360 v2 = (/mesh%x(larcb(2,iab)),mesh%y(larcb(2,iab)),mesh%z(larcb(2,iab))/)
363 call vector_product(v1,v2,vp)
368 v = (/mesh%x(i),mesh%y(i),mesh%z(i)/)
371 call vector_product(v,vp,vf)
372 call vector_product(vp,vf,vt)
375 call scoord(vt(1),vt(2),vt(3),tlat,tlon,trad)
378 call sphere_dist(tlon,tlat,mesh%lon(larcb(1,iab)),mesh%lat(larcb(1,iab)),dist_t1)
379 call sphere_dist(tlon,tlat,mesh%lon(larcb(2,iab)),mesh%lat(larcb(2,iab)),dist_t2)
380 if ((dist_t1<dist_12).and.(dist_t2<dist_12))
then 382 call sphere_dist(mesh%lon(i),mesh%lat(i),tlon,tlat,dist_t1)
383 mesh%bdist(i) =
min(mesh%bdist(i),dist_t1)
386 call sphere_dist(mesh%lon(i),mesh%lat(i),mesh%lon(larcb(1,iab)),mesh%lat(larcb(1,iab)),dist_t1)
387 call sphere_dist(mesh%lon(i),mesh%lat(i),mesh%lon(larcb(2,iab)),mesh%lat(larcb(2,iab)),dist_t2)
388 mesh%bdist(i) =
min(mesh%bdist(i),
min(dist_t1,dist_t2))
393 mesh%bdist = huge(1.0)
407 class(mesh_type),
intent(inout) :: mesh
408 real(kind_real),
intent(out) :: valid(mesh%n)
412 real(kind_real),
allocatable :: a(:),b(:),c(:),cd(:),cp(:)
413 logical :: validt(mesh%nt)
425 if (isallnotmsr(mesh%x(mesh%ltri(:,it))).and.isallnotmsr(mesh%y(mesh%ltri(:,it))).and.isallnotmsr(mesh%z(mesh%ltri(:,it))))
then 427 a = (/mesh%x(mesh%ltri(1,it)),mesh%y(mesh%ltri(1,it)),mesh%z(mesh%ltri(1,it))/)
428 b = (/mesh%x(mesh%ltri(2,it)),mesh%y(mesh%ltri(2,it)),mesh%z(mesh%ltri(2,it))/)
429 c = (/mesh%x(mesh%ltri(3,it)),mesh%y(mesh%ltri(3,it)),mesh%z(mesh%ltri(3,it))/)
432 call vector_product(c-b,a-b,cp)
438 validt(it) = sum(cp*cd)>0.0
456 if (.not.validt(it)) valid(mesh%ltri(:,it)) = 0.0
470 class(mesh_type),
intent(in) :: mesh
471 real(kind_real),
intent(in) :: lon(1)
472 real(kind_real),
intent(in) :: lat(1)
473 logical,
intent(out) :: inside_mesh
477 real(kind_real) :: p(3)
481 call trans(1,lat,lon,p(1),p(2),p(3))
484 inside_mesh = inside(p,mesh%n,mesh%x,mesh%y,mesh%z,mesh%nb,mesh%bnd,info)
501 class(mesh_type),
intent(in) :: mesh
502 real(kind_real),
intent(in) :: lon(1)
503 real(kind_real),
intent(in) :: lat(1)
504 integer,
intent(in) :: istart
505 real(kind_real),
intent(out) :: b(3)
506 integer,
intent(out) :: ib(3)
509 real(kind_real) :: p(3)
512 call trans(1,lat,lon,p(1),p(2),p(3))
517 call trfind(istart,p,mesh%n,mesh%x,mesh%y,mesh%z,mesh%list,mesh%lptr,mesh%lend,b(1),b(2),b(3),ib(1),ib(2),ib(3))
530 class(mesh_type),
intent(inout) :: mesh
531 type(mpl_type),
intent(in) :: mpl
532 real(kind_real),
intent(in) :: lonnew(1)
533 real(kind_real),
intent(in) :: latnew(1)
537 integer,
allocatable :: order(:),order_inv(:),list(:),lptr(:),lend(:)
538 real(kind_real),
allocatable :: lon(:),lat(:),x(:),y(:),z(:)
541 allocate(order(mesh%n))
542 allocate(order_inv(mesh%n))
543 allocate(lon(mesh%n))
544 allocate(lat(mesh%n))
548 allocate(list(6*(mesh%n-2)))
549 allocate(lptr(6*(mesh%n-2)))
550 allocate(lend(mesh%n))
554 order_inv = mesh%order_inv
569 allocate(mesh%order(mesh%n))
570 allocate(mesh%order_inv(mesh%n))
571 allocate(mesh%lon(mesh%n))
572 allocate(mesh%lat(mesh%n))
573 allocate(mesh%x(mesh%n))
574 allocate(mesh%y(mesh%n))
575 allocate(mesh%z(mesh%n))
576 allocate(mesh%list(6*(mesh%n-2)))
577 allocate(mesh%lptr(6*(mesh%n-2)))
578 allocate(mesh%lend(mesh%n))
581 mesh%order(1:mesh%n-1) = order
582 mesh%order_inv(1:mesh%n-1) = order_inv
583 mesh%lon(1:mesh%n-1) = lon
584 mesh%lat(1:mesh%n-1) = lat
585 mesh%x(1:mesh%n-1) = x
586 mesh%y(1:mesh%n-1) = y
587 mesh%z(1:mesh%n-1) = z
588 mesh%list(1:6*(mesh%n-3)) = list
589 mesh%lptr(1:6*(mesh%n-3)) = lptr
590 mesh%lend(1:mesh%n-1) = lend
593 call trans(1,latnew,lonnew,mesh%x(mesh%n:mesh%n),mesh%y(mesh%n:mesh%n),mesh%z(mesh%n:mesh%n))
596 mesh%order(mesh%n) = mesh%n
597 mesh%order_inv(mesh%n) = mesh%n
598 mesh%lon(mesh%n) = lonnew(1)
599 mesh%lat(mesh%n) = latnew(1)
600 call addnod(mpl,1,mesh%n,mesh%x,mesh%y,mesh%z,mesh%list,mesh%lptr,mesh%lend,mesh%lnew,info)
613 class(mesh_type),
intent(in) :: mesh
614 integer,
intent(in) :: np
615 integer,
intent(in) :: plist(np)
616 real(kind_real),
intent(out) :: area_polygon(np)
619 integer :: ip,i_src,index_triangle,i_src_last,i_src_new,i_src_stop,vertex_last,vertex_new,nb,info
620 integer :: lnew_tmp,lptr_tmp(6*(mesh%n-2)),lbtri(6,mesh%n),listc(6*(mesh%n-2))
621 real(kind_real) :: area_triangle,v1(3),v2(3),v3(3)
622 real(kind_real) :: xc(6*(mesh%n-2)),yc(6*(mesh%n-2)),zc(6*(mesh%n-2)),rc(6*(mesh%n-2))
630 call crlist(mesh%n,mesh%n,mesh%x,mesh%y,mesh%z,mesh%list,mesh%lend,lptr_tmp,lnew_tmp,lbtri,listc,nb,xc,yc,zc,rc,info)
634 area_polygon(ip) = 0.0
636 i_src_stop = mesh%lend(i_src)
637 i_src_new = i_src_stop
638 vertex_new = listc(i_src_new)
641 index_triangle = index_triangle+1
642 i_src_last = i_src_new
643 i_src_new = lptr_tmp(i_src_last)
644 vertex_last = vertex_new
645 vertex_new = listc(i_src_new)
646 v1 = (/mesh%x(i_src),mesh%y(i_src),mesh%z(i_src)/)
647 v2 = (/xc(vertex_last),yc(vertex_last),zc(vertex_last)/)
648 v3 = (/xc(vertex_new),yc(vertex_new),zc(vertex_new)/)
649 area_triangle = areas(v1,v2,v3)
650 area_polygon(ip) = area_polygon(ip)+area_triangle
651 loop = (i_src_new/=i_src_stop)
type(mesh_type) function mesh_copy(mesh)
subroutine check(action, status)
subroutine mesh_trlist(mesh)
subroutine mesh_create(mesh, mpl, rng, n, lon, lat)
subroutine mesh_inside(mesh, lon, lat, inside_mesh)
subroutine mesh_polygon(mesh, np, plist, area_polygon)
subroutine mesh_addnode(mesh, mpl, lonnew, latnew)
subroutine, public copy(self, rhs)
subroutine, public create(self, geom, vars)
Linked list implementation.
subroutine mesh_barcs(mesh)
subroutine mesh_trans(mesh, lon, lat)
subroutine mesh_check(mesh, valid)
real(kind=kind_real), parameter req
Earth radius at equator (m)
subroutine mesh_barycentric(mesh, lon, lat, istart, b, ib)
subroutine mesh_bnodes(mesh)
logical, parameter shuffle
integer, parameter, public kind_real
subroutine mesh_dealloc(mesh)