* context. This class is an abstract one and has no implementations of
* possible algorithms for these operations.
*
+ * There are several derived classes, reflecting the fact that vector
+ * types and numbering of the fine-grid discretization and of the
+ * multi-level implementation are independent.
+ *
+ * If you use multigrid for your complete system of equations, you
+ * will use @ref{MGTransferPrebuilt} together with Multigrid for
+ * Vector objects. The fine-grid vectors may still be of type
+ * BlockVector.
+ *
+ * For mixed systems, it may be required to do multigrid only for a
+ * single component or for some components. The classes
+ * @ref{MGTransferSelect} and @ref{MGTransferBlock} handle these cases.
+ *
+ * MGTransferSelect is used if you use mutligrid (on Vector oblects)
+ * for a single component, possibly grouped using
+ * @p{mg_target_component}.
+ *
+ * The class MGTransferBlock handles the case where your multigrid
+ * method operates on BlockVector objects. These can contain all or a
+ * consecutive set of the blocks of the complete system. Since most
+ * smoothers cannot operate on block structures, it is not clear
+ * whether this case is really useful. Therefore, a tested
+ * implementation of this case will be supplied when needed.
+ *
* @author Wolfgang Bangerth, Guido Kanschat, 1999, 2002
*/
template <class VECTOR>
MGLevelObject<BlockVector<number> >& v,
const std::vector<bool>& selected,
const std::vector<unsigned int>& target_component);
+ /**
+ * Adjust vectors on all levels
+ * to correct size. Count the
+ * numbers of degrees of freedom
+ * on each level component-wise
+ * in a single component. Then,
+ * assign @p{vector} the
+ * corresponding size.
+ *
+ * The boolean field @p{selected}
+ * may be nonzero in a single
+ * component, indicating the
+ * block of a block vector the
+ * argument @p{v} corresponds to.
+ *
+ * Degrees of freedom must be
+ * sorted by component in order
+ * to obtain reasonable results
+ * from this function.
+ *
+ * The argument
+ * @p{target_component} allows to
+ * re-sort and groupt components
+ * as in
+ * @p{DoFRenumbering::component_wise}.
+ */
+ template <int dim, typename number>
+ static void
+ reinit_vector (const MGDoFHandler<dim>& mg_dof,
+ MGLevelObject<Vector<number> >& v,
+ const std::vector<bool>& selected,
+ const std::vector<unsigned int>& target_component);
};
* once by looping over all cells and storing the result in a matrix for
* each level, but requires additional memory.
*
+ * See @ref{MGTransferBase} to find out which of the transfer classes
+ * is best for your needs.
+ *
* @author Wolfgang Bangerth, Guido Kanschat, 1999-2003
*/
template <typename number>
private:
- /**
- * Selected component.
- */
- unsigned int selected;
-
/**
* Sizes of the multi-level vectors.
*/
/**
* Implementation of matrix generation for @ref{MGTransferBlock} and
- * @p{MGTransferSelected}.
+ * @p{MGTransferSelect}.
*
* @author Guido Kanschat, 2001-2003
*/
*/
std::vector<unsigned int> target_component;
+ /**
+ * Target component if
+ * renumbering of level vectors
+ * is required.
+ */
+ std::vector<unsigned int> mg_target_component;
+
/**
* Sizes of the multi-level vectors.
*/
#endif
};
-
+//TODO:[GK] Update this class
/**
* Implementation of the @p{MGTransferBase} interface for block
- * matrices and block vectors. In addition to the functionality of
+ * matrices and block vectors.
+ *
+ * Warning! Due to additional requirements on MGTransferSelect, the
+ * implementation in the base class has changed. Therefore, this class
+ * is left in an untested state. If you use it and you encounter
+ * problems, please contact Guido Kanschat.
+ *
+ * In addition to the functionality of
* @ref{MGTransferPrebuilt}, the operation may be restricted to
* certain blocks of the vector.
*
* transfer routines may only have as many components as there are
* @p{true}s in the selected-field.
*
+ * See @ref{MGTransferBase} to find out which of the transfer classes
+ * is best for your needs.
+ *
* @author Guido Kanschat, 2001, 2002
*/
template <typename number>
void build_matrices (const MGDoFHandler<dim> &mg_dof,
std::vector<bool> selected = std::vector<bool>(),
const std::vector<unsigned int>& target_component
+ = std::vector<unsigned int>(),
+ const std::vector<unsigned int>& mg_target_component
=std::vector<unsigned int>());
/**
};
+//TODO:[GK] Update documentation for copy_* functions
/**
* Implementation of the @p{MGTransferBase} interface for block
- * matrices and simple vectors. This class uses @ref{MGTransferBlock}
+ * matrices and simple vectors. This class uses @ref{MGTransferBlockBase}
* selecting a single component or grouping several components into a
* single block. The transfer operators themselves are implemented for
- * simple vectors again.
+ * Vector and BlockVector objects.
+ *
+ * See @ref{MGTransferBase} to find out which of the transfer classes
+ * is best for your needs.
*
* @author Guido Kanschat, 2001, 2002, 2003
*/
* Actually build the prolongation
* matrices for grouped components.
*
- * @p{selected} is the number of
- * the component for which the
+ * @p{selected} tells the copy
+ * functions operating on single
+ * vectors, which component this
+ * vector belongs to.
+ *
+ * @p{mg_selected} is the number
+ * of the component for which the
* transfer matrices should be
* built.
*
template <int dim>
void build_matrices (const MGDoFHandler<dim> &mg_dof,
unsigned int selected,
+ unsigned int mg_selected,
const std::vector<unsigned int>& target_component
+ = std::vector<unsigned int>(),
+ const std::vector<unsigned int>& mg_target_component
= std::vector<unsigned int>());
+ /**
+ * Change selected
+ * component. Handle with care!
+ */
+ void select (const unsigned int component);
+
/**
* Prolongate a vector from level
* @p{to_level-1} to level
* on each of the levels
* separately, i.a. an @p{MGVector}.
*/
- template <int dim, class InVector>
+ template <int dim, typename number2>
void
copy_to_mg (const MGDoFHandler<dim> &mg_dof,
MGLevelObject<Vector<number> > &dst,
- const InVector &src) const;
+ const Vector<number2> &src) const;
/**
* Transfer from multi-level vector to
* constrained degrees of freedom
* are set to zero.
*/
- template <int dim, class OutVector>
+ template <int dim, typename number2>
void
copy_from_mg (const MGDoFHandler<dim> &mg_dof,
- OutVector &dst,
+ Vector<number2> &dst,
const MGLevelObject<Vector<number> > &src) const;
/**
* function, but probably not for
* continuous elements.
*/
- template <int dim, class OutVector>
+ template <int dim, typename number2>
void
copy_from_mg_add (const MGDoFHandler<dim> &mg_dof,
- OutVector &dst,
+ Vector<number2> &dst,
+ const MGLevelObject<Vector<number> > &src) const;
+
+ /**
+ * Transfer from a vector on the
+ * global grid to vectors defined
+ * on each of the levels
+ * separately, i.a. an @p{MGVector}.
+ */
+ template <int dim, typename number2>
+ void
+ copy_to_mg (const MGDoFHandler<dim> &mg_dof,
+ MGLevelObject<Vector<number> > &dst,
+ const BlockVector<number2> &src) const;
+
+ /**
+ * Transfer from multi-level vector to
+ * normal vector.
+ *
+ * Copies data from active
+ * portions of an MGVector into
+ * the respective positions of a
+ * @p{Vector<number>}. In order to
+ * keep the result consistent,
+ * constrained degrees of freedom
+ * are set to zero.
+ */
+ template <int dim, typename number2>
+ void
+ copy_from_mg (const MGDoFHandler<dim> &mg_dof,
+ BlockVector<number2> &dst,
+ const MGLevelObject<Vector<number> > &src) const;
+
+ /**
+ * Add a multi-level vector to a
+ * normal vector.
+ *
+ * Works as the previous
+ * function, but probably not for
+ * continuous elements.
+ */
+ template <int dim, typename number2>
+ void
+ copy_from_mg_add (const MGDoFHandler<dim> &mg_dof,
+ BlockVector<number2> &dst,
const MGLevelObject<Vector<number> > &src) const;
private:
- /**
- * Selected component.
- */
- unsigned int selected;
+ /**
+ * Transfer from multi-level vector to
+ * normal vector.
+ *
+ * Copies data from active
+ * portions of an MGVector into
+ * the respective positions of a
+ * @p{Vector<number>}. In order to
+ * keep the result consistent,
+ * constrained degrees of freedom
+ * are set to zero.
+ */
+ template <int dim, class OutVector>
+ void
+ do_copy_from_mg (const MGDoFHandler<dim> &mg_dof,
+ OutVector &dst,
+ const MGLevelObject<Vector<number> > &src,
+ const unsigned int offset) const;
+ /**
+ * Add a multi-level vector to a
+ * normal vector.
+ *
+ * Works as the previous
+ * function, but probably not for
+ * continuous elements.
+ */
+ template <int dim, class OutVector>
+ void
+ do_copy_from_mg_add (const MGDoFHandler<dim> &mg_dof,
+ OutVector &dst,
+ const MGLevelObject<Vector<number> > &src,
+ const unsigned int offset) const;
/**
* Implementation of the
*/
template <int dim, class InVector>
void
- copy_to_mg (const MGDoFHandler<dim> &mg_dof,
- MGLevelObject<Vector<number> > &dst,
- const InVector &src,
- const is_1d<true> &) const;
+ do_copy_to_mg (const MGDoFHandler<dim> &mg_dof,
+ MGLevelObject<Vector<number> > &dst,
+ const InVector &src,
+ const unsigned int offset,
+ const is_1d<true> &) const;
/**
* Same for all other space
*/
template <int dim, class InVector>
void
- copy_to_mg (const MGDoFHandler<dim> &mg_dof,
- MGLevelObject<Vector<number> > &dst,
- const InVector &src,
- const is_1d<false> &) const;
+ do_copy_to_mg (const MGDoFHandler<dim> &mg_dof,
+ MGLevelObject<Vector<number> > &dst,
+ const InVector &src,
+ const unsigned int offset,
+ const is_1d<false> &) const;
+
+ /**
+ * Selected component.
+ */
+ unsigned int selected_component;
};
+//----------------------------------------------------------------------//
+template <typename number>
+inline void
+MGTransferSelect<number>::select(const unsigned int component)
+{
+ selected_component = component;
+}
#endif
template <typename number>
template <int dim, class InVector>
void
-MGTransferPrebuilt<number>::copy_to_mg (const MGDoFHandler<dim> &mg_dof_handler,
- MGLevelObject<Vector<number> > &dst,
- const InVector &src) const
+MGTransferPrebuilt<number>::copy_to_mg (
+ const MGDoFHandler<dim> &mg_dof_handler,
+ MGLevelObject<Vector<number> > &dst,
+ const InVector &src) const
{
// forward to the correct
// specialization
template <typename number>
template <int dim, class InVector>
void
-MGTransferPrebuilt<number>::copy_to_mg (const MGDoFHandler<dim> &,
- MGLevelObject<Vector<number> > &,
- const InVector &,
- const is_1d<true> &) const
+MGTransferPrebuilt<number>::copy_to_mg (
+ const MGDoFHandler<dim> &,
+ MGLevelObject<Vector<number> > &,
+ const InVector &,
+ const is_1d<true> &) const
{
Assert(false, ExcNotImplemented());
}
template <typename number>
template <int dim, class InVector>
void
-MGTransferPrebuilt<number>::copy_to_mg (const MGDoFHandler<dim> &mg_dof_handler,
- MGLevelObject<Vector<number> > &dst,
- const InVector &src,
- const is_1d<false> &) const
+MGTransferPrebuilt<number>::copy_to_mg (
+ const MGDoFHandler<dim> &mg_dof_handler,
+ MGLevelObject<Vector<number> > &dst,
+ const InVector &src,
+ const is_1d<false> &) const
{
// Make src a real finite element function
// InVector src = osrc;
template <typename number>
template <int dim, class OutVector>
void
-MGTransferPrebuilt<number>::
-copy_from_mg(const MGDoFHandler<dim> &mg_dof_handler,
- OutVector &dst,
- const MGLevelObject<Vector<number> > &src) const
+MGTransferPrebuilt<number>::copy_from_mg(
+ const MGDoFHandler<dim> &mg_dof_handler,
+ OutVector &dst,
+ const MGLevelObject<Vector<number> > &src) const
{
const unsigned int dofs_per_cell = mg_dof_handler.get_fe().dofs_per_cell;
template <typename number>
template <int dim, class OutVector>
void
-MGTransferPrebuilt<number>::
-copy_from_mg_add (const MGDoFHandler<dim> &mg_dof_handler,
- OutVector &dst,
- const MGLevelObject<Vector<number> > &src) const
+MGTransferPrebuilt<number>::copy_from_mg_add (
+ const MGDoFHandler<dim> &mg_dof_handler,
+ OutVector &dst,
+ const MGLevelObject<Vector<number> > &src) const
{
const unsigned int dofs_per_cell = mg_dof_handler.get_fe().dofs_per_cell;
template <typename number>
-template <int dim, class InVector>
+template <int dim, typename number2>
void
-MGTransferSelect<number>::
-copy_to_mg (const MGDoFHandler<dim> &mg_dof_handler,
- MGLevelObject<Vector<number> > &dst,
- const InVector &src) const
+MGTransferSelect<number>::copy_to_mg (
+ const MGDoFHandler<dim> &mg_dof_handler,
+ MGLevelObject<Vector<number> > &dst,
+ const BlockVector<number2> &src) const
{
// forward to the correct
// specialization
- copy_to_mg (mg_dof_handler, dst, src, is_1d<(dim==1)>());
+ do_copy_to_mg (mg_dof_handler, dst, src, 0, is_1d<(dim==1)>());
+}
+
+
+
+template <typename number>
+template <int dim, typename number2>
+void
+MGTransferSelect<number>::copy_to_mg (
+ const MGDoFHandler<dim> &mg_dof_handler,
+ MGLevelObject<Vector<number> > &dst,
+ const Vector<number2> &src) const
+{
+ // forward to the correct
+ // specialization
+ do_copy_to_mg (mg_dof_handler, dst, src,
+ component_start[selected_component],
+ is_1d<(dim==1)>());
}
template <typename number>
template <int dim, class InVector>
void
-MGTransferSelect<number>::
-copy_to_mg (const MGDoFHandler<dim> &,
- MGLevelObject<Vector<number> > &,
- const InVector &,
- const is_1d<true> &) const
+MGTransferSelect<number>::do_copy_to_mg (
+ const MGDoFHandler<dim>&,
+ MGLevelObject<Vector<number> >&,
+ const InVector&,
+ const unsigned int,
+ const is_1d<true>&) const
{
Assert(false, ExcNotImplemented());
}
template <typename number>
template <int dim, class InVector>
void
-MGTransferSelect<number>::
-copy_to_mg (const MGDoFHandler<dim> &mg_dof_handler,
- MGLevelObject<Vector<number> > &dst,
- const InVector &osrc,
- const is_1d<false> &) const
+MGTransferSelect<number>::do_copy_to_mg (
+ const MGDoFHandler<dim>& mg_dof_handler,
+ MGLevelObject<Vector<number> >& dst,
+ const InVector& src,
+ const unsigned int offset,
+ const is_1d<false>&) const
{
// Make src a real finite element function
- InVector src = osrc;
+// InVector src = osrc;
// constraints->distribute(src);
const FiniteElement<dim>& fe = mg_dof_handler.get_fe();
Assert(sizes.size()==mg_dof_handler.get_tria().n_levels(),
ExcMatricesNotBuilt());
- for (unsigned int l=minlevel;l<=maxlevel;++l)
- dst[l].reinit(sizes[l][selected]);
+
+ MGTools::reinit_vector(mg_dof_handler, dst, selected, mg_target_component);
std::vector<unsigned int> global_dof_indices (dofs_per_cell);
std::vector<unsigned int> level_dof_indices (dofs_per_cell);
std::vector<unsigned int> level_face_indices (dofs_per_face);
- // Start of input vector inside a
- // block vector.
- const unsigned int start = component_start[selected];
-
// traverse the grid top-down
// (i.e. starting with the most
// refined grid). this way, we can
// already have built.
for (int level=maxlevel; level>=static_cast<signed int>(minlevel); --level)
{
- // Start of treated component
- // for this level
- const unsigned int level_start = mg_component_start[level][selected];
-
typename MGDoFHandler<dim>::active_cell_iterator
level_cell = mg_dof_handler.begin_active(level);
const typename MGDoFHandler<dim>::active_cell_iterator
// into the level-wise one
for (unsigned int i=0; i<dofs_per_cell; ++i)
{
- if (target_component[fe.system_to_component_index(i).first] == selected)
- dst[level](level_dof_indices[i] - level_start)
- = src(global_dof_indices[i] - start);
+ const unsigned int component
+ = mg_target_component[fe.system_to_component_index(i).first];
+ if (selected[component])
+ {
+ const unsigned int level_start
+ = mg_component_start[level][component];
+
+ dst[level](level_dof_indices[i] - level_start)
+ = src(global_dof_indices[i] - offset);
+ }
}
for (unsigned int face_n=0; face_n<GeometryInfo<dim>::faces_per_cell; ++face_n)
+template <typename number>
+template <int dim, typename number2>
+void
+MGTransferSelect<number>::copy_from_mg (
+ const MGDoFHandler<dim>& mg_dof_handler,
+ BlockVector<number2>& dst,
+ const MGLevelObject<Vector<number> >& src) const
+{
+ do_copy_from_mg (mg_dof_handler, dst, src, 0);
+}
+
+
+
+template <typename number>
+template <int dim, typename number2>
+void
+MGTransferSelect<number>::copy_from_mg (
+ const MGDoFHandler<dim>& mg_dof_handler,
+ Vector<number2>& dst,
+ const MGLevelObject<Vector<number> >& src) const
+{
+ do_copy_from_mg (mg_dof_handler, dst, src,
+ component_start[selected_component]);
+}
+
+
+
+template <typename number>
+template <int dim, typename number2>
+void
+MGTransferSelect<number>::copy_from_mg_add (
+ const MGDoFHandler<dim>& mg_dof_handler,
+ BlockVector<number2>& dst,
+ const MGLevelObject<Vector<number> >& src) const
+{
+ do_copy_from_mg_add (mg_dof_handler, dst, src, 0);
+}
+
+
+
+template <typename number>
+template <int dim, typename number2>
+void
+MGTransferSelect<number>::copy_from_mg_add (
+ const MGDoFHandler<dim>& mg_dof_handler,
+ Vector<number2>& dst,
+ const MGLevelObject<Vector<number> >& src) const
+{
+ do_copy_from_mg_add (mg_dof_handler, dst, src,
+ component_start[selected_component]);
+}
+
+
+
template <typename number>
template <int dim, class OutVector>
void
-MGTransferSelect<number>::
-copy_from_mg (const MGDoFHandler<dim> &mg_dof_handler,
- OutVector &dst,
- const MGLevelObject<Vector<number> > &src) const
+MGTransferSelect<number>::do_copy_from_mg (
+ const MGDoFHandler<dim> &mg_dof_handler,
+ OutVector &dst,
+ const MGLevelObject<Vector<number> > &src,
+ const unsigned int offset) const
{
const FiniteElement<dim>& fe = mg_dof_handler.get_fe();
const typename MGDoFHandler<dim>::active_cell_iterator
endc = mg_dof_handler.end();
- // Start of input vector inside a
- // block vector.
- const unsigned int start = component_start[selected];
-
// traverse all cells and copy the
// data appropriately to the output
// vector
DoFObjectAccessor<dim, dim>& global_cell = *level_cell;
const unsigned int level = level_cell->level();
- // Start of treated component
- // for this level
- const unsigned int level_start = mg_component_start[level][selected];
-
// get the dof numbers of
// this cell for the global
// and the level-wise
// copy level-wise data to
// global vector
for (unsigned int i=0; i<dofs_per_cell; ++i)
- if (target_component[fe.system_to_component_index(i).first] == selected)
- dst(global_dof_indices[i]-start)
- = src[level](level_dof_indices[i]-level_start);
+ {
+ const unsigned int component
+ = mg_target_component[fe.system_to_component_index(i).first];
+ if (selected[component])
+ {
+ const unsigned int level_start
+ = mg_component_start[level][component];
+ dst(global_dof_indices[i] - offset)
+ = src[level](level_dof_indices[i]-level_start);
+ }
+ }
};
// clear constrained nodes
template <typename number>
template <int dim, class OutVector>
void
-MGTransferSelect<number>::
-copy_from_mg_add (const MGDoFHandler<dim> &mg_dof_handler,
- OutVector &dst,
- const MGLevelObject<Vector<number> > &src) const
+MGTransferSelect<number>::do_copy_from_mg_add (
+ const MGDoFHandler<dim> &mg_dof_handler,
+ OutVector &dst,
+ const MGLevelObject<Vector<number> > &src,
+ const unsigned int offset) const
{
const FiniteElement<dim>& fe = mg_dof_handler.get_fe();
std::vector<unsigned int> global_dof_indices (dofs_per_cell);
std::vector<unsigned int> level_dof_indices (dofs_per_cell);
- // Start of input vector inside a
- // block vector.
- const unsigned int start = component_start[selected];
-
typename MGDoFHandler<dim>::active_cell_iterator
level_cell = mg_dof_handler.begin_active();
const typename MGDoFHandler<dim>::active_cell_iterator
DoFObjectAccessor<dim, dim>& global_cell = *level_cell;
const unsigned int level = level_cell->level();
- // Start of treated component
- // for this level
- const unsigned int level_start = mg_component_start[level][selected];
-
// get the dof numbers of
// this cell for the global
// and the level-wise
global_cell.get_dof_indices (global_dof_indices);
level_cell->get_mg_dof_indices(level_dof_indices);
-//TODO:[GK] Probably wrong for continuous elements
+//TODO:[GK+WB] Probably wrong for continuous elements
// copy level-wise data to
// global vector
for (unsigned int i=0; i<dofs_per_cell; ++i)
- if (target_component[fe.system_to_component_index(i).first] == selected)
- dst(global_dof_indices[i]-start)
- += src[level](level_dof_indices[i]-level_start);
- };
-
+ {
+ const unsigned int component
+ = mg_target_component[fe.system_to_component_index(i).first];
+ if (selected[component])
+ {
+ const unsigned int level_start
+ = mg_component_start[level][component];
+ dst(global_dof_indices[i] - offset)
+ += src[level](level_dof_indices[i] - level_start);
+ }
+ }
+ }
// clear constrained nodes
-//TODO:[GK] constraints->set_zero(dst);
+//TODO:[GK+WB] constraints->set_zero(dst);
}
template <typename number>
template <int dim, class InVector>
void
-MGTransferBlock<number>::
-copy_to_mg (const MGDoFHandler<dim> &mg_dof_handler,
- MGLevelObject<BlockVector<number> > &dst,
- const InVector &src) const
+MGTransferBlock<number>::copy_to_mg (
+ const MGDoFHandler<dim> &mg_dof_handler,
+ MGLevelObject<BlockVector<number> > &dst,
+ const InVector &src) const
{
// forward to the correct
// specialization
template <typename number>
template <int dim, class InVector>
void
-MGTransferBlock<number>::
-copy_to_mg (const MGDoFHandler<dim> &,
- MGLevelObject<BlockVector<number> > &,
- const InVector &,
- const is_1d<true> &) const
+MGTransferBlock<number>::copy_to_mg (
+ const MGDoFHandler<dim> &,
+ MGLevelObject<BlockVector<number> > &,
+ const InVector &,
+ const is_1d<true> &) const
{
Assert(false, ExcNotImplemented());
}
template <typename number>
template <int dim, class InVector>
void
-MGTransferBlock<number>::
-copy_to_mg (const MGDoFHandler<dim> &mg_dof_handler,
- MGLevelObject<BlockVector<number> > &dst,
- const InVector &src,
- const is_1d<false> &) const
+MGTransferBlock<number>::copy_to_mg (
+ const MGDoFHandler<dim> &mg_dof_handler,
+ MGLevelObject<BlockVector<number> > &dst,
+ const InVector &src,
+ const is_1d<false> &) const
{
// Make src a real finite element
// function
dst.clear();
- MGTools::reinit_vector(mg_dof_handler, dst, selected, target_component);
+ MGTools::reinit_vector(mg_dof_handler, dst, selected, mg_target_component);
std::vector<unsigned int> global_dof_indices (dofs_per_cell);
std::vector<unsigned int> level_dof_indices (dofs_per_cell);
template <typename number>
template <int dim, class OutVector>
void
-MGTransferBlock<number>::
-copy_from_mg (const MGDoFHandler<dim> &mg_dof_handler,
- OutVector &dst,
- const MGLevelObject<BlockVector<number> > &src) const
+MGTransferBlock<number>::copy_from_mg (
+ const MGDoFHandler<dim> &mg_dof_handler,
+ OutVector &dst,
+ const MGLevelObject<BlockVector<number> > &src) const
{
const FiniteElement<dim>& fe = mg_dof_handler.get_fe();
template <typename number>
template <int dim, class OutVector>
void
-MGTransferBlock<number>::
-copy_from_mg_add (const MGDoFHandler<dim> &mg_dof_handler,
- OutVector &dst,
- const MGLevelObject<BlockVector<number> > &src) const
+MGTransferBlock<number>::copy_from_mg_add (
+ const MGDoFHandler<dim> &mg_dof_handler,
+ OutVector &dst,
+ const MGLevelObject<BlockVector<number> > &src) const
{
const FiniteElement<dim>& fe = mg_dof_handler.get_fe();
const unsigned int dofs_per_cell = fe.dofs_per_cell;
}
-//TODO:[GK] Check if this function can be simplified
-// It took quite a lot of try and error to make it work with
-// target_component, so it is more grown than designed
-
template<int dim, typename number>
void
MGTools::reinit_vector (const MGDoFHandler<dim>& mg_dof,
Assert (selected.size() == target_component.size(),
ExcDimensionMismatch(selected.size(), target_component.size()));
-
- std::vector<bool> target_selected(selected.size(), false);
- for (unsigned int i=0;i<selected.size();++i)
- if (selected[i]) target_selected[target_component[i]] = true;
- unsigned int n_selected = std::accumulate(target_selected.begin(),
- target_selected.end(),
- 0U);
+ // Compute the number of blocks needed
+ const unsigned int n_selected
+ = std::accumulate(selected.begin(),
+ selected.end(),
+ 0U);
std::vector<std::vector<unsigned int> >
ndofs(mg_dof.get_tria().n_levels(),
}
+template<int dim, typename number>
+void
+MGTools::reinit_vector (const MGDoFHandler<dim>& mg_dof,
+ MGLevelObject<Vector<number> >& v,
+ const std::vector<bool>& selected,
+ const std::vector<unsigned int>& target_component)
+{
+ const unsigned int ncomp = mg_dof.get_fe().n_components();
+
+ Assert (selected.size() == target_component.size(),
+ ExcDimensionMismatch(selected.size(), target_component.size()));
+
+ // Compute the number of blocks needed
+ if (DEBUG)
+ {
+ const unsigned int n_selected
+ = std::accumulate(selected.begin(),
+ selected.end(),
+ 0U);
+ Assert(n_selected == 1, ExcDimensionMismatch(n_selected, 1));
+ }
+
+ unsigned int selected_block = 0;
+ while (!selected[selected_block])
+ ++selected_block;
+
+ std::vector<std::vector<unsigned int> >
+ ndofs(mg_dof.get_tria().n_levels(),
+ std::vector<unsigned int>(target_component.size()));
+
+ count_dofs_per_component (mg_dof, ndofs, target_component);
+
+ for (unsigned int level=v.get_minlevel();
+ level<=v.get_maxlevel();++level)
+ {
+ v[level].reinit(ndofs[level][selected_block]);
+ }
+}
+
+
const std::vector<bool>&,
const std::vector<unsigned int>&);
+template void MGTools::reinit_vector<deal_II_dimension> (
+ const MGDoFHandler<deal_II_dimension>&,
+ MGLevelObject<Vector<double> >&,
+ const std::vector<bool>&,
+ const std::vector<unsigned int>&);
+template void MGTools::reinit_vector<deal_II_dimension> (
+ const MGDoFHandler<deal_II_dimension>&,
+ MGLevelObject<Vector<float> >&,
+ const std::vector<bool>&,
+ const std::vector<unsigned int>&);
+
template void MGTools::count_dofs_per_component<deal_II_dimension> (
const MGDoFHandler<deal_II_dimension>&,
const MGDoFHandler<dim>& mg_dof,
const std::vector<bool>& select)
{
+ // Fill target component with
+ // standard values (identity) if it
+ // is empty
if (target_component.size() == 0)
{
target_component.resize(mg_dof.get_fe().n_components());
for (unsigned int i=0;i<target_component.size();++i)
target_component[i] = i;
} else {
+ // otherwise, check it for consistency
Assert (target_component.size() == mg_dof.get_fe().n_components(),
ExcDimensionMismatch(target_component.size(),
mg_dof.get_fe().n_components()));
Assert(i<target_component.size(),
ExcIndexRange(i,0,target_component.size()));
}
+ }
+ // Do the same for the multilevel
+ // components. These may be
+ // different.
+ if (mg_target_component.size() == 0)
+ {
+ mg_target_component.resize(mg_dof.get_fe().n_components());
+ for (unsigned int i=0;i<mg_target_component.size();++i)
+ mg_target_component[i] = i;
+ } else {
+ Assert (mg_target_component.size() == mg_dof.get_fe().n_components(),
+ ExcDimensionMismatch(mg_target_component.size(),
+ mg_dof.get_fe().n_components()));
+
+ for (unsigned int i=0;i<mg_target_component.size();++i)
+ {
+ Assert(i<mg_target_component.size(),
+ ExcIndexRange(i,0,mg_target_component.size()));
+ }
}
const FiniteElement<dim>& fe = mg_dof.get_fe();
+ // Effective number of components
+ // is the maximum entry in
+ // mg_target_component. This
+ // assumes that the values in that
+ // vector don't have holes.
const unsigned int n_components =
- *std::max_element(target_component.begin(), target_component.end()) + 1;
+ *std::max_element(mg_target_component.begin(), mg_target_component.end()) + 1;
const unsigned int dofs_per_cell = fe.dofs_per_cell;
const unsigned int n_levels = mg_dof.get_tria().n_levels();
+ // Selected refers to the component
+ // in mg_target_component.
selected = select;
Assert (selected.size() == fe.n_components(),
- ExcDimensionMismatch(selected.size(), fe.n_components()))
-
+ ExcDimensionMismatch(selected.size(), fe.n_components()));
+
+ // Compute the lengths of all blocks
sizes.resize(n_levels);
- MGTools::count_dofs_per_component(mg_dof, sizes, target_component);
+ MGTools::count_dofs_per_component(mg_dof, sizes, mg_target_component);
+
+ // Fill some index vectors
+ // for later use.
+ mg_component_start = sizes;
+ // Compute start indices from sizes
+ for (unsigned int l=0;l<mg_component_start.size();++l)
+ {
+ unsigned int k=0;
+ for (unsigned int i=0;i<mg_component_start[l].size();++i)
+ {
+ const unsigned int t=mg_component_start[l][i];
+ mg_component_start[l][i] = k;
+ k += t;
+ }
+ }
+
+ component_start.resize(target_component.size());
+ DoFTools::count_dofs_per_component(mg_dof, component_start, target_component);
+
+ unsigned int k=0;
+ for (unsigned int i=0;i<component_start.size();++i)
+ {
+ const unsigned int t=component_start[i];
+ component_start[i] = k;
+ k += t;
+ }
+
+// Building the matrices starts here!
// reset the size of the array of
// matrices. call resize(0) first,
= fe.system_to_component_index(i).first;
const unsigned int jcomp
= fe.system_to_component_index(j).first;
- if ((icomp==jcomp) && selected[target_component[icomp]])
+ if ((icomp==jcomp) && selected[mg_target_component[icomp]])
prolongation_sparsities[level]->add(dof_indices_child[i],
dof_indices_parent[j]);
};
{
const unsigned int icomp = fe.system_to_component_index(i).first;
const unsigned int jcomp = fe.system_to_component_index(j).first;
- if ((icomp==jcomp) && selected[target_component[icomp]])
+ if ((icomp==jcomp) && selected[mg_target_component[icomp]])
prolongation_matrices[level]->set(dof_indices_child[i],
dof_indices_parent[j],
prolongation(i,j));
};
};
};
- // Finally, fill some index vectors
- // for later use.
- mg_component_start = sizes;
- // Compute start indices from sizes
- for (unsigned int l=0;l<mg_component_start.size();++l)
- {
- unsigned int k=0;
- for (unsigned int i=0;i<mg_component_start[l].size();++i)
- {
- const unsigned int t=mg_component_start[l][i];
- mg_component_start[l][i] = k;
- k += t;
- }
- }
-
- component_start.resize(n_components);
- DoFTools::count_dofs_per_component(mg_dof, component_start);
-
- unsigned int k=0;
- for (unsigned int i=0;i<component_start.size();++i)
- {
- const unsigned int t=component_start[i];
- component_start[i] = k;
- k += t;
- }
#if defined(DEAL_PREFER_MATRIX_EZ) && 1 == 0
deallog.push("Transfer");
for (unsigned int level=0;level<n_levels-1; ++level)
void MGTransferBlock<number>::build_matrices (
const MGDoFHandler<dim> &mg_dof,
std::vector<bool> select,
- const std::vector<unsigned int>& t_component)
+ const std::vector<unsigned int>& t_component,
+ const std::vector<unsigned int>& mg_t_component)
{
if (select.size() == 0)
select = std::vector<bool> (mg_dof.get_fe().n_components(), true);
target_component = t_component;
+ mg_target_component = mg_t_component;
MGTransferBlockBase::build_matrices (mg_dof, select);
}
void MGTransferSelect<number>::build_matrices (
const MGDoFHandler<dim> &mg_dof,
unsigned int select,
- const std::vector<unsigned int>& t_component)
+ unsigned int mg_select,
+ const std::vector<unsigned int>& t_component,
+ const std::vector<unsigned int>& mg_t_component)
{
unsigned int ncomp = mg_dof.get_fe().n_components();
- selected = select;
+ selected_component = select;
std::vector<bool> s(ncomp, false);
- s[select] = true;
-
+ s[mg_select] = true;
+//TODO:[GK] Assert that select and mg_select access the same component
+// or figure out how to use different components
target_component = t_component;
+ mg_target_component = mg_t_component;
MGTransferBlockBase::build_matrices (mg_dof, s);
}
template
void MGTransferSelect<float>::build_matrices<deal_II_dimension>
(const MGDoFHandler<deal_II_dimension> &mg_dof,
- unsigned int, const std::vector<unsigned int>&);
+ unsigned int, unsigned int, const std::vector<unsigned int>&);
template
void MGTransferBlock<double>::build_matrices<deal_II_dimension>
template
void MGTransferSelect<double>::build_matrices<deal_II_dimension>
(const MGDoFHandler<deal_II_dimension> &mg_dof,
- unsigned int, const std::vector<unsigned int>&);
+ unsigned int, unsigned int, const std::vector<unsigned int>&);
template void
Assert ((to_level >= 1) && (to_level<=prolongation_matrices.size()),
ExcIndexRange (to_level, 1, prolongation_matrices.size()+1));
- prolongation_matrices[to_level-1]->block(selected, selected)
+ prolongation_matrices[to_level-1]->block(selected_component,
+ selected_component)
.vmult (dst, src);
}
Assert ((from_level >= 1) && (from_level<=prolongation_matrices.size()),
ExcIndexRange (from_level, 1, prolongation_matrices.size()+1));
- prolongation_matrices[from_level-1]->block(selected, selected)
+ prolongation_matrices[from_level-1]->block(selected_component,
+ selected_component)
.Tvmult_add (dst, src);
}
#include <grid/tria.h>
#include <grid/grid_generator.h>
#include <dofs/dof_renumbering.h>
+#include <dofs/dof_tools.h>
#include <fe/fe_dgp.h>
#include <fe/fe_dgq.h>
#include <fe/fe_q.h>
#include <multigrid/mg_dof_handler.h>
#include <multigrid/mg_transfer.h>
#include <multigrid/mg_dof_tools.h>
+#include <multigrid/mg_level_object.h>
#include <fstream>
#include <iostream>
+#include <iomanip>
#include <algorithm>
template <int dim>
void check_select(const FiniteElement<dim>& fe,
+ unsigned int selected,
std::vector<unsigned int> target_component,
std::vector<unsigned int> mg_target_component)
{
for (unsigned int l=0;l<tr.n_levels();++l)
DoFRenumbering::component_wise(mgdof, l, mg_target_component);
- std::vector<std::vector<unsigned int> > ndofs(mgdof.get_tria().n_levels());
- MGTools::count_dofs_per_component(mgdof, ndofs, mg_target_component);
- for (unsigned int l=0;l<ndofs.size();++l)
+ std::vector<std::vector<unsigned int> > mg_ndofs(mgdof.get_tria().n_levels());
+ MGTools::count_dofs_per_component(mgdof, mg_ndofs, mg_target_component);
+ for (unsigned int l=0;l<mg_ndofs.size();++l)
{
deallog << "Level " << l << " dofs:";
- for (unsigned int i=0;i<ndofs[l].size();++i)
- deallog << ' ' << ndofs[l][i];
+ for (unsigned int i=0;i<mg_ndofs[l].size();++i)
+ deallog << ' ' << mg_ndofs[l][i];
deallog << std::endl;
}
MGTransferSelect<double> transfer;
- transfer.build_matrices(mgdof, 0,
- mg_target_component);
+ transfer.build_matrices(mgdof, selected, selected,
+ target_component, mg_target_component);
- Vector<double> u2(ndofs[2][0]);
- Vector<double> u1(ndofs[1][0]);
- Vector<double> u0(ndofs[0][0]);
+ Vector<double> u2(mg_ndofs[2][0]);
+ Vector<double> u1(mg_ndofs[1][0]);
+ Vector<double> u0(mg_ndofs[0][0]);
u0 = 1;
transfer.prolongate(1,u1,u0);
deallog << "\tu1 " << u1.l2_norm()
<< "\tu0 " << u0.l2_norm()
<< std::endl;
+
+ // Check copy to mg and back
+ std::vector<unsigned int> ndofs (target_component.size());
+ DoFTools::count_dofs_per_component(mgdof, ndofs, target_component);
+ BlockVector<double> u;
+ u.reinit (ndofs);
+ for (unsigned int i=0;i<u.size();++i)
+ u(i) = i;
+
+ MGLevelObject<Vector<double> > v;
+ v.resize(2,2);
+ v[2].reinit(mg_ndofs[2][selected]);
+
+ transfer.copy_to_mg(mgdof, v, u);
+ for (unsigned int i=0; i<v[2].size();++i)
+ deallog << ' ' << (int) v[2](i);
+ deallog << std::endl;
}
int main()
std::ofstream logfile("transfer.output");
logfile.precision(3);
deallog.attach(logfile);
- deallog.depth_console(100);
+ deallog.depth_console(0);
// check_simple (FE_DGP<2>(0));
// check_simple (FE_DGP<2>(1));
v3[i] = i/2;
}
- check_select (FESystem<2>(FE_DGQ<2>(1), 4), v1, v1);
- check_select (FESystem<2>(FE_DGQ<2>(1), 4), v2, v2);
- check_select (FESystem<2>(FE_DGQ<2>(1), 4), v3, v3);
+ check_select (FESystem<2>(FE_DGQ<2>(1), 4), 0, v1, v1);
+ check_select (FESystem<2>(FE_DGQ<2>(1), 4), 1, v1, v1);
+ check_select (FESystem<2>(FE_DGQ<2>(1), 4), 0, v2, v2);
+ check_select (FESystem<2>(FE_DGQ<2>(1), 4), 0, v3, v3);
+ check_select (FESystem<2>(FE_DGQ<2>(1), 4), 1, v3, v3);
+ check_select (FESystem<2>(FE_DGQ<2>(1), 4), 0, v1, v3);
+ check_select (FESystem<2>(FE_DGQ<2>(1), 4), 1, v1, v3);
}
+
+
+
DEAL::Level 0 dofs: 4 4 4 4
DEAL::Level 1 dofs: 16 16 16 16
DEAL::Level 2 dofs: 64 64 64 64
+DEAL:Transfer::Selected 1 0 0 0
+DEAL:Transfer::com_start 0 64 128 192
+DEAL:Transfer::com_start[0] 0 4 8 12
+DEAL:Transfer::com_start[1] 0 16 32 48
+DEAL:Transfer::com_start[2] 0 64 128 192
DEAL::u0 2.00 u1 4.00 u2 8.00 u1 16.0 u0 32.0
+DEAL:: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
+DEAL::FESystem<2>[FE_DGQ<2>(1)^4]
+DEAL::Level 0 dofs: 4 4 4 4
+DEAL::Level 1 dofs: 16 16 16 16
+DEAL::Level 2 dofs: 64 64 64 64
+DEAL:Transfer::Selected 0 1 0 0
+DEAL:Transfer::com_start 0 64 128 192
+DEAL:Transfer::com_start[0] 0 4 8 12
+DEAL:Transfer::com_start[1] 0 16 32 48
+DEAL:Transfer::com_start[2] 0 64 128 192
+DEAL::u0 2.00 u1 4.00 u2 8.00 u1 16.0 u0 32.0
+DEAL:: 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
DEAL::FESystem<2>[FE_DGQ<2>(1)^4]
DEAL::Level 0 dofs: 16 0 0 0
DEAL::Level 1 dofs: 64 0 0 0
DEAL::Level 2 dofs: 256 0 0 0
+DEAL:Transfer::Selected 1 0 0 0
+DEAL:Transfer::com_start 0 256 256 256
+DEAL:Transfer::com_start[0] 0 16 16 16
+DEAL:Transfer::com_start[1] 0 64 64 64
+DEAL:Transfer::com_start[2] 0 256 256 256
DEAL::u0 4.00 u1 8.00 u2 16.0 u1 32.0 u0 64.0
+DEAL:: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
+DEAL::FESystem<2>[FE_DGQ<2>(1)^4]
+DEAL::Level 0 dofs: 8 8 0 0
+DEAL::Level 1 dofs: 32 32 0 0
+DEAL::Level 2 dofs: 128 128 0 0
+DEAL:Transfer::Selected 1 0 0 0
+DEAL:Transfer::com_start 0 128 256 256
+DEAL:Transfer::com_start[0] 0 8 16 16
+DEAL:Transfer::com_start[1] 0 32 64 64
+DEAL:Transfer::com_start[2] 0 128 256 256
+DEAL::u0 2.83 u1 5.66 u2 11.3 u1 22.6 u0 45.3
+DEAL:: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
+DEAL::FESystem<2>[FE_DGQ<2>(1)^4]
+DEAL::Level 0 dofs: 8 8 0 0
+DEAL::Level 1 dofs: 32 32 0 0
+DEAL::Level 2 dofs: 128 128 0 0
+DEAL:Transfer::Selected 0 1 0 0
+DEAL:Transfer::com_start 0 128 256 256
+DEAL:Transfer::com_start[0] 0 8 16 16
+DEAL:Transfer::com_start[1] 0 32 64 64
+DEAL:Transfer::com_start[2] 0 128 256 256
+DEAL::u0 2.83 u1 5.66 u2 11.3 u1 22.6 u0 45.3
+DEAL:: 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
+DEAL::FESystem<2>[FE_DGQ<2>(1)^4]
+DEAL::Level 0 dofs: 8 8 0 0
+DEAL::Level 1 dofs: 32 32 0 0
+DEAL::Level 2 dofs: 128 128 0 0
+DEAL:Transfer::Selected 1 0 0 0
+DEAL:Transfer::com_start 0 64 128 192
+DEAL:Transfer::com_start[0] 0 8 16 16
+DEAL:Transfer::com_start[1] 0 32 64 64
+DEAL:Transfer::com_start[2] 0 128 256 256
+DEAL::u0 2.83 u1 5.66 u2 11.3 u1 22.6 u0 45.3
+DEAL:: 0 1 2 3 64 65 66 67 4 5 6 7 68 69 70 71 8 9 10 11 72 73 74 75 12 13 14 15 76 77 78 79 16 17 18 19 80 81 82 83 20 21 22 23 84 85 86 87 24 25 26 27 88 89 90 91 28 29 30 31 92 93 94 95 32 33 34 35 96 97 98 99 36 37 38 39 100 101 102 103 40 41 42 43 104 105 106 107 44 45 46 47 108 109 110 111 48 49 50 51 112 113 114 115 52 53 54 55 116 117 118 119 56 57 58 59 120 121 122 123 60 61 62 63 124 125 126 127
DEAL::FESystem<2>[FE_DGQ<2>(1)^4]
DEAL::Level 0 dofs: 8 8 0 0
DEAL::Level 1 dofs: 32 32 0 0
DEAL::Level 2 dofs: 128 128 0 0
+DEAL:Transfer::Selected 0 1 0 0
+DEAL:Transfer::com_start 0 64 128 192
+DEAL:Transfer::com_start[0] 0 8 16 16
+DEAL:Transfer::com_start[1] 0 32 64 64
+DEAL:Transfer::com_start[2] 0 128 256 256
DEAL::u0 2.83 u1 5.66 u2 11.3 u1 22.6 u0 45.3
+DEAL:: 128 129 130 131 192 193 194 195 132 133 134 135 196 197 198 199 136 137 138 139 200 201 202 203 140 141 142 143 204 205 206 207 144 145 146 147 208 209 210 211 148 149 150 151 212 213 214 215 152 153 154 155 216 217 218 219 156 157 158 159 220 221 222 223 160 161 162 163 224 225 226 227 164 165 166 167 228 229 230 231 168 169 170 171 232 233 234 235 172 173 174 175 236 237 238 239 176 177 178 179 240 241 242 243 180 181 182 183 244 245 246 247 184 185 186 187 248 249 250 251 188 189 190 191 252 253 254 255