00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef BASICSENSOR_H
00014 #define BASICSENSOR_H
00015 #include "../driverCC/MShell.h"
00016 #include "../driverCC/SVertexFunctors.h"
00017 #include "../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 utiliities {
00033 template<typename EXTR>
00034 class BasicSensor;
00035 }
00036
00037
00038 namespace utilities {
00039
00040 template<typename EXTR>
00041 class BasicSensor {
00042 public:
00043 BasicSensor(std::ostream& os, shells::MShell * const mShell,
00044 const double sensorPosition[shells::SVertexCoordinate::numVar]);
00045 ~BasicSensor(){_os.flush();}
00046
00047 void printData(double timeStamp);
00048
00049 private:
00050 BasicSensor(const BasicSensor &);
00051 const BasicSensor & operator=(const BasicSensor &);
00052
00053 private:
00054 typedef std::vector<typename EXTR::DataType> _DataCont;
00055 typedef std::vector<shells::SVertexCoordinate::DataType> _CoordinateCont;
00056
00057 static const unsigned _spaceDim;
00058
00059 std::ostream& _os;
00060 shells::MShell * const _mShell;
00061 shells::SVertex * _closestVertex;
00062 };
00063
00064 }
00065
00066
00067
00068 namespace utilities {
00069
00070 template<typename EXTR>
00071 BasicSensor<EXTR>::BasicSensor(std::ostream& os, shells::MShell * const mShell,
00072 const double sensorPosition[shells::SVertexCoordinate::numVar]):
00073 _os(os), _mShell(mShell)
00074 {
00075
00076 _os << std::scientific;
00077
00078
00079 typedef std::set<shells::SVertex *> SVertexSet;
00080 SVertexSet vertexSet;
00081 std::insert_iterator<SVertexSet> inserter(vertexSet, vertexSet.begin());
00082 shells::SElementTriangleVertices<std::insert_iterator<SVertexSet> > op;
00083 mShell->iterateOverElements(std::bind2nd(op, inserter), shells::MShell::active);
00084 const unsigned numVertices = vertexSet.size();
00085
00086
00087 _CoordinateCont coordinates;
00088 coordinates.reserve(numVertices*_spaceDim);
00089
00090 shells::SVertexCollector<std::back_insert_iterator<_CoordinateCont>,
00091 shells::SVertexCoordinate> getCoordinates;
00092
00093 std::for_each(vertexSet.begin(), vertexSet.end(),
00094 std::bind2nd(getCoordinates, std::back_inserter(coordinates)));
00095
00096 assert((numVertices*_spaceDim)==coordinates.size());
00097
00098
00099 double minDistanceSqr = 0.0;
00100 unsigned closestVertexID = 0;
00101
00102 for (unsigned j=0; j<_spaceDim; ++j) {
00103 minDistanceSqr += (sensorPosition[j]-coordinates[j])*
00104 (sensorPosition[j]-coordinates[j]);
00105 }
00106
00107
00108 for (unsigned i=1; i<numVertices; ++i) {
00109 double distanceSqr = 0.0;
00110 for (unsigned j=0; j<_spaceDim; ++j) {
00111 distanceSqr += (sensorPosition[j]-coordinates[i*_spaceDim+j])*
00112 (sensorPosition[j]-coordinates[i*_spaceDim+j]);
00113 }
00114
00115 if (distanceSqr<minDistanceSqr) {
00116 minDistanceSqr = distanceSqr;
00117 closestVertexID = i;
00118 }
00119 }
00120
00121 SVertexSet::iterator itc = vertexSet.begin();
00122 std::advance(itc, closestVertexID);
00123 _closestVertex = *itc;
00124
00125 _os << "Attaching to vertex with GlobalD " << closestVertexID << " and position ";
00126 for (unsigned i=0; i<_spaceDim; ++i) {
00127 _os << coordinates[closestVertexID*_spaceDim+i] << " ";
00128 }
00129
00130 _os << "\nRequested sensor position ";
00131 for (unsigned i=0; i<_spaceDim; ++i) {
00132 _os << sensorPosition[i] << " ";
00133 }
00134
00135 _os << std::endl;
00136 }
00137
00138
00139
00140 template<typename EXTR>
00141 void BasicSensor<EXTR>::printData(double timeStamp)
00142 {
00143 _os << timeStamp << " ";
00144
00145 EXTR dispFunc;
00146 assert(_closestVertex!=NULL);
00147 typename EXTR::DataType *disp = dispFunc(_closestVertex);
00148
00149 for (unsigned i=0; i<EXTR::numVar; ++i) {
00150 _os << disp[i] << " ";
00151 }
00152
00153 _os << std::endl;
00154 }
00155
00156 template<typename EXTR>
00157 const unsigned BasicSensor<EXTR>::_spaceDim = shells::SVertexCoordinate::numVar;
00158
00159 }
00160
00161 #endif