1
1
# This provides various transformations (GeoData <=> Cartesian; UTMData <=> Cartesian)
2
2
#
3
3
4
- export project_CartData
4
+ export project_CartData, project_FEData_CartData
5
+
5
6
6
7
7
8
"""
@@ -99,4 +100,96 @@ function project_CartData(d_cart::CartData, d::UTMData, p::ProjectionPoint)
99
100
end
100
101
101
102
return d_cart
102
- end
103
+ end
104
+
105
+
106
+
107
+ """
108
+ inside = point_in_tetrahedron(p::_T, a::_T, b::_T, c::_T, d::_T, tol=1e-10)
109
+ Determines if a point `p` is inside a tetrahedron specified by `a`,`b`,`c`,`d` or not
110
+ """
111
+ function point_in_tetrahedron (p:: _T , a:: _T , b:: _T , c:: _T , d:: _T , tol= 1e-10 ) where _T<: Vector{Float64}
112
+
113
+ # check bounding box
114
+ xmin = min (a[1 ],b[1 ],c[1 ],d[1 ])
115
+ xmax = max (a[1 ],b[1 ],c[1 ],d[1 ])
116
+ ymin = min (a[2 ],b[2 ],c[2 ],d[2 ])
117
+ ymax = max (a[2 ],b[2 ],c[2 ],d[2 ])
118
+ zmin = min (a[3 ],b[3 ],c[3 ],d[3 ])
119
+ zmax = max (a[3 ],b[3 ],c[3 ],d[3 ])
120
+
121
+ inside = true
122
+ if p[1 ] < xmin || p[1 ] > xmax
123
+ inside = false
124
+ end
125
+ if (p[2 ] < ymin || p[2 ] > ymax) && inside
126
+ inside = false
127
+ end
128
+ if (p[3 ] < zmin || p[3 ] > zmax) && inside
129
+ inside = false
130
+ end
131
+
132
+ if inside
133
+ v0 = @SVector [d[i] - a[i] for i in 1 : 3 ]
134
+ v1 = @SVector [b[i] - a[i] for i in 1 : 3 ]
135
+ v2 = @SVector [c[i] - a[i] for i in 1 : 3 ]
136
+ v3 = @SVector [p[i] - a[i] for i in 1 : 3 ]
137
+
138
+ denom = dot (v0, cross (v1, v2))
139
+
140
+ u = dot (v3, cross (v1, v2)) / denom
141
+ v = dot (v0, cross (v3, v2)) / denom
142
+ w = dot (v0, cross (v1, v3)) / denom
143
+
144
+ inside = (u >= - tol) && (v >= - tol) && (w >= - tol) && (u + v + w <= 1 + tol)
145
+ end
146
+
147
+ return inside
148
+ end
149
+
150
+ """
151
+ data_cart = project_FEData_CartData(data_cart::CartData, data_fe::FEData)
152
+
153
+ Projects a FEData object with tetrahedrons (e.g., from Gmsh) to a Cartesian grid
154
+ """
155
+ function project_FEData_CartData (data_cart:: CartData , data_fe:: FEData )
156
+
157
+ cellfields_regions = data_fe. cellfields. regions
158
+ regions = zeros (Int64, size (data_cart. x. val))
159
+
160
+ for i = 1 : size (data_fe. connectivity,2 ) # loop over tetrahedrons
161
+ tetra = data_fe. connectivity[:,i]
162
+
163
+ a = data_fe. vertices[:,tetra[1 ]]
164
+ b = data_fe. vertices[:,tetra[2 ]]
165
+ c = data_fe. vertices[:,tetra[3 ]]
166
+ d = data_fe. vertices[:,tetra[4 ]]
167
+
168
+ xmin = min (a[1 ],b[1 ],c[1 ],d[1 ])
169
+ xmax = max (a[1 ],b[1 ],c[1 ],d[1 ])
170
+ ymin = min (a[2 ],b[2 ],c[2 ],d[2 ])
171
+ ymax = max (a[2 ],b[2 ],c[2 ],d[2 ])
172
+ zmin = min (a[3 ],b[3 ],c[3 ],d[3 ])
173
+ zmax = max (a[3 ],b[3 ],c[3 ],d[3 ])
174
+
175
+ ind = findall ( data_cart. x. val .>= xmin .&& data_cart. x. val .<= xmax .&&
176
+ data_cart. y. val .>= ymin .&& data_cart. y. val .<= ymax .&&
177
+ data_cart. z. val .>= zmin .&& data_cart. z. val .<= zmax);
178
+
179
+ for I in ind
180
+ x = data_cart. x. val[I]
181
+ y = data_cart. y. val[I]
182
+ z = data_cart. z. val[I]
183
+ p = [x,y,z]
184
+ if point_in_tetrahedron (p,a,b,c,d)
185
+ regions[I] = cellfields_regions[i]
186
+ end
187
+ end
188
+
189
+ end
190
+
191
+ return addfield (data_cart, (regions= regions,))
192
+ end
193
+
194
+
195
+
0 commit comments