1 |
|
---|
2 | #Class Triangle's triangulateio
|
---|
3 | mutable struct CTriangulateIO #{{{
|
---|
4 |
|
---|
5 | pointlist :: Ptr{Cdouble}
|
---|
6 | pointattributelist :: Ptr{Cdouble}
|
---|
7 | pointmarkerlist :: Ptr{Cint}
|
---|
8 | numberofpoints :: Cint
|
---|
9 | numberofpointattributes :: Cint
|
---|
10 |
|
---|
11 | trianglelist :: Ptr{Cint}
|
---|
12 | triangleattributelist :: Ptr{Cdouble}
|
---|
13 | trianglearealist :: Ptr{Cdouble}
|
---|
14 | neighborlist :: Ptr{Cint}
|
---|
15 | numberoftriangles :: Cint
|
---|
16 | numberofcorners :: Cint
|
---|
17 | numberoftriangleattributes :: Cint
|
---|
18 |
|
---|
19 | segmentlist :: Ptr{Cint}
|
---|
20 | segmentmarkerlist :: Ptr{Cint}
|
---|
21 | numberofsegments :: Cint
|
---|
22 |
|
---|
23 | holelist :: Ptr{Cdouble}
|
---|
24 | numberofholes :: Cint
|
---|
25 |
|
---|
26 | regionlist :: Ptr{Cdouble}
|
---|
27 | numberofregions :: Cint
|
---|
28 |
|
---|
29 | edgelist :: Ptr{Cint}
|
---|
30 | edgemarkerlist :: Ptr{Cint}
|
---|
31 | normlist :: Ptr{Cdouble}
|
---|
32 | numberofedges :: Cint
|
---|
33 | end #}}}
|
---|
34 | function CTriangulateIO() #{{{
|
---|
35 | return CTriangulateIO(C_NULL, C_NULL, C_NULL, 0, 0,
|
---|
36 | C_NULL, C_NULL, C_NULL, C_NULL, 0, 0, 0,
|
---|
37 | C_NULL, C_NULL, 0,
|
---|
38 | C_NULL, 0,
|
---|
39 | C_NULL, 0,
|
---|
40 | C_NULL, C_NULL, C_NULL, 0)
|
---|
41 | end# }}}
|
---|
42 | function Base.show(io::IO, tio::CTriangulateIO)# {{{
|
---|
43 | println(io,"CTriangulateIO(")
|
---|
44 | for name in fieldnames(typeof(tio))
|
---|
45 | a=getfield(tio,name)
|
---|
46 | print(io,"$(name) = ")
|
---|
47 | println(io,a)
|
---|
48 | end
|
---|
49 | println(io,")")
|
---|
50 | end# }}}
|
---|
51 |
|
---|
52 | using Printf #needed for sprintf
|
---|
53 |
|
---|
54 | """
|
---|
55 | TRIANGLE - create model mesh using the triangle package
|
---|
56 |
|
---|
57 | This function creates a model mesh using Triangle and a domain outline, to
|
---|
58 | within a certain resolution
|
---|
59 | #Arguments
|
---|
60 | - md is a model tuple
|
---|
61 | - domainname is the name of an Argus domain outline file
|
---|
62 | - resolution: is a characteristic length for the mesh (same unit as the domain outline unit)
|
---|
63 |
|
---|
64 | # Usage:
|
---|
65 | - md=triangle(md,domainname,resolution)
|
---|
66 | # Examples:
|
---|
67 | - md=triangle(md,'DomainOutline.exp',1000);
|
---|
68 | - md=triangle(md,'DomainOutline.exp','Rifts.exp',1500);
|
---|
69 | """
|
---|
70 | function triangle(md::model,domainname::String,resolution::Float64) #{{{
|
---|
71 |
|
---|
72 | #read input file
|
---|
73 | contours = expread(domainname)
|
---|
74 | area = resolution^2
|
---|
75 |
|
---|
76 | #Initialize i/o structures
|
---|
77 | ctio_in = CTriangulateIO();
|
---|
78 | ctio_out = CTriangulateIO();
|
---|
79 | vor_out = CTriangulateIO();
|
---|
80 |
|
---|
81 | #Construct input structure
|
---|
82 | numberofpoints = 0
|
---|
83 | numberofsegments = 0
|
---|
84 | for i in 1:length(contours)
|
---|
85 | numberofpoints += contours[i].nods-1
|
---|
86 | numberofsegments += contours[i].nods-1
|
---|
87 | end
|
---|
88 | numberofpointattributes = 1
|
---|
89 |
|
---|
90 | pointlist=Array{Cdouble,2}(undef,2,numberofpoints)
|
---|
91 | count = 0
|
---|
92 | for i in 1:length(contours)
|
---|
93 | nods = contours[i].nods
|
---|
94 | pointlist[1,count+1:count+nods-1] = contours[i].x[1:end-1]
|
---|
95 | pointlist[2,count+1:count+nods-1] = contours[i].y[1:end-1]
|
---|
96 | count += (nods-1)
|
---|
97 | end
|
---|
98 | pointattributelist=Array{Cdouble,1}(undef,numberofpoints)
|
---|
99 | pointmarkerlist=Array{Cint,1}(undef,numberofpoints)
|
---|
100 | for i in 1:numberofpoints
|
---|
101 | pointmarkerlist[i]=0
|
---|
102 | pointattributelist[i]=0.
|
---|
103 | end
|
---|
104 |
|
---|
105 | counter=0;
|
---|
106 | backcounter=0;
|
---|
107 | segmentlist=Array{Cint,2}(undef,2,numberofsegments)
|
---|
108 | segmentmarkerlist=Array{Cint,1}(undef,numberofsegments)
|
---|
109 | segmentmarkerlist[:].=0
|
---|
110 | for i in 1:length(contours)
|
---|
111 | nods = contours[i].nods
|
---|
112 | segmentlist[1,counter+1:counter+nods-2] = collect(counter+0:counter+nods-3)
|
---|
113 | segmentlist[2,counter+1:counter+nods-2] = collect(counter+1:counter+nods-2)
|
---|
114 | counter+=nods-2
|
---|
115 | #close profile
|
---|
116 | segmentlist[1,counter+1]=counter
|
---|
117 | segmentlist[2,counter+1]=backcounter
|
---|
118 | counter+=1
|
---|
119 | backcounter=counter
|
---|
120 | end
|
---|
121 |
|
---|
122 | numberofregions = 0
|
---|
123 | numberofholes = length(contours)-1
|
---|
124 | holelist = Array{Cdouble,2}(undef,2,numberofholes)
|
---|
125 | if numberofholes>0
|
---|
126 | for i in 2:length(contours)
|
---|
127 | xA=contours[i].x[1]; xB=contours[i].x[end-1]
|
---|
128 | yA=contours[i].y[1]; yB=contours[i].y[end-1]
|
---|
129 | xC=(xA+xB)/2; yC=(yA+yB)/2;
|
---|
130 | xD=xC+tan(10. /180. *pi)*(yC-yA);
|
---|
131 | yD=yC+tan(10. /180. *pi)*(xA-xC);
|
---|
132 | xE=xC-tan(10. /180. *pi)*(yC-yA);
|
---|
133 | yE=yC-tan(10. /180. *pi)*(xA-xC);
|
---|
134 | holelist[1,i-1] = xD
|
---|
135 | holelist[2,i-1] = yD
|
---|
136 | end
|
---|
137 | end
|
---|
138 |
|
---|
139 | #based on this, prepare input structure
|
---|
140 | ctio_in.numberofpoints = numberofpoints
|
---|
141 | ctio_in.pointlist=pointer(pointlist)
|
---|
142 | ctio_in.numberofpointattributes=numberofpointattributes
|
---|
143 | ctio_in.pointattributelist=pointer(pointattributelist)
|
---|
144 | ctio_in.pointmarkerlist=pointer(pointmarkerlist)
|
---|
145 | ctio_in.numberofsegments=numberofsegments
|
---|
146 | ctio_in.segmentlist=pointer(segmentlist)
|
---|
147 | ctio_in.segmentmarkerlist = pointer(segmentmarkerlist)
|
---|
148 | ctio_in.numberofholes=numberofholes
|
---|
149 | ctio_in.holelist=pointer(holelist)
|
---|
150 | ctio_in.numberofregions=0
|
---|
151 |
|
---|
152 | #Call triangle using ISSM's default options
|
---|
153 | triangle_switches = "pQzDq30ia"*@sprintf("%lf",area) #replace V by Q to quiet down the logging
|
---|
154 | #rc=ccall( (:triangulate,"libtriangle"),
|
---|
155 | rc=ccall( (:triangulate,"../../externalpackages/triangle/src/libtriangle.dylib"),
|
---|
156 | Cint, ( Cstring, Ref{CTriangulateIO}, Ref{CTriangulateIO}, Ref{CTriangulateIO}),
|
---|
157 | triangle_switches, Ref(ctio_in), Ref(ctio_out), Ref(vor_out))
|
---|
158 |
|
---|
159 | #post process output
|
---|
160 | points = convert(Array{Cdouble,2}, Base.unsafe_wrap(Array, ctio_out.pointlist, (2,Int(ctio_out.numberofpoints)), own=true))'
|
---|
161 | triangles = convert(Array{Cint,2}, Base.unsafe_wrap(Array, ctio_out.trianglelist, (3,Int(ctio_out.numberoftriangles)), own=true))' .+1
|
---|
162 | segments = convert(Array{Cint,2}, Base.unsafe_wrap(Array, ctio_out.segmentlist, (2,Int(ctio_out.numberofsegments)), own=true))' .+1
|
---|
163 |
|
---|
164 | #assign output
|
---|
165 | md.mesh = Mesh2dTriangle()
|
---|
166 | md.mesh.numberofvertices = ctio_out.numberofpoints
|
---|
167 | md.mesh.numberofelements = ctio_out.numberoftriangles
|
---|
168 | md.mesh.x = points[:,1]
|
---|
169 | md.mesh.y = points[:,2]
|
---|
170 | md.mesh.elements = triangles
|
---|
171 | md.mesh.segments = segments
|
---|
172 |
|
---|
173 | #post processing
|
---|
174 | md.mesh.vertexonboundary = zeros(Bool,md.mesh.numberofvertices)
|
---|
175 | md.mesh.vertexonboundary[md.mesh.segments] .= true
|
---|
176 |
|
---|
177 | return md
|
---|
178 | end#}}}
|
---|