00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00051
00052 #if defined(_AIX)
00053 static const std::size_t numVert;
00054 #else
00055 static const std::size_t numVert = 3;
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
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
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
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
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
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
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 }
00208
00209
00210 namespace shells {
00211
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
00222
00223
00224 void operator()(shells::SElementS *element, shells::InserterSElemSVtx inserters) const;
00225 };
00226
00227 #endif