SundanceLinearSolveDriver.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #include "SundanceLinearSolveDriver.hpp"
00043 #include "PlayaLinearSolverDecl.hpp"
00044 #include "SundanceOut.hpp"
00045 #include "PlayaTabs.hpp"
00046 
00047 
00048 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00049 #include "PlayaLinearSolverImpl.hpp"
00050 #endif
00051 
00052 
00053 
00054 
00055 using namespace Sundance;
00056 using namespace Sundance;
00057 using namespace Sundance;
00058 using namespace Sundance;
00059 using namespace Sundance;
00060 using namespace Sundance;
00061 using namespace Sundance;
00062 using namespace Teuchos;
00063 using namespace Playa;
00064 using namespace std;
00065 
00066 
00067 SolverState<double> 
00068 LinearSolveDriver::solve(const LinearSolver<double>& solver,
00069   const LinearOperator<double>& A,
00070   const Array<Vector<double> >& rhs,
00071   const Array<RCP<DiscreteSpace> >& solutionSpace,
00072   const Array<Array<string> >& names,
00073   int verb,
00074   Expr& soln) const
00075 {
00076   Tabs tab(0);
00077   Array<Vector<double> > solnVec(rhs.size());
00078   SolverState<double> state;
00079 
00080   for (int i=0; i<rhs.size(); i++)
00081   {
00082     Tabs tab1;
00083 
00084     solnVec[i] = rhs[i].copy();
00085     
00086     SUNDANCE_MSG2(verb, tab1 << "solving with RHS #" << i 
00087       << " of " << rhs.size());
00088 
00089     state = solver.solve(A, rhs[i], solnVec[i]);
00090     
00091     SUNDANCE_MSG2(verb, tab1 << "solve completed with status="
00092       << state.stateDescription());
00093 
00094     /* deal with a failure to converge */
00095     if (state.finalState() != SolveConverged)
00096     {
00097       TeuchosOStringStream ss;
00098       ss << "Solve failed! state = "
00099          << state.stateDescription()
00100          << "\nmessage=" << state.finalMsg()
00101          << "\niters taken = " << state.finalIters()
00102          << "\nfinal residual = " << state.finalResid();
00103 
00104       /* If requested, write the bad matrix and vector */
00105       if (dumpBadMatrix())
00106       {
00107         if (A.ptr().get() != 0)
00108         {
00109           ofstream osA(badMatrixFilename().c_str());
00110           A.print(osA);
00111           ss << "\nmatrix written to " << badMatrixFilename();
00112         }
00113         else
00114         {
00115           ss << "\nthe matrix is null! Evil is afoot in your code...";
00116         }
00117         if (rhs[i].ptr().get() != 0)
00118         {
00119           ofstream osb(badVectorFilename().c_str());
00120           rhs[i].print(osb);
00121           ss << "\nRHS vector written to " << badVectorFilename();
00122         }
00123         else
00124         {
00125           ss << "\nthe RHS vector is null! Evil is afoot in your code...";
00126         }
00127       }
00128       
00129       /* If solve errors are fatal, throw an exception */
00130       TEUCHOS_TEST_FOR_EXCEPTION(solveFailureIsFatal(),
00131         std::runtime_error, TEUCHOS_OSTRINGSTREAM_GET_C_STR(ss));
00132 
00133       /* otherwise, return the state information */
00134       return state;
00135     }
00136   }
00137    
00138   /* Put the solution vector into a discrete function */
00139   if (soln.ptr().get()==0)
00140   {
00141     soln = formSolutionExpr(solnVec, solutionSpace, names, verb);
00142   }
00143   else
00144   {
00145     writeIntoSolutionExpr(solnVec, soln, verb);
00146   }
00147 
00148   return state;
00149       
00150 }
00151 
00152 
00153 
00154 Expr LinearSolveDriver::formSolutionExpr(
00155   const Array<Vector<double> >& solnVector,
00156   const Array<RCP<DiscreteSpace> >& solutionSpace,
00157   const Array<Array<string> >& names,
00158   int verb) const
00159 {
00160   Array<Expr> cols(solnVector.size());
00161 
00162   for (int m=0; m<solnVector.size(); m++)
00163   {
00164     Array<Expr> col(solutionSpace.size());
00165 
00166     for (int i=0; i<col.size(); i++)
00167     {
00168       std::string name = names[m][i];
00169       if (col.size() > 1) name += "[" + Teuchos::toString(i) + "]";
00170       col[i] = new DiscreteFunction(*(solutionSpace[i]),
00171         solnVector[m].getBlock(i), name);
00172     }
00173     if (col.size() > 1)
00174     {
00175       cols[m] = new ListExpr(col);
00176     }
00177     else
00178     {
00179       cols[m] = col[0];
00180     }
00181   }
00182 
00183   if (cols.size() > 1)
00184   {
00185     return new ListExpr(cols);;
00186   }
00187   else
00188   {
00189     return cols[0];
00190   }
00191 }
00192 
00193 
00194 void LinearSolveDriver::writeIntoSolutionExpr(
00195   const Array<Vector<double> >& solnVector,
00196   Expr soln,
00197   int verb) const 
00198 {
00199 #ifdef BLAH
00200   TEUCHOS_TEST_FOR_EXCEPTION(soln.size() != solnVector.size(),
00201     std::runtime_error,
00202     "soln=" << soln << " soln.size()=" << soln.size() << " while solnVector.size()=" << solnVector.size());
00203 #endif
00204   for (int i=0; i<solnVector.size(); i++)
00205   {
00206     Expr u = soln[i];
00207     setDiscreteFunctionVector(u, solnVector[i]);
00208   }
00209 }

Site Contact