Esempio n. 1
0
/******************************************************************************
 * render a whole animation (visualization mode) 
 * this function is run in another thread, and communicates 
 * with the parent thread via a mutex 
 *****************************************************************************/
int ntlWorld::renderVisualization( bool multiThreaded ) 
{
#ifndef NOGUI
	if(getElbeemState() != SIMWORLD_INITED) { return 0; }

	if(multiThreaded) mThreadRunning = true;
	// TODO, check global state?
	while(!getStopRenderVisualization()) {

		if(mpSims->size() <= 0) {
			debMsgStd("ntlWorld::renderVisualization",DM_NOTIFY,"No simulations found, stopping...",1);
			stopSimulationThread();
			break;
		}

		// determine stepsize
		if(!mSingleStepDebug) {
			long startTime = getTime();
			advanceSims(mFrameCnt);
			mFrameCnt++;
			long stopTime = getTime();
			debMsgStd("ntlWorld::renderVisualization",DM_MSG,"Time for t="<<mSimulationTime<<": "<< getTimeString(stopTime-startTime) <<" ", 10);
		} else {
			double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getTimestep();
			singleStepSims(targetTime);

			// check paniced sims (normally done by advanceSims
			bool allPanic = true;
			for(size_t i=0;i<mpSims->size();i++) {
				if(!(*mpSims)[i]->getPanic()) allPanic = false;
			}
			if(allPanic) {
				warnMsg("ntlWorld::advanceSims","All sims panicked... stopping thread" );
				setStopRenderVisualization( true );
			}
			if(! isSimworldOk() ) {
				warnMsg("ntlWorld::advanceSims","World state error... stopping" );
				setStopRenderVisualization( true );
			}
		}

		// save frame
		if(mpOpenGLRenderer) mpOpenGLRenderer->saveAnimationFrame( mSimulationTime );
		
		// for non-threaded check events
		if(!multiThreaded) {
			Fl::check();
      gpElbeemFrame->SceneDisplay->doOnlyForcedRedraw();
		}

	}
	mThreadRunning = false;
	stopSimulationRestoreGui();
#else 
	multiThreaded = false; // remove warning
#endif
	return 0;
}
/*! check status (e.g. stop/abort) from calling program, returns !=0 if sth. happened... */
int SimulationObject::checkCallerStatus(int status, int frame) {
	//return 0; // DEBUG
	int ret = 0;
	if((mpElbeemSettings)&&(mpElbeemSettings->runsimCallback)) {
		ret = (mpElbeemSettings->runsimCallback)(mpElbeemSettings->runsimUserData, status,frame);
		if(ret!=FLUIDSIM_CBRET_CONTINUE) {
			if(ret==FLUIDSIM_CBRET_STOP) {
				debMsgStd("SimulationObject::notifySolverOfDump",DM_NOTIFY,"Got stop signal from caller",1);
				setElbeemState( SIMWORLD_STOP );
			}
			else if(ret==FLUIDSIM_CBRET_ABORT) {
				errFatal("SimulationObject::notifySolverOfDump","Got abort signal from caller, aborting...", SIMWORLD_GENERICERROR );
				mPanic = 1;
			}
			else {
				errMsg("SimulationObject::notifySolverOfDump","Invalid callback return value: "<<ret<<", ignoring... ");
			}
		}
	}

	//debMsgStd("SimulationObject::checkCallerStatus",DM_MSG, "s="<<status<<",f="<<frame<<" "<<this->getName()<<" ret="<<ret);
	if(isSimworldOk()) return 0;
	return 1;
}
int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
{
	if(! isSimworldOk() ) return 1;
	
	// already inited?
	if(mpLbm) return 0;
	
	mpGlob = glob;
	if(!getVisible()) {
		mpAttrs->setAllUsed();
		return 0;
	}


	mGeoInitId = mpAttrs->readInt("geoinitid", mGeoInitId,"LbmSolverInterface", "mGeoInitId", false);
	//mDimension, mSolverType are deprecated
	string mSolverType(""); 
	mSolverType = mpAttrs->readString("solver", mSolverType, "SimulationObject","mSolverType", false ); 

	mpLbm = createSolver(); 
  /* check lbm pointer */
	if(mpLbm == NULL) {
		errFatal("SimulationObject::initializeLbmSimulation","Unable to init LBM solver! ", SIMWORLD_INITERROR);
		return 2;
	}
	debMsgStd("SimulationObject::initialized",DM_MSG,"IdStr:"<<mpLbm->getIdString() <<" LBM solver! ", 2);

	mpParts = new ParticleTracer();

	// for non-param simulations
	mpLbm->setParametrizer( mpParam );
	mpParam->setAttrList( getAttributeList() );
	// not needed.. done in solver_init: mpParam->setSize ... in solver_interface
	mpParam->parseAttrList();

	mpLbm->setAttrList( getAttributeList() );
	mpLbm->setSwsAttrList( getSwsAttributeList() );
	mpLbm->parseAttrList();
	mpParts->parseAttrList( getAttributeList() );

	if(! isSimworldOk() ) return 3;
	mpParts->setName( getName() + "_part" );
	mpParts->initialize( glob );
	if(! isSimworldOk() ) return 4;
	
	// init material settings
	string matMc("default");
	matMc = mpAttrs->readString("material_surf", matMc, "SimulationObject","matMc", false );
	mShowSurface   = mpAttrs->readInt("showsurface", mShowSurface, "SimulationObject","mShowSurface", false ); 
	mShowParticles = mpAttrs->readInt("showparticles", mShowParticles, "SimulationObject","mShowParticles", false ); 

	checkBoundingBox( mGeoStart, mGeoEnd, "SimulationObject::initializeSimulation" );
	mpLbm->setLbmInitId( mGeoInitId );
	mpLbm->setGeoStart( mGeoStart );
	mpLbm->setGeoEnd( mGeoEnd );
	mpLbm->setRenderGlobals( mpGlob );
	mpLbm->setName( getName() + "_lbm" );
	mpLbm->setParticleTracer( mpParts );
	if(mpElbeemSettings) {
		// set further settings from API struct init
		if(mpElbeemSettings->outputPath) this->mOutFilename = string(mpElbeemSettings->outputPath);
		mpLbm->initDomainTrafo( mpElbeemSettings->surfaceTrafo );
		mpLbm->setSmoothing(1.0 * mpElbeemSettings->surfaceSmoothing, 1.0 * mpElbeemSettings->surfaceSmoothing);
		mpLbm->setIsoSubdivs(mpElbeemSettings->surfaceSubdivs);
		mpLbm->setSizeX(mpElbeemSettings->resolutionxyz);
		mpLbm->setSizeY(mpElbeemSettings->resolutionxyz);
		mpLbm->setSizeZ(mpElbeemSettings->resolutionxyz);
		mpLbm->setPreviewSize(mpElbeemSettings->previewresxyz);
		mpLbm->setRefinementDesired(mpElbeemSettings->maxRefine);
		mpLbm->setGenerateParticles(mpElbeemSettings->generateParticles);
		// set initial particles
		mpParts->setNumInitialParticles(mpElbeemSettings->numTracerParticles);
		
		// surface generation flag
		mpLbm->setSurfGenSettings(mpElbeemSettings->mFsSurfGenSetting);

		string dinitType = string("no");
		if     (mpElbeemSettings->domainobsType==FLUIDSIM_OBSTACLE_PARTSLIP) dinitType = string("part"); 
		else if(mpElbeemSettings->domainobsType==FLUIDSIM_OBSTACLE_FREESLIP) dinitType = string("free"); 
		else /*if(mpElbeemSettings->domainobsType==FLUIDSIM_OBSTACLE_NOSLIP)*/ dinitType = string("no"); 
		mpLbm->setDomainBound(dinitType);
		mpLbm->setDomainPartSlip(mpElbeemSettings->domainobsPartslip);
		mpLbm->setDumpVelocities(mpElbeemSettings->generateVertexVectors);
		mpLbm->setFarFieldSize(mpElbeemSettings->farFieldSize);
		debMsgStd("SimulationObject::initialize",DM_MSG,"Added domain bound: "<<dinitType<<" ps="<<mpElbeemSettings->domainobsPartslip<<" vv"<<mpElbeemSettings->generateVertexVectors<<","<<mpLbm->getDumpVelocities(), 9 );

		debMsgStd("SimulationObject::initialize",DM_MSG,"Set ElbeemSettings values "<<mpLbm->getGenerateParticles(),10);
	}

	if(! mpLbm->initializeSolverMemory()   )         { errMsg("SimulationObject::initialize","initializeSolverMemory failed"); mPanic=true; return 10; }
	if(checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0)) { errMsg("SimulationObject::initialize","initializeSolverMemory status"); mPanic=true; return 11; } 
	if(! mpLbm->initializeSolverGrids()    )         { errMsg("SimulationObject::initialize","initializeSolverGrids  failed"); mPanic=true; return 12; }
	if(checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0)) { errMsg("SimulationObject::initialize","initializeSolverGrids  status"); mPanic=true; return 13; } 
	if(! mpLbm->initializeSolverPostinit() )         { errMsg("SimulationObject::initialize","initializeSolverPostin failed"); mPanic=true; return 14; }
	if(checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0)) { errMsg("SimulationObject::initialize","initializeSolverPostin status"); mPanic=true; return 15; } 

	// print cell type stats
	bool printStats = true;
	if(glob_mpnum>0) printStats=false; // skip in this case
	if(printStats) {
		const int jmax = sizeof(CellFlagType)*8;
		int totalCells = 0;
		int flagCount[jmax];
		for(int j=0; j<jmax ; j++) flagCount[j] = 0;
		int diffInits = 0;
		LbmSolverInterface::CellIdentifier cid = mpLbm->getFirstCell();
		for(; mpLbm->noEndCell( cid );
					mpLbm->advanceCell( cid ) ) {
			int flag = mpLbm->getCellFlag(cid,0);
			int flag2 = mpLbm->getCellFlag(cid,1);
			if(flag != flag2) {
				diffInits++;
			}
			for(int j=0; j<jmax ; j++) {
				if( flag&(1<<j) ) flagCount[j]++;
			}
			totalCells++;
		}
		mpLbm->deleteCellIterator( &cid );

		char charNl = '\n';
		debugOutNnl("SimulationObject::initializeLbmSimulation celltype stats: " <<charNl, 5);
		debugOutNnl("no. of cells = "<<totalCells<<", "<<charNl ,5);
		for(int j=0; j<jmax ; j++) {
			std::ostringstream out;
			if(flagCount[j]>0) {
				out<<"\t" << flagCount[j] <<" x "<< convertCellFlagType2String( (CellFlagType)(1<<j) ) <<", " << charNl;
				debugOutNnl(out.str(), 5);
			}
		}
		// compute dist. of empty/bnd - fluid - if
		// cfEmpty   = (1<<0), cfBnd  = (1<< 2), cfFluid   = (1<<10), cfInter   = (1<<11),
		if(1){
			std::ostringstream out;
			out.precision(2); out.width(4);
			int totNum = flagCount[1]+flagCount[2]+flagCount[7]+flagCount[8];
			double ebFrac = (double)(flagCount[1]+flagCount[2]) / totNum;
			double flFrac = (double)(flagCount[7]) / totNum;
			double ifFrac = (double)(flagCount[8]) / totNum;
			//???
			out<<"\tFractions: [empty/bnd - fluid - interface - ext. if]  =  [" << ebFrac<<" - " << flFrac<<" - " << ifFrac<<"] "<< charNl;

			if(diffInits > 0) {
				debMsgStd("SimulationObject::initializeLbmSimulation",DM_MSG,"celltype Warning: Diffinits="<<diffInits<<"!" , 5);
			}
			debugOutNnl(out.str(), 5);
		}
	} // cellstats

	// might be modified by mpLbm
	//mpParts->setStart( mGeoStart );?  mpParts->setEnd( mGeoEnd );?
	mpParts->setStart( mpLbm->getGeoStart() );
	mpParts->setEnd(   mpLbm->getGeoEnd()   );
	mpParts->setCastShadows( false );
	mpParts->setReceiveShadows( false );
	mpParts->searchMaterial( glob->getMaterials() );

	// this has to be inited here - before, the values might be unknown
	IsoSurface *surf = mpLbm->getSurfaceGeoObj();
	if(surf) {
		surf->setName( "final" ); // final surface mesh 
		// warning - this might cause overwriting effects for multiple sims and geom dump...
		surf->setCastShadows( true );
		surf->setReceiveShadows( false );
		surf->searchMaterial( glob->getMaterials() );
		if(mShowSurface) mObjects.push_back( surf );
	}
	
