00001
00002
00003
00004
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
00018
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
00029
00030
00031
00032
00033
00034
00035 const CellTopologyData * const elem_top = shards::getCellTopologyData<shards::Hexahedron<8> >();
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);
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
00050 cubatureSide = cubFactory.create(*sideType, cubatureDegree);
00051
00052 sideDims = sideType->getDimension();
00053 numQPsSide = cubatureSide->getNumPoints();
00054
00055 numNodes = intrepidBasis->getCardinality();
00056
00057
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
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
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
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
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
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
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;
00151
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
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
00164 for (std::size_t side = 0; side < sideSet.size(); ++side) {
00165
00166
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
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
00181 Intrepid::CellTools<RealType>::mapToReferenceSubcell(refPointsSide, cubPointsSide, sideDims, elem_side, *cellType);
00182
00183
00184 Intrepid::CellTools<RealType>::setJacobian(jacobianSide, refPointsSide, physPointsCell, *cellType);
00185
00186 Intrepid::CellTools<MeshScalarT>::setJacobianDet(jacobianSide_det, jacobianSide);
00187
00188 if (sideDims < 2) {
00189 Intrepid::FunctionSpaceTools::computeEdgeMeasure<MeshScalarT>(weighted_measure, jacobianSide, cubWeightsSide, elem_side, *cellType);
00190 } else {
00191 Intrepid::FunctionSpaceTools::computeFaceMeasure<MeshScalarT>(weighted_measure, jacobianSide, cubWeightsSide, elem_side, *cellType);
00192 }
00193
00194
00195 intrepidBasis->getValues(basis_refPointsSide, refPointsSide, Intrepid::OPERATOR_VALUE);
00196
00197
00198 Intrepid::FunctionSpaceTools::HGRADtransformVALUE<RealType>(trans_basis_refPointsSide, basis_refPointsSide);
00199
00200
00201 Intrepid::FunctionSpaceTools::multiplyMeasure<MeshScalarT>(weighted_trans_basis_refPointsSide, weighted_measure, trans_basis_refPointsSide);
00202
00203
00204 Intrepid::CellTools<RealType>::mapToPhysicalFrame(physPointsSide, refPointsSide, physPointsCell, *cellType);
00205
00206
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
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
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);
00240 int numPoints = data.dimension(1);
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
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
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
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
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