-
Amira Abdel-Rahman authoredAmira Abdel-Rahman authored
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()));
}