|
1 | 1 | struct MultiFieldDistributedFESpace{V} <: DistributedFESpace{V}
|
2 |
| - vector_type :: Type{V} |
3 |
| - distributed_spaces :: Vector{<:DistributedFESpace} |
4 |
| - spaces :: DistributedData{<:MultiFieldFESpace} |
5 |
| - gids :: DistributedIndexSet |
6 |
| - end |
| 2 | + vector_type::Type{V} |
| 3 | + distributed_spaces::Vector{<:DistributedFESpace} |
| 4 | + spaces::DistributedData{<:MultiFieldFESpace} |
| 5 | + gids::DistributedIndexSet |
| 6 | +end |
7 | 7 |
|
8 |
| - function Gridap.MultiFieldFESpace(test_space::MultiFieldDistributedFESpace{V}, |
| 8 | +function Gridap.MultiFieldFESpace(test_space::MultiFieldDistributedFESpace{V}, |
9 | 9 | trial_spaces::Vector{<:DistributedFESpace{V}}) where V
|
10 |
| - spaces = DistributedData(trial_spaces...) do part, spaces_and_gids... |
11 |
| - MultiFieldFESpace([s[1] for s in spaces_and_gids]) |
12 |
| - end |
13 |
| - MultiFieldDistributedFESpace(V,trial_spaces,spaces,test_space.gids) |
14 |
| - end |
| 10 | + spaces = DistributedData(trial_spaces...) do part, spaces_and_gids... |
| 11 | + MultiFieldFESpace([s[1] for s in spaces_and_gids]) |
| 12 | + end |
| 13 | + MultiFieldDistributedFESpace(V, trial_spaces, spaces, test_space.gids) |
| 14 | +end |
15 | 15 |
|
16 | 16 |
|
17 |
| -function Gridap.FESpaces.FEFunction(dV::MultiFieldDistributedFESpace{T},x) where {T} |
18 |
| - _gen_multifield_distributed_fe_function(dV,x,FEFunction) |
| 17 | +function Gridap.FESpaces.FEFunction(dV::MultiFieldDistributedFESpace{T}, x) where {T} |
| 18 | + _gen_multifield_distributed_fe_function(dV, x, FEFunction) |
19 | 19 | end
|
20 | 20 |
|
21 | 21 |
|
22 |
| -function _gen_multifield_distributed_fe_function(dV::MultiFieldDistributedFESpace{T},x,f) where {T} |
23 |
| - single_fe_functions = DistributedFEFunction{T}[] |
24 |
| - for (field, U) in enumerate(dV.distributed_spaces) |
25 |
| - free_values_i = restrict_to_field(dV,x,field) |
26 |
| - uhi = f(U,free_values_i) |
27 |
| - push!(single_fe_functions,uhi) |
28 |
| - end |
| 22 | +function _gen_multifield_distributed_fe_function(dV::MultiFieldDistributedFESpace{T}, x, f) where {T} |
| 23 | + single_fe_functions = DistributedFEFunction{T}[] |
| 24 | + for (field, U) in enumerate(dV.distributed_spaces) |
| 25 | + free_values_i = restrict_to_field(dV, x, field) |
| 26 | + uhi = f(U, free_values_i) |
| 27 | + push!(single_fe_functions, uhi) |
| 28 | + end |
29 | 29 |
|
30 |
| - funs = DistributedData(get_comm(dV.distributed_spaces[1]), |
| 30 | + funs = DistributedData(get_comm(dV.distributed_spaces[1]), |
31 | 31 | dV.spaces, single_fe_functions...,) do part, V, fe_functions...
|
32 |
| - mfv=zero_free_values(V) |
33 |
| - current=1 |
34 |
| - for fun in fe_functions |
35 |
| - fv = get_free_values(fun) |
36 |
| - for i=1:length(fv) |
37 |
| - mfv[current]=fv[i] |
38 |
| - current=current+1 |
| 32 | + mfv = zero_free_values(V) |
| 33 | + current = 1 |
| 34 | + for fun in fe_functions |
| 35 | + fv = get_free_values(fun) |
| 36 | + for i = 1:length(fv) |
| 37 | + mfv[current] = fv[i] |
| 38 | + current = current + 1 |
| 39 | + end |
39 | 40 | end
|
40 |
| - end |
41 |
| - f(V,mfv) |
42 |
| - end |
43 |
| - multifield_fe_function=DistributedFEFunction(funs,x,dV) |
44 |
| - MultiFieldDistributedFEFunction{T}(single_fe_functions, |
| 41 | + f(V, mfv) |
| 42 | + end |
| 43 | + multifield_fe_function = DistributedFEFunction(funs, x, dV) |
| 44 | + MultiFieldDistributedFEFunction{T}(single_fe_functions, |
45 | 45 | multifield_fe_function,
|
46 | 46 | dV)
|
47 | 47 | end
|
48 | 48 |
|
49 | 49 |
|
50 |
| -function restrict_to_field(dV::MultiFieldDistributedFESpace,x::Vector,field) |
51 |
| - @assert isa(dV.gids,SequentialDistributedIndexSet) |
52 |
| - ngids = dV.distributed_spaces[field].gids.ngids |
53 |
| - xi = Vector{eltype(x)}(undef,ngids) |
54 |
| - do_on_parts(dV.spaces,dV.gids,xi,x,dV.distributed_spaces...) do part, mfspace, mfgids, xi, x,fspaces_and_gids... |
55 |
| - offset=0 |
56 |
| - for i=1:field-1 |
57 |
| - fspace = fspaces_and_gids[i][1] |
58 |
| - offset = offset + num_free_dofs(fspace) |
| 50 | +function restrict_to_field(dV::MultiFieldDistributedFESpace, x::Vector, field) |
| 51 | + @assert isa(dV.gids, SequentialDistributedIndexSet) |
| 52 | + |
| 53 | + xi = Gridap.Algebra.allocate_vector(Vector{eltype(x)}, |
| 54 | + dV.distributed_spaces[field].gids) |
| 55 | + |
| 56 | + do_on_parts(dV.spaces, dV.gids, xi, x, dV.distributed_spaces...) do part, mfspace, mfgids, xi, x, fspaces_and_gids... |
| 57 | + offset = 0 |
| 58 | + for i = 1:field - 1 |
| 59 | + fspace = fspaces_and_gids[i][1] |
| 60 | + offset = offset + num_free_dofs(fspace) |
| 61 | + end |
| 62 | + fspace = fspaces_and_gids[field][1] |
| 63 | + fgids = fspaces_and_gids[field][2] |
| 64 | + for i = 1:num_free_dofs(fspace) |
| 65 | + if fgids.lid_to_owner[i] == part |
| 66 | + xi[fgids.lid_to_gid[i]] = x[mfgids.lid_to_gid[offset + i]] |
| 67 | + end |
| 68 | + end |
59 | 69 | end
|
60 |
| - fspace = fspaces_and_gids[field][1] |
61 |
| - fgids = fspaces_and_gids[field][2] |
62 |
| - for i=1:num_free_dofs(fspace) |
63 |
| - if fgids.lid_to_owner[i] == part |
64 |
| - xi[fgids.lid_to_gid[i]]=x[mfgids.lid_to_gid[offset+i]] |
65 |
| - end |
| 70 | + xi |
| 71 | +end |
| 72 | + |
| 73 | +function restrict_to_field(dV::MultiFieldDistributedFESpace, x::PETSc.Vec{Float64}, field) |
| 74 | + fgids = dV.distributed_spaces[field].gids |
| 75 | + mfgids = dV.gids |
| 76 | + @assert isa(fgids, MPIPETScDistributedIndexSet) |
| 77 | + |
| 78 | + xi = Gridap.Algebra.allocate_vector(PETSc.Vec{Float64}, |
| 79 | + dV.distributed_spaces[field].gids) |
| 80 | + |
| 81 | + comm = get_comm(fgids) |
| 82 | + part = get_part(comm) |
| 83 | + |
| 84 | + fis_gids = [ PETSc.PetscInt(fgids.lid_to_gid_petsc[i] - 1) |
| 85 | + for i = 1:length(fgids.lid_to_gid_petsc) |
| 86 | + if fgids.parts.part.lid_to_owner[i] == part ] |
| 87 | + |
| 88 | + mfis_gids = Vector{PETSc.PetscInt}(undef,length(fis_gids)) |
| 89 | + |
| 90 | + do_on_parts(dV.gids, dV.distributed_spaces...) do part, lmfgids, fspaces_and_gids... |
| 91 | + offset = 0 |
| 92 | + for i = 1:field - 1 |
| 93 | + fspace = fspaces_and_gids[i][1] |
| 94 | + offset = offset + num_free_dofs(fspace) |
| 95 | + end |
| 96 | + fspace = fspaces_and_gids[field][1] |
| 97 | + current=1 |
| 98 | + for i = 1:num_free_dofs(fspace) |
| 99 | + if lmfgids.lid_to_owner[offset+i] == part |
| 100 | + mfis_gids[current]=mfgids.lid_to_gid_petsc[offset+i]-1 |
| 101 | + current=current+1 |
| 102 | + end |
| 103 | + end |
66 | 104 | end
|
67 |
| - end |
68 |
| - xi |
| 105 | + |
| 106 | + fis = PETSc.IS_(Float64, fis_gids; comm=comm.comm) |
| 107 | + mfis = PETSc.IS_(Float64, mfis_gids; comm=comm.comm) |
| 108 | + |
| 109 | + vscatter = PETSc.VecScatter(x, mfis, xi, fis) |
| 110 | + scatter!(vscatter,x,xi) |
| 111 | + xi |
69 | 112 | end
|
70 | 113 |
|
71 |
| -function Gridap.FESpaces.EvaluationFunction(dV::MultiFieldDistributedFESpace,x) |
72 |
| - _gen_multifield_distributed_fe_function(dV,x,EvaluationFEFunction) |
| 114 | + |
| 115 | + |
| 116 | +function Gridap.FESpaces.EvaluationFunction(dV::MultiFieldDistributedFESpace, x) |
| 117 | + _gen_multifield_distributed_fe_function(dV, x, EvaluationFEFunction) |
73 | 118 | end
|
74 | 119 |
|
75 | 120 |
|
76 | 121 | function Gridap.MultiFieldFESpace(model::DistributedDiscreteModel,
|
77 | 122 | distributed_spaces::Vector{<:DistributedFESpace{V}}) where V
|
78 | 123 |
|
79 |
| - spaces = DistributedData(distributed_spaces...) do part, spaces_and_gids... |
80 |
| - MultiFieldFESpace([s[1] for s in spaces_and_gids]) |
81 |
| - end |
82 |
| - |
83 |
| - function init_lid_to_owner(part,lspace,spaces_and_gids...) |
84 |
| - nlids = num_free_dofs(lspace) |
85 |
| - lid_to_owner = zeros(Int,nlids) |
86 |
| - current_lid = 1 |
87 |
| - for current_field_space_gids in spaces_and_gids |
88 |
| - gids = current_field_space_gids[2] |
89 |
| - for i=1:length(gids.lid_to_owner) |
90 |
| - lid_to_owner[current_lid]=gids.lid_to_owner[i] |
91 |
| - current_lid += 1 |
92 |
| - end |
| 124 | + spaces = DistributedData(distributed_spaces...) do part, spaces_and_gids... |
| 125 | + MultiFieldFESpace([s[1] for s in spaces_and_gids]) |
| 126 | + end |
| 127 | + |
| 128 | + function init_lid_to_owner(part, lspace, spaces_and_gids...) |
| 129 | + nlids = num_free_dofs(lspace) |
| 130 | + lid_to_owner = zeros(Int, nlids) |
| 131 | + current_lid = 1 |
| 132 | + for current_field_space_gids in spaces_and_gids |
| 133 | + gids = current_field_space_gids[2] |
| 134 | + for i = 1:length(gids.lid_to_owner) |
| 135 | + lid_to_owner[current_lid] = gids.lid_to_owner[i] |
| 136 | + current_lid += 1 |
| 137 | + end |
| 138 | + end |
| 139 | + lid_to_owner |
93 | 140 | end
|
94 |
| - lid_to_owner |
95 |
| - end |
96 | 141 |
|
97 |
| - comm = get_comm(model) |
| 142 | + comm = get_comm(model) |
98 | 143 |
|
99 |
| - part_to_lid_to_owner = DistributedData{Vector{Int}}(init_lid_to_owner, |
| 144 | + part_to_lid_to_owner = DistributedData{Vector{Int}}(init_lid_to_owner, |
100 | 145 | comm,
|
101 | 146 | spaces,
|
102 | 147 | distributed_spaces...)
|
103 | 148 |
|
104 |
| - offsets, ngids = _compute_offsets_and_ngids(part_to_lid_to_owner) |
| 149 | + offsets, ngids = _compute_offsets_and_ngids(part_to_lid_to_owner) |
105 | 150 |
|
106 |
| - num_dofs_x_cell = compute_num_dofs_x_cell(comm,spaces) |
| 151 | + num_dofs_x_cell = compute_num_dofs_x_cell(comm, spaces) |
107 | 152 |
|
108 |
| - part_to_lid_to_gid = _compute_part_to_lid_to_gid(model, |
| 153 | + part_to_lid_to_gid = _compute_part_to_lid_to_gid(model, |
109 | 154 | spaces,
|
110 | 155 | num_dofs_x_cell,
|
111 | 156 | part_to_lid_to_owner,
|
112 | 157 | offsets)
|
113 | 158 |
|
114 |
| - function init_free_gids(part, lid_to_gid, lid_to_owner, ngids) |
115 |
| - IndexSet(ngids, lid_to_gid, lid_to_owner) |
116 |
| - end |
| 159 | + function init_free_gids(part, lid_to_gid, lid_to_owner, ngids) |
| 160 | + IndexSet(ngids, lid_to_gid, lid_to_owner) |
| 161 | + end |
117 | 162 |
|
118 |
| - gids = DistributedIndexSet(init_free_gids, |
| 163 | + gids = DistributedIndexSet(init_free_gids, |
119 | 164 | comm,
|
120 | 165 | ngids,
|
121 | 166 | part_to_lid_to_gid,
|
122 | 167 | part_to_lid_to_owner,
|
123 | 168 | ngids)
|
124 | 169 |
|
125 |
| - MultiFieldDistributedFESpace(V, |
| 170 | + MultiFieldDistributedFESpace(V, |
126 | 171 | distributed_spaces,
|
127 | 172 | spaces,
|
128 | 173 | gids)
|
129 | 174 | end
|
130 | 175 |
|
131 | 176 | # FE Function
|
132 | 177 | struct MultiFieldDistributedFEFunction{T}
|
133 |
| - single_fe_functions :: Vector{DistributedFEFunction{T}} |
134 |
| - multifield_fe_function :: DistributedFEFunction{T} |
135 |
| - space :: MultiFieldDistributedFESpace{T} |
| 178 | + single_fe_functions::Vector{DistributedFEFunction{T}} |
| 179 | + multifield_fe_function::DistributedFEFunction{T} |
| 180 | + space::MultiFieldDistributedFESpace{T} |
136 | 181 | end
|
137 | 182 |
|
138 | 183 | Gridap.FESpaces.FEFunctionStyle(::Type{MultiFieldDistributedFEFunction}) = Val{true}()
|
|
0 commit comments