@@ -49,6 +49,50 @@ void transfer_to_particles(const Particles<T>& particles, Field<T>& field,
4949 f->eval (x, xshape, p2c, u, ushape);
5050}
5151
52+ // / Transfer the provided particle field data to the finite element
53+ // / function using local l_2 projection.
54+ // / We solve the problem: find \f(u_h \in V\f) such that
55+ // /
56+ // / \f[
57+ // / u_h(x_p) v(x_p) = u_p v(x_p) \quad \forall v \in V, \; p = 1,\ldots,n_p.
58+ // / \f]
59+ // /
60+ // / Here \f(u_p\f) is the \f(p\f)th particle's data, \f(x_p\f) is the \f(p\f)th
61+ // / particle's position, \f(n_p\f) is the total number of particles
62+ // / and \f(V\f) is the function space to which the provided finite element
63+ // / function belongs.
64+ // /
65+ // / @tparam T The function scalar type
66+ // / @tparam U The function geometry type
67+ // / @param f The finite element function
68+ // / @param pax The particles collection
69+ // / @param field The field data to be transferred
70+ template <dolfinx::scalar T, std::floating_point U>
71+ std::vector<std::int32_t > find_deficient_cells (
72+ std::shared_ptr<dolfinx::fem::Function<T>> f,
73+ const Particles<T>& pax)
74+ {
75+ std::shared_ptr<const dolfinx::mesh::Mesh<U>> mesh
76+ = f->function_space ()->mesh ();
77+ std::shared_ptr<const dolfinx::fem::FunctionSpace<T>> V
78+ = f->function_space ();
79+ const int tdim = mesh->topology ()->dim ();
80+ std::int32_t ncells = mesh->topology ()->index_map (tdim)->size_local ();
81+ std::shared_ptr<const dolfinx::fem::FiniteElement<T>> element
82+ = f->function_space ()->element ();
83+
84+ const std::vector<std::vector<std::size_t >>& c2p
85+ = pax.cell_to_particle ();
86+
87+ std::vector<std::int32_t > deficient_cells;
88+ for (std::int32_t c = 0 ; c < ncells; ++c)
89+ {
90+ const std::size_t ncdof = V->dofmap ()->cell_dofs (c).size ();
91+ if (c2p[c].size () < ncdof)
92+ deficient_cells.push_back (c);
93+ }
94+ return deficient_cells;
95+ }
5296
5397// / Transfer the provided particle field data to the finite element
5498// / function using local l_2 projection. The solve_callback function
@@ -185,6 +229,7 @@ template <dolfinx::scalar T, std::floating_point U>
185229void transfer_to_function (std::shared_ptr<dolfinx::fem::Function<T>> f,
186230 const Particles<T>& pax, const Field<T>& field)
187231{
232+ // Simply solve the particle mass matrix / rhs system
188233 std::function<const std::vector<T>(mdspan_t <T, 2 >, mdspan_t <T, 2 >)>
189234 solve_function = [](mdspan_t <T, 2 > QT_Q, mdspan_t <T, 2 > QT_L)
190235 {
@@ -238,6 +283,7 @@ void transfer_to_function_constrained(
238283 ci0[i + space_dimension] = u;
239284 }
240285
286+ // Solve the mass matrix / rhs optimisation problem with quadprog
241287 std::function<std::vector<T>(mdspan_t <T, 2 >, mdspan_t <T, 2 >)>
242288 solve_function = [&CE, &ce0, &CI, &ci0](
243289 mdspan_t <T, 2 > QT_Q, mdspan_t <T, 2 > QT_L)
0 commit comments