SundanceLinearProblem.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 "SundanceLinearProblem.hpp"
00032 #include "SundanceOut.hpp"
00033 #include "SundanceTabs.hpp"
00034 #include "SundanceAssembler.hpp"
00035 #include "SundanceDiscreteFunction.hpp"
00036 #include "SundanceEquationSet.hpp"
00037 #include "SundanceZeroExpr.hpp"
00038 #include "SundanceExpr.hpp"
00039 #include "SundanceListExpr.hpp"
00040 #include "TSFSolverState.hpp"
00041 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00042 #include "TSFLinearOperatorImpl.hpp"
00043 #endif
00044 
00045 
00046 using namespace Sundance;
00047 using namespace Teuchos;
00048 using namespace TSFExtended;
00049 using namespace std;
00050 
00051 
00052 static Time& lpCtorTimer() 
00053 {
00054   static RCP<Time> rtn 
00055     = TimeMonitor::getNewTimer("LinearProblem ctor"); 
00056   return *rtn;
00057 }
00058 
00059 
00060 LinearProblem::LinearProblem() 
00061   : assembler_(),
00062     A_(),
00063     rhs_()
00064 {
00065   TimeMonitor timer(lpCtorTimer());
00066 }
00067 
00068 
00069 
00070 LinearProblem::LinearProblem(const Mesh& mesh, 
00071   const Expr& eqn, 
00072   const Expr& bc,
00073   const Expr& test, 
00074   const Expr& unk, 
00075   const VectorType<double>& vecType)
00076   : assembler_(),
00077     A_(),
00078     rhs_(1),
00079     names_(1),
00080     solveDriver_()
00081 {
00082   bool partitionBCs = false;
00083   TimeMonitor timer(lpCtorTimer());
00084   Expr u = unk.flattenSpectral();
00085   Expr v = test.flattenSpectral();
00086 
00087   Array<Expr> zero(u.size());
00088   for (int i=0; i<u.size(); i++) 
00089   {
00090     Expr z = new ZeroExpr();
00091     zero[i] = z;
00092     names_[0].append(u[i].toString());
00093   }
00094 
00095   Expr u0 = new ListExpr(zero);
00096 
00097   Expr unkParams;
00098   Expr fixedParams;
00099   Array<Expr> fixedFields;
00100   Expr unkParamValues;
00101   Expr fixedParamValues;
00102   Array<Expr> fixedFieldValues;
00103 
00104 
00105   RCP<EquationSet> eqnSet 
00106     = rcp(new EquationSet(eqn, bc, tuple(v), tuple(u), tuple(u0),
00107         unkParams, unkParamValues,
00108         fixedParams, fixedParamValues,
00109         fixedFields, fixedFieldValues));
00110 
00111   assembler_ = rcp(new Assembler(mesh, eqnSet, tuple(vecType), tuple(vecType), partitionBCs));
00112 }
00113 
00114 
00115 LinearProblem::LinearProblem(const Mesh& mesh, 
00116   const Expr& eqn, 
00117   const Expr& bc,
00118   const Expr& test, 
00119   const Expr& unk, 
00120   const Expr& unkParams, 
00121   const Expr& unkParamVals, 
00122   const VectorType<double>& vecType)
00123   : assembler_(),
00124     A_(),
00125     rhs_(1),
00126     names_(1),
00127     solveDriver_()
00128 {
00129   bool partitionBCs = false;
00130   TimeMonitor timer(lpCtorTimer());
00131   Expr u = unk.flattenSpectral();
00132   Expr v = test.flattenSpectral();
00133   Expr alpha = unkParams.flattenSpectral();
00134   Expr alpha0 = unkParamVals.flattenSpectral();
00135   Array<Expr> zero(u.size());
00136   for (int i=0; i<u.size(); i++) 
00137   {
00138     Expr z = new ZeroExpr();
00139     zero[i] = z;
00140     names_[0].append(u[i].toString());
00141   }
00142 
00143   Expr u0 = new ListExpr(zero);
00144 
00145   Array<Expr> fixedFields;
00146   Expr fixedParams;
00147   
00148   RCP<EquationSet> eqnSet 
00149     = rcp(new EquationSet(eqn, bc, tuple(v), tuple(u), tuple(u0),
00150         alpha, alpha0,
00151         fixedParams, fixedParams, 
00152         fixedFields, fixedFields));
00153 
00154   assembler_ = rcp(new Assembler(mesh, eqnSet, tuple(vecType), tuple(vecType), partitionBCs));
00155 }
00156 
00157 
00158 
00159 LinearProblem::LinearProblem(const Mesh& mesh, 
00160   const Expr& eqn, 
00161   const Expr& bc,
00162   const BlockArray& test, 
00163   const BlockArray& unk)
00164   : assembler_(),
00165     A_(),
00166     rhs_(1),
00167     names_(unk.size()),
00168     solveDriver_()
00169 {
00170   bool partitionBCs = false;
00171   TimeMonitor timer(lpCtorTimer());
00172   Array<Expr> v(test.size());  
00173   Array<Expr> u(unk.size());
00174   Array<Expr> u0(unk.size());
00175 
00176   Array<VectorType<double> > testVecType(test.size());
00177   Array<VectorType<double> > unkVecType(unk.size());
00178 
00179   for (int i=0; i<test.size(); i++)
00180   {
00181     v[i] = test[i].expr().flattenSpectral();
00182     testVecType[i] = test[i].vecType();
00183   }
00184 
00185   for (int i=0; i<unk.size(); i++)
00186   {
00187     u[i] = unk[i].expr().flattenSpectral();
00188     unkVecType[i] = unk[i].vecType();
00189     Array<Expr> zero(u[i].size());
00190     for (int j=0; j<u[i].size(); j++) 
00191     {
00192       Expr z = new ZeroExpr();
00193       zero[j] = z;
00194       names_[i].append(u[i][j].toString());
00195     }
00196     u0[i] = new ListExpr(zero);
00197 
00198   }
00199 
00200   Expr unkParams;
00201   Expr fixedParams;
00202   Array<Expr> fixedFields;
00203   Expr unkParamValues;
00204   Expr fixedParamValues;
00205   Array<Expr> fixedFieldValues;
00206   
00207   RCP<EquationSet> eqnSet 
00208     = rcp(new EquationSet(eqn, bc, v, u, u0,
00209         unkParams, unkParamValues,
00210         fixedParams, fixedParamValues,
00211         fixedFields, fixedFieldValues));
00212 
00213   assembler_ = rcp(new Assembler(mesh, eqnSet, testVecType, unkVecType, partitionBCs));
00214 }
00215 
00216 
00217 LinearProblem::LinearProblem(const Mesh& mesh, 
00218   const Expr& eqn, 
00219   const Expr& bc,
00220   const BlockArray& test, 
00221   const BlockArray& unk,
00222   const Expr& unkParams, 
00223   const Expr& unkParamVals)
00224   : assembler_(),
00225     A_(),
00226     rhs_(1),
00227     names_(unk.size()),
00228     solveDriver_()
00229 {
00230   bool partitionBCs = false;
00231   TimeMonitor timer(lpCtorTimer());
00232   Array<Expr> v(test.size());  
00233   Array<Expr> u(unk.size());
00234   Array<Expr> u0(unk.size());
00235   Array<VectorType<double> > testVecType(test.size());
00236   Array<VectorType<double> > unkVecType(unk.size());
00237 
00238   for (int i=0; i<test.size(); i++)
00239   {
00240     v[i] = test[i].expr().flattenSpectral();
00241     testVecType[i] = test[i].vecType();
00242   }
00243 
00244   for (int i=0; i<unk.size(); i++)
00245   {
00246     u[i] = unk[i].expr().flattenSpectral();
00247     unkVecType[i] = unk[i].vecType();
00248     Array<Expr> zero(u[i].size());
00249     for (int j=0; j<u[i].size(); j++) 
00250     {
00251       Expr z = new ZeroExpr();
00252       zero[j] = z;
00253       names_[i].append(u[i][j].toString());
00254     }
00255     u0[i] = new ListExpr(zero);
00256   }
00257 
00258   Expr fixedParams;
00259   Array<Expr> fixedFields;
00260   Expr fixedParamValues;
00261   Array<Expr> fixedFieldValues;
00262   
00263   RCP<EquationSet> eqnSet 
00264     = rcp(new EquationSet(eqn, bc, v, u, u0,
00265         unkParams.flattenSpectral(), 
00266         unkParamVals.flattenSpectral(),
00267         fixedParams, fixedParamValues,
00268         fixedFields, fixedFieldValues));
00269 
00270   assembler_ = rcp(new Assembler(mesh, eqnSet, testVecType, unkVecType, partitionBCs));
00271 }
00272 
00273 LinearProblem::LinearProblem(const RCP<Assembler>& assembler)
00274   : assembler_(assembler),
00275     A_(),
00276     rhs_(1),
00277     names_()
00278 {  
00279   TimeMonitor timer(lpCtorTimer());
00280   const RCP<EquationSet>& eqn = assembler->eqnSet();
00281   names_.resize(eqn->numUnkBlocks());
00282   for (int i=0; i<eqn->numUnkBlocks(); i++)
00283   {
00284     for (int j=0; j<eqn->numUnks(i); j++) 
00285     {
00286       names_[i].append("u(" + Teuchos::toString(i) + ", "
00287         + Teuchos::toString(j) + ")");
00288     }
00289   }
00290 }
00291 
00292 /* Return the map from cells and functions to row indices */
00293 const RCP<DOFMapBase>& LinearProblem::rowMap(int blockRow) const 
00294 {return assembler_->rowMap()[blockRow];}
00295     
00296 /* Return the map from cells and functions to column indices */
00297 const RCP<DOFMapBase>& LinearProblem::colMap(int blockCol) const 
00298 {return assembler_->colMap()[blockCol];}
00299 
00300 /* Return the discrete space in which solutions live */
00301 const Array<RCP<DiscreteSpace> >& LinearProblem::solnSpace() const 
00302 {return assembler_->solutionSpace();}
00303     
00304 /* Return the set of row indices marked as 
00305  * essential boundary conditions */
00306 const RCP<Set<int> >& LinearProblem::bcRows(int blockRow) const 
00307 {return assembler_->bcRows()[blockRow];}
00308 
00309 /* Return the number of block rows in the problem  */
00310 int LinearProblem::numBlockRows() const {return assembler_->rowMap().size();}
00311 
00312 /* Return the number of block cols in the problem  */
00313 int LinearProblem::numBlockCols() const {return assembler_->colMap().size();}
00314 
00315 Array<Vector<double> > LinearProblem::getRHS() const 
00316 {
00317   Tabs tab;
00318   SUNDANCE_MSG1(assembler_->maxWatchFlagSetting("solve control"),
00319     tab << "LinearProblem::solve() building vector");
00320   assembler_->assemble(rhs_);
00321   return rhs_;
00322 }
00323 
00324 
00325 TSFExtended::LinearOperator<double> LinearProblem::getOperator() const 
00326 {
00327   Tabs tab;
00328   SUNDANCE_MSG1(assembler_->maxWatchFlagSetting("solve control"),
00329     tab << "LinearProblem::solve() building matrix and vector");
00330   assembler_->assemble(A_, rhs_);
00331   return A_;
00332 }
00333 
00334 Expr LinearProblem::solve(const LinearSolver<double>& solver) const 
00335 {
00336   Tabs tab;
00337   int verb = assembler_->maxWatchFlagSetting("solve control");
00338   Array<Vector<double> > solnVec(rhs_.size());
00339   
00340   SUNDANCE_MSG1(verb, tab << "LinearProblem::solve() building system");
00341 
00342   assembler_->assemble(A_, rhs_);
00343   for (int i=0; i<rhs_.size(); i++)
00344     rhs_[i].scale(-1.0);
00345 
00346   SUNDANCE_MSG1(verb, tab << "LinearProblem::solve() solving system");
00347 
00348   Expr rtn;
00349 
00350   /* we're not checking the status of the solve, so failures should
00351    * be considered fatal */
00352   bool save = LinearSolveDriver::solveFailureIsFatal();
00353   LinearSolveDriver::solveFailureIsFatal() = true;
00354 
00355   solveDriver_.solve(solver, A_, rhs_, solnSpace(), names_, verb, rtn);
00356 
00357   SUNDANCE_MSG1(verb, tab << "LinearProblem::solve() done solving system");
00358 
00359   /* restore original failure-handling setting */
00360   LinearSolveDriver::solveFailureIsFatal()=save; 
00361 
00362   return rtn;
00363 }
00364 
00365 SolverState<double> LinearProblem
00366 ::solve(const LinearSolver<double>& solver,
00367   Expr& soln) const 
00368 {
00369   Tabs tab;
00370   int verb = assembler_->maxWatchFlagSetting("solve control");
00371 
00372   Array<Vector<double> > solnVec(rhs_.size());
00373   
00374   SUNDANCE_MSG1(verb, tab << "LinearProblem::solve() building system");
00375 
00376   assembler_->assemble(A_, rhs_);
00377   for (int i=0; i<rhs_.size(); i++)
00378   {
00379     rhs_[i].scale(-1.0);
00380   }
00381 
00382   SUNDANCE_MSG1(verb, tab << "solving LinearProblem");
00383   
00384   return solveDriver_.solve(solver, A_, rhs_, solnSpace(), names_, verb, soln);
00385 }
00386 
00387 
00388 
00389 Vector<double> 
00390 LinearProblem::convertToMonolithicVector(const Array<Vector<double> >& internalBlock,
00391   const Array<Vector<double> >& bcBlock) const 
00392 {return assembler_->convertToMonolithicVector(internalBlock, bcBlock);}
00393 
00394 
00395 Expr LinearProblem::formSolutionExpr(const Array<Vector<double> >& vec) const
00396 {
00397   int verb = assembler_->maxWatchFlagSetting("solve control");
00398   return solveDriver_.formSolutionExpr(vec, solnSpace(), names_, verb);
00399 }
00400 
00401 
00402 

Site Contact