Go to the documentation of this file.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 "SundanceCToAInterpolator.hpp"
00043 #include "SundanceOut.hpp"
00044 #include "PlayaTabs.hpp"
00045 #include "SundanceLagrange.hpp"
00046 #include "SundanceDiscreteFuncElement.hpp"
00047
00048 using namespace Sundance;
00049 using namespace Sundance;
00050 using namespace Sundance;
00051 using namespace Sundance;
00052 using namespace Sundance;
00053 using namespace Sundance;
00054 using namespace Sundance;
00055 using namespace Teuchos;
00056 using namespace Playa;
00057
00058
00059 static Time& particleInterpolationTimer()
00060 {
00061 static RCP<Time> rtn
00062 = TimeMonitor::getNewTimer("particle interpolation");
00063 return *rtn;
00064 }
00065
00066 CToAInterpolator::CToAInterpolator(const AToCPointLocator& locator,
00067 const Expr& field)
00068 : dim_(locator.mesh().spatialDim()),
00069 nFacets_(dim_+1),
00070 rangeDim_(-1),
00071 elemToVecValuesMap_(),
00072 locator_(locator)
00073 {
00074 updateField(field);
00075 }
00076
00077 void CToAInterpolator::updateField(const Expr& field)
00078 {
00079 int newRangeDim = field.size();
00080 if (newRangeDim != rangeDim_)
00081 {
00082 rangeDim_ = newRangeDim;
00083 elemToVecValuesMap_
00084 = rcp(new Array<double>(rangeDim_ * locator_.mesh().numCells(dim_) * nFacets_));
00085 }
00086
00087 int nCells = locator_.mesh().numCells(dim_);
00088
00089 const DiscreteFunction* df = DiscreteFunction::discFunc(field);
00090 TEUCHOS_TEST_FOR_EXCEPTION(df == 0, std::runtime_error,
00091 "discrete function expected in "
00092 "CToAInterpolator::updateField()");
00093
00094 Vector<double> vec = df->getVector();
00095
00096 Array<int> cellLID(nCells);
00097 for (int i=0; i<nCells; i++)
00098 {
00099 cellLID[i] = i;
00100 }
00101 Array<Array<int> > dofs;
00102 Array<int> nNodes;
00103 Set<int> funcs;
00104 for (int i=0; i<rangeDim_; i++) funcs.put(i);
00105
00106
00107 df->map()->getDOFsForCellBatch(dim_, cellLID, funcs, dofs, nNodes,0);
00108
00109 const Array<int>& dofs0 = dofs[0];
00110
00111 for (int c=0; c<cellLID.size(); c++)
00112 {
00113 for (int n=0; n<nFacets_; n++)
00114 {
00115 for (int f=0; f<rangeDim_; f++)
00116 {
00117 int dof = dofs0[(c*rangeDim_ + f)*nFacets_ + n];
00118 (*elemToVecValuesMap_)[(cellLID[c]*nFacets_ + n)*rangeDim_ + f]
00119 = vec[dof];
00120 }
00121 }
00122 }
00123 }
00124
00125
00126 void CToAInterpolator::interpolate(const Teuchos::Array<double>& positions,
00127 Teuchos::Array<double>& results) const
00128 {
00129 TimeMonitor timer(particleInterpolationTimer());
00130
00131 TEUCHOS_TEST_FOR_EXCEPTION(positions.size() % dim_ != 0, std::runtime_error,
00132 "vector of coordinates should by an integer multiple "
00133 "of the spatial dimension");
00134
00135 int nPts = positions.size() / dim_;
00136
00137 results.resize(rangeDim_ * nPts);
00138
00139 Array<double> xLocal(dim_);
00140
00141 for (int i=0; i<nPts; i++)
00142 {
00143 const double* x = &(positions[dim_*i]);
00144
00145 int guess = locator_.guessCell(x);
00146
00147 TEUCHOS_TEST_FOR_EXCEPTION(guess < 0, std::runtime_error, "particle position "
00148 << x << " out of search grid");
00149
00150
00151 int cellLID = locator_.findEnclosingCell(guess, x, &(xLocal[0]));
00152
00153 if (dim_==2)
00154 {
00155 double s = xLocal[0];
00156 double t = xLocal[1];
00157 Array<double> phi(nFacets_);
00158 phi[0] = 1.0-s-t;
00159 phi[1] = s;
00160 phi[2] = t;
00161 for (int f=0; f<rangeDim_; f++) results[rangeDim_*i+f] = 0.0;
00162 for (int n=0; n<nFacets_; n++)
00163 {
00164 for (int f=0; f<rangeDim_; f++)
00165 {
00166 results[rangeDim_*i+f] += phi[n]*(*elemToVecValuesMap_)[(cellLID*nFacets_ + n)*rangeDim_ + f];
00167 }
00168 }
00169 }
00170 }
00171
00172 }
00173