3#ifndef DUNE_ISTL_MATRIXMARKET_HH
4#define DUNE_ISTL_MATRIXMARKET_HH
47 namespace MatrixMarketImpl
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()
159 template<
typename T,
typename A,
int i,
int j>
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>
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;
210 template<
typename T,
typename A,
int i>
215 static void print(std::ostream& os,
const M&)
217 os<<
"% ISTL_STRUCT blocked ";
218 os<<i<<
" "<<1<<std::endl;
222 template<
typename T,
typename A,
int i,
int j>
227 static void print(std::ostream& os,
const 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 inline bool lineFeed(std::istream& file)
296 inline void skipComments(std::istream& file)
304 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
310 inline 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 template<std::
size_t brows, std::
size_t bcols>
502 std::tuple<std::size_t, std::size_t, std::size_t>
503 calculateNNZ(std::size_t rows, std::size_t cols, std::size_t entries,
const MMHeader& header)
505 std::size_t blockrows=rows/brows;
506 std::size_t blockcols=cols/bcols;
507 std::size_t blocksize=brows*bcols;
508 std::size_t blockentries=0;
510 switch(header.structure)
513 blockentries = entries/blocksize;
break;
514 case skew_symmetric :
515 blockentries = 2*entries/blocksize;
break;
517 blockentries = (2*entries-rows)/blocksize;
break;
519 blockentries = (2*entries-rows)/blocksize;
break;
523 return std::make_tuple(blockrows, blockcols, blockentries);
533 struct IndexData :
public T
570 std::istream&
operator>>(std::istream& is, NumericWrapper<T>& num)
572 return is>>num.number;
575 inline std::istream&
operator>>(std::istream& is, NumericWrapper<PatternDummy>& num)
587 bool operator<(
const IndexData<T>& i1,
const IndexData<T>& i2)
589 return i1.index<i2.index;
598 std::istream&
operator>>(std::istream& is, IndexData<T>& data)
603 return is>>data.number;
612 template<
typename D,
int brows,
int bcols>
621 void operator()(
const std::vector<std::set<IndexData<D> > >& rows,
624 for(
typename M::RowIterator iter=matrix.begin();
625 iter!= matrix.end(); ++iter)
627 for(
typename M::size_type brow=iter.index()*brows,
628 browend=iter.index()*brows+brows;
629 brow<browend; ++brow)
631 typedef typename std::set<IndexData<D> >::const_iterator Siter;
632 for(Siter siter=rows[brow].begin(), send=rows[brow].end();
633 siter != send; ++siter)
634 (*iter)[siter->index/bcols][brow%brows][siter->index%bcols]=siter->number;
640 template<
int brows,
int bcols>
641 struct MatrixValuesSetter<PatternDummy,brows,bcols>
644 void operator()(
const std::vector<std::set<IndexData<PatternDummy> > >& rows,
649 template<
typename T,
typename A,
int brows,
int bcols,
typename D>
651 std::istream& file, std::size_t entries,
652 const MMHeader& mmHeader,
const D&)
658 std::vector<std::set<IndexData<D> > > rows(matrix.N()*brows);
660 for(; entries>0; --entries) {
666 assert(row/bcols<matrix.N());
668 assert(data.index/bcols<matrix.M());
669 rows[row].insert(data);
673 if(mmHeader.structure!= general)
678 for(
typename Matrix::CreateIterator iter=matrix.createbegin();
679 iter!= matrix.createend(); ++iter)
681 for(std::size_t brow=iter.index()*brows, browend=iter.index()*brows+brows;
682 brow<browend; ++brow)
684 typedef typename std::set<IndexData<D> >::const_iterator Siter;
685 for(Siter siter=rows[brow].begin(), send=rows[brow].end();
686 siter != send; ++siter, ++nnz)
687 iter.insert(siter->index/bcols);
694 MatrixValuesSetter<D,brows,bcols> Setter;
696 Setter(rows, matrix);
704 inline void mm_read_header(std::size_t& rows, std::size_t& cols,
705 MatrixMarketImpl::MMHeader& header, std::istream& istr,
708 using namespace MatrixMarketImpl;
710 if(!readMatrixMarketBanner(istr, header)) {
711 std::cerr <<
"First line was not a correct Matrix Market banner. Using default:\n"
712 <<
"%%MatrixMarket matrix coordinate real general"<<std::endl;
715 istr.seekg(0, std::ios::beg);
717 header.type=array_type;
723 throw MatrixMarketFormatError();
728 throw MatrixMarketFormatError();
732 template<
typename T,
typename A,
int entries>
737 for(
int i=0; size>0; ++i, --size) {
740 vector[i/entries][i%entries]=val;
751 template<
typename T,
typename A,
int entries>
755 using namespace MatrixMarketImpl;
758 std::size_t rows, cols;
759 mm_read_header(rows,cols,header,istr,
true);
761 DUNE_THROW(MatrixMarketFormatError,
"cols!=1, therefore this is no vector!");
763 if(header.type!=array_type)
764 DUNE_THROW(MatrixMarketFormatError,
"Vectors have to be stored in array format!");
766 std::size_t size=rows/entries;
767 if(size*entries!=rows)
768 DUNE_THROW(MatrixMarketFormatError,
"Block size of vector is not correct!");
772 istr.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
774 mm_read_vector_entries(vector, rows, istr);
784 template<
typename T,
typename A,
int brows,
int bcols>
788 using namespace MatrixMarketImpl;
791 if(!readMatrixMarketBanner(istr, header)) {
792 std::cerr <<
"First line was not a correct Matrix Market banner. Using default:\n"
793 <<
"%%MatrixMarket matrix coordinate real general"<<std::endl;
796 istr.seekg(0, std::ios::beg);
800 std::size_t rows, cols, entries;
803 throw MatrixMarketFormatError();
808 throw MatrixMarketFormatError();
812 throw MatrixMarketFormatError();
816 std::size_t nnz, blockrows, blockcols;
818 std::tie(blockrows, blockcols, nnz) = calculateNNZ<brows, bcols>(rows, cols, entries, header);
820 istr.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
823 matrix.setSize(blockrows, blockcols);
826 if(header.type==array_type)
829 readSparseEntries(matrix, istr, entries, header, NumericWrapper<T>());
833 struct mm_multipliers
836 template<
typename B,
int i,
int j,
typename A>
837 struct mm_multipliers<BCRSMatrix<FieldMatrix<B,i,j>,A> >
845 template<
typename B,
int i,
int j>
846 void mm_print_entry(
const FieldMatrix<B,i,j>& entry,
847 typename FieldMatrix<B,i,j>::size_type rowidx,
848 typename FieldMatrix<B,i,j>::size_type colidx,
853 for(riterator row=entry.begin(); row != entry.end(); ++row, ++rowidx) {
855 for(citerator col = row->begin(); col != row->end(); ++col, ++coli)
856 ostr<< rowidx<<
" "<<coli<<
" "<<*col<<std::endl;
862 void mm_print_vector_entry(
const V& entry, std::ostream& ostr,
863 const std::integral_constant<int,1>&)
865 ostr<<entry<<std::endl;
870 void mm_print_vector_entry(
const V& vector, std::ostream& ostr,
871 const std::integral_constant<int,0>&)
873 using namespace MatrixMarketImpl;
876 const int isnumeric = mm_numeric_type<typename V::block_type>::is_numeric;
877 typedef typename V::const_iterator VIter;
879 for(VIter i=vector.begin(); i != vector.end(); ++i)
881 mm_print_vector_entry(*i, ostr,
882 std::integral_constant<int,isnumeric>());
885 template<
typename T,
typename A,
int i>
886 std::size_t countEntries(
const BlockVector<FieldVector<T,i>,A>& vector)
888 return vector.size()*i;
893 void writeMatrixMarket(
const V& vector, std::ostream& ostr,
894 const std::integral_constant<int,0>&)
896 using namespace MatrixMarketImpl;
898 ostr<<countEntries(vector)<<
" "<<1<<std::endl;
899 const int isnumeric = mm_numeric_type<typename V::block_type>::is_numeric;
900 mm_print_vector_entry(vector,ostr, std::integral_constant<int,isnumeric>());
905 void writeMatrixMarket(
const M& matrix,
907 const std::integral_constant<int,1>&)
909 ostr<<matrix.N()*mm_multipliers<M>::rows<<
" "
910 <<matrix.M()*mm_multipliers<M>::cols<<
" "
913 typedef typename M::const_iterator riterator;
914 typedef typename M::ConstColIterator citerator;
915 for(riterator row=matrix.begin(); row != matrix.end(); ++row)
916 for(citerator col = row->begin(); col != row->end(); ++col)
918 mm_print_entry(*col, row.index()*mm_multipliers<M>::rows+1,
919 col.index()*mm_multipliers<M>::cols+1, ostr);
927 void writeMatrixMarket(
const M& matrix,
930 using namespace MatrixMarketImpl;
933 mm_header_printer<M>::print(ostr);
934 mm_block_structure_header<M>::print(ostr,matrix);
952 std::string filename)
954 std::ofstream file(filename.c_str());
955 file.setf(std::ios::scientific,std::ios::floatfield);
956 writeMatrixMarket(matrix, file);
974 template<
typename M,
typename G,
typename L>
976 std::string filename,
978 bool storeIndices=
true)
981 int rank = comm.communicator().
rank();
983 std::ostringstream rfilename;
984 rfilename<<filename <<
"_"<<rank<<
".mm";
985 std::cout<< rfilename.str()<<std::endl;
986 std::ofstream file(rfilename.str().c_str());
987 file.setf(std::ios::scientific,std::ios::floatfield);
988 writeMatrixMarket(matrix, file);
996 rfilename<<filename<<
"_"<<rank<<
".idx";
997 file.open(rfilename.str().c_str());
998 file.setf(std::ios::scientific,std::ios::floatfield);
1000 typedef typename IndexSet::const_iterator Iterator;
1003 file << iter->global()<<
" "<<(std::size_t)iter->local()<<
" "
1004 <<(int)iter->local().attribute()<<
" "<<(int)iter->local().isPublic()<<std::endl;
1007 file<<
"neighbours:";
1008 const std::set<int>& neighbours=comm.
remoteIndices().getNeighbours();
1009 typedef std::set<int>::const_iterator SIter;
1010 for(SIter neighbour=neighbours.begin(); neighbour != neighbours.end(); ++neighbour) {
1011 file<<
" "<< *neighbour;
1030 template<
typename M,
typename G,
typename L>
1032 const std::string& filename,
1034 bool readIndices=
true)
1036 using namespace MatrixMarketImpl;
1039 typedef typename LocalIndex::Attribute Attribute;
1041 int rank = comm.communicator().
rank();
1043 std::ostringstream rfilename;
1044 rfilename<<filename <<
"_"<<rank<<
".mm";
1046 file.open(rfilename.str().c_str(), std::ios::in);
1061 rfilename<<filename<<
"_"<<rank<<
".idx";
1062 file.open(rfilename.str().c_str());
1067 while(!file.eof() && file.peek()!=
'n') {
1084 if(s!=
"neighbours:")
1085 DUNE_THROW(MatrixMarketFormatError,
"was expecting the string: \"neighbours:\"");
1087 while(!file.eof()) {
1093 comm.ri.setNeighbours(nb);
1095 comm.ri.template rebuild<false>();
1110 template<
typename M>
1112 const std::string& filename)
1115 file.open(filename.c_str(), std::ios::in);
Implementation of the BCRSMatrix class.
A sparse block matrix with compressed row storage.
Definition: bcrsmatrix.hh:423
A vector of blocks with memory management.
Definition: bvector.hh:317
int rank() const
Return rank, is between 0 and size()-1.
Definition: mpicollectivecommunication.hh:163
ConstIterator const_iterator
typedef for stl compliant access
Definition: densematrix.hh:267
std::remove_reference< const_row_reference >::type::ConstIterator ConstColIterator
rename the iterators for easier access
Definition: densematrix.hh:271
Base class for Dune-Exceptions.
Definition: exceptions.hh:94
A dense n x m matrix.
Definition: fmatrix.hh:68
vector space out of a tensor product of fields.
Definition: fvector.hh:93
Default exception class for I/O errors.
Definition: exceptions.hh:229
Index Set Interface base class.
Definition: indexidset.hh:76
IndexType size(GeometryType type) const
Return total number of entities of given geometry type in entity set .
Definition: indexidset.hh:220
Exception indicating that the index set is not in the expected state.
Definition: indexset.hh:204
An index present on the local process.
Definition: localindex.hh:33
Default exception for dummy implementations.
Definition: exceptions.hh:261
A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
Definition: owneroverlapcopy.hh:172
const ParallelIndexSet & indexSet() const
Get the underlying parallel index set.
Definition: owneroverlapcopy.hh:463
const RemoteIndices & remoteIndices() const
Get the underlying remote indices.
Definition: owneroverlapcopy.hh:472
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:238
Stream & operator>>(Stream &stream, std::tuple< Ts... > &t)
Read a std::tuple.
Definition: streamoperators.hh:41
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentionally unused function parameters with.
Definition: unused.hh:25
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
void readMatrixMarket(Dune::BlockVector< Dune::FieldVector< T, entries >, A > &vector, std::istream &istr)
Reads a BlockVector from a matrix market file.
Definition: matrixmarket.hh:752
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:1031
void storeMatrixMarket(const M &matrix, std::string filename)
Stores a parallel matrix/vector in matrix market format in a file.
Definition: matrixmarket.hh:951
int countNonZeros(const M &matrix)
Get the number of nonzero fields in the matrix.
Definition: matrixutils.hh:153
EnableIfInterOperable< T1, T2, bool >::type operator<(const RandomAccessIteratorFacade< T1, V1, R1, D > &lhs, const RandomAccessIteratorFacade< T2, V2, R2, D > &rhs)
Comparison operator.
Definition: iteratorfacades.hh:629
Some handy generic functions for ISTL matrices.
Dune namespace.
Definition: alignedallocator.hh:10
Classes providing communication interfaces for overlapping Schwarz methods.
Test whether a type is an ISTL Matrix.
Definition: matrixutils.hh:478
Functor to the data values of the matrix.
Definition: matrixmarket.hh:614
void operator()(const std::vector< std::set< IndexData< D > > > &rows, M &matrix)
Sets the matrixvalues.
Definition: matrixmarket.hh:621
a wrapper class of numeric values.
Definition: matrixmarket.hh:551
Utility class for marking the pattern type of the MatrixMarket matrices.
Definition: matrixmarket.hh:563
Helper metaprogram to get the matrix market string representation of the numeric type.
Definition: matrixmarket.hh:59
@ is_numeric
Whether T is a supported numeric type.
Definition: matrixmarket.hh:64
Definition of the DUNE_UNUSED macro for the case that config.h is not available.