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 "SundanceNLOp.hpp"
00043 #include "SundanceOut.hpp"
00044 #include "PlayaTabs.hpp"
00045 #include "SundanceAssembler.hpp"
00046 #include "SundanceDiscreteFunction.hpp"
00047 #include "SundanceEquationSet.hpp"
00048 #include "SundanceLinearSolveDriver.hpp"
00049 #include "PlayaLinearSolverDecl.hpp"
00050
00051 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00052 #include "PlayaLinearOperatorImpl.hpp"
00053 #include "PlayaLinearSolverImpl.hpp"
00054 #include "PlayaLinearCombinationImpl.hpp"
00055 #endif
00056
00057 using namespace Sundance;
00058 using namespace Sundance;
00059 using namespace Sundance;
00060 using namespace Sundance;
00061 using namespace Sundance;
00062 using namespace Sundance;
00063 using namespace Sundance;
00064 using namespace Teuchos;
00065 using namespace std;
00066 using namespace Playa;
00067
00068
00069 static Time& nlpCtorTimer()
00070 {
00071 static RCP<Time> rtn
00072 = TimeMonitor::getNewTimer("NLOp ctor");
00073 return *rtn;
00074 }
00075
00076
00077 NLOp::NLOp()
00078 : NonlinearOperatorBase<double>(),
00079 assembler_(),
00080 u0_(),
00081 params_()
00082
00083 {
00084 TimeMonitor timer(nlpCtorTimer());
00085 }
00086
00087
00088 NLOp::NLOp(const Mesh& mesh,
00089 const Expr& eqn,
00090 const Expr& bc,
00091 const Expr& test,
00092 const Expr& unk,
00093 const Expr& u0,
00094 const VectorType<double>& vecType,
00095 bool partitionBCs)
00096 : NonlinearOperatorBase<double>(),
00097 assembler_(),
00098 u0_(u0),
00099 params_()
00100 {
00101 TimeMonitor timer(nlpCtorTimer());
00102
00103 Expr unkParams;
00104 Expr fixedParams;
00105 Expr fixedFields;
00106 Expr unkParamValues;
00107 Expr fixedParamValues;
00108 Expr fixedFieldValues;
00109
00110 RCP<EquationSet> eqnSet
00111 = rcp(new EquationSet(eqn, bc, tuple(test.flattenSpectral()), tuple(unk.flattenSpectral()), tuple(u0),
00112 unkParams, unkParamValues,
00113 fixedParams, fixedParamValues,
00114 tuple(fixedFields), tuple(fixedFieldValues)));
00115
00116 assembler_ = rcp(new Assembler(mesh, eqnSet, tuple(vecType), tuple(vecType), partitionBCs));
00117
00118 VectorSpace<double> domain = assembler_->solnVecSpace();
00119 VectorSpace<double> range = assembler_->rowVecSpace();
00120
00121 setDomainAndRange(domain, range);
00122 }
00123
00124
00125
00126 NLOp::NLOp(const Mesh& mesh,
00127 const Expr& eqn,
00128 const Expr& bc,
00129 const BlockArray& test,
00130 const BlockArray& unk,
00131 const Expr& u0)
00132 : NonlinearOperatorBase<double>(),
00133 assembler_(),
00134 u0_(u0),
00135 params_()
00136 {
00137 TimeMonitor timer(nlpCtorTimer());
00138 bool partitionBCs = false;
00139
00140 Array<Expr> v(test.size());
00141 Array<Expr> u(unk.size());
00142 Array<Expr> u0Array(unk.size());
00143
00144 Array<VectorType<double> > testVecType(test.size());
00145 Array<VectorType<double> > unkVecType(unk.size());
00146
00147 for (int i=0; i<test.size(); i++)
00148 {
00149 v[i] = test[i].expr().flattenSpectral();
00150 testVecType[i] = test[i].vecType();
00151 }
00152
00153 for (int i=0; i<unk.size(); i++)
00154 {
00155 u[i] = unk[i].expr().flattenSpectral();
00156 u0Array[i] = u0[i].flattenSpectral();
00157 unkVecType[i] = unk[i].vecType();
00158 }
00159
00160 Expr unkParams;
00161 Expr fixedParams;
00162 Expr fixedFields;
00163 Expr unkParamValues;
00164 Expr fixedParamValues;
00165 Expr fixedFieldValues;
00166
00167 RCP<EquationSet> eqnSet
00168 = rcp(new EquationSet(eqn, bc,
00169 v, u, u0Array,
00170 unkParams, unkParamValues,
00171 fixedParams, fixedParamValues,
00172 tuple(fixedFields), tuple(fixedFieldValues)));
00173
00174 assembler_ = rcp(new Assembler(mesh, eqnSet, testVecType, unkVecType, partitionBCs));
00175
00176 VectorSpace<double> domain = assembler_->solnVecSpace();
00177 VectorSpace<double> range = assembler_->rowVecSpace();
00178
00179 setDomainAndRange(domain, range);
00180 }
00181
00182
00183
00184 NLOp::NLOp(const Mesh& mesh,
00185 const Expr& eqn,
00186 const Expr& bc,
00187 const Expr& test,
00188 const Expr& unk,
00189 const Expr& u0,
00190 const Expr& params,
00191 const Expr& paramValues,
00192 const VectorType<double>& vecType,
00193 bool partitionBCs)
00194 : NonlinearOperatorBase<double>(),
00195 assembler_(),
00196 J_(),
00197 u0_(u0),
00198 params_(params)
00199 {
00200 TimeMonitor timer(nlpCtorTimer());
00201
00202 Expr unkParams;
00203 Expr fixedFields;
00204 Expr unkParamValues;
00205 Expr fixedFieldValues;
00206
00207 RCP<EquationSet> eqnSet
00208 = rcp(new EquationSet(
00209 eqn, bc, tuple(test.flattenSpectral()),
00210 tuple(unk.flattenSpectral()), tuple(u0),
00211 unkParams, unkParamValues,
00212 params, paramValues,
00213 tuple(fixedFields), tuple(fixedFieldValues)));
00214
00215 assembler_ = rcp(new Assembler(mesh, eqnSet, tuple(vecType), tuple(vecType), partitionBCs));
00216
00217 VectorSpace<double> domain = assembler_->solnVecSpace();
00218 VectorSpace<double> range = assembler_->rowVecSpace();
00219
00220 setDomainAndRange(domain, range);
00221 }
00222
00223
00224 NLOp::NLOp(const RCP<Assembler>& assembler,
00225 const Expr& u0)
00226 : NonlinearOperatorBase<double>(),
00227 assembler_(assembler),
00228 J_(),
00229 u0_(u0),
00230 params_()
00231 {
00232 TimeMonitor timer(nlpCtorTimer());
00233
00234 VectorSpace<double> domain = assembler_->solnVecSpace();
00235 VectorSpace<double> range = assembler_->rowVecSpace();
00236
00237 setDomainAndRange(domain, range);
00238 }
00239
00240
00241 void NLOp::updateDiscreteFunctionValue(const Vector<double>& vec) const
00242 {
00243 setDiscreteFunctionVector(u0_, vec.copy());
00244 }
00245
00246 Vector<double> NLOp::getInitialGuess() const
00247 {
00248 return getDiscreteFunctionVector(u0_);
00249 }
00250
00251 void NLOp::setInitialGuess(const Expr& u0New)
00252 {
00253 Vector<double> vec = getDiscreteFunctionVector(u0New);
00254 setEvalPt(vec);
00255 updateDiscreteFunctionValue(vec);
00256 }
00257
00258
00259 LinearOperator<double> NLOp::allocateJacobian() const
00260 {
00261 return assembler_->allocateMatrix();
00262 }
00263
00264
00265 LinearOperator<double> NLOp::
00266 computeJacobianAndFunction(Vector<double>& functionValue) const
00267 {
00268 updateDiscreteFunctionValue(currentEvalPt());
00269
00270 Array<Vector<double> > mv(1);
00271 mv[0].acceptCopyOf(functionValue);
00272 assembler_->assemble(J_, mv);
00273 functionValue.acceptCopyOf(mv[0]);
00274
00275 return J_;
00276 }
00277
00278 void NLOp::
00279 computeJacobianAndFunction(LinearOperator<double>& J,
00280 Vector<double>& resid) const
00281 {
00282 TEUCHOS_TEST_FOR_EXCEPTION(currentEvalPt().ptr().get()==0, std::runtime_error,
00283 "null evaluation point in "
00284 "NLOp::jacobian()");
00285
00286 TEUCHOS_TEST_FOR_EXCEPTION(J.ptr().get()==0, std::runtime_error,
00287 "null Jacobian pointer in "
00288 "NLOp::jacobian()");
00289
00290 TEUCHOS_TEST_FOR_EXCEPTION(resid.ptr().get()==0, std::runtime_error,
00291 "null residual pointer in "
00292 "NLOp::jacobian()");
00293
00294 Array<Vector<double> > mv(1);
00295 mv[0] = resid;
00296
00297 updateDiscreteFunctionValue(currentEvalPt());
00298 assembler_->assemble(J, mv);
00299
00300 resid.acceptCopyOf(mv[0]);
00301
00302 J_ = J;
00303 }
00304
00305
00306
00307
00308 Vector<double> NLOp::computeFunctionValue() const
00309 {
00310 TEUCHOS_TEST_FOR_EXCEPTION(currentEvalPt().ptr().get()==0, std::runtime_error,
00311 "null evaluation point in "
00312 "NLOp::computeFunctionValue()");
00313
00314 VectorSpace<double> spc = range();
00315 Vector<double> rtn = spc.createMember();
00316
00317 Array<Vector<double> > mv(1);
00318 mv[0] = rtn;
00319
00320 updateDiscreteFunctionValue(currentEvalPt());
00321 assembler_->assemble(mv);
00322
00323 rtn.acceptCopyOf(mv[0]);
00324
00325 return rtn;
00326 }
00327
00328
00329
00330 void NLOp::computeFunctionValue(Vector<double>& resid) const
00331 {
00332
00333
00334
00335 TEUCHOS_TEST_FOR_EXCEPTION(currentEvalPt().ptr().get()==0, std::runtime_error,
00336 "null evaluation point in "
00337 "NLOp::computeFunctionValue()");
00338
00339 TEUCHOS_TEST_FOR_EXCEPTION(resid.ptr().get()==0, std::runtime_error,
00340 "null residual pointer in "
00341 "NLOp::computeFunctionValue()");
00342
00343 updateDiscreteFunctionValue(currentEvalPt());
00344
00345
00346 Array<Vector<double> > mv(1);
00347 mv[0] = resid;
00348
00349 assembler_->assemble(mv);
00350
00351 resid.acceptCopyOf(mv[0]);
00352 }
00353
00354
00355
00356 Expr NLOp::
00357 computeSensitivities(const LinearSolver<double>& solver) const
00358 {
00359 TEUCHOS_TEST_FOR_EXCEPTION(currentEvalPt().ptr().get()==0, std::runtime_error,
00360 "null evaluation point in "
00361 "NLOp::computeSensitivities()");
00362
00363 TEUCHOS_TEST_FOR_EXCEPTION(J_.ptr().get()==0, std::runtime_error,
00364 "null Jacobian pointer in "
00365 "NLOp::computeSensitivities()");
00366
00367 TEUCHOS_TEST_FOR_EXCEPTION(params_.ptr().get()==0, std::runtime_error,
00368 "null parameters in NLOp::computeSensitivities()");
00369
00370 updateDiscreteFunctionValue(currentEvalPt());
00371
00372 Array<Vector<double> > mv(params_.size());
00373
00374 assembler_->assembleSensitivities(J_, mv);
00375
00376 LinearSolveDriver driver;
00377
00378 Expr sens;
00379 int vrb = 0;
00380 Array<Array<string> > names(params_.size());
00381 for (int i=0; i<params_.size(); i++)
00382 {
00383 names[i].resize(u0_.size());
00384 for (int j=0; j<u0_.size(); j++)
00385 names[i][j]="sens(" + u0_[j].toString() + ", " + params_[i].toString() + ")";
00386 mv[i].scale(-1.0);
00387 }
00388
00389 driver.solve(solver, J_, mv, assembler_->solutionSpace(), names, vrb, sens);
00390 return sens;
00391 }
00392
00393
00394 void NLOp::reAssembleProblem() const
00395 {
00396 assembler_->flushConfiguration();
00397 }