@@ -49,6 +49,50 @@ void transfer_to_particles(const Particles<T>& particles, Field<T>& field,
49
49
f->eval (x, xshape, p2c, u, ushape);
50
50
}
51
51
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
+ }
52
96
53
97
// / Transfer the provided particle field data to the finite element
54
98
// / function using local l_2 projection. The solve_callback function
@@ -185,6 +229,7 @@ template <dolfinx::scalar T, std::floating_point U>
185
229
void transfer_to_function (std::shared_ptr<dolfinx::fem::Function<T>> f,
186
230
const Particles<T>& pax, const Field<T>& field)
187
231
{
232
+ // Simply solve the particle mass matrix / rhs system
188
233
std::function<const std::vector<T>(mdspan_t <T, 2 >, mdspan_t <T, 2 >)>
189
234
solve_function = [](mdspan_t <T, 2 > QT_Q, mdspan_t <T, 2 > QT_L)
190
235
{
@@ -238,6 +283,7 @@ void transfer_to_function_constrained(
238
283
ci0[i + space_dimension] = u;
239
284
}
240
285
286
+ // Solve the mass matrix / rhs optimisation problem with quadprog
241
287
std::function<std::vector<T>(mdspan_t <T, 2 >, mdspan_t <T, 2 >)>
242
288
solve_function = [&CE, &ce0, &CI, &ci0](
243
289
mdspan_t <T, 2 > QT_Q, mdspan_t <T, 2 > QT_L)
0 commit comments