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
00032
00033
00034
00035
00036
00037
00038
00039
00040
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
00311 const RCP<DOFMapBase>& LinearProblem::rowMap(int blockRow) const
00312 {return assembler_->rowMap()[blockRow];}
00313
00314
00315 const RCP<DOFMapBase>& LinearProblem::colMap(int blockCol) const
00316 {return assembler_->colMap()[blockCol];}
00317
00318
00319 const Array<RCP<DiscreteSpace> >& LinearProblem::solnSpace() const
00320 {return assembler_->solutionSpace();}
00321
00322
00323
00324 const RCP<Set<int> >& LinearProblem::bcRows(int blockRow) const
00325 {return assembler_->bcRows()[blockRow];}
00326
00327
00328 int LinearProblem::numBlockRows() const {return assembler_->rowMap().size();}
00329
00330
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
00369
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
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