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