Thyra Package Browser (Single Doxygen Collection) Version of the Day
test_composite_linear_ops.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //    Thyra: Interfaces and Support for Abstract Numerical Algorithms
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #include "Thyra_DefaultSpmdVectorSpace.hpp"
00030 #include "Thyra_DefaultZeroLinearOp.hpp"
00031 #include "Thyra_DefaultIdentityLinearOp.hpp"
00032 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
00033 #include "Thyra_DefaultAddedLinearOp.hpp"
00034 #include "Thyra_DefaultMultipliedLinearOp.hpp"
00035 #include "Thyra_DefaultBlockedLinearOp.hpp"
00036 #include "Thyra_DefaultDiagonalLinearOp.hpp"
00037 #include "Thyra_ScaledAdjointLinearOpBase.hpp"
00038 #include "Thyra_VectorStdOps.hpp"
00039 #include "Thyra_MultiVectorStdOps.hpp"
00040 #include "Thyra_TestingTools.hpp"
00041 #include "Thyra_LinearOpTester.hpp"
00042 #include "Teuchos_CommandLineProcessor.hpp"
00043 #include "Teuchos_GlobalMPISession.hpp"
00044 #include "Teuchos_VerboseObject.hpp"
00045 #include "Teuchos_DefaultComm.hpp"
00046 #include "Teuchos_dyn_cast.hpp"
00047 #include "Teuchos_StandardCatchMacros.hpp"
00048 
00049 // For debugging
00050 #include "RTOpPack_SPMD_apply_op.hpp"
00051 
00052 
00055 template <class Scalar>
00056 bool run_composite_linear_ops_tests(
00057   const Teuchos::RCP<const Teuchos::Comm<Thyra::Ordinal> >   comm
00058   ,const int                                                       n
00059   ,const bool                                                      useSpmd
00060   ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType     &tol
00061   ,const bool                                                      dumpAll
00062   ,Teuchos::FancyOStream                                           *out_arg
00063   )
00064 {
00065 
00066   using Thyra::relErr;
00067   using Thyra::passfail;
00068   typedef Teuchos::ScalarTraits<Scalar> ST;
00069   typedef typename ST::magnitudeType    ScalarMag;
00070   typedef Teuchos::ScalarTraits<ScalarMag> STM;
00071   using Teuchos::RCP;
00072   using Teuchos::rcp;
00073   using Teuchos::null;
00074   using Teuchos::rcp_const_cast;
00075   using Teuchos::rcp_dynamic_cast;
00076   using Teuchos::dyn_cast;
00077   using Teuchos::OSTab;
00078 
00079   RCP<Teuchos::FancyOStream>
00080     out = rcp(new Teuchos::FancyOStream(rcp(out_arg,false)));
00081 
00082   const Teuchos::EVerbosityLevel
00083     verbLevel = dumpAll?Teuchos::VERB_EXTREME:Teuchos::VERB_HIGH;
00084 
00085   if(out.get()) *out << "\n*** Entering run_composite_linear_ops_tests<"<<ST::name()<<">(...) ...\n";
00086 
00087   bool success = true, result;
00088 
00089   const ScalarMag warning_tol = ScalarMag(1e-2)*tol, error_tol = tol;
00090   Thyra::LinearOpTester<Scalar> linearOpTester;
00091   linearOpTester.linear_properties_warning_tol(warning_tol);
00092   linearOpTester.linear_properties_error_tol(error_tol);
00093   linearOpTester.adjoint_warning_tol(warning_tol);
00094   linearOpTester.adjoint_error_tol(error_tol);
00095   linearOpTester.dump_all(dumpAll);
00096   Thyra::LinearOpTester<Scalar> symLinearOpTester(linearOpTester);
00097   symLinearOpTester.check_for_symmetry(true);
00098   symLinearOpTester.symmetry_warning_tol(STM::squareroot(warning_tol));
00099   symLinearOpTester.symmetry_error_tol(STM::squareroot(error_tol));
00100 
00101   RCP<const Thyra::VectorSpaceBase<Scalar> > space;
00102   if(useSpmd) space = Thyra::defaultSpmdVectorSpace<Scalar>(comm,n,-1);
00103   else space = Thyra::defaultSpmdVectorSpace<Scalar>(n);
00104   if(out.get()) *out << "\nUsing a basic vector space described as " << describe(*space,verbLevel) << " ...\n";
00105   
00106   if(out.get()) *out << "\nCreating random n x (n/2) multi-vector origA ...\n";
00107   RCP<Thyra::MultiVectorBase<Scalar> >
00108     mvOrigA = createMembers(space,n/2,"origA");
00109   Thyra::seed_randomize<Scalar>(0);
00110   //RTOpPack::show_spmd_apply_op_dump = true;
00111   Thyra::randomize( Scalar(Scalar(-1)*ST::one()), Scalar(Scalar(+1)*ST::one()), &*mvOrigA );
00112   RCP<const Thyra::LinearOpBase<Scalar> >
00113     origA = mvOrigA;
00114   if(out.get()) *out << "\norigA =\n" << describe(*origA,verbLevel);
00115   //RTOpPack::show_spmd_apply_op_dump = false;
00116 
00117   if(out.get()) *out << "\nTesting origA ...\n";
00118   Thyra::seed_randomize<Scalar>(0);
00119   result = linearOpTester.check(*origA,out.get());
00120   if(!result) success = false;
00121   
00122   if(out.get()) *out << "\nCreating implicit scaled linear operator A1 = scale(0.5,origA) ...\n";
00123   RCP<const Thyra::LinearOpBase<Scalar> >
00124     A1 = scale(Scalar(0.5),origA);
00125   if(out.get()) *out << "\nA1 =\n" << describe(*A1,verbLevel);
00126 
00127   if(out.get()) *out << "\nTesting A1 ...\n";
00128   Thyra::seed_randomize<Scalar>(0);
00129   result = linearOpTester.check(*A1,out.get());
00130   if(!result) success = false;
00131 
00132   if(out.get()) *out << "\nTesting that A1.getOp() == origA ...\n";
00133   Thyra::seed_randomize<Scalar>(0);
00134   result = linearOpTester.compare(*dyn_cast<const Thyra::DefaultScaledAdjointLinearOp<Scalar> >(*A1).getOp(),*origA,out.get());
00135   if(!result) success = false;
00136 
00137   {
00138 
00139     if(out.get()) *out << "\nUnwrapping origA to get non-persisting pointer to origA_1, scalar and transp ...\n";
00140     Scalar  scalar;
00141     Thyra::EOpTransp transp;
00142     const Thyra::LinearOpBase<Scalar> *origA_1 = NULL;
00143     unwrap( *origA, &scalar, &transp, &origA_1 );
00144     TEST_FOR_EXCEPT( origA_1 == NULL );
00145 
00146     if(out.get()) *out << "\nscalar = " << scalar << " == 1 ? ";
00147     result = (scalar == ST::one());
00148     if(!result) success = false;
00149     if(out.get()) *out << passfail(result) << std::endl;
00150 
00151     if(out.get()) *out << "\ntransp = " << toString(transp) << " == NOTRANS ? ";
00152     result = (transp == Thyra::NOTRANS);
00153     if(!result) success = false;
00154     if(out.get()) *out << passfail(result) << std::endl;
00155     
00156     if(out.get()) *out << "\nTesting that origA_1 == origA ...\n";
00157     Thyra::seed_randomize<Scalar>(0);
00158     result = linearOpTester.compare(*origA_1,*origA,out.get());
00159     if(!result) success = false;
00160     
00161   }
00162 
00163   {
00164 
00165     if(out.get()) *out << "\nUnwrapping A1 to get non-persisting pointer to origA_2 ...\n";
00166     Scalar  scalar;
00167     Thyra::EOpTransp transp;
00168     const Thyra::LinearOpBase<Scalar> *origA_2 = NULL;
00169     unwrap( *A1, &scalar, &transp, &origA_2 );
00170     TEST_FOR_EXCEPT( origA_2 == NULL );
00171 
00172     if(out.get()) *out << "\nscalar = " << scalar << " == 0.5 ? ";
00173     result = (scalar == Scalar(0.5));
00174     if(!result) success = false;
00175     if(out.get()) *out << passfail(result) << std::endl;
00176 
00177     if(out.get()) *out << "\ntransp = " << toString(transp) << " == NOTRANS ? ";
00178     result = (transp == Thyra::NOTRANS);
00179     if(!result) success = false;
00180     if(out.get()) *out << passfail(result) << std::endl;
00181 
00182     if(out.get()) *out << "\nTesting that origA_2 == origA ...\n";
00183     Thyra::seed_randomize<Scalar>(0);
00184     result = linearOpTester.compare(*origA_2,*origA,out.get());
00185     if(!result) success = false;
00186 
00187   }
00188   
00189   if(out.get()) *out << "\nCreating implicit scaled linear operator A2 = adjoint(A1) ...\n";
00190   RCP<const Thyra::LinearOpBase<Scalar> >
00191     A2 = adjoint(A1);
00192   if(out.get()) *out << "\nA2 =\n" << describe(*A2,verbLevel);
00193 
00194   if(out.get()) *out << "\nTesting A2 ...\n";
00195   Thyra::seed_randomize<Scalar>(0);
00196   result = linearOpTester.check(*A2,out.get());
00197   if(!result) success = false;
00198 
00199   if(out.get()) *out << "\nTesting that A2.getOp() == A1 ...\n";
00200   Thyra::seed_randomize<Scalar>(0);
00201   result = linearOpTester.compare(*dyn_cast<const Thyra::DefaultScaledAdjointLinearOp<Scalar> >(*A2).getOp(),*A1,out.get());
00202   if(!result) success = false;
00203   
00204   if(out.get()) *out << "\nCreating implicit scaled, adjoined linear operator A3 = adjoint(scale(2.0,(A2)) ...\n";
00205   RCP<const Thyra::LinearOpBase<Scalar> >
00206     A3 = adjoint(scale(Scalar(2.0),A2));
00207   if(out.get()) *out << "\nA3 =\n" << describe(*A3,verbLevel);
00208 
00209   if(out.get()) *out << "\nTesting A3 ...\n";
00210   Thyra::seed_randomize<Scalar>(0);
00211   result = linearOpTester.check(*A3,out.get());
00212   if(!result) success = false;
00213 
00214   if(out.get()) *out << "\nTesting that A3 == origA ...\n";
00215   Thyra::seed_randomize<Scalar>(0);
00216   result = linearOpTester.compare(*A3,*origA,out.get());
00217   if(!result) success = false;
00218 
00219   if(out.get()) *out << "\nCalling all of the rest of the functions for non-const just to test them ...\n";
00220   RCP<Thyra::LinearOpBase<Scalar> >
00221     A4 = nonconstScale(
00222       Scalar(0.25)
00223       ,nonconstAdjoint(
00224         nonconstTranspose(
00225           nonconstAdjoint(
00226             nonconstScaleAndAdjoint(
00227               Scalar(4.0)
00228               ,Thyra::TRANS
00229               ,Teuchos::rcp_const_cast<Thyra::LinearOpBase<Scalar> >(origA)
00230               )
00231             )
00232           )
00233         )
00234       );
00235   if(!ST::isComplex) A4 = nonconstTranspose(nonconstAdjoint(A4)); // Should result in CONJ
00236   if(out.get()) *out << "\nA4 =\n" << describe(*A4,verbLevel);
00237 
00238   if(out.get()) *out << "\nTesting A4 ...\n";
00239   Thyra::seed_randomize<Scalar>(0);
00240   result = linearOpTester.check(*A4,out.get());
00241   if(!result) success = false;
00242 
00243   if(out.get()) *out << "\nCalling all of the rest of the functions for const just to test them ...\n";
00244   RCP<const Thyra::LinearOpBase<Scalar> >
00245     A5 = scale(
00246       Scalar(0.25)
00247       ,adjoint(
00248         transpose(
00249           adjoint(
00250             scaleAndAdjoint(
00251               Scalar(4.0)
00252               ,Thyra::TRANS
00253               ,origA
00254               )
00255             )
00256           )
00257         )
00258       );
00259   if(!ST::isComplex) A5 = transpose(adjoint(A5)); // Should result in CONJ
00260   if(out.get()) *out << "\nA5 =\n" << describe(*A5,verbLevel);
00261 
00262   if(out.get()) *out << "\nTesting A5 ...\n";
00263   Thyra::seed_randomize<Scalar>(0);
00264   result = linearOpTester.check(*A5,out.get());
00265   if(!result) success = false;
00266 
00267   if(out.get()) *out << "\nCreating a multiplied operator A6 = origA^H*A1 ...\n";
00268   RCP<const Thyra::LinearOpBase<Scalar> >
00269     A6 = multiply(adjoint(origA),A1);
00270   if(out.get()) *out << "\nA6 =\n" << describe(*A6,verbLevel);
00271 
00272   if(out.get()) *out << "\nTesting A6 ...\n";
00273   Thyra::seed_randomize<Scalar>(0);
00274   result = symLinearOpTester.check(*A6,out.get());
00275   if(!result) success = false;
00276   // Note that testing the symmetry above helps to check the transpose mode
00277   // against the non-transpose mode!
00278 
00279 #ifdef TEUCHOS_DEBUG
00280   if(out.get()) *out << "\nCreating an invalid multiplied operator A6b = origA*origA (should throw an exception) ...\n\n";
00281   try {
00282     RCP<const Thyra::LinearOpBase<Scalar> >
00283       A6b = multiply(origA,origA);
00284     result = true;
00285   }
00286   TEUCHOS_STANDARD_CATCH_STATEMENTS(true,out.get()?*out:std::cerr,result)
00287   if(out.get())
00288     *out << "\nCaught expected exception : " << (result?"failed\n":"passed\n");
00289   if(result) success = false;
00290 #endif // TEUCHOS_DEBUG
00291 
00292   if(out.get()) *out << "\nCreating a non-const multiplied operator A7 = origA^H*A1 ...\n";
00293   RCP<Thyra::LinearOpBase<Scalar> >
00294     A7 = nonconstMultiply(
00295       rcp_const_cast<Thyra::LinearOpBase<Scalar> >(adjoint(origA))
00296       ,rcp_const_cast<Thyra::LinearOpBase<Scalar> >(A1)
00297       );
00298   if(out.get()) *out << "\nA7 =\n" << describe(*A7,verbLevel);
00299 
00300   if(out.get()) *out << "\nTesting A7 ...\n";
00301   Thyra::seed_randomize<Scalar>(0);
00302   result = symLinearOpTester.check(*A7,out.get());
00303   if(!result) success = false;
00304 
00305   if(out.get()) *out << "\nCreating an added operator A8 = origA + A1 ...\n";
00306   RCP<const Thyra::LinearOpBase<Scalar> >
00307     A8 = add(origA,A1);
00308   if(out.get()) *out << "\nA8 =\n" << describe(*A8,verbLevel);
00309 
00310   if(out.get()) *out << "\nTesting A8 ...\n";
00311   Thyra::seed_randomize<Scalar>(0);
00312   result = linearOpTester.check(*A8,out.get());
00313   if(!result) success = false;
00314 
00315   if(out.get()) *out << "\nCreating a symmetric subtracted operator A8b = A6 + adjoint(origA)*origA ...\n";
00316   RCP<const Thyra::LinearOpBase<Scalar> >
00317     A8b = subtract(A6,multiply(adjoint(origA),origA));
00318   if(out.get()) *out << "\nA8b =\n" << describe(*A8b,verbLevel);
00319 
00320   if(out.get()) *out << "\nTesting A8b ...\n";
00321   Thyra::seed_randomize<Scalar>(0);
00322   result = symLinearOpTester.check(*A8b,out.get());
00323   if(!result) success = false;
00324 
00325 #ifdef TEUCHOS_DEBUG
00326   if(out.get()) *out << "\nCreating an invalid added operator A8c = origA + adjoint(origA) (should throw an exception) ...\n\n";
00327   try {
00328     RCP<const Thyra::LinearOpBase<Scalar> >
00329       A8c = add(origA,adjoint(origA));
00330     result = true;
00331   }
00332   TEUCHOS_STANDARD_CATCH_STATEMENTS(true,out.get()?*out:std::cerr,result)
00333   if(out.get())
00334     *out << "\nCaught expected exception : " << (result?"failed\n":"passed\n");
00335   if(result) success = false;
00336 #endif // TEUCHOS_DEBUG
00337 
00338   RCP<const Thyra::LinearOpBase<Scalar> >
00339     nullOp = null;
00340 
00341   if(out.get()) *out << "\nCreating a blocked 2x2 linear operator A9 = [ A6, A1^H; A1, null ] ...\n";
00342   RCP<const Thyra::LinearOpBase<Scalar> >
00343     A9 = Thyra::block2x2<Scalar>(
00344       A6,  adjoint(A1)
00345       ,A1, nullOp
00346       );
00347   if(out.get()) *out << "\nA9 =\n" << describe(*A9,verbLevel);
00348   
00349   if(out.get()) *out << "\nTesting A9 ...\n";
00350   Thyra::seed_randomize<Scalar>(0);
00351   result = symLinearOpTester.check(*A9,out.get());
00352   if(!result) success = false;
00353   // Note that testing the symmetry above helps to check the transpose mode
00354   // against the non-transpose mode!
00355 
00356   if(out.get()) *out << "\nCreating a blocked 2x2 linear operator A9_a = [ A6, A1^H; A1, null ] using pre-formed range and domain product spaces ...\n";
00357   RCP<Thyra::PhysicallyBlockedLinearOpBase<Scalar> >
00358     A9_a = rcp(new Thyra::DefaultBlockedLinearOp<Scalar>());
00359   A9_a->beginBlockFill(
00360     rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(A9,true)->productRange()
00361     ,rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<Scalar> >(A9,true)->productDomain()
00362     );
00363   A9_a->setBlock(0,0,A6);
00364   A9_a->setBlock(0,1,adjoint(A1));
00365   A9_a->setBlock(1,0,A1);
00366   A9_a->endBlockFill();
00367   if(out.get()) *out << "\nA9_a =\n" << describe(*A9_a,verbLevel);
00368   
00369   if(out.get()) *out << "\nTesting A9_a ...\n";
00370   Thyra::seed_randomize<Scalar>(0);
00371   result = symLinearOpTester.check(*A9_a,out.get());
00372   if(!result) success = false;
00373   // Note that testing the symmetry above helps to check the transpose mode
00374   // against the non-transpose mode!
00375   
00376   if(out.get()) *out << "\nComparing A9 == A9_a ...\n";
00377   Thyra::seed_randomize<Scalar>(0);
00378   result = linearOpTester.compare(*A9,*A9_a,out.get());
00379   if(!result) success = false;
00380 
00381   if(out.get()) *out << "\nCreating a blocked 2x2 linear operator A9_b = [ A6, A1^H; A1, null ] using flexible fill ...\n";
00382   RCP<Thyra::PhysicallyBlockedLinearOpBase<Scalar> >
00383     A9_b = rcp(new Thyra::DefaultBlockedLinearOp<Scalar>());
00384   A9_b->beginBlockFill();
00385   A9_b->setBlock(0,0,A6);
00386   A9_b->setBlock(0,1,adjoint(A1));
00387   A9_b->setBlock(1,0,A1);
00388   A9_b->endBlockFill();
00389   if(out.get()) *out << "\nA9_b =\n" << describe(*A9_b,verbLevel);
00390   
00391   if(out.get()) *out << "\nTesting A9_b ...\n";
00392   Thyra::seed_randomize<Scalar>(0);
00393   result = symLinearOpTester.check(*A9_b,out.get());
00394   if(!result) success = false;
00395   // Note that testing the symmetry above helps to check the transpose mode
00396   // against the non-transpose mode!
00397   
00398   if(out.get()) *out << "\nComparing A9 == A9_b ...\n";
00399   Thyra::seed_randomize<Scalar>(0);
00400   result = linearOpTester.compare(*A9,*A9_b,out.get());
00401   if(!result) success = false;
00402 
00403   if(out.get()) *out << "\nCreating a blocked 2x2 linear operator A9a = [ null, A1^H; A1, null ] ...\n";
00404   RCP<const Thyra::LinearOpBase<Scalar> >
00405     A9a = Thyra::block2x2<Scalar>(
00406       nullOp,  adjoint(A1),
00407       A1,      nullOp
00408       );
00409   if(out.get()) *out << "\nA9a =\n" << describe(*A9a,verbLevel);
00410   
00411   if(out.get()) *out << "\nTesting A9a ...\n";
00412   Thyra::seed_randomize<Scalar>(0);
00413   result = symLinearOpTester.check(*A9a,out.get());
00414   if(!result) success = false;
00415   // Note that testing the symmetry above helps to check the transpose mode
00416   // against the non-transpose mode!
00417   
00418 #ifdef TEUCHOS_DEBUG
00419   if(out.get()) *out << "\nCreating an invalid blocked 2x2 operator A9b = [ A6, A1^H; A1, A1 ] (should throw an exception) ...\n\n";
00420   try {
00421     RCP<const Thyra::LinearOpBase<Scalar> >
00422       A9b = Thyra::block2x2<Scalar>(
00423         A6,  adjoint(A1),
00424         A1,  A1
00425         );
00426     result = true;
00427   }
00428   TEUCHOS_STANDARD_CATCH_STATEMENTS(true,out.get()?*out:std::cerr,result)
00429   if(out.get())
00430     *out << "\nCaught expected exception : " << (result?"failed\n":"passed\n");
00431   if(result) success = false;
00432 #endif // TEUCHOS_DEBUG
00433 
00434 #ifdef TEUCHOS_DEBUG
00435   if(out.get()) *out << "\nCreating an invalid blocked 2x2 operator A9c = [ A1, A1 ; null, null ] (should throw an exception) ...\n\n";
00436   try {
00437     RCP<const Thyra::LinearOpBase<Scalar> >
00438       A9c = Thyra::block2x2<Scalar>(
00439         A1,       A1,
00440         nullOp,   nullOp
00441         );
00442     result = true;
00443   }
00444   TEUCHOS_STANDARD_CATCH_STATEMENTS(true,out.get()?*out:std::cerr,result)
00445   if(out.get())
00446     *out << "\nCaught expected exception : " << (result?"failed\n":"passed\n");
00447   if(result) success = false;
00448 #endif // TEUCHOS_DEBUG
00449 
00450 #ifdef TEUCHOS_DEBUG
00451   if(out.get()) *out << "\nCreating an invalid blocked 2x2 operator A9d = [ A1, null; A1, null ] (should throw an exception) ...\n\n";
00452   try {
00453     RCP<const Thyra::LinearOpBase<Scalar> >
00454       A9d = Thyra::block2x2<Scalar>(
00455         A1,  nullOp,
00456         A1,  nullOp
00457         );
00458     result = true;
00459   }
00460   TEUCHOS_STANDARD_CATCH_STATEMENTS(true,out.get()?*out:std::cerr,result)
00461   if(out.get())
00462     *out << "\nCaught expected exception : " << (result?"failed\n":"passed\n");
00463   if(result) success = false;
00464 #endif // TEUCHOS_DEBUG
00465 
00466   if(out.get()) *out << "\nCreating a blocked 2x1 linear operator A10 = [ A6; A1 ] ...\n";
00467   RCP<const Thyra::LinearOpBase<Scalar> >
00468     A10 = Thyra::block2x1<Scalar>(
00469       A6,
00470       A1
00471       );
00472   if(out.get()) *out << "\nA10 =\n" << describe(*A10,verbLevel);
00473   
00474   if(out.get()) *out << "\nTesting A10 ...\n";
00475   Thyra::seed_randomize<Scalar>(0);
00476   result = linearOpTester.check(*A10,out.get());
00477   if(!result) success = false;
00478 
00479   if(out.get()) *out << "\nCreating a blocked 1x2 linear operator A11 = [ A9, A10 ] ...\n";
00480   RCP<const Thyra::LinearOpBase<Scalar> >
00481     A11 = Thyra::block1x2<Scalar>( A9, A10 );
00482   if(out.get()) *out << "\nA11 =\n" << describe(*A11,verbLevel);
00483   
00484   if(out.get()) *out << "\nTesting A11 ...\n";
00485   Thyra::seed_randomize<Scalar>(0);
00486   result = linearOpTester.check(*A11,out.get());
00487   if(!result) success = false;
00488 
00489   if(out.get()) *out << "\nCreating a zero linear operator A12 = 0 (range and domain spaces of origA) ...\n";
00490   RCP<const Thyra::LinearOpBase<Scalar> >
00491     A12 = Thyra::zero(origA->range(),origA->domain());
00492   if(out.get()) *out << "\nA12 =\n" << describe(*A12,verbLevel);
00493 
00494   if(out.get()) *out << "\nTesting A12 ...\n";
00495   Thyra::seed_randomize<Scalar>(0);
00496   result = linearOpTester.check(*A12,out.get());
00497   if(!result) success = false;
00498 
00499   if(out.get()) *out << "\nCreating a blocked 2x2 linear operator A13 = [ zero, A1^H; A1, zero ] ...\n";
00500   RCP<const Thyra::LinearOpBase<Scalar> >
00501     A13 = Thyra::block2x2<Scalar>(
00502       Thyra::zero(A1->domain(),A1->domain()),   adjoint(A1),
00503       A1,                                       Thyra::zero(A1->range(),A1->range())
00504       );
00505   if(out.get()) *out << "\nA13 =\n" << describe(*A13,verbLevel);
00506   
00507   if(out.get()) *out << "\nComparing A9a == A13 ...\n";
00508   Thyra::seed_randomize<Scalar>(0);
00509   result = linearOpTester.compare(*A9a,*A13,out.get());
00510   if(!result) success = false;
00511 
00512   if(out.get()) *out << "\nCreating a zero linear operator A14 = I (range space of origA) ...\n";
00513   RCP<const Thyra::LinearOpBase<Scalar> >
00514     A14 = Thyra::identity(origA->range());
00515   if(out.get()) *out << "\nA14 =\n" << describe(*A14,verbLevel);
00516   
00517   if(out.get()) *out << "\nTesting A14 ...\n";
00518   Thyra::seed_randomize<Scalar>(0);
00519   result = symLinearOpTester.check(*A14,out.get());
00520   if(!result) success = false;
00521   
00522   if(out.get()) *out << "\n*** Leaving run_composite_linear_ops_tests<"<<ST::name()<<">(...) ...\n";
00523 
00524   return success;
00525 
00526 } // end run_composite_linear_ops_tests() [Doxygen looks for this!]
00527 
00528 int main( int argc, char* argv[] ) {
00529 
00530   using Teuchos::CommandLineProcessor;
00531 
00532   bool success = true;
00533   bool verbose = true;
00534 
00535   Teuchos::GlobalMPISession mpiSession(&argc,&argv);
00536 
00537   const Teuchos::RCP<const Teuchos::Comm<Thyra::Ordinal> >
00538     comm = Teuchos::DefaultComm<Thyra::Ordinal>::getComm();
00539 
00540   Teuchos::RCP<Teuchos::FancyOStream>
00541     out = Teuchos::VerboseObjectBase::getDefaultOStream();
00542   
00543   try {
00544 
00545     //
00546     // Read options from command-line
00547     //
00548 
00549     int n         = 4;
00550     bool useSpmd   = true;
00551     bool dumpAll  = false;
00552 
00553     CommandLineProcessor  clp;
00554     clp.throwExceptions(false);
00555     clp.addOutputSetupOptions(true);
00556     clp.setOption( "verbose", "quiet", &verbose, "Set if output is printed or not." );
00557     clp.setOption( "local-dim", &n, "Local number of elements in each constituent vector." );
00558     clp.setOption( "use-spmd", "use-serial", &useSpmd, "Determines if MPI or serial vector space is used." );
00559     clp.setOption( "dump-all", "no-dump-all", &dumpAll, "Determines if vectors are printed or not." );
00560     CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
00561     if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return;
00562 
00563     //
00564     // Run the tests
00565     //
00566 
00567 #ifdef HAVE_THYRA_TEUCHOS_BLASFLOAT
00568     if( !run_composite_linear_ops_tests<float>(comm,n,useSpmd,float(1e-4),dumpAll,verbose?&*out:NULL) ) success = false;
00569 #endif // HAVE_THYRA_TEUCHOS_BLASFLOAT
00570     if( !run_composite_linear_ops_tests<double>(comm,n,useSpmd,double(1e-12),dumpAll,verbose?&*out:NULL) ) success = false;
00571 #if defined(HAVE_THYRA_COMPLEX)
00572 #ifdef HAVE_THYRA_TEUCHOS_BLASFLOAT
00573     if( !run_composite_linear_ops_tests<std::complex<float> >(comm,n,useSpmd,float(1e-4),dumpAll,verbose?&*out:NULL) ) success = false;
00574 #endif // HAVE_THYRA_TEUCHOS_BLASFLOAT
00575     if( !run_composite_linear_ops_tests<std::complex<double> >(comm,n,useSpmd,double(1e-12),dumpAll,verbose?&*out:NULL) ) success = false;
00576 #endif
00577 #if defined(HAVE_TEUCHOS_GNU_MP) && !defined(USE_MPI) // mpf_class can not be used with MPI yet!
00578     if( !run_composite_linear_ops_tests<mpf_class>(comm,n,useSpmd,mpf_class(1e-12),dumpAll,verbose?&*out:NULL) ) success = false;
00579 #endif
00580 
00581   } // end try
00582   TEUCHOS_STANDARD_CATCH_STATEMENTS(true,*out,success)
00583 
00584   if( verbose ) {
00585     if(success) *out << "\nAll of the tests seem to have run successfully!\n";
00586     else        *out << "\nOh no! at least one of the tests failed!\n"; 
00587   }
00588   
00589   return success ? 0 : 1;
00590 
00591 } // end main() [Doxygen looks for this!]
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines