00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef BASICSENSORSPECIFIC_H
00014 #define BASICSENSORSPECIFIC_H
00015 #include "shells/driverCC/MShell.h"
00016 #include "shells/driverCC/SVertexFunctors.h"
00017 #include "shells/driverCC/SElementFunctors.h"
00018
00019 #include <functional>
00020 #include <iterator>
00021 #include <ostream>
00022 #include <cassert>
00023 #include <set>
00024 #include <vector>
00025 #include <algorithm>
00026
00027
00028 namespace shells {
00029 class MShell;
00030 }
00031
00032 namespace specific {
00033 template<typename EXTR>
00034 class BasicSensor;
00035 }
00036
00037
00038
00039 namespace {
00040 double distanceSqr(const double f[3], const double s[3]) {
00041 const double dx = f[0]-s[0];
00042 const double dy = f[1]-s[1];
00043 const double dz = f[2]-s[2];
00044 return (dx*dx+dy*dy+dz*dz);
00045 }
00046 }
00047
00048
00049 namespace specific {
00050
00051 template<typename EXTR>
00052 class BasicSensor {
00053 public:
00054 BasicSensor(std::ostream& os, shells::MShell * const mShell,
00055 const double sensorPosition[shells::SVertexCoordinate::numVar]);
00056 ~BasicSensor(){_os.flush();}
00057
00058 void printData(double timeStamp);
00059
00060 private:
00061 BasicSensor(const BasicSensor &);
00062 const BasicSensor & operator=(const BasicSensor &);
00063
00064 private:
00065 static const unsigned _spaceDim;
00066
00067 std::ostream& _os;
00068 shells::MShell * const _mShell;
00069 shells::SVertex * _closestVertex;
00070 };
00071
00072 }
00073
00074
00075
00076 namespace specific {
00077
00078 template<typename EXTR>
00079 BasicSensor<EXTR>::BasicSensor(std::ostream& os, shells::MShell * const mShell,
00080 const double sensorPosition[shells::SVertexCoordinate::numVar]):
00081 _os(os), _mShell(mShell)
00082 {
00083
00084 _os << std::scientific;
00085
00086
00087 typedef std::vector<shells::SVertex *> SVertexVec;
00088 SVertexVec vertices;
00089 typedef std::back_insert_iterator<SVertexVec> BinsVtxIt;
00090 BinsVtxIt verticesIt(vertices);
00091 shells::SElementTriangleVertices<BinsVtxIt> verticesCollect;
00092 mShell->iterateOverElements(std::bind2nd(verticesCollect, verticesIt), shells::MShell::active);
00093
00094 typedef std::vector<shells::SVertexCoordinate::DataType> CoordinateVec;
00095 CoordinateVec centers;
00096 typedef std::back_insert_iterator<CoordinateVec> BinsCoorIt;
00097 shells::SElementTriangleAverage<BinsCoorIt, shells::SVertexCoordinate> centerCollect;
00098 BinsCoorIt centersIt(centers);
00099 mShell->iterateOverElements(std::bind2nd(centerCollect, centersIt), shells::MShell::active);
00100
00101 const unsigned numElements = static_cast<unsigned>(centers.size()/_spaceDim);
00102
00103
00104 double minDistanceSqr = 1.e18;
00105 int clossestElementID=0;
00106
00107 assert(_spaceDim==3);
00108 for (unsigned i=0; i<numElements; ++i) {
00109 const double dc = distanceSqr(&(centers[i*_spaceDim]), sensorPosition);
00110 const double sameSideTest = centers[i*_spaceDim]*sensorPosition[0];
00111 if ((dc<minDistanceSqr)&&(sameSideTest>0.0)) {
00112 minDistanceSqr = dc;
00113 clossestElementID = i;
00114 }
00115 }
00116
00117
00118 const int vtxPerElem = shells::SElementTriangleVertices<BinsVtxIt>::numVert;
00119 shells::SVertex *vtx = vertices[clossestElementID*vtxPerElem];
00120 shells::SVertexCoordinate getCoordinate;
00121
00122 minDistanceSqr = 1.e18;
00123 _closestVertex = NULL;
00124
00125 for (unsigned i=0; i<vtxPerElem; ++i) {
00126 vtx = vertices[clossestElementID*vtxPerElem+i];
00127 double * vtxCoor = getCoordinate(vtx);
00128 const double dc = distanceSqr(vtxCoor, sensorPosition);
00129
00130 if (dc<minDistanceSqr) {
00131 minDistanceSqr = dc;
00132 _closestVertex = vtx;
00133 }
00134 }
00135
00136 assert(_closestVertex!=NULL);
00137
00138 shells::SVertexNodeID getId;
00139 const unsigned vertexId = *(getId(_closestVertex));
00140 _os << "Attaching to vertex with GlobalID " << vertexId << " an position ";
00141 double *vtxCoor = getCoordinate(_closestVertex);
00142
00143
00144 const double eps = 1.e-8;
00145 if (sensorPosition[0]<0.0) {
00146 _os << vtxCoor[0]- eps << " ";
00147 } else {
00148 _os << vtxCoor[0]+ eps << " ";
00149 }
00150
00151 _os << vtxCoor[1] << " " << vtxCoor[2];
00152
00153 _os << "\n Requested sensor position ";
00154 for (unsigned i=0; i<_spaceDim; ++i) {
00155 _os << sensorPosition[i] << " ";
00156 }
00157
00158 _os << std::endl;
00159 }
00160
00161
00162
00163 template<typename EXTR>
00164 void BasicSensor<EXTR>::printData(double timeStamp)
00165 {
00166 _os << timeStamp << " ";
00167
00168 EXTR dispFunc;
00169 assert(_closestVertex!=NULL);
00170 typename EXTR::DataType *disp = dispFunc(_closestVertex);
00171
00172 for (unsigned i=0; i<EXTR::numVar; ++i) {
00173 _os << disp[i] << " ";
00174 }
00175
00176 _os << std::endl;
00177 }
00178
00179 template<typename EXTR>
00180 const unsigned BasicSensor<EXTR>::_spaceDim = shells::SVertexCoordinate::numVar;
00181
00182 }
00183
00184 #endif