1
+
2
+ # It is defined here just to avoid syntax errors below
3
+ # To be REMOVED in the future
4
+ struct VoidDistributedFESpace{A} <: Gridap.GridapType
5
+ parts:: A
6
+ end
7
+
8
+ # It is defined here just to avoid syntax errors below
9
+ # To be REMOVED in the future
10
+ function change_parts (x:: Union{MPIArray,Nothing} , new_parts; default= nothing )
11
+ x_new = map (new_parts) do _p
12
+ if isa (x,MPIArray)
13
+ PartitionedArrays. getany (x)
14
+ else
15
+ default
16
+ end
17
+ end
18
+ return x_new
19
+ end
20
+
21
+ # It is defined here just to avoid syntax errors below
22
+ # To be REMOVED in the future
23
+ function change_parts (:: Type{<:GridapDistributed.DistributedCellField} ,x,new_parts)
24
+ if isa (x,GridapDistributed. DistributedCellField)
25
+ fields = change_parts (local_views (x),new_parts)
26
+ else
27
+ fields = change_parts (nothing ,new_parts;default= void (CellField))
28
+ end
29
+ return GridapDistributed. DistributedCellField (fields)
30
+ end
31
+
32
+ function _allocate_cell_wise_dofs (cell_to_ldofs)
33
+ map (cell_to_ldofs) do cell_to_ldofs
34
+ cache = array_cache (cell_to_ldofs)
35
+ ncells = length (cell_to_ldofs)
36
+ ptrs = Vector {Int32} (undef,ncells+ 1 )
37
+ for cell in 1 : ncells
38
+ ldofs = getindex! (cache,cell_to_ldofs,cell)
39
+ ptrs[cell+ 1 ] = length (ldofs)
40
+ end
41
+ PartitionedArrays. length_to_ptrs! (ptrs)
42
+ ndata = ptrs[end ]- 1
43
+ data = Vector {Float64} (undef,ndata)
44
+ PartitionedArrays. JaggedArray (data,ptrs)
45
+ end
46
+ end
47
+
48
+ function _update_cell_dof_values_with_local_info! (cell_dof_values_new,
49
+ cell_dof_values_old,
50
+ new2old)
51
+ map (cell_dof_values_new,
52
+ cell_dof_values_old,
53
+ new2old) do cell_dof_values_new,cell_dof_values_old,new2old
54
+ ocache = array_cache (cell_dof_values_old)
55
+ for (ncell,ocell) in enumerate (new2old)
56
+ if ocell!= 0
57
+ # Copy ocell to ncell
58
+ oentry = getindex! (ocache,cell_dof_values_old,ocell)
59
+ range = cell_dof_values_new. ptrs[ncell]: cell_dof_values_new. ptrs[ncell+ 1 ]- 1
60
+ cell_dof_values_new. data[range] .= oentry
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ function _allocate_comm_data (num_dofs_x_cell,lids)
67
+ map (num_dofs_x_cell,lids) do num_dofs_x_cell,lids
68
+ n = length (lids)
69
+ ptrs = Vector {Int32} (undef,n+ 1 )
70
+ ptrs.= 0
71
+ for i = 1 : n
72
+ for j = lids. ptrs[i]: lids. ptrs[i+ 1 ]- 1
73
+ ptrs[i+ 1 ] = ptrs[i+ 1 ] + num_dofs_x_cell. data[j]
74
+ end
75
+ end
76
+ PartitionedArrays. length_to_ptrs! (ptrs)
77
+ ndata = ptrs[end ]- 1
78
+ data = Vector {Float64} (undef,ndata)
79
+ PartitionedArrays. JaggedArray (data,ptrs)
80
+ end
81
+ end
82
+
83
+ function _pack_snd_data! (snd_data,cell_dof_values,snd_lids)
84
+ map (snd_data,cell_dof_values,snd_lids) do snd_data,cell_dof_values,snd_lids
85
+ cache = array_cache (cell_dof_values)
86
+ s = 1
87
+ for i = 1 : length (snd_lids)
88
+ for j = snd_lids. ptrs[i]: snd_lids. ptrs[i+ 1 ]- 1
89
+ cell = snd_lids. data[j]
90
+ ldofs = getindex! (cache,cell_dof_values,cell)
91
+
92
+ e = s+ length (ldofs)- 1
93
+ range = s: e
94
+ snd_data. data[range] .= ldofs
95
+ s = e+ 1
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ function _unpack_rcv_data! (cell_dof_values,rcv_data,rcv_lids)
102
+ map (cell_dof_values,rcv_data,rcv_lids) do cell_dof_values,rcv_data,rcv_lids
103
+ s = 1
104
+ for i = 1 : length (rcv_lids. ptrs)- 1
105
+ for j = rcv_lids. ptrs[i]: rcv_lids. ptrs[i+ 1 ]- 1
106
+ cell = rcv_lids. data[j]
107
+ range_cell_dof_values = cell_dof_values. ptrs[cell]: cell_dof_values. ptrs[cell+ 1 ]- 1
108
+
109
+ e = s+ length (range_cell_dof_values)- 1
110
+ range_rcv_data = s: e
111
+ cell_dof_values. data[range_cell_dof_values] .= rcv_data. data[range_rcv_data]
112
+ s = e+ 1
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ function get_glue_components (glue:: GridapDistributed.RedistributeGlue ,reverse:: Val{false} )
119
+ return glue. lids_rcv, glue. lids_snd, glue. parts_rcv, glue. parts_snd, glue. new2old
120
+ end
121
+
122
+ function get_glue_components (glue:: GridapDistributed.RedistributeGlue ,reverse:: Val{true} )
123
+ return glue. lids_snd, glue. lids_rcv, glue. parts_snd, glue. parts_rcv, glue. old2new
124
+ end
125
+
126
+ function _num_dofs_x_cell (cell_dofs_array,lids)
127
+ map (cell_dofs_array,lids) do cell_dofs_array, lids
128
+ data = [length (cell_dofs_array[i]) for i = 1 : length (cell_dofs_array) ]
129
+ PartitionedArrays. JaggedArray (data,lids. ptrs)
130
+ end
131
+ end
132
+
133
+ function get_redistribute_cell_dofs_cache (cell_dof_values_old,
134
+ cell_dof_ids_new,
135
+ model_new,
136
+ glue:: GridapDistributed.RedistributeGlue ;
137
+ reverse= false )
138
+
139
+ lids_rcv, lids_snd, parts_rcv, parts_snd, new2old = get_glue_components (glue,Val (reverse))
140
+
141
+ cell_dof_values_old = change_parts (cell_dof_values_old,get_parts (glue);default= [])
142
+ cell_dof_ids_new = change_parts (cell_dof_ids_new,get_parts (glue);default= [[]])
143
+
144
+ num_dofs_x_cell_snd = _num_dofs_x_cell (cell_dof_values_old, lids_snd)
145
+ num_dofs_x_cell_rcv = _num_dofs_x_cell (cell_dof_ids_new, lids_rcv)
146
+ snd_data = _allocate_comm_data (num_dofs_x_cell_snd, lids_snd)
147
+ rcv_data = _allocate_comm_data (num_dofs_x_cell_rcv, lids_rcv)
148
+
149
+ cell_dof_values_new = _allocate_cell_wise_dofs (cell_dof_ids_new)
150
+
151
+ caches = snd_data, rcv_data, cell_dof_values_new
152
+ return caches
153
+ end
154
+
155
+ function redistribute_cell_dofs (cell_dof_values_old,
156
+ cell_dof_ids_new,
157
+ model_new,
158
+ glue:: GridapDistributed.RedistributeGlue ;
159
+ reverse= false )
160
+ caches = get_redistribute_cell_dofs_cache (cell_dof_values_old,cell_dof_ids_new,model_new,glue;reverse= reverse)
161
+ return redistribute_cell_dofs! (caches,cell_dof_values_old,cell_dof_ids_new,model_new,glue;reverse= reverse)
162
+ end
163
+
164
+ function redistribute_cell_dofs! (caches,
165
+ cell_dof_values_old,
166
+ cell_dof_ids_new,
167
+ model_new,
168
+ glue:: GridapDistributed.RedistributeGlue ;
169
+ reverse= false )
170
+
171
+ snd_data, rcv_data, cell_dof_values_new = caches
172
+ lids_rcv, lids_snd, parts_rcv, parts_snd, new2old = get_glue_components (glue,Val (reverse))
173
+
174
+ cell_dof_values_old = change_parts (cell_dof_values_old,get_parts (glue);default= [])
175
+ cell_dof_ids_new = change_parts (cell_dof_ids_new,get_parts (glue);default= [[]])
176
+
177
+ _pack_snd_data! (snd_data,cell_dof_values_old,lids_snd)
178
+
179
+ graph= ExchangeGraph (parts_snd,parts_rcv)
180
+ t= exchange! (rcv_data,snd_data,graph)
181
+
182
+ # We have to build the owned part of "cell_dof_values_new" out of
183
+ # 1. cell_dof_values_old (for those cells s.t. new2old[:]!=0)
184
+ # 2. cell_dof_values_new_rcv (for those cells s.t. new2old[:]=0)
185
+ _update_cell_dof_values_with_local_info! (cell_dof_values_new,
186
+ cell_dof_values_old,
187
+ new2old)
188
+
189
+ wait (t)
190
+
191
+ _unpack_rcv_data! (cell_dof_values_new,rcv_data,lids_rcv)
192
+
193
+ # Now that every part knows it's new owned dofs, exchange ghosts
194
+ new_parts = model_new. parts
195
+ cell_dof_values_new = change_parts (cell_dof_values_new,new_parts)
196
+ if i_am_in (new_parts)
197
+ cache = fetch_vector_ghost_values_cache (cell_dof_values_new,
198
+ partition (get_cell_gids (model_new)))
199
+ fetch_vector_ghost_values! (cell_dof_values_new,cache) |> wait
200
+ end
201
+ return cell_dof_values_new
202
+ end
203
+
204
+ function get_redistribute_free_values_cache (fv_new:: Union{PVector,Nothing} ,
205
+ Uh_new:: Union{GridapDistributed.DistributedSingleFieldFESpace,VoidDistributedFESpace} ,
206
+ fv_old:: Union{PVector,Nothing} ,
207
+ dv_old:: Union{AbstractArray,Nothing} ,
208
+ Uh_old:: Union{GridapDistributed.DistributedSingleFieldFESpace,VoidDistributedFESpace} ,
209
+ model_new,
210
+ glue:: GridapDistributed.RedistributeGlue ;
211
+ reverse= false )
212
+ cell_dof_values_old = ! isa (fv_old,Nothing) ? map (scatter_free_and_dirichlet_values,local_views (Uh_old),local_views (fv_old),dv_old) : nothing
213
+ cell_dof_ids_new = ! isa (fv_new,Nothing) ? map (get_cell_dof_ids, local_views (Uh_new)) : nothing
214
+ caches = get_redistribute_cell_dofs_cache (cell_dof_values_old,cell_dof_ids_new,model_new,glue;reverse= reverse)
215
+
216
+ return caches
217
+ end
218
+
219
+ function redistribute_free_values! (fv_new:: Union{PVector,Nothing} ,
220
+ Uh_new:: Union{GridapDistributed.DistributedSingleFieldFESpace,VoidDistributedFESpace} ,
221
+ fv_old:: Union{PVector,Nothing} ,
222
+ dv_old:: Union{AbstractArray,Nothing} ,
223
+ Uh_old:: Union{GridapDistributed.DistributedSingleFieldFESpace,VoidDistributedFESpace} ,
224
+ model_new,
225
+ glue:: GridapDistributed.RedistributeGlue ;
226
+ reverse= false )
227
+
228
+ caches = get_redistribute_free_values_cache (fv_new,Uh_new,fv_old,dv_old,Uh_old,model_new,glue;reverse= reverse)
229
+ return redistribute_free_values! (caches,fv_new,Uh_new,fv_old,dv_old,Uh_old,model_new,glue;reverse= reverse)
230
+ end
231
+
232
+ function redistribute_free_values! (caches,
233
+ fv_new:: Union{PVector,Nothing} ,
234
+ Uh_new:: Union{GridapDistributed.DistributedSingleFieldFESpace,VoidDistributedFESpace} ,
235
+ fv_old:: Union{PVector,Nothing} ,
236
+ dv_old:: Union{AbstractArray,Nothing} ,
237
+ Uh_old:: Union{GridapDistributed.DistributedSingleFieldFESpace,VoidDistributedFESpace} ,
238
+ model_new,
239
+ glue:: GridapDistributed.RedistributeGlue ;
240
+ reverse= false )
241
+
242
+ cell_dof_values_old = ! isa (fv_old,Nothing) ? map (scatter_free_and_dirichlet_values,local_views (Uh_old),local_views (fv_old),dv_old) : nothing
243
+ cell_dof_ids_new = ! isa (fv_new,Nothing) ? map (get_cell_dof_ids, local_views (Uh_new)) : nothing
244
+ cell_dof_values_new = redistribute_cell_dofs! (caches,cell_dof_values_old,cell_dof_ids_new,model_new,glue;reverse= reverse)
245
+
246
+ # Gather the new free dofs
247
+ if ! isa (fv_new,Nothing)
248
+ Gridap. FESpaces. gather_free_values! (fv_new,Uh_new,cell_dof_values_new)
249
+ end
250
+ return fv_new
251
+ end
252
+
253
+ function redistribute_fe_function (uh_old:: Union{GridapDistributed.DistributedSingleFieldFEFunction,Nothing} ,
254
+ Uh_new:: Union{GridapDistributed.DistributedSingleFieldFESpace,VoidDistributedFESpace} ,
255
+ model_new,
256
+ glue:: GridapDistributed.RedistributeGlue ;
257
+ reverse= false )
258
+
259
+ cell_dof_values_old = ! isa (uh_old,Nothing) ? map (get_cell_dof_values,local_views (uh_old)) : nothing
260
+ cell_dof_ids_new = ! isa (Uh_new,VoidDistributedFESpace) ? map (get_cell_dof_ids,local_views (Uh_new)) : nothing
261
+
262
+ map (cell_dof_values_old,partition (Uh_new. gids)) do cell_dof_values_old, indices
263
+ print (" [$(part_id (indices)) ]: $(cell_dof_values_old) " ); print (" \n " )
264
+ end
265
+
266
+ cell_dof_values_new = redistribute_cell_dofs (cell_dof_values_old,cell_dof_ids_new,model_new,glue;reverse= reverse)
267
+
268
+ map (cell_dof_values_new,partition (Uh_new. gids)) do cell_dof_values_new, indices
269
+ print (" [$(part_id (indices)) ]: $(cell_dof_values_new) " ); print (" \n " )
270
+ end
271
+
272
+ # Assemble the new FEFunction
273
+ if i_am_in (get_parts (Uh_new))
274
+ free_values, dirichlet_values = Gridap. FESpaces. gather_free_and_dirichlet_values (Uh_new,cell_dof_values_new)
275
+ free_values = PVector (free_values,partition (Uh_new. gids))
276
+ uh_new = FEFunction (Uh_new,free_values,dirichlet_values)
277
+ return uh_new
278
+ else
279
+ return nothing
280
+ end
281
+ end
282
+
283
+ function Gridap. FESpaces. gather_free_and_dirichlet_values (f:: GridapDistributed.DistributedFESpace ,cv)
284
+ free_values, dirichlet_values = map (local_views (f),cv) do f, cv
285
+ Gridap. FESpaces. gather_free_and_dirichlet_values (f,cv)
286
+ end |> tuple_of_arrays
287
+ return free_values, dirichlet_values
288
+ end
0 commit comments