vtf-logo

fsi/sfc-amroc/TubeCJBurnFrac/src/BasicSensorSpecific.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00004 // 
00005 //                                   Fehmi Cirak
00006 //                        California Institute of Technology
00007 //                           (C) 2005 All Rights Reserved
00008 //
00009 // <LicenseText>
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 // helper
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 // implementations
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         // scientific format for output
00084         _os << std::scientific;
00085 
00086         // find triangle vertices - this also works for fracture
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         // find clossest element center
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         // find the clossest Vertex
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         // following trick ensures that exctract disp works properly
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

Generated on Fri Aug 24 13:02:34 2007 for Virtual Test Facility Coupled Applications by  doxygen 1.4.7