#ifdef ELBEEM_PLUGIN
	mShowParticles=1; // for e.g. dumping
#endif // ELBEEM_PLUGIN
	if((mpLbm->getGenerateParticles()>0.0)||(mpParts->getNumInitialParticles()>0)) {
		mShowParticles=1;
		mpParts->setDumpParts(true);
	}
		//debMsgStd("SimulationObject::init",DM_NOTIFY,"Using envvar ELBEEM_DUMPPARTICLE to set mShowParticles, DEBUG!",1);
	//}  // DEBUG ENABLE!!!!!!!!!!
	if(mShowParticles) {
		mObjects.push_back(mpParts);
	}

	// add objects to display for debugging (e.g. levelset particles)
	vector<ntlGeometryObject *> debugObjs = mpLbm->getDebugObjects();
	for(size_t i=0;i<debugObjs.size(); i++) {
		debugObjs[i]->setCastShadows( false );
		debugObjs[i]->setReceiveShadows( false );
		debugObjs[i]->searchMaterial( glob->getMaterials() );
		mObjects.push_back( debugObjs[i] );
		debMsgStd("SimulationObject::init",DM_NOTIFY,"Added debug obj "<<debugObjs[i]->getName(), 10 );
	}
	return 0;
}
Esempio n. 4
0
void ntlWorld::finishWorldInit()
{
	if(! isSimworldOk() ) return;

	// init the scene for the first time
  long sstartTime = getTime();

	// first init sim scene for geo setup
	mpGlob->getSimScene()->buildScene(0.0, true);
	if(! isSimworldOk() ) return;
	mpGlob->getRenderScene()->buildScene(0.0, true);
	if(! isSimworldOk() ) return;
	long sstopTime = getTime();
	debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Scene build time: "<< getTimeString(sstopTime-sstartTime) <<" ", 10);

	// TODO check simulations, run first steps
	mFirstSim = -1;
	if(mpSims->size() > 0) {

		// use values from first simulation as master time scale
		long startTime = getTime();
		
		// remember first active sim
		for(size_t i=0;i<mpSims->size();i++) {
			if(!(*mpSims)[i]->getVisible()) continue;
			if((*mpSims)[i]->getPanic())    continue;

			// check largest timestep
			if(mFirstSim>=0) {
				if( (*mpSims)[i]->getTimestep() > (*mpSims)[mFirstSim]->getTimestep() ) {
					mFirstSim = i;
					debMsgStd("ntlWorld::ntlWorld",DM_MSG,"First Sim changed: "<<i ,10);
				}
			}
			// check any valid sim
			if(mFirstSim<0) {
				mFirstSim = i;
				debMsgStd("ntlWorld::ntlWorld",DM_MSG,"First Sim: "<<i ,10);
			}
		}

		if(mFirstSim>=0) {
			debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Anistart Time: "<<(*mpSims)[mFirstSim]->getStartTime() ,10);
			while(mSimulationTime < (*mpSims)[mFirstSim]->getStartTime() ) {
			debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Anistart Time: "<<(*mpSims)[mFirstSim]->getStartTime()<<" simtime:"<<mSimulationTime ,10);
				advanceSims(-1);
			}
			long stopTime = getTime();

			mSimulationTime += (*mpSims)[mFirstSim]->getStartTime();
			debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Time for start-sims:"<< getTimeString(stopTime-startTime) , 1);
#ifndef NOGUI
			guiResetSimulationTimeRange( mSimulationTime );
#endif
		} else {
			if(!mpGlob->getSingleFrameMode()) debMsgStd("ntlWorld::ntlWorld",DM_WARNING,"No active simulations!", 1);
		}
	}

	if(! isSimworldOk() ) return;
	setElbeemState( SIMWORLD_INITED );
}
Esempio n. 5
0
/******************************************************************************
 * advance simulations by time t 
 *****************************************************************************/
