00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef EXBASICSENSOR_H
00014 #define EXBASICSENSOR_H
00015 #include <functional>
00016 #include <iterator>
00017 #include <cmath>
00018
00019 #include "shells/driverCC/MShell.h"
00020 #include "shells/driverCC/SVertexFunctors.h"
00021
00022
00023
00024 namespace cylExp {
00025 template<typename EXTR>
00026 class BasicSensor;
00027 }
00028
00029
00030 namespace cylExp {
00031
00032 template<typename EXTR>
00033 class BasicSensor {
00034 public:
00035 BasicSensor(std::ostream& os, shells::MShell * const mShell,
00036 const double sensorPosition[shells::SVertexCoordinate::numVar]);
00037 ~BasicSensor(){_os.flush();}
00038
00039 void printData(double timeStamp);
00040
00041 private:
00042 BasicSensor(const BasicSensor &);
00043 const BasicSensor & operator=(const BasicSensor &);
00044
00045 private:
00046 typedef std::vector<typename EXTR::DataType> _DataCont;
00047 typedef std::vector<shells::SVertexCoordinate::DataType> _CoordinateCont;
00048
00049
00050 static const unsigned _spaceDim;
00051 std::ostream& _os;
00052 shells::MShell * const _mShell;
00053 int _closestVertexID;
00054 shells::SVertexCoordinate::DataType _position[shells::SVertexCoordinate::numVar];
00055 };
00056 }
00057
00058
00059
00060 namespace cylExp {
00061
00062
00063 template<typename EXTR>
00064 const unsigned BasicSensor<EXTR>::_spaceDim = shells::SVertexCoordinate::numVar;
00065
00066
00067
00068 template<typename EXTR>
00069 BasicSensor<EXTR>::BasicSensor(std::ostream& os, shells::MShell * const mShell,
00070 const double sensorPosition[shells::SVertexCoordinate::numVar]):
00071 _os(os), _mShell(mShell)
00072 {
00073
00074 _os << std::scientific;
00075
00076
00077 _CoordinateCont coordinates;
00078 size_t numVertices = _mShell->numberOfVertices();
00079 coordinates.reserve(numVertices*_spaceDim);
00080
00081
00082 shells::SVertexCollector<std::back_insert_iterator<_CoordinateCont>,
00083 shells::SVertexCoordinate> getCoordinates;
00084 _mShell->iterateOverVertices(std::bind2nd(getCoordinates,
00085 std::back_inserter(coordinates)));
00086
00087 assert((numVertices*_spaceDim)==coordinates.size());
00088 assert(numVertices);
00089
00090
00091 double minDistanceSqr = 0.0;
00092 _closestVertexID = 0;
00093
00094 for (unsigned j=0; j<_spaceDim; ++j) {
00095 minDistanceSqr += (sensorPosition[j]-coordinates[j])*
00096 (sensorPosition[j]-coordinates[j]);
00097 }
00098
00099
00100 for (unsigned i=1; i<numVertices; ++i) {
00101 double distanceSqr = 0.0;
00102 for (unsigned j=0; j<_spaceDim; ++j) {
00103 distanceSqr += (sensorPosition[j]-coordinates[i*_spaceDim+j])*
00104 (sensorPosition[j]-coordinates[i*_spaceDim+j]);
00105 }
00106
00107 if (distanceSqr<minDistanceSqr) {
00108 minDistanceSqr = distanceSqr;
00109 _closestVertexID = i;
00110 }
00111 }
00112
00113 for (unsigned i=0; i<_spaceDim; ++i) {
00114 _position[i] = coordinates[_closestVertexID*_spaceDim+i];
00115 }
00116
00117 std::cout << "Attaching to vertex with GlobalD: " << _closestVertexID << " and position ";
00118 for (unsigned i=0; i<_spaceDim; ++i) {
00119 std::cout << _position[i] << " ";
00120 }
00121 std::cout << std::endl;
00122 }
00123
00124
00125
00126 template<typename EXTR>
00127 void BasicSensor<EXTR>::printData(double timeStamp)
00128 {
00129 const size_t numVar = EXTR::numVar;
00130 size_t numVertices = _mShell->numberOfVertices();
00131
00132
00133 _DataCont variable;
00134 variable.reserve(numVertices*numVar);
00135 shells::SVertexCollector<std::back_insert_iterator<_DataCont>, EXTR> getData;
00136 _mShell->iterateOverVertices(std::bind2nd(getData,
00137 std::back_inserter(variable)));
00138
00139 assert((numVertices*numVar)==variable.size());
00140
00141
00142 double disp[3];
00143 _os << timeStamp << " ";
00144
00145 for (unsigned i=0; i<numVar; ++i) {
00146 unsigned offSet = _closestVertexID*numVar+i;
00147 assert(offSet<variable.size());
00148 disp[i] = variable[offSet];
00149 _os << disp[i] << " ";
00150 }
00151
00152 double rad = std::sqrt(disp[0]*disp[0]+disp[1]*disp[1]);
00153 const double skp = disp[0]*_position[0]+disp[1]*_position[1];
00154
00155 if (skp<0.0) {
00156 rad = -rad;
00157 }
00158
00159 _os << rad << std::endl;
00160 }
00161 }
00162
00163 #endif