Go to the documentation of this file.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 "SundanceEdgeLocalizedBasis.hpp"
00043 #include "SundanceADReal.hpp"
00044 #include "PlayaExceptions.hpp"
00045 #include "SundanceSpatialDerivSpecifier.hpp"
00046 #include "SundancePoint.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 EdgeLocalizedBasis::EdgeLocalizedBasis()
00057 {}
00058
00059 bool EdgeLocalizedBasis::supportsCellTypePair(
00060 const CellType& maximalCellType,
00061 const CellType& cellType
00062 ) const
00063 {
00064 switch(maximalCellType)
00065 {
00066 case TriangleCell:
00067 case TetCell:
00068 case QuadCell:
00069 case BrickCell:
00070 switch(cellType)
00071 {
00072 case LineCell:
00073 return true;
00074 default:
00075 return false;
00076 }
00077 default:
00078 return false;
00079 }
00080 }
00081
00082 void EdgeLocalizedBasis::print(std::ostream& os) const
00083 {
00084 os << "EdgeLocalizedBasis()";
00085 }
00086
00087 int EdgeLocalizedBasis::nReferenceDOFsWithoutFacets(
00088 const CellType& maximalCellType,
00089 const CellType& cellType
00090 ) const
00091 {
00092 switch(cellType)
00093 {
00094 case LineCell:
00095 return 1;
00096 default:
00097 return 0;
00098 }
00099 }
00100
00101 void EdgeLocalizedBasis::getReferenceDOFs(
00102 const CellType& maximalCellType,
00103 const CellType& cellType,
00104 Array<Array<Array<int> > >& dofs) const
00105 {
00106 typedef Array<int> Aint;
00107 switch(cellType)
00108 {
00109 case LineCell:
00110 dofs.resize(2);
00111 dofs[0] = Array<Array<int> >();
00112 dofs[1] = tuple<Aint>(tuple<int>(0));
00113 return;
00114 case TriangleCell:
00115 dofs.resize(3);
00116 dofs[0] = tuple(Array<int>());
00117 dofs[1] = tuple<Aint>(tuple(0), tuple(1), tuple(2));
00118 dofs[2] = tuple(Array<int>());
00119 return;
00120 default:
00121 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Cell type "
00122 << cellType << " not implemented in EdgeLocalizedBasis basis");
00123 }
00124 }
00125
00126
00127
00128 void EdgeLocalizedBasis::refEval(
00129 const CellType& cellType,
00130 const Array<Point>& pts,
00131 const SpatialDerivSpecifier& sds,
00132 Array<Array<Array<double> > >& result,
00133 int verbosity) const
00134 {
00135 TEUCHOS_TEST_FOR_EXCEPTION(!(sds.isPartial() || sds.isIdentity()),
00136 std::runtime_error,
00137 "cannot evaluate spatial derivative " << sds << " on EdgeLocalizedBasis basis");
00138 const MultiIndex& deriv = sds.mi();
00139 typedef Array<double> Adouble;
00140 result.resize(1);
00141 result[0].resize(pts.length());
00142
00143 int dim = dimension(cellType);
00144
00145 if (dim==0)
00146 {
00147 result[0] = tuple<Adouble>(tuple(1.0));
00148 }
00149 else if (dim==1)
00150 {
00151 for (int i=0; i<pts.length(); i++)
00152 {
00153 evalOnLine(pts[i], deriv, result[0][i]);
00154 }
00155 }
00156 else if (dim==2)
00157 {
00158 for (int i=0; i<pts.length(); i++)
00159 {
00160 evalOnTriangle(pts[i], deriv, result[0][i]);
00161 }
00162 }
00163 else if (dim==3)
00164 {
00165 for (int i=0; i<pts.length(); i++)
00166 {
00167 evalOnTet(pts[i], deriv, result[0][i]);
00168 }
00169 }
00170 }
00171
00172
00173
00174
00175 void EdgeLocalizedBasis::evalOnLine(const Point& pt,
00176 const MultiIndex& deriv,
00177 Array<double>& result) const
00178 {
00179 ADReal one(1.0, 1);
00180 result.resize(1);
00181 Array<ADReal> tmp(result.length());
00182
00183 tmp[0] = one;
00184
00185 for (int i=0; i<tmp.length(); i++)
00186 {
00187 if (deriv.order()==0) result[i] = tmp[i].value();
00188 else result[i] = tmp[i].gradient()[deriv.firstOrderDirection()];
00189 }
00190 }
00191
00192 void EdgeLocalizedBasis::evalOnTriangle(const Point& pt,
00193 const MultiIndex& deriv,
00194 Array<double>& result) const
00195 {
00196 ADReal x = ADReal(pt[0], 0, 2);
00197 ADReal y = ADReal(pt[1], 1, 2);
00198 ADReal one(1.0, 2);
00199 ADReal zero(0.0, 2);
00200
00201 Array<ADReal> tmp;
00202
00203 SUNDANCE_OUT(this->verb() > 3, "x=" << x.value() << " y="
00204 << y.value());
00205
00206 result.resize(3);
00207 tmp.resize(3);
00208
00209 bool onEdge2 = std::fabs(pt[1]) < 1.0e-14;
00210 bool onEdge0 = std::fabs(1.0-pt[0]-pt[1]) < 1.0e-14;
00211 bool onEdge1 = std::fabs(pt[0]) < 1.0e-14;
00212
00213 TEUCHOS_TEST_FOR_EXCEPTION(!(onEdge0 || onEdge1 || onEdge2),
00214 std::runtime_error,
00215 "EdgeLocalizedBasis should not be evaluated at points not on edges");
00216
00217 TEUCHOS_TEST_FOR_EXCEPTION((onEdge0 && onEdge1) || (onEdge1 && onEdge2)
00218 || (onEdge2 && onEdge0), std::runtime_error,
00219 "Ambiguous edge in EdgeLocalizedBasis::evalOnTriangle()");
00220
00221 if (onEdge0)
00222 {
00223 tmp[0] = one;
00224 tmp[1] = zero;
00225 tmp[2] = zero;
00226 }
00227 if (onEdge1)
00228 {
00229 tmp[0] = zero;
00230 tmp[1] = one;
00231 tmp[2] = zero;
00232 }
00233 if (onEdge2)
00234 {
00235 tmp[0] = zero;
00236 tmp[1] = zero;
00237 tmp[2] = one;
00238 }
00239
00240
00241 for (int i=0; i<tmp.length(); i++)
00242 {
00243 SUNDANCE_OUT(this->verb() > 3,
00244 "tmp[" << i << "]=" << tmp[i].value()
00245 << " grad=" << tmp[i].gradient());
00246 if (deriv.order()==0) result[i] = tmp[i].value();
00247 else
00248 result[i] = tmp[i].gradient()[deriv.firstOrderDirection()];
00249 }
00250
00251 }
00252
00253
00254
00255
00256 void EdgeLocalizedBasis::evalOnTet(const Point& pt,
00257 const MultiIndex& deriv,
00258 Array<double>& result) const
00259 {
00260 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00261 "EdgeLocalizedBasis::evalOnTet not implemented");
00262 }