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 "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