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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "SundanceBubble.hpp"
00043 #include "SundanceSpatialDerivSpecifier.hpp"
00044 #include "SundancePoint.hpp"
00045 #include "SundanceADReal.hpp"
00046 #include "PlayaExceptions.hpp"
00047 #include "SundanceObjectWithVerbosity.hpp"
00048 #include "SundanceOut.hpp"
00049
00050 using namespace Sundance;
00051 using namespace Sundance;
00052 using namespace Sundance;
00053 using namespace Teuchos;
00054
00055
00056
00057
00058 bool Bubble::supportsCellTypePair(
00059 const CellType& maximalCellType,
00060 const CellType& cellType
00061 ) const
00062 {
00063 switch(maximalCellType)
00064 {
00065 case LineCell:
00066 switch(cellType)
00067 {
00068 case LineCell:
00069 case PointCell:
00070 return true;
00071 default:
00072 return false;
00073 }
00074 case TriangleCell:
00075 switch(cellType)
00076 {
00077 case TriangleCell:
00078 case LineCell:
00079 case PointCell:
00080 return true;
00081 default:
00082 return false;
00083 }
00084 case TetCell:
00085 switch(cellType)
00086 {
00087 case TetCell:
00088 case TriangleCell:
00089 case LineCell:
00090 case PointCell:
00091 return true;
00092 default:
00093 return false;
00094 }
00095 default:
00096 return false;
00097 }
00098 }
00099
00100 void Bubble::print(std::ostream& os) const
00101 {
00102 os << "Bubble(" << order_ << ")";
00103 }
00104
00105 int Bubble::nReferenceDOFsWithoutFacets(
00106 const CellType& maximalCellType,
00107 const CellType& cellType
00108 ) const
00109 {
00110 if (maximalCellType==cellType) return 1;
00111 else return 0;
00112 }
00113
00114 void Bubble::getReferenceDOFs(
00115 const CellType& maxCellType,
00116 const CellType& cellType,
00117 Array<Array<Array<int> > >& dofs) const
00118 {
00119 typedef Array<int> Aint;
00120
00121 Aint z(1);
00122 z[0] = 0;
00123
00124 switch(cellType)
00125 {
00126 case PointCell:
00127 switch(maxCellType)
00128 {
00129 case LineCell:
00130 case TriangleCell:
00131 case TetCell:
00132 dofs.resize(1);
00133 dofs[0].resize(1);
00134 return;
00135 default:
00136 TEUCHOS_TEST_FOR_EXCEPT(1);
00137 }
00138 case LineCell:
00139 dofs.resize(2);
00140 dofs[0].resize(2);
00141 dofs[1].resize(1);
00142 if (maxCellType==LineCell)
00143 {
00144 dofs[1] = tuple<Aint>(z);
00145 }
00146 return;
00147 case TriangleCell:
00148 dofs.resize(3);
00149 dofs[0].resize(3);
00150 dofs[1].resize(3);
00151 dofs[2].resize(1);
00152 if (maxCellType==TriangleCell)
00153 {
00154 dofs[2]=tuple<Aint>(z);
00155 }
00156 return;
00157 case TetCell:
00158 dofs.resize(4);
00159 dofs[0].resize(4);
00160 dofs[1].resize(6);
00161 dofs[2].resize(4);
00162 dofs[3].resize(1);
00163 if (maxCellType==TetCell)
00164 {
00165 dofs[3]=tuple<Aint>(z);
00166 }
00167 return;
00168 default:
00169 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Cell type "
00170 << cellType << " not implemented in Bubble basis");
00171 }
00172 }
00173
00174
00175
00176
00177 void Bubble::refEval(
00178 const CellType& cellType,
00179 const Array<Point>& pts,
00180 const SpatialDerivSpecifier& sds,
00181 Array<Array<Array<double> > >& result,
00182 int verbosity) const
00183 {
00184 TEUCHOS_TEST_FOR_EXCEPTION(!(sds.isPartial() || sds.isIdentity()),
00185 std::runtime_error,
00186 "cannot evaluate spatial derivative " << sds << " on Bubble basis");
00187 const MultiIndex& deriv = sds.mi();
00188 typedef Array<double> Adouble;
00189 result.resize(1);
00190 result[0].resize(pts.length());
00191
00192 switch(cellType)
00193 {
00194 case PointCell:
00195 result[0] = tuple<Adouble>(tuple(1.0));
00196 return;
00197 case LineCell:
00198 for (int i=0; i<pts.length(); i++)
00199 {
00200 evalOnLine(pts[i], deriv, result[0][i]);
00201 }
00202 break;
00203 case TriangleCell:
00204 for (int i=0; i<pts.length(); i++)
00205 {
00206 evalOnTriangle(pts[i], deriv, result[0][i]);
00207 }
00208 break;
00209 case TetCell:
00210 for (int i=0; i<pts.length(); i++)
00211 {
00212 evalOnTet(pts[i], deriv, result[0][i]);
00213 }
00214 break;
00215 default:
00216 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00217 "Bubble::refEval() unimplemented for cell type "
00218 << cellType);
00219
00220 }
00221 }
00222
00223
00224
00225 void Bubble::evalOnLine(const Point& pt,
00226 const MultiIndex& deriv,
00227 Array<double>& result) const
00228 {
00229 ADReal x = ADReal(pt[0], 0, 1);
00230 ADReal one(1.0, 1);
00231
00232 result.resize(1);
00233 Array<ADReal> tmp(result.length());
00234
00235 int p = (order_+1)/2;
00236 if (order_==0) p=1;
00237 ADReal xp = one;
00238 for (int i=0; i<p; i++) xp = xp*x;
00239
00240 tmp[0] = xp*(1.0-xp);
00241
00242 for (int i=0; i<tmp.length(); i++)
00243 {
00244 if (deriv.order()==0) result[i] = tmp[i].value();
00245 else result[i] = tmp[i].gradient()[0];
00246 }
00247 }
00248
00249 void Bubble::evalOnTriangle(const Point& pt,
00250 const MultiIndex& deriv,
00251 Array<double>& result) const
00252
00253
00254
00255 {
00256 ADReal x = ADReal(pt[0], 0, 2);
00257 ADReal y = ADReal(pt[1], 1, 2);
00258 ADReal one(1.0, 2);
00259
00260 Array<ADReal> tmp(1);
00261 result.resize(1);
00262
00263
00264 SUNDANCE_OUT(this->verb() > 3, "x=" << x.value() << " y="
00265 << y.value());
00266
00267 int p = (order_+2)/3;
00268 if (order_==0) p=1;
00269
00270 ADReal xp = one;
00271 ADReal yp = one;
00272 for (int i=0; i<p; i++)
00273 {
00274 xp = xp*x;
00275 yp = yp*y;
00276 }
00277
00278 tmp[0] = xp*yp*(1.0-xp-yp)*std::pow(2.0,3*p);
00279
00280 for (int i=0; i<tmp.length(); i++)
00281 {
00282 SUNDANCE_OUT(this->verb() > 3,
00283 "tmp[" << i << "]=" << tmp[i].value()
00284 << " grad=" << tmp[i].gradient());
00285 if (deriv.order()==0) result[i] = tmp[i].value();
00286 else
00287 result[i] = tmp[i].gradient()[deriv.firstOrderDirection()];
00288 }
00289 }
00290
00291
00292 void Bubble::evalOnTet(const Point& pt,
00293 const MultiIndex& deriv,
00294 Array<double>& result) const
00295 {
00296 ADReal x = ADReal(pt[0], 0, 3);
00297 ADReal y = ADReal(pt[1], 1, 3);
00298 ADReal z = ADReal(pt[2], 2, 3);
00299 ADReal one(1.0, 3);
00300
00301 result.resize(1);
00302 Array<ADReal> tmp(result.length());
00303
00304 int p = (order_+3)/4;
00305 if (order_==0) p=1;
00306
00307 ADReal xp = one;
00308 ADReal yp = one;
00309 ADReal zp = one;
00310 for (int i=0; i<p; i++)
00311 {
00312 xp = xp*x;
00313 yp = yp*y;
00314 zp = zp*z;
00315 }
00316
00317 tmp[0] = (1.0-xp-yp-zp)*xp*yp*zp*std::pow(2.0,4*p);
00318
00319 for (int i=0; i<tmp.length(); i++)
00320 {
00321 if (deriv.order()==0) result[i] = tmp[i].value();
00322 else
00323 result[i] = tmp[i].gradient()[deriv.firstOrderDirection()];
00324 }
00325 }
00326