Skip to content
Snippets Groups Projects
beamFea.js 8.5 KiB
Newer Older
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
// Amira Abdel-Rahman
// (c) Massachusetts Institute of Technology 2019

////////////3D bar-truss fea/////////////////////
function solveFea(){
	// # determine the global matrices
	var M,K,F;
	var t0 = performance.now();
	[M,K,F]=getMatrices(setup);
	var t1 = performance.now();
	console.log("Call to getMatrices " + (t1 - t0) + " milliseconds.");


	// M.print();
	// K.print();
	// F.print();
	
	// M, K, F = get_matrices(properties)
	
	// [Q,R]=tf.linalg.qr(K);
	t0 = performance.now();
	var displacements=lusolve(K.arraySync(), F.arraySync(),false);
	t1 = performance.now();
	console.log("Call to invert " + (t1 - t0) + " milliseconds.");
	// 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);

	// 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 A = element.area;
		var E = element.stiffness;// youngs modulus
		var G=1.0;//todo shear_modulus
		var ixx = 1.0;//todo section ixx
		var iyy = 1.0;//todo section.iyy//
		var l0=length.dataSync();
		var j=1.0;//todo check
		var l02 = l0 * l0;
        var l03 = l0 * l0 * l0;


	
		// 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]]);
		k = tf.tensor([
            [E*A/l0, 0, 0, 0, 0, 0, -E*A/l0, 0, 0, 0, 0, 0],
            [0, 12*E*ixx/l03, 0, 0, 0, 6*E*ixx/l02, 0, -12*E*ixx/l03, 0, 0, 0, 6*E*ixx/l02],
            [0, 0, 12*E*iyy/l03, 0, -6*E*iyy/l02, 0, 0, 0, -12*E*iyy/l03, 0, -6*E*iyy/l02, 0],
            [0, 0, 0, G*j/l0, 0, 0, 0, 0, 0, -G*j/l0, 0, 0],
            [0, 0, -6*E*iyy/l02, 0, 4*E*iyy/l0, 0, 0, 0, 6*E*iyy/l02, 0, 2*E*iyy/l0, 0],
            [0, 6*E*ixx/l02, 0, 0, 0, 4*E*ixx/l0, 0, -6*E*ixx/l02, 0, 0, 0, 2*E*ixx/l0],
            [-E*A/l0, 0, 0, 0, 0, 0, E*A/l0, 0, 0, 0, 0, 0],
            [0, -12*E*ixx/l03, 0, 0, 0, -6*E*ixx/l02, 0, 12*E*ixx/l03, 0, 0, 0, -6*E*ixx/l02],
            [0, 0, -12*E*iyy/l03, 0, 6*E*iyy/l02, 0, 0, 0, 12*E*iyy/l03, 0, 6*E*iyy/l02, 0],
            [0, 0, 0, -G*j/l0, 0, 0, 0, 0, 0, G*j/l0, 0, 0],
            [0, 0, -6*E*iyy/l02, 0, 2*E*iyy/l0, 0, 0, 0, 6*E*iyy/l02, 0, 4*E*iyy/l0, 0],
            [0, 6*E*ixx/l02, 0, 0, 0, 2*E*ixx/l0, 0, -6*E*ixx/l02, 0, 0, 0, 4*E*ixx/l0]
        ]);

		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([12,setup.ndofs]);
		var B=[];
		for(var i=0;i<12;i++){
			B.push([]);
			for(var j=0;j<setup.ndofs;j++){
				B[i].push(0.0);
			}
		}
		for(var i=0;i<12;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
		K=tf.add(K, 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.push(0.0);
		F.push(0.0);
		F.push(0.0);
	}
	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.source].angle.x,setup.nodes[element.source].angle.y,setup.nodes[element.source].angle.z,
											setup.nodes[element.target].displacement.x,setup.nodes[element.target].displacement.y,setup.nodes[element.target].displacement.z,
											setup.nodes[element.target].angle.x,setup.nodes[element.target].angle.y,setup.nodes[element.target].angle.z]) //# todo change

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

		var strain=tf.div(tf.sub(q[6],q[0]),element_vector.norm()); //todo check smarter way to do it
		//stress x axis
		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){ //todo check again 

	var L=element_vector.norm().arraySync();
	element_vector=element_vector.arraySync();
	// x1 = self.iNode.X
	// x2 = self.jNode.X
	// y1 = self.iNode.Y
	// y2 = self.jNode.Y
	// z1 = self.iNode.Z
	// z2 = self.jNode.Z
	// L = self.L
	
	// # Calculate direction cosines for the transformation matrix
	var l = (element_vector[0])/L;
	var m = (element_vector[1])/L;
	var n = (element_vector[2])/L;
	var D = ( l**2+ m **2+n**2)**0.5;
	// console.log(D);
	
	// if l == 0 and m == 0 and n > 0:
	//     dirCos = matrix([[0, 0, 1],
	//                      [0, 1, 0],
	//                      [-1, 0, 0]])
	// elif l == 0 and m == 0 and n < 0:
	//     dirCos = matrix([[0, 0, -1],
	//                      [0, 1, 0],
	//                      [1, 0, 0]])
	// else:
	//     dirCos = matrix([[l, m, n],
	//                      [-m/D, l/D, 0],
	//                      [-l*n/D, -m*n/D, D]])
	
	var transMatrix=tf.tensor([
	[      l,      m, n, 0, 0, 0, 0, 0, 0, 0, 0, 0],
	[   -m/D,    l/D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
	[ -l*n/D, -m*n/D, D, 0, 0, 0, 0, 0, 0, 0, 0, 0],
	[ 0, 0, 0,      l,      m, n, 0, 0, 0, 0, 0, 0],
	[ 0, 0, 0,   -m/D,    l/D, 0, 0, 0, 0, 0, 0, 0],
	[ 0, 0, 0, -l*n/D, -m*n/D, D, 0, 0, 0, 0, 0, 0],
	[ 0, 0, 0, 0, 0, 0,      l,      m, n, 0, 0, 0],
	[ 0, 0, 0, 0, 0, 0,   -m/D,    l/D, 0, 0, 0, 0],
	[ 0, 0, 0, 0, 0, 0, -l*n/D, -m*n/D, D, 0, 0, 0],
	[ 0, 0, 0, 0, 0, 0, 0, 0, 0,      l,      m, n],
	[ 0, 0, 0, 0, 0, 0, 0, 0, 0,   -m/D,    l/D, 0],
	[ 0, 0, 0, 0, 0, 0, 0, 0, 0, -l*n/D, -m*n/D, D]
	]);
		

	// # Build the transformation matrix
	// transMatrix = zeros((12, 12))
	// transMatrix[0:3, 0:3] = dirCos
	// transMatrix[3:6, 3:6] = dirCos
	// transMatrix[6:9, 6:9] = dirCos
	// transMatrix[9:12, 9:12] = dirCos
	
	return transMatrix;
}

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