PlayaPoissonBoltzmannOp.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                 Playa: Programmable Linear Algebra
00005 //                 Copyright 2012 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 "PlayaPoissonBoltzmannOp.hpp"
00043 #include "PlayaTabs.hpp"
00044 
00045 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00046 #include "PlayaVectorImpl.hpp"
00047 #include "PlayaLinearOperatorImpl.hpp"
00048 #endif
00049 
00050 using namespace Teuchos;
00051 
00052 namespace Playa
00053 {
00054 
00055 PoissonBoltzmannOp::PoissonBoltzmannOp(int nLocal, const VectorType<double>& vecType)
00056   : NonlinearOperatorBase<double>(), J_(nLocal, vecType), importer_(),
00057     uLeftBC_(0.0), uRightBC_(2.0*log(cosh(1.0/sqrt(2.0))))
00058 {
00059   setDomainAndRange(J_.domain(), J_.range());
00060 
00061   int rank = MPIComm::world().getRank();
00062   int nProc = MPIComm::world().getNProc();
00063   if (nProc > 1)
00064   {
00065     Array<int> ghosts;
00066     int low = J_.domain().baseGlobalNaturalIndex();
00067     int high = low + J_.domain().numLocalElements();
00068     if (rank != nProc - 1)
00069     {
00070       ghosts.append(high);
00071     }
00072     if (rank != 0) 
00073     {
00074       ghosts.append(low-1);
00075     }
00076 
00077     importer_ = vecType.createGhostImporter(J_.domain(), ghosts.size(), &(ghosts[0]));
00078   }
00079   else
00080   {
00081     importer_ = vecType.createGhostImporter(J_.domain(), 0, 0);
00082   }
00083 }
00084 
00085 Vector<double> PoissonBoltzmannOp::getInitialGuess() const
00086 {
00087   Vector<double> rtn = J_.domain().createMember();
00088 
00089   rtn.setToConstant(0.5);
00090 
00091   return rtn;
00092 }
00093 
00094 
00095 LinearOperator<double> 
00096 PoissonBoltzmannOp::computeJacobianAndFunction(Vector<double>& functionValue) const 
00097 {
00098   Tabs tab;
00099   Out::root() << tab << "in PBOp::computeJacAndVec" << std::endl;
00100   Vector<double> x = currentEvalPt() ;
00101   Out::root() << tab << "eval pt = " << std::endl;
00102   Out::os() << x << std::endl;
00103   J_.setEvalPoint(x);
00104   
00105 
00106   RCP<GhostView<double> > u;
00107   Out::root() << tab << "importing view" << std::endl;
00108   importer_->importView(currentEvalPt(), u);
00109   Out::root() << tab << "done importing view" << std::endl;
00110   int low = J_.domain().baseGlobalNaturalIndex();
00111   int high = low + J_.domain().numLocalElements();
00112   Out::os() << tab << "my indices are: " << low << ", " << high-1 << std::endl;
00113 
00114   functionValue = J_.range().createMember();
00115   double h= J_.h();
00116 
00117   for (int r=low; r<high; r++)
00118   {
00119     Tabs tab1;
00120     double u_i = u->getElement(r);
00121     double f = 0.0;
00122     if (r==0) 
00123     {
00124       f = u_i - uLeftBC_;
00125     }
00126     else if (r==J_.domain().dim()-1)
00127     {
00128       f = u_i - uRightBC_;
00129     }
00130     else
00131     {
00132       double u_plus = u->getElement(r+1);
00133       double u_minus = u->getElement(r-1);
00134       f = (u_plus + u_minus - 2.0*u_i)/h/h - exp(-u_i);
00135     }
00136     functionValue[r-low] = f;
00137   }
00138 
00139   Out::root() << tab << "done PBOp::computeJacAndVec" << std::endl;
00140   return J_.getOp();
00141 }
00142 
00143 Vector<double> PoissonBoltzmannOp::exactSoln() const
00144 {
00145   Tabs tab;
00146   Out::root() << tab << "in PBOp::exactSoln" << std::endl;
00147   Vector<double> rtn = J_.domain().createMember();
00148 
00149   int low = J_.domain().baseGlobalNaturalIndex();
00150   int high = low + J_.domain().numLocalElements();
00151 
00152   double h= J_.h();
00153   
00154   for (int r=low; r<high; r++)
00155   {
00156     double x = r*h;
00157     double u = 2.0*log(cosh(x/sqrt(2.0)));
00158     rtn[r-low] = u;
00159   }
00160 
00161   Out::os() << tab << "done PBOp::exactSoln" << std::endl;
00162   return rtn;
00163 }
00164 
00165 }

Site Contact