メニュー

技術情報 Techinicalinfo

  1. ホーム
  2. 技術情報
  3. 【技術情報】有限要素法入門
  4. 4.6 有限要素法のプログラム(その4)

【技術情報】有限要素法入門

4.6 有限要素法のプログラム(その4)

ここで解析用のクラス Analysis を定義します。今までに定義した有限要素法で使用されるテーブルや物性、境界条件、荷重および節点や要素の情報を保持し、これらに対する操作を行う関数を用意します。
ファイル fem.h に次の定義をかきこんでください。


class Analysis
{
    //解析クラス
    int  anal_type;                                    // = 1 : 軸対称  = 2 : 2次元  = 3 : 3次元

    int       iccg_max;                                //ICCG法パラメータ
    double    iccg_eps;
    int       newton_max;                              //ニュートン・ラフソン法パラメータ
    double    newton_eps;

    int       numtab,numat,numbc,numld,numnp,numel;    //解析データ数

    Table**     table;                                 //テーブル
    Material**  material;                              //物性
    Boundary**  boundary;                              //境界条件
    Load**      load;                                  //荷重条件
    Node**      node;                                  //節点
    Element**   element;                               //要素

public:
    Analysis()
    {
        iccg_max = 10000;
        iccg_eps = 1.0e-6;
        newton_max = 50;
        newton_eps = 1.0e-3;
        numtab = numat = numbc = numld = numnp = numel = 0;
        table    = NULL;
        material = NULL;
        boundary = NULL;
        load     = NULL;
        node     = NULL;
        element  = NULL;
    }
    virtual ~Analysis()
    {
        for (int n=0; n<numel; n++)
            delete element[n];
        if(numel > 0) delete[] element;
        for (int n=0; n<numnp; n++)
            delete node[n];
        if(numnp > 0) delete[] node;
        for (int n=0; n<numld; n++)
            delete load[n];
        if(numld > 0) delete[] load;
        for (int n=0; n<numbc; n++)
            delete boundary[n];
        if(numbc > 0) delete[] boundary;
        for (int n=0; n<numat; n++)
            delete material[n];
        if(numat > 0) delete[] material;
        for (int n=0; n<numtab; n++)
            delete table[n];
        if(numtab > 0) delete[] table;
    }
    int getAnaltype() { return anal_type; }
    int getICCGmax() { return iccg_max; }
    double getICCGeps() { return iccg_eps; }
    int getNewtonmax() { return newton_max; }
    double getNewtoneps() {return newton_eps; }
    int getNumtab() { return numtab; }
    int getNumat() { return numat; }
    int getNumbc() { return numbc; }
    int getNumld() { return numld; }
    int getNumnp() { return numnp; }
    int getNumel() { return numel; }
    Table* getTable(int n) { return table[n]; }
    Material* getMaterial(int n) { return material[n]; }
    Boundary* getBoundary(int n) { return boundary[n]; }
    Load* getLoad(int n) { return load[n]; }
    Node* getNode(int n) { return node[n]; }
    Element* getElement(int n) { return element[n]; }
    bool isLinearanalysis();
    Table* getTimetable();
    void read(ifstream* fp_in);
    void write(ofstream* fp_out);
};

メンバー関数の実装はファイル fem.cpp に次のように行います。


//解析クラス
bool Analysis::isLinearanalysis()
{
    //線形解析か
    for (int n=0; n<numel; n++)
    {
        Material* material = element[n]->getMaterial();

        if(material->getTable(0) != NULL)
            return false;
    }
    return true;
}
Table* Analysis::getTimetable()
{
    //荷重条件に時間テーブルがあればそれを返す
    Table* timetable = NULL;
    for (int n=0; n<numld; n++)
    {
        if(load[n] != NULL)
        {
            if(load[n]->getTable() != NULL)
            {
                timetable = load[n]->getTable();
            }
        }
    }
    return timetable; 
}
void Analysis::read(ifstream* fp_in)
{
    string strArray[MAX_COLUMN];
    char str[MAX_COLUMN];

    //解析タイプの読み込み
    Input::readln(fp_in, strArray);
    strcpy(str,strArray[0].c_str()); anal_type = atoi(str);

    //解析データ数の読み込み
    Input::readln(fp_in, strArray);
    strcpy(str,strArray[0].c_str()); numtab = atoi(str);
    strcpy(str,strArray[1].c_str()); numat  = atoi(str);
    strcpy(str,strArray[2].c_str()); numbc  = atoi(str);
    strcpy(str,strArray[3].c_str()); numld  = atoi(str);
    strcpy(str,strArray[4].c_str()); numnp  = atoi(str);
    strcpy(str,strArray[5].c_str()); numel  = atoi(str);

    //配列の確保
    if(numtab > 0)
        table = new Table*[numtab];
    else
        table = NULL;
    material = new Material*[numat];
    boundary = new Boundary*[numbc];
    load     = new Load*[numld];
    node     = new Node*[numnp];
    element  = new Element*[numel];
    
    //テーブルデータの読み込み
    for (int n=0; n<numtab; n++)
    {
        table[n] = new Table();
        table[n]->read(fp_in);
    }

    //物性データの読み込み
    for (int n=0; n<numat; n++)
    {
        material[n] = new Material();
        material[n]->read(numtab,table,fp_in);
    }

    //境界条件データの読み込み
    for (int n=0; n<numbc; n++)
    {
        boundary[n] = new Boundary();
        boundary[n]->read(fp_in);
    }

    //荷重データの読み込み
    for (int n=0; n<numld; n++)
    {
        load[n] = new Load();
        load[n]->read(numtab,table,fp_in);
    }
    
    //節点データの読み込み
    for (int n=0; n<numnp; n++)
    {
        node[n] = new Node();
        node[n]->read(numbc, boundary, numld, load, fp_in);
    }

    //要素データの読み込み
    for (int n=0; n<numel; n++)
    {
        Input::readln(fp_in, strArray);
        strcpy(str,strArray[0].c_str());  int ID = atoi(str);
        strcpy(str,strArray[1].c_str());  int type = atoi(str);
        element[n] = Element::getElement(ID,type);
        element[n]->read(strArray, numat, material, numld, load, numnp, node, fp_in);
    }
}
void Analysis::write(ofstream* fp_out)
{
}