I have a code version in which I am using a FESystem (3d) composed of three elements: FE_Nedelec (w), FE_RaviartThomas (u) and DGQ (p).
The code compiles fine but gives unreasonable results and I do not see what I am doing wrong or what I forgot.
/////////////////////////////////////////////////////////////
// System and dof setup
/////////////////////////////////////////////////////////////
template <int dim>
void
BoussinesqModel<dim>::setup_nse_matrices(
const std::vector<IndexSet> &nse_partitioning,
const std::vector<IndexSet> &nse_relevant_partitioning)
{
nse_matrix.clear();
LA::BlockSparsityPattern sp(nse_partitioning,
nse_partitioning,
nse_relevant_partitioning,
this->mpi_communicator);
Table<2, DoFTools::Coupling> coupling(2 * dim + 1, 2 * dim + 1);
for (unsigned int c = 0; c < 2 * dim + 1; ++c)
{
for (unsigned int d = 0; d < 2 * dim + 1; ++d)
{
if (c < dim)
{
if (d < 2 * dim - 1)
coupling[c][d] = DoFTools::always;
else
coupling[c][d] = DoFTools::none;
}
else if ((c >= dim) && (c < 2 * dim))
{
coupling[c][d] = DoFTools::always;
}
else if (c == 2 * dim)
{
if ((d >= dim) && (d < 2 * dim))
coupling[c][d] = DoFTools::always;
else
coupling[c][d] = DoFTools::none;
}
}
}
DoFTools::make_sparsity_pattern(nse_dof_handler,
coupling,
sp,
nse_constraints,
false,
Utilities::MPI::this_mpi_process(
this->mpi_communicator));
sp.compress();
nse_matrix.reinit(sp);
}
template <int dim>
void
BoussinesqModel<dim>::setup_dofs()
{
TimerOutput::Scope timing_section(
this->computing_timer, "BoussinesqModel - setup dofs of systems");
/*
* Setup dof handlers for nse and temperature
*/
std::vector<unsigned int> nse_sub_blocks(3, 0);
nse_sub_blocks[1] = 1;
nse_sub_blocks[2] = 2;
nse_dof_handler.distribute_dofs(nse_fe);
/*
* Reduce bandwidth for ILU preconditioning
*/
DoFRenumbering::Cuthill_McKee(nse_dof_handler);
DoFRenumbering::block_wise(nse_dof_handler);
/*
* Count dofs
*/
std::vector<types::global_dof_index> nse_dofs_per_block(3);
DoFTools::count_dofs_per_block(nse_dof_handler,
nse_dofs_per_block,
nse_sub_blocks);
const unsigned int n_w = nse_dofs_per_block[0], n_u = nse_dofs_per_block[1],
n_p = nse_dofs_per_block[2],
n_T = temperature_dof_handler.n_dofs();
/*
* Comma separated large numbers
*/
std::locale s = this->pcout.get_stream().getloc();
this->pcout.get_stream().imbue(std::locale(""));
/*
* Print some mesh and dof info
*/
this->pcout << "Number of active cells: "
<< this->triangulation.n_global_active_cells() << " (on "
<< this->triangulation.n_levels() << " levels)" << std::endl
<< "Number of degrees of freedom: " << n_w + n_u + n_p + n_T
<< " (" << n_w << " + " << n_u << " + " << n_p << " + " << n_T
<< ")" << std::endl
<< std::endl;
this->pcout.get_stream().imbue(s);
/*
* Setup partitioners to store what dofs and matrix entries are stored on
* the local processor
*/
{
nse_index_set = nse_dof_handler.locally_owned_dofs();
nse_partitioning.push_back(nse_index_set.get_view(0, n_w));
nse_partitioning.push_back(nse_index_set.get_view(n_w, n_w + n_u));
nse_partitioning.push_back(
nse_index_set.get_view(n_w + n_u, n_w + n_u + n_p));
DoFTools::extract_locally_relevant_dofs(nse_dof_handler,
nse_relevant_set);
nse_relevant_partitioning.push_back(nse_relevant_set.get_view(0, n_w));
nse_relevant_partitioning.push_back(
nse_relevant_set.get_view(n_w, n_w + n_u));
nse_relevant_partitioning.push_back(
nse_relevant_set.get_view(n_w + n_u, n_w + n_u + n_p));
}
/*
* Setup constraints and boundary values for NSE. Make sure this is
* consistent with the initial data.
*/
{
nse_constraints.clear();
nse_constraints.reinit(nse_relevant_set);
DoFTools::make_hanging_node_constraints(nse_dof_handler, nse_constraints);
/*
* Lower boundary (id=0)
*/
VectorTools::project_boundary_values_curl_conforming_l2(
nse_dof_handler,
/*first vector component */ 0,
Functions::ZeroFunction<dim>(dim),
/*boundary id*/ 0,
nse_constraints);
VectorTools::project_boundary_values_div_conforming(
nse_dof_handler,
/*first vector component */
3,
Functions::ZeroFunction<dim>(dim),
/*boundary id*/ 0,
nse_constraints);
/*
* Upper boundary (id=1)
*/
VectorTools::project_boundary_values_curl_conforming_l2(
nse_dof_handler,
/*first vector component */ 0,
ConstantFunction<dim>(1, dim),
/*boundary id*/ 1,
nse_constraints);
VectorTools::project_boundary_values_div_conforming(
nse_dof_handler,
/*first vector component */
3,
Functions::ZeroFunction<dim>(dim),
/*boundary id*/ 1,
nse_constraints);
nse_constraints.close();
}
/*
* Setup the matrix and vector objects.
*/
setup_nse_matrices(nse_partitioning, nse_relevant_partitioning);
nse_rhs.reinit(nse_partitioning,
nse_relevant_partitioning,
this->mpi_communicator,
true);
nse_solution.reinit(nse_relevant_partitioning, this->mpi_communicator);
old_nse_solution.reinit(nse_solution);
}