5#ifndef DUNE_ISTL_MATRIXMARKET_HH
6#define DUNE_ISTL_MATRIXMARKET_HH
24#include <dune/common/exceptions.hh>
25#include <dune/common/fmatrix.hh>
26#include <dune/common/fvector.hh>
27#include <dune/common/gmpfield.hh>
28#include <dune/common/hybridutilities.hh>
29#include <dune/common/quadmath.hh>
30#include <dune/common/stdstreams.hh>
31#include <dune/common/simd/simd.hh>
66 namespace MatrixMarketImpl
86 static std::string str()
93 struct mm_numeric_type<int>
102 static std::string str()
109 struct mm_numeric_type<double>
118 static std::string str()
125 struct mm_numeric_type<float>
134 static std::string str()
141 template<
unsigned int precision>
142 struct mm_numeric_type<Dune::GMPField<precision>>
151 static std::string str()
160 struct mm_numeric_type<Dune::Float128>
169 static std::string str()
177 struct mm_numeric_type<
std::complex<double> >
186 static std::string str()
193 struct mm_numeric_type<
std::complex<float> >
202 static std::string str()
219 template<
typename T,
typename A>
222 static void print(std::ostream& os)
224 os<<
"%%MatrixMarket matrix coordinate ";
225 os<<mm_numeric_type<Simd::Scalar<typename Imp::BlockTraits<T>::field_type>>::str()<<
" general"<<std::endl;
229 template<
typename B,
typename A>
232 static void print(std::ostream& os)
234 os<<
"%%MatrixMarket matrix array ";
235 os<<mm_numeric_type<Simd::Scalar<typename Imp::BlockTraits<B>::field_type>>::str()<<
" general"<<std::endl;
239 template<
typename T,
int j>
240 struct mm_header_printer<FieldVector<T,j> >
242 static void print(std::ostream& os)
244 os<<
"%%MatrixMarket matrix array ";
245 os<<mm_numeric_type<T>::str()<<
" general"<<std::endl;
249 template<
typename T,
int i,
int j>
250 struct mm_header_printer<FieldMatrix<T,i,j> >
252 static void print(std::ostream& os)
254 os<<
"%%MatrixMarket matrix array ";
255 os<<mm_numeric_type<T>::str()<<
" general"<<std::endl;
270 template<
typename T,
typename A>
274 static_assert(IsNumber<T>::value,
"Only scalar entries are expected here!");
276 static void print(std::ostream& os,
const M&)
278 os<<
"% ISTL_STRUCT blocked ";
279 os<<
"1 1"<<std::endl;
283 template<
typename T,
typename A,
int i>
284 struct mm_block_structure_header<
BlockVector<FieldVector<T,i>,A> >
288 static void print(std::ostream& os,
const M&)
290 os<<
"% ISTL_STRUCT blocked ";
291 os<<i<<
" "<<1<<std::endl;
295 template<
typename T,
typename A>
296 struct mm_block_structure_header<BCRSMatrix<T,A> >
298 typedef BCRSMatrix<T,A> M;
299 static_assert(IsNumber<T>::value,
"Only scalar entries are expected here!");
301 static void print(std::ostream& os,
const M&)
303 os<<
"% ISTL_STRUCT blocked ";
304 os<<
"1 1"<<std::endl;
308 template<
typename T,
typename A,
int i,
int j>
309 struct mm_block_structure_header<BCRSMatrix<FieldMatrix<T,i,j>,A> >
311 typedef BCRSMatrix<FieldMatrix<T,i,j>,A> M;
313 static void print(std::ostream& os,
const M&)
315 os<<
"% ISTL_STRUCT blocked ";
316 os<<i<<
" "<<j<<std::endl;
321 template<
typename T,
int i,
int j>
322 struct mm_block_structure_header<FieldMatrix<T,i,j> >
324 typedef FieldMatrix<T,i,j> M;
326 static void print(std::ostream& ,
const M& )
330 template<
typename T,
int i>
331 struct mm_block_structure_header<FieldVector<T,i> >
333 typedef FieldVector<T,i> M;
335 static void print(std::ostream& ,
const M& )
339 enum LineType { MM_HEADER, MM_ISTLSTRUCT, DATA };
340 enum { MM_MAX_LINE_LENGTH=1025 };
342 enum MM_TYPE { coordinate_type, array_type, unknown_type };
344 enum MM_CTYPE { integer_type, double_type, complex_type, pattern, unknown_ctype };
346 enum MM_STRUCTURE { general, symmetric, skew_symmetric, hermitian, unknown_structure };
351 : type(coordinate_type), ctype(double_type), structure(general)
355 MM_STRUCTURE structure;
358 inline bool lineFeed(std::istream& file)
382 inline void skipComments(std::istream& file)
390 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
396 inline bool readMatrixMarketBanner(std::istream& file, MMHeader& mmHeader)
405 dverb<<buffer<<std::endl;
407 if(buffer!=
"%%MatrixMarket") {
409 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
420 if(buffer !=
"matrix")
423 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
437 std::transform(buffer.begin(), buffer.end(), buffer.begin(),
444 if(buffer !=
"array")
446 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
449 mmHeader.type=array_type;
453 if(buffer !=
"coordinate")
455 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
458 mmHeader.type=coordinate_type;
461 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
475 std::transform(buffer.begin(), buffer.end(), buffer.begin(),
481 if(buffer !=
"integer")
483 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
486 mmHeader.ctype=integer_type;
492 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
495 mmHeader.ctype=double_type;
499 if(buffer !=
"complex")
501 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
504 mmHeader.ctype=complex_type;
508 if(buffer !=
"pattern")
510 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
513 mmHeader.ctype=pattern;
516 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
525 std::transform(buffer.begin(), buffer.end(), buffer.begin(),
531 if(buffer !=
"general")
533 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
536 mmHeader.structure=general;
540 if(buffer !=
"hermitian")
542 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
545 mmHeader.structure=hermitian;
548 if(buffer.size()==1) {
549 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
557 if(buffer !=
"symmetric")
559 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
562 mmHeader.structure=symmetric;
566 if(buffer !=
"skew-symmetric")
568 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
571 mmHeader.structure=skew_symmetric;
574 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
579 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
582 file.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
588 template<std::
size_t brows, std::
size_t bcols>
589 std::tuple<std::size_t, std::size_t, std::size_t>
590 calculateNNZ(std::size_t rows, std::size_t cols, std::size_t entries,
const MMHeader& header)
592 std::size_t blockrows=rows/brows;
593 std::size_t blockcols=cols/bcols;
594 std::size_t blocksize=brows*bcols;
595 std::size_t blockentries=0;
597 switch(header.structure)
600 blockentries = entries/blocksize;
break;
601 case skew_symmetric :
602 blockentries = 2*entries/blocksize;
break;
604 blockentries = (2*entries-rows)/blocksize;
break;
606 blockentries = (2*entries-rows)/blocksize;
break;
608 throw Dune::NotImplemented();
610 return std::make_tuple(blockrows, blockcols, blockentries);
620 struct IndexData :
public T
622 std::size_t index = {};
657 std::istream& operator>>(std::istream& is, NumericWrapper<T>& num)
659 return is>>num.number;
662 inline std::istream& operator>>(std::istream& is, [[maybe_unused]] NumericWrapper<PatternDummy>& num)
673 bool operator<(
const IndexData<T>& i1,
const IndexData<T>& i2)
675 return i1.index<i2.index;
684 std::istream& operator>>(std::istream& is, IndexData<T>& data)
689 return is>>data.number;
698 std::istream& operator>>(std::istream& is, IndexData<
NumericWrapper<std::complex<T>>>& data)
708 data.number = {real.number, imag.number};
718 template<
typename D,
int brows,
int bcols>
727 void operator()(
const std::vector<std::set<IndexData<D> > >& rows,
730 static_assert(IsNumber<T>::value && brows==1 && bcols==1,
"Only scalar entries are expected here!");
731 for (
auto iter=matrix.
begin(); iter!= matrix.
end(); ++iter)
733 auto brow=iter.index();
734 for (
auto siter=rows[brow].begin(); siter != rows[brow].end(); ++siter)
735 (*iter)[siter->index] = siter->number;
745 void operator()(
const std::vector<std::set<IndexData<D> > >& rows,
746 BCRSMatrix<FieldMatrix<T,brows,bcols> >& matrix)
748 for (
auto iter=matrix.begin(); iter!= matrix.end(); ++iter)
750 for (
auto brow=iter.index()*brows,
751 browend=iter.index()*brows+brows;
752 brow<browend; ++brow)
754 for (
auto siter=rows[brow].begin(), send=rows[brow].end();
755 siter != send; ++siter)
756 (*iter)[siter->index/bcols][brow%brows][siter->index%bcols]=siter->number;
762 template<
int brows,
int bcols>
763 struct MatrixValuesSetter<PatternDummy,brows,bcols>
766 void operator()(
const std::vector<std::set<IndexData<PatternDummy> > >& ,
771 template<
class T>
struct is_complex : std::false_type {};
772 template<
class T>
struct is_complex<
std::complex<T>> : std::true_type {};
776 std::enable_if_t<!is_complex<T>::value, T> conj(
const T& r){
781 std::enable_if_t<is_complex<T>::value, T> conj(
const T& r){
786 struct mm_multipliers
789 template<
typename B,
typename A>
790 struct mm_multipliers<BCRSMatrix<B,A> >
798 template<
typename B,
int i,
int j,
typename A>
799 struct mm_multipliers<BCRSMatrix<FieldMatrix<B,i,j>,A> >
807 template<
typename T,
typename A,
typename D>
809 std::istream& file, std::size_t entries,
810 const MMHeader& mmHeader,
const D&)
815 constexpr int brows = mm_multipliers<Matrix>::rows;
816 constexpr int bcols = mm_multipliers<Matrix>::cols;
821 std::vector<std::set<IndexData<D> > > rows(matrix.
N()*brows);
823 auto readloop = [&] (
auto symmetryFixup) {
824 for(std::size_t i = 0; i < entries; ++i) {
830 assert(row/bcols<matrix.
N());
832 assert(data.index/bcols<matrix.
M());
833 rows[row].insert(data);
835 symmetryFixup(row, data);
839 switch(mmHeader.structure)
842 readloop([](
auto...){});
845 readloop([&](
auto row,
auto data) {
846 IndexData<D> data_sym(data);
847 data_sym.index = row;
848 rows[data.index].insert(data_sym);
851 case skew_symmetric :
852 readloop([&](
auto row,
auto data) {
853 IndexData<D> data_sym;
854 data_sym.number = -data.number;
855 data_sym.index = row;
856 rows[data.index].insert(data_sym);
860 readloop([&](
auto row,
auto data) {
861 IndexData<D> data_sym;
862 data_sym.number = conj(data.number);
863 data_sym.index = row;
864 rows[data.index].insert(data_sym);
868 DUNE_THROW(Dune::NotImplemented,
869 "Only general, symmetric, skew-symmetric and hermitian is supported right now!");
874 for(
typename Matrix::CreateIterator iter=matrix.
createbegin();
877 for(std::size_t brow=iter.index()*brows, browend=iter.index()*brows+brows;
878 brow<browend; ++brow)
880 typedef typename std::set<IndexData<D> >::const_iterator Siter;
881 for(Siter siter=rows[brow].begin(), send=rows[brow].end();
882 siter != send; ++siter, ++nnz)
883 iter.insert(siter->index/bcols);
890 MatrixValuesSetter<D,brows,bcols> Setter;
892 Setter(rows, matrix);
895 inline std::tuple<std::string, std::string> splitFilename(
const std::string& filename) {
896 std::size_t lastdot = filename.find_last_of(
".");
897 if(lastdot == std::string::npos)
898 return std::make_tuple(filename,
"");
900 std::string potentialFileExtension = filename.substr(lastdot);
901 if (potentialFileExtension ==
".mm" || potentialFileExtension ==
".mtx")
902 return std::make_tuple(filename.substr(0, lastdot), potentialFileExtension);
904 return std::make_tuple(filename,
"");
910 class MatrixMarketFormatError :
public Dune::Exception
914 inline void mm_read_header(std::size_t& rows, std::size_t& cols,
915 MatrixMarketImpl::MMHeader& header, std::istream& istr,
918 using namespace MatrixMarketImpl;
920 if(!readMatrixMarketBanner(istr, header)) {
921 std::cerr <<
"First line was not a correct Matrix Market banner. Using default:\n"
922 <<
"%%MatrixMarket matrix coordinate real general"<<std::endl;
925 istr.seekg(0, std::ios::beg);
927 header.type=array_type;
933 throw MatrixMarketFormatError();
938 throw MatrixMarketFormatError();
942 template<
typename T,
typename A>
948 for (
int i=0; size>0; ++i, --size)
949 istr>>Simd::lane(lane,vector[i]);
952 template<
typename T,
typename A,
int entries>
953 void mm_read_vector_entries(
Dune::BlockVector<Dune::FieldVector<T,entries>,A>& vector,
958 for(
int i=0; size>0; ++i, --size) {
961 Simd::lane(lane, vector[i/entries][i%entries])=val;
972 template<
typename T,
typename A>
977 using namespace MatrixMarketImpl;
980 std::size_t rows, cols;
981 mm_read_header(rows,cols,header,istr,
true);
982 if(cols!=Simd::lanes<field_type>()) {
983 if(Simd::lanes<field_type>() == 1)
984 DUNE_THROW(MatrixMarketFormatError,
"cols!=1, therefore this is no vector!");
986 DUNE_THROW(MatrixMarketFormatError,
"cols does not match the number of lanes in the field_type!");
989 if(header.type!=array_type)
990 DUNE_THROW(MatrixMarketFormatError,
"Vectors have to be stored in array format!");
993 if constexpr (Dune::IsNumber<T>())
998 auto blocksize = dummy.size();
999 std::size_t size=rows/blocksize;
1000 if(size*blocksize!=rows)
1001 DUNE_THROW(MatrixMarketFormatError,
"Block size of vector is not correct!");
1006 istr.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
1007 for(
size_t l=0;l<Simd::lanes<field_type>();++l){
1008 mm_read_vector_entries(vector, rows, istr, l);
1018 template<
typename T,
typename A>
1022 using namespace MatrixMarketImpl;
1026 if(!readMatrixMarketBanner(istr, header)) {
1027 std::cerr <<
"First line was not a correct Matrix Market banner. Using default:\n"
1028 <<
"%%MatrixMarket matrix coordinate real general"<<std::endl;
1031 istr.seekg(0, std::ios::beg);
1035 std::size_t rows, cols, entries;
1038 throw MatrixMarketFormatError();
1043 throw MatrixMarketFormatError();
1047 throw MatrixMarketFormatError();
1051 std::size_t nnz, blockrows, blockcols;
1054 constexpr int brows = mm_multipliers<Matrix>::rows;
1055 constexpr int bcols = mm_multipliers<Matrix>::cols;
1057 std::tie(blockrows, blockcols, nnz) = calculateNNZ<brows, bcols>(rows, cols, entries, header);
1059 istr.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
1062 matrix.
setSize(blockrows, blockcols, nnz);
1065 if(header.type==array_type)
1066 DUNE_THROW(Dune::NotImplemented,
"Array format currently not supported for matrices!");
1068 readSparseEntries(matrix, istr, entries, header, NumericWrapper<typename Matrix::field_type>());
1072 template<
typename B>
1073 void mm_print_entry(
const B& entry,
1078 if constexpr (IsNumber<B>())
1079 ostr << rowidx <<
" " << colidx <<
" " << entry << std::endl;
1082 for (
auto row=entry.begin(); row != entry.end(); ++row, ++rowidx) {
1084 for (
auto col = row->begin(); col != row->end(); ++col, ++coli)
1085 ostr<< rowidx<<
" "<<coli<<
" "<<*col<<std::endl;
1091 template<
typename V>
1092 void mm_print_vector_entry(
const V& entry, std::ostream& ostr,
1093 const std::integral_constant<int,1>&,
1096 ostr<<Simd::lane(lane,entry)<<std::endl;
1100 template<
typename V>
1101 void mm_print_vector_entry(
const V& vector, std::ostream& ostr,
1102 const std::integral_constant<int,0>&,
1105 using namespace MatrixMarketImpl;
1108 const int isnumeric = mm_numeric_type<Simd::Scalar<typename V::block_type>>::is_numeric;
1109 typedef typename V::const_iterator VIter;
1111 for(VIter i=vector.begin(); i != vector.end(); ++i)
1113 mm_print_vector_entry(*i, ostr,
1114 std::integral_constant<int,isnumeric>(),
1118 template<
typename T,
typename A>
1119 std::size_t countEntries(
const BlockVector<T,A>& vector)
1121 return vector.size();
1124 template<
typename T,
typename A,
int i>
1125 std::size_t countEntries(
const BlockVector<FieldVector<T,i>,A>& vector)
1127 return vector.size()*i;
1131 template<
typename V>
1133 const std::integral_constant<int,0>&)
1135 using namespace MatrixMarketImpl;
1136 typedef typename V::field_type field_type;
1138 ostr<<countEntries(vector)<<
" "<<Simd::lanes<field_type>()<<std::endl;
1139 const int isnumeric = mm_numeric_type<Simd::Scalar<V>>::is_numeric;
1140 for(
size_t l=0;l<Simd::lanes<field_type>(); ++l){
1141 mm_print_vector_entry(vector,ostr, std::integral_constant<int,isnumeric>(), l);
1146 template<
typename M>
1149 const std::integral_constant<int,1>&)
1151 ostr<<matrix.N()*MatrixMarketImpl::mm_multipliers<M>::rows<<
" "
1152 <<matrix.M()*MatrixMarketImpl::mm_multipliers<M>::cols<<
" "
1155 typedef typename M::const_iterator riterator;
1156 typedef typename M::ConstColIterator citerator;
1157 for(riterator row=matrix.begin(); row != matrix.end(); ++row)
1158 for(citerator col = row->begin(); col != row->end(); ++col)
1160 mm_print_entry(*col, row.index()*MatrixMarketImpl::mm_multipliers<M>::rows+1,
1161 col.index()*MatrixMarketImpl::mm_multipliers<M>::cols+1, ostr);
1168 template<
typename M>
1172 using namespace MatrixMarketImpl;
1175 mm_header_printer<M>::print(ostr);
1176 mm_block_structure_header<M>::print(ostr,matrix);
1181 static const int default_precision = -1;
1193 template<
typename M>
1195 std::string filename,
1196 int prec=default_precision)
1198 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename(filename);
1199 std::string rfilename;
1201 if (extension !=
"") {
1202 rfilename = pureFilename + extension;
1203 file.open(rfilename.c_str());
1205 DUNE_THROW(IOError,
"Could not open file for storage: " << rfilename.c_str());
1209 rfilename = pureFilename +
".mm";
1210 file.open(rfilename.c_str());
1212 DUNE_THROW(IOError,
"Could not open file for storage: " << rfilename.c_str());
1215 file.setf(std::ios::scientific,std::ios::floatfield);
1217 file.precision(prec);
1237 template<
typename M,
typename G,
typename L>
1239 std::string filename,
1241 bool storeIndices=
true,
1242 int prec=default_precision)
1245 int rank = comm.communicator().rank();
1247 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename(filename);
1248 std::string rfilename;
1250 if (extension !=
"") {
1251 rfilename = pureFilename +
"_" + std::to_string(rank) + extension;
1252 file.open(rfilename.c_str());
1253 dverb<< rfilename <<std::endl;
1255 DUNE_THROW(IOError,
"Could not open file for storage: " << rfilename.c_str());
1259 rfilename = pureFilename +
"_" + std::to_string(rank) +
".mm";
1260 file.open(rfilename.c_str());
1261 dverb<< rfilename <<std::endl;
1263 DUNE_THROW(IOError,
"Could not open file for storage: " << rfilename.c_str());
1265 file.setf(std::ios::scientific,std::ios::floatfield);
1267 file.precision(prec);
1275 rfilename = pureFilename +
"_" + std::to_string(rank) +
".idx";
1276 file.open(rfilename.c_str());
1278 DUNE_THROW(IOError,
"Could not open file for storage: " << rfilename.c_str());
1279 file.setf(std::ios::scientific,std::ios::floatfield);
1281 typedef typename IndexSet::const_iterator Iterator;
1282 for(Iterator iter = comm.
indexSet().begin();
1283 iter != comm.
indexSet().end(); ++iter) {
1284 file << iter->global()<<
" "<<(std::size_t)iter->local()<<
" "
1285 <<(int)iter->local().attribute()<<
" "<<(int)iter->local().isPublic()<<std::endl;
1288 file<<
"neighbours:";
1289 const std::set<int>& neighbours=comm.
remoteIndices().getNeighbours();
1290 typedef std::set<int>::const_iterator SIter;
1291 for(SIter neighbour=neighbours.begin(); neighbour != neighbours.end(); ++neighbour) {
1292 file<<
" "<< *neighbour;
1311 template<
typename M,
typename G,
typename L>
1313 const std::string& filename,
1315 bool readIndices=
true)
1317 using namespace MatrixMarketImpl;
1320 typedef typename LocalIndexT::Attribute Attribute;
1322 int rank = comm.communicator().rank();
1324 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename(filename);
1325 std::string rfilename;
1327 if (extension !=
"") {
1328 rfilename = pureFilename +
"_" + std::to_string(rank) + extension;
1329 file.open(rfilename.c_str(), std::ios::in);
1330 dverb<< rfilename <<std::endl;
1332 DUNE_THROW(IOError,
"Could not open file: " << rfilename.c_str());
1336 rfilename = pureFilename +
"_" + std::to_string(rank) +
".mm";
1337 file.open(rfilename.c_str(), std::ios::in);
1339 rfilename = pureFilename +
"_" + std::to_string(rank) +
".mtx";
1340 file.open(rfilename.c_str(), std::ios::in);
1341 dverb<< rfilename <<std::endl;
1343 DUNE_THROW(IOError,
"Could not open file: " << rfilename.c_str());
1354 IndexSet& pis=comm.pis;
1355 rfilename = pureFilename +
"_" + std::to_string(rank) +
".idx";
1356 file.open(rfilename.c_str());
1358 DUNE_THROW(IOError,
"Could not open file: " << rfilename.c_str());
1360 DUNE_THROW(InvalidIndexSetState,
"Index set is not empty!");
1363 while(!file.eof() && file.peek()!=
'n') {
1372 pis.add(g,LocalIndexT(l,Attribute(c),b));
1380 if(s!=
"neighbours:")
1381 DUNE_THROW(MatrixMarketFormatError,
"was expecting the string: \"neighbours:\"");
1383 while(!file.eof()) {
1389 comm.ri.setNeighbours(nb);
1391 comm.ri.template rebuild<false>();
1406 template<
typename M>
1408 const std::string& filename)
1410 auto [pureFilename, extension] = MatrixMarketImpl::splitFilename(filename);
1411 std::string rfilename;
1413 if (extension !=
"") {
1414 rfilename = pureFilename + extension;
1415 file.open(rfilename.c_str());
1417 DUNE_THROW(IOError,
"Could not open file: " << rfilename.c_str());
1421 rfilename = pureFilename +
".mm";
1422 file.open(rfilename.c_str(), std::ios::in);
1424 rfilename = pureFilename +
".mtx";
1425 file.open(rfilename.c_str(), std::ios::in);
1427 DUNE_THROW(IOError,
"Could not open file: " << rfilename.c_str());
Implementation of the BCRSMatrix class.
This file implements a vector space as a tensor product of a given vector space. The number of compon...
A sparse block matrix with compressed row storage.
Definition: bcrsmatrix.hh:468
Iterator begin()
Get iterator to first row.
Definition: bcrsmatrix.hh:673
Iterator end()
Get iterator to one beyond last row.
Definition: bcrsmatrix.hh:679
CreateIterator createend()
get create iterator pointing to one after the last block
Definition: bcrsmatrix.hh:1107
size_type M() const
number of columns (counted in blocks)
Definition: bcrsmatrix.hh:2014
CreateIterator createbegin()
get initial create iterator
Definition: bcrsmatrix.hh:1101
size_type N() const
number of rows (counted in blocks)
Definition: bcrsmatrix.hh:2008
void setBuildMode(BuildMode bm)
Sets the build mode of the matrix.
Definition: bcrsmatrix.hh:832
void setSize(size_type rows, size_type columns, size_type nnz=0)
Set the size of the matrix.
Definition: bcrsmatrix.hh:860
A vector of blocks with memory management.
Definition: bvector.hh:392
void resize(size_type size)
Resize the vector.
Definition: bvector.hh:496
typename Imp::BlockTraits< B >::field_type field_type
export the type representing the field
Definition: bvector.hh:398
A generic dynamic dense matrix.
Definition: matrix.hh:561
A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
Definition: owneroverlapcopy.hh:174
const ParallelIndexSet & indexSet() const
Get the underlying parallel index set.
Definition: owneroverlapcopy.hh:459
const RemoteIndices & remoteIndices() const
Get the underlying remote indices.
Definition: owneroverlapcopy.hh:468
Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet
The type of the parallel index set.
Definition: owneroverlapcopy.hh:446
void readMatrixMarket(Dune::BCRSMatrix< T, A > &matrix, std::istream &istr)
Reads a sparse matrix from a matrix market file.
Definition: matrixmarket.hh:1019
void writeMatrixMarket(const M &matrix, std::ostream &ostr)
writes a ISTL matrix or vector to a stream in matrix market format.
Definition: matrixmarket.hh:1169
void storeMatrixMarket(const M &matrix, std::string filename, const OwnerOverlapCopyCommunication< G, L > &comm, bool storeIndices=true, int prec=default_precision)
Stores a parallel matrix/vector in matrix market format in a file.
Definition: matrixmarket.hh:1238
void loadMatrixMarket(M &matrix, const std::string &filename)
Load a matrix/vector stored in matrix market format.
Definition: matrixmarket.hh:1407
auto countNonZeros(const M &, typename std::enable_if_t< Dune::IsNumber< M >::value > *sfinae=nullptr)
Get the number of nonzero fields in the matrix.
Definition: matrixutils.hh:119
bool operator<(const IndexData< T > &i1, const IndexData< T > &i2)
LessThan operator.
Definition: matrixmarket.hh:673
Some handy generic functions for ISTL matrices.
Classes providing communication interfaces for overlapping Schwarz methods.
Test whether a type is an ISTL Matrix.
Definition: matrixutils.hh:504
Functor to the data values of the matrix.
Definition: matrixmarket.hh:720
void operator()(const std::vector< std::set< IndexData< D > > > &rows, BCRSMatrix< T > &matrix)
Sets the matrix values.
Definition: matrixmarket.hh:727
void operator()(const std::vector< std::set< IndexData< D > > > &rows, BCRSMatrix< FieldMatrix< T, brows, bcols > > &matrix)
Sets the matrix values.
Definition: matrixmarket.hh:745
a wrapper class of numeric values.
Definition: matrixmarket.hh:638
Utility class for marking the pattern type of the MatrixMarket matrices.
Definition: matrixmarket.hh:650
Helper metaprogram to get the matrix market string representation of the numeric type.
Definition: matrixmarket.hh:78
@ is_numeric
Whether T is a supported numeric type.
Definition: matrixmarket.hh:83