msvc: Use source folder structure for project file.
[blender.git] / intern / elbeem / intern / solver_control.cpp
index bda464f56d68d66156322e611bb9e5b54719df63..c3015b82f0a739c5342da5a435dfdd92e0630bee 100644 (file)
@@ -1,3 +1,6 @@
+/** \file elbeem/intern/solver_control.cpp
+ *  \ingroup elbeem
+ */
 /******************************************************************************
  *
  * El'Beem - the visual lattice boltzmann freesurface simulator
@@ -49,7 +52,9 @@ void LbmControlSet::initCparts() {
 
 LbmControlData::LbmControlData() : 
        mSetForceStrength(0.),
-       mCons(), mCpUpdateInterval(16), mCpOutfile(""),
+       mCons(), 
+       mCpUpdateInterval(8), // DG: was 16 --> causes problems (big sphere after some time), unstable
+       mCpOutfile(""), 
        mCpForces(), mCpKernel(), mMdKernel(),
        mDiffVelCon(1.),
        mDebugCpscale(0.), 
@@ -63,6 +68,9 @@ LbmControlData::LbmControlData() :
 
 LbmControlData::~LbmControlData() 
 {
+       while (!mCons.empty()) {
+               delete mCons.back();  mCons.pop_back();
+       }
 }
 
 
@@ -217,7 +225,10 @@ LbmFsgrSolver::initCpdata()
        
        // manually switch on! if this is zero, nothing is done...
        mpControl->mSetForceStrength = this->mTForceStrength = 1.;
-       mpControl->mCons.clear();
+       while (!mpControl->mCons.empty()) {
+               delete mpControl->mCons.back();  mpControl->mCons.pop_back();
+       }
+
        
        // init all control fluid objects
        int numobjs = (int)(mpGiObjects->size());
@@ -233,7 +244,6 @@ LbmFsgrSolver::initCpdata()
                        // dont load any file
                        cset->mContrPartFile = string("");
 
-                       // TODO dg: switch to channels later
                        cset->mcForceAtt = obj->getCpsAttrFStr();
                        cset->mcRadiusAtt = obj->getCpsAttrFRad();
                        cset->mcForceVel = obj->getCpsVelFStr();
@@ -242,6 +252,9 @@ LbmFsgrSolver::initCpdata()
                        cset->mCparts->setCPSTimeStart(obj->getCpsTimeStart());
                        cset->mCparts->setCPSTimeEnd(obj->getCpsTimeEnd());
                        
+                       if(obj->getCpsQuality() > LBM_EPSILON)
+                               cset->mCparts->setCPSWith(1.0 / obj->getCpsQuality());
+                       
                        // this value can be left at 0.5:
                        cset->mCparts->setCPSMvmWeightFac(0.5);
 
@@ -254,7 +267,9 @@ LbmFsgrSolver::initCpdata()
        if(0) {
                // manually switch on! if this is zero, nothing is done...
                mpControl->mSetForceStrength = this->mTForceStrength = 1.;
-               mpControl->mCons.clear();
+               while (!mpControl->mCons.empty()) {
+                       delete mpControl->mCons.back();  mpControl->mCons.pop_back();
+               }
 
                // add new set
                LbmControlSet *cset;
@@ -413,6 +428,10 @@ LbmFsgrSolver::handleCpdata()
                return;
        }
        
+       // check if we have control objects
+       if(mpControl->mCons.size()==0)
+               return;
+       
        if((mpControl->mCpUpdateInterval<1) || (this->mStepCnt%mpControl->mCpUpdateInterval==0)) {
                // do full reinit later on... 
        }
@@ -485,8 +504,8 @@ LbmFsgrSolver::handleCpdata()
        // init for current time
        for(int cpssi=0; cpssi<(int)mpControl->mCons.size(); cpssi++) {
                ControlParticles *cparts = mpControl->mCons[cpssi]->mCparts;
-
                LbmControlSet *cset = mpControl->mCons[cpssi];
+               
                cparts->setRadiusAtt(cset->mcRadiusAtt.get(mSimulationTime));
                cparts->setRadiusVel(cset->mcRadiusVel.get(mSimulationTime));
                cparts->setInfluenceAttraction(cset->mcForceAtt.get(mSimulationTime) );
@@ -500,18 +519,22 @@ LbmFsgrSolver::handleCpdata()
                cparts->setInfluenceVelocity( cset->mcForceVel.get(mSimulationTime), mLevel[fineLev].timestep );
                cparts->setLastOffset( vec2L(cset->mcCpOffset.get(mSimulationTime-mLevel[fineLev].timestep)) );
                cparts->setLastScale(  vec2L(cset->mcCpScale.get(mSimulationTime-mLevel[fineLev].timestep)) );
+               
        }
 
        // check actual values
-       LbmFloat iatt  = mpControl->mCons[0]->mCparts->getInfluenceAttraction();
+       LbmFloat iatt  = ABS(mpControl->mCons[0]->mCparts->getInfluenceAttraction());
        LbmFloat ivel  = mpControl->mCons[0]->mCparts->getInfluenceVelocity();
        LbmFloat imaxd = mpControl->mCons[0]->mCparts->getInfluenceMaxdist();
        //errMsg("FINCIT","iatt="<<iatt<<" ivel="<<ivel<<" imaxd="<<imaxd);
        for(int cpssi=1; cpssi<(int)mpControl->mCons.size(); cpssi++) {
-               LbmFloat iatt2  = mpControl->mCons[cpssi]->mCparts->getInfluenceAttraction();
+               LbmFloat iatt2  = ABS(mpControl->mCons[cpssi]->mCparts->getInfluenceAttraction());
                LbmFloat ivel2  = mpControl->mCons[cpssi]->mCparts->getInfluenceVelocity();
                LbmFloat imaxd2 = mpControl->mCons[cpssi]->mCparts->getInfluenceMaxdist();
-               if(iatt2 >iatt)   iatt = iatt2;
+               
+               // we allow negative attraction force here!
+               if(iatt2 > iatt)   iatt = iatt2;
+               
                if(ivel2 >ivel)   ivel = ivel2;
                if(imaxd2>imaxd)  imaxd= imaxd2;
                //errMsg("FINCIT"," "<<cpssi<<" iatt2="<<iatt2<<" ivel2="<<ivel2<<" imaxd2="<<imaxd<<" NEW "<<" iatt="<<iatt<<" ivel="<<ivel<<" imaxd="<<imaxd);
@@ -575,6 +598,12 @@ LbmFsgrSolver::handleCpdata()
        for(int cpssi=0; cpssi<(int)mpControl->mCons.size(); cpssi++) {
                ControlParticles *cparts = mpControl->mCons[cpssi]->mCparts;
                // ControlParticles *cpmotion = mpControl->mCons[cpssi]->mCpmotion;
+               
+               // if control set is not active skip it
+               if((cparts->getControlTimStart() > mSimulationTime) || (cparts->getControlTimEnd() < mLastSimTime))
+               {
+                       continue;
+               }
 
                const LbmFloat velLatticeScale = mLevel[lev].timestep/mLevel[lev].nodeSize;
                LbmFloat gsx = ((mvGeoEnd[0]-mvGeoStart[0])/(LbmFloat)mLevel[lev].lSizex);