Skip to content
Snippets Groups Projects
barFea.js 5.38 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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;
    	[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()));
    }