Пример #1
0
void SolverThread::stiffnessAssembly() 
{ 
    updateF0();
    
    FEMTetrahedronMesh::Tetrahedron * tetrahedra = m_mesh->tetrahedra();
	unsigned totalTetrahedra = m_mesh->numTetrahedra();
	for(unsigned k=0;k<totalTetrahedra;k++) {
		Matrix33F Re = tetrahedra[k].Re;
		Matrix33F ReT = Re; ReT.transpose();

		for (unsigned i = 0; i < 4; ++i) {
			for (unsigned j = 0; j < 4; ++j) {
				Matrix33F tmpKe = tetrahedra[k].Ke[i][j];
				if (j >= i) {
					//Based on pseudocode given in Fig. 10.12 on page 361
					Matrix33F tmp = (Re*tmpKe)*ReT; 
					Matrix33F tmpT = tmp; tmpT.transpose();
					
					m_K_row[ tetrahedra[k].indices[i] ][tetrahedra[k].indices[j]]+=(tmp);
					
					if (j > i) {
						m_K_row[ tetrahedra[k].indices[j] ][tetrahedra[k].indices[i]]+= tmpT;
					}
				}

			}		
		}  	
	}
}
Пример #2
0
void SolverThread::addPlasticityForce(float dt) 
{
    unsigned totalTetrahedra = m_mesh->numTetrahedra();
	Vector3F * X = m_mesh->X();
    Vector3F * Xi = m_mesh->Xi();
    FEMTetrahedronMesh::Tetrahedron * tetrahedra = m_mesh->tetrahedra();
	
    for(unsigned k=0;k<totalTetrahedra;k++) {
		float e_total[6];
		float e_elastic[6];
		for(int i=0;i<6;++i)
			e_elastic[i] = e_total[i] = 0;

		//--- Compute total strain: e_total  = Be (Re^{-1} x - x0)
		for(unsigned int j=0;j<4;++j) {

			Vector3F x_j  =  X[tetrahedra[k].indices[j]];
			Vector3F x0_j = Xi[tetrahedra[k].indices[j]];
			Matrix33F ReT  = tetrahedra[k].Re; ReT.transpose();
			Vector3F prod = ReT * x_j;
			//Vector3F(ReT[0][0]*x_j.x+ ReT[0][1]*x_j.y+ReT[0][2]*x_j.z, //tmpKe*x0;
			//						   ReT[1][0]*x_j.x+ ReT[1][1]*x_j.y+ReT[1][2]*x_j.z,
				//					   ReT[2][0]*x_j.x+ ReT[2][1]*x_j.y+ReT[2][2]*x_j.z);
				
			Vector3F tmp = prod - x0_j;

			//B contains Jacobian of shape funcs. B=SN
			float bj = tetrahedra[k].B[j].x;
			float cj = tetrahedra[k].B[j].y;
			float dj = tetrahedra[k].B[j].z;

			e_total[0] += bj*tmp.x;
			e_total[1] +=            cj*tmp.y;
			e_total[2] +=                       dj*tmp.z;
			e_total[3] += cj*tmp.x + bj*tmp.y;
			e_total[4] += dj*tmp.x            + bj*tmp.z;
			e_total[5] +=            dj*tmp.y + cj*tmp.z;
		}

		//--- Compute elastic strain
		for(int i=0;i<6;++i)
			e_elastic[i] = e_total[i] - tetrahedra[k].plastic[i];

		//--- if elastic strain exceeds c_yield then it is added to plastic strain by c_creep
		float norm_elastic = 0;
		for(int i=0;i<6;++i)
			norm_elastic += e_elastic[i]*e_elastic[i];
		norm_elastic = sqrt(norm_elastic);
		if(norm_elastic > yield) {
		    float creepdt = 1.f /dt;
		    if(creepdt > creep) creepdt = creep;
			float amount = dt * creepdt;  //--- make sure creep do not exceed 1/dt
			for(int i=0;i<6;++i)
				tetrahedra[k].plastic[i] += amount*e_elastic[i];
		}

		//--- if plastic strain exceeds c_max then it is clamped to maximum magnitude
		float norm_plastic = 0;
		for(int i=0;i<6;++i)
			norm_plastic += tetrahedra[k].plastic[i]* tetrahedra[k].plastic[i];
		norm_plastic = sqrt(norm_plastic);

		if(norm_plastic > m_max) { 
			float scale = m_max/norm_plastic;
			for(int i=0;i<6;++i)
				tetrahedra[k].plastic[i] *= scale;
		}

		for(unsigned n=0;n<4;++n) {
			float* e_plastic = tetrahedra[k].plastic;
			//bn, cn and dn are the shape function derivative wrt. x,y and z axis
			//These were calculated in CalculateK function

			//Eq. 10.140(a) & (b) on page 365
			float bn = tetrahedra[k].B[n].x;
			float cn = tetrahedra[k].B[n].y;
			float dn = tetrahedra[k].B[n].z;
			float D0 = D.x;
			float D1 = D.y;
			float D2 = D.z;
			Vector3F f  = Vector3F::Zero;

			float  bnD0 = bn*D0;
			float  bnD1 = bn*D1;
			float  bnD2 = bn*D2;
			float  cnD0 = cn*D0;
			float  cnD1 = cn*D1;
			float  cnD2 = cn*D2;
			float  dnD0 = dn*D0;
			float  dnD1 = dn*D1;
			float  dnD2 = dn*D2;
			
			//Eq. 10.141 on page 365
			f.x = bnD0*e_plastic[0] + bnD1*e_plastic[1] + bnD1*e_plastic[2] + cnD2*e_plastic[3] + dnD2*e_plastic[4];
			f.y = cnD1*e_plastic[0] + cnD0*e_plastic[1] + cnD1*e_plastic[2] + bnD2*e_plastic[3] +                  + dnD2*e_plastic[5];
			f.z = dnD1*e_plastic[0] + dnD1*e_plastic[1] + dnD0*e_plastic[2] +                    bnD2*e_plastic[4] + cnD2*e_plastic[5];
			
			f *= tetrahedra[k].volume;
			int idx = tetrahedra[k].indices[n];
			m_F[idx] += tetrahedra[k].Re*f;
		}
	}
}