3#ifndef DUNE_MATRIXMARKET_HH
4#define DUNE_MATRIXMARKET_HH
59 struct mm_numeric_type {
69 struct mm_numeric_type<int>
78 static std::string str()
85 struct mm_numeric_type<double>
94 static std::string str()
101 struct mm_numeric_type<float>
110 static std::string str()
117 struct mm_numeric_type<
std::complex<double> >
126 static std::string str()
133 struct mm_numeric_type<
std::complex<float> >
142 static std::string str()
157 struct mm_header_printer;
159 template<
typename T,
typename A,
int i,
int j>
160 struct mm_header_printer<BCRSMatrix<FieldMatrix<T,i,j>,A> >
162 static void print(std::ostream& os)
164 os<<
"%%MatrixMarket matrix coordinate ";
165 os<<mm_numeric_type<T>::str()<<
" general"<<std::endl;
169 template<
typename B,
typename A>
170 struct mm_header_printer<BlockVector<B,A> >
172 static void print(std::ostream& os)
174 os<<
"%%MatrixMarket matrix array ";
175 os<<mm_numeric_type<typename B::field_type>::str()<<
" general"<<std::endl;
179 template<
typename T,
int j>
180 struct mm_header_printer<FieldVector<T,j> >
182 static void print(std::ostream& os)
184 os<<
"%%MatrixMarket matrix array ";
185 os<<mm_numeric_type<T>::str()<<
" general"<<std::endl;
189 template<
typename T,
int i,
int j>
190 struct mm_header_printer<FieldMatrix<T,i,j> >
192 static void print(std::ostream& os)
194 os<<
"%%MatrixMarket matrix array ";
195 os<<mm_numeric_type<T>::str()<<
" general"<<std::endl;
208 struct mm_block_structure_header;
210 template<
typename T,
typename A,
int i>
211 struct mm_block_structure_header<BlockVector<FieldVector<T,i>,A> >
213 typedef BlockVector<FieldVector<T,i>,A> M;
215 static void print(std::ostream& os,
const M& m)
217 os<<
"% ISTL_STRUCT blocked ";
218 os<<i<<
" "<<1<<std::endl;
222 template<
typename T,
typename A,
int i,
int j>
223 struct mm_block_structure_header<BCRSMatrix<FieldMatrix<T,i,j>,A> >
225 typedef BCRSMatrix<FieldMatrix<T,i,j>,A> M;
227 static void print(std::ostream& os,
const M& m)
229 os<<
"% ISTL_STRUCT blocked ";
230 os<<i<<
" "<<j<<std::endl;
235 template<
typename T,
int i,
int j>
236 struct mm_block_structure_header<FieldMatrix<T,i,j> >
238 typedef FieldMatrix<T,i,j> M;
240 static void print(std::ostream& os,
const M& m)
244 template<
typename T,
int i>
245 struct mm_block_structure_header<FieldVector<T,i> >
247 typedef FieldVector<T,i> M;
249 static void print(std::ostream& os,
const M& m)
253 enum LineType { MM_HEADER, MM_ISTLSTRUCT, DATA };
254 enum { MM_MAX_LINE_LENGTH=1025 };
256 enum MM_TYPE { coordinate_type, array_type, unknown_type };
258 enum MM_CTYPE { integer_type, double_type, complex_type, pattern, unknown_ctype };
260 enum MM_STRUCTURE { general, symmetric, skew_symmetric, hermitian, unknown_structure };
265 : type(coordinate_type), ctype(double_type), structure(general)
269 MM_STRUCTURE structure;
272 bool lineFeed(std::istream& file)
296 void skipComments(std::istream& file)
304 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
310 bool readMatrixMarketBanner(std::istream& file, MMHeader& mmHeader)
319 std::cout<<buffer<<std::endl;
321 if(buffer!=
"%%MatrixMarket") {
323 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
334 if(buffer !=
"matrix")
337 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
351 std::transform(buffer.begin(), buffer.end(), buffer.begin(),
358 if(buffer !=
"array")
360 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
363 mmHeader.type=array_type;
367 if(buffer !=
"coordinate")
369 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
372 mmHeader.type=coordinate_type;
375 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
389 std::transform(buffer.begin(), buffer.end(), buffer.begin(),
395 if(buffer !=
"integer")
397 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
400 mmHeader.ctype=integer_type;
406 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
409 mmHeader.ctype=double_type;
413 if(buffer !=
"complex")
415 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
418 mmHeader.ctype=complex_type;
422 if(buffer !=
"pattern")
424 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
427 mmHeader.ctype=pattern;
430 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
439 std::transform(buffer.begin(), buffer.end(), buffer.begin(),
445 if(buffer !=
"general")
447 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
450 mmHeader.structure=general;
454 if(buffer !=
"hermitian")
456 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
459 mmHeader.structure=hermitian;
462 if(buffer.size()==1) {
463 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
471 if(buffer !=
"symmetric")
473 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
476 mmHeader.structure=symmetric;
480 if(buffer !=
"skew-symmetric")
482 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
485 mmHeader.structure=skew_symmetric;
488 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
492 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
495 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
501 void readNextLine(std::istream& file, std::ostringstream&, LineType& type)
508 while(index==0&&!file.eof())
511 while(!file.eof() && (c=file.get())==
' ') ;
514 while(!file.eof() && (c=file.get())==
'\n') {
519 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
527 template<std::
size_t brows, std::
size_t bcols>
529 calculateNNZ(std::size_t rows, std::size_t cols, std::size_t entries,
const MMHeader& header)
531 std::size_t blockrows=rows/brows;
532 std::size_t blockcols=cols/bcols;
533 std::size_t blocksize=brows*bcols;
534 std::size_t blockentries=0;
536 switch(header.structure)
539 blockentries = entries/blocksize;
break;
540 case skew_symmetric :
541 blockentries = 2*entries/blocksize;
break;
543 blockentries = (2*entries-rows)/blocksize;
break;
545 blockentries = (2*entries-rows)/blocksize;
break;
549 return Dune::make_tuple(blockrows, blockcols, blockentries);
559 struct IndexData :
public T
576 struct NumericWrapper
592 struct NumericWrapper<PatternDummy>
596 std::istream&
operator>>(std::istream& is, NumericWrapper<T>& num)
598 return is>>num.number;
601 std::istream&
operator>>(std::istream& is, NumericWrapper<PatternDummy>& num)
613 bool operator<(
const IndexData<T>& i1,
const IndexData<T>& i2)
615 return i1.index<i2.index;
624 std::istream&
operator>>(std::istream& is, IndexData<T>& data)
629 return is>>data.number;
638 template<
typename D,
int brows,
int bcols>
639 struct MatrixValuesSetter
647 void operator()(
const std::vector<std::set<IndexData<D> > >& rows,
650 for(
typename M::RowIterator iter=matrix.begin();
651 iter!= matrix.end(); ++iter)
653 for(
typename M::size_type brow=iter.index()*brows,
654 browend=iter.index()*brows+brows;
655 brow<browend; ++brow)
657 typedef typename std::set<IndexData<D> >::const_iterator Siter;
658 for(Siter siter=rows[brow].begin(), send=rows[brow].end();
659 siter != send; ++siter)
660 (*iter)[siter->index/bcols][brow%brows][siter->index%bcols]=siter->number;
666 template<
int brows,
int bcols>
667 struct MatrixValuesSetter<PatternDummy,brows,bcols>
670 void operator()(
const std::vector<std::set<IndexData<PatternDummy> > >& rows,
675 template<
typename T,
typename A,
int brows,
int bcols,
typename D>
677 std::istream& file, std::size_t entries,
678 const MMHeader& mmHeader,
const D&)
684 std::vector<std::set<IndexData<D> > > rows(matrix.N()*brows);
686 for(; entries>0; --entries) {
692 assert(row/bcols<matrix.N());
694 assert(data.index/bcols<matrix.M());
695 rows[row].insert(data);
699 if(mmHeader.structure!= general)
704 for(
typename Matrix::CreateIterator iter=matrix.createbegin();
705 iter!= matrix.createend(); ++iter)
707 for(std::size_t brow=iter.index()*brows, browend=iter.index()*brows+brows;
708 brow<browend; ++brow)
710 typedef typename std::set<IndexData<D> >::const_iterator Siter;
711 for(Siter siter=rows[brow].begin(), send=rows[brow].end();
712 siter != send; ++siter, ++nnz)
713 iter.insert(siter->index/bcols);
720 MatrixValuesSetter<D,brows,bcols> Setter;
722 Setter(rows, matrix);
730 void mm_read_header(std::size_t& rows, std::size_t& cols, MMHeader& header, std::istream& istr,
733 if(!readMatrixMarketBanner(istr, header)) {
734 std::cerr <<
"First line was not a correct Matrix Market banner. Using default:\n"
735 <<
"%%MatrixMarket matrix coordinate real general"<<std::endl;
738 istr.seekg(0, std::ios::beg);
740 header.type=array_type;
746 throw MatrixMarketFormatError();
751 throw MatrixMarketFormatError();
755 template<
typename T,
typename A,
int entries>
760 for(
int i=0; size>0; ++i, --size) {
763 vector[i/entries][i%entries]=val;
774 template<
typename T,
typename A,
int entries>
779 std::size_t rows, cols;
780 mm_read_header(rows,cols,header,istr,
true);
782 DUNE_THROW(MatrixMarketFormatError,
"cols!=1, therefore this is no vector!");
784 if(header.type!=array_type)
785 DUNE_THROW(MatrixMarketFormatError,
"Vectors have to be stored in array format!");
787 std::size_t size=rows/entries;
788 if(size*entries!=rows)
789 DUNE_THROW(MatrixMarketFormatError,
"Block size of vector is not correct1");
793 istr.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
795 mm_read_vector_entries(vector, rows, istr);
805 template<
typename T,
typename A,
int brows,
int bcols>
810 if(!readMatrixMarketBanner(istr, header)) {
811 std::cerr <<
"First line was not a correct Matrix Market banner. Using default:\n"
812 <<
"%%MatrixMarket matrix coordinate real general"<<std::endl;
815 istr.seekg(0, std::ios::beg);
819 std::size_t rows, cols, entries;
822 throw MatrixMarketFormatError();
827 throw MatrixMarketFormatError();
831 throw MatrixMarketFormatError();
835 std::size_t nnz, blockrows, blockcols;
837 Dune::tie(blockrows, blockcols, nnz) = calculateNNZ<brows, bcols>(rows, cols, entries, header);
839 istr.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
842 matrix.setSize(blockrows, blockcols);
845 if(header.type==array_type)
848 readSparseEntries(matrix, istr, entries, header, NumericWrapper<T>());
852 struct mm_multipliers
855 template<
typename B,
int i,
int j,
typename A>
856 struct mm_multipliers<BCRSMatrix<FieldMatrix<B,i,j>,A> >
864 template<
typename B,
int i,
int j>
865 void mm_print_entry(
const FieldMatrix<B,i,j>& entry,
866 typename FieldMatrix<B,i,j>::size_type rowidx,
867 typename FieldMatrix<B,i,j>::size_type colidx,
872 for(riterator row=entry.begin(); row != entry.end(); ++row, ++rowidx) {
874 for(citerator col = row->begin(); col != row->end(); ++col, ++coli)
875 ostr<< rowidx<<
" "<<coli<<
" "<<*col<<std::endl;
881 void mm_print_vector_entry(
const V& entry, std::ostream& ostr,
882 const integral_constant<int,1>&)
884 ostr<<entry<<std::endl;
889 void mm_print_vector_entry(
const V& vector, std::ostream& ostr,
890 const integral_constant<int,0>&)
893 const int isnumeric = mm_numeric_type<typename V::block_type>::is_numeric;
894 typedef typename V::const_iterator VIter;
896 for(VIter i=vector.begin(); i != vector.end(); ++i)
898 mm_print_vector_entry(*i, ostr,
899 integral_constant<int,isnumeric>());
902 template<
typename T,
typename A,
int i>
903 std::size_t countEntries(
const BlockVector<FieldVector<T,i>,A>& vector)
905 return vector.size()*i;
910 void writeMatrixMarket(
const V& vector, std::ostream& ostr,
911 const integral_constant<int,0>&)
913 ostr<<countEntries(vector)<<
" "<<1<<std::endl;
914 const int isnumeric = mm_numeric_type<typename V::block_type>::is_numeric;
915 mm_print_vector_entry(vector,ostr, integral_constant<int,isnumeric>());
920 void writeMatrixMarket(
const M& matrix,
922 const integral_constant<int,1>&)
924 ostr<<matrix.M()*mm_multipliers<M>::rows<<
" "
925 <<matrix.N()*mm_multipliers<M>::cols<<
" "
928 typedef typename M::const_iterator riterator;
929 typedef typename M::ConstColIterator citerator;
930 for(riterator row=matrix.begin(); row != matrix.end(); ++row)
931 for(citerator col = row->begin(); col != row->end(); ++col)
933 mm_print_entry(*col, row.index()*mm_multipliers<M>::rows+1,
934 col.index()*mm_multipliers<M>::cols+1, ostr);
942 void writeMatrixMarket(
const M& matrix,
946 mm_header_printer<M>::print(ostr);
947 mm_block_structure_header<M>::print(ostr,matrix);
965 std::string filename)
967 std::ofstream file(filename.c_str());
968 file.setf(std::ios::scientific,std::ios::floatfield);
969 writeMatrixMarket(matrix, file);
987 template<
typename M,
typename G,
typename L>
989 std::string filename,
991 bool storeIndices=
true)
994 int rank = comm.communicator().
rank();
996 std::ostringstream rfilename;
997 rfilename<<filename <<
"_"<<rank<<
".mm";
998 std::cout<< rfilename.str()<<std::endl;
999 std::ofstream file(rfilename.str().c_str());
1000 file.setf(std::ios::scientific,std::ios::floatfield);
1001 writeMatrixMarket(matrix, file);
1009 rfilename<<filename<<
"_"<<rank<<
".idx";
1010 file.open(rfilename.str().c_str());
1011 file.setf(std::ios::scientific,std::ios::floatfield);
1013 typedef typename IndexSet::const_iterator Iterator;
1016 file << iter->global()<<
" "<<(std::size_t)iter->local()<<
" "
1017 <<(int)iter->local().attribute()<<
" "<<(int)iter->local().isPublic()<<std::endl;
1020 file<<
"neighbours:";
1021 const std::set<int>& neighbours=comm.
remoteIndices().getNeighbours();
1022 typedef std::set<int>::const_iterator SIter;
1023 for(SIter neighbour=neighbours.begin(); neighbour != neighbours.end(); ++neighbour) {
1024 file<<
" "<< *neighbour;
1043 template<
typename M,
typename G,
typename L>
1045 const std::string& filename,
1047 bool readIndices=
true)
1050 typedef typename LocalIndex::Attribute Attribute;
1052 int rank = comm.communicator().
rank();
1054 std::ostringstream rfilename;
1055 rfilename<<filename <<
"_"<<rank<<
".mm";
1057 file.open(rfilename.str().c_str(), std::ios::in);
1072 rfilename<<filename<<
"_"<<rank<<
".idx";
1073 file.open(rfilename.str().c_str());
1078 while(!file.eof() && file.peek()!=
'n') {
1095 if(s!=
"neighbours:")
1096 DUNE_THROW(MatrixMarketFormatError,
"was exspecting the string: \"neighbours:\"");
1098 while(!file.eof()) {
1104 comm.ri.setNeighbours(nb);
1106 comm.ri.template rebuild<false>();
1121 template<
typename M>
1123 const std::string& filename)
1126 file.open(filename.c_str(), std::ios::in);
Implementation of the BCRSMatrix class.
A sparse block matrix with compressed row storage.
Definition: bcrsmatrix.hh:414
A vector of blocks with memory management.
Definition: bvector.hh:254
int rank() const
Return rank, is between 0 and size()-1.
Definition: mpicollectivecommunication.hh:162
ConstIterator const_iterator
typedef for stl compliant access
Definition: densematrix.hh:290
row_type::ConstIterator ConstColIterator
rename the iterators for easier access
Definition: densematrix.hh:294
Base class for Dune-Exceptions.
Definition: exceptions.hh:92
A dense n x m matrix.
Definition: fmatrix.hh:67
vector space out of a tensor product of fields.
Definition: fvector.hh:92
Default exception class for I/O errors.
Definition: exceptions.hh:257
Index Set Interface base class.
Definition: indexidset.hh:78
IndexType size(GeometryType type) const
Return total number of entities of given geometry type in entity set .
Definition: indexidset.hh:204
Exception indicating that the index set is not in the expected state.
Definition: indexset.hh:205
An index present on the local process.
Definition: localindex.hh:34
Default exception for dummy implementations.
Definition: exceptions.hh:289
A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
Definition: owneroverlapcopy.hh:173
const ParallelIndexSet & indexSet() const
Get the underlying parallel index set.
Definition: owneroverlapcopy.hh:466
const RemoteIndices & remoteIndices() const
Get the underlying remote indices.
Definition: owneroverlapcopy.hh:475
A Tuple of objects.
Definition: tuples.hh:294
Implements a matrix constructed from a given type representing a field and compile-time given number ...
iterator begin()
Get an iterator over the indices positioned at the first index.
iterator end()
Get an iterator over the indices positioned after the last index.
LI LocalIndex
The type of the local index, e.g. ParallelLocalIndex.
Definition: indexset.hh:239
std::istream & operator>>(std::istream &is, Pair< T1, T2 > &pair)
Read a pair or tuple.
Definition: tuples.hh:949
#define DUNE_THROW(E, m)
Definition: exceptions.hh:244
void readMatrixMarket(Dune::BlockVector< Dune::FieldVector< T, entries >, A > &vector, std::istream &istr)
Reads a BlockVector from a matrix market file.
Definition: matrixmarket.hh:775
void loadMatrixMarket(M &matrix, const std::string &filename, OwnerOverlapCopyCommunication< G, L > &comm, bool readIndices=true)
Load a parallel matrix/vector stored in matrix market format.
Definition: matrixmarket.hh:1044
void storeMatrixMarket(const M &matrix, std::string filename)
Stores a parallel matrix/vector in matrix market format in a file.
Definition: matrixmarket.hh:964
int countNonZeros(const M &matrix)
Get the number of nonzero fields in the matrix.
Definition: matrixutils.hh:155
Some handy generic functions for ISTL matrices.
Dune namespace.
Definition: alignment.hh:14
Classes providing communication interfaces for overlapping Schwarz methods.
Test whether a type is an ISTL Matrix.
Definition: matrixutils.hh:453
Generate a type for a given integral constant.
Definition: typetraits.hh:457
Fallback implementation of the std::tuple class.
Definition of the DUNE_UNUSED macro for the case that config.h is not available.
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentional unused function parameters with.
Definition: unused.hh:18