void QVX_TensileTest::BeginTensileTest(QVX_Sim* pSim, int NumStepIn, double ConvThreshIn, Vec3D<double> MixRadIn, MatBlendModel ModelIn, double PolyExpIn)
//void QVX_TensileTest::BeginTensileTest(QVX_Environment* pEnvIn, int NumStepIn, double ConvThreshIn, double MixRadiusIn, MatBlendModel ModelIn, double PolyExpIn)
{
	//set up local copy of the environment and object...
	//QVX_Environment* pEnvIn = (QVX_Environment*) pSim->pEnv;

		
	LocObj = *(pSim->pEnv->pObj); //otherwise just simulate the original object.
	LocEnv = *pSim->pEnv; //set local environment params to those of the input
	LocEnv.pObj = &LocObj; //make sure local environment points to local object

	//set up blending if desired
	bool EnableBlending = false;
	if (MixRadIn.x != 0 || MixRadIn.y != 0 || MixRadIn.z != 0){ //if some blending...
		//check for 2 or fewer materials!
		if (LocObj.GetNumLeafMatInUse() > 2){
			QMessageBox::warning(NULL, "Warning", "Currently blending only supported with 2 or fewer materials. Aborting.");
			return;
		}
		EnableBlending = true;
		MixRadius = MixRadIn;
		BlendModel = ModelIn;
		PolyExp = PolyExpIn;

		if (MixRadius.x==0)MixRadius.x = LocObj.GetLatticeDim()/10000; //set to tiny fraction to avoid blowup of exponential function
		if (MixRadius.y==0)MixRadius.y = LocObj.GetLatticeDim()/10000; //set to tiny fraction to avoid blowup of exponential function
		if (MixRadius.z==0)MixRadius.z = LocObj.GetLatticeDim()/10000; //set to tiny fraction to avoid blowup of exponential function

		RenderMixedObject(pSim->pEnv->pObj, &LocObj, MixRadius); //if there's any mixing, we need to make it...

	}
	EnableFeature(VXSFEAT_BLENDING, EnableBlending);
	
	NumStep = NumStepIn;
	ConvThresh = ConvThreshIn;
	CurTick = 0;
	TotalTick = NumStep;
	CancelFlag = false;

	std::string Message = "";

	LocEnv.EnableFloor(false);
	LocEnv.EnableGravity(false);
	LocEnv.EnableTemp(false);

	Import(&LocEnv, NULL, &Message);
	EnableFeature(VXSFEAT_COLLISIONS, false);
	EnableFeature(VXSFEAT_EQUILIBRIUM_MODE, true);
	EnableFeature(VXSFEAT_PLASTICITY, false);
	EnableFeature(VXSFEAT_FAILURE, false);
	EnableFeature(VXSFEAT_VOLUME_EFFECTS, pSim->IsFeatureEnabled(VXSFEAT_VOLUME_EFFECTS)); //enables volume effects according to last set physics sandbox value
	SetStopConditionType(SC_MIN_MAXMOVE);
	SetStopConditionValue(ConvThreshIn);

	if (!DoBCChecks()) return;

	OutFilePath = QFileDialog::getSaveFileName(NULL, "Save Tensile Test Results", GetLastDir(), "TXT Files (*.txt)");
	
	pTensileView->VoxMesh.LinkSimVoxels(this, pTensileView);
	pTensileView->VoxMesh.DefMesh.DrawSmooth=false;

	//match view to current selection of the physics sandbox
	pTensileView->SetCurViewCol(pSim->pSimView->GetCurViewCol());
	pTensileView->SetCurViewMode(pSim->pSimView->GetCurViewMode());
	pTensileView->SetCurViewVox(pSim->pSimView->GetCurViewVox());
	pTensileView->SetViewAngles(pSim->pSimView->GetViewAngles());
	pTensileView->SetViewForce(pSim->pSimView->GetViewForce());
	emit StartExternalGLUpdate(33);

	TestRunning = true;
	if (OutFilePath != "") TensileThread.Execute(false);
//	RunTensileTest(&DispMesg);
	if (ProgressMessage != "") QMessageBox::warning(NULL, "warning", QString::fromStdString(ProgressMessage));

}
Example #2
0
void CommandLineParser::ParseToken(CStdString sToken)
{
	CStdString sSwitch = GetSwitchKeyFromToken(sToken);

	if (m_bFirstToken)
	{
		m_bFirstToken = false;
		CStdString sTemp = sToken;
		if (sTemp.ToLower().Find(_T(".exe"))!=-1)
			return;

		if (sSwitch.IsEmpty())
			return; // probably the filename without exe on it
	}

	if (sSwitch == _T("install"))
	{
		m_bInstall = true;
	}
	else if (sSwitch == _T("uninstall"))
	{
		m_bUninstall = true;
	}
	else if (sSwitch == _T("silent"))
	{
		m_bIsSilent = true;
	}
	else if (sSwitch == _T("quiet"))
	{
		m_bIsQuiet = true;
	}
	else if (sSwitch == _T("repair"))
	{
		m_bRepair = true;
	}
	else if (sSwitch == _T("reinstall"))
	{
		m_bReinstall = true;
	}
	else if (sSwitch == _T("logfile"))
	{
		m_sLogFile = GetValueFromToken(sToken);
		m_bSeenBadParams |= m_sLogFile.IsEmpty();
	}
	else if (sSwitch == _T("licfile"))
	{
		m_sLicFile = GetValueFromToken(sToken);
		m_bSeenBadParams |= m_sLicFile.IsEmpty();
	}
	else if (sSwitch == _T("err"))
	{
		m_bShowDemoError = true;
	}
	else if (sSwitch == _T("userinit"))
	{
		m_bUserInit = true;
		
		m_bIsSilent = true;
	}
	else if (sSwitch == _T("notesinifile"))
	{
		m_sNotesIniFile = GetValueFromToken(sToken);
	}
	else if (sSwitch == _T("email"))
	{
		m_sEmailProvider  = GetValueFromToken(sToken);
		m_bSeenBadParams |= m_sEmailProvider.IsEmpty();
	}
	else if (sSwitch == _T("wordintegration"))
	{
		m_bInstallWordMacro = true;
	}
	else if( sSwitch == _T("skipcheck") )
	{
		m_bSkipCheck = true;
	}
	else if( sSwitch == _T("module") )
	{
		m_modulesMask.SetMask( _ttoi( GetValueFromToken( sToken ).c_str() ) );
		m_bModulesSpecifiedOnCmdLine = true;
	}
	else if( sSwitch == _T("review") )
	{
		EnableFeature( ModulesMask::REVIEW, GetBoolFromToken(sToken) );
	}
	else if( sSwitch == _T("protect") )
	{
		EnableFeature( ModulesMask::SECURITY, GetBoolFromToken(sToken) );
	}
	else if( sSwitch == _T("compare") )
	{
		EnableFeature( ModulesMask::COMPARE, GetBoolFromToken(sToken) );
	}
	else if( sSwitch == _T("sharepoint") )
	{
		EnableFeature( ModulesMask::SHAREPOINT, GetBoolFromToken(sToken) );
	}
	else if (sSwitch == _T("securefiletransfer") )
	{
		if (GetBoolFromToken(sToken))
		{
			EnableFeature(ModulesMask::SECURITY, GetBoolFromToken(sToken) );
		}
		EnableFeature(ModulesMask::SECUREFILETRANSFER, GetBoolFromToken(sToken) );
	}
    else if( sSwitch == _T("installshortcuts") )
    {
        CStdString sVal = GetValueFromToken(sToken);
        if (sVal.ToLower() == _T("false"))
        {
            m_bInstallShortcuts = false;
        }
        else
        {
            m_bInstallShortcuts = true;
        }
    }
	else if ( sSwitch == _T("hygiene") )
	{
		m_bHygiene = true;
	}
	else if (sSwitch == _T("dontshowwelcome"))
	{
		m_bShowWelcomeScreenAfterInstall = false;
	}
	else if (sSwitch.CompareNoCase(_T("treaterrorsaswarnings")) == 0)
	{
		m_bTreatErrorsAsWarnings = true;
	}
	else if (sSwitch.CompareNoCase(_T("installlocation")) == 0)
	{
		m_sInstallLocation = GetValueFromToken(sToken);
	}
	else if (sSwitch == _T("configuredmsonly"))
	{
		m_bConfigureDmsOnly = true;
		m_bIsSilent = true;
	}
	else
	{
		m_bSeenBadParams = true;
	}
}
void QVX_TensileTest::RunTensileTest(QString* pDispMessage)
{
	QFile File(OutFilePath);
		
	if (!File.open(QIODevice::WriteOnly | QIODevice::Text)) {
		ProgressMessage = "Could not open file. Aborting.";
		return;
	}
	QTextStream out(&File); 

//	double CurMaxDisp = 9e9;
	std::string IntMsg;

	vfloat StepPercAmt = 1.0/NumStep;
	int VoxCount = NumVox();

	int count = 0;
	int MinimumPerStep = 5;

	int NumBCs = pEnv->GetNumBCs();
	for (int j=0; j<NumBCs; j++){
		if (pEnv->GetBC(j)->Displace.Length2() == 0 ) continue; //if zero displacement, continue
		out << "Disp (m)" << "\t" << "Force (N)" << "\t";
		if (IsBasicTensile){out << "Strain (%)" << "\t" << "Stress (MPa)" << "\t" << "Modulus (MPa)" << "\t";}
	}
	
	out << "\n";

	double LastStress; //so we can calculate modulus at each point for simple tensile...
	double LastStrain;
	double MaxMotion = -FLT_MAX; //the stop condition will be a threshold of this in auto mode
	double LastMotion = 0;
	bool FoundMaxMotion = false;
	if (AutoConverge){ ConvThresh = 0; SetStopConditionValue(ConvThresh);}//don't stop until we get a max

	for (int i=0; i<NumStep; i++){
		ProgressMessage = "Performing tensile test...";
		for (int j=0; j<VoxCount; j++) VoxArray[j].ScaleExternalInputs((i+1)*StepPercAmt);
		//wiat to settle between timesteps...
		int LastBroken = -1;
		ClearHistories(); //needed so it doesn't immediately "converge" on the next time step


		while (NumBroken() != LastBroken){ //if one breaks, repeat the settling until we're done breaking...
			LastBroken = NumBroken();
			EnableFeature(VXSFEAT_FAILURE, false);

		//	EnableFailure(false);
	
//			SetSlowDampZ(CurDamp);

			count = 0;
//			bool LastUnder = false; //were we under the threshhold last time?
//			while (!LastUnder || CurMaxDisp > ConvThresh){
			while (!StopConditionMet()){
	//			if (CurMaxDisp < ConvThresh) LastUnder = true;


				for (int i=0; i<MinimumPerStep; i++){
					if (CancelFlag) break;

					if (!TimeStep(&IntMsg)){ //always do at least 5 steps...
						ProgressMessage = "Tensile test failed. \n \n" + IntMsg;
						CancelFlag = true; //get outta here!
					}
//					CurMaxDisp = SS.NormObjDisp;
				}
				if (CancelFlag) break;
				
				if (!FoundMaxMotion && AutoConverge){
					if (MotionZeroed){ //find first max motion (actually max KE, but close enough)
						FoundMaxMotion = true;
						ConvThresh = LastMotion / AutoConvergeExp;
						SetStopConditionValue(ConvThresh);
						//ProgressMessage = "Auto convergence threshhold calculated: " + QString::number(ConvThresh).toStdString();
					}
					else LastMotion = SS.MaxVoxVel*dt;
				}

				if (count%100==0){
					ProgressMessage = "Performing tensile test...";
					if (AutoConverge && !FoundMaxMotion) ProgressMessage += "\nDetermining convergence threshhold.";
					//else ProgressMessage += "\nMotion at " + QString::number(MaxMoveHistory[0]*1000000, 'g', 3).toStdString() + "/" + QString::number(ConvThresh, 'g', 3).toStdString();
					else ProgressMessage += "\nStep " + QString::number(count, 'g', 3).toStdString() +/*", Max Displacement " + QString::number(SS.MaxVoxDisp, 'g', 3).toStdString() + */", Convergence threshhold " + QString::number(ConvThresh, 'g', 3).toStdString();

					if (count > 20000){
						ProgressMessage += "\nSimulation not converging.\nConsider retrying with a larger threshold. (Currently " + QString::number(MaxMoveHistory[0]*1000, 'g', 3).toStdString() +")";
					}	
				}

				count+=MinimumPerStep;

			}
			if (CancelFlag) break;

			EnableFeature(VXSFEAT_FAILURE, true);
//			EnableFailure(true); //do one step to apply breaking and re-settle as needed...
			if (!TimeStep(&IntMsg)){
				ProgressMessage = "Tensile test failed. \n \n" + IntMsg;
				CancelFlag = true; //get outta here!
			}
		}

		for (int j=0; j<NumBCs; j++){
			CVX_FRegion* pThisBC = pEnv->GetBC(j);
			if (pThisBC->Displace.Length2() != 0 ){ //if non-zero displacement
				double CurDisp = pThisBC->Displace.Length()*(i+1.0)/((double)NumStep);
				double tmp2 = -GetSumForceDir(pThisBC);
				out << CurDisp << "\t" << tmp2 << "\t";
				if (IsBasicTensile){ //only two materials, only one with displacement, so we should only ever enter here once!!
					double ThisStress = tmp2/CSArea;
					double ThisStrain = CurDisp/IniLength;
					out << ThisStrain*100 << "\t" << ThisStress/1e6 << "\t";
					if (i!=0) out << (ThisStress-LastStress)/(ThisStrain-LastStrain)/1e6 << "\t";
					else out << "" << "\t";
					LastStress = ThisStress;
					LastStrain = ThisStrain;
				}
			}
		}
		
		out << "\n";

//		for (int k=0; k<VoxArray.size(); k++){
//			VoxArray[k].ExternalDisp *= (i+2.0)/(i+1.0);
//		}

		CurTick = i+1;
	}
	int stop = 1;

	
	File.close();
	ProgressMessage = ""; //flag to not display message boc on return...
	TestRunning = false;
	emit StopExternalGLUpdate();

}