• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

FELIX_ResponseSurfaceVelocityMismatch_Def.hpp

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
00005 //*****************************************************************//
00006 
00007 #include <fstream>
00008 #include "Teuchos_TestForException.hpp"
00009 #include "Phalanx_DataLayout.hpp"
00010 #include "Teuchos_CommHelpers.hpp"
00011 #include "Phalanx.hpp"
00012 #include "Intrepid_FunctionSpaceTools.hpp"
00013 
00014 template<typename EvalT, typename Traits>
00015 FELIX::ResponseSurfaceVelocityMismatch<EvalT, Traits>::ResponseSurfaceVelocityMismatch(Teuchos::ParameterList& p, const Teuchos::RCP<Albany::Layouts>& dl) :
00016     coordVec("Coord Vec", dl->vertices_vector), surfaceVelocity_field("Surface Velocity", dl->node_vector), velocityRMS_field("Velocity RMS", dl->node_vector), velocity_field("Velocity", dl->node_vector), numVecDim(2) {
00017   // get and validate Response parameter list
00018   //meshSpecs(p.get<Teuchos::RCP<Albany::MeshSpecsStruct> >("Mesh Specs Struct")),
00019   Teuchos::ParameterList* plist = p.get<Teuchos::ParameterList*>("Parameter List");
00020   std::string fieldName;
00021   fieldName = plist->get<std::string>("Field Name", "");
00022 
00023   Teuchos::RCP<const Teuchos::ParameterList> reflist = this->getValidResponseParameters();
00024   plist->validateParameters(*reflist, 0);
00025 
00026   int position;
00027 
00028   // PHX::Tag<ScalarT> fieldTag(name, dl->dummy);
00029 
00030   // this->addEvaluatedField(fieldTag);
00031 
00032   // Build element and side integration support
00033 
00034   //const CellTopologyData * const elem_top = shards::getCellTopologyData< shards::Tetrahedron<4> >(); //&meshSpecs->ctd;
00035   const CellTopologyData * const elem_top = shards::getCellTopologyData<shards::Hexahedron<8> >(); //&meshSpecs->ctd;
00036 
00037   intrepidBasis = Albany::getIntrepidBasis(*elem_top);
00038 
00039   cellType = Teuchos::rcp(new shards::CellTopology(elem_top));
00040 
00041   Intrepid::DefaultCubatureFactory<RealType> cubFactory;
00042   cubatureCell = cubFactory.create(*cellType, 1); //meshSpecs->cubatureDegree);
00043 
00044   const CellTopologyData * const side_top = elem_top->side[0].topology;
00045 
00046   sideType = Teuchos::rcp(new shards::CellTopology(side_top));
00047 
00048   int cubatureDegree = 1;
00049   //int cubatureDegree = (p.get<int>("Cubature Degree") > 0) ? p.get<int>("Cubature Degree") : meshSpecs->cubatureDegree;
00050   cubatureSide = cubFactory.create(*sideType, cubatureDegree);
00051 
00052   sideDims = sideType->getDimension();
00053   numQPsSide = cubatureSide->getNumPoints();
00054 
00055   numNodes = intrepidBasis->getCardinality();
00056 
00057   // Get Dimensions
00058   std::vector<PHX::DataLayout::size_type> dim;
00059   dl->qp_tensor->dimensions(dim);
00060   int containerSize = dim[0];
00061   numQPs = dim[1];
00062   cellDims = dim[2];
00063 
00064   // Allocate Temporary FieldContainers
00065   cubPointsSide.resize(numQPsSide, sideDims);
00066   refPointsSide.resize(numQPsSide, cellDims);
00067   cubWeightsSide.resize(numQPsSide);
00068   physPointsSide.resize(1, numQPsSide, cellDims);
00069   dofSide.resize(1, numQPsSide);
00070   dofSideVec.resize(1, numQPsSide, numVecDim);
00071 
00072   // Do the BC one side at a time for now
00073   jacobianSide.resize(1, numQPsSide, cellDims, cellDims);
00074   jacobianSide_det.resize(1, numQPsSide);
00075 
00076   weighted_measure.resize(1, numQPsSide);
00077   basis_refPointsSide.resize(numNodes, numQPsSide);
00078   trans_basis_refPointsSide.resize(1, numNodes, numQPsSide);
00079   weighted_trans_basis_refPointsSide.resize(1, numNodes, numQPsSide);
00080 
00081   physPointsCell.resize(1, numNodes, cellDims);
00082   dofCell.resize(1, numNodes);
00083   dofCellVec.resize(1, numNodes, numVecDim);
00084   data.resize(1, numQPsSide);
00085 
00086   // Pre-Calculate reference element quantitites
00087   cubatureSide->getCubature(cubPointsSide, cubWeightsSide);
00088 
00089   std::vector<PHX::DataLayout::size_type> dims;
00090   dl->qp_gradient->dimensions(dims);
00091   numQPs = dims[1];
00092   numDims = dims[2];
00093 
00094   // add dependent fields
00095   this->addDependentField(velocity_field);
00096   this->addDependentField(surfaceVelocity_field);
00097   this->addDependentField(velocityRMS_field);
00098   this->addDependentField(coordVec);
00099 
00100   this->setName(fieldName + " Response Surface Velocity Mismatch" + PHX::TypeString<EvalT>::value);
00101 
00102   using PHX::MDALayout;
00103 
00104   // Setup scatter evaluator
00105   p.set("Stand-alone Evaluator", false);
00106   std::string local_response_name = fieldName + " Local Response Surface Velocity Mismatch";
00107   std::string global_response_name = fieldName + " Global Response Surface Velocity Mismatch";
00108   int worksetSize = dl->qp_scalar->dimension(0);
00109   int responseSize = 1;
00110   Teuchos::RCP<PHX::DataLayout> local_response_layout = Teuchos::rcp(new MDALayout<Cell, Dim>(worksetSize, responseSize));
00111   Teuchos::RCP<PHX::DataLayout> global_response_layout = Teuchos::rcp(new MDALayout<Dim>(responseSize));
00112   PHX::Tag<ScalarT> local_response_tag(local_response_name, local_response_layout);
00113   PHX::Tag<ScalarT> global_response_tag(global_response_name, global_response_layout);
00114   p.set("Local Response Field Tag", local_response_tag);
00115   p.set("Global Response Field Tag", global_response_tag);
00116   PHAL::SeparableScatterScalarResponse<EvalT, Traits>::setup(p, dl);
00117 }
00118 
00119 // **********************************************************************
00120 template<typename EvalT, typename Traits>
00121 void FELIX::ResponseSurfaceVelocityMismatch<EvalT, Traits>::postRegistrationSetup(typename Traits::SetupData d, PHX::FieldManager<Traits>& fm) {
00122   this->utils.setFieldData(coordVec, fm);
00123   this->utils.setFieldData(velocity_field, fm);
00124   this->utils.setFieldData(surfaceVelocity_field, fm);
00125   this->utils.setFieldData(velocityRMS_field, fm);
00126   PHAL::SeparableScatterScalarResponse<EvalT, Traits>::postRegistrationSetup(d, fm);
00127 }
00128 
00129 // **********************************************************************
00130 template<typename EvalT, typename Traits>
00131 void FELIX::ResponseSurfaceVelocityMismatch<EvalT, Traits>::preEvaluate(typename Traits::PreEvalData workset) {
00132   for (typename PHX::MDField<ScalarT>::size_type i = 0; i < this->global_response.size(); i++)
00133     this->global_response[i] = 0.0;
00134 
00135   // Do global initialization
00136   PHAL::SeparableScatterScalarResponse<EvalT, Traits>::preEvaluate(workset);
00137 }
00138 
00139 // **********************************************************************
00140 template<typename EvalT, typename Traits>
00141 void FELIX::ResponseSurfaceVelocityMismatch<EvalT, Traits>::evaluateFields(typename Traits::EvalData workset) {
00142 
00143   if (workset.sideSets == Teuchos::null)
00144     TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Side sets defined in input file but not properly specified on the mesh" << std::endl);
00145 
00146   const Albany::SideSetList& ssList = *(workset.sideSets);
00147   Albany::SideSetList::const_iterator it = ssList.find("upperside");
00148 
00149   if (it == ssList.end())
00150     return; // This sideset does not exist in this workset (GAH - this can go away
00151             // once we move logic to BCUtils
00152 
00153   const std::vector<Albany::SideStruct>& sideSet = it->second;
00154 
00155   Intrepid::FieldContainer<ScalarT> surfaceVelocityOnSide(1, numQPsSide, numVecDim);
00156   Intrepid::FieldContainer<ScalarT> velocityRMSOnSide(1, numQPsSide, numVecDim);
00157   Intrepid::FieldContainer<ScalarT> velocityOnSide(1, numQPsSide, numVecDim);
00158 
00159   // Zero out local response
00160   for (typename PHX::MDField<ScalarT>::size_type i = 0; i < this->local_response.size(); i++)
00161     this->local_response[i] = 0.0;
00162 
00163   // Loop over the sides that form the boundary condition
00164   for (std::size_t side = 0; side < sideSet.size(); ++side) { // loop over the sides on this ws and name
00165 
00166     // Get the data that corresponds to the side
00167 
00168     const int elem_GID = sideSet[side].elem_GID;
00169     const int elem_LID = sideSet[side].elem_LID;
00170     const int elem_side = sideSet[side].side_local_id;
00171 
00172     // Copy the coordinate data over to a temp container
00173 
00174     for (std::size_t node = 0; node < numNodes; ++node) {
00175       for (std::size_t dim = 0; dim < cellDims - 1; ++dim)
00176         physPointsCell(0, node, dim) = coordVec(elem_LID, node, dim);
00177       physPointsCell(0, node, 2) = 0;
00178     }
00179 
00180     // Map side cubature points to the reference parent cell based on the appropriate side (elem_side)
00181     Intrepid::CellTools<RealType>::mapToReferenceSubcell(refPointsSide, cubPointsSide, sideDims, elem_side, *cellType);
00182 
00183     // Calculate side geometry
00184     Intrepid::CellTools<RealType>::setJacobian(jacobianSide, refPointsSide, physPointsCell, *cellType);
00185 
00186     Intrepid::CellTools<MeshScalarT>::setJacobianDet(jacobianSide_det, jacobianSide);
00187 
00188     if (sideDims < 2) { //for 1 and 2D, get weighted edge measure
00189       Intrepid::FunctionSpaceTools::computeEdgeMeasure<MeshScalarT>(weighted_measure, jacobianSide, cubWeightsSide, elem_side, *cellType);
00190     } else { //for 3D, get weighted face measure
00191       Intrepid::FunctionSpaceTools::computeFaceMeasure<MeshScalarT>(weighted_measure, jacobianSide, cubWeightsSide, elem_side, *cellType);
00192     }
00193 
00194     // Values of the basis functions at side cubature points, in the reference parent cell domain
00195     intrepidBasis->getValues(basis_refPointsSide, refPointsSide, Intrepid::OPERATOR_VALUE);
00196 
00197     // Transform values of the basis functions
00198     Intrepid::FunctionSpaceTools::HGRADtransformVALUE<RealType>(trans_basis_refPointsSide, basis_refPointsSide);
00199 
00200     // Multiply with weighted measure
00201     Intrepid::FunctionSpaceTools::multiplyMeasure<MeshScalarT>(weighted_trans_basis_refPointsSide, weighted_measure, trans_basis_refPointsSide);
00202 
00203     // Map cell (reference) cubature points to the appropriate side (elem_side) in physical space
00204     Intrepid::CellTools<RealType>::mapToPhysicalFrame(physPointsSide, refPointsSide, physPointsCell, *cellType);
00205 
00206     // Map cell (reference) degree of freedom points to the appropriate side (elem_side)
00207     Intrepid::FieldContainer<MeshScalarT> surfaceVelocityOnCell(1, numNodes, numVecDim);
00208     Intrepid::FieldContainer<MeshScalarT> velocityRMSOnCell(1, numNodes, numVecDim);
00209     Intrepid::FieldContainer<ScalarT> velocityOnCell(1, numNodes, numVecDim);
00210     for (std::size_t node = 0; node < numNodes; ++node) {
00211       for (std::size_t dim = 0; dim < numVecDim; ++dim) {
00212         surfaceVelocityOnCell(0, node, dim) = surfaceVelocity_field(elem_LID, node, dim);
00213         velocityRMSOnCell(0, node, dim) = velocityRMS_field(elem_LID, node, dim);
00214         dofCellVec(0, node, dim) = velocity_field(elem_LID, node, dim);
00215       }
00216       // This is needed, since evaluate currently sums into
00217       for (int i = 0; i < numQPsSide; i++) {
00218         for (std::size_t dim = 0; dim < numVecDim; ++dim) {
00219           surfaceVelocityOnSide(0, i, dim) = 0.0;
00220           velocityRMSOnSide(0, i, dim) = 0.0;
00221         }
00222       }
00223       for (int i = 0; i < dofSideVec.size(); i++)
00224         dofSideVec[i] = 0.0;
00225 
00226       // Get dof at cubature points of appropriate side (see DOFVecInterpolation evaluator)
00227       for (std::size_t node = 0; node < numNodes; ++node) {
00228         for (std::size_t qp = 0; qp < numQPsSide; ++qp) {
00229           for (std::size_t dim = 0; dim < numVecDim; ++dim) {
00230             surfaceVelocityOnSide(0, qp, dim) += surfaceVelocityOnCell(0, node, dim) * trans_basis_refPointsSide(0, node, qp);
00231             velocityRMSOnSide(0, qp, dim) += velocityRMSOnCell(0, node, dim) * trans_basis_refPointsSide(0, node, qp);
00232             dofSideVec(0, qp, dim) += dofCellVec(0, node, dim) * trans_basis_refPointsSide(0, node, qp);
00233           }
00234         }
00235       }
00236 
00237     }
00238 
00239     int numCells = data.dimension(0); // How many cell's worth of data is being computed?
00240     int numPoints = data.dimension(1); // How many QPs per cell?
00241 
00242     //std::cout << "DEBUG: applying const dudn to sideset " << this->sideSetID << ": " << (const_val * scale) << std::endl;
00243 
00244     //Intrepid::FieldContainer<MeshScalarT> side_normals(numCells, numPoints, cellDims);
00245     //Intrepid::FieldContainer<MeshScalarT> normal_lengths(numCells, numPoints);
00246 
00247     // for this side in the reference cell, get the components of the normal direction vector
00248     //Intrepid::CellTools<MeshScalarT>::getPhysicalSideNormals(side_normals, jacobian_side_refcell, local_side_id, celltopo);
00249 
00250     // scale normals (unity)
00251     //Intrepid::RealSpaceTools<MeshScalarT>::vectorNorm(normal_lengths, side_normals, Intrepid::NORM_TWO);
00252     //Intrepid::FunctionSpaceTools::scalarMultiplyDataData<MeshScalarT>(side_normals, normal_lengths, side_normals, true);
00253 
00254     double factor = 1.0;
00255     for (int cell = 0; cell < numCells; cell++) {
00256       for (int pt = 0; pt < numPoints; pt++) {
00257         ScalarT refVel0 = std::asinh(surfaceVelocityOnSide(cell, pt, 0) / velocityRMSOnSide(cell, pt, 0) / factor);
00258         ScalarT refVel1 = std::asinh(surfaceVelocityOnSide(cell, pt, 1) / velocityRMSOnSide(cell, pt, 1) / factor);
00259         ScalarT vel0 = std::asinh(dofSideVec(cell, pt, 0) / velocityRMSOnSide(cell, pt, 0) / factor);
00260         ScalarT vel1 = std::asinh(dofSideVec(cell, pt, 1) / velocityRMSOnSide(cell, pt, 1) / factor);
00261         data(cell, pt) = factor * factor * ((refVel0 - vel0) * (refVel0 - vel0) + (refVel1 - vel1) * (refVel1 - vel1));
00262       }
00263     }
00264     //  }
00265 
00266     ScalarT t = 0;
00267     for (std::size_t node = 0; node < numNodes; ++node)
00268       for (std::size_t qp = 0; qp < numQPsSide; ++qp)
00269         t += data(0, qp) * weighted_trans_basis_refPointsSide(0, node, qp);
00270 
00271     this->local_response(elem_LID, 0) += t;
00272     this->global_response(0) += t;
00273 
00274   }
00275 
00276   // Do any local-scattering necessary
00277   PHAL::SeparableScatterScalarResponse<EvalT, Traits>::evaluateFields(workset);
00278 }
00279 
00280 // **********************************************************************
00281 template<typename EvalT, typename Traits>
00282 void FELIX::ResponseSurfaceVelocityMismatch<EvalT, Traits>::postEvaluate(typename Traits::PostEvalData workset) {
00283   // Add contributions across processors
00284   Teuchos::RCP<Teuchos::ValueTypeSerializer<int, ScalarT> > serializer = workset.serializerManager.template getValue<EvalT>();
00285   Teuchos::reduceAll(*workset.comm, *serializer, Teuchos::REDUCE_SUM, this->global_response.size(), &this->global_response[0], &this->global_response[0]);
00286 
00287   if (rank(*workset.comm) == 0) {
00288     std::ofstream ofile;
00289     ofile.open("mismatch");
00290     if (ofile.is_open(), std::ofstream::out | std::ofstream::trunc) {
00291       ofile << sqrt(this->global_response[0]);
00292       ofile.close();
00293     }
00294   }
00295 
00296   // Do global scattering
00297   PHAL::SeparableScatterScalarResponse<EvalT, Traits>::postEvaluate(workset);
00298 }
00299 
00300 // **********************************************************************
00301 template<typename EvalT, typename Traits>
00302 Teuchos::RCP<const Teuchos::ParameterList> FELIX::ResponseSurfaceVelocityMismatch<EvalT, Traits>::getValidResponseParameters() const {
00303   Teuchos::RCP<Teuchos::ParameterList> validPL = rcp(new Teuchos::ParameterList("Valid ResponseSurfaceVelocityMismatch Params"));
00304   Teuchos::RCP<const Teuchos::ParameterList> baseValidPL = PHAL::SeparableScatterScalarResponse<EvalT, Traits>::getValidResponseParameters();
00305   validPL->setParameters(*baseValidPL);
00306 
00307   validPL->set<std::string>("Name", "", "Name of response function");
00308   validPL->set<std::string>("Field Name", "Solution", "Not used");
00309   validPL->set<int>("Phalanx Graph Visualization Detail", 0, "Make dot file to visualize phalanx graph");
00310   validPL->set<std::string>("Description", "", "Description of this response used by post processors");
00311 
00312   return validPL;
00313 }
00314 
00315 // **********************************************************************
00316 

Generated on Wed Mar 26 2014 18:36:38 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1