00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
00293 const RCP<DOFMapBase>& LinearProblem::rowMap(int blockRow) const
00294 {return assembler_->rowMap()[blockRow];}
00295
00296
00297 const RCP<DOFMapBase>& LinearProblem::colMap(int blockCol) const
00298 {return assembler_->colMap()[blockCol];}
00299
00300
00301 const Array<RCP<DiscreteSpace> >& LinearProblem::solnSpace() const
00302 {return assembler_->solutionSpace();}
00303
00304
00305
00306 const RCP<Set<int> >& LinearProblem::bcRows(int blockRow) const
00307 {return assembler_->bcRows()[blockRow];}
00308
00309
00310 int LinearProblem::numBlockRows() const {return assembler_->rowMap().size();}
00311
00312
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
00351
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
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