Skip to content
Snippets Groups Projects
barFea.js 5.38 KiB
// Amira Abdel-Rahman
// (c) Massachusetts Institute of Technology 2019

////////////3D bar-truss fea/////////////////////
function solveFea(){
	// # determine the global matrices
	var M,K,F;
	[M,K,F]=getMatrices(setup);
	// M.print();
	// K.print();
	// F.print();
	
	// M, K, F = get_matrices(properties)
	
	// [Q,R]=tf.linalg.qr(K);

	var displacements=lusolve(K.arraySync(), F.arraySync(),false);
	// console.log(displacements);

	updateDisplacement(displacements);
	var X= tf.tensor(displacements);//change later to more effecient solver
	console.log("Displacements:")
	X.print();

	// # determine the stresses in each element
	var stresses = get_stresses(setup, displacements);
	updateStresses(stresses.arraySync());

	console.log("Stresses:");
	stresses.print()

	// console.log(setup);
	//TODO CHECK SINGULARITY AND DOFSC

}

function getMatrices(setup){
	

	var M = tf.zeros([setup.ndofs,setup.ndofs]);
	var K = tf.zeros([setup.ndofs,setup.ndofs]);
	  
	for(var ii=0;ii<setup.edges.length;ii++){
		var element=setup.edges[ii];
		var fromPoint= toTf3D(setup.nodes[element.source].position);
		var toPoint= toTf3D(setup.nodes[element.target].position);
		var dofs=[];
		dofs.push(...setup.nodes[element.source].degrees_of_freedom);
		dofs.push(...setup.nodes[element.target].degrees_of_freedom);

		var  element_vector=tf.sub (toPoint,fromPoint);
		
		
		var length   = element_vector.norm();
		var rho = tf.scalar(element.density);
		var area = tf.scalar(element.area);
		var E = tf.scalar(element.stiffness);// youngs modulus
	
		var Cm = tf.div(tf.mul(rho,tf.mul(area,length)),tf.scalar(6.0));//rho * area * length /6.0
		var Ck= tf.div(tf.mul(E,area),length);//E * area / length 
		// Cm.print();

		var m = tf.tensor ([[2,1],[1,2]]) ;
		var k = tf.tensor([[1,-1],[-1,1]]);

		var x_axis=tf.tensor ([1,0,0]);
		var y_axis=tf.tensor ([0,1,0]);
		var z_axis=tf.tensor ([0,0,1]);

		// # find rotated mass and stifness matrices
		var tau = rotation_matrix(element_vector, x_axis,y_axis,z_axis);
		var m_r=tf.matMul(tau,tf.matMul(m,tau) ,true ,false) //tau.T.dot(m).dot(tau)
		var k_r=tf.matMul(tau,tf.matMul(k,tau) ,true ,false) //tau.T.dot(k).dot(tau)

		// # change from element to global coordinate
		var B=tf.zeros([6,setup.ndofs]);
		var B=[]
		for(var i=0;i<6;i++){
			B.push([]);
			for(var j=0;j<setup.ndofs;j++){
				B[i].push(0.0);
			}
		}
		for(var i=0;i<6;i++){
			B[i][dofs[i]]=1.0;
		}
		
		B=tf.tensor(B);
		// B.print()
		
		
		var M_rG=tf.matMul(B,tf.matMul(m_r,B) ,true ,false) //B.T.dot(m_r).dot(B)
		var K_rG=tf.matMul(B,tf.matMul(k_r,B) ,true ,false) //B.T.dot(k_r).dot(B)

		M=tf.add(M,tf.mul(Cm, M_rG));  //+= Cm * M_rG
		K=tf.add(K,tf.mul(Ck, K_rG));  //+= Ck * K_rG

	}
	


	// # construct the force vector
	var F=[];
	for(var i=0;i<setup.nodes.length;i++){
		F.push(setup.nodes[i].force.x);
		F.push(setup.nodes[i].force.y);
		F.push(setup.nodes[i].force.z);
	}
	F=tf.tensor(F);
	// # remove the restrained dofs
	var remove_indices=[];
	for(var i=0;i<setup.nodes.length;i++){
		for(var j=0;j<setup.nodes[i].degrees_of_freedom.length;j++){
			if(setup.nodes[i].restrained_degrees_of_freedom[j]){
				remove_indices.push(setup.nodes[i].degrees_of_freedom[j]);
			}
		}
	}
	// M.print();
	// K.print();
	// F.print();

	for(var i=0;i<2;i++){
		M=tf_delete(M,remove_indices,i);
		K=tf_delete(K,remove_indices,i);
	}
	

	F=tf_delete(F,remove_indices,0);

	// M.print()
	// K.print()
	// F.print()
	return [ M,K,F ]
}

function get_stresses(setup,X){
	//   # find the stresses in each member
	var stresses=[];
	for(var ii=0;ii<setup.edges.length;ii++){
		var element=setup.edges[ii];
		// # find the element geometry
		var fromPoint= toTf3D(setup.nodes[element.source].position);
		var toPoint= toTf3D(setup.nodes[element.target].position);
		var dofs=[];
		dofs.push(...setup.nodes[element.source].degrees_of_freedom);
		dofs.push(...setup.nodes[element.target].degrees_of_freedom);
		var  element_vector=tf.sub (toPoint,fromPoint);

		var x_axis=tf.tensor ([1,0,0]);
		var y_axis=tf.tensor ([0,1,0]);
		var z_axis=tf.tensor ([0,0,1]);

		// # find rotated mass and stifness matrices
		var tau = rotation_matrix(element_vector, x_axis,y_axis,z_axis);

		var global_displacements=tf.tensor([setup.nodes[element.source].displacement.x,setup.nodes[element.source].displacement.y,setup.nodes[element.source].displacement.z,
			setup.nodes[element.target].displacement.x,setup.nodes[element.target].displacement.y,setup.nodes[element.target].displacement.z]) //# todo change

		// # nodal displacement
		var q=tf.dot(tau,global_displacements);
		var q=tf.unstack(q);

		var strain=tf.div(tf.sub(q[1],q[0]),element_vector.norm()); //todo check smarter way to do it
		
		var E = tf.scalar(element.stiffness);
		var stress=tf.mul(E,strain);
		stresses.push(stress);
	} 

	return tf.stack(stresses,0);
}

///////utils////////
function rotation_matrix(element_vector, x_axis, y_axis, z_axis){
	// # find the direction cosines
	var x_proj = direction_cosine(element_vector, x_axis);
	var y_proj = direction_cosine(element_vector, y_axis);
	var z_proj = direction_cosine(element_vector, z_axis);
	var zero=tf.tensor([0]);
	var temp1=tf.concat([x_proj.expandDims(0), y_proj.expandDims(0), z_proj.expandDims(0), zero, zero, zero]);
	var temp2=tf.concat([ zero, zero, zero, x_proj.expandDims(0), y_proj.expandDims(0), z_proj.expandDims(0)]);
	return tf.stack([temp1,temp2]);

}

function direction_cosine(vec1, vec2){
	return tf.div(tf.dot(vec1,vec2) ,tf.mul( vec1.norm() , vec2.norm()));
}