00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef __CALCIUM_COUPLING_POLICY__
00028 #define __CALCIUM_COUPLING_POLICY__
00029
00030 #include <vector>
00031 #include <map>
00032
00033 #include "DisplayPair.hxx"
00034 #include "CouplingPolicy.hxx"
00035 #include "AdjacentFunctor.hxx"
00036 #include <boost/lambda/lambda.hpp>
00037 #include <boost/utility/enable_if.hpp>
00038 #include <boost/type_traits/is_arithmetic.hpp>
00039 #include "CalciumTypes.hxx"
00040 #include "CalciumException.hxx"
00041
00042
00043
00044 class CalciumCouplingPolicy : public CouplingPolicy {
00045
00046
00047 public:
00048
00049 template <typename T_TIME, typename T_TAG > class InternalDataIdContainer;
00050 template <typename T_TIME, typename T_TAG > friend class InternalDataIdContainer;
00051 template <typename DataManipulator,
00052 class EnableIf > friend class BoundedDataIdProcessor;
00053 template <typename DataManipulator > friend class EraseDataIdProcessor;
00054 template <typename DataManipulator > friend class DisconnectProcessor;
00055
00056 typedef CalciumTypes::DependencyType DependencyType;
00057 typedef CalciumTypes::DateCalSchem DateCalSchem;
00058 typedef CalciumTypes::InterpolationSchem InterpolationSchem;
00059 typedef CalciumTypes::ExtrapolationSchem ExtrapolationSchem;
00060 typedef CalciumTypes::DisconnectDirective DisconnectDirective;
00061
00062 private:
00063
00064 DependencyType _dependencyType;
00065 size_t _storageLevel;
00066 DateCalSchem _dateCalSchem;
00067 InterpolationSchem _interpolationSchem;
00068 ExtrapolationSchem _extrapolationSchem;
00069 double _alpha;
00070 double _deltaT;
00071 DisconnectDirective _disconnectDirective;
00072
00073 public:
00074 CalciumCouplingPolicy();
00075
00076 void setDependencyType (DependencyType dependencyType);
00077 DependencyType getDependencyType () const;
00078
00079 void setStorageLevel (size_t storageLevel);
00080 size_t getStorageLevel () const;
00081
00082 void setDateCalSchem (DateCalSchem dateCalSchem);
00083 DateCalSchem getDateCalSchem () const;
00084
00085 void setAlpha(double alpha);
00086 double getAlpha() const ;
00087
00088 void setDeltaT(double deltaT );
00089 double getDeltaT() const ;
00090
00091 void setInterpolationSchem (InterpolationSchem interpolationSchem);
00092 void setExtrapolationSchem (ExtrapolationSchem extrapolationSchem);
00093 InterpolationSchem getInterpolationSchem () const ;
00094 ExtrapolationSchem getExtrapolationSchem () const ;
00095
00096
00097
00098
00099 typedef double TimeType;
00100 typedef long TagType;
00101 typedef std::pair< TimeType , TagType > DataId;
00102 typedef InternalDataIdContainer < TimeType , TagType > DataIdContainer;
00103 typedef std::vector< DataId >::iterator iterator;
00104
00105 template <typename T_TIME, typename T_TAG >
00106 struct InternalDataIdContainer;
00107
00108 inline TimeType getTime(const DataId &dataId) const { return dataId.first;}
00109 inline TagType getTag (const DataId &dataId) const { return dataId.second;}
00110
00111 template <typename DataManipulator,
00112 class EnableIf = void > struct BoundedDataIdProcessor;
00113
00114 template <typename DataManipulator> struct EraseDataIdProcessor;
00115 template <typename DataManipulator> struct DisconnectProcessor;
00116
00117
00118
00119
00120
00121
00122
00123 template < typename AssocContainer >
00124 bool isDataIdConveniant( AssocContainer & storedDatas,
00125 const typename AssocContainer::key_type & expectedDataId,
00126 bool & isEqual, bool & isBounded,
00127 typename AssocContainer::iterator & wDataIt1) const;
00128
00129 TimeType getEffectiveTime(TimeType ti, TimeType tf);
00130
00131 void disconnect(bool provideLastGivenValue);
00132
00133 };
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 template <typename T_TIME, typename T_TAG >
00144 struct CalciumCouplingPolicy::InternalDataIdContainer : public std::vector< std::pair< T_TIME,T_TAG> > {
00145 typedef std::vector < DataId > DataIdVect;
00146
00147 InternalDataIdContainer(const DataId & dataId,
00148 const CalciumCouplingPolicy & policy
00149 ):std::vector< std::pair< T_TIME,T_TAG> >() {
00150
00151 switch (policy._dependencyType) {
00152 case CalciumTypes::TIME_DEPENDENCY:
00153 this->push_back(DataId(dataId.first,0));
00154 break;
00155 case CalciumTypes::ITERATION_DEPENDENCY:
00156 this->push_back(DataId(0,dataId.second));
00157 break;
00158 default:
00159 throw(CalciumException(CalciumTypes::CPIT,LOC("The dependency type must be set by setDependencyType before calling DataIdContainer contructor")));
00160 break;
00161 }
00162 };
00163 };
00164
00165
00166 template <typename DataManipulator, class EnableIf >
00167 struct CalciumCouplingPolicy::BoundedDataIdProcessor{
00168 BoundedDataIdProcessor(const CouplingPolicy & couplingPolicy) {};
00169 template < typename Iterator, typename DataId >
00170 void inline apply(typename iterator_t<Iterator>::value_type & data,
00171 const DataId & dataId,
00172 const Iterator & it1) const {
00173 typedef typename iterator_t<Iterator>::value_type value_type;
00174 #ifdef MYDEBUG
00175 std::cout << "-------- Calcium Generic BoundedDataIdProcessor.apply() called " << std::endl;
00176 #endif
00177
00178 }
00179 };
00180
00181
00182 template <typename DataManipulator >
00183 struct CalciumCouplingPolicy::BoundedDataIdProcessor<
00184 DataManipulator,
00185 typename boost::enable_if< boost::is_float< typename DataManipulator::InnerType> >::type > {
00186
00187 const CalciumCouplingPolicy & _couplingPolicy;
00188
00189 BoundedDataIdProcessor(const CalciumCouplingPolicy &couplingPolicy):
00190 _couplingPolicy(couplingPolicy) {};
00191
00192
00193 template < typename MapIterator >
00194 void inline apply (typename iterator_t<MapIterator>::value_type & data,
00195 const DataId & dataId, const MapIterator & it1) const {
00196
00197 typedef typename iterator_t<MapIterator>::value_type value_type;
00198 typedef typename DataManipulator::InnerType InnerType;
00199 typedef typename DataManipulator::Type Type;
00200
00201 MapIterator it2=it1; ++it2;
00202 size_t dataSize1 = DataManipulator::size(it1->second);
00203 #ifdef MYDEBUG
00204 std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Taille de donnée dataId1 : " << dataSize1 << std::endl;
00205 #endif
00206
00207
00208
00209 size_t dataSize2 = DataManipulator::size(it2->second);
00210 #ifdef MYDEBUG
00211 std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Taille de donnée dataId2 : " << dataSize2 << std::endl;
00212 #endif
00213
00214 size_t dataSize = std::min< size_t >( dataSize1, dataSize2 );
00215 DataId dataId2 = it2->first;
00216 DataId dataId1 = it1->first;
00217 TimeType t2 = dataId2.first;
00218 TimeType t1 = dataId1.first;
00219 #ifdef MYDEBUG
00220 std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de t1 : " << t1 << std::endl;
00221 std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de t2 : " << t2 << std::endl;
00222 #endif
00223 TimeType t = dataId.first;
00224 #ifdef MYDEBUG
00225 std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de t : " << t << std::endl;
00226 #endif
00227 TimeType timeDiff = t2-t1;
00228 #ifdef MYDEBUG
00229 std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de timeDiff : " << timeDiff << std::endl;
00230 #endif
00231 TimeType coeff = (t2-t)/timeDiff;
00232 #ifdef MYDEBUG
00233 std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Valeur de coeff : " << coeff << std::endl;
00234 #endif
00235
00236 InnerType const * const InIt1 = DataManipulator::getPointer(it1->second);
00237 #ifdef MYDEBUG
00238 std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Données à t1 : " << std::endl;
00239 std::copy(InIt1,InIt1+dataSize1,std::ostream_iterator<InnerType>(std::cout," "));
00240 std::cout << std::endl;
00241 #endif
00242 InnerType const * const InIt2 = DataManipulator::getPointer(it2->second);
00243 #ifdef MYDEBUG
00244 std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Données à t2 : " << std::endl;
00245 std::copy(InIt2,InIt2+dataSize2,std::ostream_iterator<InnerType>(std::cout," "));
00246 std::cout << std::endl;
00247 #endif
00248 Type dataOut = DataManipulator::create(dataSize);
00249 InnerType * const OutIt = DataManipulator::getPointer(dataOut);
00250
00251 #ifdef MYDEBUG
00252 std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : interpolationSchem : " << _couplingPolicy._interpolationSchem << std::endl;
00253 std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : alpha : " << _couplingPolicy._alpha << std::endl;
00254 std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : datecalschem : " << _couplingPolicy._dateCalSchem << std::endl;
00255 std::cerr << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : storageLevel : " << _couplingPolicy._storageLevel << std::endl;
00256 #endif
00257 if ( timeDiff == 0.0 || _couplingPolicy._interpolationSchem == CalciumTypes::L0_SCHEM ) {
00258 std::copy(InIt1,InIt1+dataSize,OutIt);
00259 } else {
00260
00261 boost::lambda::placeholder1_type _1;
00262 boost::lambda::placeholder2_type _2;
00263
00264
00265 std::transform(InIt1,InIt1+dataSize,InIt2,OutIt,
00266 ( _1 - _2 ) * coeff + _2 );
00267
00268
00269
00270
00271 }
00272 #ifdef MYDEBUG
00273 std::cout << "-------- CalciumCouplingPolicy::BoundedDataIdProcessor : Données calculées à t : " << std::endl;
00274 std::copy(OutIt,OutIt+dataSize,std::ostream_iterator<InnerType>(std::cout," "));
00275 std::cout << std::endl;
00276 #endif
00277 data = dataOut;
00278
00279 }
00280 };
00281
00282
00283
00284
00285
00286
00287
00288 template < typename AssocContainer >
00289 bool CalciumCouplingPolicy::isDataIdConveniant( AssocContainer & storedDatas, const typename AssocContainer::key_type & expectedDataId,
00290 bool & isEqual, bool & isBounded, typename AssocContainer::iterator & wDataIt1) const {
00291
00292
00293 typedef typename AssocContainer::key_type key_type;
00294 AdjacentFunctor< key_type > af(expectedDataId);
00295 if ( _dependencyType == CalciumTypes::TIME_DEPENDENCY )
00296 {
00297 #ifdef MYDEBUG
00298 std::cout << "-------- time expected : " << expectedDataId.first << std::endl;
00299 std::cout << "-------- time expected corrected : " << expectedDataId.first*(1.0-_deltaT) << std::endl;
00300 #endif
00301 af.setMaxValue(key_type(expectedDataId.first*(1.0-_deltaT),0));
00302 }
00303 isBounded = false;
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 typename AssocContainer::iterator prev = storedDatas.begin();
00321 typename AssocContainer::iterator current = prev;
00322 while ( (current != storedDatas.end()) && !af(current->first) )
00323 {
00324 #ifdef MYDEBUG
00325 std::cerr << "------- stored time : " << current->first << std::endl;
00326 #endif
00327
00328 prev = current++;
00329 }
00330
00331 isEqual = af.isEqual();
00332
00333
00334
00335 if ( _dependencyType == CalciumTypes::TIME_DEPENDENCY) isBounded = af.isBounded();
00336
00337 if ( isEqual ) wDataIt1 = current;
00338 else
00339 if (isBounded) wDataIt1 = prev;
00340 else
00341 wDataIt1 = storedDatas.end();
00342
00343 #ifdef MYDEBUG
00344 std::cout << "-------- isDataIdConvenient : isEqual : " << isEqual << " , isBounded " << isBounded << std::endl;
00345 #endif
00346
00347 return isEqual || isBounded;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357 template < typename DataManipulator >
00358 struct CalciumCouplingPolicy::EraseDataIdProcessor {
00359
00360 CalciumCouplingPolicy &_couplingPolicy;
00361
00362 EraseDataIdProcessor(CalciumCouplingPolicy &couplingPolicy):
00363 _couplingPolicy(couplingPolicy) {};
00364
00365 template < typename Container >
00366 void apply(Container & storedDatas,
00367 typename Container::iterator & wDataIt1 ) const {
00368
00369 typedef typename Container::key_type key_type;
00370 typedef typename Container::value_type value_type;
00371 typedef typename Container::iterator iterator;
00372
00373 #ifdef MYDEBUG
00374 std::cout << "-------- CalciumCouplingPolicy::eraseDataId, storedDatasSize : " << storedDatas.size() << std::endl;
00375 #endif
00376
00377 if ( _couplingPolicy._storageLevel == CalciumTypes::UNLIMITED_STORAGE_LEVEL ) return;
00378
00379 size_t storedDatasSize = storedDatas.size();
00380 long s = storedDatasSize - _couplingPolicy._storageLevel;
00381 if (s > 0 ) {
00382 size_t dist=distance(storedDatas.begin(),wDataIt1);
00383 for (int i=0; i<s; ++i) {
00384
00385 DataManipulator::delete_data((*storedDatas.begin()).second);
00386 storedDatas.erase(storedDatas.begin());
00387 }
00388
00389 if (dist < s ) {
00390 throw(CalciumException(CalciumTypes::CPNTNULL,LOC(OSS()<< "StorageLevel management "
00391 << _couplingPolicy._storageLevel <<
00392 " has just removed the data to send")));
00393 }
00394 }
00395 #ifdef MYDEBUG
00396 std::cout << "-------- CalciumCouplingPolicy::eraseDataId, new storedDatasSize : " << storedDatas.size() << std::endl;
00397 #endif
00398 return;
00399
00400 }
00401 };
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 template < typename DataManipulator >
00412 struct CalciumCouplingPolicy::DisconnectProcessor {
00413
00414 const CalciumCouplingPolicy & _couplingPolicy;
00415
00416 DisconnectProcessor(const CalciumCouplingPolicy & couplingPolicy):
00417 _couplingPolicy(couplingPolicy) {};
00418
00419 template < typename Container, typename DataId >
00420 bool apply(Container & storedDatas,
00421 const DataId & expectedDataId,
00422 typename Container::iterator & wDataIt1 ) const {
00423
00424 typedef typename Container::key_type key_type;
00425 typedef typename Container::value_type value_type;
00426 typedef typename Container::iterator iterator;
00427
00428
00429 #ifdef MYDEBUG
00430 std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK1 ("<< _couplingPolicy._disconnectDirective<<") --------" << std::endl;
00431 #endif
00432 if ( (_couplingPolicy._disconnectDirective) == (CalciumTypes::UNDEFINED_DIRECTIVE) ) return false;
00433
00434 #ifdef MYDEBUG
00435 std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK2 --------" << std::endl;
00436 #endif
00437
00438
00439 if ( _couplingPolicy._disconnectDirective == CalciumTypes::CP_ARRET )
00440 throw(CalciumException(CalciumTypes::CPINARRET,LOC(OSS()<< "CP_ARRET directive"
00441 << " interrupts all further data reading")));
00442 #ifdef MYDEBUG
00443 std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK3 --------" << std::endl;
00444 #endif
00445
00446
00447
00448
00449 if ( storedDatas.empty() )
00450 throw(CalciumException(CalciumTypes::CPNTNULL,LOC(OSS()<< "CP_CONT directive"
00451 << " is active but no data is available.")));
00452
00453
00454
00455
00456
00457 #ifdef MYDEBUG
00458 std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK4 " << expectedDataId <<" --------" << std::endl;
00459 #endif
00460
00461
00462 iterator it1 = storedDatas.lower_bound(expectedDataId);
00463 #ifdef MYDEBUG
00464 std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK5 " << std::endl;
00465 for (iterator it=storedDatas.begin();it!=storedDatas.end();++it)
00466 std::cout <<" "<<(*it).first ;
00467 std::cout <<std::endl;
00468 #endif
00469
00470
00471 if (it1 == storedDatas.end())
00472 throw(CalciumException(CalciumTypes::CPNTNULL,LOC(OSS()<< "CP_CONT directive"
00473 << " is active but the requested dataId is less or equal to the last one received.")));
00474
00475 #ifdef MYDEBUG
00476 std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor MARK6 " << std::endl;
00477 #endif
00478
00479 wDataIt1 = storedDatas.end();
00480 --wDataIt1;
00481 #ifdef MYDEBUG
00482 std::cout << "-------- CalciumCouplingPolicy::DisconnectProcessor, CP_CONT : " << (*wDataIt1).first << std::endl;
00483 #endif
00484
00485 return true;
00486 }
00487 };
00488
00489 #endif