This commit is contained in:
Jukka Aho
2016-06-02 22:58:54 +03:00
parent 07812f3bc7
commit bf9b44e057
9 changed files with 253 additions and 68 deletions
+5 -2
View File
@@ -23,11 +23,11 @@ export AbstractPoint, Point, IntegrationPoint, IP, Node
### ELEMENTS ###
include("elements.jl") # common element routines
export Node, AbstractElement, Element, update!, get_connectivity
export Node, AbstractElement, Element, update!, get_connectivity, get_basis, get_dbasis
include("lagrange_macro.jl") # Continuous Galerkin (Lagrange) elements generated using macro
export Seg2, Seg3, Tri3, Tri6, Quad4, Hex8, Tet4, Tet10
include("nurbs.jl")
export NSeg, NSurf, NSolid
export NSeg, NSurf, NSolid, is_nurbs
#include("hierarchical.jl") # P-elements
#include("mortar_elements.jl") # Mortar elements
@@ -64,6 +64,9 @@ include("solver_utils.jl")
include("solvers.jl")
export Solver
include("optics.jl")
export find_intersection, calc_reflection
### MORTAR STUFF ###
include("mortar.jl") # mortar projection
+2
View File
@@ -46,6 +46,7 @@ function set_debug_off!()
pop!(ENV, "DEBUG");
end
#=
""" Simple linspace extension to arrays.
Examples
@@ -60,6 +61,7 @@ Examples
function linspace{T<:Array}(X1::T, X2::T, n)
[1/2*(1-ti)*X1 + 1/2*(1+ti)*X2 for ti in linspace(-1, 1, n)]
end
=#
function resize!(A::SparseMatrixCSC, m::Int64, n::Int64)
(n == A.n) && (m == A.m) && return
+5 -1
View File
@@ -116,7 +116,11 @@ function update!(element::Element, field_name::ASCIIString, data::Dict)
end
function update!(element::Element, field_name::ASCIIString, data::Union{Real, Vector, Pair})
element[field_name] = data
if haskey(element, field_name)
update!(element[field_name], data)
else
element[field_name] = data
end
end
function update!(elements::Vector, field_name::ASCIIString, data)
+13 -2
View File
@@ -1,3 +1,6 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
""" NURBS segment. """
type NSeg <: AbstractElement
order :: Int
@@ -62,7 +65,7 @@ function get_basis(element::Element{NSeg}, xi::Vector, time)
w = element.properties.weights
nu = length(tu)-pu-1
u = xi[1]
N = [w[j]*NURBS(j,pu,u,tu) for j=1:nu]
N = vec([w[j]*NURBS(j,pu,u,tu) for j=1:nu])'
return N/sum(N)
end
@@ -75,7 +78,7 @@ function get_basis(element::Element{NSurf}, xi::Vector, time)
nu = length(tu)-pu-1
nv = length(tv)-pv-1
u, v = xi
N = [w[i,j]*NURBS(i,pu,u,tu)*NURBS(j,pv,v,tv) for i=1:nu, j=1:nv]
N = vec([w[i,j]*NURBS(i,pu,u,tu)*NURBS(j,pv,v,tv) for i=1:nu, j=1:nv])'
return N / sum(N)
end
@@ -125,3 +128,11 @@ function size(element::Element{NSolid})
return (3, length(element))
end
function is_nurbs(element::Element)
return false
end
function is_nurbs{E<:Union{NSeg, NSurf, NSolid}}(element::Element{E})
return true
end
+124
View File
@@ -0,0 +1,124 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md
function gen_rtic_grid!{S<:Union{Seg2,Seg3}}(thetas, element::Element{S}; npts=2)
xi1 = midpoints(linspace(-1, 1, npts+1))
for xi in xi1
push!(thetas, [0.0, xi])
end
end
function gen_rtic_grid!(thetas, element::Element{NSeg}; npts=2)
knots_u = element.properties.knots
u = midpoints(linspace(minimum(knots_u), maximum(knots_u), npts+1))
for ui in u
push!(thetas, [0.0, ui])
end
end
function gen_rtic_grid!(thetas, element::Element{NSurf}; npts=2)
knots_u = element.properties.knots_u
knots_v = element.properties.knots_v
u = midpoints(linspace(minimum(knots_u), maximum(knots_u), npts+1))
v = midpoints(linspace(minimum(knots_v), maximum(knots_v), npts+1))
for ui in u
for vi in v
push!(thetas, [0.0, ui, vi])
end
end
end
"""
Find intersection between element surface X(ξ) and ray x(t) = s + t*n by
solving equation F(t, ξ) = x(t) - X(ξ) = 0
Returns
-------
t, ξ
References
----------
[1] https://en.wikipedia.org/wiki/Ray_tracing_%28graphics%29
"""
function find_intersection{S<:Union{Seg2, Seg3, NSeg, NSurf}}(element::Element{S}, s, n, time;
max_iterations=10, tolerance=1.0e-12, info_output=false, deformed=true, secondary=false, npts=2)
x = element["geometry"](time)
if deformed && haskey(element, "displacement")
x += element["displacement"](time)
end
function calc_intersection!(theta)
i = 0
dtheta = zeros(theta)
for i=1:max_iterations
t = theta[1]
xi = theta[2:end]
N = get_basis(element, xi, time)
dN = get_dbasis(element, xi, time)
A = [n -dN*x]
r = s + t*n - N*x
try
dtheta = A \ -r
catch err
info("failed to solve equation.")
dump(theta)
dump(A)
dump(r)
throw(err)
end
theta[:] += dtheta
info_output && info("iter $i, theta = $theta, norm(dtheta) = $(norm(dtheta))")
norm(dtheta) < tolerance && return theta
isnan(theta[1]) && break
end
theta[1] = NaN
return theta
# error("didn't converge in $i iterations")
end
thetas = Vector{Float64}[]
gen_rtic_grid!(thetas, element; npts=npts)
map(calc_intersection!, thetas)
filter!(t -> !isnan(t[1]), thetas)
info_output && info("thetas: $thetas")
secondary && filter!(t -> t[1] > 1.0e-12, thetas)
# error("failure finding ray trace, thetas vec is empty")
length(thetas) == 0 && return NaN, [NaN, NaN]
sort!(thetas, alg=MergeSort, lt=(a,b)->a[1]<b[1])
theta = thetas[1]
return theta[1], theta[2:end]
end
"""
References
----------
[1] http://fp.optics.arizona.edu/optomech/Fall13/Notes/6%20Mirror%20matrices.pdf
"""
function calc_reflection{S<:Union{Seg2, Seg3, NSeg}}(element::Element{S}, xi, k, time; deformed=true)
x = element["geometry"](time)
if deformed && haskey(element, "displacement")
x += element["displacement"](time)
end
Q = [0.0 1.0; -1.0 0.0]
dN = get_dbasis(element, xi, time)
n = Q*(dN*x)
n /= norm(n)
k2 = k - 2*vecdot(k, n)*n
return k2
end
function calc_reflection{S<:Union{Quad4, NSurf}}(element::Element{S}, xi, k, time; deformed=true)
x = element["geometry"](time)
if deformed && haskey(element, "displacement")
x += element["displacement"](time)
end
dN = get_dbasis(element, xi, time)
J = transpose(sum([kron(dN[:,i], x[i]') for i=1:length(x)]))
n = cross(J[:,1], J[:,2])
n /= norm(n)
k2 = k - 2*vecdot(k, n)*n
return k2
end