From 308868c417207d99d2149bd070f12584f0c09b41 Mon Sep 17 00:00:00 2001 From: Markus Blatt <mblatt@dune-project.org> Date: Wed, 27 Apr 2005 14:50:11 +0000 Subject: [PATCH] More elaborate examples for Dune::IndexSet. [[Imported from SVN: r1972]] --- doc/istl/comm/Makefile.am | 2 ++ doc/istl/comm/buildindexset.hh | 58 +++++++++++++++++++++++++++++++++ doc/istl/comm/communication.tex | 27 +++++++++++++-- doc/istl/comm/indexset.cc | 39 ++++++++-------------- doc/istl/comm/reverse.hh | 40 +++++++++++++++++++++++ 5 files changed, 138 insertions(+), 28 deletions(-) create mode 100644 doc/istl/comm/buildindexset.hh create mode 100644 doc/istl/comm/reverse.hh diff --git a/doc/istl/comm/Makefile.am b/doc/istl/comm/Makefile.am index 30ea425e2..f4d1c6e13 100644 --- a/doc/istl/comm/Makefile.am +++ b/doc/istl/comm/Makefile.am @@ -9,6 +9,8 @@ SUFFIXES = .dvi .tex .pdf dist_pkgdata_DATA = communication.pdf communication.ps +#communication.dvi_DEPENDENCIES = communication.tex indexset.cc reverse.hh + noinst_PROGRAMS = $(MPIPROGRAMS) indexset_SOURCES = indexset.cc diff --git a/doc/istl/comm/buildindexset.hh b/doc/istl/comm/buildindexset.hh new file mode 100644 index 000000000..c0b612453 --- /dev/null +++ b/doc/istl/comm/buildindexset.hh @@ -0,0 +1,58 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +// $Id$ +#ifndef BUILDINDEXSET_HH +#define BUILDINDEXSET_HH + + +#include <dune/istl/indexset.hh> +#include <dune/istl/plocalindex.hh> +#include "mpi.h" + +/** + * @brief Flag for marking the indices. + */ +enum Flag {owner, overlap}; + +// The type of local index we use +typedef Dune::ParallelLocalIndex<Flag> LocalIndex; + +/** + * @brief Add indices to the example index set. + * @param indexSet The index set to build. + */ +template<class TG, int N> +void build(Dune::IndexSet<TG,LocalIndex,N>& indexSet) +{ + // + // The number of processes + int size; + MPI_Comm_size(MPI_COMM_WORLD, &size); + + // The rank of our process + int rank; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + // Indicate that we add or remove indices. + indexSet.beginResize(); + + if(rank==0) { + indexSet.add(0, LocalIndex(0,overlap,true)); + indexSet.add(2, LocalIndex(1,owner,true)); + indexSet.add(6, LocalIndex(2,owner,true)); + indexSet.add(3, LocalIndex(3,owner,true)); + indexSet.add(5, LocalIndex(4,owner,true)); + } + + if(rank==1) { + indexSet.add(0, LocalIndex(0,owner,true)); + indexSet.add(1, LocalIndex(1,owner,true)); + indexSet.add(7, LocalIndex(2,owner,true)); + indexSet.add(5, LocalIndex(3,overlap,true)); + indexSet.add(4, LocalIndex(4,owner,true)); + } + + // Modification is over + indexSet.endResize(); +} +#endif diff --git a/doc/istl/comm/communication.tex b/doc/istl/comm/communication.tex index 2a4e59312..e038f54e0 100644 --- a/doc/istl/comm/communication.tex +++ b/doc/istl/comm/communication.tex @@ -147,6 +147,19 @@ to be persistent. Further on we will call this global identifier \lstinline!N! is used internally to specify the chunk size of the array list. +The pairs of global and local index are ordered by ascending global +index. Thus it it possible to access the pairs via +\lstinline!operator[](TG& global)! in $log(n)$ time, where $n$ is the +number of pairs in the set. + +Due to the ordering the index set can only be changed, i.~e. indices +added or deleted, in a special resize phase. By calling the functions +\lstinline!beginResize()! and \lstinline!endResize()! the programmer +indicates that the resize phase starts and ends, respectively. During +the call of \lstinline!endResize()! the deleted indices will be +removed and the added indices will be merged with the existing +ones. + To be able to attach further information to the index the only prerequesite for the type of the local index is that it is convertible to \lstinline!std::size_t! as it it meant for adressing array @@ -170,9 +183,19 @@ As the programmer often knows in advance which indices might also be present on other processes there is the possiblity to mark the index as public. -Let us look at a short example on how to use the classes: +\paragraph{Usage Examples} +Let us look at a short example on how to build an index set: + +\lstinputlisting[caption=Build an Index Set, +label=lst:build_indexset]{buildindexset.hh} + +Due to the complexity of \lstinline!operator[](TG& global)! it is +always advisable to use iterators to access the index pairs of the +set. +The following example demonstrates their usage: +\lstinputlisting[caption=Usage of Index Set Iterators, +label=lst:indexset_iterator]{reverse.hh} -\lstinputlisting[caption=build an index set, label=lst:build_indexset]{indexset.cc} \section{Remote Indices} \label{sec:remote-indices} diff --git a/doc/istl/comm/indexset.cc b/doc/istl/comm/indexset.cc index 44bf5da69..67e9b1b10 100644 --- a/doc/istl/comm/indexset.cc +++ b/doc/istl/comm/indexset.cc @@ -5,12 +5,8 @@ #include <dune/istl/plocalindex.hh> #include <iostream> #include "mpi.h" - -/** - * @brief Flag for marking the indices. - */ -enum Flag {owner, overlap}; - +#include "buildindexset.hh" +#include "reverse.hh" int main(int argc, char **argv) { @@ -20,11 +16,10 @@ int main(int argc, char **argv) // The number of processes int size; + MPI_Comm_size(MPI_COMM_WORLD, &size); // The rank of our process int rank; - - MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); // The type used as the local index @@ -40,30 +35,22 @@ int main(int argc, char **argv) // The index set IndexSet indexSet; - // Indicate that we add or remove indices. - indexSet.beginResize(); + build(indexSet); - if(rank==0) { - indexSet.add(0, LocalIndex(0,overlap,true)); - indexSet.add(2, LocalIndex(1,owner,true)); - indexSet.add(6, LocalIndex(2,owner,true)); - indexSet.add(3, LocalIndex(3,owner,true)); - indexSet.add(5, LocalIndex(4,owner,true)); - } - if(rank==1) { + // Print the index set + std::cout<<indexSet<<std::endl; - indexSet.add(0, LocalIndex(0,owner,true)); - indexSet.add(1, LocalIndex(1,owner,true)); - indexSet.add(7, LocalIndex(2,owner,true)); - indexSet.add(5, LocalIndex(3,overlap,true)); - indexSet.add(4, LocalIndex(4,owner,true)); - } - // Modification is over - indexSet.endResize(); + reverseLocalIndex(indexSet); // Print the index set + if(rank==0) + std::cout<<"Reordered lcoal indices:"<<std::endl; + + MPI_Barrier(MPI_COMM_WORLD); + std::cout<<indexSet<<std::endl; + // Assign new local indices // Let MPI do a cleanup MPI_Finalize(); diff --git a/doc/istl/comm/reverse.hh b/doc/istl/comm/reverse.hh new file mode 100644 index 000000000..abe015a75 --- /dev/null +++ b/doc/istl/comm/reverse.hh @@ -0,0 +1,40 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +// $Id$ +#ifndef REVERSE_HH +#define REVERSE_HH + +#include <dune/istl/plocalindex.hh> +#include <dune/istl/indexset.hh> + +/** + * @brief Reverse the local indices of an index set. + * + * Let the index set have N entries than the index 0 will become N-1, + * 1 become N-2, ..., and N-1 will become 0. + * @param indexSet The index set to reverse. + */ +template<typename TG, typename TL, int N> +void reverseLocalIndex(Dune::IndexSet<TG,TL,N>& indexSet) +{ + // reverse the local indices + typedef typename Dune::IndexSet<TG,TL,N>::iterator iterator; + + iterator end = indexSet.end(); + size_t maxLocal = 0; + + // find the maximal local index + for(iterator index = indexSet.begin(); index != end; ++index) { + // Get the local index + LocalIndex& local = index->local(); + maxLocal = std::max(maxLocal, local.local()); + } + + for(iterator index = indexSet.begin(); index != end; ++index) { + // Get the local index + LocalIndex& local = index->local(); + local = maxLocal--; + } + +} +#endif -- GitLab