SundanceLinearSolveDriver.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                              Sundance
00005 //                 Copyright (2005) Sandia Corporation
00006 // 
00007 // Copyright (year first published) Sandia Corporation.  Under the terms 
00008 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 
00009 // retains certain rights in this software.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //                                                                                 
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA                                                                                
00025 // Questions? Contact Kevin Long (krlong@sandia.gov), 
00026 // Sandia National Laboratories, Livermore, California, USA
00027 // 
00028 // ************************************************************************
00029 /* @HEADER@ */
00030 
00031 #include "SundanceLinearSolveDriver.hpp"
00032 #include "PlayaLinearSolverDecl.hpp"
00033 #include "SundanceOut.hpp"
00034 #include "PlayaTabs.hpp"
00035 
00036 
00037 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00038 #include "PlayaLinearSolverImpl.hpp"
00039 #endif
00040 
00041 
00042 
00043 
00044 using namespace Sundance;
00045 using namespace Sundance;
00046 using namespace Sundance;
00047 using namespace Sundance;
00048 using namespace Sundance;
00049 using namespace Sundance;
00050 using namespace Sundance;
00051 using namespace Teuchos;
00052 using namespace Playa;
00053 using namespace std;
00054 
00055 
00056 SolverState<double> 
00057 LinearSolveDriver::solve(const LinearSolver<double>& solver,
00058   const LinearOperator<double>& A,
00059   const Array<Vector<double> >& rhs,
00060   const Array<RCP<DiscreteSpace> >& solutionSpace,
00061   const Array<Array<string> >& names,
00062   int verb,
00063   Expr& soln) const
00064 {
00065   Tabs tab(0);
00066   Array<Vector<double> > solnVec(rhs.size());
00067   SolverState<double> state;
00068 
00069   for (int i=0; i<rhs.size(); i++)
00070   {
00071     Tabs tab1;
00072 
00073     solnVec[i] = rhs[i].copy();
00074     
00075     SUNDANCE_MSG2(verb, tab1 << "solving with RHS #" << i 
00076       << " of " << rhs.size());
00077 
00078     state = solver.solve(A, rhs[i], solnVec[i]);
00079     
00080     SUNDANCE_MSG2(verb, tab1 << "solve completed with status="
00081       << state.stateDescription());
00082 
00083     /* deal with a failure to converge */
00084     if (state.finalState() != SolveConverged)
00085     {
00086       TeuchosOStringStream ss;
00087       ss << "Solve failed! state = "
00088          << state.stateDescription()
00089          << "\nmessage=" << state.finalMsg()
00090          << "\niters taken = " << state.finalIters()
00091          << "\nfinal residual = " << state.finalResid();
00092 
00093       /* If requested, write the bad matrix and vector */
00094       if (dumpBadMatrix())
00095       {
00096         if (A.ptr().get() != 0)
00097         {
00098           ofstream osA(badMatrixFilename().c_str());
00099           A.print(osA);
00100           ss << "\nmatrix written to " << badMatrixFilename();
00101         }
00102         else
00103         {
00104           ss << "\nthe matrix is null! Evil is afoot in your code...";
00105         }
00106         if (rhs[i].ptr().get() != 0)
00107         {
00108           ofstream osb(badVectorFilename().c_str());
00109           rhs[i].print(osb);
00110           ss << "\nRHS vector written to " << badVectorFilename();
00111         }
00112         else
00113         {
00114           ss << "\nthe RHS vector is null! Evil is afoot in your code...";
00115         }
00116       }
00117       
00118       /* If solve errors are fatal, throw an exception */
00119       TEUCHOS_TEST_FOR_EXCEPTION(solveFailureIsFatal(),
00120         std::runtime_error, TEUCHOS_OSTRINGSTREAM_GET_C_STR(ss));
00121 
00122       /* otherwise, return the state information */
00123       return state;
00124     }
00125   }
00126    
00127   /* Put the solution vector into a discrete function */
00128   if (soln.ptr().get()==0)
00129   {
00130     soln = formSolutionExpr(solnVec, solutionSpace, names, verb);
00131   }
00132   else
00133   {
00134     writeIntoSolutionExpr(solnVec, soln, verb);
00135   }
00136 
00137   return state;
00138       
00139 }
00140 
00141 
00142 
00143 Expr LinearSolveDriver::formSolutionExpr(
00144   const Array<Vector<double> >& solnVector,
00145   const Array<RCP<DiscreteSpace> >& solutionSpace,
00146   const Array<Array<string> >& names,
00147   int verb) const
00148 {
00149   Array<Expr> cols(solnVector.size());
00150 
00151   for (int m=0; m<solnVector.size(); m++)
00152   {
00153     Array<Expr> col(solutionSpace.size());
00154 
00155     for (int i=0; i<col.size(); i++)
00156     {
00157       std::string name = names[m][i];
00158       if (col.size() > 1) name += "[" + Teuchos::toString(i) + "]";
00159       col[i] = new DiscreteFunction(*(solutionSpace[i]),
00160         solnVector[m].getBlock(i), name);
00161     }
00162     if (col.size() > 1)
00163     {
00164       cols[m] = new ListExpr(col);
00165     }
00166     else
00167     {
00168       cols[m] = col[0];
00169     }
00170   }
00171 
00172   if (cols.size() > 1)
00173   {
00174     return new ListExpr(cols);;
00175   }
00176   else
00177   {
00178     return cols[0];
00179   }
00180 }
00181 
00182 
00183 void LinearSolveDriver::writeIntoSolutionExpr(
00184   const Array<Vector<double> >& solnVector,
00185   Expr soln,
00186   int verb) const 
00187 {
00188 #ifdef BLAH
00189   TEUCHOS_TEST_FOR_EXCEPTION(soln.size() != solnVector.size(),
00190     std::runtime_error,
00191     "soln=" << soln << " soln.size()=" << soln.size() << " while solnVector.size()=" << solnVector.size());
00192 #endif
00193   for (int i=0; i<solnVector.size(); i++)
00194   {
00195     Expr u = soln[i];
00196     setDiscreteFunctionVector(u, solnVector[i]);
00197   }
00198 }

Site Contact