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 #include "FEApp_InitPostOps.hpp"
00033 #include "Teuchos_TestForException.hpp"
00034
00035 #include "Epetra_Map.h"
00036
00037 FEApp::ResidualOp::ResidualOp(
00038 const Teuchos::RCP<const Epetra_Vector>& overlapped_xdot,
00039 const Teuchos::RCP<const Epetra_Vector>& overlapped_x,
00040 const Teuchos::RCP<Epetra_Vector>& overlapped_f) :
00041 xdot(overlapped_xdot),
00042 x(overlapped_x),
00043 f(overlapped_f)
00044 {
00045 }
00046
00047 FEApp::ResidualOp::~ResidualOp()
00048 {
00049 }
00050
00051 void
00052 FEApp::ResidualOp::elementInit(const FEApp::AbstractElement& e,
00053 unsigned int neqn,
00054 std::vector<double>* elem_xdot,
00055 std::vector<double>& elem_x)
00056 {
00057
00058 unsigned int node_GID;
00059
00060
00061 unsigned int firstDOF;
00062
00063
00064 unsigned int nnode = e.numNodes();
00065
00066
00067 for (unsigned int i=0; i<nnode; i++) {
00068 node_GID = e.nodeGID(i);
00069 firstDOF = x->Map().LID(node_GID*neqn);
00070 for (unsigned int j=0; j<neqn; j++) {
00071 elem_x[neqn*i+j] = (*x)[firstDOF+j];
00072 if (elem_xdot != NULL)
00073 (*elem_xdot)[neqn*i+j] = (*xdot)[firstDOF+j];
00074 }
00075 }
00076 }
00077
00078 void
00079 FEApp::ResidualOp::elementPost(const FEApp::AbstractElement& e,
00080 unsigned int neqn,
00081 std::vector<double>& elem_f)
00082 {
00083
00084 unsigned int nnode = e.numNodes();
00085
00086
00087 int row;
00088 unsigned int lrow;
00089 for (unsigned int node_row=0; node_row<nnode; node_row++) {
00090 for (unsigned int eq_row=0; eq_row<neqn; eq_row++) {
00091 lrow = neqn*node_row+eq_row;
00092 row = static_cast<int>(e.nodeGID(node_row)*neqn + eq_row);
00093 f->SumIntoGlobalValue(row, 0, elem_f[lrow]);
00094 }
00095 }
00096 }
00097
00098 void
00099 FEApp::ResidualOp::nodeInit(const FEApp::NodeBC& bc,
00100 unsigned int neqn,
00101 std::vector<double>* node_xdot,
00102 std::vector<double>& node_x)
00103 {
00104
00105 unsigned int node_GID = bc.getNodeGID();
00106
00107
00108 unsigned int firstDOF = x->Map().LID(node_GID*neqn);
00109
00110
00111 for (unsigned int j=0; j<neqn; j++) {
00112 node_x[j] = (*x)[firstDOF+j];
00113 if (node_xdot != NULL)
00114 (*node_xdot)[j] = (*xdot)[firstDOF+j];
00115 }
00116 }
00117
00118 void
00119 FEApp::ResidualOp::nodePost(const FEApp::NodeBC& bc,
00120 unsigned int neqn,
00121 std::vector<double>& node_f)
00122 {
00123
00124 unsigned int node_GID = bc.getNodeGID();
00125
00126
00127 unsigned int firstDOF = node_GID*neqn;
00128
00129
00130 const std::vector<unsigned int>& offsets = bc.getOffsets();
00131
00132
00133 for (unsigned int j=0; j<offsets.size(); j++) {
00134 int row = static_cast<int>(firstDOF + offsets[j]);
00135 if (bc.isOwned())
00136 f->ReplaceGlobalValue(row, 0, node_f[offsets[j]]);
00137 else if (bc.isShared())
00138 f->ReplaceGlobalValue(row, 0, 0.0);
00139 }
00140 }
00141
00142 FEApp::JacobianOp::JacobianOp(
00143 double alpha, double beta,
00144 const Teuchos::RCP<const Epetra_Vector>& overlapped_xdot,
00145 const Teuchos::RCP<const Epetra_Vector>& overlapped_x,
00146 const Teuchos::RCP<Epetra_Vector>& overlapped_f,
00147 const Teuchos::RCP<Epetra_CrsMatrix>& overlapped_jac) :
00148 m_coeff(alpha),
00149 j_coeff(beta),
00150 xdot(overlapped_xdot),
00151 x(overlapped_x),
00152 f(overlapped_f),
00153 jac(overlapped_jac)
00154 {
00155 }
00156
00157 FEApp::JacobianOp::~JacobianOp()
00158 {
00159 }
00160
00161 void
00162 FEApp::JacobianOp::elementInit(
00163 const FEApp::AbstractElement& e,
00164 unsigned int neqn,
00165 std::vector< Sacado::Fad::DFad<double> >* elem_xdot,
00166 std::vector< Sacado::Fad::DFad<double> >& elem_x)
00167 {
00168
00169 unsigned int node_GID;
00170
00171
00172 unsigned int firstDOF;
00173
00174
00175 unsigned int nnode = e.numNodes();
00176
00177
00178 unsigned int ndof = nnode*neqn;
00179
00180
00181 for (unsigned int i=0; i<nnode; i++) {
00182 node_GID = e.nodeGID(i);
00183 firstDOF = x->Map().LID(node_GID*neqn);
00184 for (unsigned int j=0; j<neqn; j++) {
00185 elem_x[neqn*i+j] =
00186 Sacado::Fad::DFad<double>(ndof, (*x)[firstDOF+j]);
00187 elem_x[neqn*i+j].fastAccessDx(neqn*i+j) = j_coeff;
00188 if (elem_xdot != NULL) {
00189 (*elem_xdot)[neqn*i+j] =
00190 Sacado::Fad::DFad<double>(ndof, (*xdot)[firstDOF+j]);
00191 (*elem_xdot)[neqn*i+j].fastAccessDx(neqn*i+j) = m_coeff;
00192 }
00193
00194 }
00195 }
00196 }
00197
00198 void
00199 FEApp::JacobianOp::elementPost(
00200 const FEApp::AbstractElement& e,
00201 unsigned int neqn,
00202 std::vector< Sacado::Fad::DFad<double> >& elem_f)
00203 {
00204
00205 unsigned int nnode = e.numNodes();
00206
00207
00208
00209 int row, col;
00210 unsigned int lrow, lcol;
00211 for (unsigned int node_row=0; node_row<nnode; node_row++) {
00212
00213
00214 for (unsigned int eq_row=0; eq_row<neqn; eq_row++) {
00215 lrow = neqn*node_row+eq_row;
00216
00217
00218 row = static_cast<int>(e.nodeGID(node_row)*neqn + eq_row);
00219
00220
00221 if (f != Teuchos::null)
00222 f->SumIntoGlobalValue(row, 0, elem_f[lrow].val());
00223
00224
00225 if (elem_f[lrow].hasFastAccess()) {
00226
00227
00228 for (unsigned int node_col=0; node_col<nnode; node_col++){
00229
00230
00231 for (unsigned int eq_col=0; eq_col<neqn; eq_col++) {
00232 lcol = neqn*node_col+eq_col;
00233
00234
00235 col = static_cast<int>(e.nodeGID(node_col)*neqn + eq_col);
00236
00237
00238 jac->SumIntoGlobalValues(row, 1,
00239 &(elem_f[lrow].fastAccessDx(lcol)),
00240 &col);
00241
00242 }
00243
00244 }
00245
00246 }
00247
00248 }
00249
00250 }
00251
00252 }
00253
00254 void
00255 FEApp::JacobianOp::nodeInit(
00256 const FEApp::NodeBC& bc,
00257 unsigned int neqn,
00258 std::vector< Sacado::Fad::DFad<double> >* node_xdot,
00259 std::vector< Sacado::Fad::DFad<double> >& node_x)
00260 {
00261
00262 unsigned int node_GID = bc.getNodeGID();
00263
00264
00265 unsigned int firstDOF = x->Map().LID(node_GID*neqn);
00266
00267
00268 for (unsigned int j=0; j<neqn; j++) {
00269 node_x[j] = Sacado::Fad::DFad<double>(neqn, (*x)[firstDOF+j]);
00270 node_x[j].fastAccessDx(j) = j_coeff;
00271 if (node_xdot != NULL) {
00272 (*node_xdot)[j] = Sacado::Fad::DFad<double>(neqn, (*xdot)[firstDOF+j]);
00273 (*node_xdot)[j].fastAccessDx(j) = m_coeff;
00274 }
00275 }
00276 }
00277
00278 void
00279 FEApp::JacobianOp::nodePost(const FEApp::NodeBC& bc,
00280 unsigned int neqn,
00281 std::vector< Sacado::Fad::DFad<double> >& node_f)
00282 {
00283
00284 unsigned int node_GID = bc.getNodeGID();
00285
00286
00287 unsigned int firstDOF = node_GID*neqn;
00288
00289
00290 const std::vector<unsigned int>& offsets = bc.getOffsets();
00291
00292 int num_entries;
00293 double* row_view = 0;
00294 int row, col;
00295
00296
00297 for (unsigned int eq_row=0; eq_row<offsets.size(); eq_row++) {
00298
00299
00300 row = static_cast<int>(firstDOF + offsets[eq_row]);
00301
00302
00303 if (f != Teuchos::null) {
00304 if (bc.isOwned())
00305 f->ReplaceGlobalValue(row, 0, node_f[offsets[eq_row]].val());
00306 else if (bc.isShared())
00307 f->ReplaceGlobalValue(row, 0, 0.0);
00308 }
00309
00310
00311 if (bc.isOwned() || bc.isShared()) {
00312 jac->ExtractGlobalRowView(row, num_entries, row_view);
00313 for (int k=0; k<num_entries; k++)
00314 row_view[k] = 0.0;
00315 }
00316
00317
00318 if (node_f[offsets[eq_row]].hasFastAccess()) {
00319
00320
00321 for (unsigned int eq_col=0; eq_col<neqn; eq_col++) {
00322
00323
00324 col = static_cast<int>(firstDOF + eq_col);
00325
00326
00327 if (bc.isOwned())
00328 jac->ReplaceGlobalValues(row, 1,
00329 &(node_f[eq_row].fastAccessDx(eq_col)),
00330 &col);
00331
00332 }
00333
00334 }
00335
00336 }
00337
00338 }
00339
00340 FEApp::TangentOp::TangentOp(
00341 double alpha, double beta, bool sum_derivs_,
00342 const Teuchos::RCP<const Epetra_Vector>& overlapped_xdot,
00343 const Teuchos::RCP<const Epetra_Vector>& overlapped_x,
00344 const Teuchos::RCP<Sacado::ScalarParameterVector>& p,
00345 const Teuchos::RCP<const Epetra_MultiVector>& overlapped_Vx,
00346 const Teuchos::RCP<const Epetra_MultiVector>& overlapped_Vxdot,
00347 const Teuchos::RCP<const Teuchos::SerialDenseMatrix<int,double> >& Vp_,
00348 const Teuchos::RCP<Epetra_Vector>& overlapped_f,
00349 const Teuchos::RCP<Epetra_MultiVector>& overlapped_JV,
00350 const Teuchos::RCP<Epetra_MultiVector>& overlapped_fp) :
00351 m_coeff(alpha),
00352 j_coeff(beta),
00353 sum_derivs(sum_derivs_),
00354 xdot(overlapped_xdot),
00355 x(overlapped_x),
00356 params(p),
00357 Vx(overlapped_Vx),
00358 Vxdot(overlapped_Vxdot),
00359 Vp(Vp_),
00360 f(overlapped_f),
00361 JV(overlapped_JV),
00362 fp(overlapped_fp),
00363 num_cols_x(0),
00364 num_cols_p(0),
00365 num_cols_tot(0),
00366 param_offset(0)
00367 {
00368 if (Vx != Teuchos::null)
00369 num_cols_x = Vx->NumVectors();
00370 else if (Vxdot != Teuchos::null)
00371 num_cols_x = Vxdot->NumVectors();
00372 if (params != Teuchos::null) {
00373 if (Vp != Teuchos::null)
00374 num_cols_p = Vp->numCols();
00375 else
00376 num_cols_p = params->size();
00377 }
00378 if (sum_derivs) {
00379 num_cols_tot = num_cols_x;
00380 param_offset = 0;
00381 }
00382 else {
00383 num_cols_tot = num_cols_x + num_cols_p;
00384 param_offset = num_cols_x;
00385 }
00386
00387 TEST_FOR_EXCEPTION(sum_derivs && (num_cols_x != 0) && (num_cols_p != 0) &&
00388 (num_cols_x != num_cols_p),
00389 std::logic_error,
00390 "Seed matrices Vx and Vp must have the same number " <<
00391 " of columns when sum_derivs is true and both are "
00392 << "non-null!" << std::endl);
00393 }
00394
00395 FEApp::TangentOp::~TangentOp()
00396 {
00397 }
00398
00399 void
00400 FEApp::TangentOp::elementInit(
00401 const FEApp::AbstractElement& e,
00402 unsigned int neqn,
00403 std::vector< Sacado::Fad::DFad<double> >* elem_xdot,
00404 std::vector< Sacado::Fad::DFad<double> >& elem_x)
00405 {
00406
00407 unsigned int node_GID;
00408
00409
00410 unsigned int firstDOF;
00411
00412
00413 unsigned int nnode = e.numNodes();
00414
00415
00416 for (unsigned int i=0; i<nnode; i++) {
00417 node_GID = e.nodeGID(i);
00418 firstDOF = x->Map().LID(node_GID*neqn);
00419
00420 for (unsigned int j=0; j<neqn; j++) {
00421 if (Vx != Teuchos::null && j_coeff != 0.0) {
00422 elem_x[neqn*i+j] =
00423 Sacado::Fad::DFad<double>(num_cols_tot, (*x)[firstDOF+j]);
00424 for (int k=0; k<num_cols_x; k++)
00425 elem_x[neqn*i+j].fastAccessDx(k) = j_coeff*(*Vx)[k][firstDOF+j];
00426 }
00427 else
00428 elem_x[neqn*i+j] =
00429 Sacado::Fad::DFad<double>((*x)[firstDOF+j]);
00430
00431 if (elem_xdot != NULL) {
00432 if (Vxdot != Teuchos::null && m_coeff != 0.0) {
00433 (*elem_xdot)[neqn*i+j] =
00434 Sacado::Fad::DFad<double>(num_cols_tot, (*xdot)[firstDOF+j]);
00435 for (int k=0; k<num_cols_x; k++)
00436 (*elem_xdot)[neqn*i+j].fastAccessDx(k) =
00437 m_coeff*(*Vxdot)[k][firstDOF+j];
00438 }
00439 else
00440 (*elem_xdot)[neqn*i+j] =
00441 Sacado::Fad::DFad<double>((*xdot)[firstDOF+j]);
00442 }
00443
00444 }
00445 }
00446
00447 if (params != Teuchos::null) {
00448 FadType p;
00449 for (unsigned int i=0; i<params->size(); i++) {
00450 p = FadType(num_cols_tot, (*params)[i].baseValue);
00451 if (Vp != Teuchos::null)
00452 for (int k=0; k<num_cols_p; k++)
00453 p.fastAccessDx(param_offset+k) = (*Vp)(i,k);
00454 else
00455 p.fastAccessDx(param_offset+i) = 1.0;
00456 (*params)[i].family->setValueAsIndependent(p);
00457 }
00458 }
00459 }
00460
00461 void
00462 FEApp::TangentOp::elementPost(
00463 const FEApp::AbstractElement& e,
00464 unsigned int neqn,
00465 std::vector< Sacado::Fad::DFad<double> >& elem_f)
00466 {
00467
00468 unsigned int nnode = e.numNodes();
00469
00470 int row;
00471 unsigned int lrow;
00472 for (unsigned int node_row=0; node_row<nnode; node_row++) {
00473
00474
00475 for (unsigned int eq_row=0; eq_row<neqn; eq_row++) {
00476 lrow = neqn*node_row+eq_row;
00477
00478
00479 row = static_cast<int>(e.nodeGID(node_row)*neqn + eq_row);
00480
00481
00482 if (f != Teuchos::null)
00483 f->SumIntoGlobalValue(row, 0, elem_f[lrow].val());
00484
00485
00486 if (JV != Teuchos::null)
00487 for (int col=0; col<num_cols_x; col++)
00488 JV->SumIntoGlobalValue(row, col, elem_f[lrow].dx(col));
00489 if (fp != Teuchos::null)
00490 for (int col=0; col<num_cols_p; col++)
00491 fp->SumIntoGlobalValue(row, col, elem_f[lrow].dx(col+param_offset));
00492
00493 }
00494
00495 }
00496
00497 }
00498
00499 void
00500 FEApp::TangentOp::nodeInit(
00501 const FEApp::NodeBC& bc,
00502 unsigned int neqn,
00503 std::vector< Sacado::Fad::DFad<double> >* node_xdot,
00504 std::vector< Sacado::Fad::DFad<double> >& node_x)
00505 {
00506
00507 unsigned int node_GID = bc.getNodeGID();
00508
00509
00510 unsigned int firstDOF = x->Map().LID(node_GID*neqn);
00511
00512
00513 for (unsigned int j=0; j<neqn; j++) {
00514 if (Vx != Teuchos::null && j_coeff != 0.0) {
00515 node_x[j] = Sacado::Fad::DFad<double>(num_cols_tot, (*x)[firstDOF+j]);
00516 for (int k=0; k < num_cols_x; k++)
00517 node_x[j].fastAccessDx(k) = j_coeff*(*Vx)[k][firstDOF+j];
00518 }
00519 else
00520 node_x[j] = Sacado::Fad::DFad<double>((*x)[firstDOF+j]);
00521
00522 if (node_xdot != NULL) {
00523 if (Vxdot != Teuchos::null && m_coeff != 0.0) {
00524 (*node_xdot)[j] =
00525 Sacado::Fad::DFad<double>(num_cols_tot, (*xdot)[firstDOF+j]);
00526 for (int k=0; k < num_cols_x; k++)
00527 (*node_xdot)[j].fastAccessDx(k) = m_coeff*(*Vxdot)[k][firstDOF+j];
00528 }
00529 else
00530 (*node_xdot)[j] =
00531 Sacado::Fad::DFad<double>((*xdot)[firstDOF+j]);
00532 }
00533 }
00534
00535 if (params != Teuchos::null) {
00536 FadType p;
00537 for (unsigned int i=0; i<params->size(); i++) {
00538 p = FadType(num_cols_tot, (*params)[i].baseValue);
00539 if (Vp != Teuchos::null)
00540 for (int k=0; k<num_cols_p; k++)
00541 p.fastAccessDx(param_offset+k) = (*Vp)(i,k);
00542 else
00543 p.fastAccessDx(param_offset+i) = 1.0;
00544 (*params)[i].family->setValueAsIndependent(p);
00545 }
00546 }
00547 }
00548
00549 void
00550 FEApp::TangentOp::nodePost(const FEApp::NodeBC& bc,
00551 unsigned int neqn,
00552 std::vector< Sacado::Fad::DFad<double> >& node_f)
00553 {
00554
00555 unsigned int node_GID = bc.getNodeGID();
00556
00557
00558 unsigned int firstDOF = node_GID*neqn;
00559
00560
00561 const std::vector<unsigned int>& offsets = bc.getOffsets();
00562
00563 int row;
00564
00565
00566 for (unsigned int eq_row=0; eq_row<offsets.size(); eq_row++) {
00567
00568
00569 row = static_cast<int>(firstDOF + offsets[eq_row]);
00570
00571
00572 if (f != Teuchos::null) {
00573 if (bc.isOwned())
00574 f->ReplaceGlobalValue(row, 0, node_f[offsets[eq_row]].val());
00575 else if (bc.isShared())
00576 f->ReplaceGlobalValue(row, 0, 0.0);
00577 }
00578
00579 if (bc.isOwned()) {
00580
00581
00582 if (JV != Teuchos::null && Vx != Teuchos::null)
00583 for (int col=0; col<num_cols_x; col++)
00584 JV->ReplaceGlobalValue(row, col, node_f[offsets[eq_row]].dx(col));
00585
00586 if (fp != Teuchos::null)
00587 for (int col=0; col<num_cols_p; col++)
00588 fp->ReplaceGlobalValue(row, col,
00589 node_f[offsets[eq_row]].dx(col+param_offset));
00590 }
00591 else if (bc.isShared()) {
00592 if (JV != Teuchos::null && Vx != Teuchos::null)
00593 for (int col=0; col<num_cols_x; col++)
00594 JV->ReplaceGlobalValue(row, col, 0.0);
00595
00596 if (fp != Teuchos::null)
00597 for (int col=0; col<num_cols_p; col++)
00598 fp->ReplaceGlobalValue(row, col, 0.0);
00599 }
00600
00601 }
00602
00603 }
00604