FEM1D 部品

最低限必要な部品。
言語は疑似コードです。

1次節点

class Node1D
{
 //■FEM
 //自身を含む節点を格納する全体リストへの参照
 //FEMクラスでも良い
 List<Node1D> Nodes;
 
 //節点自身の全体中でのIndex位置
 //行列計算でとてもよく使用する
 int GetIndex()
 {
   return this.Nodes.IndexOf(this);
 }
 
 //■要素
 //節点に接続する(節点に構築される)要素
 List<Truss1D> ConnectedElement = new List<Truss1D>();
 
 //■節点
 //初期座標
 //doubleあるいはVector1Dとして構成される
 double Initial_X = 0;
 //現在座標
 double X = 0;
 
 //初期位置からの変位
 double DX()
 {
   return this.X-this.Initial_X;
 }
 
 //コンストラクタ
 Node1D(List<Node1D> global_list, double initial_x)
 {
   this.Nodes = global_list;
   this.Initial_X = initial_x;
   this.X = this.Initial_X;
 } 
}

1次トラス要素

class Truss1D
{
 //■FEM
 //自身が所属するFEMに対する参照があっても良い

 //■節点
 //要素を構成する節点に対する参照
 //ここではインデックスで管理しているが
 //Node1Dクラスへの参照でも良い
 
 //端1
 public int TargetNodeIndex1;
 //端2
 public int TargetNodeIndex2; 
 //ばね定数
 public double k = 1;
 
 //コンストラクタ
 Truss1D()
 {
   
 }
}

FEM1D

class FEM1D
{   
 float t = 0.1;
 
 double Global_K[][];//全体剛性
 double Global_U[];//変位ベクトル
 double Global_F[];//力ベクトル
 
 //全ての節点
 List<Node1D> Node1Ds = new List<Node1D>();
 //節点の成分の次数
 int ComponentCount = 1;
 
 //全ての要素
 ArrayList<Truss1D> Truss1Ds = new ArrayList<Truss1D>();
 
 //固定された節点
 ArrayList<Integer> FixNodeIndexes = new ArrayList<Integer>();
}

マトリックス変位法

力が入力された時
変位が発生した時に実行される

 void static_displacement(List<int> fix_node_indexes, int displace_index)
 {
   double[][] copy_K = make_copy(this.Global_K);
   double[] copy_F = new double[this.Global_F.length];
   //FEM2Dだと変位境界処理で使用するためにUベクトルの更新が必要だが、
   //FEM1Dだと不要
   
   //変位境界処理
   for(int i = 0; i<this.Node1Ds.size(); i++)
   {
     Node1D node = this.Node1Ds[i];
     double dx = node.getDX(); //Uベクトルの更新にあたる処理
     
     if(contain(fix_node_indexes, i)||displace_index==i)
     {
       for(int j = 0; j<this.Node1Ds.size(); j++)
       {
         copy_F[j]-=copy_K[j][i]*dx;
         copy_K[j][i]=0;
         copy_K[i][j]=0;
       }        
       copy_F[i]=dx;
       copy_K[i][i]=1;
     }
   }    
   
   //連立方程式を解く
   double[] u = solve(copy_K, copy_F);
   copy_vector(u,this.Global_U);
   
   //変位適用
   for(int i = 0; i<Global_U.length; i++)
   {
     if(contain(fix_node_indexes, i)){continue;}             
     
     Node1D tnode = Node1Ds.get(i);      
     tnode.X = tnode.Initial_X + Global_U[i];
   }
   
   copy_vector(copy_F,this.Global_F);    
   
 }//static_displacement

全体剛性行列Kの組み立て

 void Assembly_K()
 {   
   for(int i = 0; i<Truss1Ds.size(); i++)
   {
     int str = Truss1Ds[i].TargetNodeIndex1;
     int end = Truss1Ds[i].TargetNodeIndex2;
     double k = Truss1Ds[i].k;
     
     this.Global_K[str][str] += k;
     this.Global_K[end][end] += k;
     this.Global_K[str][end] += -k;    
     this.Global_K[end][str] += -k;          
   }
 }   


この記事が気に入ったらサポートをしてみませんか?