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

Site Contact