/*************************************************************************/ /********** ChanTAUrk4.cpp *************/ /*************************************************************************/ /**** ****/ /**** Methods for the class Stepmaster ****/ /**** commands initialisation and steps of attached Steppers ****/ /**** ****/ /*************************************************************************/ #include "StepmstrRk4.h" #include "StepperRk4.h" // global Stepmaster: Stepmaster gStepmaster; Stepmaster::Stepmaster() // constructor { itsListHead = itsListTail = 0; itsCurIdx = 0; } Stepmaster::~Stepmaster() // destructor { // destroy all attached Steppers before we die StepperNode *nextNode, *curNode; for (curNode = itsListHead; curNode; curNode = nextNode) { nextNode = curNode->itsNext; delete curNode; } // now we can die peacefully } void Stepmaster::Attach( Stepper& pStepper) { // first, if the Stepper is already attached to another Stepmaster, // then remove it if (pStepper.itsMaster) pStepper.itsMaster->Remove( pStepper ); // now add the given stepper to the tail of the list StepperNode *node = new StepperNode( itsListTail, pStepper ); itsListTail = node; if (!itsListHead) itsListHead = node; // and set its pointer to point to us pStepper.itsMaster = this; } void Stepmaster::doStepinit(const real dt ) { // call the Stepinit method for all attached Steppers for (StepperNode *node=itsListHead; node; node = node->itsNext) { node->itsStepper->Init(dt); } } /* General step function. The only one that update the time */ void Stepmaster::StepAll( const real dt ) { // call the Step(dt) method for all attached Steppers for (StepperNode *node=itsListHead; node; node = node->itsNext) { node->itsStepper->Step(dt); } // now update itsCurIdx itsCurIdx = !itsCurIdx; } /* Runge Kutta step functions : one for each step of the method */ void Stepmaster::doStepk1( const real dt ) { // call the Stepk1(dt) method for all attached Steppers for (StepperNode *node=itsListHead; node; node = node->itsNext) { node->itsStepper->Stepk1(dt); } } void Stepmaster::doStepk2( const real dt ) { // call the Stepk2(dt) method for all attached Steppers for (StepperNode *node=itsListHead; node; node = node->itsNext) { node->itsStepper->Stepk2(dt); } } void Stepmaster::doStepk3( const real dt ) { // call the Stepk3(dt) method for all attached Steppers for (StepperNode *node=itsListHead; node; node = node->itsNext) { node->itsStepper->Stepk3(dt); } } void Stepmaster::doStepk4( const real dt ) { // call the Stepk4(dt) method for all attached Steppers for (StepperNode *node=itsListHead; node; node = node->itsNext) { node->itsStepper->Stepk4(dt); } } void Stepmaster::Remove( Stepper& pStepper ) { // the given Stepper is either dying or attaching to another master // so remove it from our list, and update its pointer StepperNode *curNode, *lastNode=0; for (curNode = itsListHead; curNode; lastNode = curNode, curNode = curNode->itsNext) { if ( curNode->itsStepper == &pStepper ) { // found it! now remove it from the list if (lastNode) lastNode->itsNext = curNode->itsNext; if (curNode==itsListHead) itsListHead = curNode->itsNext; if (curNode==itsListTail) itsListTail = lastNode; delete curNode; pStepper.itsMaster = 0; return; } } // if we get to this point, it means we didn't find the given Stepper // this should never happen -- if you want to throw an exception, // do it here }