new style concrete problem

This commit is contained in:
Jukka Aho
2016-02-02 22:22:21 +02:00
parent fe98a75cbe
commit 60046942e5
4 changed files with 167 additions and 179 deletions
+71 -75
View File
@@ -6,13 +6,80 @@ abstract StandardBasis
abstract DualBasis
global const BiorthogonalBasis = DualBasis
function DirichletProblem(parent_field_name::ASCIIString, parent_field_dim::Int, dim::Int=1, elements=Element[]; basis=StandardBasis)
return BoundaryProblem{DirichletProblem{basis}}("dirichlet boundary", parent_field_name, parent_field_dim, dim, elements)
type Dirichlet <: AbstractProblem
dual_basis :: Bool
end
function DirichletProblem(problem_name::ASCIIString, parent_field_name::ASCIIString, parent_field_dim::Int, dim::Int=1, elements=Element[]; basis=StandardBasis)
return BoundaryProblem{DirichletProblem{basis}}(problem_name, parent_field_name, parent_field_dim, dim, elements)
function Dirichlet()
Dirichlet(true)
end
function assemble!(assembly::BoundaryAssembly, problem::BoundaryProblem{Dirichlet}, element::Element, time::Real)
@assert problem.properties.dual_basis
# get dimension and name of PARENT field
field_dim = problem.parent_field_dim
field_name = problem.parent_field_name
gdofs = get_gdofs(element, field_dim)
# calculate bi-orthogonal basis transformation matrix Ae
nnodes = size(element, 2)
De = zeros(nnodes, nnodes)
Me = zeros(nnodes, nnodes)
for ip in get_integration_points(element, Val{2})
w = ip.weight
J = get_jacobian(element, ip, time)
JT = transpose(J)
if size(JT, 2) == 1 # plane problem
w *= norm(JT)
else
w *= norm(cross(JT[:,1], JT[:,2]))
end
N = element(ip, time)
De += w*diagm(vec(N))
Me += w*N'*N
end
Ae = De*inv(Me)
# do the actual integration
for ip in get_integration_points(element, Val{2})
w = ip.weight
J = get_jacobian(element, ip, time)
JT = transpose(J)
if size(JT, 2) == 1 # plane problem
w *= norm(JT)
else
w *= norm(cross(JT[:,1], JT[:,2]))
end
N = element(ip, time)
Phi = (Ae*N')'
A = w*Phi'*N
A[abs(A) .< 1.0e-12] = 0
if haskey(element, field_name)
for i=1:field_dim
g = element(field_name, ip, time)
ldofs = gdofs[i:field_dim:end]
add!(assembly.C1, ldofs, ldofs, A)
add!(assembly.C2, ldofs, ldofs, A)
add!(assembly.g, ldofs, w*g*Phi')
end
else
for i=1:field_dim
ldofs = gdofs[i:field_dim:end]
if haskey(element, field_name*" $i")
g = element(field_name*" $i", ip, time)
add!(assembly.C1, ldofs, ldofs, A)
add!(assembly.C2, ldofs, ldofs, A)
add!(assembly.g, ldofs, w*g*Phi')
end
end
end
end
end
function assemble!(assembly::BoundaryAssembly, problem::BoundaryProblem{DirichletProblem}, element::Element, time::Real)
# get dimension and name of PARENT field
@@ -61,74 +128,3 @@ function assemble!(assembly::BoundaryAssembly, problem::BoundaryProblem{Dirichle
end
end
function assemble!(assembly::BoundaryAssembly, problem::BoundaryProblem{DirichletProblem{BiorthogonalBasis}}, element::Element, time::Real)
# get dimension and name of PARENT field
field_dim = problem.parent_field_dim
field_name = problem.parent_field_name
gdofs = get_gdofs(element, field_dim)
# calculate bi-orthogonal basis transformation matrix Ae
nnodes = size(element, 2)
De = zeros(nnodes, nnodes)
Me = zeros(nnodes, nnodes)
for ip in get_integration_points(element, Val{2})
w = ip.weight
J = get_jacobian(element, ip, time)
JT = transpose(J)
if size(JT, 2) == 1 # plane problem
w *= norm(JT)
else
w *= norm(cross(JT[:,1], JT[:,2]))
end
N = element(ip, time)
De += w*diagm(vec(N))
Me += w*N'*N
end
Ae = De*inv(Me)
# do the actual integration
for ip in get_integration_points(element, Val{2})
w = ip.weight
J = get_jacobian(element, ip, time)
JT = transpose(J)
if size(JT, 2) == 1 # plane problem
w *= norm(JT)
else
w *= norm(cross(JT[:,1], JT[:,2]))
end
N = element(ip, time)
Phi = (Ae*N')'
A = w*Phi'*N
A[abs(A) .< 1.0e-9] = 0
# C1 matrix is always the same
# for i=1:field_dim
# ldofs = gdofs[i:field_dim:end]
# add!(assembly.C1, ldofs, ldofs, A)
# end
if haskey(element, field_name)
# add all dimensions at once if defined element["blaa"] = 0.0
for i=1:field_dim
g = element(field_name, ip, time)
ldofs = gdofs[i:field_dim:end]
add!(assembly.C1, ldofs, ldofs, A)
add!(assembly.C2, ldofs, ldofs, A)
add!(assembly.g, ldofs, w*g*Phi')
end
else
for i=1:field_dim
ldofs = gdofs[i:field_dim:end]
if haskey(element, field_name*" $i")
g = element(field_name*" $i", ip, time)
add!(assembly.C1, ldofs, ldofs, A)
add!(assembly.C2, ldofs, ldofs, A)
add!(assembly.g, ldofs, w*g*Phi')
# else
# add!(assembly.D, ldofs, ldofs, A)
end
end
end
end
end