Ejemplo n.º 1
0
/*! This bond is appended to the master bond array (BondArray). 
The behavior of the bond is determined by BondType. If the bond is permanent and should persist throughout the simulation PermIn should be to true.
@param[in] BondTypeIn The physical behavior of the bond being added.
@param[in] SIndex1 One simulation voxel index to be joined.
@param[in] SIndex2 The other simulation voxel index to be joined.
@param[in] PermIn Denotes whether this bond should persist throughout the simulation (true) or is temporary (false).
*/
bool CVX_Sim::CreateBond(BondType BondTypeIn, int SIndex1In, int SIndex2In, bool PermIn, int* pBondIndexOut, bool LinkBond) //take care of all dynamic memory stuff...
{
	if(IS_ALL_FIXED(VoxArray[SIndex1In].GetDofFixed()) && IS_ALL_FIXED(VoxArray[SIndex2In].GetDofFixed())) return true; //if both voxels are fixed don't bother making a bond. (unnecessary)

	CVXS_Bond tmp(this);
	if (!tmp.DefineBond(BondTypeIn, SIndex1In, SIndex2In, PermIn)) return false;
//	tmp.ThisBondType = BondTypeIn;
//	tmp.SetVox1SInd(SIndex1In);
//	tmp.SetVox2SInd(SIndex2In);
//	tmp.OrigDist = VoxArray[SIndex2In].GetOrigPos() - VoxArray[SIndex1In].GetOrigPos(); //was S.Pos
//	tmp.Perm = PermIn; 

//	tmp.UpdateConstants(); //do this here, cause we can...

	BondArray.push_back(tmp);
	
	int MyBondIndex = NumBond()-1;

	if(LinkBond){
		VoxArray[SIndex1In].LinkBond(MyBondIndex); // .BondInds.push_back(NumBond());
		VoxArray[SIndex2In].LinkBond(MyBondIndex); // BondInds.push_back(NumBond());
	}
	if (pBondIndexOut) *pBondIndexOut = MyBondIndex;
	return true;
}
Ejemplo n.º 2
0
Vec3D<> CVXS_Voxel::CalcTotalScaleForce(void) //calculate Scaling force
{
	Vec3D<> TotalSForce(0,0,0);

	Vec3D<> TmpThisForce;

	for (int i=0; i<GetNumLocalBonds(); i++){
		TmpThisForce -= GetBond(i)->GetForce1(); //positive for tension, negative for compression
	}

	//add forces to enforce poissons ratio...
	vfloat MyStiff = p_Sim->LocalVXC.GetLeafMat(MatIndex)->GetElasticMod()*p_Sim->LocalVXC.GetLatticeDim();
	TotalSForce += Vec3D<>((S.Angle.Conjugate()*CQuat<double>(TmpThisForce)*S.Angle).ToVec()); //add in the force internal to the voxel...
	TotalSForce -= 2*MyStiff*(S.Scale-OriginalSize);
	vfloat poiss = 0.5;
	if (p_Sim->PoissonKickBackEnabled) {
		vfloat VolScale = OriginalSize.x*OriginalSize.y*OriginalSize.z/(S.Scale.x*S.Scale.y*S.Scale.z); //>1 if we're too small <1 if we're too large
		TotalSForce -= (2*poiss)*(1-VolScale) * MyStiff*(S.Scale); //arbitrary scaling factor...
	}

	TotalSForce -= 2*ScaleMass*sqrt(MyStiff/ScaleMass)*S.ScaleVel;  //Damping force for this bond:

	if (IS_ALL_FIXED(DofFixed)) TotalSForce = Vec3D<>(0,0,0);
	return TotalSForce;
}
Ejemplo n.º 3
0
bool QVX_TensileTest::DoBCChecks(void) //returns true if passes all checks
{
	int NumBCs = pEnv->GetNumBCs();
	std::vector<bool> FullFixed(NumBCs, false);
	int NumFullFixed = 0;
	for (int i=0; i<NumBCs; i++){if (IS_ALL_FIXED(pEnv->GetBC(i)->DofFixed)){ FullFixed[i] = true; NumFullFixed++;}}


	//Are there at least two fixed regions?
	if (NumFullFixed < 2){
		QMessageBox::critical(NULL, "Tensile test error", "At least two fixed boundary conditions are necessary. Aborting.");
		return false;

	}

	//(Calculate maximum presribed deflection)
	double MaxPrescDisp = 0.0;
	for (int i=0; i<NumBCs; i++){
		if (pEnv->GetBC(i)->Displace.Length() > MaxPrescDisp) MaxPrescDisp = pEnv->GetBC(i)->Displace.Length();
	}

	//Does at least one fixed region have a displacement attached to it?
	if (MaxPrescDisp == 0.0){
		QMessageBox::critical(NULL, "Tensile test error", "At least one fixed boundary conditions must have non-zero displacement. Aborting.");
		return false;
	}

	//Is the displacement reasonable? (warn if large displacement...?)
	if (MaxPrescDisp/NumStep > pEnv->pObj->GetLatticeDim()){
		if (QMessageBox::warning(NULL, "Tensile test warning", "Displacement steps are larger than the voxel size. This may cause instability. Do you want to continue?", QMessageBox::Yes | QMessageBox::No)!=QMessageBox::Yes) return false;
	}

	//Are there any forces? (warn that they will be constant throughout simulation)
	//if (pEnv->Forced.size() != 0) QMessageBox::warning(NULL, "Tensile test warning", "Forcing boundary conditions present. Applied forces will be constant throughout tensile test.");

	//checks for a basic, full tensile test:
	
	IsBasicTensile = true; //assume it is until proven false
	int DisplacedBCInd = 0; //which BC is fixed? (can only be 0 or 1)
	//Are all voxel present?
	if (LocObj.GetNumVox() != LocObj.GetStArraySize()) IsBasicTensile = false;
	//are there exactly two BC's, both of them fully fixed?
	if (NumFullFixed != 2 || NumBCs != 2) IsBasicTensile = false;
	//is at least one not moving?
	if (!(pEnv->GetBC(0)->Displace.Length() == 0 || pEnv->GetBC(1)->Displace.Length()==0)) IsBasicTensile = false;
	//is at least one moving?
	if (!(pEnv->GetBC(0)->Displace.Length() != 0 || pEnv->GetBC(1)->Displace.Length()!=0)) IsBasicTensile = false;
	//record which one is fixed
	if (pEnv->GetBC(0)->Displace.Length() == 0) DisplacedBCInd = 1;
	//else DisplacedBCInd already 0...
	//is box shaped regions?
	if (!pEnv->GetBC(0)->IsBox()) IsBasicTensile = false;
	if (!pEnv->GetBC(1)->IsBox()) IsBasicTensile = false;


	//is the BCdisplaced in only one dimension?

	//check if in X Direction...
	if (pEnv->GetBC(DisplacedBCInd)->Displace.x != 0){
		if (pEnv->GetBC(DisplacedBCInd)->Displace.y != 0) IsBasicTensile = false;
		if (pEnv->GetBC(DisplacedBCInd)->Displace.z != 0) IsBasicTensile = false;
		for (int i=0; i<2; i++){
			if (!(pEnv->GetBC(i)->GetRegion()->X == 0.0 || pEnv->GetBC(i)->GetRegion()->X > 1-1.0/LocObj.GetVXDim())) IsBasicTensile = false;
			if (pEnv->GetBC(i)->GetRegion()->Y != 0.0) IsBasicTensile = false;
			if (pEnv->GetBC(i)->GetRegion()->Z != 0.0) IsBasicTensile = false;

			if (pEnv->GetBC(i)->GetRegion()->dX >= 1.0/LocObj.GetVXDim()) IsBasicTensile = false;
			if (pEnv->GetBC(i)->GetRegion()->dY != 1.0) IsBasicTensile = false;
			if (pEnv->GetBC(i)->GetRegion()->dZ != 1.0) IsBasicTensile = false;
		}

		if (IsBasicTensile) {
			TensileAxis = XAXIS;
			Vec3D<> Size = LocObj.GetWorkSpace();
			CSArea = Size.y*Size.z;
			IniLength = Size.x*(((double)LocObj.GetVXDim()-1.0)/LocObj.GetVXDim());
		}
	}

	//check if in Y Direction...
	if (pEnv->GetBC(DisplacedBCInd)->Displace.y != 0){
		if (pEnv->GetBC(DisplacedBCInd)->Displace.x != 0) IsBasicTensile = false;
		if (pEnv->GetBC(DisplacedBCInd)->Displace.z != 0) IsBasicTensile = false;
		for (int i=0; i<2; i++){
			if (!(pEnv->GetBC(i)->GetRegion()->Y == 0.0 || pEnv->GetBC(i)->GetRegion()->Y > 1-1.0/LocObj.GetVYDim())) IsBasicTensile = false;
			if (pEnv->GetBC(i)->GetRegion()->X != 0.0) IsBasicTensile = false;
			if (pEnv->GetBC(i)->GetRegion()->Z != 0.0) IsBasicTensile = false;

			if (pEnv->GetBC(i)->GetRegion()->dY >= 1.0/LocObj.GetVYDim()) IsBasicTensile = false;
			if (pEnv->GetBC(i)->GetRegion()->dX != 1.0) IsBasicTensile = false;
			if (pEnv->GetBC(i)->GetRegion()->dZ != 1.0) IsBasicTensile = false;
		}

		if (IsBasicTensile) {
			TensileAxis = YAXIS;
			Vec3D<> Size = LocObj.GetWorkSpace();
			CSArea = Size.x*Size.z;
			IniLength = Size.y*((LocObj.GetVYDim()-1)/LocObj.GetVYDim());
		}
	}

	//check if in Z Direction...
	if (pEnv->GetBC(DisplacedBCInd)->Displace.z != 0){
		if (pEnv->GetBC(DisplacedBCInd)->Displace.y != 0) IsBasicTensile = false;
		if (pEnv->GetBC(DisplacedBCInd)->Displace.z != 0) IsBasicTensile = false;
		for (int i=0; i<2; i++){
			if (!(pEnv->GetBC(i)->GetRegion()->Z == 0.0 || pEnv->GetBC(i)->GetRegion()->Z > 1-1.0/LocObj.GetVZDim())) IsBasicTensile = false;
			if (pEnv->GetBC(i)->GetRegion()->Y != 0.0) IsBasicTensile = false;
			if (pEnv->GetBC(i)->GetRegion()->X != 0.0) IsBasicTensile = false;

			if (pEnv->GetBC(i)->GetRegion()->dZ >= 1.0/LocObj.GetVZDim()) IsBasicTensile = false;
			if (pEnv->GetBC(i)->GetRegion()->dY != 1.0) IsBasicTensile = false;
			if (pEnv->GetBC(i)->GetRegion()->dX != 1.0) IsBasicTensile = false;
		}

		if (IsBasicTensile) {
			TensileAxis = ZAXIS;
			Vec3D<> Size = LocObj.GetWorkSpace();
			CSArea = Size.x*Size.y;
			IniLength = Size.z*((LocObj.GetVZDim()-1)/LocObj.GetVZDim());
		}
	}


	return true;
}
Ejemplo n.º 4
0
//http://klas-physics.googlecode.com/svn/trunk/src/general/Integrator.cpp (reference)
void CVXS_Voxel::EulerStep(void)
{
	double dt = p_Sim->dt;
	//bool EqMode = p_Sim->IsEquilibriumEnabled();
	if (IS_ALL_FIXED(DofFixed)){ //if fixed, just update the position and forces acting on it (for correct simulation-wide summing
		S.LinMom = Vec3D<double>(0,0,0);
		S.Pos = OriginalPos + ExtInputScale*ExternalDisp;
		S.AngMom = Vec3D<double>(0,0,0);
		S.Angle.FromRotationVector(Vec3D<double>(ExtInputScale*ExternalTDisp));
		dS.Force = CalcTotalForce();
	}
	else {
		Vec3D<> ForceTot = CalcTotalForce(); //TotVoxForce;

		//DISPLACEMENT
		S.LinMom = S.LinMom + ForceTot*dt;
		Vec3D<double> Disp(S.LinMom*(dt*_massInv)); //vector of what the voxel moves

		if(p_Sim->IsMaxVelLimitEnabled()){ //check to make sure we're not going over the speed limit!
			vfloat DispMag = Disp.Length();
			vfloat MaxDisp = p_Sim->GetMaxVoxVelLimit()*p_Sim->pEnv->pObj->GetLatticeDim();
			if (DispMag>MaxDisp) Disp *= (MaxDisp/DispMag);
		}
		S.Pos += Disp; //update position (source of noise in float mode???

		if (IS_FIXED(DOF_X, DofFixed)){S.Pos.x = OriginalPos.x + ExtInputScale*ExternalDisp.x; S.LinMom.x = 0;}
		if (IS_FIXED(DOF_Y, DofFixed)){S.Pos.y = OriginalPos.y + ExtInputScale*ExternalDisp.y; S.LinMom.y = 0;}
		if (IS_FIXED(DOF_Z, DofFixed)){S.Pos.z = OriginalPos.z + ExtInputScale*ExternalDisp.z; S.LinMom.z = 0;}

		//ANGLE
		Vec3D<> TotVoxMoment = CalcTotalMoment(); //debug
		S.AngMom = S.AngMom + TotVoxMoment*dt;

		//convert Angular velocity to quaternion form ("Spin")
		Vec3D<double> dSAngVel(S.AngMom * _inertiaInv);
		CQuat<double> Spin = 0.5 * CQuat<double>(0, dSAngVel.x, dSAngVel.y, dSAngVel.z) * S.Angle; //current "angular velocity"

		S.Angle += CQuat<double>(Spin*dt); //see above
		S.Angle.NormalizeFast(); //Through profiling, quicker to normalize every time than check to see if needed then do it...

	//	TODO: Only constrain fixed angles if one is non-zero! (support symmetry boundary conditions while still only doing this calculation) (only works if all angles are constrained for now...)
		if (IS_FIXED(DOF_TX, DofFixed) && IS_FIXED(DOF_TY, DofFixed) && IS_FIXED(DOF_TZ, DofFixed)){
			S.Angle.FromRotationVector(Vec3D<double>(ExtInputScale*ExternalTDisp));
			S.AngMom = Vec3D<>(0,0,0);
		}
	}

	//SCALE
	//	S.ScaleMom = S.ScaleMom + CalcTotalScaleForce()*p_Sim->dt;
	vfloat TempFact = 1.0;
	if(p_Sim->pEnv->IsTempEnabled()){ 
		//TempFact = (1+(p_Sim->pEnv->CurTemp-p_Sim->pEnv->TempBase)*GetCTE()); //LocalVXC.GetBaseMat(VoxArray[i].MatIndex)->GetCTE());
		
		double ThisTemp = p_Sim->pEnv->pObj->GetBaseMat(GetMaterial())->GetCurMatTemp();
		double ThisCTE = GetCTE();
		double TempBase =  p_Sim->pEnv->GetTempBase();

		TempFact = (1+(ThisTemp - TempBase)*ThisCTE);	//To allow selective temperature actuation for each different material
	}
	if (TempFact < MIN_TEMP_FACTOR) TempFact = MIN_TEMP_FACTOR;
	S.Scale = TempFact*OriginalSize;


	//Recalculate secondary:
	S.AngVel = S.AngMom * _inertiaInv;
	S.Vel = S.LinMom * _massInv;
	//vfloat LastKinE = S.KineticEnergy;
	if(p_Sim->StatToCalc & CALCSTAT_KINE) S.KineticEnergy = 0.5*Mass*S.Vel.Length2() + 0.5*Inertia*S.AngVel.Length2(); //1/2 m v^2

	////Testing:
	//if (EqMode && S.KineticEnergy < LastKinE){
	//	S.LinMom *= 0.99; //Vec3D<double>(0,0,0);
	//	S.AngMom *= 0.99; //= Vec3D<double>(0,0,0);
	//	S.Vel *= 0.99; //= Vec3D<>(0,0,0);
	//	S.AngVel*= 0.99; // = Vec3D<>(0,0,0);
	//	//S.KineticEnergy = 0;
	//	S.KineticEnergy = 0.5*Mass*S.Vel.Length2() + 0.5*Inertia*S.AngVel.Length2(); //1/2 m v^2
	//}
}