PDEOptPointData.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 
00043 #include "PDEOptPointData.hpp"
00044 #include "PlayaTabs.hpp"
00045 
00046 namespace Sundance
00047 {
00048 using namespace Teuchos;
00049 using namespace Playa;
00050 
00051 PointData::PointData(const Array<Point>& locations, 
00052   const Array<double>& values,
00053   const double& tol)
00054   : sensorVals_(), sensorLocations_()
00055 {
00056   init(locations, values, tol);
00057 }
00058 
00059 PointData::PointData(const XMLObject& xml,
00060   const Mesh& mesh)
00061   : sensorVals_(), sensorLocations_()
00062 {
00063   TEUCHOS_TEST_FOR_EXCEPTION(xml.getTag() != "PointData", RuntimeError,
00064     "expected tag PointData, found " << xml.getTag());
00065 
00066   double tol = xml.getRequiredDouble("tol");
00067 
00068   Array<Point> locations;
00069   Array<double> values;
00070 
00071   for (int i=0; i<xml.numChildren(); i++)
00072   {
00073     const XMLObject& pt = xml.getChild(i);
00074     values.append( pt.getRequiredDouble("value") );
00075     const string& ptStr = pt.getRequired("pt");
00076     Array<string> tok = StrUtils::stringTokenizer(ptStr);
00077     Point p;
00078     if (tok.size()==1)
00079     {
00080       p = Point(StrUtils::atof(tok[0]));
00081     }
00082     else if (tok.size()==2)
00083     {
00084       p = Point(StrUtils::atof(tok[0]),
00085         StrUtils::atof(tok[1]));
00086     }
00087     else if (tok.size()==3)
00088     {
00089       p = Point(StrUtils::atof(tok[0]),
00090         StrUtils::atof(tok[1]),
00091         StrUtils::atof(tok[2]));
00092     }
00093     locations.append(p);
00094   }
00095 
00096   locations = snapToMesh(mesh, locations);
00097   init(locations, values, tol);
00098 }
00099 
00100 
00101 void PointData::init(const Array<Point>& locations, 
00102   const Array<double>& values,
00103   const double& tol) 
00104 {
00105   TEUCHOS_TEST_FOR_EXCEPTION(locations.size() != values.size(), RuntimeError,
00106     "inconsistent measurement data: num locations = "
00107     << locations.size() << " but num readings = " 
00108     << values.size());
00109 
00110   TEUCHOS_TEST_FOR_EXCEPTION(locations.size() < 1, RuntimeError,
00111     "Empty data set in PointData ctor");
00112 
00113   /* make sure all points have the same dimension */
00114   int dim = locations[0].dim();
00115   for (int i=0; i<locations.size(); i++)
00116   {
00117     TEUCHOS_TEST_FOR_EXCEPTION(dim != locations[i].dim(), RuntimeError,
00118       "inconsistent point dimensions in PointData ctor. "
00119       "points are " << locations);
00120   }
00121 
00122   CellFilter allPoints = new DimensionalCellFilter(0);
00123   sensorLocations_ 
00124     = allPoints.subset(new PointDataCellPredicateFunctor(locations, tol));
00125 
00126   RefCountPtr<UserDefFunctor> op 
00127     = rcp(new PointDataExprFunctor(locations, values, tol));
00128 
00129 
00130 
00131   Expr x = new CoordExpr(0);
00132   Expr y = new CoordExpr(1);
00133   Expr z = new CoordExpr(2);
00134 
00135   Expr coords;
00136   if (dim==1) coords = x;
00137   else if (dim==2) coords = List(x, y);
00138   else coords = List(x, y, z);
00139 
00140   sensorVals_ = new UserDefOp(coords, op);
00141 }
00142 
00143 
00144 Array<Point> PointData::snapToMesh(const Mesh& mesh, 
00145   const Array<Point>& locations)
00146 {
00147   Array<Point> rtn(locations.size());
00148 
00149   for (int i=0; i<locations.size(); i++)
00150   {
00151     rtn[i] = nearestMeshPoint(mesh, locations[i]);
00152   }
00153   return rtn;
00154 }
00155 
00156 Point PointData::nearestMeshPoint(const Mesh& mesh, const Point& x)
00157 {
00158   double d2Min = 1.0e100;
00159   int iPt = 0;
00160   for (int i=0; i<mesh.numCells(0); i++)
00161   {
00162     const Point& p = mesh.nodePosition(i);
00163     Point dx = x - p;
00164     double d2 = dx*dx;
00165     if (d2 < d2Min)
00166     {
00167       d2Min = d2;
00168       iPt = i;
00169     }
00170   }
00171   return mesh.nodePosition(iPt);
00172 }
00173 
00174 
00175 
00176 PointDataExprFunctor::PointDataExprFunctor(const Array<Point>& locations, 
00177   const Array<double>& values,
00178   const double& tol)
00179   : PointwiseUserDefFunctor0("pointData", locations[0].dim(), 1), pointToValueMap_(tol),
00180     dim_(locations[0].dim())
00181 {
00182   Tabs tabs;
00183   for (int i=0; i<locations.size(); i++)
00184   {
00185     TEUCHOS_TEST_FOR_EXCEPTION(pointToValueMap_.find(locations[i]) != pointToValueMap_.end(),
00186       RuntimeError,
00187       "Data set contains duplicate point " << locations[i]
00188       << " to within tolerance "
00189       << tol << ". Points are "
00190       << locations);
00191     pointToValueMap_[locations[i]] = values[i];
00192 
00193     TEUCHOS_TEST_FOR_EXCEPTION(pointToValueMap_.find(locations[i]) == pointToValueMap_.end(),
00194       InternalError,
00195       "Bad map integrity in PointDataExprFunctor ctor: point "
00196       << locations[i] << " could not be recovered from map");
00197   }
00198 }
00199 
00200 void PointDataExprFunctor::eval0(const double* in, double* out) const
00201 {
00202   Point p;
00203   if (dim_==1) p = Point(in[0]);
00204   else if (dim_==2) p = Point(in[0], in[1]);
00205   else p = Point(in[0], in[1], in[2]);
00206   
00207   typedef std::map<Point, double, SloppyPointComparitor>::const_iterator iter;
00208   iter pos = pointToValueMap_.find(p);
00209   TEUCHOS_TEST_FOR_EXCEPTION(pos == pointToValueMap_.end(), RuntimeError,
00210     "Point " << p << " not found in list of data values");
00211 
00212 
00213   Tabs tabs;
00214 
00215   *out = pos->second;
00216 }
00217  
00218 
00219 PointDataCellPredicateFunctor
00220 ::PointDataCellPredicateFunctor(const Array<Point>& locations,
00221   const double& tol)
00222   : pointSet_(SloppyPointComparitor(tol))
00223 {
00224   for (int i=0; i<locations.size(); i++)
00225   {
00226     pointSet_.insert(locations[i]);
00227   }
00228 }
00229 
00230 bool PointDataCellPredicateFunctor::operator()(const Point& x) const
00231 {
00232   Tabs tabs;
00233   bool rtn = pointSet_.find(x) != pointSet_.end();
00234   return rtn;
00235 }
00236  
00237  
00238 bool SloppyPointComparitor::operator()(const Point& p1, const Point& p2) const
00239 {
00240   /* first, compare dimensions */
00241   if (p1.dim() < p2.dim()) return true;
00242   if (p2.dim() < p1.dim()) return false;
00243 
00244   /* if the dimensions are the same, do lexigraphic ordering on the
00245    * coordinate directions */
00246   for (int i=0; i<p1.dim(); i++)
00247   {
00248     if (p1[i] < p2[i] - tol_) return true;
00249     if (p1[i] > p2[i] + tol_) return false;
00250   }
00251   return false;
00252 }
00253 
00254 }

Site Contact