#include "Thyra_DefaultSpmdVectorSpace.hpp"
#include "Thyra_DefaultProductVectorSpace.hpp"
#include "Thyra_VectorStdOpsTester.hpp"
#include "Thyra_MultiVectorStdOpsTester.hpp"
#include "Thyra_TestingTools.hpp"
#include "Teuchos_GlobalMPISession.hpp"
#include "Teuchos_CommandLineProcessor.hpp"
#include "Teuchos_VerboseObject.hpp"
#include "Teuchos_DefaultComm.hpp"
#include "Teuchos_arrayArg.hpp"
namespace Thyra {
template <class Scalar>
bool run_std_ops_tests(
const int n
,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType max_rel_err
,const bool dumpAll
,Teuchos::FancyOStream *out_arg
)
{
using Teuchos::RefCountPtr;
using Teuchos::rcp;
using Teuchos::OSTab;
typedef Teuchos::ScalarTraits<Scalar> ST;
typedef typename ST::magnitudeType ScalarMag;
typedef Thyra::Index Index;
RefCountPtr<Teuchos::FancyOStream>
out = rcp(new Teuchos::FancyOStream(rcp(out_arg,false)));
VectorStdOpsTester<Scalar> vectorStdOpsTester;
vectorStdOpsTester.warning_tol(ScalarMag(0.1)*max_rel_err);
vectorStdOpsTester.error_tol(max_rel_err);
MultiVectorStdOpsTester<Scalar> multiVectorStdOpsTester;
multiVectorStdOpsTester.warning_tol(ScalarMag(0.1)*max_rel_err);
multiVectorStdOpsTester.error_tol(max_rel_err);
if(out.get()) *out << "\n*** Entering run_std_ops_tests<"<<ST::name()<<">(...) ...\n";
bool success = true;
if(out.get()) *out << "\nCreating a serial vector space svs with n="<<n<<" vector elements ...\n";
const RefCountPtr<const Teuchos::Comm<Index> >
comm = Teuchos::DefaultComm<Index>::getComm();
const DefaultSpmdVectorSpace<Scalar> svs(comm,n,-1);
if(out.get()) *out << "\nTesting standard vector ops with svs ...\n";
if(!vectorStdOpsTester.checkStdOps(svs,OSTab(out).getOStream().get(),dumpAll)) success = false;
if(out.get()) *out << "\nTesting standard multi-vector ops with svs ...\n";
if(!multiVectorStdOpsTester.checkStdOps(svs,OSTab(out).getOStream().get(),dumpAll)) success = false;
const int numBlocks = 3;
if(out.get()) *out << "\nCreating a product space pvs with numBlocks="<<numBlocks<<" and n="<<n<<"vector elements per block ...\n";
Teuchos::Array<Teuchos::RefCountPtr<const Thyra::VectorSpaceBase<Scalar> > >
vecSpaces(numBlocks);
Teuchos::RefCountPtr<const Thyra::VectorSpaceBase<Scalar> >
spaceBlock = Teuchos::rcp(new Thyra::DefaultSpmdVectorSpace<Scalar>(comm,n,-1));
for( int i = 0; i < numBlocks; ++i )
vecSpaces[i] = spaceBlock;
Thyra::DefaultProductVectorSpace<Scalar> pvs(numBlocks,&vecSpaces[0]);
if(out.get()) *out << "\nTesting standard vector ops with pvs ...\n";
if(!vectorStdOpsTester.checkStdOps(pvs,OSTab(out).getOStream().get(),dumpAll)) success = false;
if(out.get()) *out << "\nTesting standard multi-vector ops with pvs ...\n";
if(!multiVectorStdOpsTester.checkStdOps(pvs,OSTab(out).getOStream().get(),dumpAll)) success = false;
if(out.get()) *out << "\nCreating a nested product space ppvs with numBlocks="<<numBlocks<<" product spaces as components ...\n";
Teuchos::Array<Teuchos::RefCountPtr<const Thyra::VectorSpaceBase<Scalar> > >
blockVecSpaces(numBlocks);
for( int i = 0; i < numBlocks; ++i )
blockVecSpaces[i] = Teuchos::rcp(&pvs,false);
Thyra::DefaultProductVectorSpace<Scalar> ppvs(numBlocks,&blockVecSpaces[0]);
if(out.get()) *out << "\nTesting standard vector ops with ppvs ...\n";
if(!vectorStdOpsTester.checkStdOps(ppvs,OSTab(out).getOStream().get(),dumpAll)) success = false;
if(out.get()) *out << "\nTesting standard multi-vector ops with ppvs ...\n";
if(!multiVectorStdOpsTester.checkStdOps(ppvs,OSTab(out).getOStream().get(),dumpAll)) success = false;
return success;
}
}
int main( int argc, char* argv[] ) {
using Teuchos::CommandLineProcessor;
bool success = true;
bool verbose = true;
bool dumpAll = false;
Teuchos::GlobalMPISession mpiSession(&argc,&argv);
Teuchos::RefCountPtr<Teuchos::FancyOStream>
out = Teuchos::VerboseObjectBase::getDefaultOStream();
try {
int local_dim = 4;
CommandLineProcessor clp;
clp.throwExceptions(false);
clp.addOutputSetupOptions(true);
clp.setOption( "verbose", "quiet", &verbose, "Determines if any output is printed or not." );
clp.setOption( "dump-all", "no-dump", &dumpAll, "Determines if quantities are dumped or not." );
clp.setOption( "local-dim", &local_dim, "Number of vector elements per process." );
CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return;
if( !Thyra::run_std_ops_tests<float>(local_dim,float(100.0*Teuchos::ScalarTraits<float>::eps()),dumpAll,verbose?&*out:NULL) ) success = false;
if( !Thyra::run_std_ops_tests<double>(local_dim,double(100.0*Teuchos::ScalarTraits<double>::eps()),dumpAll,verbose?&*out:NULL) ) success = false;
#if defined(HAVE_COMPLEX) && defined(HAVE_TEUCHOS_COMPLEX)
if( !Thyra::run_std_ops_tests<std::complex<float> >(local_dim,float(100.0*Teuchos::ScalarTraits<float>::eps()),dumpAll,verbose?&*out:NULL) ) success = false;
if( !Thyra::run_std_ops_tests<std::complex<double> >(local_dim,double(100.0*Teuchos::ScalarTraits<double>::eps()),dumpAll,verbose?&*out:NULL) ) success = false;
#endif
#ifdef HAVE_TEUCHOS_GNU_MP
#endif
}
catch( const std::exception &excpt ) {
if(verbose)
std::cerr << "*** Caught a standard exception : " << excpt.what() << std::endl;
success = false;
}
catch( ... ) {
if(verbose)
std::cerr << "*** Caught an unknown exception!\n";
success = false;
}
if(verbose) {
if(success)
*out << "\nAll of the tests seem to have run successfully!\n";
else
*out << "\nOh no! at least one of the test failed!\n";
}
return success ? 0 : 1;
}