SundanceLinearEigenproblem.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 "SundanceLinearEigenproblem.hpp"
00043 #include "SundanceOut.hpp"
00044 #include "PlayaTabs.hpp"
00045 #include "SundanceTestFunction.hpp"
00046 #include "SundanceUnknownFunction.hpp"
00047 #include "SundanceEssentialBC.hpp"
00048 #include "SundanceIntegral.hpp"
00049 #include "SundanceListExpr.hpp"
00050 #include "SundanceZeroExpr.hpp"
00051 #include "SundanceEquationSet.hpp"
00052 #include "SundanceQuadratureFamily.hpp"
00053 #include "SundanceAssembler.hpp"
00054 #include "SundanceMaximalCellFilter.hpp"
00055 #include "SundanceGaussianQuadrature.hpp"
00056 
00057 #include "PlayaLinearCombinationDecl.hpp"
00058 #include "PlayaLinearCombinationImpl.hpp"
00059 #include "PlayaLinearOperatorDecl.hpp"
00060 #include "PlayaVectorDecl.hpp"
00061 #include "PlayaSimpleDiagonalOpDecl.hpp"
00062 
00063 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00064 #include "PlayaVectorImpl.hpp"
00065 #include "PlayaLinearCombinationImpl.hpp"
00066 #include "PlayaLinearOperatorImpl.hpp"
00067 #include "PlayaSimpleDiagonalOpImpl.hpp"
00068 #endif
00069 
00070 using namespace Sundance;
00071 using namespace Sundance;
00072 using namespace Sundance;
00073 using namespace Sundance;
00074 using namespace Teuchos;
00075 using namespace Playa;
00076 using namespace PlayaExprTemplates;
00077 
00078 static Time& normalizationTimer() 
00079 {
00080   static RCP<Time> rtn 
00081     = TimeMonitor::getNewTimer("Eigenfunction normalization"); 
00082   return *rtn;
00083 }
00084 
00085 static Time& makeEigensystemTimer() 
00086 {
00087   static RCP<Time> rtn 
00088     = TimeMonitor::getNewTimer("Building eigensystem stiffness matrix"); 
00089   return *rtn;
00090 }
00091 
00092 LinearEigenproblem::LinearEigenproblem(
00093   const Mesh& mesh, const Expr& eqn,
00094   const Expr& v, const Expr& u,
00095   const VectorType<double>& vecType)
00096   : lumpMass_(false),
00097     kProb_(),
00098     mProb_(),
00099     M_(),
00100     MUnlumped_(),
00101     discSpace_()
00102 {
00103   Expr empty;
00104   
00105   kProb_ = LinearProblem(mesh, eqn, empty, v, u, vecType);
00106   discSpace_ = *(kProb_.solnSpace()[0]);
00107 }    
00108 
00109 LinearEigenproblem::LinearEigenproblem(
00110   const Mesh& mesh, const Expr& eqn,
00111   const Expr& v, const Expr& u,
00112   const VectorType<double>& vecType,
00113   bool lumpedMass)
00114   : lumpMass_(lumpedMass),
00115     kProb_(),
00116     mProb_(),
00117     M_(),
00118     MUnlumped_(),
00119     discSpace_()
00120 {
00121   Expr empty;
00122   
00123   kProb_ = LinearProblem(mesh, eqn, empty, v, u, vecType);
00124   mProb_ = makeMassProb(mesh, empty, v, u, vecType);
00125   discSpace_ = *(kProb_.solnSpace()[0]);
00126   MUnlumped_ = mProb_.getOperator();
00127   if (lumpMass_)
00128   {
00129     M_ = lumpedOperator(MUnlumped_);
00130   }
00131   else
00132   {
00133     M_ = MUnlumped_;
00134   }
00135 }    
00136 
00137 
00138 LinearEigenproblem::LinearEigenproblem(
00139   const Mesh& mesh, const Expr& eqn,
00140   const Expr& massExpr,
00141   const Expr& v, const Expr& u,
00142   const VectorType<double>& vecType,
00143   bool lumpedMass)
00144   : lumpMass_(lumpedMass),
00145     kProb_(),
00146     mProb_(),
00147     M_(),
00148     MUnlumped_(),
00149     discSpace_()
00150 {
00151   Expr bc;
00152   kProb_ = LinearProblem(mesh, eqn, bc, v, u, vecType);
00153   mProb_ = makeMassProb(mesh, massExpr, v, u, vecType);
00154   discSpace_ = *(kProb_.solnSpace()[0]);
00155 
00156   MUnlumped_ = mProb_.getOperator();
00157   if (lumpMass_)
00158   {
00159     M_ = lumpedOperator(MUnlumped_);
00160   }
00161   else
00162   {
00163     M_ = MUnlumped_;
00164   }
00165   
00166 }    
00167 
00168 LinearProblem LinearEigenproblem::makeMassProb(
00169   const Mesh& mesh,
00170   const Expr& massExpr,
00171   const Expr& v, const Expr& u,
00172   const VectorType<double>& vecType) const
00173 {
00174   Expr eqn;
00175   
00176   CellFilter interior = new MaximalCellFilter();
00177   QuadratureFamily quad = new GaussianQuadrature( 4 );
00178   if (massExpr.ptr().get()==0)
00179   {
00180     eqn = Integral(interior, v*u, quad);
00181   }
00182   else
00183   {
00184     eqn = Integral(interior, massExpr, quad);
00185   }
00186   Expr bc;
00187   LinearProblem rtn(mesh, eqn, bc, v, u, vecType);
00188   return rtn;
00189 }
00190 
00191 
00192 Array<Expr> LinearEigenproblem::makeEigenfunctions(
00193   Array<Vector<double> >& ev) const 
00194 {
00195   TimeMonitor timer(normalizationTimer());
00196 
00197   Array<Expr> x(ev.size());
00198   CellFilter interior = new MaximalCellFilter();
00199   QuadratureFamily q = new GaussianQuadrature(2);
00200   for (int i=0; i<ev.size(); i++) 
00201   {
00202     x[i] = new DiscreteFunction(discSpace_, ev[i], "ev[" + Teuchos::toString(i)+"]");
00203     double N = 1.0;
00204     if (MUnlumped_.ptr().get())
00205     {
00206       N = ev[i] * (MUnlumped_ * ev[i]);
00207     }
00208     else
00209     {
00210       N = evaluateIntegral(discSpace_.mesh(), 
00211         Integral(interior, x[i]*x[i], q));
00212     }
00213     ev[i].scale(1.0/sqrt(N));
00214   }
00215 
00216   return x;
00217 }
00218 
00219 
00220 LinearOperator<double> 
00221 LinearEigenproblem::lumpedOperator(const LinearOperator<double>& M) const 
00222 {
00223   Vector<double> ones = M.domain().createMember();
00224   ones.setToConstant(1.0);
00225   Vector<double> m = M * ones;
00226   LinearOperator<double> rtn = diagonalOperator(m);
00227 
00228   return rtn;
00229 }
00230 
00231 
00232 Eigensolution LinearEigenproblem::solve(const Eigensolver<double>& solver) const 
00233 {
00234   Array<std::complex<double> > ew;
00235   Array<Vector<double> > ev;
00236 
00237   LinearOperator<double> K;
00238   {
00239     TimeMonitor timer(makeEigensystemTimer());
00240     K = kProb_.getOperator();
00241   }
00242   
00243   solver.solve(K, M_, ev, ew);
00244 
00245   Array<Expr> eigenfuncs = makeEigenfunctions(ev);
00246 
00247   return Eigensolution(eigenfuncs, ew);
00248 }
00249 

Site Contact