int ntlWorld::advanceSims(int framenum)
{
	bool done = false;
	bool allPanic = true;

	// stop/quit (abort), dont display/render
	if(!isSimworldOk()) { 
		return 1;
	}

	for(size_t i=0;i<mpSims->size();i++) { (*mpSims)[i]->setFrameNum(framenum); }

	// time stopped? nothing else to do...
	if( (*mpSims)[mFirstSim]->getFrameTime(framenum) <= 0.0 ){ 
		done=true; allPanic=false; 

		/* DG: Need to check for user cancel here (fix for [#30298]) */
		(*mpSims)[mFirstSim]->checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0);
	}

	// Prevent bug [#29186] Object contribute to fluid sim animation start earlier than keyframe
	// Was: double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getFrameTime(framenum); - DG
	double totalTime = 0.0, targetTime = 0.0;
	for(size_t i = 0; i < mSimFrameCnt; i++)
	{
		/* We need an intermediate array "mSimFrameValue" because
		otherwise if we don't start with starttime = 0, 
		the sim gets out of sync - DG */
		totalTime += (*mpSims)[mFirstSim]->getFrameTime(mSimFrameValue[i]);	
	}
	targetTime = totalTime + (*mpSims)[mFirstSim]->getFrameTime(framenum);

	int gstate = 0;
	myTime_t advsstart = getTime();

	// step all the sims, and check for panic
	debMsgStd("ntlWorld::advanceSims",DM_MSG, " sims "<<mpSims->size()<<" t"<<targetTime<<" done:"<<done<<" panic:"<<allPanic<<" gstate:"<<gstate, 10); // debug // timedebug
	while(!done) {
		double nextTargetTime = (*mpSims)[mFirstSim]->getCurrentTime() + (*mpSims)[mFirstSim]->getTimestep();
		singleStepSims(nextTargetTime);

		// check target times
		done = true;
		allPanic = false;
		
		if((*mpSims)[mFirstSim]->getTimestep() <1e-9 ) { 
			// safety check, avoid timesteps that are too small
			errMsg("ntlWorld::advanceSims","Invalid time step, causing panic! curr:"<<(*mpSims)[mFirstSim]->getCurrentTime()<<" next:"<<nextTargetTime<<", stept:"<< (*mpSims)[mFirstSim]->getTimestep() );
			allPanic = true; 
		} else {
			for(size_t i=0;i<mpSims->size();i++) {
				if(!(*mpSims)[i]->getVisible()) continue;
				if((*mpSims)[i]->getPanic()) allPanic = true; // do any panic now!?
				debMsgStd("ntlWorld::advanceSims",DM_MSG, "Sim "<<i<<", currt:"<<(*mpSims)[i]->getCurrentTime()<<", nt:"<<nextTargetTime<<", panic:"<<(*mpSims)[i]->getPanic()<<", targett:"<<targetTime, 10); // debug // timedebug
			} 
		}
		if( (targetTime - (*mpSims)[mFirstSim]->getCurrentTime()) > LBM_TIME_EPSILON) done=false;
		if(allPanic) done = true;
	}

	if(allPanic) {
		warnMsg("ntlWorld::advanceSims","All sims panicked... stopping thread" );
		setStopRenderVisualization( true );
		return 1;
	}

	myTime_t advsend = getTime();
	debMsgStd("ntlWorld::advanceSims",DM_MSG,"Overall steps so far took:"<< getTimeString(advsend-advsstart)<<" for sim time "<<targetTime, 4);

	// finish step
	for(size_t i=0;i<mpSims->size();i++) {
		SimulationObject *sim = (*mpSims)[i];
		if(!sim->getVisible()) continue;
		if(sim->getPanic()) continue;
		sim->prepareVisualization();
	}

	mSimFrameValue.push_back(framenum);
	mSimFrameCnt++;

	return 0;
}