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 #if SGFAD_ACTIVE
00038 #include "EpetraExt_MatrixMatrix.h"
00039 #endif
00040
00041 FEApp::ResidualOp::ResidualOp(
00042 const Teuchos::RCP<const Epetra_Vector>& overlapped_xdot,
00043 const Teuchos::RCP<const Epetra_Vector>& overlapped_x,
00044 const Teuchos::RCP<Epetra_Vector>& overlapped_f) :
00045 xdot(overlapped_xdot),
00046 x(overlapped_x),
00047 f(overlapped_f)
00048 {
00049 }
00050
00051 FEApp::ResidualOp::~ResidualOp()
00052 {
00053 }
00054
00055 void
00056 FEApp::ResidualOp::elementInit(const FEApp::AbstractElement& e,
00057 unsigned int neqn,
00058 std::vector<double>* elem_xdot,
00059 std::vector<double>& elem_x)
00060 {
00061
00062 unsigned int node_GID;
00063
00064
00065 unsigned int firstDOF;
00066
00067
00068 unsigned int nnode = e.numNodes();
00069
00070
00071 for (unsigned int i=0; i<nnode; i++) {
00072 node_GID = e.nodeGID(i);
00073 firstDOF = x->Map().LID(node_GID*neqn);
00074 for (unsigned int j=0; j<neqn; j++) {
00075 elem_x[neqn*i+j] = (*x)[firstDOF+j];
00076 if (elem_xdot != NULL)
00077 (*elem_xdot)[neqn*i+j] = (*xdot)[firstDOF+j];
00078 }
00079 }
00080 }
00081
00082 void
00083 FEApp::ResidualOp::elementPost(const FEApp::AbstractElement& e,
00084 unsigned int neqn,
00085 std::vector<double>& elem_f)
00086 {
00087
00088 unsigned int nnode = e.numNodes();
00089
00090
00091 int row;
00092 unsigned int lrow;
00093 for (unsigned int node_row=0; node_row<nnode; node_row++) {
00094 for (unsigned int eq_row=0; eq_row<neqn; eq_row++) {
00095 lrow = neqn*node_row+eq_row;
00096 row = static_cast<int>(e.nodeGID(node_row)*neqn + eq_row);
00097 f->SumIntoGlobalValue(row, 0, elem_f[lrow]);
00098 }
00099 }
00100 }
00101
00102 void
00103 FEApp::ResidualOp::nodeInit(const FEApp::NodeBC& bc,
00104 unsigned int neqn,
00105 std::vector<double>* node_xdot,
00106 std::vector<double>& node_x)
00107 {
00108
00109 unsigned int node_GID = bc.getNodeGID();
00110
00111
00112 unsigned int firstDOF = x->Map().LID(node_GID*neqn);
00113
00114
00115 for (unsigned int j=0; j<neqn; j++) {
00116 node_x[j] = (*x)[firstDOF+j];
00117 if (node_xdot != NULL)
00118 (*node_xdot)[j] = (*xdot)[firstDOF+j];
00119 }
00120 }
00121
00122 void
00123 FEApp::ResidualOp::nodePost(const FEApp::NodeBC& bc,
00124 unsigned int neqn,
00125 std::vector<double>& node_f)
00126 {
00127
00128 unsigned int node_GID = bc.getNodeGID();
00129
00130
00131 unsigned int firstDOF = node_GID*neqn;
00132
00133
00134 const std::vector<unsigned int>& offsets = bc.getOffsets();
00135
00136
00137 for (unsigned int j=0; j<offsets.size(); j++) {
00138 int row = static_cast<int>(firstDOF + offsets[j]);
00139 if (bc.isOwned())
00140 f->ReplaceGlobalValue(row, 0, node_f[offsets[j]]);
00141 else if (bc.isShared())
00142 f->ReplaceGlobalValue(row, 0, 0.0);
00143 }
00144 }
00145
00146 FEApp::JacobianOp::JacobianOp(
00147 double alpha, double beta,
00148 const Teuchos::RCP<const Epetra_Vector>& overlapped_xdot,
00149 const Teuchos::RCP<const Epetra_Vector>& overlapped_x,
00150 const Teuchos::RCP<Epetra_Vector>& overlapped_f,
00151 const Teuchos::RCP<Epetra_CrsMatrix>& overlapped_jac) :
00152 m_coeff(alpha),
00153 j_coeff(beta),
00154 xdot(overlapped_xdot),
00155 x(overlapped_x),
00156 f(overlapped_f),
00157 jac(overlapped_jac)
00158 {
00159 }
00160
00161 FEApp::JacobianOp::~JacobianOp()
00162 {
00163 }
00164
00165 void
00166 FEApp::JacobianOp::elementInit(
00167 const FEApp::AbstractElement& e,
00168 unsigned int neqn,
00169 std::vector< FadType >* elem_xdot,
00170 std::vector< FadType >& elem_x)
00171 {
00172
00173 unsigned int node_GID;
00174
00175
00176 unsigned int firstDOF;
00177
00178
00179 unsigned int nnode = e.numNodes();
00180
00181
00182 unsigned int ndof = nnode*neqn;
00183
00184
00185 for (unsigned int i=0; i<nnode; i++) {
00186 node_GID = e.nodeGID(i);
00187 firstDOF = x->Map().LID(node_GID*neqn);
00188 for (unsigned int j=0; j<neqn; j++) {
00189 elem_x[neqn*i+j] =
00190 FadType(ndof, (*x)[firstDOF+j]);
00191 elem_x[neqn*i+j].fastAccessDx(neqn*i+j) = j_coeff;
00192 if (elem_xdot != NULL) {
00193 (*elem_xdot)[neqn*i+j] =
00194 FadType(ndof, (*xdot)[firstDOF+j]);
00195 (*elem_xdot)[neqn*i+j].fastAccessDx(neqn*i+j) = m_coeff;
00196 }
00197
00198 }
00199 }
00200 }
00201
00202 void
00203 FEApp::JacobianOp::elementPost(
00204 const FEApp::AbstractElement& e,
00205 unsigned int neqn,
00206 std::vector< FadType >& elem_f)
00207 {
00208
00209 unsigned int nnode = e.numNodes();
00210
00211
00212
00213 int row, col;
00214 unsigned int lrow, lcol;
00215 for (unsigned int node_row=0; node_row<nnode; node_row++) {
00216
00217
00218 for (unsigned int eq_row=0; eq_row<neqn; eq_row++) {
00219 lrow = neqn*node_row+eq_row;
00220
00221
00222 row = static_cast<int>(e.nodeGID(node_row)*neqn + eq_row);
00223
00224
00225 if (f != Teuchos::null)
00226 f->SumIntoGlobalValue(row, 0, elem_f[lrow].val());
00227
00228
00229 if (elem_f[lrow].hasFastAccess()) {
00230
00231
00232 for (unsigned int node_col=0; node_col<nnode; node_col++){
00233
00234
00235 for (unsigned int eq_col=0; eq_col<neqn; eq_col++) {
00236 lcol = neqn*node_col+eq_col;
00237
00238
00239 col = static_cast<int>(e.nodeGID(node_col)*neqn + eq_col);
00240
00241
00242 jac->SumIntoGlobalValues(row, 1,
00243 &(elem_f[lrow].fastAccessDx(lcol)),
00244 &col);
00245
00246 }
00247
00248 }
00249
00250 }
00251
00252 }
00253
00254 }
00255
00256 }
00257
00258 void
00259 FEApp::JacobianOp::nodeInit(
00260 const FEApp::NodeBC& bc,
00261 unsigned int neqn,
00262 std::vector< FadType >* node_xdot,
00263 std::vector< FadType >& node_x)
00264 {
00265
00266 unsigned int node_GID = bc.getNodeGID();
00267
00268
00269 unsigned int firstDOF = x->Map().LID(node_GID*neqn);
00270
00271
00272 for (unsigned int j=0; j<neqn; j++) {
00273 node_x[j] = FadType(neqn, (*x)[firstDOF+j]);
00274 node_x[j].fastAccessDx(j) = j_coeff;
00275 if (node_xdot != NULL) {
00276 (*node_xdot)[j] = FadType(neqn, (*xdot)[firstDOF+j]);
00277 (*node_xdot)[j].fastAccessDx(j) = m_coeff;
00278 }
00279 }
00280 }
00281
00282 void
00283 FEApp::JacobianOp::nodePost(const FEApp::NodeBC& bc,
00284 unsigned int neqn,
00285 std::vector< FadType >& node_f)
00286 {
00287
00288 unsigned int node_GID = bc.getNodeGID();
00289
00290
00291 unsigned int firstDOF = node_GID*neqn;
00292
00293
00294 const std::vector<unsigned int>& offsets = bc.getOffsets();
00295
00296 int num_entries;
00297 double* row_view = 0;
00298 int row, col;
00299
00300
00301 for (unsigned int eq_row=0; eq_row<offsets.size(); eq_row++) {
00302
00303
00304 row = static_cast<int>(firstDOF + offsets[eq_row]);
00305
00306
00307 if (f != Teuchos::null) {
00308 if (bc.isOwned())
00309 f->ReplaceGlobalValue(row, 0, node_f[offsets[eq_row]].val());
00310 else if (bc.isShared())
00311 f->ReplaceGlobalValue(row, 0, 0.0);
00312 }
00313
00314
00315 if (bc.isOwned() || bc.isShared()) {
00316 jac->ExtractGlobalRowView(row, num_entries, row_view);
00317 for (int k=0; k<num_entries; k++)
00318 row_view[k] = 0.0;
00319 }
00320
00321
00322 if (node_f[offsets[eq_row]].hasFastAccess()) {
00323
00324
00325 for (unsigned int eq_col=0; eq_col<neqn; eq_col++) {
00326
00327
00328 col = static_cast<int>(firstDOF + eq_col);
00329
00330
00331 if (bc.isOwned())
00332 jac->ReplaceGlobalValues(row, 1,
00333 &(node_f[eq_row].fastAccessDx(eq_col)),
00334 &col);
00335
00336 }
00337
00338 }
00339
00340 }
00341
00342 }
00343
00344 FEApp::TangentOp::TangentOp(
00345 double alpha, double beta, bool sum_derivs_,
00346 const Teuchos::RCP<const Epetra_Vector>& overlapped_xdot,
00347 const Teuchos::RCP<const Epetra_Vector>& overlapped_x,
00348 const Teuchos::RCP<Sacado::ScalarParameterVector>& p,
00349 const Teuchos::RCP<const Epetra_MultiVector>& overlapped_Vx,
00350 const Teuchos::RCP<const Epetra_MultiVector>& overlapped_Vxdot,
00351 const Teuchos::RCP<const Teuchos::SerialDenseMatrix<int,double> >& Vp_,
00352 const Teuchos::RCP<Epetra_Vector>& overlapped_f,
00353 const Teuchos::RCP<Epetra_MultiVector>& overlapped_JV,
00354 const Teuchos::RCP<Epetra_MultiVector>& overlapped_fp) :
00355 m_coeff(alpha),
00356 j_coeff(beta),
00357 sum_derivs(sum_derivs_),
00358 xdot(overlapped_xdot),
00359 x(overlapped_x),
00360 params(p),
00361 Vx(overlapped_Vx),
00362 Vxdot(overlapped_Vxdot),
00363 Vp(Vp_),
00364 f(overlapped_f),
00365 JV(overlapped_JV),
00366 fp(overlapped_fp),
00367 num_cols_x(0),
00368 num_cols_p(0),
00369 num_cols_tot(0),
00370 param_offset(0)
00371 {
00372 if (Vx != Teuchos::null)
00373 num_cols_x = Vx->NumVectors();
00374 else if (Vxdot != Teuchos::null)
00375 num_cols_x = Vxdot->NumVectors();
00376 if (params != Teuchos::null) {
00377 if (Vp != Teuchos::null)
00378 num_cols_p = Vp->numCols();
00379 else
00380 num_cols_p = params->size();
00381 }
00382 if (sum_derivs) {
00383 num_cols_tot = num_cols_x;
00384 param_offset = 0;
00385 }
00386 else {
00387 num_cols_tot = num_cols_x + num_cols_p;
00388 param_offset = num_cols_x;
00389 }
00390
00391 TEST_FOR_EXCEPTION(sum_derivs && (num_cols_x != 0) && (num_cols_p != 0) &&
00392 (num_cols_x != num_cols_p),
00393 std::logic_error,
00394 "Seed matrices Vx and Vp must have the same number " <<
00395 " of columns when sum_derivs is true and both are "
00396 << "non-null!" << std::endl);
00397 }
00398
00399 FEApp::TangentOp::~TangentOp()
00400 {
00401 }
00402
00403 void
00404 FEApp::TangentOp::elementInit(
00405 const FEApp::AbstractElement& e,
00406 unsigned int neqn,
00407 std::vector< FadType >* elem_xdot,
00408 std::vector< FadType >& elem_x)
00409 {
00410
00411 unsigned int node_GID;
00412
00413
00414 unsigned int firstDOF;
00415
00416
00417 unsigned int nnode = e.numNodes();
00418
00419
00420 for (unsigned int i=0; i<nnode; i++) {
00421 node_GID = e.nodeGID(i);
00422 firstDOF = x->Map().LID(node_GID*neqn);
00423
00424 for (unsigned int j=0; j<neqn; j++) {
00425 if (Vx != Teuchos::null && j_coeff != 0.0) {
00426 elem_x[neqn*i+j] =
00427 FadType(num_cols_tot, (*x)[firstDOF+j]);
00428 for (int k=0; k<num_cols_x; k++)
00429 elem_x[neqn*i+j].fastAccessDx(k) = j_coeff*(*Vx)[k][firstDOF+j];
00430 }
00431 else
00432 elem_x[neqn*i+j] =
00433 FadType((*x)[firstDOF+j]);
00434
00435 if (elem_xdot != NULL) {
00436 if (Vxdot != Teuchos::null && m_coeff != 0.0) {
00437 (*elem_xdot)[neqn*i+j] =
00438 FadType(num_cols_tot, (*xdot)[firstDOF+j]);
00439 for (int k=0; k<num_cols_x; k++)
00440 (*elem_xdot)[neqn*i+j].fastAccessDx(k) =
00441 m_coeff*(*Vxdot)[k][firstDOF+j];
00442 }
00443 else
00444 (*elem_xdot)[neqn*i+j] =
00445 FadType((*xdot)[firstDOF+j]);
00446 }
00447
00448 }
00449 }
00450
00451 if (params != Teuchos::null) {
00452 FadType p;
00453 for (unsigned int i=0; i<params->size(); i++) {
00454 p = FadType(num_cols_tot, (*params)[i].baseValue);
00455 if (Vp != Teuchos::null)
00456 for (int k=0; k<num_cols_p; k++)
00457 p.fastAccessDx(param_offset+k) = (*Vp)(i,k);
00458 else
00459 p.fastAccessDx(param_offset+i) = 1.0;
00460 (*params)[i].family->setValueAsIndependent(p);
00461 }
00462 }
00463 }
00464
00465 void
00466 FEApp::TangentOp::elementPost(
00467 const FEApp::AbstractElement& e,
00468 unsigned int neqn,
00469 std::vector< FadType >& elem_f)
00470 {
00471
00472 unsigned int nnode = e.numNodes();
00473
00474 int row;
00475 unsigned int lrow;
00476 for (unsigned int node_row=0; node_row<nnode; node_row++) {
00477
00478
00479 for (unsigned int eq_row=0; eq_row<neqn; eq_row++) {
00480 lrow = neqn*node_row+eq_row;
00481
00482
00483 row = static_cast<int>(e.nodeGID(node_row)*neqn + eq_row);
00484
00485
00486 if (f != Teuchos::null)
00487 f->SumIntoGlobalValue(row, 0, elem_f[lrow].val());
00488
00489
00490 if (JV != Teuchos::null)
00491 for (int col=0; col<num_cols_x; col++)
00492 JV->SumIntoGlobalValue(row, col, elem_f[lrow].dx(col));
00493 if (fp != Teuchos::null)
00494 for (int col=0; col<num_cols_p; col++)
00495 fp->SumIntoGlobalValue(row, col, elem_f[lrow].dx(col+param_offset));
00496
00497 }
00498
00499 }
00500
00501 }
00502
00503 void
00504 FEApp::TangentOp::nodeInit(
00505 const FEApp::NodeBC& bc,
00506 unsigned int neqn,
00507 std::vector< FadType >* node_xdot,
00508 std::vector< FadType >& node_x)
00509 {
00510
00511 unsigned int node_GID = bc.getNodeGID();
00512
00513
00514 unsigned int firstDOF = x->Map().LID(node_GID*neqn);
00515
00516
00517 for (unsigned int j=0; j<neqn; j++) {
00518 if (Vx != Teuchos::null && j_coeff != 0.0) {
00519 node_x[j] = FadType(num_cols_tot, (*x)[firstDOF+j]);
00520 for (int k=0; k < num_cols_x; k++)
00521 node_x[j].fastAccessDx(k) = j_coeff*(*Vx)[k][firstDOF+j];
00522 }
00523 else
00524 node_x[j] = FadType((*x)[firstDOF+j]);
00525
00526 if (node_xdot != NULL) {
00527 if (Vxdot != Teuchos::null && m_coeff != 0.0) {
00528 (*node_xdot)[j] =
00529 FadType(num_cols_tot, (*xdot)[firstDOF+j]);
00530 for (int k=0; k < num_cols_x; k++)
00531 (*node_xdot)[j].fastAccessDx(k) = m_coeff*(*Vxdot)[k][firstDOF+j];
00532 }
00533 else
00534 (*node_xdot)[j] =
00535 FadType((*xdot)[firstDOF+j]);
00536 }
00537 }
00538
00539 if (params != Teuchos::null) {
00540 FadType p;
00541 for (unsigned int i=0; i<params->size(); i++) {
00542 p = FadType(num_cols_tot, (*params)[i].baseValue);
00543 if (Vp != Teuchos::null)
00544 for (int k=0; k<num_cols_p; k++)
00545 p.fastAccessDx(param_offset+k) = (*Vp)(i,k);
00546 else
00547 p.fastAccessDx(param_offset+i) = 1.0;
00548 (*params)[i].family->setValueAsIndependent(p);
00549 }
00550 }
00551 }
00552
00553 void
00554 FEApp::TangentOp::nodePost(const FEApp::NodeBC& bc,
00555 unsigned int neqn,
00556 std::vector< FadType >& node_f)
00557 {
00558
00559 unsigned int node_GID = bc.getNodeGID();
00560
00561
00562 unsigned int firstDOF = node_GID*neqn;
00563
00564
00565 const std::vector<unsigned int>& offsets = bc.getOffsets();
00566
00567 int row;
00568
00569
00570 for (unsigned int eq_row=0; eq_row<offsets.size(); eq_row++) {
00571
00572
00573 row = static_cast<int>(firstDOF + offsets[eq_row]);
00574
00575
00576 if (f != Teuchos::null) {
00577 if (bc.isOwned())
00578 f->ReplaceGlobalValue(row, 0, node_f[offsets[eq_row]].val());
00579 else if (bc.isShared())
00580 f->ReplaceGlobalValue(row, 0, 0.0);
00581 }
00582
00583 if (bc.isOwned()) {
00584
00585
00586 if (JV != Teuchos::null && Vx != Teuchos::null)
00587 for (int col=0; col<num_cols_x; col++)
00588 JV->ReplaceGlobalValue(row, col, node_f[offsets[eq_row]].dx(col));
00589
00590 if (fp != Teuchos::null)
00591 for (int col=0; col<num_cols_p; col++)
00592 fp->ReplaceGlobalValue(row, col,
00593 node_f[offsets[eq_row]].dx(col+param_offset));
00594 }
00595 else if (bc.isShared()) {
00596 if (JV != Teuchos::null && Vx != Teuchos::null)
00597 for (int col=0; col<num_cols_x; col++)
00598 JV->ReplaceGlobalValue(row, col, 0.0);
00599
00600 if (fp != Teuchos::null)
00601 for (int col=0; col<num_cols_p; col++)
00602 fp->ReplaceGlobalValue(row, col, 0.0);
00603 }
00604
00605 }
00606
00607 }
00608
00609 #if SG_ACTIVE
00610
00611 FEApp::SGResidualOp::SGResidualOp(
00612 const Teuchos::RCP<const Epetra_Map>& base_map,
00613 const Teuchos::RCP<const Stokhos::OrthogPolyBasis<double> >& sg_basis_,
00614 const Teuchos::RCP<const EpetraExt::BlockVector>& sg_overlapped_xdot,
00615 const Teuchos::RCP<const EpetraExt::BlockVector>& sg_overlapped_x,
00616 const Teuchos::RCP<EpetraExt::BlockVector>& sg_overlapped_f) :
00617 nblock(sg_basis_->size()),
00618 map(base_map),
00619 sg_basis(sg_basis_),
00620 sg_xdot(sg_overlapped_xdot),
00621 sg_x(sg_overlapped_x),
00622 sg_f(sg_overlapped_f),
00623 xdot(sg_xdot != Teuchos::null ? nblock : 0),
00624 x(nblock)
00625 {
00626 for (unsigned int block=0; block<nblock; block++) {
00627
00628 if (sg_xdot != Teuchos::null)
00629 xdot[block] = Teuchos::rcp(new Epetra_Vector(*map));
00630 x[block] = Teuchos::rcp(new Epetra_Vector(*map));
00631
00632
00633 sg_x->ExtractBlockValues(*x[block], block);
00634 if (sg_xdot != Teuchos::null)
00635 sg_xdot->ExtractBlockValues(*xdot[block], block);
00636 }
00637 }
00638
00639 FEApp::SGResidualOp::~SGResidualOp()
00640 {
00641 }
00642
00643 void
00644 FEApp::SGResidualOp::reset(
00645 const Teuchos::RCP<const EpetraExt::BlockVector>& sg_overlapped_xdot,
00646 const Teuchos::RCP<const EpetraExt::BlockVector>& sg_overlapped_x)
00647 {
00648 sg_xdot = sg_overlapped_xdot;
00649 sg_x = sg_overlapped_x;
00650
00651
00652 for (unsigned int block=0; block<nblock; block++) {
00653 sg_x->ExtractBlockValues(*x[block], block);
00654 if (sg_xdot != Teuchos::null)
00655 sg_xdot->ExtractBlockValues(*xdot[block], block);
00656 }
00657 }
00658
00659 void
00660 FEApp::SGResidualOp::elementInit(const FEApp::AbstractElement& e,
00661 unsigned int neqn,
00662 std::vector<SGType>* elem_xdot,
00663 std::vector<SGType>& elem_x)
00664 {
00665
00666 unsigned int node_GID;
00667
00668
00669 unsigned int firstDOF;
00670
00671
00672 unsigned int nnode = e.numNodes();
00673
00674
00675 for (unsigned int i=0; i<nnode; i++) {
00676 for (unsigned int j=0; j<neqn; j++) {
00677 if (elem_x[neqn*i+j].size() != nblock)
00678 elem_x[neqn*i+j].resize(nblock);
00679 if (elem_xdot != NULL && (*elem_xdot)[neqn*i+j].size() != nblock)
00680 (*elem_xdot)[neqn*i+j].resize(nblock);
00681 elem_x[neqn*i+j].copyForWrite();
00682 if (elem_xdot != NULL)
00683 (*elem_xdot)[neqn*i+j].copyForWrite();
00684 }
00685 }
00686
00687 for (unsigned int block=0; block<nblock; block++) {
00688
00689
00690 for (unsigned int i=0; i<nnode; i++) {
00691 node_GID = e.nodeGID(i);
00692 firstDOF = map->LID(node_GID*neqn);
00693 for (unsigned int j=0; j<neqn; j++) {
00694 elem_x[neqn*i+j].fastAccessCoeff(block) = (*x[block])[firstDOF+j];
00695 if (elem_xdot != NULL)
00696 (*elem_xdot)[neqn*i+j].fastAccessCoeff(block) =
00697 (*xdot[block])[firstDOF+j];
00698 }
00699 }
00700
00701 }
00702 }
00703
00704 void
00705 FEApp::SGResidualOp::elementPost(const FEApp::AbstractElement& e,
00706 unsigned int neqn,
00707 std::vector<SGType>& elem_f)
00708 {
00709
00710 unsigned int nnode = e.numNodes();
00711
00712
00713 unsigned int nblock = sg_basis->size();
00714
00715 int row;
00716 unsigned int lrow;
00717 double c;
00718
00719 for (unsigned int block=0; block<nblock; block++) {
00720
00721
00722 for (unsigned int node_row=0; node_row<nnode; node_row++) {
00723 for (unsigned int eq_row=0; eq_row<neqn; eq_row++) {
00724 lrow = neqn*node_row+eq_row;
00725 row = static_cast<int>(e.nodeGID(node_row)*neqn + eq_row);
00726 c = elem_f[lrow].coeff(block);
00727 sg_f->BlockSumIntoGlobalValues(1, &c, &row, block);
00728 }
00729 }
00730
00731 }
00732 }
00733
00734 void
00735 FEApp::SGResidualOp::nodeInit(const FEApp::NodeBC& bc,
00736 unsigned int neqn,
00737 std::vector<SGType>* node_xdot,
00738 std::vector<SGType>& node_x)
00739 {
00740
00741 unsigned int node_GID = bc.getNodeGID();
00742
00743
00744 unsigned int firstDOF = map->LID(node_GID*neqn);
00745
00746
00747 for (unsigned int j=0; j<neqn; j++) {
00748 if (node_x[j].size() != nblock)
00749 node_x[j].resize(nblock);
00750 if (node_xdot != NULL && node_x[j].size() != nblock)
00751 (*node_xdot)[j].resize(nblock);
00752 node_x[j].copyForWrite();
00753 if (node_xdot != NULL)
00754 (*node_xdot)[j].copyForWrite();
00755 }
00756
00757 for (unsigned int block=0; block<nblock; block++) {
00758
00759
00760 for (unsigned int j=0; j<neqn; j++) {
00761 node_x[j].fastAccessCoeff(block) = (*x[block])[firstDOF+j];
00762 if (node_xdot != NULL)
00763 (*node_xdot)[j].fastAccessCoeff(block) = (*xdot[block])[firstDOF+j];
00764 }
00765
00766 }
00767 }
00768
00769 void
00770 FEApp::SGResidualOp::nodePost(const FEApp::NodeBC& bc,
00771 unsigned int neqn,
00772 std::vector<SGType>& node_f)
00773 {
00774
00775 unsigned int node_GID = bc.getNodeGID();
00776
00777
00778 unsigned int firstDOF = node_GID*neqn;
00779
00780 double c;
00781 double zero = 0.0;
00782
00783
00784 const std::vector<unsigned int>& offsets = bc.getOffsets();
00785
00786 for (unsigned int block=0; block<nblock; block++) {
00787
00788
00789 for (unsigned int j=0; j<offsets.size(); j++) {
00790 int row = static_cast<int>(firstDOF + offsets[j]);
00791 if (bc.isOwned()) {
00792 c = node_f[offsets[j]].coeff(block);
00793 sg_f->BlockReplaceGlobalValues(1, &c, &row, block);
00794 }
00795 else if (bc.isShared())
00796 sg_f->BlockReplaceGlobalValues(1, &zero, &row, block);
00797 }
00798
00799 }
00800 }
00801
00802 void
00803 FEApp::SGResidualOp::finalizeFill()
00804 {
00805
00806
00807
00808 }
00809
00810 #endif // SG_ACTIVE
00811
00812 #if SGFAD_ACTIVE
00813
00814 FEApp::SGJacobianOp::SGJacobianOp(
00815 const Teuchos::RCP<const Epetra_Map>& base_map,
00816 const Teuchos::RCP<const Epetra_CrsGraph>& base_graph,
00817 const Teuchos::RCP<const Stokhos::OrthogPolyBasis<double> >& sg_basis_,
00818 const Teuchos::RCP<const FEApp::SGJacobianOp::tp_type>& Cijk_,
00819 double alpha, double beta,
00820 const Teuchos::RCP<const EpetraExt::BlockVector>& sg_overlapped_xdot,
00821 const Teuchos::RCP<const EpetraExt::BlockVector>& sg_overlapped_x,
00822 const Teuchos::RCP<EpetraExt::BlockVector>& sg_overlapped_f,
00823 const Teuchos::RCP<EpetraExt::BlockCrsMatrix>& sg_overlapped_jac) :
00824 nblock(sg_basis_->size()),
00825 map(base_map),
00826 graph(base_graph),
00827 sg_basis(sg_basis_),
00828 Cijk(Cijk_),
00829 m_coeff(alpha),
00830 j_coeff(beta),
00831 sg_xdot(sg_overlapped_xdot),
00832 sg_x(sg_overlapped_x),
00833 sg_f(sg_overlapped_f),
00834 sg_jac(sg_overlapped_jac),
00835 xdot(sg_xdot != Teuchos::null ? nblock : 0),
00836 x(nblock)
00837 {
00838 for (unsigned int block=0; block<nblock; block++) {
00839
00840 if (sg_xdot != Teuchos::null)
00841 xdot[block] = Teuchos::rcp(new Epetra_Vector(*map));
00842 x[block] = Teuchos::rcp(new Epetra_Vector(*map));
00843
00844
00845 sg_x->ExtractBlockValues(*x[block], block);
00846 if (sg_xdot != Teuchos::null)
00847 sg_xdot->ExtractBlockValues(*xdot[block], block);
00848 }
00849 }
00850
00851 FEApp::SGJacobianOp::~SGJacobianOp()
00852 {
00853 }
00854
00855 void
00856 FEApp::SGJacobianOp::reset(
00857 double alpha, double beta,
00858 const Teuchos::RCP<const EpetraExt::BlockVector>& sg_overlapped_xdot,
00859 const Teuchos::RCP<const EpetraExt::BlockVector>& sg_overlapped_x)
00860 {
00861 m_coeff = alpha;
00862 j_coeff = beta;
00863 sg_xdot = sg_overlapped_xdot;
00864 sg_x = sg_overlapped_x;
00865
00866
00867 for (unsigned int block=0; block<nblock; block++) {
00868 sg_x->ExtractBlockValues(*x[block], block);
00869 if (sg_xdot != Teuchos::null)
00870 sg_xdot->ExtractBlockValues(*xdot[block], block);
00871 }
00872 }
00873
00874 void
00875 FEApp::SGJacobianOp::elementInit(const FEApp::AbstractElement& e,
00876 unsigned int neqn,
00877 std::vector< SGFadType >* elem_xdot,
00878 std::vector< SGFadType >& elem_x)
00879 {
00880
00881 unsigned int node_GID;
00882
00883
00884 unsigned int firstDOF;
00885
00886
00887 unsigned int nnode = e.numNodes();
00888
00889
00890 unsigned int ndof = nnode*neqn;
00891
00892
00893 for (unsigned int i=0; i<nnode; i++) {
00894 node_GID = e.nodeGID(i);
00895 firstDOF = map->LID(node_GID*neqn);
00896 for (unsigned int j=0; j<neqn; j++) {
00897 elem_x[neqn*i+j] = SGFadType(ndof, 0.0);
00898 elem_x[neqn*i+j].fastAccessDx(neqn*i+j) = j_coeff;
00899 elem_x[neqn*i+j].val().resize(nblock);
00900 elem_x[neqn*i+j].val().copyForWrite();
00901 for (unsigned int block=0; block<nblock; block++)
00902 elem_x[neqn*i+j].val().fastAccessCoeff(block) =
00903 (*x[block])[firstDOF+j];
00904 if (elem_xdot != NULL) {
00905 (*elem_xdot)[neqn*i+j] = SGFadType(ndof, 0.0);
00906 (*elem_xdot)[neqn*i+j].fastAccessDx(neqn*i+j) = m_coeff;
00907 (*elem_xdot)[neqn*i+j].val().resize(nblock);
00908 (*elem_xdot)[neqn*i+j].val().copyForWrite();
00909 for (unsigned int block=0; block<nblock; block++)
00910 (*elem_xdot)[neqn*i+j].val().fastAccessCoeff(block) =
00911 (*xdot[block])[firstDOF+j];
00912 }
00913
00914 }
00915 }
00916
00917 }
00918
00919 void
00920 FEApp::SGJacobianOp::elementPost(const FEApp::AbstractElement& e,
00921 unsigned int neqn,
00922 std::vector< SGFadType >& elem_f)
00923 {
00924
00925 unsigned int nnode = e.numNodes();
00926
00927
00928
00929 int row, col;
00930 unsigned int lrow, lcol, nl, i, j;
00931 double v1, v2, cijk;
00932
00933 for (unsigned int node_row=0; node_row<nnode; node_row++) {
00934
00935
00936 for (unsigned int eq_row=0; eq_row<neqn; eq_row++) {
00937 lrow = neqn*node_row+eq_row;
00938
00939
00940 row = static_cast<int>(e.nodeGID(node_row)*neqn + eq_row);
00941
00942
00943 if (sg_f != Teuchos::null)
00944 for (unsigned int k=0; k<nblock; k++) {
00945 v1 = elem_f[lrow].val().coeff(k);
00946 sg_f->BlockSumIntoGlobalValues(1, &v1, &row, k);
00947 }
00948
00949
00950 if (elem_f[lrow].hasFastAccess()) {
00951
00952
00953 for (unsigned int node_col=0; node_col<nnode; node_col++){
00954
00955
00956 for (unsigned int eq_col=0; eq_col<neqn; eq_col++) {
00957 lcol = neqn*node_col+eq_col;
00958
00959
00960 col = static_cast<int>(e.nodeGID(node_col)*neqn + eq_col);
00961
00962
00963 for (unsigned int k=0; k<nblock; k++) {
00964 v1 = elem_f[lrow].fastAccessDx(lcol).coeff(k);
00965 nl = Cijk->num_values(k);
00966 for (unsigned int l=0; l<nl; l++) {
00967 Cijk->triple_value(k,l,i,j,cijk);
00968 v2 = v1 * cijk / Cijk->norm_squared(i);
00969 sg_jac->BlockSumIntoGlobalValues(row, 1, &v2, &col, i, j);
00970 }
00971 }
00972
00973 }
00974
00975 }
00976
00977 }
00978
00979 }
00980
00981 }
00982
00983 }
00984
00985 void
00986 FEApp::SGJacobianOp::nodeInit(const FEApp::NodeBC& bc,
00987 unsigned int neqn,
00988 std::vector< SGFadType >* node_xdot,
00989 std::vector< SGFadType >& node_x)
00990 {
00991
00992 unsigned int node_GID = bc.getNodeGID();
00993
00994
00995 unsigned int firstDOF = map->LID(node_GID*neqn);
00996
00997
00998 for (unsigned int j=0; j<neqn; j++) {
00999 node_x[j] = SGFadType(neqn, 0.0);
01000 node_x[j].fastAccessDx(j) = j_coeff;
01001 node_x[j].val().resize(nblock);
01002 node_x[j].val().copyForWrite();
01003 for (unsigned int block=0; block<nblock; block++)
01004 node_x[j].val().fastAccessCoeff(block) = (*x[block])[firstDOF+j];
01005 if (node_xdot != NULL) {
01006 (*node_xdot)[j] = SGFadType(neqn, 0.0);
01007 (*node_xdot)[j].fastAccessDx(j) = m_coeff;
01008 (*node_xdot)[j].val().resize(nblock);
01009 (*node_xdot)[j].val().copyForWrite();
01010 for (unsigned int block=0; block<nblock; block++)
01011 (*node_xdot)[j].val().fastAccessCoeff(block) =
01012 (*xdot[block])[firstDOF+j];
01013 }
01014 }
01015 }
01016
01017 void
01018 FEApp::SGJacobianOp::nodePost(const FEApp::NodeBC& bc,
01019 unsigned int neqn,
01020 std::vector< SGFadType >& node_f)
01021 {
01022
01023 unsigned int node_GID = bc.getNodeGID();
01024
01025
01026 unsigned int firstDOF = node_GID*neqn;
01027
01028
01029 const std::vector<unsigned int>& offsets = bc.getOffsets();
01030
01031 int num_entries;
01032 double* row_view = 0;
01033 int row, col;
01034 unsigned int nl, i, j;
01035 double v1, v2, cijk, zero;
01036 zero = 0.0;
01037
01038
01039 for (unsigned int eq_row=0; eq_row<offsets.size(); eq_row++) {
01040
01041
01042 row = static_cast<int>(firstDOF + offsets[eq_row]);
01043
01044
01045 if (sg_f != Teuchos::null) {
01046 if (bc.isOwned()) {
01047 for (unsigned int k=0; k<nblock; k++) {
01048 v1 = node_f[offsets[eq_row]].val().coeff(k);
01049 sg_f->BlockReplaceGlobalValues(1, &v1, &row, k);
01050 }
01051 }
01052 else if (bc.isShared()) {
01053 for (unsigned int k=0; k<nblock; k++)
01054 sg_f->BlockReplaceGlobalValues(1, &zero, &row, k);
01055 }
01056 }
01057
01058
01059
01060 if (bc.isOwned() || bc.isShared()) {
01061 for (unsigned int i=0; i<nblock; i++)
01062 for (unsigned int j=0; j<nblock; j++) {
01063 sg_jac->BlockExtractGlobalRowView(row, num_entries, row_view, i, j);
01064 for (int k=0; k<num_entries; k++)
01065 row_view[k] = 0.0;
01066 }
01067 }
01068
01069
01070 if (node_f[offsets[eq_row]].hasFastAccess()) {
01071
01072
01073 for (unsigned int eq_col=0; eq_col<neqn; eq_col++) {
01074
01075
01076 col = static_cast<int>(firstDOF + eq_col);
01077
01078
01079 if (bc.isOwned()) {
01080 for (unsigned int k=0; k<nblock; k++) {
01081 v1 = node_f[eq_row].fastAccessDx(eq_col).coeff(k);
01082 nl = Cijk->num_values(k);
01083 for (unsigned int l=0; l<nl; l++) {
01084 Cijk->triple_value(k,l,i,j,cijk);
01085 v2 = v1 * cijk / Cijk->norm_squared(i);
01086 sg_jac->BlockSumIntoGlobalValues(row, 1, &v2, &col, i, j);
01087 }
01088 }
01089 }
01090
01091 }
01092
01093 }
01094
01095 }
01096
01097 }
01098
01099 void
01100 FEApp::SGJacobianOp::finalizeFill()
01101 {
01102 }
01103
01104 FEApp::SGMatrixFreeJacobianOp::SGMatrixFreeJacobianOp(
01105 const Teuchos::RCP<const Epetra_Map>& base_map,
01106 const Teuchos::RCP<const Epetra_CrsGraph>& base_graph,
01107 const Teuchos::RCP<const Stokhos::OrthogPolyBasis<double> >& sg_basis_,
01108 double alpha, double beta,
01109 const Teuchos::RCP<const EpetraExt::BlockVector>& sg_overlapped_xdot,
01110 const Teuchos::RCP<const EpetraExt::BlockVector>& sg_overlapped_x,
01111 const Teuchos::RCP<EpetraExt::BlockVector>& sg_overlapped_f) :
01112 nblock(sg_basis_->size()),
01113 map(base_map),
01114 graph(base_graph),
01115 sg_basis(sg_basis_),
01116 m_coeff(alpha),
01117 j_coeff(beta),
01118 sg_xdot(sg_overlapped_xdot),
01119 sg_x(sg_overlapped_x),
01120 sg_f(sg_overlapped_f),
01121 xdot(sg_xdot != Teuchos::null ? nblock : 0),
01122 x(nblock),
01123 jac(nblock)
01124 {
01125 for (unsigned int block=0; block<nblock; block++) {
01126
01127 if (sg_xdot != Teuchos::null)
01128 xdot[block] = Teuchos::rcp(new Epetra_Vector(*map));
01129 x[block] = Teuchos::rcp(new Epetra_Vector(*map));
01130 jac[block] = Teuchos::rcp(new Epetra_CrsMatrix(Copy, *graph));
01131
01132
01133 sg_x->ExtractBlockValues(*x[block], block);
01134 if (sg_xdot != Teuchos::null)
01135 sg_xdot->ExtractBlockValues(*xdot[block], block);
01136 }
01137 }
01138
01139 FEApp::SGMatrixFreeJacobianOp::~SGMatrixFreeJacobianOp()
01140 {
01141 }
01142
01143 void
01144 FEApp::SGMatrixFreeJacobianOp::reset(
01145 double alpha, double beta,
01146 const Teuchos::RCP<const EpetraExt::BlockVector>& sg_overlapped_xdot,
01147 const Teuchos::RCP<const EpetraExt::BlockVector>& sg_overlapped_x)
01148 {
01149 m_coeff = alpha;
01150 j_coeff = beta;
01151 sg_xdot = sg_overlapped_xdot;
01152 sg_x = sg_overlapped_x;
01153
01154
01155 for (unsigned int block=0; block<nblock; block++) {
01156 sg_x->ExtractBlockValues(*x[block], block);
01157 if (sg_xdot != Teuchos::null)
01158 sg_xdot->ExtractBlockValues(*xdot[block], block);
01159 jac[block]->PutScalar(0.0);
01160 }
01161 }
01162
01163 std::vector< Teuchos::RCP<Epetra_CrsMatrix> >&
01164 FEApp::SGMatrixFreeJacobianOp::getJacobianBlocks()
01165 {
01166 return jac;
01167 }
01168
01169
01170 void
01171 FEApp::SGMatrixFreeJacobianOp::elementInit(const FEApp::AbstractElement& e,
01172 unsigned int neqn,
01173 std::vector< SGFadType >* elem_xdot,
01174 std::vector< SGFadType >& elem_x)
01175 {
01176
01177 unsigned int node_GID;
01178
01179
01180 unsigned int firstDOF;
01181
01182
01183 unsigned int nnode = e.numNodes();
01184
01185
01186 unsigned int ndof = nnode*neqn;
01187
01188
01189 for (unsigned int i=0; i<nnode; i++) {
01190 node_GID = e.nodeGID(i);
01191 firstDOF = map->LID(node_GID*neqn);
01192 for (unsigned int j=0; j<neqn; j++) {
01193 elem_x[neqn*i+j] = SGFadType(ndof, 0.0);
01194 elem_x[neqn*i+j].fastAccessDx(neqn*i+j) = j_coeff;
01195 elem_x[neqn*i+j].val().resize(nblock);
01196 elem_x[neqn*i+j].val().copyForWrite();
01197 for (unsigned int block=0; block<nblock; block++)
01198 elem_x[neqn*i+j].val().fastAccessCoeff(block) =
01199 (*x[block])[firstDOF+j];
01200 if (elem_xdot != NULL) {
01201 (*elem_xdot)[neqn*i+j] = SGFadType(ndof, 0.0);
01202 (*elem_xdot)[neqn*i+j].fastAccessDx(neqn*i+j) = m_coeff;
01203 (*elem_xdot)[neqn*i+j].val().resize(nblock);
01204 (*elem_xdot)[neqn*i+j].val().copyForWrite();
01205 for (unsigned int block=0; block<nblock; block++)
01206 (*elem_xdot)[neqn*i+j].val().fastAccessCoeff(block) =
01207 (*xdot[block])[firstDOF+j];
01208 }
01209
01210 }
01211 }
01212
01213 }
01214
01215 void
01216 FEApp::SGMatrixFreeJacobianOp::elementPost(const FEApp::AbstractElement& e,
01217 unsigned int neqn,
01218 std::vector< SGFadType >& elem_f)
01219 {
01220
01221 unsigned int nnode = e.numNodes();
01222
01223
01224
01225 int row, col;
01226 unsigned int lrow, lcol;
01227 double c;
01228
01229 for (unsigned int node_row=0; node_row<nnode; node_row++) {
01230
01231
01232 for (unsigned int eq_row=0; eq_row<neqn; eq_row++) {
01233 lrow = neqn*node_row+eq_row;
01234
01235
01236 row = static_cast<int>(e.nodeGID(node_row)*neqn + eq_row);
01237
01238
01239 if (sg_f != Teuchos::null)
01240 for (unsigned int block=0; block<nblock; block++) {
01241 c = elem_f[lrow].val().coeff(block);
01242 sg_f->BlockSumIntoGlobalValues(1, &c, &row, block);
01243 }
01244
01245
01246 if (elem_f[lrow].hasFastAccess()) {
01247
01248
01249 for (unsigned int node_col=0; node_col<nnode; node_col++){
01250
01251
01252 for (unsigned int eq_col=0; eq_col<neqn; eq_col++) {
01253 lcol = neqn*node_col+eq_col;
01254
01255
01256 col = static_cast<int>(e.nodeGID(node_col)*neqn + eq_col);
01257
01258
01259 for (unsigned int block=0; block<nblock; block++) {
01260 c = elem_f[lrow].fastAccessDx(lcol).coeff(block);
01261 jac[block]->SumIntoGlobalValues(row, 1, &c, &col);
01262 }
01263
01264 }
01265
01266 }
01267
01268 }
01269
01270 }
01271
01272 }
01273
01274 }
01275
01276 void
01277 FEApp::SGMatrixFreeJacobianOp::nodeInit(const FEApp::NodeBC& bc,
01278 unsigned int neqn,
01279 std::vector< SGFadType >* node_xdot,
01280 std::vector< SGFadType >& node_x)
01281 {
01282
01283 unsigned int node_GID = bc.getNodeGID();
01284
01285
01286 unsigned int firstDOF = map->LID(node_GID*neqn);
01287
01288
01289 for (unsigned int j=0; j<neqn; j++) {
01290 node_x[j] = SGFadType(neqn, 0.0);
01291 node_x[j].fastAccessDx(j) = j_coeff;
01292 node_x[j].val().resize(nblock);
01293 node_x[j].val().copyForWrite();
01294 for (unsigned int block=0; block<nblock; block++)
01295 node_x[j].val().fastAccessCoeff(block) = (*x[block])[firstDOF+j];
01296 if (node_xdot != NULL) {
01297 (*node_xdot)[j] = SGFadType(neqn, 0.0);
01298 (*node_xdot)[j].fastAccessDx(j) = m_coeff;
01299 (*node_xdot)[j].val().resize(nblock);
01300 (*node_xdot)[j].val().copyForWrite();
01301 for (unsigned int block=0; block<nblock; block++)
01302 (*node_xdot)[j].val().fastAccessCoeff(block) =
01303 (*xdot[block])[firstDOF+j];
01304 }
01305 }
01306 }
01307
01308 void
01309 FEApp::SGMatrixFreeJacobianOp::nodePost(const FEApp::NodeBC& bc,
01310 unsigned int neqn,
01311 std::vector< SGFadType >& node_f)
01312 {
01313
01314 unsigned int node_GID = bc.getNodeGID();
01315
01316
01317 unsigned int firstDOF = node_GID*neqn;
01318
01319
01320 const std::vector<unsigned int>& offsets = bc.getOffsets();
01321
01322 int num_entries;
01323 double* row_view = 0;
01324 int row, col;
01325 double c;
01326 double zero = 0.0;
01327
01328 for (unsigned int block=0; block<nblock; block++) {
01329
01330
01331 for (unsigned int eq_row=0; eq_row<offsets.size(); eq_row++) {
01332
01333
01334 row = static_cast<int>(firstDOF + offsets[eq_row]);
01335
01336
01337 if (sg_f != Teuchos::null) {
01338 if (bc.isOwned()) {
01339 c = node_f[offsets[eq_row]].val().coeff(block);
01340 sg_f->BlockReplaceGlobalValues(1, &c, &row, block);
01341 }
01342 else if (bc.isShared())
01343 sg_f->BlockReplaceGlobalValues(1, &zero, &row, block);
01344 }
01345
01346
01347 if (bc.isOwned() || bc.isShared()) {
01348 jac[block]->ExtractGlobalRowView(row, num_entries, row_view);
01349 for (int k=0; k<num_entries; k++)
01350 row_view[k] = 0.0;
01351 }
01352
01353
01354 if (node_f[offsets[eq_row]].hasFastAccess()) {
01355
01356
01357 for (unsigned int eq_col=0; eq_col<neqn; eq_col++) {
01358
01359
01360 col = static_cast<int>(firstDOF + eq_col);
01361
01362
01363 if (bc.isOwned()) {
01364 c = node_f[eq_row].fastAccessDx(eq_col).coeff(block);
01365 jac[block]->ReplaceGlobalValues(row, 1, &c, &col);
01366 }
01367
01368 }
01369
01370 }
01371
01372 }
01373
01374 }
01375
01376 }
01377
01378 void
01379 FEApp::SGMatrixFreeJacobianOp::finalizeFill()
01380 {
01381 }
01382
01383 #endif // SGFAD_ACTIVE