SundanceAToCDensitySampler.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 "SundanceAToCDensitySampler.hpp"
00043 #include "SundanceOut.hpp"
00044 #include "PlayaTabs.hpp"
00045 #include "SundanceGeomUtils.hpp"
00046 #include "SundanceLagrange.hpp"
00047 #include "SundanceDiscreteFuncElement.hpp"
00048 #include <queue>
00049 
00050 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00051 #include "PlayaVectorImpl.hpp"
00052 #include "PlayaSimpleTransposedOpImpl.hpp"
00053 #endif
00054 
00055 using namespace Sundance;
00056 using namespace Teuchos;
00057 using namespace Playa;
00058 
00059 
00060 static Time& densitySamplingTimer() 
00061 {
00062   static RCP<Time> rtn 
00063     = TimeMonitor::getNewTimer("density sampling"); 
00064   return *rtn;
00065 }
00066 
00067 AToCDensitySampler::AToCDensitySampler(const AToCPointLocator& locator,
00068                                        const VectorType<double>& vecType)
00069   : discSpace_(locator.mesh(), new Lagrange(0), locator.subdomain(), vecType),
00070     dim_(locator.mesh().spatialDim()),
00071     mesh_(locator.mesh()),
00072     elemToVecIndexMap_(),
00073     elemWeights_(new DiscreteFunction(discSpace_, 0.0)),
00074     elemWeightVec_(),
00075     locator_(locator),
00076     isAxisymmetric_(false),
00077     origin_(),
00078     axis_()
00079 {
00080   init();
00081 }
00082 
00083 
00084 AToCDensitySampler::AToCDensitySampler(const AToCPointLocator& locator,
00085                                        const std::vector<double>& origin,
00086                                        const std::vector<double>& rotationalAxis,
00087                                        const VectorType<double>& vecType)
00088   : discSpace_(locator.mesh(), new Lagrange(0), locator.subdomain(), vecType),
00089     dim_(locator.mesh().spatialDim()),
00090     mesh_(locator.mesh()),
00091     elemToVecIndexMap_(),
00092     elemWeights_(new DiscreteFunction(discSpace_, 0.0)),
00093     elemWeightVec_(),
00094     locator_(locator),
00095     isAxisymmetric_(true),
00096     origin_(vec2point(origin)),
00097     axis_(normPoint(vec2point(rotationalAxis)))
00098 {
00099   init();
00100 }
00101 
00102 
00103 
00104 void AToCDensitySampler::init()
00105 {
00106   const CellFilter& domain = discSpace_.cellFilters(0);
00107 
00108   elemWeightVec_ = DiscreteFunction::discFunc(elemWeights_)->getVector();
00109 
00110   elemToVecIndexMap_ = rcp(new Array<int>(mesh_.numCells(dim_), -1));
00111 
00112   Array<int>& a = *elemToVecIndexMap_;
00113 
00114   CellSet cells = domain.getCells(mesh_);
00115 
00116   Array<int> cellLID;
00117   cellLID.reserve(mesh_.numCells(dim_));
00118 
00119   for (CellIterator i=cells.begin(); i!=cells.end(); i++)
00120     {
00121       cellLID.append(*i);
00122     }
00123 
00124   const RCP<DOFMapBase>& dofMap = discSpace_.map();
00125 
00126   Set<int> funcs = makeSet(0);
00127   Array<Array<int> > dofs;
00128   Array<int> nNodes;
00129   dofMap->getDOFsForCellBatch(dim_, cellLID, funcs, dofs, nNodes,0);
00130   
00131   const Array<int>& dofs0 = dofs[0];
00132   for (int c=0; c<cellLID.size(); c++)
00133     {
00134       int vecIndex = dofs0[c];
00135       int lid = cellLID[c];
00136       a[lid] = vecIndex;
00137       double vol = volume(mesh_, dim_, lid);
00138       if (isAxisymmetric_)
00139         {
00140           Point xCell = mesh_.centroid(dim_, lid) - origin_;
00141           double dPerp = ::sqrt(xCell*xCell - (xCell*axis_)*(xCell*axis_));
00142           vol = vol * dPerp;
00143         }
00144       elemWeightVec_[vecIndex] = vol;
00145     }
00146 }
00147 
00148 Point AToCDensitySampler::vec2point(const std::vector<double>& x) const
00149 {
00150   if (x.size()==1) return Point(x[0]);
00151   else if (x.size()==2U) return Point(x[0], x[1]);
00152   else if (x.size()==3U) return Point(x[0], x[1], x[2]);
00153   TEUCHOS_TEST_FOR_EXCEPT(x.size() < 1 || x.size() > 3U);
00154   return Point();
00155 }
00156 
00157 Point AToCDensitySampler::normPoint(const Point& x) const
00158 {
00159   return x/sqrt(x*x);
00160 }
00161 
00162 
00163 Expr AToCDensitySampler::sample(const std::vector<double>& positions,
00164                                 const double& particleWeight) const 
00165 {
00166   TimeMonitor timer(densitySamplingTimer());
00167 
00168   TEUCHOS_TEST_FOR_EXCEPTION(positions.size() % dim_ != 0, std::runtime_error,
00169                      "vector of coordinates should by an integer multiple "
00170                      "of the spatial dimension");
00171 
00172   Expr rtn = new DiscreteFunction(discSpace_, 0.0);
00173   Vector<double> density = DiscreteFunction::discFunc(rtn)->getVector();
00174 
00175   int nPts = positions.size() / dim_;
00176 
00177   for (int i=0; i<nPts; i++)
00178     {
00179       const double* x = &(positions[dim_*i]);
00180 
00181       int guess = locator_.guessCell(x);
00182 
00183       TEUCHOS_TEST_FOR_EXCEPTION(guess < 0, std::runtime_error, "particle #" << i << " position="
00184                          << AToCPointLocator::makePoint(dim_, x) 
00185                          << " is out of search grid");
00186 
00187       int cellLID = locator_.findEnclosingCell(guess, x);
00188 
00189       int vecIndex = (*elemToVecIndexMap_)[cellLID];
00190       double vol = elemWeightVec_[vecIndex];
00191       density[vecIndex] += particleWeight/vol;
00192     }
00193 
00194   return rtn;
00195 }
00196 
00197 
00198 Expr AToCDensitySampler::resetCounts() const 
00199 {
00200   Expr rtn = new DiscreteFunction(discSpace_, 0.0);
00201 
00202   return rtn;
00203 }
00204 
00205 void AToCDensitySampler::addToCounts(const std::vector<double>& positions,
00206                                      const double& particleWeight,
00207                                      Expr density) const 
00208 {
00209   TimeMonitor timer(densitySamplingTimer());
00210 
00211   TEUCHOS_TEST_FOR_EXCEPTION(positions.size() % dim_ != 0, std::runtime_error,
00212                      "vector of coordinates should by an integer multiple "
00213                      "of the spatial dimension");
00214 
00215   Vector<double> vec = DiscreteFunction::discFunc(density)->getVector();
00216 
00217   int nPts = positions.size() / dim_;
00218 
00219   for (int i=0; i<nPts; i++)
00220     {
00221       const double* x = &(positions[dim_*i]);
00222 
00223       int guess = locator_.guessCell(x);
00224 
00225       TEUCHOS_TEST_FOR_EXCEPTION(guess < 0, std::runtime_error, "particle #" << i << " position="
00226                          << AToCPointLocator::makePoint(dim_, x) 
00227                          << " is out of search grid");
00228 
00229       int cellLID = locator_.findEnclosingCell(guess, x);
00230 
00231       int vecIndex = (*elemToVecIndexMap_)[cellLID];
00232       double vol = elemWeightVec_[vecIndex];
00233       vec[vecIndex] += particleWeight/vol;
00234     }
00235 }
00236 
00237 

Site Contact