00001
00002
00003
00004
00005
00006
00007 #include "Teuchos_TestForException.hpp"
00008 #include "Teuchos_VerboseObject.hpp"
00009 #include "Phalanx_DataLayout.hpp"
00010 #include "Sacado.hpp"
00011
00012 #include "Intrepid_FunctionSpaceTools.hpp"
00013
00014
00015
00016
00017 namespace FELIX {
00018 const double pi = 3.1415926535897932385;
00019 const double g = 9.8;
00020 const double rho = 910;
00021 const double rho_g = rho*g;
00022
00023
00024
00025 template<typename EvalT, typename Traits>
00026 StokesFOBodyForce<EvalT, Traits>::
00027 StokesFOBodyForce(const Teuchos::ParameterList& p,
00028 const Teuchos::RCP<Albany::Layouts>& dl) :
00029 force(p.get<std::string>("Body Force Name"), dl->qp_vector),
00030 A(1.0),
00031 n(3.0),
00032 alpha(0.0)
00033 {
00034 Teuchos::RCP<Teuchos::FancyOStream> out(Teuchos::VerboseObjectBase::getDefaultOStream());
00035 Teuchos::ParameterList* bf_list =
00036 p.get<Teuchos::ParameterList*>("Parameter List");
00037
00038 std::string type = bf_list->get("Type", "None");
00039 A = bf_list->get("Glen's Law A", 1.0);
00040 n = bf_list->get("Glen's Law n", 3.0);
00041 alpha = bf_list->get("FELIX alpha", 0.0);
00042 #ifdef OUTPUT_TO_SCREEN
00043 *out << "alpha: " << alpha << std::endl;
00044 #endif
00045 alpha *= pi/180.0;
00046 if (type == "None") {
00047 bf_type = NONE;
00048 }
00049 else if (type == "FO INTERP SURF GRAD") {
00050 #ifdef OUTPUT_TO_SCREEN
00051 *out << "INTERP SURFACE GRAD Source!" << std::endl;
00052 #endif
00053 surfaceGrad = PHX::MDField<MeshScalarT,Cell,QuadPoint,Dim>(
00054 p.get<std::string>("Surface Height Gradient Name"), dl->qp_gradient);
00055 this->addDependentField(surfaceGrad);
00056 bf_type = FO_INTERP_SURF_GRAD;
00057 }
00058 else if (type == "FOSinCos2D") {
00059 bf_type = FO_SINCOS2D;
00060 muFELIX = PHX::MDField<ScalarT,Cell,QuadPoint>(
00061 p.get<std::string>("FELIX Viscosity QP Variable Name"), dl->qp_scalar);
00062 coordVec = PHX::MDField<MeshScalarT,Cell,QuadPoint,Dim>(
00063 p.get<std::string>("Coordinate Vector Name"), dl->qp_gradient);
00064 this->addDependentField(muFELIX);
00065 this->addDependentField(coordVec);
00066 }
00067 else if (type == "FOSinExp2D") {
00068 bf_type = FO_SINEXP2D;
00069 muFELIX = PHX::MDField<ScalarT,Cell,QuadPoint>(
00070 p.get<std::string>("FELIX Viscosity QP Variable Name"), dl->qp_scalar);
00071 coordVec = PHX::MDField<MeshScalarT,Cell,QuadPoint,Dim>(
00072 p.get<std::string>("Coordinate Vector Name"), dl->qp_gradient);
00073 this->addDependentField(muFELIX);
00074 this->addDependentField(coordVec);
00075 }
00076 else if (type == "FOCosExp2D") {
00077 bf_type = FO_COSEXP2D;
00078 muFELIX = PHX::MDField<ScalarT,Cell,QuadPoint>(
00079 p.get<std::string>("FELIX Viscosity QP Variable Name"), dl->qp_scalar);
00080 coordVec = PHX::MDField<MeshScalarT,Cell,QuadPoint,Dim>(
00081 p.get<std::string>("Coordinate Vector Name"), dl->qp_gradient);
00082 this->addDependentField(muFELIX);
00083 this->addDependentField(coordVec);
00084 }
00085 else if (type == "FOCosExp2DFlip") {
00086 bf_type = FO_COSEXP2DFLIP;
00087 muFELIX = PHX::MDField<ScalarT,Cell,QuadPoint>(
00088 p.get<std::string>("FELIX Viscosity QP Variable Name"), dl->qp_scalar);
00089 coordVec = PHX::MDField<MeshScalarT,Cell,QuadPoint,Dim>(
00090 p.get<std::string>("Coordinate Vector Name"), dl->qp_gradient);
00091 this->addDependentField(muFELIX);
00092 this->addDependentField(coordVec);
00093 }
00094 else if (type == "FOCosExp2DAll") {
00095 bf_type = FO_COSEXP2DALL;
00096 muFELIX = PHX::MDField<ScalarT,Cell,QuadPoint>(
00097 p.get<std::string>("FELIX Viscosity QP Variable Name"), dl->qp_scalar);
00098 coordVec = PHX::MDField<MeshScalarT,Cell,QuadPoint,Dim>(
00099 p.get<std::string>("Coordinate Vector Name"), dl->qp_gradient);
00100 this->addDependentField(muFELIX);
00101 this->addDependentField(coordVec);
00102 }
00103 else if (type == "FOSinCosZ") {
00104 bf_type = FO_SINCOSZ;
00105 muFELIX = PHX::MDField<ScalarT,Cell,QuadPoint>(
00106 p.get<std::string>("FELIX Viscosity QP Variable Name"), dl->qp_scalar);
00107 coordVec = PHX::MDField<MeshScalarT,Cell,QuadPoint,Dim>(
00108 p.get<std::string>("Coordinate Vector Name"), dl->qp_gradient);
00109 this->addDependentField(muFELIX);
00110 this->addDependentField(coordVec);
00111 }
00112 else if (type == "Poisson") {
00113 bf_type = POISSON;
00114 muFELIX = PHX::MDField<ScalarT,Cell,QuadPoint>(
00115 p.get<std::string>("FELIX Viscosity QP Variable Name"), dl->qp_scalar);
00116 coordVec = PHX::MDField<MeshScalarT,Cell,QuadPoint,Dim>(
00117 p.get<std::string>("Coordinate Vector Name"), dl->qp_gradient);
00118 this->addDependentField(muFELIX);
00119 this->addDependentField(coordVec);
00120 }
00121
00122 else if ((type == "FO ISMIP-HOM Test A") || (type == "FO ISMIP-HOM Test B") || (type == "FO ISMIP-HOM Test C") || (type == "FO ISMIP-HOM Test D")) {
00123 *out << "ISMIP-HOM Tests A/B/C/D \n WARNING: computing INTERP SURFACE GRAD Source! \nPlease set Force Type = FO INTERP GRAD SURF." << std::endl;
00124 surfaceGrad = PHX::MDField<MeshScalarT,Cell,QuadPoint,Dim>(
00125 p.get<std::string>("Surface Height Gradient Name"), dl->qp_gradient);
00126 this->addDependentField(surfaceGrad);
00127 bf_type = FO_INTERP_SURF_GRAD;
00128 }
00129 else if (type == "FO Dome") {
00130 #ifdef OUTPUT_TO_SCREEN
00131 *out << "Dome Source!" << std::endl;
00132 #endif
00133 coordVec = PHX::MDField<MeshScalarT,Cell,QuadPoint,Dim>(
00134 p.get<std::string>("Coordinate Vector Name"), dl->qp_gradient);
00135 bf_type = FO_DOME;
00136 this->addDependentField(coordVec);
00137 }
00138
00139 this->addEvaluatedField(force);
00140
00141 std::vector<PHX::DataLayout::size_type> dims;
00142 dl->qp_gradient->dimensions(dims);
00143 numQPs = dims[1];
00144 numDims = dims[2];
00145 dl->qp_vector->dimensions(dims);
00146 vecDim = dims[2];
00147
00148
00149
00150
00151
00152
00153 this->setName("StokesFOBodyForce"+PHX::TypeString<EvalT>::value);
00154 }
00155
00156
00157 template<typename EvalT, typename Traits>
00158 void StokesFOBodyForce<EvalT, Traits>::
00159 postRegistrationSetup(typename Traits::SetupData d,
00160 PHX::FieldManager<Traits>& fm)
00161 {
00162 if (bf_type == FO_SINCOS2D || bf_type == FO_SINEXP2D || bf_type == FO_COSEXP2D || bf_type == FO_COSEXP2DFLIP ||
00163 bf_type == FO_COSEXP2DALL || bf_type == FO_SINCOSZ || bf_type == POISSON) {
00164 this->utils.setFieldData(muFELIX,fm);
00165 this->utils.setFieldData(coordVec,fm);
00166 }
00167 else if (bf_type == FO_DOME) {
00168 this->utils.setFieldData(coordVec,fm);
00169 }
00170 else if (bf_type == FO_INTERP_SURF_GRAD)
00171 this->utils.setFieldData(surfaceGrad,fm);
00172
00173 this->utils.setFieldData(force,fm);
00174 }
00175
00176
00177 template<typename EvalT, typename Traits>
00178 void StokesFOBodyForce<EvalT, Traits>::
00179 evaluateFields(typename Traits::EvalData workset)
00180 {
00181 if (bf_type == NONE) {
00182 for (std::size_t cell=0; cell < workset.numCells; ++cell)
00183 for (std::size_t qp=0; qp < numQPs; ++qp)
00184 for (std::size_t i=0; i < vecDim; ++i)
00185 force(cell,qp,i) = 0.0;
00186 }
00187
00188 else if (bf_type == FO_INTERP_SURF_GRAD) {
00189 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00190 for (std::size_t qp=0; qp < numQPs; ++qp) {
00191 force(cell,qp,0) = rho_g*surfaceGrad(cell,qp,0);
00192 force(cell,qp,1) = rho_g*surfaceGrad(cell,qp,1);
00193 }
00194 }
00195 }
00196 else if (bf_type == FO_SINCOS2D) {
00197 double xphase=0.0, yphase=0.0;
00198 double r = 3*pi;
00199 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00200 for (std::size_t qp=0; qp < numQPs; ++qp) {
00201 ScalarT* f = &force(cell,qp,0);
00202 MeshScalarT x2pi = 2.0*pi*coordVec(cell,qp,0);
00203 MeshScalarT y2pi = 2.0*pi*coordVec(cell,qp,1);
00204 MeshScalarT muargt = 2.0*pi*cos(x2pi + xphase)*cos(y2pi + yphase) + r;
00205 MeshScalarT muqp = 0.5*pow(A, -1.0/n)*pow(muargt, 1.0/n - 1.0);
00206 MeshScalarT dmuargtdx = -4.0*pi*pi*sin(x2pi + xphase)*cos(y2pi + yphase);
00207 MeshScalarT dmuargtdy = -4.0*pi*pi*cos(x2pi + xphase)*sin(y2pi + yphase);
00208 MeshScalarT exx = 2.0*pi*cos(x2pi + xphase)*cos(y2pi + yphase) + r;
00209 MeshScalarT eyy = -2.0*pi*cos(x2pi + xphase)*cos(y2pi + yphase) - r;
00210 MeshScalarT exy = 0.0;
00211 f[0] = 2.0*muqp*(-4.0*pi*pi*sin(x2pi + xphase)*cos(y2pi + yphase))
00212 + 2.0*0.5*pow(A, -1.0/n)*(1.0/n - 1.0)*pow(muargt, 1.0/n - 2.0)*(dmuargtdx*(2.0*exx + eyy) + dmuargtdy*exy);
00213 f[1] = 2.0*muqp*(4.0*pi*pi*cos(x2pi + xphase)*sin(y2pi + yphase))
00214 + 2.0*0.5*pow(A, -1.0/n)*(1.0/n - 1.0)*pow(muargt, 1.0/n - 2.0)*(dmuargtdx*exy + dmuargtdy*(exx + 2.0*eyy));
00215 }
00216 }
00217 }
00218 else if (bf_type == FO_SINEXP2D) {
00219 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00220 for (std::size_t qp=0; qp < numQPs; ++qp) {
00221 ScalarT* f = &force(cell,qp,0);
00222 MeshScalarT x2pi = 2.0*pi*coordVec(cell,qp,0);
00223 MeshScalarT y2pi = 2.0*pi*coordVec(cell,qp,1);
00224 MeshScalarT muqp = 1.0 ;
00225 f[0] = -1.0*(-4.0*muqp*exp(coordVec(cell,qp,0)) - 12.0*muqp*pi*pi*cos(x2pi)*cos(y2pi) + 4.0*muqp*pi*pi*cos(y2pi));
00226 f[1] = -1.0*(20.0*muqp*pi*pi*sin(x2pi)*sin(y2pi));
00227 }
00228 }
00229 }
00230 else if (bf_type == POISSON) {
00231 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00232 for (std::size_t qp=0; qp < numQPs; ++qp) {
00233 ScalarT* f = &force(cell,qp,0);
00234 MeshScalarT x = coordVec(cell,qp,0);
00235 f[0] = exp(x);
00236 }
00237 }
00238 }
00239 else if (bf_type == FO_COSEXP2D) {
00240 const double a = 1.0;
00241 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00242 for (std::size_t qp=0; qp < numQPs; ++qp) {
00243 ScalarT* f = &force(cell,qp,0);
00244 MeshScalarT x2pi = 2.0*pi*coordVec(cell,qp,0);
00245 MeshScalarT x = coordVec(cell,qp,0);
00246 MeshScalarT y2pi = 2.0*pi*coordVec(cell,qp,1);
00247 MeshScalarT muqp = 1.0 ;
00248 f[0] = 2.0*muqp*(2.0*a*a*exp(a*x)*cos(y2pi) + 6.0*pi*pi*cos(x2pi)*cos(y2pi) - 2.0*pi*pi*exp(a*x)*cos(y2pi));
00249 f[1] = 2.0*muqp*(-3.0*pi*a*exp(a*x)*sin(y2pi) - 10.0*pi*pi*sin(x2pi)*sin(y2pi));
00250 }
00251 }
00252 }
00253 else if (bf_type == FO_COSEXP2DFLIP) {
00254 const double a = 1.0;
00255 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00256 for (std::size_t qp=0; qp < numQPs; ++qp) {
00257 ScalarT* f = &force(cell,qp,0);
00258 MeshScalarT x2pi = 2.0*pi*coordVec(cell,qp,0);
00259 MeshScalarT x = coordVec(cell,qp,0);
00260 MeshScalarT y2pi = 2.0*pi*coordVec(cell,qp,1);
00261 MeshScalarT muqp = 1.0 ;
00262 f[0] = 2.0*muqp*(-3.0*pi*a*exp(a*x)*sin(y2pi) - 10.0*pi*pi*sin(x2pi)*sin(y2pi));
00263 f[1] = 2.0*muqp*(1.0/2.0*a*a*exp(a*x)*cos(y2pi) + 6.0*pi*pi*cos(x2pi)*cos(y2pi) - 8.0*pi*pi*exp(a*x)*cos(y2pi));
00264 }
00265 }
00266 }
00267 else if (bf_type == FO_COSEXP2DALL) {
00268 const double a = 1.0;
00269 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00270 for (std::size_t qp=0; qp < numQPs; ++qp) {
00271 ScalarT* f = &force(cell,qp,0);
00272 MeshScalarT x2pi = 2.0*pi*coordVec(cell,qp,0);
00273 MeshScalarT x = coordVec(cell,qp,0);
00274 MeshScalarT y2pi = 2.0*pi*coordVec(cell,qp,1);
00275 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);
00276 muargt = sqrt(muargt)*exp(a*x);
00277 MeshScalarT muqp = 1.0/2.0*pow(A, -1.0/n)*pow(muargt, 1.0/n - 1.0);
00278 MeshScalarT dmuargtdx = a*muargt;
00279 MeshScalarT dmuargtdy = 3.0/2.0*pi*(a*a+4.0*pi*pi-4.0*pi*a)*cos(y2pi)*sin(y2pi)*exp(a*x)/sqrt((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));
00280 MeshScalarT exx = a*exp(a*x)*sin(y2pi);
00281 MeshScalarT eyy = -2.0*pi*exp(a*x)*sin(y2pi);
00282 MeshScalarT exy = 1.0/2.0*(2.0*pi+a)*exp(a*x)*cos(y2pi);
00283 f[0] = 2.0*muqp*(2.0*a*a*exp(a*x)*sin(y2pi) - 3.0*pi*a*exp(a*x)*sin(y2pi) - 2.0*pi*pi*exp(a*x)*sin(y2pi))
00284 + 2.0*0.5*pow(A, -1.0/n)*(1.0/n-1.0)*pow(muargt, 1.0/n-2.0)*(dmuargtdx*(2.0*exx + eyy) + dmuargtdy*exy);
00285 f[1] = 2.0*muqp*(3.0*a*pi*exp(a*x)*cos(y2pi) + 1.0/2.0*a*a*exp(a*x)*cos(y2pi) - 8.0*pi*pi*exp(a*x)*cos(y2pi))
00286 + 2.0*0.5*pow(A, -1.0/n)*(1.0/n-1.0)*pow(muargt, 1.0/n-2.0)*(dmuargtdx*exy + dmuargtdy*(exx + 2.0*eyy));
00287 }
00288 }
00289 }
00290
00291 else if (bf_type == FO_SINCOSZ) {
00292 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00293 for (std::size_t qp=0; qp < numQPs; ++qp) {
00294 ScalarT* f = &force(cell,qp,0);
00295 MeshScalarT x2pi = 2.0*pi*coordVec(cell,qp,0);
00296 MeshScalarT y2pi = 2.0*pi*coordVec(cell,qp,1);
00297 MeshScalarT& z = coordVec(cell,qp,2);
00298 MeshScalarT muqp = 1.0;
00299
00300 ScalarT t1 = z*(1.0-z)*(1.0-2.0*z);
00301 ScalarT t2 = 2.0*z - 1.0;
00302
00303 f[0] = 2.0*muqp*(-16.0*pi*pi*t1 + 3.0*t2)*sin(x2pi)*sin(y2pi);
00304 f[1] = 2.0*muqp*(16.0*pi*pi*t1 - 3.0*t2)*cos(x2pi)*cos(y2pi);
00305 }
00306 }
00307 }
00308
00309 else if (bf_type == FO_DOME) {
00310 for (std::size_t cell=0; cell < workset.numCells; ++cell) {
00311 for (std::size_t qp=0; qp < numQPs; ++qp) {
00312 ScalarT* f = &force(cell,qp,0);
00313 MeshScalarT x = coordVec(cell,qp,0);
00314 MeshScalarT y = coordVec(cell,qp,1);
00315 f[0] = -rho_g*x*0.7071/sqrt(450.0-x*x-y*y)/sqrt(450.0);
00316 f[1] = -rho_g*y*0.7071/sqrt(450.0-x*x-y*y)/sqrt(450.0);
00317 }
00318 }
00319 }
00320 }
00321
00322 }
00323