@@ -3,6 +3,8 @@ using GridapEmbedded
3
3
using FillArrays
4
4
using LinearAlgebra
5
5
6
+ include (" BulkGhostPenaltyAssembleMaps.jl" )
7
+
6
8
# Manufactured solution
7
9
order = 1
8
10
uex (x) = x[1 ]^ order + x[2 ]^ order
@@ -235,80 +237,15 @@ for (i,cells) in enumerate(aggregate_to_local_cells)
235
237
end
236
238
end
237
239
238
- # TO-DO: Better name?
239
- struct AssembleLhsMap{A} <: Gridap.Fields.Map
240
- agg_cells_lhs_contribs:: A
241
- end
242
-
243
- function _get_rank (:: Type{Array{T,N}} ) where {T,N}
244
- N
245
- end
246
-
247
- function Gridap. Fields. return_cache (m:: AssembleLhsMap ,cells)
248
- cache_unassembled_lhs= array_cache (m. agg_cells_lhs_contribs)
249
- T= eltype (m. agg_cells_lhs_contribs)
250
- evaluate_result= Gridap. Arrays. CachedArray (eltype (T),_get_rank (T))
251
- cache_unassembled_lhs,evaluate_result
252
- end
253
-
254
- function Gridap. Fields. evaluate! (cache,m:: AssembleLhsMap ,cells)
255
- cache_unassembled_lhs,result= cache
256
- contrib = getindex! (cache_unassembled_lhs,m. agg_cells_lhs_contribs,1 )
257
-
258
- Gridap. Arrays. setsize! (result,size (contrib))
259
- result. array .= 0.0
260
- for (i,cell) in enumerate (cells)
261
- contrib = getindex! (cache_unassembled_lhs,m. agg_cells_lhs_contribs,cell)
262
- result. array .+ = contrib
263
- end
264
- result. array
265
- end
266
240
267
241
# Finally assemble LHS contributions
268
- ass_lhs_map= AssembleLhsMap (agg_cells_to_lhs_contribs)
242
+ ass_lhs_map= BulkGhostPenaltyAssembleLhsMap (agg_cells_to_lhs_contribs)
269
243
lhs= lazy_map (ass_lhs_map,aggregate_to_local_cells)
270
244
271
245
# Compute contributions to the RHS of the L2 projection
272
246
du = get_trial_fe_basis (Ustd)
247
+ dv = get_fe_basis (Vstd)
273
248
Ωagg_cell_dof_ids = get_cell_dof_ids (Ustd,Ωagg_cells)
274
- agg_cells_rhs_contribs= get_array (∫ (vbb_Ωagg_cells* du)dΩagg_cells)
275
-
276
- # TO-DO: Better name?
277
- struct AssembleRhsMap{A,B} <: Gridap.Fields.Map
278
- agg_cells_local_dof_ids:: A
279
- agg_cells_rhs_contribs:: B
280
- end
281
-
282
- function Gridap. Fields. return_cache (m:: AssembleRhsMap ,aggregate_local_cells)
283
- cache_agg_cells_local_dof_ids= array_cache (m. agg_cells_local_dof_ids)
284
- cache_unassembled_rhs= array_cache (m. agg_cells_rhs_contribs)
285
- evaluate_result= Gridap. Arrays. CachedArray (eltype (eltype (m. agg_cells_rhs_contribs)),2 )
286
- cache_agg_cells_local_dof_ids,cache_unassembled_rhs,evaluate_result
287
- end
288
-
289
- function Gridap. Fields. evaluate! (cache,m:: AssembleRhsMap ,aggregate_local_cells)
290
- cache_agg_cells_local_dof_ids,cache_unassembled_rhs,result= cache
291
- contrib = getindex! (cache_unassembled_rhs,m. agg_cells_rhs_contribs,1 )
292
-
293
- max_local_dof_id= - 1
294
- for (i,cell) in enumerate (aggregate_local_cells)
295
- current_cell_local_dof_ids = getindex! (cache_agg_cells_local_dof_ids,m. agg_cells_local_dof_ids,cell)
296
- for local_dof in current_cell_local_dof_ids
297
- max_local_dof_id= max (max_local_dof_id,local_dof)
298
- end
299
- end
300
-
301
- Gridap. Arrays. setsize! (result,(size (contrib,1 ),max_local_dof_id))
302
- result. array .= 0.0
303
- for (i,cell) in enumerate (aggregate_local_cells)
304
- current_cell_local_dof_ids = getindex! (cache_agg_cells_local_dof_ids,m. agg_cells_local_dof_ids,cell)
305
- contrib = getindex! (cache_unassembled_rhs,m. agg_cells_rhs_contribs,cell)
306
- for (j,local_dof) in enumerate (current_cell_local_dof_ids)
307
- result. array[:,local_dof] += contrib[:,j]
308
- end
309
- end
310
- result. array
311
- end
312
249
313
250
# ## BEGIN TESTING CODE
314
251
# This code is just for testing purposes, so I have commented it out
@@ -344,42 +281,26 @@ function compute_agg_cells_local_dof_ids(agg_cells_dof_ids, aggregate_to_agg_cel
344
281
agg_cells_local_dof_ids
345
282
end
346
283
347
- agg_cells_local_dof_ids= compute_agg_cells_local_dof_ids (Ωagg_cell_dof_ids, aggregate_to_local_cells)
348
- ass_rhs_map= AssembleRhsMap (agg_cells_local_dof_ids,agg_cells_rhs_contribs)
349
- rhs= lazy_map (ass_rhs_map,aggregate_to_local_cells)
350
-
351
- # TO-DO: optimize using our own optimized version Gridap.Fields.Map
352
- # of backslash that re-uses storage for lu factors among cells, etc.
353
- dv_l2_proj_bb_dofs= lazy_map (\ ,lhs,rhs)
354
-
355
- # Generate bb-wise array of fields. For each aggregate's bounding box,
356
- # it provides the l2 projection of all basis functions in Ustd
357
- # restricted to the cells included in the bounding box of the aggregate
358
- dv_l2_proj_bb_array= lazy_map (Gridap. Fields. linear_combination,
359
- dv_l2_proj_bb_dofs,
360
- Gridap. CellData. get_data (vbb))
361
-
362
- # Change domain of dv_l2_proj_bb_array from bb to agg_cells
363
- dv_l2_proj_bb_array_agg_cells= lazy_map (Broadcasting (∘ ),
364
- lazy_map (Reindex (dv_l2_proj_bb_array),agg_cells_to_aggregate),
365
- ref_agg_cell_to_ref_bb_map)
366
- du_l2_proj_agg_cells= Gridap. CellData. GenericCellField (lazy_map (transpose,dv_l2_proj_bb_array_agg_cells),
367
- Ωagg_cells,
368
- ReferenceDomain ())
284
+ agg_cells_local_dof_ids=
285
+ compute_agg_cells_local_dof_ids (Ωagg_cell_dof_ids, aggregate_to_local_cells)
369
286
370
287
# Compute and assemble the bulk penalty stabilization term
371
288
# ∫( (dv-dv_l2_proj_agg_cells)*(du-du_l2_proj_agg_cells))*dΩ_agg_cells
372
289
# ∫( (dv)*(du-du_l2_proj_agg_cells))*dΩ_agg_cells
373
290
374
291
375
- γ = 10.0 # Interior bulk-penalty stabilization parameter
376
- # (@amartinhuertas no idea what a reasonable value is)
292
+ function set_up_h_U (aggregates_bounding_box_model,
293
+ agg_cells_to_aggregate,
294
+ Ωagg_cells)
295
+ degree = 0 # We are integrating a constant function
296
+ # Thus, degree=0 is enough for exact integration
297
+ Ωbb = Triangulation (aggregates_bounding_box_model)
298
+ dΩbb = Measure (Ωbb, degree)
299
+ h_U_array = get_array (∫ (1.0 )dΩbb)
300
+ h_U_array = lazy_map (Reindex (h_U_array), agg_cells_to_aggregate)
301
+ CellField (h_U_array, Ωagg_cells)
302
+ end
377
303
378
- Ωbb = Triangulation (aggregates_bounding_box_model)
379
- dΩbb = Measure (Ωbb, degree)
380
- h_U_array = get_array (∫ (1.0 )dΩbb)
381
- h_U_array = lazy_map (Reindex (h_U_array), agg_cells_to_aggregate)
382
- h_U = CellField (h_U_array, Ωagg_cells)
383
304
384
305
function compute_aggregate_dof_ids (agg_cells_dof_ids, aggregate_to_agg_cells)
385
306
aggregate_dof_ids= Vector {Vector{Int}} (undef, length (aggregate_to_agg_cells))
@@ -402,26 +323,127 @@ function compute_aggregate_dof_ids(agg_cells_dof_ids, aggregate_to_agg_cells)
402
323
aggregate_dof_ids
403
324
end
404
325
326
+ function _get_single_field_fe_basis (a:: Gridap.MultiField.MultiFieldFEBasisComponent )
327
+ a. single_field
328
+ end
329
+ function _get_single_field_fe_basis (a)
330
+ a
331
+ end
332
+ function _is_multifield_fe_basis_component (a:: Gridap.MultiField.MultiFieldFEBasisComponent )
333
+ true
334
+ end
335
+ function _is_multifield_fe_basis_component (a)
336
+ false
337
+ end
338
+ function _nfields (a:: Gridap.MultiField.MultiFieldFEBasisComponent )
339
+ a. nfields
340
+ end
341
+ function _fieldid (a:: Gridap.MultiField.MultiFieldFEBasisComponent )
342
+ a. fieldid
343
+ end
344
+
345
+ """
346
+ dv, du: Test and trial basis functions. They may be components of a MultiFieldCellField
347
+
348
+ # Compute and assemble the bulk penalty stabilization term
349
+ # ∫( (dv-dv_l2_proj_agg_cells)*(du-du_l2_proj_agg_cells))*dΩ_agg_cells (long version)
350
+ # ∫( (dv)*(du-du_l2_proj_agg_cells))*dΩ_agg_cells (simplified, equivalent version)
351
+ """
352
+ function interior_bulk_penalty_stabilization_collect_cell_matrix (agg_cells_to_aggregate,
353
+ ref_agg_cell_to_ref_bb_map,
354
+ dΩagg_cells,
355
+ dv, # Test basis
356
+ du, # Trial basis (to project)
357
+ dvbb, # Bounding box space test basis
358
+ lhs,
359
+ Ωagg_cell_dof_ids,
360
+ agg_cells_local_dof_ids,
361
+ agg_cells_to_aggregate_dof_ids,
362
+ h_U,
363
+ γ)
364
+
365
+
366
+ Ωagg_cells= dΩagg_cells. quad. trian
367
+
368
+ # Change domain of vbb (test) from Ωbb to Ωagg_cells
369
+ dvbb_Ωagg_cells= change_domain_bb_to_agg_cells (dvbb,
370
+ ref_agg_cell_to_ref_bb_map,
371
+ Ωagg_cells,
372
+ agg_cells_to_aggregate)
373
+
374
+ du_single_field= _get_single_field_fe_basis (du)
375
+ agg_cells_rhs_contribs= get_array (∫ (dvbb_Ωagg_cells* du_single_field)dΩagg_cells)
376
+ ass_rhs_map= BulkGhostPenaltyAssembleRhsMap (agg_cells_local_dof_ids,agg_cells_rhs_contribs)
377
+ rhs= lazy_map (ass_rhs_map,aggregate_to_local_cells)
378
+
379
+ # TO-DO: optimize using our own optimized version Gridap.Fields.Map
380
+ # of backslash that re-uses storage for lu factors among cells, etc.
381
+ dv_l2_proj_bb_dofs= lazy_map (\ ,lhs,rhs)
382
+
383
+ # Generate bb-wise array of fields. For each aggregate's bounding box,
384
+ # it provides the l2 projection of all basis functions in Ustd
385
+ # restricted to the cells included in the bounding box of the aggregate
386
+ dv_l2_proj_bb_array= lazy_map (Gridap. Fields. linear_combination,
387
+ dv_l2_proj_bb_dofs,
388
+ Gridap. CellData. get_data (dvbb))
389
+
390
+ # Change domain of dv_l2_proj_bb_array from bb to agg_cells
391
+ dv_l2_proj_bb_array_agg_cells= lazy_map (Broadcasting (∘ ),
392
+ lazy_map (Reindex (dv_l2_proj_bb_array),agg_cells_to_aggregate),
393
+ ref_agg_cell_to_ref_bb_map)
394
+
395
+ if (_is_multifield_fe_basis_component (du))
396
+ @assert _is_multifield_fe_basis_component (dv)
397
+ @assert _nfields (du)== _nfields (dv)
398
+ nfields= _nfields (du)
399
+ fieldid= _fieldid (du)
400
+ dv_l2_proj_bb_array_agg_cells= lazy_map (BlockMap (fieldid,nfields),dv_l2_proj_bb_array_agg_cells)
401
+ end
402
+
403
+
404
+ du_l2_proj_agg_cells= Gridap. CellData. GenericCellField (lazy_map (transpose, dv_l2_proj_bb_array_agg_cells),
405
+ dΩagg_cells. quad. trian,
406
+ ReferenceDomain ())
407
+
408
+ # Manually set up the arrays that collect_cell_matrix would return automatically
409
+ w = []
410
+ r = []
411
+ c = []
412
+
413
+ dv_du_mat_contribs= get_array (∫ (γ* (1.0 / h_U* h_U)* dv* du)* dΩagg_cells)
414
+ push! (w, dv_du_mat_contribs)
415
+ push! (r, Ωagg_cell_dof_ids)
416
+ push! (c, Ωagg_cell_dof_ids)
417
+
418
+ proj_dv_du_mat_contribs= get_array (∫ (γ* (1.0 / h_U* h_U)* (- 1.0 )* dv* (du_l2_proj_agg_cells))* dΩagg_cells)
419
+ push! (w, proj_dv_du_mat_contribs)
420
+ push! (r, Ωagg_cell_dof_ids)
421
+ push! (c, agg_cells_to_aggregate_dof_ids)
422
+
423
+ w, r, c
424
+ end
425
+
405
426
aggregate_dof_ids= compute_aggregate_dof_ids (Ωagg_cell_dof_ids,aggregate_to_cells)
406
427
agg_cells_to_aggregate_dof_ids= lazy_map (Reindex (aggregate_dof_ids),agg_cells_to_aggregate)
407
428
408
- # Manually set up the arrays that collect_cell_matrix would return automatically
409
- w = []
410
- r = []
411
- c = []
412
-
413
- dv= get_fe_basis (Vstd)
414
- du= get_trial_fe_basis (Ustd)
429
+ γ = 10.0 # Interior bulk-penalty stabilization parameter
430
+ # (@amartinhuertas no idea what a reasonable value is)
415
431
416
- dv_du_mat_contribs= get_array (∫ (γ* (1.0 / h_U* h_U)* dv* du)* dΩagg_cells)
417
- push! (w, dv_du_mat_contribs)
418
- push! (r, Ωagg_cell_dof_ids)
419
- push! (c, Ωagg_cell_dof_ids)
432
+ h_U = set_up_h_U (aggregates_bounding_box_model, agg_cells_to_aggregate, Ωagg_cells)
420
433
421
- proj_dv_du_mat_contribs= get_array (∫ (γ* (1.0 / h_U* h_U)* (- 1.0 )* dv* (du_l2_proj_agg_cells))* dΩagg_cells)
422
- push! (w, proj_dv_du_mat_contribs)
423
- push! (r, Ωagg_cell_dof_ids)
424
- push! (c, agg_cells_to_aggregate_dof_ids)
434
+ # Manually set up the arrays that collect_cell_matrix would return automatically
435
+ w,r,c= interior_bulk_penalty_stabilization_collect_cell_matrix (agg_cells_to_aggregate,
436
+ ref_agg_cell_to_ref_bb_map,
437
+ dΩagg_cells,
438
+ dv, # Test basis
439
+ du, # Trial basis (to project)
440
+ vbb, # Bounding box space test basis
441
+ lhs,
442
+ Ωagg_cell_dof_ids,
443
+ agg_cells_local_dof_ids,
444
+ agg_cells_to_aggregate_dof_ids,
445
+ h_U,
446
+ γ)
425
447
426
448
# Set up global projection matrix
427
449
Ωcut = Triangulation (cutdisk,PHYSICAL)
@@ -448,4 +470,4 @@ b = assemble_vector(l, Vstd)
448
470
global_l2_proj_dofs = Awithstab\ b
449
471
uh = FEFunction (Ustd, global_l2_proj_dofs)
450
472
eh = uex- uh
451
- @assert sum (∫ (eh* eh)* dΩcut) < 1.0e-12
473
+ @assert sum (∫ (eh* eh)* dΩcut) < 1.0e-12
0 commit comments