vtf-logo

shells/driverCC/SElementFunctors.h

Go to the documentation of this file.
00001 // -*- C++ -*- 
00002 //
00003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00004 //
00005 //                                   Fehmi Cirak
00006 //                        California Institute of Technology
00007 //                           (C) 2004 All Rights Reserved
00008 //
00009 // <LicenseText>
00010 //
00011 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00012 //
00013 #ifndef SELEMENTFUNCTORS_H
00014 #define SELEMENTFUNCTORS_H
00015 #include "../fem/definitions.h"
00016 #include "../fem/selement.h"
00017 #include "../fem/internalStorage.h"
00018 
00019 #include "SVertexFunctors.h"
00020 
00021 #include <vector>
00022 #include <functional>
00023 
00024 
00025 namespace shells {
00026     template<typename Inserter>
00027     struct SElementTriangleVertices;
00028     template<typename Inserter, typename OP>
00029     struct SElementTriangleCollector;
00030     template<typename Inserter, typename OP>
00031     struct SElementTriangleAverage;
00032 
00033     template <typename Inserter>
00034     struct SELementInternalDataAverage;
00035     template <typename Inserter>
00036     struct SELementInternalDataCollect;
00037     template <typename IT>
00038     class SELementInternalDataDistrib;
00039     
00040     struct SElementOneNeighborhood;
00041 }
00042 
00043 
00044 namespace shells {
00045 
00046 template<typename Inserter>
00047 struct SElementTriangleVertices  : 
00048     public std::binary_function<shells::SElement *, Inserter, void> {
00049 public:
00050     // insert the three pointers to the triangle vertices into inserter
00051 
00052 #if defined(_AIX)    
00053     static const std::size_t numVert; // IBM compiler workaround
00054 #else
00055     static const std::size_t numVert = 3; // each element has three vertices
00056 #endif
00057 
00058     void operator()(shells::SElement *element, Inserter ins) const 
00059         {
00060             for (unsigned i=0; i<numVert; ++i) {
00061                 *ins++ = element->vtx[i];
00062             }
00063         }
00064 };
00065 
00066 #if defined(_AIX)
00067 // IBM compiler workaround
00068 template<typename Inserter>
00069 const std::size_t SElementTriangleVertices<Inserter>::numVert = 3;
00070 #endif
00071 
00072 
00073 
00074 template<typename Inserter, typename OP=shells::SVertexCoordinate>
00075 struct SElementTriangleCollector  : 
00076     public std::binary_function<shells::SElement *, Inserter, void> {
00077 public:
00078     // collect the data at the triangle vertices (default coordinates)
00079     
00080     void operator()(shells::SElement *element, Inserter ins) const
00081         {
00082             const std::size_t numVert = SElementTriangleVertices<Inserter>::numVert; 
00083 
00084             SVertex *vtx[numVert]; 
00085             SElementTriangleVertices<SVertex **> getVertices;
00086             getVertices(element, vtx);
00087 
00088             OP getData;
00089             for (std::size_t ivtx=0; ivtx<numVert; ++ivtx) {
00090 
00091                 // insert data to ins
00092                 typename OP::DataType *data = getData(vtx[ivtx]);
00093                 for (std::size_t dim=0; dim<OP::numVar; ++dim) {
00094                     *ins++ = data[dim];
00095                 }
00096             }
00097         }
00098 };
00099 
00100 
00101 template<typename Inserter, typename OP=shells::SVertexCoordinate>
00102 struct SElementTriangleAverage  : 
00103     public std::binary_function<shells::SElement *, Inserter, void> {
00104 public:
00105     // compute the average of triangle data (default coordinates)
00106     
00107     void operator()(shells::SElement *element, Inserter ins) const
00108         {
00109             const std::size_t numVert = SElementTriangleVertices<Inserter>::numVert;
00110 
00111             SVertex *vtx[numVert]; 
00112             SElementTriangleVertices<SVertex **> getVertices;
00113             getVertices(element, vtx);
00114 
00115             OP getData;
00116             typename OP::DataType average[OP::numVar];
00117             std::size_t numVar = OP::numVar;
00118 
00119             for (std::size_t dim=0; dim<numVar; ++dim) {
00120                 average[dim] = 0.0;
00121             }
00122                 
00123             for (std::size_t ivtx=0; ivtx<numVert; ++ivtx) {
00124                 typename OP::DataType *data = getData(vtx[ivtx]);
00125                 for (std::size_t dim=0; dim<OP::numVar; ++dim) {
00126                     average[dim] += data[dim];
00127                 }
00128             }
00129                             
00130             for (std::size_t dim=0; dim<numVar; ++dim) {
00131                 *ins++ = average[dim]/3.0;
00132             }
00133         }
00134 };
00135 
00136 
00137 template <typename Inserter>
00138 struct SELementInternalDataAverage : 
00139         public std::binary_function<shells::SElement *, Inserter, void> {
00140     void operator()(shells::SElement *element, Inserter ins) const 
00141         {           
00142             double stress[9];
00143             const int maxSize = 20;
00144             double internal[maxSize];
00145             
00146             int size = shells::getNumInternal(element->matStorage);
00147             assert(size<maxSize);
00148             shells::averageInternalStorage(element->matStorage, stress, internal, maxSize);
00149             
00150             // don't store the stress for the moment
00151             for (unsigned i=0; i<static_cast<unsigned>(size); ++i) {
00152                 *ins++ = internal[i];
00153             }
00154             
00155             return;
00156         }    
00157 };
00158 
00159 
00160 template <typename Inserter>
00161 struct SELementInternalDataCollect : 
00162         public std::binary_function<shells::SElement *, Inserter, void> {
00163     void operator()(shells::SElement *element, Inserter ins) const 
00164         {           
00165             int size;
00166             double *data;
00167             
00168             shells::selementPtrToHistory(element, &data, &size);
00169             
00170             for (unsigned i=0; i<static_cast<unsigned>(size); ++i) {
00171                 *ins++ = *data++;
00172             }
00173             
00174             return;
00175         }    
00176 };
00177     
00178                 
00179 
00180 template <typename IT>
00181 class SELementInternalDataDistrib :
00182         public std::unary_function<shells::SElement *, void > {
00183 public:     
00184     SELementInternalDataDistrib(IT begin, IT end):_begin(begin), _end(end){}
00185     
00186     void operator()(shells::SElement * element) 
00187         {                   
00188             double *dummy;
00189             int size;              
00190             shells::selementPtrToHistory(element, &dummy, &size);
00191             _tmpCont.resize(size);              
00192             std::copy(_begin, _begin+size, _tmpCont.begin());
00193             
00194             shells::selementResetHistory(element, &(_tmpCont[0]));                  
00195             
00196             // advance begin iterator by the size of internal data size
00197             std::advance(_begin, static_cast<unsigned>(size));              
00198         }
00199     
00200 private:
00201     IT           _begin;
00202     const IT     _end;
00203     
00204     std::vector<double> _tmpCont;
00205 };
00206         
00207 } // namespace shells
00208 
00209 
00210 namespace shells {
00211     // pair for collecting elements as well as vertices
00212     typedef std::pair<std::back_insert_iterator<std::vector<shells::SElementS*> >,
00213                       std::back_insert_iterator<std::vector<shells::SVertexS*> > >  
00214                                                                 InserterSElemSVtx;
00215 }
00216 
00217 
00218 
00219 struct shells::SElementOneNeighborhood :
00220     public std::binary_function<shells::SElementS *, shells::InserterSElemSVtx , void> {
00221     // find all the elements and vertices in *element's one neigborhood 
00222     // all elements except *element are inserted in inserters.first
00223     // vertices are inserted in inserters.second
00224     void operator()(shells::SElementS *element, shells::InserterSElemSVtx inserters) const;
00225 };
00226 
00227 #endif

Generated on Fri Aug 24 13:00:24 2007 for SFC Thin-Shell Finite Element Solver by  doxygen 1.4.7