Hello,
I've been trying to refactor my code to use the new MatrixFreeOperators, 
but I've run into a problem trying to use the Jacobi preconditioner with 
the MatrixFreeOperators::LaplaceOperator with a vector-valued variable. 

In short, I wrote a short code to solve a simple 2D Poisson problem. For a 
scalar field, it works well both when using the identity matrix 
preconditioner and the Jacobi preconditioner. However, for a vector field, 
it works when using the identity matrix preconditioner but won't converge 
with the Jacobi preconditioner.

Aside from all of the standard book-keeping (creating an FESystem with 
multiple components, applying vector-valued ICs and BCs, etc.), my only 
change between the scalar case and the vector case is the template 
parameter for the MatrixFreeOperators::LaplaceOperator object.

Digging into it, I found that approximately every other element of the 
diagonal vector was zero, excluding a few that I believe are from the BCs 
(that is, in "compute_diagonal()", half of the elements in 
"inverse_diagonal_vector" are zero after the cell loop but before the 
reciprocal is taken). In the scalar case, all of the diagonal elements are 
non-zero, as one would expect. The zero elements of the diagonal seem to 
come from the "local_diagonal_cell" method, where "phi.dofs_per_cell" and 
"phi.tensor_dofs_per_cell" don't change between the scalar and vector case 
(4 in this case, with linear elements), when I'd expect the dofs per cell 
in the vector case to be the number of components times the dofs per cell 
in the scalar case.

If I multiply  "phi.dofs_per_cell" and "phi.tensor_dofs_per_cell" by the 
number of components everywhere in the "local_diagonal_cell" method, the 
preconditioner works (see the highlighted edits at the bottom of the post).

So, does anyone have an idea of what's going on here? Is this a bug, or is 
there an extra step I'm missing to use MatrixFreeOperators with a vector 
that I'm compensating for?

Thanks,
Steve

template <int dim, int fe_degree, int n_q_points_1d, int n_components, 
typename VectorType>
  void
  CustomLaplaceOperator<dim, fe_degree, n_q_points_1d, n_components, 
VectorType>::
  local_diagonal_cell (const MatrixFree<dim,typename dealii::
MatrixFreeOperators::Base<dim,VectorType>::value_type> &data,
                       VectorType                                       &dst
,
                       const unsigned int &,
                       const std::pair<unsigned int,unsigned int>       &
cell_range) const
  {
    typedef typename 
dealii::MatrixFreeOperators::Base<dim,VectorType>::value_type 
Number;
    FEEvaluation<dim,fe_degree,n_q_points_1d,n_components,Number> phi (data, 
this->selected_rows[0]);

    for (unsigned int cell=cell_range.first; cell<cell_range.second; ++cell)
      {
        phi.reinit (cell);
        VectorizedArray<Number> local_diagonal_vector[phi.
tensor_dofs_per_cell* n_components];
        for (unsigned int i=0; i<phi.dofs_per_cell* n_components; ++i)
          {
            for (unsigned int j=0; j<phi.dofs_per_cell* n_components; ++j)
            //for (unsigned int j=0; j<phi.tensor_dofs_per_cell; ++j)
              phi.begin_dof_values()[j] = VectorizedArray<Number>();
            phi.begin_dof_values()[i] = 1.;
            do_operation_on_cell(phi,cell);
            local_diagonal_vector[i] = phi.begin_dof_values()[i];
          }
          for (unsigned int i=0; i<phi.tensor_dofs_per_cell* n_components; 
++i){
              phi.begin_dof_values()[i] = local_diagonal_vector[i];
          }
        phi.distribute_local_to_global (dst);
      }
  }

-- 
The deal.II project is located at http://www.dealii.org/
For mailing list/forum options, see 
https://groups.google.com/d/forum/dealii?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"deal.II User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to