189template <
typename SC,
typename LO,
typename GO,
typename NO>
190template <
typename SCALAR,
typename>
191Teuchos::RCP<const Thyra::MultiVectorBase<SCALAR> >
192MultiVector<SC,LO,GO,NO>::getThyraMultiVectorConst( )
const {
194 auto thyTpMap = Thyra::tpetraVectorSpace<SCALAR,LO,GO,NO>(multiVector_->getMap());
195 Teuchos::RCP<Tpetra::MultiVector<SCALAR,LO,GO,NO>> tpMV = multiVector_;
196 auto thyDomMap =Thyra::tpetraVectorSpace<SCALAR,LO,GO,NO>(Tpetra::createLocalMapWithNode<LO,GO,NO>(multiVector_->getNumVectors(), multiVector_->getMap()->getComm()));
197 auto thyMV = rcp(
new Thyra::TpetraMultiVector<SCALAR,LO,GO,NO>());
198 thyMV->initialize(thyTpMap, thyDomMap, tpMV);
202#ifdef HAVE_EXPLICIT_INSTANTIATION
203template Teuchos::RCP<const Thyra::MultiVectorBase<double>> MultiVector<double, default_lo, default_go, default_no>::getThyraMultiVectorConst<double, void>()
const;
211template <
class SC,
class LO,
class GO,
class NO>
212void MultiVector<SC,LO,GO,NO>::fromThyraMultiVector( Teuchos::RCP< Thyra::MultiVectorBase<SC> > thyraMV){
214 typedef Thyra::TpetraOperatorVectorExtraction<SC,LO,GO,NO> TOVE_Type;
216 Teuchos::RCP<TpetraMultiVector_Type> tMV = TOVE_Type::getTpetraMultiVector( thyraMV );
220template <
class SC,
class LO,
class GO,
class NO>
221void MultiVector<SC,LO,GO,NO>::norm2(
const Teuchos::ArrayView<
typename Teuchos::ScalarTraits<SC>::magnitudeType> &norms)
const {
222 TEUCHOS_TEST_FOR_EXCEPTION( multiVector_.is_null(), std::runtime_error,
"MultiVector in norm2 is null.")
223 multiVector_->norm2(norms);
227template <class SC, class LO, class GO, class NO>
228void MultiVector<SC,LO,GO,NO>::normInf(const Teuchos::ArrayView< typename Teuchos::ScalarTraits<SC>::magnitudeType> &normsInf)
const {
229 TEUCHOS_TEST_FOR_EXCEPTION( multiVector_.is_null(), std::runtime_error,
"MultiVector in normInf is null.")
230 multiVector_->normInf(normsInf);
234template <class SC, class LO, class GO, class NO>
235void MultiVector<SC,LO,GO,NO>::abs(MultiVectorConstPtr_Type a) {
236 TEUCHOS_TEST_FOR_EXCEPTION( multiVector_.is_null(), std::runtime_error,
"MultiVector in abs is null.")
237 multiVector_->abs( *a->getTpetraMultiVector());
240template <class SC, class LO, class GO, class NO>
241void MultiVector<SC,LO,GO,NO>::dot(MultiVectorConstPtr_Type a, const Teuchos::ArrayView< typename Teuchos::ScalarTraits<SC>::magnitudeType> &dots)
const {
242 TEUCHOS_TEST_FOR_EXCEPTION( multiVector_.is_null(), std::runtime_error,
"MultiVector in dot is null.")
243 multiVector_->dot( *a->getTpetraMultiVector(), dots );
246template <class SC, class LO, class GO, class NO>
247void MultiVector<SC,LO,GO,NO>::update( const SC& alpha, const MultiVector_Type& A, const SC& beta) {
248 TEUCHOS_TEST_FOR_EXCEPTION( getNumVectors() != A.getNumVectors(), std::logic_error,
"MultiVectors for update have different number of vectors.")
249 multiVector_->update( alpha, *A.getTpetraMultiVector(), beta );
252template <class SC, class LO, class GO, class NO>
253void MultiVector<SC,LO,GO,NO>::update( const SC& alpha, const MultiVector_Type& A, const SC& beta , const MultiVector_Type& B, const SC& gamma) {
254 TEUCHOS_TEST_FOR_EXCEPTION( getNumVectors() != A.getNumVectors(), std::logic_error,
"MultiVectors for update have different number of vectors.")
256 multiVector_->update( alpha, *A.getTpetraMultiVector(), beta, *B.getTpetraMultiVector(), gamma );
260template <class SC, class LO, class GO, class NO>
261void MultiVector<SC,LO,GO,NO>::putScalar( const SC& alpha ){
262 multiVector_->putScalar( alpha );
265template <
class SC,
class LO,
class GO,
class NO>
266void MultiVector<SC,LO,GO,NO>::scale(
const SC& alpha ){
267 multiVector_->scale( alpha );
270template <
class SC,
class LO,
class GO,
class NO>
271void MultiVector<SC,LO,GO,NO>::multiply(Teuchos::ETransp transA, Teuchos::ETransp transB,
const SC &alpha, MultiVectorConstPtr_Type &A, MultiVectorConstPtr_Type &B,
const SC &beta){
272 multiVector_->multiply( transA, transB, alpha, *A->getTpetraMultiVector(), *B->getTpetraMultiVector(), beta );
275#if __cplusplus >= 202002L
276template <
class SC,
class LO,
class GO,
class NO>
277void MultiVector<SC,LO,GO,NO>::multiply(Teuchos::ETransp transA, Teuchos::ETransp transB,
const SC &alpha, BlockMultiVectorConstPtr_Type &A, BlockMultiVectorConstPtr_Type &B,
const SC &beta)
requires std::same_as<SC,double>{
281 for (
int i=0; i<A->size(); i++){
282 MultiVectorConstPtr_Type a = A->getBlock(i);
283 MultiVectorConstPtr_Type b = B->getBlock(i);
285 this->multiply( transA, transB, alpha, a, b, beta );
287 this->multiply( transA, transB, alpha, a, b, Teuchos::ScalarTraits<SC>::one() );
292template <
typename SC,
typename LO,
typename GO,
typename NO>
293template <
typename SCALAR,
typename>
294void MultiVector<SC,LO,GO,NO>::multiply(Teuchos::ETransp transA, Teuchos::ETransp transB,
const SCALAR &alpha, BlockMultiVectorConstPtr_Type &A, BlockMultiVectorConstPtr_Type &B,
const SCALAR &beta) {
298 for (
int i=0; i<A->size(); i++){
299 MultiVectorConstPtr_Type a = A->getBlock(i);
300 MultiVectorConstPtr_Type b = B->getBlock(i);
302 this->multiply( transA, transB, alpha, a, b, beta );
304 this->multiply( transA, transB, alpha, a, b, Teuchos::ScalarTraits<SCALAR>::one() );
308#ifdef HAVE_EXPLICIT_INSTANTIATION
309template void MultiVector<double, default_lo, default_go, default_no>::multiply<double, void>(Teuchos::ETransp transA, Teuchos::ETransp transB,
const double &alpha, BlockMultiVectorConstPtr_Type &A, BlockMultiVectorConstPtr_Type &B,
const double &beta);
315template <
class SC,
class LO,
class GO,
class NO>
316void MultiVector<SC,LO,GO,NO>::importFromVector( MultiVectorConstPtr_Type mvIn,
bool reuseImport, std::string combineMode, std::string type) {
318 TEUCHOS_TEST_FOR_EXCEPTION( getNumVectors() != mvIn->getNumVectors(), std::logic_error,
"MultiVectors for fillFromVector have different number of vectors.")
320 if ( importer_.is_null() || !reuseImport) {
322 importer_ = Teuchos::RCP(
new Tpetra::Import<LO, GO, NO>(mvIn->getMapTpetra(), this->getMapTpetra() ));
323 else if(type==
"Reverse")
324 importer_ = Teuchos::RCP(
new Tpetra::Import<LO, GO, NO>(this->getMapTpetra(), mvIn->getMapTpetra() ));
326 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown type for import. Choose Forward or Reverse")
329 TEUCHOS_TEST_FOR_EXCEPTION( !importer_->getSourceMap()->isSameAs( *mvIn->getMap()->getTpetraMap() ), std::logic_error,
"Source maps of Importer and Multivector are not the same.")
330 TEUCHOS_TEST_FOR_EXCEPTION( !importer_->getTargetMap()->isSameAs( *this->getMap()->getTpetraMap() ), std::logic_error,
"Target maps of Importer and Multivector are not the same.")
334 if (type==
"Forward") {
335 if ( !combineMode.compare(
"Insert") )
336 multiVector_->doImport ( *mvIn->getTpetraMultiVector(), *importer_, Tpetra::INSERT);
337 else if ( !combineMode.compare(
"Add") )
338 multiVector_->doImport ( *mvIn->getTpetraMultiVector(), *importer_, Tpetra::ADD);
340 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown combine mode.")
342 else if(type==
"Reverse"){
343 if ( !combineMode.compare(
"Insert") )
344 multiVector_->doExport ( *mvIn->getTpetraMultiVector(), *importer_, Tpetra::INSERT);
345 else if ( !combineMode.compare(
"Add") )
346 multiVector_->doExport ( *mvIn->getTpetraMultiVector(), *importer_, Tpetra::ADD);
348 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown combine mode.")
351 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown type for import. Choose Forward or Reverse")
354template <
class SC,
class LO,
class GO,
class NO>
355void MultiVector<SC,LO,GO,NO>::exportFromVector( MultiVectorConstPtr_Type mvIn,
bool reuseExport, std::string combineMode, std::string type) {
356 TEUCHOS_TEST_FOR_EXCEPTION( getNumVectors() != mvIn->getNumVectors(), std::logic_error,
"MultiVectors for exportToVector have different number of vectors.")
358 if ( exporter_.is_null() || !reuseExport) {
360 exporter_ = Teuchos::RCP(
new Tpetra::Export<LO, GO, NO>(mvIn->getMapTpetra(), this->getMapTpetra() ));
361 else if(type==
"Reverse")
362 exporter_ = Teuchos::RCP(
new Tpetra::Export<LO, GO, NO>(this->getMapTpetra(), mvIn->getMapTpetra() ));
364 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown type for export. Choose Forward or Reverse")
367 TEUCHOS_TEST_FOR_EXCEPTION( !exporter_->getSourceMap()->isSameAs( *this->getMap()->getTpetraMap() ), std::logic_error,
"Source maps of Exporter and Multivector are not the same.")
368 TEUCHOS_TEST_FOR_EXCEPTION( !exporter_->getTargetMap()->isSameAs( *mvIn->getMap()->getTpetraMap() ), std::logic_error,
"Target maps of Exporter and Multivector are not the same.")
370 if (type==
"Forward") {
371 if ( !combineMode.compare(
"Insert") )
372 multiVector_->doExport ( *mvIn->getTpetraMultiVector(), *exporter_, Tpetra::INSERT);
373 else if ( !combineMode.compare(
"Add") )
374 multiVector_->doExport ( *mvIn->getTpetraMultiVector(), *exporter_, Tpetra::ADD);
376 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown combine mode.")
378 else if (type==
"Reverse") {
379 if ( !combineMode.compare(
"Insert") )
380 multiVector_->doImport ( *mvIn->getTpetraMultiVector(), *exporter_, Tpetra::INSERT);
381 else if ( !combineMode.compare(
"Add") )
382 multiVector_->doImport ( *mvIn->getTpetraMultiVector(), *exporter_, Tpetra::ADD);
384 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown combine mode.")
387 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown type for export. Choose Forward or Reverse")
390template <
class SC,
class LO,
class GO,
class NO>
391void MultiVector<SC,LO,GO,NO>::writeMM(std::string fileName)
const{
392 TEUCHOS_TEST_FOR_EXCEPTION( multiVector_.is_null(), std::runtime_error,
"MultiVector in writeMM is null.")
394 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraCrsMatrix;
396 Tpetra::MatrixMarket::Writer< TpetraCrsMatrix > tpetraWriter;
398 tpetraWriter.writeDenseFile(fileName, multiVector_,
"multivector",
"");
402template <class SC, class LO, class GO, class NO>
403void MultiVector<SC,LO,GO,NO>::readMM(std::
string fileName)
const{
404 TEUCHOS_TEST_FOR_EXCEPTION( multiVector_.is_null(), std::runtime_error,
"MultiVector in writeMM is null.")
406 typedef Tpetra::CrsMatrix<SC,LO,GO,NO> TpetraCrsMatrix;
407 typedef Teuchos::RCP<TpetraCrsMatrix> TpetraCrsMatrixPtr;
409 typedef Tpetra::
MultiVector<SC,LO,GO,NO> TpetraMultiVector;
410 typedef Teuchos::RCP<TpetraMultiVector> TpetraMultiVectorPtr;
412 typedef Tpetra::
Map<LO,GO,NO> TpetraMap;
413 typedef Teuchos::RCP<TpetraMap> TpetraMapPtr;
415 Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
417 TpetraMultiVectorPtr tpetraMultiVector = multiVector_;
419 Teuchos::RCP<const Tpetra::
Map<LO,GO,NO> > tpetraMap = tpetraMultiVector->getMap();
421 Tpetra::MatrixMarket::Reader< TpetraCrsMatrix > tpetraReader;
423 tpetraMultiVector = tpetraReader.readDenseFile(fileName, multiVector_->getMap()->getComm() ,tpetraMap);
425 for (UN j=0; j<this->getNumVectors(); j++) {
426 Teuchos::ArrayRCP< const SC > valuesIn = tpetraMultiVector->getData(j);
427 Teuchos::ArrayRCP< SC > valuesThis = this->getDataNonConst(j);
428 for (UN i=0; i<valuesThis.size(); i++)
429 valuesThis[i] = valuesIn[i];
436template <
class SC,
class LO,
class GO,
class NO>
437typename MultiVector<SC,LO,GO,NO>::MultiVectorConstPtr_Type MultiVector<SC,LO,GO,NO>::getVector(
int i )
const{
439 TpetraMultiVectorConstPtr_Type tpetraMV = multiVector_->getVector( i );
440 TpetraMultiVectorPtr_Type tpetraMVNonConst = Teuchos::rcp_const_cast<TpetraMultiVector_Type>( tpetraMV );
441 MultiVectorConstPtr_Type singleMV = Teuchos::rcp(
new const MultiVector_Type ( tpetraMVNonConst ) );
446template <
class SC,
class LO,
class GO,
class NO>
447typename MultiVector<SC,LO,GO,NO>::MultiVectorPtr_Type MultiVector<SC,LO,GO,NO>::sumColumns()
const{
449 MultiVectorPtr_Type sumMV = Teuchos::rcp(
new MultiVector_Type ( map_, 1 ) );
450 sumMV->putScalar(0.);
451 for (
int i=0; i<this->getNumVectors(); i++)
452 sumMV->getTpetraMultiVectorNonConst()->getVectorNonConst(0)->update( 1., *multiVector_->getVector(i), 1. );
457template <
class SC,
class LO,
class GO,
class NO>
458SC MultiVector<SC,LO,GO,NO>::getMax()
const{
459 TEUCHOS_TEST_FOR_EXCEPTION( this->getNumVectors() > 1, std::runtime_error,
"numMultiVector>1: max function not implemented!")
460 return multiVector_->getVector(0)->normInf();