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 "SundanceFourier.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 Teuchos;
00052 using std::endl;
00053
00054
00055 Fourier::Fourier(int N) : N_(N)
00056 {}
00057
00058 bool Fourier::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 default:
00075 return false;
00076 }
00077 }
00078
00079 void Fourier::print(std::ostream& os) const
00080 {
00081 os << "Fourier(" << N_ << ")";
00082 }
00083
00084 int Fourier::nReferenceDOFsWithoutFacets(
00085 const CellType& maximalCellType,
00086 const CellType& cellType
00087 ) const
00088 {
00089 switch(cellType)
00090 {
00091 case PointCell:
00092 return 0;
00093 case LineCell:
00094 return 2*N_+1;
00095 default:
00096 TEUCHOS_TEST_FOR_EXCEPTION( true , std::invalid_argument , "illegal combination of cell type and maximal cell type" );
00097 return -1;
00098 }
00099 }
00100
00101 Array<int> Fourier::makeRange(int low, int high)
00102 {
00103 if (high < low) return Array<int>();
00104
00105 Array<int> rtn(high-low+1);
00106 for (int i=0; i<rtn.length(); i++) rtn[i] = low+i;
00107 return rtn;
00108 }
00109
00110 void Fourier::getReferenceDOFs(
00111 const CellType& maximalCellType,
00112 const CellType& cellType,
00113 Array<Array<Array<int> > >& dofs) const
00114 {
00115 typedef Array<int> Aint;
00116
00117 switch(cellType)
00118 {
00119 case LineCell:
00120 {
00121 dofs.resize(2);
00122 dofs[0] = Array<Array<int> >();
00123 dofs[1] = tuple(makeRange(0, 2*N_));
00124 }
00125 break;
00126 default:
00127 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Cell type "
00128 << cellType << " not implemented in Fourier basis");
00129 }
00130 }
00131
00132
00133 void Fourier::refEval(
00134 const CellType& cellType,
00135 const Array<Point>& pts,
00136 const SpatialDerivSpecifier& sds,
00137 Array<Array<Array<double> > >& result,
00138 int verbosity) const
00139 {
00140 TEUCHOS_TEST_FOR_EXCEPTION(!(sds.isPartial() || sds.isIdentity()),
00141 std::runtime_error,
00142 "cannot evaluate spatial derivative " << sds << " on Fourier basis");
00143 const MultiIndex& deriv = sds.mi();
00144 typedef Array<double> Adouble;
00145 result.resize(1);
00146 result[0].resize(pts.length());
00147
00148 switch(cellType)
00149 {
00150 case LineCell:
00151 for (int i=0; i<pts.length(); i++)
00152 {
00153 evalOnLine(pts[i], deriv, result[0][i]);
00154 }
00155 break;
00156 default:
00157 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00158 "Fourier::refEval() unimplemented for cell type "
00159 << cellType);
00160 }
00161 }
00162
00163
00164
00165 void Fourier::evalOnLine(const Point& pt,
00166 const MultiIndex& deriv,
00167 Array<double>& result) const
00168 {
00169 result.resize(2*N_+1);
00170 double x = pt[0];
00171 const double pi = 4.0*atan(1.0);
00172
00173 if (deriv.order()==0)
00174 {
00175 result[0] = 1.0;
00176 for (int n=1; n<=N_; n++)
00177 {
00178 result[2*n-1]=::cos(2.0*pi*n*x);
00179 result[2*n]=::sin(2.0*pi*n*x);
00180 }
00181 }
00182 else if (deriv.order()==1)
00183 {
00184 result[0] = 0.0;
00185 for (int n=1; n<=N_; n++)
00186 {
00187 result[2*n-1]=-2.0*pi*n*::sin(2.0*pi*n*x);
00188 result[2*n]=2.0*n*pi*::cos(2.0*pi*n*x);
00189 }
00190 }
00191 else
00192 {
00193 TEUCHOS_TEST_FOR_EXCEPT(true);
00194 }
00195
00196 Out::os() << "quad point=" << x << endl;
00197 Out::os() << "bas: " << result << endl;
00198 }
00199