00001
00002
00003
00004
00005
00006
00007 #include "Teuchos_TestForException.hpp"
00008 #include "Phalanx_DataLayout.hpp"
00009 #include <string>
00010
00011 #include "Intrepid_FunctionSpaceTools.hpp"
00012 #include "Sacado_ParameterRegistration.hpp"
00013
00014
00015
00016
00017
00018 namespace PHAL {
00019 const double pi = 3.1415926535897932385;
00020
00021
00022 template<typename EvalT, typename Traits>
00023 NeumannBase<EvalT, Traits>::
00024 NeumannBase(const Teuchos::ParameterList& p) :
00025
00026 dl (p.get<Teuchos::RCP<Albany::Layouts> >("Layouts Struct")),
00027 meshSpecs (p.get<Teuchos::RCP<Albany::MeshSpecsStruct> >("Mesh Specs Struct")),
00028 offset (p.get<Teuchos::Array<int> >("Equation Offset")),
00029 sideSetID (p.get<std::string>("Side Set ID")),
00030 coordVec (p.get<std::string>("Coordinate Vector Name"), dl->vertices_vector)
00031 {
00032
00033 name = p.get< std::string >("Neumann Input String");
00034
00035
00036 inputValues = p.get<Teuchos::Array<double> >("Neumann Input Value");
00037
00038
00039 inputConditions = p.get< std::string >("Neumann Input Conditions");
00040
00041
00042
00043 numDOFsSet = offset.size();
00044
00045
00046 Teuchos::RCP<ParamLib> paramLib = p.get< Teuchos::RCP<ParamLib> > ("Parameter Library");
00047
00048
00049
00050
00051 int position;
00052
00053 if((inputConditions == "scaled jump" || inputConditions == "robin") &&
00054 p.isType<Teuchos::RCP<QCAD::MaterialDatabase> >("MaterialDB")){
00055
00057 Teuchos::RCP<QCAD::MaterialDatabase> materialDB =
00058 p.get< Teuchos::RCP<QCAD::MaterialDatabase> >("MaterialDB");
00059
00060
00061 if(inputConditions == "scaled jump") {
00062 bc_type = INTJUMP;
00063 const_val = inputValues[0];
00064 new Sacado::ParameterRegistration<EvalT, SPL_Traits> (name, this, paramLib);
00065 }
00066 else {
00067 bc_type = ROBIN;
00068 robin_vals[0] = inputValues[0];
00069 robin_vals[1] = inputValues[1];
00070 robin_vals[2] = inputValues[2];
00071
00072 for(int i = 0; i < 3; i++) {
00073 std::stringstream ss; ss << name << "[" << i << "]";
00074 new Sacado::ParameterRegistration<EvalT, SPL_Traits> (ss.str(), this, paramLib);
00075 }
00076 }
00077
00078
00079 matScaling.resize(meshSpecs->ebNameToIndex.size());
00080
00081
00082
00083 std::map<std::string, int>::const_iterator it;
00084 for(it = meshSpecs->ebNameToIndex.begin(); it != meshSpecs->ebNameToIndex.end(); it++){
00085
00086
00087
00088
00089 TEUCHOS_TEST_FOR_EXCEPTION(!materialDB->isElementBlockParam(it->first, "Flux Scale"),
00090 Teuchos::Exceptions::InvalidParameter, "Cannot locate the value of \"Flux Scale\" for element block "
00091 << it->first << " in the material database");
00092
00093 matScaling[it->second] =
00094 materialDB->getElementBlockParam<double>(it->first, "Flux Scale");
00095
00096 }
00097
00098
00099
00100 if (inputConditions == "robin") {
00101
00102
00103
00104
00105 TEUCHOS_TEST_FOR_EXCEPTION(p.get<bool>("Vector Field") == true,
00106 Teuchos::Exceptions::InvalidParameter,
00107 std::endl << "Error: \"Robin\" Neumann boundary conditions "
00108 << "only supported when the DOF is not a vector" << std::endl);
00109
00110 PHX::MDField<ScalarT,Cell,Node> tmp(p.get<std::string>("DOF Name"),
00111 p.get<Teuchos::RCP<PHX::DataLayout> >("DOF Data Layout"));
00112 dof = tmp;
00113
00114 this->addDependentField(dof);
00115 }
00116 }
00117
00118
00119
00120
00121 else if((position = inputConditions.find_first_of("(")) != std::string::npos){
00122
00123 if(inputConditions.find("t_x", position + 1)){
00124
00125 bc_type = TRACTION;
00126 }
00127 else {
00128
00129 bc_type = COORD;
00130 }
00131
00132 dudx.resize(meshSpecs->numDim);
00133 for(int i = 0; i < dudx.size(); i++)
00134 dudx[i] = inputValues[i];
00135
00136 for(int i = 0; i < dudx.size(); i++) {
00137 std::stringstream ss; ss << name << "[" << i << "]";
00138 new Sacado::ParameterRegistration<EvalT, SPL_Traits> (ss.str(), this, paramLib);
00139 }
00140 }
00141 else if(inputConditions == "P"){
00142
00143
00144 bc_type = PRESS;
00145 const_val = inputValues[0];
00146 new Sacado::ParameterRegistration<EvalT, SPL_Traits> (name, this, paramLib);
00147
00148 }
00149 else if(inputConditions == "basal"){
00150
00151
00152 bc_type = BASAL;
00153 robin_vals[0] = inputValues[0];
00154 robin_vals[1] = inputValues[1];
00155 robin_vals[2] = inputValues[2];
00156 robin_vals[3] = inputValues[3];
00157 robin_vals[4] = inputValues[4];
00158
00159 for(int i = 0; i < 5; i++) {
00160 std::stringstream ss; ss << name << "[" << i << "]";
00161 new Sacado::ParameterRegistration<EvalT, SPL_Traits> (ss.str(), this, paramLib);
00162 }
00163 PHX::MDField<ScalarT,Cell,Node,VecDim> tmp(p.get<std::string>("DOF Name"),
00164 p.get<Teuchos::RCP<PHX::DataLayout> >("DOF Data Layout"));
00165 dofVec = tmp;
00166 #ifdef ALBANY_FELIX
00167 beta_field = PHX::MDField<ScalarT,Cell,Node>(
00168 p.get<std::string>("Beta Field Name"), dl->node_scalar);
00169 #endif
00170
00171 betaName = p.get<std::string>("BetaXY");
00172 L = p.get<double>("L");
00173 #ifdef OUTPUT_TO_SCREEN
00174 *out << "BetaName: " << betaName << std::endl;
00175 *out << "L: " << L << std::endl;
00176 #endif
00177 if (betaName == "Constant")
00178 beta_type = CONSTANT;
00179 else if (betaName == "ExpTrig")
00180 beta_type = EXPTRIG;
00181 else if (betaName == "ISMIP-HOM Test C")
00182 beta_type = ISMIP_HOM_TEST_C;
00183 else if (betaName == "ISMIP-HOM Test D")
00184 beta_type = ISMIP_HOM_TEST_D;
00185 else if (betaName == "Confined Shelf")
00186 beta_type = CONFINEDSHELF;
00187 else if (betaName == "Circular Shelf")
00188 beta_type = CIRCULARSHELF;
00189 else if (betaName == "Dome UQ")
00190 beta_type = DOMEUQ;
00191 else if (betaName == "Scalar Field")
00192 beta_type = SCALAR_FIELD;
00193
00194 this->addDependentField(dofVec);
00195 #ifdef ALBANY_FELIX
00196 this->addDependentField(beta_field);
00197 #endif
00198 }
00199 else if(inputConditions == "lateral"){
00200
00201
00202 bc_type = LATERAL;
00203 beta_type = LATERAL_BACKPRESSURE;
00204
00205 for(int i = 0; i < 5; i++) {
00206 std::stringstream ss; ss << name << "[" << i << "]";
00207 new Sacado::ParameterRegistration<EvalT, SPL_Traits> (ss.str(), this, paramLib);
00208 }
00209 PHX::MDField<ScalarT,Cell,Node,VecDim> tmp(p.get<std::string>("DOF Name"),
00210 p.get<Teuchos::RCP<PHX::DataLayout> >("DOF Data Layout"));
00211 dofVec = tmp;
00212 #ifdef ALBANY_FELIX
00213 thickness_field = PHX::MDField<ScalarT,Cell,Node>(
00214 p.get<std::string>("Thickness Field Name"), dl->node_scalar);
00215 elevation_field = PHX::MDField<RealType,Cell,Node>(
00216 p.get<std::string>("Elevation Field Name"), dl->node_scalar);
00217
00218 this->addDependentField(thickness_field);
00219 this->addDependentField(elevation_field);
00220 #endif
00221
00222 this->addDependentField(dofVec);
00223 }
00224
00225 else {
00226
00227
00228 bc_type = NORMAL;
00229 const_val = inputValues[0];
00230 new Sacado::ParameterRegistration<EvalT, SPL_Traits> (name, this, paramLib);
00231
00232 }
00233
00234 this->addDependentField(coordVec);
00235
00236 PHX::Tag<ScalarT> fieldTag(name, dl->dummy);
00237
00238 this->addEvaluatedField(fieldTag);
00239
00240
00241
00242 const CellTopologyData * const elem_top = &meshSpecs->ctd;
00243
00244 intrepidBasis = Albany::getIntrepidBasis(*elem_top);
00245
00246 cellType = Teuchos::rcp(new shards::CellTopology (elem_top));
00247
00248 Intrepid::DefaultCubatureFactory<RealType> cubFactory;
00249 cubatureCell = cubFactory.create(*cellType, meshSpecs->cubatureDegree);
00250
00251 const CellTopologyData * const side_top = elem_top->side[0].topology;
00252
00253 if(strncasecmp(side_top->name, "Line", 4) == 0)
00254
00255 side_type = LINE;
00256
00257 else if(strncasecmp(side_top->name, "Tri", 3) == 0)
00258
00259 side_type = TRI;
00260
00261 else if(strncasecmp(side_top->name, "Quad", 4) == 0)
00262
00263 side_type = QUAD;
00264
00265 else
00266
00267 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
00268 "PHAL_Neumann: side type : " << side_top->name << " is not supported." << std::endl);
00269
00270
00271 sideType = Teuchos::rcp(new shards::CellTopology(side_top));
00272 int cubatureDegree = (p.get<int>("Cubature Degree") > 0 ) ? p.get<int>("Cubature Degree") : meshSpecs->cubatureDegree;
00273 cubatureSide = cubFactory.create(*sideType, cubatureDegree);
00274
00275 sideDims = sideType->getDimension();
00276 numQPsSide = cubatureSide->getNumPoints();
00277
00278 numNodes = intrepidBasis->getCardinality();
00279
00280
00281 std::vector<PHX::DataLayout::size_type> dim;
00282 dl->qp_tensor->dimensions(dim);
00283 int containerSize = dim[0];
00284 numQPs = dim[1];
00285 cellDims = dim[2];
00286
00287
00288 cubPointsSide.resize(numQPsSide, sideDims);
00289 refPointsSide.resize(numQPsSide, cellDims);
00290 cubWeightsSide.resize(numQPsSide);
00291 physPointsSide.resize(1, numQPsSide, cellDims);
00292 dofSide.resize(1, numQPsSide);
00293 dofSideVec.resize(1, numQPsSide, numDOFsSet);
00294
00295
00296 jacobianSide.resize(1, numQPsSide, cellDims, cellDims);
00297 jacobianSide_det.resize(1, numQPsSide);
00298
00299 weighted_measure.resize(1, numQPsSide);
00300 basis_refPointsSide.resize(numNodes, numQPsSide);
00301 trans_basis_refPointsSide.resize(1, numNodes, numQPsSide);
00302 weighted_trans_basis_refPointsSide.resize(1, numNodes, numQPsSide);
00303
00304 physPointsCell.resize(1, numNodes, cellDims);
00305 dofCell.resize(1, numNodes);
00306 dofCellVec.resize(1, numNodes, numDOFsSet);
00307 neumann.resize(containerSize, numNodes, numDOFsSet);
00308 data.resize(1, numQPsSide, numDOFsSet);
00309
00310
00311 cubatureSide->getCubature(cubPointsSide, cubWeightsSide);
00312
00313 this->setName(name+PHX::TypeString<EvalT>::value);
00314
00315 }
00316
00317
00318 template<typename EvalT, typename Traits>
00319 void NeumannBase<EvalT, Traits>::
00320 postRegistrationSetup(typename Traits::SetupData d,
00321 PHX::FieldManager<Traits>& fm)
00322 {
00323 this->utils.setFieldData(coordVec,fm);
00324 if (inputConditions == "robin") this->utils.setFieldData(dof,fm);
00325 #ifdef ALBANY_FELIX
00326 else if (inputConditions == "basal")
00327 {
00328 this->utils.setFieldData(dofVec,fm);
00329 this->utils.setFieldData(beta_field,fm);
00330 }
00331 else if(inputConditions == "lateral")
00332 {
00333 this->utils.setFieldData(dofVec,fm);
00334 this->utils.setFieldData(thickness_field,fm);
00335 this->utils.setFieldData(elevation_field,fm);
00336 }
00337 #endif
00338
00339
00340 }
00341
00342 template<typename EvalT, typename Traits>
00343 void NeumannBase<EvalT, Traits>::
00344 evaluateNeumannContribution(typename Traits::EvalData workset)
00345 {
00346
00347
00348
00349
00350
00351
00352
00353
00354 if(workset.sideSets == Teuchos::null || this->sideSetID.length() == 0)
00355
00356 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
00357 "Side sets defined in input file but not properly specified on the mesh" << std::endl);
00358
00359
00360 const Albany::SideSetList& ssList = *(workset.sideSets);
00361 Albany::SideSetList::const_iterator it = ssList.find(this->sideSetID);
00362
00363 for (std::size_t cell=0; cell < workset.numCells; ++cell)
00364 for (std::size_t node=0; node < numNodes; ++node)
00365 for (std::size_t dim=0; dim < numDOFsSet; ++dim)
00366 neumann(cell, node, dim) = 0.0;
00367
00368 if(it == ssList.end()) return;
00369
00370
00371 const std::vector<Albany::SideStruct>& sideSet = it->second;
00372
00373 Intrepid::FieldContainer<ScalarT> betaOnSide(1,numQPsSide);
00374 Intrepid::FieldContainer<ScalarT> thicknessOnSide(1,numQPsSide);
00375 Intrepid::FieldContainer<ScalarT> elevationOnSide(1,numQPsSide);
00376
00377
00378
00379 for (std::size_t side=0; side < sideSet.size(); ++side) {
00380
00381
00382
00383 const int elem_GID = sideSet[side].elem_GID;
00384 const int elem_LID = sideSet[side].elem_LID;
00385 const int elem_side = sideSet[side].side_local_id;
00386
00387
00388
00389 for (std::size_t node=0; node < numNodes; ++node)
00390 for (std::size_t dim=0; dim < cellDims; ++dim)
00391 physPointsCell(0, node, dim) = coordVec(elem_LID, node, dim);
00392
00393
00394
00395 Intrepid::CellTools<RealType>::mapToReferenceSubcell
00396 (refPointsSide, cubPointsSide, sideDims, elem_side, *cellType);
00397
00398
00399 Intrepid::CellTools<RealType>::setJacobian
00400 (jacobianSide, refPointsSide, physPointsCell, *cellType);
00401
00402 Intrepid::CellTools<MeshScalarT>::setJacobianDet(jacobianSide_det, jacobianSide);
00403
00404 if (sideDims < 2) {
00405 Intrepid::FunctionSpaceTools::computeEdgeMeasure<MeshScalarT>
00406 (weighted_measure, jacobianSide, cubWeightsSide, elem_side, *cellType);
00407 }
00408 else {
00409 Intrepid::FunctionSpaceTools::computeFaceMeasure<MeshScalarT>
00410 (weighted_measure, jacobianSide, cubWeightsSide, elem_side, *cellType);
00411 }
00412
00413
00414 intrepidBasis->getValues(basis_refPointsSide, refPointsSide, Intrepid::OPERATOR_VALUE);
00415
00416
00417 Intrepid::FunctionSpaceTools::HGRADtransformVALUE<RealType>
00418 (trans_basis_refPointsSide, basis_refPointsSide);
00419
00420
00421 Intrepid::FunctionSpaceTools::multiplyMeasure<MeshScalarT>
00422 (weighted_trans_basis_refPointsSide, weighted_measure, trans_basis_refPointsSide);
00423
00424
00425 Intrepid::CellTools<RealType>::mapToPhysicalFrame
00426 (physPointsSide, refPointsSide, physPointsCell, *cellType);
00427
00428
00429
00430 if(bc_type == ROBIN) {
00431 for (std::size_t node=0; node < numNodes; ++node)
00432 dofCell(0, node) = dof(elem_LID, node);
00433
00434
00435 for (int i=0; i < numQPsSide ; i++) dofSide(0,i) = 0.0;
00436
00437
00438 Intrepid::FunctionSpaceTools::
00439 evaluate<ScalarT>(dofSide, dofCell, trans_basis_refPointsSide);
00440 }
00441
00442
00443 else if(bc_type == BASAL) {
00444 Intrepid::FieldContainer<ScalarT> betaOnCell(1, numNodes);
00445 for (std::size_t node=0; node < numNodes; ++node)
00446 {
00447 betaOnCell(0,node) = beta_field(elem_LID,node);
00448 for(int dim = 0; dim < numDOFsSet; dim++)
00449 dofCellVec(0,node,dim) = dofVec(elem_LID,node,this->offset[dim]);
00450 }
00451
00452
00453 for (int i=0; i < numQPsSide ; i++) betaOnSide(0,i) = 0.0;
00454 for (int i=0; i < dofSideVec.size() ; i++) dofSideVec[i] = 0.0;
00455
00456
00457 for (std::size_t node=0; node < numNodes; ++node) {
00458 for (std::size_t qp=0; qp < numQPsSide; ++qp) {
00459 betaOnSide(0, qp) += betaOnCell(0, node) * trans_basis_refPointsSide(0, node, qp);
00460 for (int dim = 0; dim < numDOFsSet; dim++) {
00461 dofSideVec(0, qp, dim) += dofCellVec(0, node, dim) * trans_basis_refPointsSide(0, node, qp);
00462 }
00463 }
00464 }
00465
00466
00467
00468
00469 }
00470 #ifdef ALBANY_FELIX
00471 else if(bc_type == LATERAL) {
00472 Intrepid::FieldContainer<ScalarT> thicknessOnCell(1, numNodes);
00473 Intrepid::FieldContainer<MeshScalarT> elevationOnCell(1, numNodes);
00474 for (std::size_t node=0; node < numNodes; ++node)
00475 {
00476 thicknessOnCell(0,node) = thickness_field(elem_LID,node);
00477 elevationOnCell(0,node) = elevation_field(elem_LID,node);
00478 for(int dim = 0; dim < numDOFsSet; dim++)
00479 dofCellVec(0,node,dim) = dofVec(elem_LID,node,this->offset[dim]);
00480 }
00481
00482
00483 for (int i=0; i < numQPsSide ; i++)
00484 {
00485 thicknessOnSide(0,i) = 0.0;
00486 elevationOnSide(0,i) = 0.0;
00487 }
00488 for (int i=0; i < dofSideVec.size() ; i++) dofSideVec[i] = 0.0;
00489
00490
00491 for (std::size_t node=0; node < numNodes; ++node) {
00492 for (std::size_t qp=0; qp < numQPsSide; ++qp) {
00493 thicknessOnSide(0, qp) += thicknessOnCell(0, node) * trans_basis_refPointsSide(0, node, qp);
00494 elevationOnSide(0, qp) += elevationOnCell(0, node) * trans_basis_refPointsSide(0, node, qp);
00495 for (int dim = 0; dim < numDOFsSet; dim++) {
00496 dofSideVec(0, qp, dim) += dofCellVec(0, node, dim) * trans_basis_refPointsSide(0, node, qp);
00497 }
00498 }
00499 }
00500
00501
00502
00503
00504 }
00505 #endif
00506
00507
00508 switch(bc_type){
00509
00510 case INTJUMP:
00511 {
00512 const ScalarT elem_scale = matScaling[sideSet[side].elem_ebIndex];
00513 calc_dudn_const(data, physPointsSide, jacobianSide, *cellType, cellDims, elem_side, elem_scale);
00514 break;
00515 }
00516
00517 case ROBIN:
00518 {
00519 const ScalarT elem_scale = matScaling[sideSet[side].elem_ebIndex];
00520 calc_dudn_robin(data, physPointsSide, dofSide, jacobianSide, *cellType, cellDims, elem_side, elem_scale, robin_vals);
00521 break;
00522 }
00523
00524 case NORMAL:
00525
00526 calc_dudn_const(data, physPointsSide, jacobianSide, *cellType, cellDims, elem_side);
00527 break;
00528
00529 case PRESS:
00530
00531 calc_press(data, physPointsSide, jacobianSide, *cellType, cellDims, elem_side);
00532 break;
00533
00534 case BASAL:
00535
00536 #ifdef ALBANY_FELIX
00537 calc_dudn_basal(data, betaOnSide, dofSideVec, jacobianSide, *cellType, cellDims, elem_side);
00538
00539 #endif
00540 break;
00541
00542 case LATERAL:
00543
00544 #ifdef ALBANY_FELIX
00545 calc_dudn_lateral(data, thicknessOnSide, elevationOnSide, dofSideVec, jacobianSide, *cellType, cellDims, elem_side);
00546
00547 #endif
00548 break;
00549
00550 case TRACTION:
00551
00552 calc_traction_components(data, physPointsSide, jacobianSide, *cellType, cellDims, elem_side);
00553 break;
00554
00555 default:
00556
00557 calc_gradu_dotn_const(data, physPointsSide, jacobianSide, *cellType, cellDims, elem_side);
00558 break;
00559
00560 }
00561
00562
00563
00564 for (std::size_t node=0; node < numNodes; ++node)
00565 for (std::size_t qp=0; qp < numQPsSide; ++qp)
00566 for (std::size_t dim=0; dim < numDOFsSet; ++dim)
00567 neumann(elem_LID, node, dim) +=
00568 data(0, qp, dim) * weighted_trans_basis_refPointsSide(0, node, qp);
00569
00570
00571 }
00572
00573 }
00574
00575 template<typename EvalT, typename Traits>
00576 typename NeumannBase<EvalT, Traits>::ScalarT&
00577 NeumannBase<EvalT, Traits>::
00578 getValue(const std::string &n) {
00579
00580 if(std::string::npos != n.find("robin")) {
00581 for(int i = 0; i < 3; i++) {
00582 std::stringstream ss; ss << name << "[" << i << "]";
00583 if (n == ss.str()) return robin_vals[i];
00584 }
00585 }
00586 else if(std::string::npos != n.find("basal")) {
00587 for(int i = 0; i < 5; i++) {
00588 std::stringstream ss; ss << name << "[" << i << "]";
00589 if (n == ss.str()) return robin_vals[i];
00590 }
00591 }
00592 else {
00593 for(int i = 0; i < dudx.size(); i++) {
00594 std::stringstream ss; ss << name << "[" << i << "]";
00595 if (n == ss.str()) return dudx[i];
00596 }
00597 }
00598
00599
00600 return const_val;
00601
00602 }
00603
00604
00605 template<typename EvalT, typename Traits>
00606 void NeumannBase<EvalT, Traits>::
00607 calc_traction_components(Intrepid::FieldContainer<ScalarT> & qp_data_returned,
00608 const Intrepid::FieldContainer<MeshScalarT>& phys_side_cub_points,
00609 const Intrepid::FieldContainer<MeshScalarT>& jacobian_side_refcell,
00610 const shards::CellTopology & celltopo,
00611 const int cellDims,
00612 int local_side_id){
00613
00614 int numCells = qp_data_returned.dimension(0);
00615 int numPoints = qp_data_returned.dimension(1);
00616 int numDOFs = qp_data_returned.dimension(2);
00617
00618 Intrepid::FieldContainer<ScalarT> traction(numCells, numPoints, cellDims);
00619
00620
00621
00622
00623
00624
00625
00626
00627 for(int cell = 0; cell < numCells; cell++)
00628 for(int pt = 0; pt < numPoints; pt++)
00629 for(int dim = 0; dim < cellDims; dim++)
00630 traction(cell, pt, dim) = dudx[dim];
00631
00632 for(int pt = 0; pt < numPoints; pt++)
00633 for(int dim = 0; dim < numDOFsSet; dim++)
00634 qp_data_returned(0, pt, dim) = -traction(0, pt, dim);
00635
00636 }
00637
00638 template<typename EvalT, typename Traits>
00639 void NeumannBase<EvalT, Traits>::
00640 calc_gradu_dotn_const(Intrepid::FieldContainer<ScalarT> & qp_data_returned,
00641 const Intrepid::FieldContainer<MeshScalarT>& phys_side_cub_points,
00642 const Intrepid::FieldContainer<MeshScalarT>& jacobian_side_refcell,
00643 const shards::CellTopology & celltopo,
00644 const int cellDims,
00645 int local_side_id){
00646
00647 int numCells = qp_data_returned.dimension(0);
00648 int numPoints = qp_data_returned.dimension(1);
00649 int numDOFs = qp_data_returned.dimension(2);
00650
00651 Intrepid::FieldContainer<ScalarT> grad_T(numCells, numPoints, cellDims);
00652 Intrepid::FieldContainer<MeshScalarT> side_normals(numCells, numPoints, cellDims);
00653 Intrepid::FieldContainer<MeshScalarT> normal_lengths(numCells, numPoints);
00654
00655
00656
00657
00658
00659
00660
00661
00662 for(int cell = 0; cell < numCells; cell++)
00663 for(int pt = 0; pt < numPoints; pt++)
00664 for(int dim = 0; dim < cellDims; dim++)
00665 grad_T(cell, pt, dim) = dudx[dim];
00666
00667
00668 Intrepid::CellTools<MeshScalarT>::getPhysicalSideNormals(side_normals, jacobian_side_refcell,
00669 local_side_id, celltopo);
00670
00671
00672 Intrepid::RealSpaceTools<MeshScalarT>::vectorNorm(normal_lengths, side_normals, Intrepid::NORM_TWO);
00673 Intrepid::FunctionSpaceTools::scalarMultiplyDataData<MeshScalarT>(side_normals, normal_lengths,
00674 side_normals, true);
00675
00676
00677
00678
00679
00680 for(int pt = 0; pt < numPoints; pt++)
00681 for(int dim = 0; dim < numDOFsSet; dim++)
00682 qp_data_returned(0, pt, dim) = grad_T(0, pt, dim) * side_normals(0, pt, dim);
00683
00684 }
00685
00686 template<typename EvalT, typename Traits>
00687 void NeumannBase<EvalT, Traits>::
00688 calc_dudn_const(Intrepid::FieldContainer<ScalarT> & qp_data_returned,
00689 const Intrepid::FieldContainer<MeshScalarT>& phys_side_cub_points,
00690 const Intrepid::FieldContainer<MeshScalarT>& jacobian_side_refcell,
00691 const shards::CellTopology & celltopo,
00692 const int cellDims,
00693 int local_side_id,
00694 ScalarT scale){
00695
00696 int numCells = qp_data_returned.dimension(0);
00697 int numPoints = qp_data_returned.dimension(1);
00698 int numDOFs = qp_data_returned.dimension(2);
00699
00700
00701
00702 for(int pt = 0; pt < numPoints; pt++)
00703 for(int dim = 0; dim < numDOFsSet; dim++)
00704 qp_data_returned(0, pt, dim) = -const_val * scale;
00705
00706
00707 }
00708
00709 template<typename EvalT, typename Traits>
00710 void NeumannBase<EvalT, Traits>::
00711 calc_dudn_robin(Intrepid::FieldContainer<ScalarT> & qp_data_returned,
00712 const Intrepid::FieldContainer<MeshScalarT>& phys_side_cub_points,
00713 const Intrepid::FieldContainer<ScalarT>& dof_side,
00714 const Intrepid::FieldContainer<MeshScalarT>& jacobian_side_refcell,
00715 const shards::CellTopology & celltopo,
00716 const int cellDims,
00717 int local_side_id,
00718 ScalarT scale,
00719 const ScalarT* robin_param_values){
00720
00721 int numCells = qp_data_returned.dimension(0);
00722 int numPoints = qp_data_returned.dimension(1);
00723 int numDOFs = qp_data_returned.dimension(2);
00724
00725 const ScalarT& dof_value = robin_vals[0];
00726 const ScalarT& coeff = robin_vals[1];
00727 const ScalarT& jump = robin_vals[2];
00728
00729 for(int pt = 0; pt < numPoints; pt++)
00730 for(int dim = 0; dim < numDOFsSet; dim++)
00731 qp_data_returned(0, pt, dim) = coeff*(dof_side(0,pt) - dof_value) - jump * scale * 2.0;
00732
00733
00734 }
00735
00736
00737 template<typename EvalT, typename Traits>
00738 void NeumannBase<EvalT, Traits>::
00739 calc_press(Intrepid::FieldContainer<ScalarT> & qp_data_returned,
00740 const Intrepid::FieldContainer<MeshScalarT>& phys_side_cub_points,
00741 const Intrepid::FieldContainer<MeshScalarT>& jacobian_side_refcell,
00742 const shards::CellTopology & celltopo,
00743 const int cellDims,
00744 int local_side_id){
00745
00746 int numCells = qp_data_returned.dimension(0);
00747 int numPoints = qp_data_returned.dimension(1);
00748 int numDOFs = qp_data_returned.dimension(2);
00749
00750 Intrepid::FieldContainer<MeshScalarT> side_normals(numCells, numPoints, cellDims);
00751 Intrepid::FieldContainer<MeshScalarT> normal_lengths(numCells, numPoints);
00752 Intrepid::FieldContainer<MeshScalarT> ref_normal(cellDims);
00753
00754
00755 Intrepid::CellTools<MeshScalarT>::getPhysicalSideNormals(side_normals, jacobian_side_refcell,
00756 local_side_id, celltopo);
00757
00758
00759 Intrepid::CellTools<MeshScalarT>::getReferenceSideNormal(ref_normal, local_side_id, celltopo);
00760
00761
00762
00763
00764
00765 MeshScalarT area =
00766 Intrepid::RealSpaceTools<MeshScalarT>::vectorNorm(ref_normal, Intrepid::NORM_TWO);
00767
00768
00769
00770 switch(side_type){
00771
00772 case LINE:
00773
00774 area *= 2;
00775 break;
00776
00777 case TRI:
00778
00779 area /= 2;
00780 break;
00781
00782 case QUAD:
00783
00784 break;
00785
00786 default:
00787 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
00788 "Need to supply area function for boundary type: " << side_type << std::endl);
00789 break;
00790
00791 }
00792
00793
00794 Intrepid::RealSpaceTools<MeshScalarT>::vectorNorm(normal_lengths, side_normals, Intrepid::NORM_TWO);
00795 Intrepid::FunctionSpaceTools::scalarMultiplyDataData<MeshScalarT>(side_normals, normal_lengths,
00796 side_normals, true);
00797
00798
00799
00800 for(int cell = 0; cell < numCells; cell++)
00801 for(int pt = 0; pt < numPoints; pt++)
00802 for(int dim = 0; dim < numDOFsSet; dim++)
00803
00804 qp_data_returned(cell, pt, dim) = const_val * side_normals(cell, pt, dim) / area;
00805
00806
00807 }
00808
00809
00810 #ifdef ALBANY_FELIX
00811 template<typename EvalT, typename Traits>
00812 void NeumannBase<EvalT, Traits>::
00813 calc_dudn_basal(Intrepid::FieldContainer<ScalarT> & qp_data_returned,
00814 const Intrepid::FieldContainer<ScalarT>& basalFriction_side,
00815 const Intrepid::FieldContainer<ScalarT>& dof_side,
00816 const Intrepid::FieldContainer<MeshScalarT>& jacobian_side_refcell,
00817 const shards::CellTopology & celltopo,
00818 const int cellDims,
00819 int local_side_id){
00820
00821 int numCells = qp_data_returned.dimension(0);
00822 int numPoints = qp_data_returned.dimension(1);
00823 int numDOFs = qp_data_returned.dimension(2);
00824
00825
00826
00827 const ScalarT& beta = robin_vals[0];
00828 const ScalarT& alpha = robin_vals[1];
00829 const ScalarT& beta1 = robin_vals[2];
00830 const ScalarT& beta2 = robin_vals[3];
00831 const ScalarT& beta3 = robin_vals[4];
00832
00833 Intrepid::FieldContainer<MeshScalarT> side_normals(numCells, numPoints, cellDims);
00834 Intrepid::FieldContainer<MeshScalarT> normal_lengths(numCells, numPoints);
00835
00836
00837 Intrepid::CellTools<MeshScalarT>::getPhysicalSideNormals(side_normals, jacobian_side_refcell,
00838 local_side_id, celltopo);
00839
00840
00841 Intrepid::RealSpaceTools<MeshScalarT>::vectorNorm(normal_lengths, side_normals, Intrepid::NORM_TWO);
00842 Intrepid::FunctionSpaceTools::scalarMultiplyDataData<MeshScalarT>(side_normals, normal_lengths,
00843 side_normals, true);
00844
00845 const double a = 1.0;
00846 const double Atmp = 1.0;
00847 const double ntmp = 3.0;
00848 if (beta_type == CONSTANT) {
00849 betaXY = 1.0;
00850 for(int cell = 0; cell < numCells; cell++) {
00851 for(int pt = 0; pt < numPoints; pt++) {
00852 for(int dim = 0; dim < numDOFsSet; dim++) {
00853 qp_data_returned(cell, pt, dim) = betaXY*beta*dof_side(cell, pt,dim) - alpha;
00854 }
00855 }
00856 }
00857 }
00858 if (beta_type == SCALAR_FIELD) {
00859 betaXY = 1.0;
00860 for(int cell = 0; cell < numCells; cell++) {
00861 for(int pt = 0; pt < numPoints; pt++) {
00862 for(int dim = 0; dim < numDOFsSet; dim++) {
00863 qp_data_returned(cell, pt, dim) = betaXY*basalFriction_side(cell, pt)*dof_side(cell, pt,dim);
00864 }
00865 }
00866 }
00867 }
00868 else if (beta_type == EXPTRIG) {
00869 const double a = 1.0;
00870 const double A = 1.0;
00871 const double n = L;
00872 for(int cell = 0; cell < numCells; cell++) {
00873 for(int pt = 0; pt < numPoints; pt++) {
00874 for(int dim = 0; dim < numDOFsSet; dim++) {
00875 MeshScalarT x = physPointsSide(cell,pt,0);
00876 MeshScalarT y2pi = 2.0*pi*physPointsSide(cell,pt,1);
00877 MeshScalarT muargt = (a*a + 4.0*pi*pi - 2.0*pi*a)*sin(y2pi)*sin(y2pi) + 1.0/4.0*(2.0*pi+a)*(2.0*pi+a)*cos(y2pi)*cos(y2pi);
00878 muargt = sqrt(muargt)*exp(a*x);
00879 betaXY = 1.0/2.0*pow(A, -1.0/n)*pow(muargt, 1.0/n - 1.0);
00880 qp_data_returned(cell, pt, dim) = betaXY*beta*dof_side(cell, pt,dim) - alpha*side_normals(cell,pt,dim);
00881 }
00882 }
00883 }
00884 }
00885 else if (beta_type == ISMIP_HOM_TEST_C) {
00886 for(int cell = 0; cell < numCells; cell++) {
00887 for(int pt = 0; pt < numPoints; pt++) {
00888 for(int dim = 0; dim < numDOFsSet; dim++) {
00889 MeshScalarT x = physPointsSide(cell,pt,0);
00890 MeshScalarT y = physPointsSide(cell,pt,1);
00891 betaXY = 1.0 + sin(2.0*pi/L*x)*sin(2.0*pi/L*y);
00892 qp_data_returned(cell, pt, dim) = betaXY*beta*dof_side(cell, pt,dim) - alpha*side_normals(cell,pt,dim);
00893 }
00894 }
00895 }
00896 }
00897 else if (beta_type == ISMIP_HOM_TEST_D) {
00898 for(int cell = 0; cell < numCells; cell++) {
00899 for(int pt = 0; pt < numPoints; pt++) {
00900 for(int dim = 0; dim < numDOFsSet; dim++) {
00901 MeshScalarT x = physPointsSide(cell,pt,0);
00902 betaXY = 1.0 + sin(2.0*pi/L*x);
00903 qp_data_returned(cell, pt, dim) = betaXY*beta*dof_side(cell, pt,dim) - alpha*side_normals(cell,pt,dim);
00904 }
00905 }
00906 }
00907 }
00908 else if (beta_type == CONFINEDSHELF) {
00909 const double s = 0.06;
00910 for(int cell = 0; cell < numCells; cell++) {
00911 for(int pt = 0; pt < numPoints; pt++) {
00912 for(int dim = 0; dim < numDOFsSet; dim++) {
00913 MeshScalarT z = physPointsSide(cell,pt,2);
00914 if (z > 0.0)
00915 betaXY = 0.0;
00916 else
00917 betaXY = -z;
00918 qp_data_returned(cell, pt, dim) = -(beta*(s-z) + alpha*betaXY);
00919 }
00920 }
00921 }
00922 }
00923 else if (beta_type == CIRCULARSHELF) {
00924 const double s = 0.11479;
00925 for(int cell = 0; cell < numCells; cell++) {
00926 for(int pt = 0; pt < numPoints; pt++) {
00927 for(int dim = 0; dim < numDOFsSet; dim++) {
00928 MeshScalarT z = physPointsSide(cell,pt,2);
00929 if (z > 0.0)
00930 betaXY = 0.0;
00931 else
00932 betaXY = -z;
00933 qp_data_returned(cell, pt, dim) = -(beta*(s-z) + alpha*betaXY)*side_normals(cell,pt,dim);
00934 }
00935 }
00936 }
00937 }
00938 else if (beta_type == DOMEUQ) {
00939 for(int cell = 0; cell < numCells; cell++) {
00940 for(int pt = 0; pt < numPoints; pt++) {
00941 for(int dim = 0; dim < numDOFsSet; dim++) {
00942 MeshScalarT x = physPointsSide(cell,pt,0);
00943 MeshScalarT y = physPointsSide(cell,pt,1);
00944 MeshScalarT r = sqrt(x*x+y*y);
00945 qp_data_returned(cell, pt, dim) = (alpha + beta1*x + beta2*y + beta3*r)*dof_side(cell,pt,dim);
00946 }
00947 }
00948 }
00949 }
00950
00951
00952 }
00953
00954
00955 template<typename EvalT, typename Traits>
00956 void NeumannBase<EvalT, Traits>::
00957 calc_dudn_lateral(Intrepid::FieldContainer<ScalarT> & qp_data_returned,
00958 const Intrepid::FieldContainer<ScalarT>& thickness_side,
00959 const Intrepid::FieldContainer<ScalarT>& elevation_side,
00960 const Intrepid::FieldContainer<ScalarT>& dof_side,
00961 const Intrepid::FieldContainer<MeshScalarT>& jacobian_side_refcell,
00962 const shards::CellTopology & celltopo,
00963 const int cellDims,
00964 int local_side_id){
00965
00966 int numCells = qp_data_returned.dimension(0);
00967 int numPoints = qp_data_returned.dimension(1);
00968
00969
00970
00971 Intrepid::FieldContainer<MeshScalarT> side_normals(numCells, numPoints, cellDims);
00972 Intrepid::FieldContainer<MeshScalarT> normal_lengths(numCells, numPoints);
00973
00974
00975 Intrepid::CellTools<MeshScalarT>::getPhysicalSideNormals(side_normals, jacobian_side_refcell,
00976 local_side_id, celltopo);
00977
00978
00979 Intrepid::RealSpaceTools<MeshScalarT>::vectorNorm(normal_lengths, side_normals, Intrepid::NORM_TWO);
00980 Intrepid::FunctionSpaceTools::scalarMultiplyDataData<MeshScalarT>(side_normals, normal_lengths,
00981 side_normals, true);
00982
00983 if (beta_type == LATERAL_BACKPRESSURE)
00984 {
00985 const double g = 9.8;
00986 const double rho = 910;
00987 const double rho_w = 1028;
00988 for(int cell = 0; cell < numCells; cell++) {
00989 for(int pt = 0; pt < numPoints; pt++) {
00990 ScalarT H = thickness_side(cell, pt);
00991 ScalarT s = elevation_side(cell, pt);
00992 ScalarT immersedRatio = 0.;
00993 if(H > 1e-8)
00994 {
00995 ScalarT ratio = s/H;
00996 if(ratio < 0.)
00997 immersedRatio = 1;
00998 else if(ratio < 1)
00999 immersedRatio = 1. - ratio;
01000 }
01001 ScalarT normalStress = - 0.5 * g * H * (rho - rho_w * immersedRatio*immersedRatio);
01002
01003 for(int dim = 0; dim < numDOFsSet; dim++)
01004 qp_data_returned(cell, pt, dim) = normalStress * side_normals(cell,pt,dim);
01005
01006 }
01007 }
01008 }
01009 }
01010
01011 #endif
01012
01013
01014
01015
01016 template<typename Traits>
01017 Neumann<PHAL::AlbanyTraits::Residual,Traits>::
01018 Neumann(Teuchos::ParameterList& p)
01019 : NeumannBase<PHAL::AlbanyTraits::Residual,Traits>(p)
01020 {
01021 }
01022
01023 template<typename Traits>
01024 void Neumann<PHAL::AlbanyTraits::Residual, Traits>::
01025 evaluateFields(typename Traits::EvalData workset)
01026 {
01027
01028 Teuchos::RCP<Epetra_Vector> f = workset.f;
01029 ScalarT *valptr;
01030
01031
01032 this->evaluateNeumannContribution(workset);
01033
01034
01035 for (std::size_t cell=0; cell < workset.numCells; ++cell ) {
01036 const Teuchos::ArrayRCP<Teuchos::ArrayRCP<int> >& nodeID = workset.wsElNodeEqID[cell];
01037
01038
01039 for (std::size_t node = 0; node < this->numNodes; ++node)
01040 for (std::size_t dim = 0; dim < this->numDOFsSet; ++dim){
01041
01042 valptr = &(this->neumann)(cell, node, dim);
01043 (*f)[nodeID[node][this->offset[dim]]] += *valptr;
01044
01045 }
01046 }
01047 }
01048
01049
01050
01051
01052
01053 template<typename Traits>
01054 Neumann<PHAL::AlbanyTraits::Jacobian, Traits>::
01055 Neumann(Teuchos::ParameterList& p)
01056 : NeumannBase<PHAL::AlbanyTraits::Jacobian,Traits>(p)
01057 {
01058 }
01059
01060
01061 template<typename Traits>
01062 void Neumann<PHAL::AlbanyTraits::Jacobian, Traits>::
01063 evaluateFields(typename Traits::EvalData workset)
01064 {
01065 Teuchos::RCP<Epetra_Vector> f = workset.f;
01066 Teuchos::RCP<Epetra_CrsMatrix> Jac = workset.Jac;
01067 ScalarT *valptr;
01068
01069
01070 this->evaluateNeumannContribution(workset);
01071
01072 int row, lcol, col;
01073
01074 for (std::size_t cell=0; cell < workset.numCells; ++cell ) {
01075 const Teuchos::ArrayRCP<Teuchos::ArrayRCP<int> >& nodeID = workset.wsElNodeEqID[cell];
01076
01077 for (std::size_t node = 0; node < this->numNodes; ++node)
01078 for (std::size_t dim = 0; dim < this->numDOFsSet; ++dim){
01079
01080 valptr = &(this->neumann)(cell, node, dim);
01081
01082 row = nodeID[node][this->offset[dim]];
01083 int neq = nodeID[node].size();
01084
01085 if (f != Teuchos::null)
01086 f->SumIntoMyValue(row, 0, valptr->val());
01087
01088
01089 if (valptr->hasFastAccess()) {
01090
01091
01092 for (unsigned int node_col=0; node_col<this->numNodes; node_col++){
01093
01094
01095 for (unsigned int eq_col=0; eq_col<neq; eq_col++) {
01096 lcol = neq * node_col + eq_col;
01097
01098
01099 col = nodeID[node_col][eq_col];
01100
01101 if (workset.is_adjoint) {
01102
01103 Jac->SumIntoMyValues(col, 1, &(valptr->fastAccessDx(lcol)), &row);
01104 }
01105 else {
01106
01107 Jac->SumIntoMyValues(row, 1, &(valptr->fastAccessDx(lcol)), &col);
01108 }
01109 }
01110 }
01111 }
01112 }
01113 }
01114 }
01115
01116
01117
01118
01119
01120 template<typename Traits>
01121 Neumann<PHAL::AlbanyTraits::Tangent, Traits>::
01122 Neumann(Teuchos::ParameterList& p)
01123 : NeumannBase<PHAL::AlbanyTraits::Tangent,Traits>(p)
01124 {
01125 }
01126
01127
01128 template<typename Traits>
01129 void Neumann<PHAL::AlbanyTraits::Tangent, Traits>::
01130 evaluateFields(typename Traits::EvalData workset)
01131 {
01132 Teuchos::RCP<Epetra_Vector> f = workset.f;
01133 Teuchos::RCP<Epetra_MultiVector> JV = workset.JV;
01134 Teuchos::RCP<Epetra_MultiVector> fp = workset.fp;
01135 ScalarT *valptr;
01136
01137 const Epetra_BlockMap *row_map = NULL;
01138
01139 if (f != Teuchos::null)
01140 row_map = &(f->Map());
01141 else if (JV != Teuchos::null)
01142 row_map = &(JV->Map());
01143 else if (fp != Teuchos::null)
01144 row_map = &(fp->Map());
01145 else
01146 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
01147 "One of f, JV, or fp must be non-null! " << std::endl);
01148
01149
01150
01151 this->evaluateNeumannContribution(workset);
01152
01153 for (std::size_t cell=0; cell < workset.numCells; ++cell ) {
01154 const Teuchos::ArrayRCP<Teuchos::ArrayRCP<int> >& nodeID = workset.wsElNodeEqID[cell];
01155
01156 for (std::size_t node = 0; node < this->numNodes; ++node)
01157 for (std::size_t dim = 0; dim < this->numDOFsSet; ++dim){
01158
01159 valptr = &(this->neumann)(cell, node, dim);
01160
01161 int row = nodeID[node][this->offset[dim]];
01162
01163 if (f != Teuchos::null)
01164 f->SumIntoMyValue(row, 0, valptr->val());
01165
01166 if (JV != Teuchos::null)
01167 for (int col=0; col<workset.num_cols_x; col++)
01168
01169 JV->SumIntoMyValue(row, col, valptr->dx(col));
01170
01171 if (fp != Teuchos::null)
01172 for (int col=0; col<workset.num_cols_p; col++)
01173 fp->SumIntoMyValue(row, col, valptr->dx(col+workset.param_offset));
01174 }
01175 }
01176 }
01177
01178
01179
01180
01181
01182 #ifdef ALBANY_SG_MP
01183 template<typename Traits>
01184 Neumann<PHAL::AlbanyTraits::SGResidual, Traits>::
01185 Neumann(Teuchos::ParameterList& p)
01186 : NeumannBase<PHAL::AlbanyTraits::SGResidual,Traits>(p)
01187 {
01188 }
01189
01190
01191
01192 template<typename Traits>
01193 void Neumann<PHAL::AlbanyTraits::SGResidual, Traits>::
01194 evaluateFields(typename Traits::EvalData workset)
01195 {
01196
01197 Teuchos::RCP< Stokhos::EpetraVectorOrthogPoly > f = workset.sg_f;
01198 ScalarT *valptr;
01199
01200 int nblock = f->size();
01201
01202
01203
01204 this->evaluateNeumannContribution(workset);
01205
01206 for (std::size_t cell=0; cell < workset.numCells; ++cell ) {
01207 const Teuchos::ArrayRCP<Teuchos::ArrayRCP<int> >& nodeID = workset.wsElNodeEqID[cell];
01208
01209 for (std::size_t node = 0; node < this->numNodes; ++node)
01210 for (std::size_t dim = 0; dim < this->numDOFsSet; ++dim){
01211
01212 valptr = &(this->neumann)(cell, node, dim);
01213
01214 for (int block=0; block<nblock; block++)
01215 (*f)[block][nodeID[node][this->offset[dim]]] += valptr->coeff(block);
01216
01217 }
01218 }
01219 }
01220
01221
01222
01223
01224
01225 template<typename Traits>
01226 Neumann<PHAL::AlbanyTraits::SGJacobian, Traits>::
01227 Neumann(Teuchos::ParameterList& p)
01228 : NeumannBase<PHAL::AlbanyTraits::SGJacobian,Traits>(p)
01229 {
01230 }
01231
01232
01233 template<typename Traits>
01234 void Neumann<PHAL::AlbanyTraits::SGJacobian, Traits>::
01235 evaluateFields(typename Traits::EvalData workset)
01236 {
01237 Teuchos::RCP< Stokhos::EpetraVectorOrthogPoly > f = workset.sg_f;
01238 Teuchos::RCP< Stokhos::VectorOrthogPoly<Epetra_CrsMatrix> > Jac =
01239 workset.sg_Jac;
01240 ScalarT *valptr;
01241
01242
01243
01244 this->evaluateNeumannContribution(workset);
01245
01246 int row, lcol, col;
01247 int nblock = 0;
01248
01249 if (f != Teuchos::null)
01250 nblock = f->size();
01251
01252 int nblock_jac = Jac->size();
01253 double c;
01254
01255 for (std::size_t cell=0; cell < workset.numCells; ++cell ) {
01256 const Teuchos::ArrayRCP<Teuchos::ArrayRCP<int> >& nodeID = workset.wsElNodeEqID[cell];
01257
01258 for (std::size_t node = 0; node < this->numNodes; ++node)
01259 for (std::size_t dim = 0; dim < this->numDOFsSet; ++dim){
01260
01261 valptr = &(this->neumann)(cell, node, dim);
01262
01263 row = nodeID[node][this->offset[dim]];
01264 int neq = nodeID[node].size();
01265
01266 if (f != Teuchos::null) {
01267
01268 for (int block=0; block<nblock; block++)
01269 (*f)[block].SumIntoMyValue(row, 0, valptr->val().coeff(block));
01270
01271 }
01272
01273
01274 if (valptr->hasFastAccess()) {
01275
01276
01277 for (unsigned int node_col=0; node_col<this->numNodes; node_col++){
01278
01279
01280 for (unsigned int eq_col=0; eq_col<neq; eq_col++) {
01281 lcol = neq * node_col + eq_col;
01282
01283
01284 col = nodeID[node_col][eq_col];
01285
01286
01287 for (int block=0; block<nblock_jac; block++) {
01288
01289 c = valptr->fastAccessDx(lcol).coeff(block);
01290 if (workset.is_adjoint) {
01291
01292 (*Jac)[block].SumIntoMyValues(col, 1, &c, &row);
01293
01294 }
01295 else {
01296
01297 (*Jac)[block].SumIntoMyValues(row, 1, &c, &col);
01298
01299 }
01300 }
01301 }
01302 }
01303 }
01304 }
01305 }
01306 }
01307
01308
01309
01310
01311
01312 template<typename Traits>
01313 Neumann<PHAL::AlbanyTraits::SGTangent, Traits>::
01314 Neumann(Teuchos::ParameterList& p)
01315 : NeumannBase<PHAL::AlbanyTraits::SGTangent,Traits>(p)
01316 {
01317 }
01318
01319
01320 template<typename Traits>
01321 void Neumann<PHAL::AlbanyTraits::SGTangent, Traits>::
01322 evaluateFields(typename Traits::EvalData workset)
01323 {
01324 Teuchos::RCP< Stokhos::EpetraVectorOrthogPoly > f = workset.sg_f;
01325 Teuchos::RCP< Stokhos::EpetraMultiVectorOrthogPoly > JV = workset.sg_JV;
01326 Teuchos::RCP< Stokhos::EpetraMultiVectorOrthogPoly > fp = workset.sg_fp;
01327 ScalarT *valptr;
01328
01329
01330
01331 this->evaluateNeumannContribution(workset);
01332
01333 int nblock = 0;
01334 if (f != Teuchos::null)
01335 nblock = f->size();
01336 else if (JV != Teuchos::null)
01337 nblock = JV->size();
01338 else if (fp != Teuchos::null)
01339 nblock = fp->size();
01340 else
01341 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
01342 "One of sg_f, sg_JV, or sg_fp must be non-null! " <<
01343 std::endl);
01344
01345 for (std::size_t cell=0; cell < workset.numCells; ++cell ) {
01346
01347 const Teuchos::ArrayRCP<Teuchos::ArrayRCP<int> >& nodeID = workset.wsElNodeEqID[cell];
01348
01349 for (std::size_t node = 0; node < this->numNodes; ++node)
01350 for (std::size_t dim = 0; dim < this->numDOFsSet; ++dim){
01351
01352 valptr = &(this->neumann)(cell, node, dim);
01353
01354 int row = nodeID[node][this->offset[dim]];
01355
01356 if (f != Teuchos::null)
01357 for (int block=0; block<nblock; block++)
01358 (*f)[block].SumIntoMyValue(row, 0, valptr->val().coeff(block));
01359
01360 if (JV != Teuchos::null)
01361 for (int col=0; col<workset.num_cols_x; col++)
01362 for (int block=0; block<nblock; block++)
01363 (*JV)[block].SumIntoMyValue(row, col, valptr->dx(col).coeff(block));
01364
01365 for (int col=0; col<workset.num_cols_p; col++)
01366 for (int block=0; block<nblock; block++)
01367 (*fp)[block].SumIntoMyValue(row, col, valptr->dx(col+workset.param_offset).coeff(block));
01368 }
01369 }
01370 }
01371
01372
01373
01374
01375
01376 template<typename Traits>
01377 Neumann<PHAL::AlbanyTraits::MPResidual, Traits>::
01378 Neumann(Teuchos::ParameterList& p)
01379 : NeumannBase<PHAL::AlbanyTraits::MPResidual,Traits>(p)
01380 {
01381 }
01382
01383
01384 template<typename Traits>
01385 void Neumann<PHAL::AlbanyTraits::MPResidual, Traits>::
01386 evaluateFields(typename Traits::EvalData workset)
01387 {
01388 Teuchos::RCP< Stokhos::ProductEpetraVector > f = workset.mp_f;
01389 ScalarT *valptr;
01390
01391
01392
01393 this->evaluateNeumannContribution(workset);
01394
01395 int nblock = f->size();
01396 for (std::size_t cell=0; cell < workset.numCells; ++cell ) {
01397 const Teuchos::ArrayRCP<Teuchos::ArrayRCP<int> >& nodeID = workset.wsElNodeEqID[cell];
01398
01399 for (std::size_t node = 0; node < this->numNodes; ++node)
01400 for (std::size_t dim = 0; dim < this->numDOFsSet; ++dim){
01401
01402 valptr = &(this->neumann)(cell, node, dim);
01403
01404 for (int block=0; block<nblock; block++)
01405 (*f)[block][nodeID[node][this->offset[dim]]] += valptr->coeff(block);
01406
01407 }
01408 }
01409 }
01410
01411
01412
01413
01414
01415 template<typename Traits>
01416 Neumann<PHAL::AlbanyTraits::MPJacobian, Traits>::
01417 Neumann(Teuchos::ParameterList& p)
01418 : NeumannBase<PHAL::AlbanyTraits::MPJacobian,Traits>(p)
01419 {
01420 }
01421
01422
01423 template<typename Traits>
01424 void Neumann<PHAL::AlbanyTraits::MPJacobian, Traits>::
01425 evaluateFields(typename Traits::EvalData workset)
01426 {
01427 Teuchos::RCP< Stokhos::ProductEpetraVector > f = workset.mp_f;
01428 Teuchos::RCP< Stokhos::ProductContainer<Epetra_CrsMatrix> > Jac =
01429 workset.mp_Jac;
01430 ScalarT *valptr;
01431
01432
01433
01434 this->evaluateNeumannContribution(workset);
01435
01436 int row, lcol, col;
01437 int nblock = 0;
01438
01439 if (f != Teuchos::null)
01440 nblock = f->size();
01441
01442 int nblock_jac = Jac->size();
01443 double c;
01444
01445 for (std::size_t cell=0; cell < workset.numCells; ++cell ) {
01446 const Teuchos::ArrayRCP<Teuchos::ArrayRCP<int> >& nodeID = workset.wsElNodeEqID[cell];
01447
01448 for (std::size_t node = 0; node < this->numNodes; ++node)
01449 for (std::size_t dim = 0; dim < this->numDOFsSet; ++dim){
01450
01451 valptr = &(this->neumann)(cell, node, dim);
01452
01453 row = nodeID[node][this->offset[dim]];
01454 int neq = nodeID[node].size();
01455
01456 if (f != Teuchos::null)
01457 for (int block=0; block<nblock; block++)
01458 (*f)[block].SumIntoMyValue(row, 0, valptr->val().coeff(block));
01459
01460
01461
01462 if (valptr->hasFastAccess()) {
01463
01464
01465 for (unsigned int node_col=0; node_col<this->numNodes; node_col++){
01466
01467
01468 for (unsigned int eq_col=0; eq_col<neq; eq_col++) {
01469 lcol = neq * node_col + eq_col;
01470
01471
01472 col = nodeID[node_col][eq_col];
01473
01474
01475 for (int block=0; block<nblock_jac; block++) {
01476
01477 c = valptr->fastAccessDx(lcol).coeff(block);
01478 (*Jac)[block].SumIntoMyValues(row, 1, &c, &col);
01479
01480 }
01481 }
01482 }
01483 }
01484 }
01485 }
01486 }
01487
01488
01489
01490
01491
01492 template<typename Traits>
01493 Neumann<PHAL::AlbanyTraits::MPTangent, Traits>::
01494 Neumann(Teuchos::ParameterList& p)
01495 : NeumannBase<PHAL::AlbanyTraits::MPTangent,Traits>(p)
01496 {
01497 }
01498
01499
01500 template<typename Traits>
01501 void Neumann<PHAL::AlbanyTraits::MPTangent, Traits>::
01502 evaluateFields(typename Traits::EvalData workset)
01503 {
01504 Teuchos::RCP< Stokhos::ProductEpetraVector > f = workset.mp_f;
01505 Teuchos::RCP< Stokhos::ProductEpetraMultiVector > JV = workset.mp_JV;
01506 Teuchos::RCP< Stokhos::ProductEpetraMultiVector > fp = workset.mp_fp;
01507 ScalarT *valptr;
01508
01509
01510
01511 this->evaluateNeumannContribution(workset);
01512
01513 int nblock = 0;
01514 if (f != Teuchos::null)
01515 nblock = f->size();
01516 else if (JV != Teuchos::null)
01517 nblock = JV->size();
01518 else if (fp != Teuchos::null)
01519 nblock = fp->size();
01520 else
01521 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
01522 "One of mp_f, mp_JV, or mp_fp must be non-null! " <<
01523 std::endl);
01524
01525 for (std::size_t cell=0; cell < workset.numCells; ++cell ) {
01526 const Teuchos::ArrayRCP<Teuchos::ArrayRCP<int> >& nodeID = workset.wsElNodeEqID[cell];
01527
01528 for (std::size_t node = 0; node < this->numNodes; ++node)
01529 for (std::size_t dim = 0; dim < this->numDOFsSet; ++dim){
01530
01531 valptr = &(this->neumann)(cell, node, dim);
01532
01533 int row = nodeID[node][this->offset[dim]];
01534
01535 if (f != Teuchos::null)
01536 for (int block=0; block<nblock; block++)
01537 (*f)[block].SumIntoMyValue(row, 0, valptr->val().coeff(block));
01538
01539 if (JV != Teuchos::null)
01540 for (int col=0; col<workset.num_cols_x; col++)
01541 for (int block=0; block<nblock; block++)
01542 (*JV)[block].SumIntoMyValue(row, col, valptr->dx(col).coeff(block));
01543
01544 if (fp != Teuchos::null)
01545 for (int col=0; col<workset.num_cols_p; col++)
01546 for (int block=0; block<nblock; block++)
01547 (*fp)[block].SumIntoMyValue(row, col, valptr->dx(col+workset.param_offset).coeff(block));
01548
01549 }
01550 }
01551 }
01552 #endif //ALBANY_SG_MP
01553
01554
01555
01556
01557
01558
01559 template<typename EvalT, typename Traits>
01560 NeumannAggregator<EvalT, Traits>::
01561 NeumannAggregator(const Teuchos::ParameterList& p)
01562 {
01563 Teuchos::RCP<PHX::DataLayout> dl = p.get< Teuchos::RCP<PHX::DataLayout> >("Data Layout");
01564
01565 std::vector<std::string>& nbcs = *(p.get<std::vector<std::string>* >("NBC Names"));
01566
01567 for (unsigned int i=0; i<nbcs.size(); i++) {
01568 PHX::Tag<ScalarT> fieldTag(nbcs[i], dl);
01569 this->addDependentField(fieldTag);
01570 }
01571
01572 PHX::Tag<ScalarT> fieldTag(p.get<std::string>("NBC Aggregator Name"), dl);
01573 this->addEvaluatedField(fieldTag);
01574
01575 this->setName("Neumann Aggregator"+PHX::TypeString<EvalT>::value);
01576 }
01577
01578
01579 }