-
Notifications
You must be signed in to change notification settings - Fork 98
/
MultiFieldFEFunctions.jl
85 lines (73 loc) · 3 KB
/
MultiFieldFEFunctions.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
"""
struct MultiFieldFEFunction <: CellField
# private fields
end
"""
struct MultiFieldFEFunction{T<:MultiFieldCellField} <: FEFunction
single_fe_functions::Vector{<:SingleFieldFEFunction}
free_values::AbstractArray
fe_space::MultiFieldFESpace
multi_cell_field::T
function MultiFieldFEFunction(
free_values::AbstractVector,
space::MultiFieldFESpace,
single_fe_functions::Vector{<:SingleFieldFEFunction})
multi_cell_field = MultiFieldCellField(map(i->i.cell_field,single_fe_functions))
T = typeof(multi_cell_field)
new{T}(
single_fe_functions,
free_values,
space,
multi_cell_field)
end
end
CellData.get_data(f::MultiFieldFEFunction) = get_data(f.multi_cell_field)
CellData.get_triangulation(f::MultiFieldFEFunction) = get_triangulation(f.multi_cell_field)
CellData.DomainStyle(::Type{MultiFieldFEFunction{T}}) where T = DomainStyle(T)
FESpaces.get_free_dof_values(f::MultiFieldFEFunction) = f.free_values
FESpaces.get_fe_space(f::MultiFieldFEFunction) = f.fe_space
function FESpaces.get_cell_dof_values(f::MultiFieldFEFunction)
msg = """\n
This method does not make sense for multi-field
since each field can be defined on a different triangulation.
Pass a triangulation in the second argument to get the DOF values
on top of the corresponding cells.
"""
trians = map(get_triangulation,f.fe_space.spaces)
trian = first(trians)
@check all(map(t->is_change_possible(t,trian),trians)) msg
get_cell_dof_values(f,trian)
end
function FESpaces.get_cell_dof_values(f::MultiFieldFEFunction,trian::Triangulation)
uhs = f.single_fe_functions
blockmask = [ is_change_possible(get_triangulation(uh),trian) for uh in uhs ]
active_block_ids = findall(blockmask)
active_block_data = Any[ get_cell_dof_values(uhs[i],trian) for i in active_block_ids ]
nblocks = length(uhs)
lazy_map(BlockMap(nblocks,active_block_ids),active_block_data...)
end
#function FESpaces.get_cell_dof_values(f::MultiFieldFEFunction,trian::SkeletonTriangulation)
# cell_values_plus = get_cell_dof_values(f,trian.plus)
# cell_values_minus = get_cell_dof_values(f,trian.minus)
# lazy_map(BlockMap(2,[1,2]),cell_values_plus,cell_values_minus)
#end
"""
num_fields(m::MultiFieldFEFunction)
"""
num_fields(m::MultiFieldFEFunction) = length(m.single_fe_functions)
Base.iterate(m::MultiFieldFEFunction) = iterate(m.single_fe_functions)
Base.iterate(m::MultiFieldFEFunction,state) = iterate(m.single_fe_functions,state)
Base.getindex(m::MultiFieldFEFunction,field_id::Integer) = m.single_fe_functions[field_id]
Base.length(m::MultiFieldFEFunction) = num_fields(m)
function LinearAlgebra.dot(a::MultiFieldFEFunction,b::MultiFieldFEFunction)
@check num_fields(a) == num_fields(b)
return sum(map(dot,a,b))
end
function LinearAlgebra.dot(a::MultiFieldCellField,b::MultiFieldFEFunction)
@check num_fields(a) == num_fields(b)
return sum(map(dot,a,b))
end
function LinearAlgebra.dot(a::MultiFieldFEFunction,b::MultiFieldCellField)
@check num_fields(a) == num_fields(b)
return sum(map(dot,a,b))
end