00001 #ifndef __FIBER_GRID_TYPES_CURVEDERIVATIVE_HPP
00002 #define __FIBER_GRID_TYPES_CURVEDERIVATIVE_HPP
00003
00004 #include "gridtypesDllApi.h"
00005 #include <grid/Grid.hpp>
00006 #include <eagle/PhysicalSpace.hpp>
00007
00008 #include <grid/EuclideanMetric.hpp>
00009 #include "LineSet.hpp"
00010
00011
00012
00013 namespace Fiber
00014 {
00015
00016 struct IdentityOperator
00017 {
00018 template <class ValueType, class PointType>
00019 static const ValueType&compute(const ValueType&Value, index_t, const PointType&)
00020 {
00021 return Value;
00022 }
00023 };
00024
00025 struct ComputeUnitVector
00026 {
00027 template <class ValueType, class PointType>
00028 static const ValueType&compute(const ValueType&Value, index_t, const PointType&)
00029 {
00030 return unit(Value);
00031 }
00032 };
00033
00034
00035 struct DerivativeOperatorData
00036 {
00037 WeakPtr<Grid> theGrid;
00038 const RefPtr<FragmentID>& fragV;
00039 string fieldName;
00040
00041 DerivativeOperatorData(WeakPtr<Grid> theGridP, const string& fieldNameP, const RefPtr<FragmentID>& fragVP )
00042 : theGrid( theGridP )
00043 , fragV( fragVP )
00044 , fieldName(fieldNameP)
00045 {}
00046 };
00047
00063 template <class Type, class Metric = EuclideanMetric, class ValueOperator = IdentityOperator>
00064 struct CurveDerivative : public Metric, public ValueOperator
00065 {
00066 typedef typename Metric::point point;
00067 using Metric::distance;
00068
00069 using ValueOperator::compute;
00070
00071 RefPtr<MemArray<1, Type> > Quantity;
00072 RefPtr<MemArray<1, Type> > DerivedQuantity;
00073
00074 typedef MemArray<1, Type> ResultArray_t;
00075
00076 typedef DerivativeOperatorData Constructor_t;
00077
00078 RefPtr<ResultArray_t> result() const
00079 {
00080 return DerivedQuantity;
00081 }
00082
00083 typedef std::string Parameters;
00084
00085 CurveDerivative(const Constructor_t&C, const MemBase::Creator_t&Crec )
00086 {
00087 #ifdef VERBOSE
00088 puts("CurveDerivative::CurveDerivative() enter");fflush(stdout);
00089 #endif
00090 if (!C.theGrid)
00091 {
00092 puts("CurveDerivative::CurveDerivative() No Grid!");fflush(stdout);
00093 return;
00094 }
00095
00096 LineSet LS = C.theGrid;
00097
00098 if (!LS)
00099 {
00100 puts("CurveDerivative::CurveDerivative() No LineSet!");fflush(stdout);
00101 return;
00102 }
00103
00104
00105 if (!LS.CartesianVertices)
00106 {
00107 puts("CurveDerivative::CurveDerivative() No Cartesian Vertices!");fflush(stdout);
00108 return;
00109 }
00110
00111 if (!LS.getCoords( C.fragV ) )
00112 {
00113 puts("CurveDerivative::CurveDerivative() No Coords!");fflush(stdout);
00114 return;
00115 }
00116
00117 #ifdef VERBOSE
00118 puts("CurveDerivative::CurveDerivative() progressing");fflush(stdout);
00119 #endif
00120
00121 string QuantityFieldName = C.fieldName;
00122
00123 #ifdef VERBOSE
00124 puts("CurveDerivative::CurveDerivative() progressing 2");fflush(stdout);
00125 std::cout << "CurveDerivative::CurveDerivative() doing: " << QuantityFieldName << std::endl;fflush(stdout);
00126 #endif
00127
00128 RefPtr<Field> QuantityVertexField = (*LS.CartesianVertices)[ QuantityFieldName ];
00129 if (!QuantityVertexField)
00130 {
00131 puts("CurveDerivative::CurveDerivative() No Quantity Field found!");fflush(stdout);
00132 return;
00133 }
00134 if (Quantity = QuantityVertexField->getData( C.fragV ) )
00135 {
00136 DerivedQuantity = new ResultArray_t( LS.getCoords( C.fragV )->nElements(), Crec );
00137
00138 #ifdef VERBOSE
00139 puts("CurveDerivative::CurveDerivative() iterating"); fflush(stdout);
00140 #endif
00141 LS.ApplyOnVertexFragment( *this, C.fragV );
00142
00143 #ifdef VERBOSE
00144 puts("CurveDerivative::CurveDerivative() post iteration"); fflush(stdout);
00145 #endif
00146
00147 }
00148 else
00149 {
00150 puts("CurveDerivative::CurveDerivative() No Data retrieved!");fflush(stdout);
00151 }
00152 }
00153
00154 void apply(const CreativeIterator<Eagle::PhysicalSpace::point>&Vertices,
00155 const LineSet::LineIndices_t&Line)
00156 {
00157 #ifdef VERBOSE
00158 puts("CurveDerivative::apply()");fflush(stdout);
00159 #endif
00160 MultiArray<1, Type>&Values = *Quantity;
00161 MultiArray<1, Type>&ValueDerivative = *DerivedQuantity;
00162
00163 if (Line.size()<1)
00164 {
00165 #ifdef VERBOSE
00166 puts("CurveDerivative::apply() No Data");
00167 #endif
00168 return;
00169 }
00170 if (Line.size()<2)
00171 {
00172 #ifdef VERBOSE
00173 puts("CurveDerivative::apply() One Element");
00174 #endif
00175 const point&P0 = Vertices[ Line[0] ];
00176 const Type&Q = ValueOperator::compute( Values [ Line[0] ], Line[0], P0 );
00177
00178 ValueDerivative[ Line[0] ] = Q-Q;
00179 #ifdef VERBOSE
00180 std::cout << "First" << ValueDerivative[ Line[0] ] << std::endl;
00181 #endif
00182 return;
00183 }
00184
00185
00186
00187 {
00188 const point&P0 = Vertices[ Line[0] ],
00189 &P1 = Vertices[ Line[1] ];
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 const Type&Q0 = Values [ Line[0] ];
00201 const Type&Q1 = Values [ Line[1] ];
00202
00203 double ds = Eagle::norm(P1 - P0);
00204
00205 ValueDerivative[ Line[0] ] = (Q1 - Q0) / ds;
00206 #ifdef VERBOSE
00207 std::cout << "Q0= " << Q0 << ", Q1= " << Q1 << std::endl;
00208 std::cout << "First " << ValueDerivative[ Line[0] ] << std::endl;
00209 #endif
00210 }
00211
00212
00213
00214
00215
00216 index_t I = Line.size();
00217 for(unsigned i=1; i<I-1; i++)
00218 {
00219 const point&Pm = Vertices[ Line[i-1] ],
00220 &P = Vertices[ Line[i ] ],
00221 &Pp = Vertices[ Line[i+1] ];
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 const Type&Qm = Values [ Line[i-1] ],
00233 &Q = Values [ Line[i ] ],
00234 &Qp = Values [ Line[i+1] ];
00235
00236 double ds2_m = 2*Eagle::norm( P - Pm ),
00237 ds2_p = 2*Eagle::norm( Pp - P );
00238
00239 ValueDerivative[ Line[i] ] = (Q - Qm ) / ds2_m
00240 +
00241 (Qp - Q ) / ds2_p
00242 ;
00243
00244 #ifdef VERBOSE
00245 std::cout << "i: " << i << " " << ValueDerivative[ Line[i] ] << std::endl;
00246 #endif
00247 }
00248
00249
00250 if (I>2)
00251 {
00252 index_t I = Line.size();
00253
00254 const point&P0 = Vertices[ Line[I-2] ],
00255 &P1 = Vertices[ Line[I-1] ];
00256
00257
00258
00259
00260
00261
00262
00263 const Type&Q0 = Values [ Line[I-2] ];
00264 const Type&Q1 = Values [ Line[I-1] ];
00265
00266 double ds = Eagle::norm(P1-P0);
00267
00268 ValueDerivative[ Line[I-1] ] = (Q1 - Q0) / ds;
00269 #ifdef VERBOSE
00270 std::cout << "Last: " << ValueDerivative[ Line[I-1] ] << std::endl;
00271 #endif
00272 }
00273
00274 }
00275 };
00276
00277 }
00278
00279 #endif // __FIBER_GRID_TYPES_CURVEDERIVATIVE_HPP
00280