Dune Core Modules (2.3.1)

matrixmarket.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_MATRIXMARKET_HH
4 #define DUNE_MATRIXMARKET_HH
5 
6 #include <ostream>
7 #include <istream>
8 #include <fstream>
9 #include <sstream>
10 #include <limits>
11 #include <ios>
12 #include "matrixutils.hh"
13 #include "bcrsmatrix.hh"
14 #include "owneroverlapcopy.hh"
15 #include <dune/common/fmatrix.hh>
16 #include <dune/common/tuples.hh>
17 #include <dune/common/unused.hh>
18 
19 namespace Dune
20 {
21 
47  namespace
48  {
58  template<class T>
59  struct mm_numeric_type {
60  enum {
64  is_numeric=false
65  };
66  };
67 
68  template<>
69  struct mm_numeric_type<int>
70  {
71  enum {
75  is_numeric=true
76  };
77 
78  static std::string str()
79  {
80  return "integer";
81  }
82  };
83 
84  template<>
85  struct mm_numeric_type<double>
86  {
87  enum {
91  is_numeric=true
92  };
93 
94  static std::string str()
95  {
96  return "real";
97  }
98  };
99 
100  template<>
101  struct mm_numeric_type<float>
102  {
103  enum {
107  is_numeric=true
108  };
109 
110  static std::string str()
111  {
112  return "real";
113  }
114  };
115 
116  template<>
117  struct mm_numeric_type<std::complex<double> >
118  {
119  enum {
123  is_numeric=true
124  };
125 
126  static std::string str()
127  {
128  return "complex";
129  }
130  };
131 
132  template<>
133  struct mm_numeric_type<std::complex<float> >
134  {
135  enum {
139  is_numeric=true
140  };
141 
142  static std::string str()
143  {
144  return "complex";
145  }
146  };
147 
156  template<class M>
157  struct mm_header_printer;
158 
159  template<typename T, typename A, int i, int j>
160  struct mm_header_printer<BCRSMatrix<FieldMatrix<T,i,j>,A> >
161  {
162  static void print(std::ostream& os)
163  {
164  os<<"%%MatrixMarket matrix coordinate ";
165  os<<mm_numeric_type<T>::str()<<" general"<<std::endl;
166  }
167  };
168 
169  template<typename B, typename A>
170  struct mm_header_printer<BlockVector<B,A> >
171  {
172  static void print(std::ostream& os)
173  {
174  os<<"%%MatrixMarket matrix array ";
175  os<<mm_numeric_type<typename B::field_type>::str()<<" general"<<std::endl;
176  }
177  };
178 
179  template<typename T, int j>
180  struct mm_header_printer<FieldVector<T,j> >
181  {
182  static void print(std::ostream& os)
183  {
184  os<<"%%MatrixMarket matrix array ";
185  os<<mm_numeric_type<T>::str()<<" general"<<std::endl;
186  }
187  };
188 
189  template<typename T, int i, int j>
190  struct mm_header_printer<FieldMatrix<T,i,j> >
191  {
192  static void print(std::ostream& os)
193  {
194  os<<"%%MatrixMarket matrix array ";
195  os<<mm_numeric_type<T>::str()<<" general"<<std::endl;
196  }
197  };
198 
207  template<class M>
208  struct mm_block_structure_header;
209 
210  template<typename T, typename A, int i>
211  struct mm_block_structure_header<BlockVector<FieldVector<T,i>,A> >
212  {
213  typedef BlockVector<FieldVector<T,i>,A> M;
214 
215  static void print(std::ostream& os, const M& m)
216  {
217  os<<"% ISTL_STRUCT blocked ";
218  os<<i<<" "<<1<<std::endl;
219  }
220  };
221 
222  template<typename T, typename A, int i, int j>
223  struct mm_block_structure_header<BCRSMatrix<FieldMatrix<T,i,j>,A> >
224  {
225  typedef BCRSMatrix<FieldMatrix<T,i,j>,A> M;
226 
227  static void print(std::ostream& os, const M& m)
228  {
229  os<<"% ISTL_STRUCT blocked ";
230  os<<i<<" "<<j<<std::endl;
231  }
232  };
233 
234 
235  template<typename T, int i, int j>
236  struct mm_block_structure_header<FieldMatrix<T,i,j> >
237  {
238  typedef FieldMatrix<T,i,j> M;
239 
240  static void print(std::ostream& os, const M& m)
241  {}
242  };
243 
244  template<typename T, int i>
245  struct mm_block_structure_header<FieldVector<T,i> >
246  {
247  typedef FieldVector<T,i> M;
248 
249  static void print(std::ostream& os, const M& m)
250  {}
251  };
252 
253  enum LineType { MM_HEADER, MM_ISTLSTRUCT, DATA };
254  enum { MM_MAX_LINE_LENGTH=1025 };
255 
256  enum MM_TYPE { coordinate_type, array_type, unknown_type };
257 
258  enum MM_CTYPE { integer_type, double_type, complex_type, pattern, unknown_ctype };
259 
260  enum MM_STRUCTURE { general, symmetric, skew_symmetric, hermitian, unknown_structure };
261 
262  struct MMHeader
263  {
264  MMHeader()
265  : type(coordinate_type), ctype(double_type), structure(general)
266  {}
267  MM_TYPE type;
268  MM_CTYPE ctype;
269  MM_STRUCTURE structure;
270  };
271 
272  bool lineFeed(std::istream& file)
273  {
274  char c;
275  if(!file.eof())
276  c=file.peek();
277  else
278  return false;
279  // ignore whitespace
280  while(c==' ')
281  {
282  file.get();
283  if(file.eof())
284  return false;
285  c=file.peek();
286  }
287 
288  if(c=='\n') {
289  /* eat the line feed */
290  file.get();
291  return true;
292  }
293  return false;
294  }
295 
296  void skipComments(std::istream& file)
297  {
298  lineFeed(file);
299  char c=file.peek();
300  // ignore comment lines
301  while(c=='%')
302  {
303  /* disgard the rest of the line */
304  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
305  c=file.peek();
306  }
307  }
308 
309 
310  bool readMatrixMarketBanner(std::istream& file, MMHeader& mmHeader)
311  {
312  std::string buffer;
313  char c;
314  file >> buffer;
315  c=buffer[0];
316  mmHeader=MMHeader();
317  if(c!='%')
318  return false;
319  std::cout<<buffer<<std::endl;
320  /* read the banner */
321  if(buffer!="%%MatrixMarket") {
322  /* disgard the rest of the line */
323  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
324  return false;
325  }
326 
327  if(lineFeed(file))
328  /* premature end of line */
329  return false;
330 
331  /* read the matrix_type */
332  file >> buffer;
333 
334  if(buffer != "matrix")
335  {
336  /* disgard the rest of the line */
337  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
338  return false;
339  }
340 
341  if(lineFeed(file))
342  /* premature end of line */
343  return false;
344 
345  /* The type of the matrix */
346  file >> buffer;
347 
348  if(buffer.empty())
349  return false;
350 
351  std::transform(buffer.begin(), buffer.end(), buffer.begin(),
352  tolower);
353 
354  switch(buffer[0])
355  {
356  case 'a' :
357  /* sanity check */
358  if(buffer != "array")
359  {
360  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
361  return false;
362  }
363  mmHeader.type=array_type;
364  break;
365  case 'c' :
366  /* sanity check */
367  if(buffer != "coordinate")
368  {
369  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
370  return false;
371  }
372  mmHeader.type=coordinate_type;
373  break;
374  default :
375  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
376  return false;
377  }
378 
379  if(lineFeed(file))
380  /* premature end of line */
381  return false;
382 
383  /* The numeric type used. */
384  file >> buffer;
385 
386  if(buffer.empty())
387  return false;
388 
389  std::transform(buffer.begin(), buffer.end(), buffer.begin(),
390  tolower);
391  switch(buffer[0])
392  {
393  case 'i' :
394  /* sanity check */
395  if(buffer != "integer")
396  {
397  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
398  return false;
399  }
400  mmHeader.ctype=integer_type;
401  break;
402  case 'r' :
403  /* sanity check */
404  if(buffer != "real")
405  {
406  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
407  return false;
408  }
409  mmHeader.ctype=double_type;
410  break;
411  case 'c' :
412  /* sanity check */
413  if(buffer != "complex")
414  {
415  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
416  return false;
417  }
418  mmHeader.ctype=complex_type;
419  break;
420  case 'p' :
421  /* sanity check */
422  if(buffer != "pattern")
423  {
424  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
425  return false;
426  }
427  mmHeader.ctype=pattern;
428  break;
429  default :
430  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
431  return false;
432  }
433 
434  if(lineFeed(file))
435  return false;
436 
437  file >> buffer;
438 
439  std::transform(buffer.begin(), buffer.end(), buffer.begin(),
440  tolower);
441  switch(buffer[0])
442  {
443  case 'g' :
444  /* sanity check */
445  if(buffer != "general")
446  {
447  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
448  return false;
449  }
450  mmHeader.structure=general;
451  break;
452  case 'h' :
453  /* sanity check */
454  if(buffer != "hermitian")
455  {
456  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
457  return false;
458  }
459  mmHeader.structure=hermitian;
460  break;
461  case 's' :
462  if(buffer.size()==1) {
463  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
464  return false;
465  }
466 
467  switch(buffer[1])
468  {
469  case 'y' :
470  /* sanity check */
471  if(buffer != "symmetric")
472  {
473  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
474  return false;
475  }
476  mmHeader.structure=symmetric;
477  break;
478  case 'k' :
479  /* sanity check */
480  if(buffer != "skew-symmetric")
481  {
482  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
483  return false;
484  }
485  mmHeader.structure=skew_symmetric;
486  break;
487  default :
488  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
489  return false;
490  }
491  default :
492  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
493  return false;
494  }
495  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
496  c=file.peek();
497  return true;
498 
499  }
500 
501  void readNextLine(std::istream& file, std::ostringstream&, LineType& type)
502  {
503  DUNE_UNUSED_PARAMETER(type);
504  char c;
505  std::size_t index=0;
506 
507  //empty lines will be disgarded and we will simply read the next line
508  while(index==0&&!file.eof())
509  {
510  // strip spaces
511  while(!file.eof() && (c=file.get())==' ') ;
512 
513  //read the rest of the line until comment
514  while(!file.eof() && (c=file.get())=='\n') {
515  switch(c)
516  {
517  case '%' :
518  /* disgard the rest of the line */
519  file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
520  }
521  }
522  }
523 
524  // buffer[index]='\0';
525  }
526 
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)
530  {
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;
535 
536  switch(header.structure)
537  {
538  case general :
539  blockentries = entries/blocksize; break;
540  case skew_symmetric :
541  blockentries = 2*entries/blocksize; break;
542  case symmetric :
543  blockentries = (2*entries-rows)/blocksize; break;
544  case hermitian :
545  blockentries = (2*entries-rows)/blocksize; break;
546  default :
547  throw Dune::NotImplemented();
548  }
549  return Dune::make_tuple(blockrows, blockcols, blockentries);
550  }
551 
552  /*
553  * @brief Storage class for the column index and the numeric value.
554  *
555  * \tparam T Either a NumericWrapper of the numeric type or PatternDummy
556  * for MatrixMarket pattern case.
557  */
558  template<typename T>
559  struct IndexData : public T
560  {
561  std::size_t index;
562  };
563 
564 
575  template<typename T>
576  struct NumericWrapper
577  {
578  T number;
579  operator T&()
580  {
581  return number;
582  }
583  };
584 
588  struct PatternDummy
589  {};
590 
591  template<>
592  struct NumericWrapper<PatternDummy>
593  {};
594 
595  template<typename T>
596  std::istream& operator>>(std::istream& is, NumericWrapper<T>& num)
597  {
598  return is>>num.number;
599  }
600 
601  std::istream& operator>>(std::istream& is, NumericWrapper<PatternDummy>& num)
602  {
604  return is;
605  }
606 
612  template<typename T>
613  bool operator<(const IndexData<T>& i1, const IndexData<T>& i2)
614  {
615  return i1.index<i2.index;
616  }
617 
623  template<typename T>
624  std::istream& operator>>(std::istream& is, IndexData<T>& data)
625  {
626  is>>data.index;
627  /* MatrixMarket indices are one based. Decrement for C++ */
628  --data.index;
629  return is>>data.number;
630  }
631 
638  template<typename D, int brows, int bcols>
639  struct MatrixValuesSetter
640  {
646  template<typename M>
647  void operator()(const std::vector<std::set<IndexData<D> > >& rows,
648  M& matrix)
649  {
650  for(typename M::RowIterator iter=matrix.begin();
651  iter!= matrix.end(); ++iter)
652  {
653  for(typename M::size_type brow=iter.index()*brows,
654  browend=iter.index()*brows+brows;
655  brow<browend; ++brow)
656  {
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;
661  }
662  }
663  }
664  };
665 
666  template<int brows, int bcols>
667  struct MatrixValuesSetter<PatternDummy,brows,bcols>
668  {
669  template<typename M>
670  void operator()(const std::vector<std::set<IndexData<PatternDummy> > >& rows,
671  M& matrix)
672  {}
673  };
674 
675  template<typename T, typename A, int brows, int bcols, typename D>
676  void readSparseEntries(Dune::BCRSMatrix<Dune::FieldMatrix<T,brows,bcols>,A>& matrix,
677  std::istream& file, std::size_t entries,
678  const MMHeader& mmHeader, const D&)
679  {
681  // First path
682  // store entries together with column index in a speparate
683  // data structure
684  std::vector<std::set<IndexData<D> > > rows(matrix.N()*brows);
685 
686  for(; entries>0; --entries) {
687  std::size_t row;
688  IndexData<D> data;
689  skipComments(file);
690  file>>row;
691  --row; // Index was 1 based.
692  assert(row/bcols<matrix.N());
693  file>>data;
694  assert(data.index/bcols<matrix.M());
695  rows[row].insert(data);
696  }
697 
698  // TODO extend to capture the nongeneral cases.
699  if(mmHeader.structure!= general)
700  DUNE_THROW(Dune::NotImplemented, "Only general is supported right now!");
701 
702  // Setup the matrix sparsity pattern
703  int nnz=0;
704  for(typename Matrix::CreateIterator iter=matrix.createbegin();
705  iter!= matrix.createend(); ++iter)
706  {
707  for(std::size_t brow=iter.index()*brows, browend=iter.index()*brows+brows;
708  brow<browend; ++brow)
709  {
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);
714  }
715  }
716 
717  //Set the matrix values
718  matrix=0;
719 
720  MatrixValuesSetter<D,brows,bcols> Setter;
721 
722  Setter(rows, matrix);
723  }
724  } // end anonymous namespace
725 
726  class MatrixMarketFormatError : public Dune::Exception
727  {};
728 
729 
730  void mm_read_header(std::size_t& rows, std::size_t& cols, MMHeader& header, std::istream& istr,
731  bool isVector)
732  {
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;
736  // Go to the beginning of the file
737  istr.clear() ;
738  istr.seekg(0, std::ios::beg);
739  if(isVector)
740  header.type=array_type;
741  }
742 
743  skipComments(istr);
744 
745  if(lineFeed(istr))
746  throw MatrixMarketFormatError();
747 
748  istr >> rows;
749 
750  if(lineFeed(istr))
751  throw MatrixMarketFormatError();
752  istr >> cols;
753  }
754 
755  template<typename T, typename A, int entries>
756  void mm_read_vector_entries(Dune::BlockVector<Dune::FieldVector<T,entries>,A>& vector,
757  std::size_t size,
758  std::istream& istr)
759  {
760  for(int i=0; size>0; ++i, --size) {
761  T val;
762  istr>>val;
763  vector[i/entries][i%entries]=val;
764  }
765  }
766 
767 
774  template<typename T, typename A, int entries>
776  std::istream& istr)
777  {
778  MMHeader header;
779  std::size_t rows, cols;
780  mm_read_header(rows,cols,header,istr, true);
781  if(cols!=1)
782  DUNE_THROW(MatrixMarketFormatError, "cols!=1, therefore this is no vector!");
783 
784  if(header.type!=array_type)
785  DUNE_THROW(MatrixMarketFormatError, "Vectors have to be stored in array format!");
786 
787  std::size_t size=rows/entries;
788  if(size*entries!=rows)
789  DUNE_THROW(MatrixMarketFormatError, "Block size of vector is not correct1");
790 
791  vector.resize(size);
792 
793  istr.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
794 
795  mm_read_vector_entries(vector, rows, istr);
796  }
797 
798 
805  template<typename T, typename A, int brows, int bcols>
807  std::istream& istr)
808  {
809  MMHeader header;
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;
813  // Go to the beginning of the file
814  istr.clear() ;
815  istr.seekg(0, std::ios::beg);
816  }
817  skipComments(istr);
818 
819  std::size_t rows, cols, entries;
820 
821  if(lineFeed(istr))
822  throw MatrixMarketFormatError();
823 
824  istr >> rows;
825 
826  if(lineFeed(istr))
827  throw MatrixMarketFormatError();
828  istr >> cols;
829 
830  if(lineFeed(istr))
831  throw MatrixMarketFormatError();
832 
833  istr >>entries;
834 
835  std::size_t nnz, blockrows, blockcols;
836 
837  Dune::tie(blockrows, blockcols, nnz) = calculateNNZ<brows, bcols>(rows, cols, entries, header);
838 
839  istr.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
840 
841 
842  matrix.setSize(blockrows, blockcols);
843  matrix.setBuildMode(Dune::BCRSMatrix<Dune::FieldMatrix<T,brows,bcols>,A>::row_wise);
844 
845  if(header.type==array_type)
846  DUNE_THROW(Dune::NotImplemented, "Array format currently not supported for matrices!");
847 
848  readSparseEntries(matrix, istr, entries, header, NumericWrapper<T>());
849  }
850 
851  template<typename M>
852  struct mm_multipliers
853  {};
854 
855  template<typename B, int i, int j, typename A>
856  struct mm_multipliers<BCRSMatrix<FieldMatrix<B,i,j>,A> >
857  {
858  enum {
859  rows = i,
860  cols = j
861  };
862  };
863 
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,
868  std::ostream& ostr)
869  {
870  typedef typename FieldMatrix<B,i,j>::const_iterator riterator;
871  typedef typename FieldMatrix<B,i,j>::ConstColIterator citerator;
872  for(riterator row=entry.begin(); row != entry.end(); ++row, ++rowidx) {
873  int coli=colidx;
874  for(citerator col = row->begin(); col != row->end(); ++col, ++coli)
875  ostr<< rowidx<<" "<<coli<<" "<<*col<<std::endl;
876  }
877  }
878 
879  // Write a vector entry
880  template<typename V>
881  void mm_print_vector_entry(const V& entry, std::ostream& ostr,
882  const integral_constant<int,1>&)
883  {
884  ostr<<entry<<std::endl;
885  }
886 
887  // Write a vector
888  template<typename V>
889  void mm_print_vector_entry(const V& vector, std::ostream& ostr,
890  const integral_constant<int,0>&)
891  {
892  // Is the entry a supported numeric type?
893  const int isnumeric = mm_numeric_type<typename V::block_type>::is_numeric;
894  typedef typename V::const_iterator VIter;
895 
896  for(VIter i=vector.begin(); i != vector.end(); ++i)
897 
898  mm_print_vector_entry(*i, ostr,
899  integral_constant<int,isnumeric>());
900  }
901 
902  template<typename T, typename A, int i>
903  std::size_t countEntries(const BlockVector<FieldVector<T,i>,A>& vector)
904  {
905  return vector.size()*i;
906  }
907 
908  // Version for writing vectors.
909  template<typename V>
910  void writeMatrixMarket(const V& vector, std::ostream& ostr,
911  const integral_constant<int,0>&)
912  {
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>());
916  }
917 
918  // Versions for writing matrices
919  template<typename M>
920  void writeMatrixMarket(const M& matrix,
921  std::ostream& ostr,
922  const integral_constant<int,1>&)
923  {
924  ostr<<matrix.M()*mm_multipliers<M>::rows<<" "
925  <<matrix.N()*mm_multipliers<M>::cols<<" "
926  <<countNonZeros(matrix)<<std::endl;
927 
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)
932  // Matrix Market indexing start with 1!
933  mm_print_entry(*col, row.index()*mm_multipliers<M>::rows+1,
934  col.index()*mm_multipliers<M>::cols+1, ostr);
935  }
936 
937 
941  template<typename M>
942  void writeMatrixMarket(const M& matrix,
943  std::ostream& ostr)
944  {
945  // Write header information
946  mm_header_printer<M>::print(ostr);
947  mm_block_structure_header<M>::print(ostr,matrix);
948  // Choose the correct function for matrix and vector
949  writeMatrixMarket(matrix,ostr,integral_constant<int,IsMatrix<M>::value>());
950  }
951 
952 
963  template<typename M>
964  void storeMatrixMarket(const M& matrix,
965  std::string filename)
966  {
967  std::ofstream file(filename.c_str());
968  file.setf(std::ios::scientific,std::ios::floatfield);
969  writeMatrixMarket(matrix, file);
970  file.close();
971  }
972 
973 #if HAVE_MPI
987  template<typename M, typename G, typename L>
988  void storeMatrixMarket(const M& matrix,
989  std::string filename,
991  bool storeIndices=true)
992  {
993  // Get our rank
994  int rank = comm.communicator().rank();
995  // Write the local matrix
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);
1002  file.close();
1003 
1004  if(!storeIndices)
1005  return;
1006 
1007  // Write the global to local index mapping
1008  rfilename.str("");
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;
1014  for(Iterator iter = comm.indexSet().begin();
1015  iter != comm.indexSet().end(); ++iter) {
1016  file << iter->global()<<" "<<(std::size_t)iter->local()<<" "
1017  <<(int)iter->local().attribute()<<" "<<(int)iter->local().isPublic()<<std::endl;
1018  }
1019  // Store neighbour information for efficient remote indices setup.
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;
1025  }
1026  file.close();
1027  }
1028 
1043  template<typename M, typename G, typename L>
1044  void loadMatrixMarket(M& matrix,
1045  const std::string& filename,
1047  bool readIndices=true)
1048  {
1050  typedef typename LocalIndex::Attribute Attribute;
1051  // Get our rank
1052  int rank = comm.communicator().rank();
1053  // load local matrix
1054  std::ostringstream rfilename;
1055  rfilename<<filename <<"_"<<rank<<".mm";
1056  std::ifstream file;
1057  file.open(rfilename.str().c_str(), std::ios::in);
1058  if(!file)
1059  DUNE_THROW(IOError, "Could not open file" << rfilename.str().c_str());
1060  //if(!file.is_open())
1061  //
1062  readMatrixMarket(matrix,file);
1063  file.close();
1064 
1065  if(!readIndices)
1066  return;
1067 
1068  // read indices
1070  IndexSet& pis=comm.pis;
1071  rfilename.str("");
1072  rfilename<<filename<<"_"<<rank<<".idx";
1073  file.open(rfilename.str().c_str());
1074  if(pis.size()!=0)
1075  DUNE_THROW(InvalidIndexSetState, "Index set is not empty!");
1076 
1077  pis.beginResize();
1078  while(!file.eof() && file.peek()!='n') {
1079  G g;
1080  file >>g;
1081  std::size_t l;
1082  file >>l;
1083  int c;
1084  file >>c;
1085  bool b;
1086  file >> b;
1087  pis.add(g,LocalIndex(l,Attribute(c),b));
1088  lineFeed(file);
1089  }
1090  pis.endResize();
1091  if(!file.eof()) {
1092  // read neighbours
1093  std::string s;
1094  file>>s;
1095  if(s!="neighbours:")
1096  DUNE_THROW(MatrixMarketFormatError, "was exspecting the string: \"neighbours:\"");
1097  std::set<int> nb;
1098  while(!file.eof()) {
1099  int i;
1100  file >> i;
1101  nb.insert(i);
1102  }
1103  file.close();
1104  comm.ri.setNeighbours(nb);
1105  }
1106  comm.ri.template rebuild<false>();
1107  }
1108 
1109  #endif
1110 
1121  template<typename M>
1122  void loadMatrixMarket(M& matrix,
1123  const std::string& filename)
1124  {
1125  std::ifstream file;
1126  file.open(filename.c_str(), std::ios::in);
1127  if(!file)
1128  DUNE_THROW(IOError, "Could not open file" << filename);
1129  readMatrixMarket(matrix,file);
1130  file.close();
1131  }
1132 
1134 }
1135 #endif
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
Manager class for the mapping between local indices and globally unique indices.
Definition: indexset.hh:218
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.
TL 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
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)