SundanceFourier.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
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 // ctor
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 /* ---------- evaluation on different cell types -------------- */
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 

Site Contact