Hi Lorenzo
Good that you have found a workaround, your solution is good, I would do the same.
Regarding local projection, this is its implementation in the code:
void ga_local_projection(const getfem::model &md, const mesh_im &mim,
const std::string &expr, const mesh_fem &mf,
base_vector &result, const mesh_region ®ion) {
// The case where the expression is a vector one and mf a scalar fem is
// not taken into account for the moment.
// Could be improved by not performing the assembly of the global mass matrix
// working locally. This means a specific assembly.
size_type nbdof = mf.nb_dof();
model_real_sparse_matrix M(nbdof, nbdof);
asm_mass_matrix(M, mim, mf, region);
// FIXME: M should be cached for performance
ga_workspace workspace(md, ga_workspace::inherit::NONE);
gmm::sub_interval I(0,nbdof);
workspace.add_fem_variable("c__dummy_var_95_", mf, I, base_vector(nbdof));
if (mf.get_qdims().size() > 1)
workspace.add_expression("("+expr+"):Test_c__dummy_var_95_",mim,region,2);
else
workspace.add_expression("("+expr+").Test_c__dummy_var_95_",mim,region,2);
getfem::base_vector F(nbdof);
workspace.set_assembled_vector(F);
workspace.assembly(1);
gmm::resize(result, nbdof);
getfem::base_matrix loc_M;
getfem::base_vector loc_U;
for (mr_visitor v(region, mf.linked_mesh(), true); !v.finished(); ++v) {
if (mf.convex_index().is_in(v.cv())) {
size_type nd = mf.nb_basic_dof_of_element(v.cv());
loc_M.base_resize(nd, nd); gmm::resize(loc_U, nd);
gmm::sub_index J(mf.ind_basic_dof_of_element(v.cv()));
gmm::copy(gmm::sub_matrix(M, J, J), loc_M);
gmm::lu_solve(loc_M, loc_U, gmm::sub_vector(F, J));
gmm::copy(loc_U, gmm::sub_vector(result, J));
}
}
MPI_SUM_VECTOR(result);
}
In the line
gmm::sub_index J(mf.ind_basic_dof_of_element(v.cv()));
we can see that only entire elements are treated and not element faces. We should extend the implementation to cover this use case.