@@ -163,7 +163,8 @@ void modify_mpc_cell(
163
163
// Zero out slave entries in element matrix
164
164
// Zero slave row
165
165
std::ranges::for_each (local_index[0 ],
166
- [&Ae, ndim1](const auto dof) {
166
+ [&Ae, ndim1](const auto dof)
167
+ {
167
168
std::ranges::fill_n (
168
169
std::next (Ae.data_handle (), ndim1 * dof), ndim1,
169
170
0.0 );
@@ -276,6 +277,8 @@ void assemble_exterior_facets(
276
277
std::span<const std::int32_t >,
277
278
const std::span<const T>)>& mat_add_values,
278
279
const dolfinx::mesh::Mesh<U>& mesh, std::span<const std::int32_t> facets,
280
+ std::span<const std::int32_t> facets0,
281
+ std::span<const std::int32_t> facets1,
279
282
const std::function<void(const std::span<T>&,
280
283
const std::span<const std::uint32_t >&,
281
284
std::int32_t , int )>& apply_dof_transformation,
@@ -289,7 +292,8 @@ void assemble_exterior_facets(
289
292
const std::uint8_t *)>& kernel,
290
293
const std::span<const T> coeffs, int cstride,
291
294
const std::vector<T>& constants,
292
- const std::span<const std::uint32_t>& cell_info,
295
+ const std::span<const std::uint32_t>& cell_info0,
296
+ const std::span<const std::uint32_t>& cell_info1,
293
297
const std::shared_ptr<const dolfinx_mpc::MultiPointConstraint<T, U>>& mpc0,
294
298
const std::shared_ptr<const dolfinx_mpc::MultiPointConstraint<T, U>>& mpc1)
295
299
{
@@ -335,7 +339,8 @@ void assemble_exterior_facets(
335
339
std::vector<T> scratch_memory (2 * ndim0 * ndim1 + ndim0 + ndim1);
336
340
for (std::size_t l = 0 ; l < facets.size (); l += 2 )
337
341
{
338
-
342
+ const std::int32_t cell0 = facets0[l];
343
+ const std::int32_t cell1 = facets1[l];
339
344
const std::int32_t cell = facets[l];
340
345
const int local_facet = facets[l + 1 ];
341
346
@@ -352,12 +357,12 @@ void assemble_exterior_facets(
352
357
std::ranges::fill (Aeb, 0 );
353
358
kernel (Aeb.data (), coeffs.data () + l / 2 * cstride, constants.data (),
354
359
coordinate_dofs.data (), &local_facet, nullptr );
355
- apply_dof_transformation (_Ae, cell_info, cell , ndim1);
356
- apply_dof_transformation_to_transpose (_Ae, cell_info, cell , ndim0);
360
+ apply_dof_transformation (_Ae, cell_info0, cell0 , ndim1);
361
+ apply_dof_transformation_to_transpose (_Ae, cell_info1, cell1 , ndim0);
357
362
358
363
// Zero rows/columns for essential bcs
359
- auto dmap0 = dofmap0.cell_dofs (cell );
360
- auto dmap1 = dofmap1.cell_dofs (cell );
364
+ auto dmap0 = dofmap0.cell_dofs (cell0 );
365
+ auto dmap1 = dofmap1.cell_dofs (cell1 );
361
366
if (!bc0.empty ())
362
367
{
363
368
for (std::uint32_t i = 0 ; i < num_dofs0; ++i)
@@ -393,11 +398,11 @@ void assemble_exterior_facets(
393
398
394
399
// Modify local element matrix Ae and insert contributions into master
395
400
// locations
396
- if ((cell_to_slaves[0 ]->num_links (cell ) > 0 )
397
- || (cell_to_slaves[1 ]->num_links (cell ) > 0 ))
401
+ if ((cell_to_slaves[0 ]->num_links (cell0 ) > 0 )
402
+ || (cell_to_slaves[1 ]->num_links (cell1 ) > 0 ))
398
403
{
399
404
const std::array<std::span<const std::int32_t >, 2 > slaves
400
- = {cell_to_slaves[0 ]->links (cell ), cell_to_slaves[1 ]->links (cell )};
405
+ = {cell_to_slaves[0 ]->links (cell0 ), cell_to_slaves[1 ]->links (cell1 )};
401
406
const std::array<std::span<const std::int32_t >, 2 > dofs = {dmap0, dmap1};
402
407
modify_mpc_cell<T>(mat_add_values, num_dofs, Ae, dofs, bs, slaves,
403
408
masters, coefficients, is_slave, scratch_memory);
@@ -416,6 +421,8 @@ void assemble_cells_impl(
416
421
const std::span<const T>)>& mat_add_values,
417
422
const dolfinx::mesh::Geometry<U>& geometry,
418
423
std::span<const std::int32_t> active_cells,
424
+ std::span<const std::int32_t> active_cells0,
425
+ std::span<const std::int32_t> active_cells1,
419
426
std::function<void(std::span<T>, const std::span<const std::uint32_t >,
420
427
const std::int32_t , const int )>
421
428
apply_dof_transformation,
@@ -429,7 +436,8 @@ void assemble_cells_impl(
429
436
const std::uint8_t *)>& kernel,
430
437
const std::span<const T>& coeffs, int cstride,
431
438
const std::vector<T>& constants,
432
- const std::span<const std::uint32_t>& cell_info,
439
+ const std::span<const std::uint32_t>& cell_info0,
440
+ const std::span<const std::uint32_t>& cell_info1,
433
441
const std::shared_ptr<const dolfinx_mpc::MultiPointConstraint<T, U>>& mpc0,
434
442
const std::shared_ptr<const dolfinx_mpc::MultiPointConstraint<T, U>>& mpc1)
435
443
{
@@ -471,9 +479,12 @@ void assemble_cells_impl(
471
479
const std::span<T> _Ae (Aeb);
472
480
std::vector<T> scratch_memory (2 * ndim0 * ndim1 + ndim0 + ndim1);
473
481
474
- for (std::size_t c = 0 ; c < active_cells .size (); c ++)
482
+ for (std::size_t index = 0 ; index < active_cells0 .size (); index ++)
475
483
{
476
- const std::int32_t cell = active_cells[c];
484
+ const std::int32_t cell = active_cells[index ];
485
+ const std::int32_t cell0 = active_cells0[index ];
486
+ const std::int32_t cell1 = active_cells1[index ];
487
+
477
488
// Get cell coordinates/geometry
478
489
auto x_dofs = MDSPAN_IMPL_STANDARD_NAMESPACE::submdspan (
479
490
x_dofmap, cell, MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent);
@@ -485,14 +496,14 @@ void assemble_cells_impl(
485
496
486
497
// Tabulate tensor
487
498
std::ranges::fill (Aeb, 0 );
488
- kernel (Aeb.data (), coeffs.data () + c * cstride, constants.data (),
499
+ kernel (Aeb.data (), coeffs.data () + index * cstride, constants.data (),
489
500
coordinate_dofs.data (), nullptr , nullptr );
490
- apply_dof_transformation (_Ae, cell_info, cell , ndim1);
491
- apply_dof_transformation_to_transpose (_Ae, cell_info, cell , ndim0);
501
+ apply_dof_transformation (_Ae, cell_info0, cell0 , ndim1);
502
+ apply_dof_transformation_to_transpose (_Ae, cell_info1, cell1 , ndim0);
492
503
493
504
// Zero rows/columns for essential bcs
494
- std::span<const std::int32_t > dofs0 = dofmap0.cell_dofs (cell );
495
- std::span<const std::int32_t > dofs1 = dofmap1.cell_dofs (cell );
505
+ std::span<const std::int32_t > dofs0 = dofmap0.cell_dofs (cell0 );
506
+ std::span<const std::int32_t > dofs1 = dofmap1.cell_dofs (cell1 );
496
507
if (!bc0.empty ())
497
508
{
498
509
for (std::uint32_t i = 0 ; i < num_dofs0; ++i)
@@ -517,11 +528,11 @@ void assemble_cells_impl(
517
528
518
529
// Modify local element matrix Ae and insert contributions into master
519
530
// locations
520
- if ((cell_to_slaves[0 ]->num_links (cell ) > 0 )
521
- || (cell_to_slaves[1 ]->num_links (cell ) > 0 ))
531
+ if ((cell_to_slaves[0 ]->num_links (cell0 ) > 0 )
532
+ || (cell_to_slaves[1 ]->num_links (cell1 ) > 0 ))
522
533
{
523
534
const std::array<std::span<const std::int32_t >, 2 > slaves
524
- = {cell_to_slaves[0 ]->links (cell ), cell_to_slaves[1 ]->links (cell )};
535
+ = {cell_to_slaves[0 ]->links (cell0 ), cell_to_slaves[1 ]->links (cell1 )};
525
536
const std::array<std::span<const std::int32_t >, 2 > dofs = {dofs0, dofs1};
526
537
modify_mpc_cell<T>(mat_add_values, num_dofs, Ae, dofs, bs, slaves,
527
538
masters, coefficients, is_slave, scratch_memory);
@@ -543,9 +554,18 @@ void assemble_matrix_impl(
543
554
const std::shared_ptr<const dolfinx_mpc::MultiPointConstraint<T, U>>& mpc0,
544
555
const std::shared_ptr<const dolfinx_mpc::MultiPointConstraint<T, U>>& mpc1)
545
556
{
546
- auto mesh = a.mesh ();
557
+ // Integration domain mesh
558
+ std::shared_ptr<const mesh::Mesh<U>> mesh = a.mesh ();
547
559
assert (mesh);
548
560
561
+ // Test function mesh
562
+ auto mesh0 = a.function_spaces ().at (0 )->mesh ();
563
+ assert (mesh0);
564
+
565
+ // Trial function mesh
566
+ auto mesh1 = a.function_spaces ().at (1 )->mesh ();
567
+ assert (mesh1);
568
+
549
569
// Get dofmap data
550
570
std::shared_ptr<const dolfinx::fem::DofMap> dofmap0
551
571
= a.function_spaces ().at (0 )->dofmap ();
@@ -573,62 +593,61 @@ void assemble_matrix_impl(
573
593
= element1->template dof_transformation_right_fn <T>(
574
594
dolfinx::fem::doftransform::transpose);
575
595
596
+ const int num_cell_types = mesh->topology ()->cell_types ().size ();
597
+ if (num_cell_types > 1 )
598
+ throw std::runtime_error (" Not implemented for mixed cell types" );
599
+
576
600
const bool needs_transformation_data
577
601
= element0->needs_dof_transformations ()
578
602
or element1->needs_dof_transformations ()
579
603
or a.needs_facet_permutations ();
580
- std::span<const std::uint32_t > cell_info;
604
+ std::span<const std::uint32_t > cell_info0;
605
+ std::span<const std::uint32_t > cell_info1;
581
606
if (needs_transformation_data)
582
607
{
583
- mesh->topology_mutable ()->create_entity_permutations ();
584
- cell_info = std::span (mesh->topology ()->get_cell_permutation_info ());
608
+ mesh0->topology_mutable ()->create_entity_permutations ();
609
+ mesh1->topology_mutable ()->create_entity_permutations ();
610
+ cell_info0 = std::span (mesh0->topology ()->get_cell_permutation_info ());
611
+ cell_info1 = std::span (mesh1->topology ()->get_cell_permutation_info ());
585
612
}
586
613
for (int i : a.integral_ids (dolfinx::fem::IntegralType::cell))
587
614
{
588
- const auto & fn = a.kernel (dolfinx::fem::IntegralType::cell, i);
615
+ const auto & fn = a.kernel (dolfinx::fem::IntegralType::cell, i, 0 );
589
616
const auto & [coeffs, cstride]
590
617
= coefficients.at ({dolfinx::fem::IntegralType::cell, i});
591
618
std::span<const std::int32_t > active_cells
592
- = a.domain (dolfinx::fem::IntegralType::cell, i);
619
+ = a.domain (dolfinx::fem::IntegralType::cell, i, 0 );
620
+ std::span<const std::int32_t > active_cells0
621
+ = a.domain_arg (dolfinx::fem::IntegralType::cell, 0 , i, 0 );
622
+ std::span<const std::int32_t > active_cells1
623
+ = a.domain_arg (dolfinx::fem::IntegralType::cell, 1 , i, 0 );
593
624
assemble_cells_impl<T>(
594
625
mat_add_block_values, mat_add_values, mesh->geometry (), active_cells,
595
- apply_dof_transformation, *dofmap0,
626
+ active_cells0, active_cells1, apply_dof_transformation, *dofmap0,
596
627
apply_dof_transformation_to_transpose, *dofmap1, bc0, bc1, fn, coeffs,
597
- cstride, constants, cell_info , mpc0, mpc1);
628
+ cstride, constants, cell_info0, cell_info1 , mpc0, mpc1);
598
629
}
599
630
600
631
for (int i : a.integral_ids (dolfinx::fem::IntegralType::exterior_facet))
601
632
{
602
- const auto & fn = a.kernel (dolfinx::fem::IntegralType::exterior_facet, i);
633
+ const auto & fn = a.kernel (dolfinx::fem::IntegralType::exterior_facet, i, 0 );
603
634
const auto & [coeffs, cstride]
604
635
= coefficients.at ({dolfinx::fem::IntegralType::exterior_facet, i});
605
636
std::span<const std::int32_t > facets
606
- = a.domain (dolfinx::fem::IntegralType::exterior_facet, i);
607
- assemble_exterior_facets<T>(mat_add_block_values, mat_add_values, *mesh,
608
- facets, apply_dof_transformation, *dofmap0,
609
- apply_dof_transformation_to_transpose, *dofmap1,
610
- bc0, bc1, fn, coeffs, cstride, constants,
611
- cell_info, mpc0, mpc1);
637
+ = a.domain (dolfinx::fem::IntegralType::exterior_facet, i, 0 );
638
+ std::span<const std::int32_t > active_facets0
639
+ = a.domain_arg (dolfinx::fem::IntegralType::exterior_facet, 0 , i, 0 );
640
+ std::span<const std::int32_t > active_facets1
641
+ = a.domain_arg (dolfinx::fem::IntegralType::exterior_facet, 1 , i, 0 );
642
+ assemble_exterior_facets<T>(
643
+ mat_add_block_values, mat_add_values, *mesh, facets, active_facets0,
644
+ active_facets1, apply_dof_transformation, *dofmap0,
645
+ apply_dof_transformation_to_transpose, *dofmap1, bc0, bc1, fn, coeffs,
646
+ cstride, constants, cell_info0, cell_info1, mpc0, mpc1);
612
647
}
613
648
614
- // if (a.num_integrals(dolfinx::fem::IntegralType::interior_facet) > 0)
615
- // {
616
- // throw std::runtime_error("Not implemented yet");
617
- // // const int tdim = mesh->topology()->dim();
618
- // // mesh->topology_mutable().create_connectivity(tdim - 1, tdim);
619
- // // mesh->topology_mutable().create_entity_permutations();
620
-
621
- // // std::function<std::uint8_t(std::size_t)> get_perm;
622
- // // if (a.needs_facet_permutations())
623
- // // {
624
- // // mesh->topology_mutable().create_entity_permutations();
625
- // // const std::vector<std::uint8_t>& perms
626
- // // = mesh->topology()->get_facet_permutations();
627
- // // get_perm = [&perms](std::size_t i) { return perms[i]; };
628
- // // }
629
- // // else
630
- // // get_perm = [](std::size_t) { return 0; };
631
- // }
649
+ if (a.integral_ids (dolfinx::fem::IntegralType::interior_facet).size () > 0 )
650
+ throw std::runtime_error (" Not implemented yet" );
632
651
}
633
652
// -----------------------------------------------------------------------------
634
653
template <typename T, std::floating_point U>
0 commit comments