$treeview $search $mathjax
Palabos  Version 1.1
$projectbrief
$projectbrief
$searchbox

dynamics.hh

Go to the documentation of this file.
00001 /* This file is part of the Palabos library.
00002  *
00003  * Copyright (C) 2011 FlowKit Sarl
00004  * Avenue de Chailly 23
00005  * 1012 Lausanne, Switzerland
00006  * E-mail contact: contact@flowkit.com
00007  *
00008  * The most recent release of Palabos can be downloaded at 
00009  * <http://www.palabos.org/>
00010  *
00011  * The library Palabos is free software: you can redistribute it and/or
00012  * modify it under the terms of the GNU Affero General Public License as
00013  * published by the Free Software Foundation, either version 3 of the
00014  * License, or (at your option) any later version.
00015  *
00016  * The library is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Affero General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Affero General Public License
00022  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00023 */
00024 
00029 #ifndef DYNAMICS_HH
00030 #define DYNAMICS_HH
00031 
00032 #include "core/dynamics.h"
00033 #include "core/cell.h"
00034 #include "core/dynamicsIdentifiers.h"
00035 #include "core/hierarchicSerializer.h"
00036 #include "latticeBoltzmann/dynamicsTemplates.h"
00037 #include "latticeBoltzmann/momentTemplates.h"
00038 #include "core/latticeStatistics.h"
00039 #include "multiGrid/multiGridUtil.h"
00040 #include <algorithm>
00041 #include <limits>
00042 
00043 namespace plb {
00044 
00045 /* *************** Class Dynamics ******************************************* */
00046 
00048 template<typename T, template<typename U> class Descriptor>
00049 int Dynamics<T,Descriptor>::getId() const {
00050     return 0;
00051 }
00052 
00054 template<typename T, template<typename U> class Descriptor>
00055 bool Dynamics<T,Descriptor>::velIsJ() const {
00056     return false;
00057 }
00058 
00060 template<typename T, template<typename U> class Descriptor>
00061 bool Dynamics<T,Descriptor>::isComposite() const {
00062     return false;
00063 }
00064 
00066 template<typename T, template<typename U> class Descriptor>
00067 bool Dynamics<T,Descriptor>::isComposeable() const {
00068     return true;
00069 }
00070 
00072 template<typename T, template<typename U> class Descriptor>
00073 bool Dynamics<T,Descriptor>::isBoundary() const {
00074     return false;
00075 }
00076 
00078 template<typename T, template<typename U> class Descriptor>
00079 bool Dynamics<T,Descriptor>::isNonLocal() const {
00080     return false;
00081 }
00082 
00083 template<typename T, template<typename U> class Descriptor>
00084 T Dynamics<T,Descriptor>::getParameter(plint whichParameter) const {
00085     if (whichParameter == dynamicParams::omega_shear) {
00086         return getOmega();
00087     }
00088     return 0.;
00089 }
00090 
00091 template<typename T, template<typename U> class Descriptor>
00092 void Dynamics<T,Descriptor>::setParameter(plint whichParameter, T value) {
00093     if (whichParameter == dynamicParams::omega_shear) {
00094         setOmega(value);
00095     }
00096 }
00097 
00098 template<typename T, template<typename U> class Descriptor>
00099 void Dynamics<T,Descriptor>::serialize(HierarchicSerializer& serializer) const
00100 {
00101     serializer.addValue(this->getOmega());
00102 }
00103 
00104 template<typename T, template<typename U> class Descriptor>
00105 void Dynamics<T,Descriptor>::unserialize(HierarchicUnserializer& unserializer)
00106 {
00107     this->setOmega(unserializer.readValue<T>());
00108 }
00109 
00110 template<typename T, template<typename U> class Descriptor>
00111 void Dynamics<T,Descriptor>::collide (
00112         Cell<T,Descriptor>& cell, T rhoBar,
00113         Array<T,Descriptor<T>::d> const& j, T thetaBar, BlockStatistics& stat )
00114 {
00115     T oldRhoBar;
00116     Array<T,Descriptor<T>::d> oldJ;
00117     computeRhoBarJ(cell, oldRhoBar, oldJ);
00118     T oldJsqr = normSqr(oldJ);
00119     T jSqr = normSqr(j);
00120     for (int iPop=0; iPop<Descriptor<T>::q; ++iPop) {
00121         T oldEq = computeEquilibrium(iPop, oldRhoBar, oldJ, oldJsqr);
00122         T newEq = computeEquilibrium(iPop, rhoBar, j, jSqr);
00123         cell[iPop] += newEq - oldEq;
00124     }
00125     collide(cell, stat);
00126 }
00127 
00128 
00129 template<typename T, template<typename U> class Descriptor>
00130 void Dynamics<T,Descriptor>::computeEquilibria (
00131         Array<T,Descriptor<T>::q>& fEq,  T rhoBar, Array<T,Descriptor<T>::d> const& j, T jSqr, T thetaBar ) const
00132 {
00133     for (int iPop=0; iPop<Descriptor<T>::q; ++iPop) {
00134         fEq[iPop] = computeEquilibrium(iPop, rhoBar, j, jSqr, thetaBar);
00135     }
00136 }
00137 
00138 template<typename T, template<typename U> class Descriptor>
00139 void Dynamics<T,Descriptor>::rescale(int dxScale, int dtScale) {
00140     int dimDx = 2;
00141     int dimDt = -1;
00142     T scaleFactor = scaleFromReference(dxScale, dimDx, dtScale, dimDt);
00143     T omega = this->getOmega();
00144     T nu_cs2 = (T)1/omega - (T)1/(T)2;
00145     this->setOmega( (T)1/(scaleFactor*nu_cs2+(T)1/(T)2) );
00146 }
00147 
00148 template<typename T, template<typename U> class Descriptor>
00149 void Dynamics<T,Descriptor>::getPopulations(Cell<T,Descriptor> const& cell, Array<T,Descriptor<T>::q>& f) const {
00150     f = cell.getRawPopulations();
00151 }
00152 
00153 template<typename T, template<typename U> class Descriptor>
00154 void Dynamics<T,Descriptor>::getExternalField (
00155         Cell<T,Descriptor> const& cell, plint pos, plint size, T* ext) const
00156 {
00157     PLB_PRECONDITION(pos+size <= Descriptor<T>::ExternalField::numScalars);
00158     T const* externalData = cell.getExternal(pos);
00159     for (plint iExt=0; iExt<size; ++iExt) {
00160         ext[iExt] = externalData[iExt];
00161     }
00162 }
00163 
00164 template<typename T, template<typename U> class Descriptor>
00165 void Dynamics<T,Descriptor>::setPopulations(Cell<T,Descriptor>& cell, Array<T,Descriptor<T>::q> const& f)
00166 {
00167     cell.getRawPopulations() = f;
00168 }
00169 
00170 template<typename T, template<typename U> class Descriptor>
00171 void Dynamics<T,Descriptor>::setExternalField (
00172         Cell<T,Descriptor>& cell, plint pos, plint size, const T* ext)
00173 {
00174     PLB_PRECONDITION(pos+size <= Descriptor<T>::ExternalField::numScalars);
00175     T* externalData = cell.getExternal(pos);
00176     for (plint iExt=0; iExt<size; ++iExt) {
00177         externalData[iExt] = ext[iExt];
00178     }
00179 }
00180 
00189 template<typename T, template<typename U> class Descriptor>
00190 void Dynamics<T,Descriptor>::defineDensity(Cell<T,Descriptor>& cell, T density) { }
00191 
00200 template<typename T, template<typename U> class Descriptor>
00201 void Dynamics<T,Descriptor>::defineVelocity(Cell<T,Descriptor>& cell, Array<T,Descriptor<T>::d> const& u) { }
00202 
00211 template<typename T, template<typename U> class Descriptor>
00212 void Dynamics<T,Descriptor>::defineTemperature(Cell<T,Descriptor>& cell, T temperature) { }
00213 
00222 template<typename T, template<typename U> class Descriptor>
00223 void Dynamics<T,Descriptor>::defineHeatFlux(Cell<T,Descriptor>& cell, Array<T,Descriptor<T>::d> const& q) { }
00224 
00233 template<typename T, template<typename U> class Descriptor>
00234 void Dynamics<T,Descriptor>::defineDeviatoricStress(Cell<T,Descriptor>& cell, Array<T,SymmetricTensor<T,Descriptor>::n> const& PiNeq)
00235 { }
00236 
00245 template<typename T, template<typename U> class Descriptor>
00246 void Dynamics<T,Descriptor>::defineMoment(Cell<T,Descriptor>& cell, plint momentId, T const* value)
00247 { }
00248 
00249 
00250 /* *************** Class BasicBulkDynamics *************************** */
00251 
00252 template<typename T, template<typename U> class Descriptor>
00253 BasicBulkDynamics<T,Descriptor>::BasicBulkDynamics(T omega_)
00254     : omega(omega_)
00255 { }
00256 
00257 template<typename T, template<typename U> class Descriptor>
00258 T BasicBulkDynamics<T,Descriptor>::computeDensity(Cell<T,Descriptor> const& cell) const
00259     {
00260     return momentTemplates<T,Descriptor>::compute_rho(cell);
00261 }
00262 
00263 template<typename T, template<typename U> class Descriptor>
00264 T BasicBulkDynamics<T,Descriptor>::computePressure(Cell<T,Descriptor> const& cell) const
00265 {
00266     return Descriptor<T>::cs2 * computeDensity(cell) * computeTemperature(cell);
00267 }
00268 
00269 template<typename T, template<typename U> class Descriptor>
00270 void BasicBulkDynamics<T,Descriptor>::computeVelocity (
00271         Cell<T,Descriptor> const& cell,
00272         Array<T,Descriptor<T>::d>& u) const
00273 {
00274     momentTemplates<T,Descriptor>::compute_uLb(cell, u);
00275 }
00276 
00279 template<typename T, template<typename U> class Descriptor>
00280 T BasicBulkDynamics<T,Descriptor>::computeTemperature(Cell<T,Descriptor> const& cell) const
00281 {
00282     return (T)1;
00283 }
00284 
00287 template<typename T, template<typename U> class Descriptor>
00288 void BasicBulkDynamics<T,Descriptor>::computeDeviatoricStress (
00289         Cell<T,Descriptor> const& cell, Array<T,SymmetricTensor<T,Descriptor>::n>& PiNeq ) const
00290 {
00291     PiNeq.resetToZero();
00292 }
00293 
00296 template<typename T, template<typename U> class Descriptor>
00297 void BasicBulkDynamics<T,Descriptor>::computeHeatFlux (
00298         Cell<T,Descriptor> const& cell,
00299         Array<T,Descriptor<T>::d>& q) const
00300 {
00301     q.resetToZero();
00302 }
00303 
00304 template<typename T, template<typename U> class Descriptor>
00305 void BasicBulkDynamics<T,Descriptor>::computeMoment(
00306         Cell<T,Descriptor> const& cell, plint momentId, T* moment ) const
00307 {
00308     PLB_PRECONDITION( false );
00309 }
00310 
00311 template<typename T, template<typename U> class Descriptor>
00312 T BasicBulkDynamics<T,Descriptor>::getOmega() const {
00313     return omega;
00314 }
00315 
00316 template<typename T, template<typename U> class Descriptor>
00317 void BasicBulkDynamics<T,Descriptor>::setOmega(T omega_) {
00318     omega = omega_;
00319 }
00320 
00321 template<typename T, template<typename U> class Descriptor>
00322 T BasicBulkDynamics<T,Descriptor>::computeRhoBar(Cell<T,Descriptor> const& cell) const
00323 {
00324     return momentTemplates<T,Descriptor>::get_rhoBar(cell);
00325 }
00326 
00327 template<typename T, template<typename U> class Descriptor>
00328 void BasicBulkDynamics<T,Descriptor>::computeRhoBarJ (
00329         Cell<T,Descriptor> const& cell, T& rhoBar, Array<T,Descriptor<T>::d>& j ) const
00330 {
00331     momentTemplates<T,Descriptor>::get_rhoBar_j(cell, rhoBar, j);
00332 }
00333 
00334 template<typename T, template<typename U> class Descriptor>
00335 void BasicBulkDynamics<T,Descriptor>::computeRhoBarJPiNeq (
00336         Cell<T,Descriptor> const& cell, T& rhoBar, Array<T,Descriptor<T>::d>& j,
00337         Array<T,SymmetricTensor<T,Descriptor>::n>& PiNeq ) const
00338 {
00339     momentTemplates<T,Descriptor>::compute_rhoBar_j_PiNeq(cell, rhoBar, j, PiNeq);
00340 }
00341 
00342 template<typename T, template<typename U> class Descriptor>
00343 T BasicBulkDynamics<T,Descriptor>::computeEbar(Cell<T,Descriptor> const& cell) const
00344 {
00345     return momentTemplates<T,Descriptor>::get_eBar(cell);
00346 }
00347 
00348 
00349 /* *************** Class CompositeDynamics *************************** */
00350 
00351 template<typename T, template<typename U> class Descriptor>
00352 CompositeDynamics<T,Descriptor>::CompositeDynamics(Dynamics<T,Descriptor>* baseDynamics_,
00353                                                    bool automaticPrepareCollision_)
00354     : baseDynamics(baseDynamics_),
00355       automaticPrepareCollision(automaticPrepareCollision_)
00356 { }
00357 
00358 template<typename T, template<typename U> class Descriptor>
00359 CompositeDynamics<T,Descriptor>::CompositeDynamics(CompositeDynamics<T,Descriptor> const& rhs)
00360     : baseDynamics(rhs.baseDynamics->clone()),
00361       automaticPrepareCollision(rhs.automaticPrepareCollision)
00362 { }
00363 
00364 template<typename T, template<typename U> class Descriptor>
00365 CompositeDynamics<T,Descriptor>::~CompositeDynamics() {
00366     delete baseDynamics;
00367 }
00368 
00369 template<typename T, template<typename U> class Descriptor>
00370 CompositeDynamics<T,Descriptor>& CompositeDynamics<T,Descriptor>::operator=(CompositeDynamics<T,Descriptor> const& rhs)
00371 {
00372     delete baseDynamics;
00373     baseDynamics = rhs.baseDynamics->clone();
00374     automaticPrepareCollision = rhs.automaticPrepareCollision;
00375     return *this;
00376 }
00377 
00378 template<typename T, template<typename U> class Descriptor>
00379 CompositeDynamics<T,Descriptor>* CompositeDynamics<T,Descriptor>::cloneWithNewBase (
00380         Dynamics<T,Descriptor>* baseDynamics_) const
00381 {
00382     // First, create a clone, based on the dynamic type of CompositeDynamics
00383     CompositeDynamics<T,Descriptor>* newDynamics = clone();
00384     // Then, replace its original baseDynamics by the one we've received as parameter
00385     newDynamics->replaceBaseDynamics(baseDynamics_);
00386     return newDynamics;
00387 }
00388 
00389 template<typename T, template<typename U> class Descriptor>
00390 bool CompositeDynamics<T,Descriptor>::isComposite() const {
00391     return true;
00392 }
00393 
00394 template<typename T, template<typename U> class Descriptor>
00395 bool CompositeDynamics<T,Descriptor>::velIsJ() const {
00396     return this->getBaseDynamics().velIsJ();
00397 }
00398 
00399 template<typename T, template<typename U> class Descriptor>
00400 void CompositeDynamics<T,Descriptor>::replaceBaseDynamics(Dynamics<T,Descriptor>* newBaseDynamics) {
00401     delete baseDynamics;
00402     baseDynamics = newBaseDynamics;
00403 }
00404 
00405 template<typename T, template<typename U> class Descriptor>
00406 Dynamics<T,Descriptor>& CompositeDynamics<T,Descriptor>::getBaseDynamics() {
00407     return *baseDynamics;
00408 }
00409 
00410 template<typename T, template<typename U> class Descriptor>
00411 Dynamics<T,Descriptor> const& CompositeDynamics<T,Descriptor>::getBaseDynamics() const {
00412     return *baseDynamics;
00413 }
00414 
00415 template<typename T, template<typename U> class Descriptor>
00416 void CompositeDynamics<T,Descriptor>::serialize(HierarchicSerializer& serializer) const
00417 {
00418     serializer.addValue(this->doesAutomaticPrepareCollision());
00419     serializer.nextDynamics(this->getBaseDynamics().getId());
00420     this->getBaseDynamics().serialize(serializer);
00421 }
00422 
00423 template<typename T, template<typename U> class Descriptor>
00424 void CompositeDynamics<T,Descriptor>::unserialize(HierarchicUnserializer& unserializer)
00425 {
00426     PLB_PRECONDITION( unserializer.getId() == this->getId() );
00427     this->toggleAutomaticPrepareCollision(unserializer.readValue<bool>());
00428     // If the composite dynamics is fully constructed, just initialize the variables
00429     //   from the unserializer.
00430     if (baseDynamics) {
00431         this->getBaseDynamics().unserialize(unserializer);
00432     }
00433     // If the composite dynamics is being constructed, then the base dynamics must
00434     //   be newly created.
00435     else {
00436         baseDynamics = meta::dynamicsRegistration<T,Descriptor>().generate(unserializer);
00437     }
00438 }
00439 
00440 template<typename T, template<typename U> class Descriptor>
00441 void CompositeDynamics<T,Descriptor>::collide (
00442         Cell<T,Descriptor>& cell, BlockStatistics& statistics )
00443 {
00444     if (automaticPrepareCollision) prepareCollision(cell);
00445     baseDynamics -> collide(cell, statistics);
00446 }
00447 
00448 template<typename T, template<typename U> class Descriptor>
00449 void CompositeDynamics<T,Descriptor>::collide (
00450         Cell<T,Descriptor>& cell, T rhoBar,
00451         Array<T,Descriptor<T>::d> const& j, T thetaBar, BlockStatistics& stat )
00452 {
00453     if (automaticPrepareCollision) prepareCollision(cell);
00454     baseDynamics -> collide(cell, rhoBar, j, thetaBar, stat);
00455 }
00456 
00457 template<typename T, template<typename U> class Descriptor>
00458 T CompositeDynamics<T,Descriptor>::computeEquilibrium (
00459         plint iPop, T rhoBar, Array<T,Descriptor<T>::d> const& j, T jSqr, T thetaBar) const
00460 {
00461     return baseDynamics -> computeEquilibrium(iPop, rhoBar, j, jSqr, thetaBar);
00462 }
00463 
00464 template<typename T, template<typename U> class Descriptor>
00465 void CompositeDynamics<T,Descriptor>::regularize (
00466         Cell<T,Descriptor>& cell, T rhoBar, Array<T,Descriptor<T>::d> const& j,
00467         T jSqr, Array<T,SymmetricTensor<T,Descriptor>::n> const& PiNeq, T thetaBar ) const
00468 {
00469     baseDynamics -> regularize(cell, rhoBar, j, jSqr, PiNeq, thetaBar);
00470 }
00471 
00472 template<typename T, template<typename U> class Descriptor>
00473 T CompositeDynamics<T,Descriptor>::computeDensity(Cell<T,Descriptor> const& cell) const {
00474     return this->getBaseDynamics().computeDensity(cell);
00475 }
00476 
00477 template<typename T, template<typename U> class Descriptor>
00478 T CompositeDynamics<T,Descriptor>::computePressure(Cell<T,Descriptor> const& cell) const {
00479     return this->getBaseDynamics().computePressure(cell);
00480 }
00481 
00482 template<typename T, template<typename U> class Descriptor>
00483 void CompositeDynamics<T,Descriptor>::computeVelocity(Cell<T,Descriptor> const& cell,
00484                                                           Array<T,Descriptor<T>::d>& u ) const
00485 {
00486     this->getBaseDynamics().computeVelocity(cell, u);
00487 }
00488 
00489 template<typename T, template<typename U> class Descriptor>
00490 T CompositeDynamics<T,Descriptor>::computeTemperature(Cell<T,Descriptor> const& cell) const {
00491     return this->getBaseDynamics().computeTemperature(cell);
00492 }
00493 
00494 template<typename T, template<typename U> class Descriptor>
00495 void CompositeDynamics<T,Descriptor>::computeDeviatoricStress (
00496         Cell<T,Descriptor> const& cell, Array<T,SymmetricTensor<T,Descriptor>::n>& PiNeq ) const
00497 {
00498     return this->getBaseDynamics().computeDeviatoricStress(cell, PiNeq);
00499 }
00500 
00501 template<typename T, template<typename U> class Descriptor>
00502 void CompositeDynamics<T,Descriptor>::computeHeatFlux(Cell<T,Descriptor> const& cell,
00503                                                           Array<T,Descriptor<T>::d>& q ) const
00504 {
00505     this->getBaseDynamics().computeHeatFlux(cell, q);
00506 }
00507 
00508 template<typename T, template<typename U> class Descriptor>
00509 void CompositeDynamics<T,Descriptor>::computeMoment (
00510         Cell<T,Descriptor> const& cell, plint momentId, T* moment ) const
00511 {
00512     this->getBaseDynamics().computeMoment(cell, momentId, moment);
00513 }
00514 
00515 template<typename T, template<typename U> class Descriptor>
00516 plint CompositeDynamics<T,Descriptor>::numDecomposedVariables(plint order) const {
00517     return baseDynamics->numDecomposedVariables(order);
00518 }
00519 
00520 template<typename T, template<typename U> class Descriptor>
00521 void CompositeDynamics<T,Descriptor>::decompose (
00522         Cell<T,Descriptor> const& cell, std::vector<T>& rawData, plint order ) const
00523 {
00524     baseDynamics->decompose(cell, rawData, order);
00525 }
00526 
00527 template<typename T, template<typename U> class Descriptor>
00528 void CompositeDynamics<T,Descriptor>::recompose (
00529         Cell<T,Descriptor>& cell, std::vector<T> const& rawData, plint order ) const
00530 {
00531     baseDynamics->recompose(cell, rawData, order);
00532 }
00533 
00534 template<typename T, template<typename U> class Descriptor>
00535 void CompositeDynamics<T,Descriptor>::rescale (
00536         std::vector<T>& rawData, T xDxInv, T xDt, plint order ) const
00537 {
00538     baseDynamics->rescale(rawData, xDxInv, xDt, order);
00539 }
00540 
00541 template<typename T, template<typename U> class Descriptor>
00542 T CompositeDynamics<T,Descriptor>::computeRhoBar(Cell<T,Descriptor> const& cell) const
00543 {
00544     return this->getBaseDynamics().computeRhoBar(cell);
00545 }
00546 
00547 template<typename T, template<typename U> class Descriptor>
00548 void CompositeDynamics<T,Descriptor>::computeRhoBarJ (
00549         Cell<T,Descriptor> const& cell, T& rhoBar, Array<T,Descriptor<T>::d>& j ) const
00550 {
00551     this->getBaseDynamics().computeRhoBarJ(cell, rhoBar, j);
00552 }
00553 
00554 template<typename T, template<typename U> class Descriptor>
00555 void CompositeDynamics<T,Descriptor>::computeRhoBarJPiNeq (
00556         Cell<T,Descriptor> const& cell, T& rhoBar, Array<T,Descriptor<T>::d>& j,
00557         Array<T,SymmetricTensor<T,Descriptor>::n>& PiNeq ) const
00558 {
00559     this->getBaseDynamics().computeRhoBarJPiNeq(cell, rhoBar, j, PiNeq);
00560 }
00561 
00562 template<typename T, template<typename U> class Descriptor>
00563 T CompositeDynamics<T,Descriptor>::computeEbar(Cell<T,Descriptor> const& cell) const {
00564     return this->getBaseDynamics().computeEbar(cell);
00565 }
00566 
00567 template<typename T, template<typename U> class Descriptor>
00568 T CompositeDynamics<T,Descriptor>::getOmega() const {
00569     return baseDynamics -> getOmega();
00570 }
00571 
00572 template<typename T, template<typename U> class Descriptor>
00573 void CompositeDynamics<T,Descriptor>::setOmega(T omega_) {
00574     baseDynamics -> setOmega(omega_);
00575 }
00576 
00577 template<typename T, template<typename U> class Descriptor>
00578 T CompositeDynamics<T,Descriptor>::getParameter(plint whichParameter) const {
00579     return baseDynamics -> getParameter(whichParameter);
00580 }
00581 
00582 template<typename T, template<typename U> class Descriptor>
00583 void CompositeDynamics<T,Descriptor>::setParameter(plint whichParameter, T value) {
00584     baseDynamics -> setParameter(whichParameter, value);
00585 }
00586 
00587 template<typename T, template<typename U> class Descriptor>
00588 void CompositeDynamics<T,Descriptor>::getPopulations(Cell<T,Descriptor> const& cell, Array<T,Descriptor<T>::q>& f) const {
00589     baseDynamics -> getPopulations(cell, f);
00590 }
00591 
00592 template<typename T, template<typename U> class Descriptor>
00593 void CompositeDynamics<T,Descriptor>::getExternalField(Cell<T,Descriptor> const& cell,
00594                                                     plint pos, plint size, T* ext) const
00595 {
00596     baseDynamics -> getExternalField(cell, pos, size, ext);
00597 }
00598 
00599 template<typename T, template<typename U> class Descriptor>
00600 void CompositeDynamics<T,Descriptor>::setPopulations(Cell<T,Descriptor>& cell, Array<T,Descriptor<T>::q> const& f)
00601 {
00602     baseDynamics -> setPopulations(cell, f);
00603 }
00604 
00605 template<typename T, template<typename U> class Descriptor>
00606 void CompositeDynamics<T,Descriptor>::setExternalField(Cell<T,Descriptor>& cell, plint pos,
00607                                                     plint size, const T* ext)
00608 {
00609     baseDynamics -> setExternalField(cell, pos, size, ext);
00610 }
00611 
00612 template<typename T, template<typename U> class Descriptor>
00613 void CompositeDynamics<T,Descriptor>::defineDensity(Cell<T,Descriptor>& cell, T density) {
00614     baseDynamics -> defineDensity(cell, density);
00615 }
00616 
00617 
00618 template<typename T, template<typename U> class Descriptor>
00619 void CompositeDynamics<T,Descriptor>::defineVelocity(Cell<T,Descriptor>& cell, Array<T,Descriptor<T>::d> const& u) {
00620     baseDynamics -> defineVelocity(cell, u);
00621 }
00622 
00623 template<typename T, template<typename U> class Descriptor>
00624 void CompositeDynamics<T,Descriptor>::defineTemperature(Cell<T,Descriptor>& cell, T temperature) {
00625     baseDynamics -> defineTemperature(cell, temperature);
00626 }
00627 
00628 template<typename T, template<typename U> class Descriptor>
00629 void CompositeDynamics<T,Descriptor>::defineHeatFlux(Cell<T,Descriptor>& cell, Array<T,Descriptor<T>::d> const& q) {
00630     baseDynamics -> defineHeatFlux(cell, q);
00631 }
00632 
00633 template<typename T, template<typename U> class Descriptor>
00634 void CompositeDynamics<T,Descriptor>::defineDeviatoricStress(Cell<T,Descriptor>& cell,
00635                             Array<T,SymmetricTensor<T,Descriptor>::n> const& PiNeq)
00636 {
00637     baseDynamics -> defineDeviatoricStress(cell, PiNeq);
00638 }
00639 
00640 template<typename T, template<typename U> class Descriptor>
00641 void CompositeDynamics<T,Descriptor>::defineMoment(Cell<T,Descriptor>& cell, plint momentId, T const* value) {
00642     baseDynamics -> defineMoment(cell, momentId, value);
00643 }
00644 
00645 template<typename T, template<typename U> class Descriptor>
00646 bool CompositeDynamics<T,Descriptor>::doesAutomaticPrepareCollision() const {
00647     return automaticPrepareCollision;
00648 }
00649 
00650 template<typename T, template<typename U> class Descriptor>
00651 void CompositeDynamics<T,Descriptor>::toggleAutomaticPrepareCollision(bool flag) {
00652     automaticPrepareCollision = flag;
00653 }
00654 
00655 /* *************** Class PreparePopulationsDynamics *********************** */
00656 
00657 template<typename T, template<typename U> class Descriptor>
00658 PreparePopulationsDynamics<T,Descriptor>::PreparePopulationsDynamics (
00659         Dynamics<T,Descriptor>* baseDynamics_,
00660         bool automaticPrepareCollision_)
00661     : CompositeDynamics<T,Descriptor>(baseDynamics_, automaticPrepareCollision_)
00662 { }
00663 
00664 template<typename T, template<typename U> class Descriptor>
00665 void PreparePopulationsDynamics<T,Descriptor>::prepareCollision(Cell<T,Descriptor>& cell) {
00666     completePopulations(cell);
00667 }
00668 
00669 template<typename T, template<typename U> class Descriptor>
00670 void PreparePopulationsDynamics<T,Descriptor>::serialize(HierarchicSerializer& serializer) const
00671 {
00672     CompositeDynamics<T,Descriptor>::serialize(serializer);
00673 }
00674 
00675 template<typename T, template<typename U> class Descriptor>
00676 void PreparePopulationsDynamics<T,Descriptor>::unserialize(HierarchicUnserializer& unserializer)
00677 {
00678     CompositeDynamics<T,Descriptor>::unserialize(unserializer);
00679 }
00680 
00681 
00682 /* *************** Class BulkCompositeDynamics *********************** */
00683 
00684 template<typename T, template<typename U> class Descriptor>
00685 BulkCompositeDynamics<T,Descriptor>::BulkCompositeDynamics (
00686         Dynamics<T,Descriptor>* baseDynamics_, bool automaticPrepareCollision_)
00687     : PreparePopulationsDynamics<T,Descriptor>(baseDynamics_, automaticPrepareCollision_)
00688 { }
00689 
00690 
00691 template<typename T, template<typename U> class Descriptor>
00692 void BulkCompositeDynamics<T,Descriptor>::serialize(HierarchicSerializer& serializer) const
00693 {
00694     PreparePopulationsDynamics<T,Descriptor>::serialize(serializer);
00695 }
00696 
00697 template<typename T, template<typename U> class Descriptor>
00698 void BulkCompositeDynamics<T,Descriptor>::unserialize(HierarchicUnserializer& unserializer)
00699 {
00700     PreparePopulationsDynamics<T,Descriptor>::unserialize(unserializer);
00701 }
00702 
00703 
00704 /* *************** Class BounceBack ********************************** */
00705 
00706 template<typename T, template<typename U> class Descriptor>
00707 int BounceBack<T,Descriptor>::id =
00708     meta::registerOneParamDynamics<T,Descriptor,BounceBack<T,Descriptor> >("BounceBack");
00709 
00710 template<typename T, template<typename U> class Descriptor>
00711 BounceBack<T,Descriptor>::BounceBack(T rho_)
00712     :rho(rho_)
00713 { }
00714 
00715 template<typename T, template<typename U> class Descriptor>
00716 BounceBack<T,Descriptor>* BounceBack<T,Descriptor>::clone() const {
00717     return new BounceBack<T,Descriptor>(*this);
00718 }
00719  
00720 template<typename T, template<typename U> class Descriptor>
00721 int BounceBack<T,Descriptor>::getId() const {
00722     return id;
00723 }
00724 
00725 template<typename T, template<typename U> class Descriptor>
00726 void BounceBack<T,Descriptor>::serialize(HierarchicSerializer& serializer) const
00727 {
00728     serializer.addValue(rho);
00729 }
00730 
00731 template<typename T, template<typename U> class Descriptor>
00732 void BounceBack<T,Descriptor>::unserialize(HierarchicUnserializer& unserializer) 
00733 {
00734     PLB_PRECONDITION( unserializer.getId() == this->getId() );
00735     rho = unserializer.readValue<T>();
00736 }
00737 
00738 template<typename T, template<typename U> class Descriptor>
00739 void BounceBack<T,Descriptor>::collide (
00740         Cell<T,Descriptor>& cell,
00741         BlockStatistics& statistics )
00742 {
00743     for (plint iPop=1; iPop <= Descriptor<T>::q/2; ++iPop) {
00744         std::swap(cell[iPop], cell[iPop+Descriptor<T>::q/2]);
00745     }
00746 }
00747 
00748 template<typename T, template<typename U> class Descriptor>
00749 T BounceBack<T,Descriptor>::computeEquilibrium(plint iPop, T rhoBar, Array<T,Descriptor<T>::d> const& j,
00750                                                T jSqr, T thetaBar) const
00751 {
00752     return T();
00753 }
00754 
00755 template<typename T, template<typename U> class Descriptor>
00756 void BounceBack<T,Descriptor>::regularize(
00757         Cell<T,Descriptor>& cell, T rhoBar, Array<T,Descriptor<T>::d> const& j,
00758         T jSqr, Array<T,SymmetricTensor<T,Descriptor>::n> const& PiNeq, T thetaBar ) const
00759 { }
00760 
00761 template<typename T, template<typename U> class Descriptor>
00762 T BounceBack<T,Descriptor>::computeDensity(Cell<T,Descriptor> const& cell) const {
00763     return rho;
00764 }
00765 
00766 template<typename T, template<typename U> class Descriptor>
00767 T BounceBack<T,Descriptor>::computePressure(Cell<T,Descriptor> const& cell) const {
00768     return T();
00769 }
00770 
00771 template<typename T, template<typename U> class Descriptor>
00772 void BounceBack<T,Descriptor>::computeVelocity (
00773         Cell<T,Descriptor> const& cell,
00774         Array<T,Descriptor<T>::d>& u) const
00775 {
00776     u.resetToZero();
00777 }
00778 
00779 template<typename T, template<typename U> class Descriptor>
00780 T BounceBack<T,Descriptor>::computeTemperature(Cell<T,Descriptor> const& cell) const {
00781     return T();
00782 }
00783 
00784 template<typename T, template<typename U> class Descriptor>
00785 void BounceBack<T,Descriptor>::computeDeviatoricStress (
00786         Cell<T,Descriptor> const& cell,
00787         Array<T,SymmetricTensor<T,Descriptor>::n>& PiNeq ) const
00788 {
00789     PiNeq.resetToZero();
00790 }
00791 
00792 template<typename T, template<typename U> class Descriptor>
00793 void BounceBack<T,Descriptor>::computeHeatFlux (
00794         Cell<T,Descriptor> const& cell,
00795         Array<T,Descriptor<T>::d>& q) const
00796 {
00797     q.resetToZero();
00798 }
00799 
00800 template<typename T, template<typename U> class Descriptor>
00801 void BounceBack<T,Descriptor>::computeMoment (
00802         Cell<T,Descriptor> const& cell, plint momentId, T* moment) const
00803 { }
00804 
00805 template<typename T, template<typename U> class Descriptor>
00806 T BounceBack<T,Descriptor>::getOmega() const {
00807     return T();
00808 }
00809 
00810 template<typename T, template<typename U> class Descriptor>
00811 void BounceBack<T,Descriptor>::setOmega(T omega_)
00812 { }
00813 
00814 template<typename T, template<typename U> class Descriptor>
00815 T BounceBack<T,Descriptor>::computeRhoBar(Cell<T,Descriptor> const& cell) const {
00816     return Descriptor<T>::rhoBar(rho);
00817 }
00818 
00819 template<typename T, template<typename U> class Descriptor>
00820 void BounceBack<T,Descriptor>::computeRhoBarJ (
00821         Cell<T,Descriptor> const& cell, T& rhoBar, Array<T,Descriptor<T>::d>& j) const
00822 {
00823     rhoBar = Descriptor<T>::rhoBar(rho);
00824     j.resetToZero();
00825 }
00826 
00827 template<typename T, template<typename U> class Descriptor>
00828 void BounceBack<T,Descriptor>::computeRhoBarJPiNeq (
00829         Cell<T,Descriptor> const& cell, T& rhoBar, Array<T,Descriptor<T>::d>& j,
00830         Array<T,SymmetricTensor<T,Descriptor>::n>& PiNeq ) const
00831 {
00832     rhoBar = Descriptor<T>::rhoBar(rho);
00833     j.resetToZero();
00834     PiNeq.resetToZero();
00835 }
00836 
00837 template<typename T, template<typename U> class Descriptor>
00838 T BounceBack<T,Descriptor>::computeEbar(Cell<T,Descriptor> const& cell) const
00839 {
00840     return T();
00841 }
00842 
00843 template<typename T, template<typename U> class Descriptor>
00844 plint BounceBack<T,Descriptor>::numDecomposedVariables(plint order) const {
00845     return Descriptor<T>::q + Descriptor<T>::ExternalField::numScalars;
00846 }
00847 
00848 template<typename T, template<typename U> class Descriptor>
00849 void BounceBack<T,Descriptor>::decompose (
00850         Cell<T,Descriptor> const& cell, std::vector<T>& rawData, plint order ) const
00851 {
00852     rawData.resize(numDecomposedVariables(order));
00853     std::fill(rawData.begin(), rawData.end(), T());
00854 }
00855 
00856 template<typename T, template<typename U> class Descriptor>
00857 void BounceBack<T,Descriptor>::recompose (
00858         Cell<T,Descriptor>& cell, std::vector<T> const& rawData, plint order ) const
00859 {
00860 //     PLB_PRECONDITION( (plint)rawData.size() == numDecomposedVariables(order) );
00861 }
00862 
00863 template<typename T, template<typename U> class Descriptor>
00864 void BounceBack<T,Descriptor>::rescale (
00865         std::vector<T>& rawData, T xDxInv, T xDt, plint order ) const
00866 { }
00867 
00868 template<typename T, template<typename U> class Descriptor>
00869 bool BounceBack<T,Descriptor>::isBoundary() const {
00870     return true;
00871 }
00872 
00873 /* *************** Class NoDynamics ********************************** */
00874 
00875 template<typename T, template<typename U> class Descriptor>
00876 int NoDynamics<T,Descriptor>::id =
00877     meta::registerOneParamDynamics<T,Descriptor,NoDynamics<T,Descriptor> >("NoDynamics");
00878 
00879 template<typename T, template<typename U> class Descriptor>
00880 NoDynamics<T,Descriptor>::NoDynamics(T rho_)
00881     :rho(rho_)
00882 { }
00883 
00884 template<typename T, template<typename U> class Descriptor>
00885 NoDynamics<T,Descriptor>* NoDynamics<T,Descriptor>::clone() const {
00886     return new NoDynamics<T,Descriptor>(*this);
00887 }
00888  
00889 template<typename T, template<typename U> class Descriptor>
00890 int NoDynamics<T,Descriptor>::getId() const {
00891     return id;
00892 }
00893 
00894 template<typename T, template<typename U> class Descriptor>
00895 void NoDynamics<T,Descriptor>::serialize(HierarchicSerializer& serializer) const
00896 {
00897     serializer.addValue(rho);
00898 }
00899 
00900 template<typename T, template<typename U> class Descriptor>
00901 void NoDynamics<T,Descriptor>::unserialize(HierarchicUnserializer& unserializer)
00902 {
00903     PLB_PRECONDITION( unserializer.getId() == this->getId() );
00904     rho = unserializer.readValue<T>();
00905 }
00906 
00907 template<typename T, template<typename U> class Descriptor>
00908 void NoDynamics<T,Descriptor>::collide (
00909         Cell<T,Descriptor>& cell,
00910         BlockStatistics& statistics )
00911 { }
00912 
00913 template<typename T, template<typename U> class Descriptor>
00914 T NoDynamics<T,Descriptor>::computeEquilibrium(plint iPop, T rhoBar, Array<T,Descriptor<T>::d> const& j,
00915                                             T jSqr, T thetaBar) const
00916 {
00917     return T();
00918 }
00919 
00920 template<typename T, template<typename U> class Descriptor>
00921 void NoDynamics<T,Descriptor>::regularize(
00922         Cell<T,Descriptor>& cell, T rhoBar, Array<T,Descriptor<T>::d> const& j,
00923         T jSqr, Array<T,SymmetricTensor<T,Descriptor>::n> const& PiNeq, T thetaBar ) const
00924 { }
00925 
00926 
00927 template<typename T, template<typename U> class Descriptor>
00928 T NoDynamics<T,Descriptor>::computeDensity(Cell<T,Descriptor> const& cell) const {
00929     return rho;
00930 }
00931 
00932 template<typename T, template<typename U> class Descriptor>
00933 T NoDynamics<T,Descriptor>::computePressure(Cell<T,Descriptor> const& cell) const {
00934     return T();
00935 }
00936 
00937 template<typename T, template<typename U> class Descriptor>
00938 void NoDynamics<T,Descriptor>::computeVelocity (
00939         Cell<T,Descriptor> const& cell,
00940         Array<T,Descriptor<T>::d>& u) const
00941 {
00942     u.resetToZero();
00943 }
00944 
00945 template<typename T, template<typename U> class Descriptor>
00946 T NoDynamics<T,Descriptor>::computeTemperature(Cell<T,Descriptor> const& cell) const {
00947     return T();
00948 }
00949 
00950 template<typename T, template<typename U> class Descriptor>
00951 void NoDynamics<T,Descriptor>::computeDeviatoricStress (
00952         Cell<T,Descriptor> const& cell,
00953         Array<T,SymmetricTensor<T,Descriptor>::n>& PiNeq ) const
00954 {
00955     PiNeq.resetToZero();
00956 }
00957 
00958 template<typename T, template<typename U> class Descriptor>
00959 void NoDynamics<T,Descriptor>::computeHeatFlux (
00960         Cell<T,Descriptor> const& cell,
00961         Array<T,Descriptor<T>::d>& q) const
00962 {
00963     q.resetToZero();
00964 }
00965 
00966 template<typename T, template<typename U> class Descriptor>
00967 void NoDynamics<T,Descriptor>::computeMoment (
00968         Cell<T,Descriptor> const& cell, plint momentId, T* moment) const
00969 { }
00970 
00971 template<typename T, template<typename U> class Descriptor>
00972 T NoDynamics<T,Descriptor>::getOmega() const {
00973     return T();
00974 }
00975 
00976 template<typename T, template<typename U> class Descriptor>
00977 void NoDynamics<T,Descriptor>::setOmega(T omega_)
00978 { }
00979 
00980 template<typename T, template<typename U> class Descriptor>
00981 T NoDynamics<T,Descriptor>::computeRhoBar(Cell<T,Descriptor> const& cell) const
00982 {
00983     return (T)1 - Descriptor<T>::SkordosFactor();
00984 }
00985 
00986 template<typename T, template<typename U> class Descriptor>
00987 void NoDynamics<T,Descriptor>::computeRhoBarJ (
00988         Cell<T,Descriptor> const& cell, T& rhoBar, Array<T,Descriptor<T>::d>& j) const
00989 {
00990     rhoBar = (T)1 - Descriptor<T>::SkordosFactor();
00991     j.resetToZero();
00992 }
00993 
00994 template<typename T, template<typename U> class Descriptor>
00995 void NoDynamics<T,Descriptor>::computeRhoBarJPiNeq (
00996         Cell<T,Descriptor> const& cell, T& rhoBar, Array<T,Descriptor<T>::d>& j,
00997         Array<T,SymmetricTensor<T,Descriptor>::n>& PiNeq ) const
00998 {
00999     rhoBar = (T)1 - Descriptor<T>::SkordosFactor();
01000     j.resetToZero();
01001     PiNeq.resetToZero();
01002 }
01003 
01004 template<typename T, template<typename U> class Descriptor>
01005 T NoDynamics<T,Descriptor>::computeEbar(Cell<T,Descriptor> const& cell) const
01006 {
01007     return T();
01008 }
01009 
01010 template<typename T, template<typename U> class Descriptor>
01011 plint NoDynamics<T,Descriptor>::numDecomposedVariables(plint order) const {
01012     return Descriptor<T>::q + Descriptor<T>::ExternalField::numScalars;
01013 }
01014 
01015 template<typename T, template<typename U> class Descriptor>
01016 void NoDynamics<T,Descriptor>::decompose (
01017         Cell<T,Descriptor> const& cell, std::vector<T>& rawData, plint order ) const
01018 {
01019     rawData.resize(numDecomposedVariables(order));
01020     std::fill(rawData.begin(), rawData.end(), T());
01021 }
01022 
01023 template<typename T, template<typename U> class Descriptor>
01024 void NoDynamics<T,Descriptor>::recompose (
01025         Cell<T,Descriptor>& cell, std::vector<T> const& rawData, plint order ) const
01026 {
01027     PLB_PRECONDITION( (plint)rawData.size() == numDecomposedVariables(order) );
01028 }
01029 
01030 template<typename T, template<typename U> class Descriptor>
01031 void NoDynamics<T,Descriptor>::rescale (
01032         std::vector<T>& rawData, T xDxInv, T xDt, plint order ) const
01033 { }
01034 
01035 template<typename T, template<typename U> class Descriptor>
01036 void constructIdChain(Dynamics<T,Descriptor> const& dynamics, std::vector<int>& chain)
01037 {
01038     chain.push_back(dynamics.getId());
01039     if(dynamics.isComposite()) {
01040         constructIdChain(dynamic_cast<CompositeDynamics<T,Descriptor> const&>(dynamics).getBaseDynamics(), chain);
01041     }
01042 }
01043 
01044 template<typename T, template<typename U> class Descriptor>
01045 Dynamics<T,Descriptor> const& getBottomMostDynamics(Dynamics<T,Descriptor> const& dynamics)
01046 {
01047     if(dynamics.isComposite()) {
01048         return getBottomMostDynamics (
01049                 dynamic_cast<CompositeDynamics<T,Descriptor> const&>(dynamics).getBaseDynamics() );
01050     }
01051     else {
01052         return dynamics;
01053     }
01054 }
01055 
01056 template<typename T, template<typename U> class Descriptor>
01057 Dynamics<T,Descriptor>* cloneAndReplaceBottomDynamics(Dynamics<T,Descriptor> const& dynamics,
01058                                                       Dynamics<T,Descriptor>* newBottom)
01059 {
01060     if (!dynamics.isComposite()) {
01061         return newBottom;
01062     }
01063     Dynamics<T,Descriptor>* clonedDynamics = dynamics.clone();
01064     Dynamics<T,Descriptor>* component = clonedDynamics;
01065     Dynamics<T,Descriptor>* child = clonedDynamics;
01066     while (child->isComposite()) {
01067         component = child;
01068         child = &(dynamic_cast<CompositeDynamics<T,Descriptor>*>(child)->getBaseDynamics());
01069     }
01070     dynamic_cast<CompositeDynamics<T,Descriptor>*>(component)->replaceBaseDynamics(newBottom);
01071     return clonedDynamics;
01072 }
01073 
01074 template<typename T, template<typename U> class Descriptor>
01075 Dynamics<T,Descriptor>* cloneAndInsertAtTopDynamics(Dynamics<T,Descriptor> const& dynamics,
01076                                                     CompositeDynamics<T,Descriptor>* newTop)
01077 {
01078     if (dynamics.isComposeable()) {
01079         newTop->replaceBaseDynamics(dynamics.clone());
01080     }
01081     else {
01082         // Original top dynamics is composite but not composeable.
01083         if (dynamics.isComposite()) {
01084             CompositeDynamics<T,Descriptor> const& compositeDynamics =
01085                 dynamic_cast<CompositeDynamics<T,Descriptor>const&>(dynamics);
01086             newTop->replaceBaseDynamics(compositeDynamics.getBaseDynamics().clone());
01087             // New top is composeable. Insert right behind original top dynamics.
01088             if (newTop->isComposeable()) {
01089                 newTop = compositeDynamics.cloneWithNewBase(newTop);
01090             }
01091             // If new top is not composeable, then ignore original top dynamics.
01092         }
01093         // If original top dynamics is non composite and not composeable,
01094         //   then ignore original top dynamics.
01095     }
01096     return newTop;
01097 }
01098 
01099 template<typename T, template<typename U> class Descriptor>
01100 Dynamics<T,Descriptor>* removeBoundaryComponents(Dynamics<T,Descriptor> const& dynamics)
01101 {
01102     if (dynamics.isComposite()) {
01103         CompositeDynamics<T,Descriptor> const& compositeDynamics =
01104             dynamic_cast<CompositeDynamics<T,Descriptor>const&>(dynamics);
01105         Dynamics<T,Descriptor>* noBoundaryBase = removeBoundaryComponents(compositeDynamics.getBaseDynamics());
01106         if (dynamics.isBoundary()) {
01107             return noBoundaryBase;
01108         }
01109         else {
01110             return  dynamics.cloneWithNewBase(noBoundaryBase);
01111         }
01112     }
01113     else {
01115         return dynamics.clone();
01116     }
01117 }
01118 
01119 template<typename T, template<typename U> class Descriptor>
01120 void serialize(Dynamics<T,Descriptor> const& dynamics, std::vector<char>& data) {
01121     HierarchicSerializer serializer(data, dynamics.getId());
01122     dynamics.serialize(serializer);
01123 }
01124 
01125 template<typename T, template<typename U> class Descriptor>
01126 void serialize(std::vector<Dynamics<T,Descriptor>*> const& dynamics, std::vector<char>& data)
01127 {
01128     for (pluint iDyn=0; iDyn<dynamics.size(); ++iDyn) {
01129         serialize(*dynamics[iDyn], data);
01130     }
01131 }
01132 
01133 template<typename T, template<typename U> class Descriptor>
01134 pluint unserialize( Dynamics<T,Descriptor>& dynamics,
01135                     std::vector<char> const& data, pluint serializerPos )
01136 {
01137     PLB_ASSERT( serializerPos < data.size() );
01138     HierarchicUnserializer unserializer(data, serializerPos);
01139     dynamics.unserialize(unserializer);
01140     return unserializer.getCurrentPos();
01141 }
01142 
01144 template<typename T, template<typename U> class Descriptor>
01145 void generateAndUnserializeDynamics (
01146         std::vector<char> const& data,
01147         std::vector<Dynamics<T,Descriptor>*>& dynamics)
01148 {
01149     pluint serializerPos = 0;
01150     while (serializerPos < data.size()) {
01151         HierarchicUnserializer unserializer(data, serializerPos);
01152         dynamics.push_back (
01153                 meta::dynamicsRegistration<T,Descriptor>().generate(unserializer) );
01154         serializerPos = unserializer.getCurrentPos();
01155     }
01156 }
01157 
01158 
01159 }  // namespace plb
01160 
01161 #endif  // DYNAMICS_HH