信頼性評価関連ユーティリティ

概要

信頼性評価における限界状態関数法をサポートするためのユーティリティ機能をGitHub上からパッケージとして提供する.パッケージ名はUtility,モジュール名LimitStateである.

モジュールLimitStateの利用法

  1. ターミナルモードで以下のコマンドを入力し,パッケージUtilityをインストールする
    pip install git+https://github.com/ShinsukeSakai0321/Utility
    ただし、更新の場合には
    pip install --upgrade git+https://github.com/ShinsukeSakai0321/Utility
  2. プログラム内で以下のimport文でLimitStateモジュールを読み込む
    from Utility import LimitState as ls
  3. 登録されているコマンドは以下のhelp文で確認できる
    help(ls))

基本的使い方

モジュール内のクラスLSFMを継承したクラスをユーザが定義することにより、限界状態関数法を容易に利用できる。LSFMのメソッドを以下に示す。

LSFMのメソッド内容
RFn()Rackvitz Fiessler法による設計点探索
GetBeta()信頼性指標βの取得
GetAlpha()感度ベクトルの取得
GetPOF()破損確率の取得
GetDP()設計点の取得
GetConv()RF法の収束回数の取得
GetPSF()部分安全係数の取得

例題1

RSモデルへの適用例


プログラムリスト

        # RSモデル
        # 限界状態関数クラスを新規に定義して利用する場合
        class GRS(ls.LSFM):  #LSFMから継承する
            def __init__(self,n,muX,sigmmaX,dist):
                super().__init__(n,muX,sigmmaX,dist)
            def gcalc(self,X): #g値を計算する仮想関数
                R=X[0]
                S=X[1]
                g=R-S  #限界状態関数
                return g  #必ずg値を戻す
            def dGdXcalc(self,X): #gの微分ベクトルを計算する仮想関数
                R=X[0]
                S=X[1]
                dGdX=[0]*len(X) #Xと同じ大きさのリストを作る
                dGdX[0] =1.0
                dGdX[1] =-1.0
                return dGdX #必ず微分ベクトルを戻す
        dist=['normal','normal'] #分布形はweibull,normal,lognormal,gumbel,uniformのいずれか
        muX=[200,100]
        sigmmaX=[10,20]
        n=2
        rs=GRS(n,muX,sigmmaX,dist) #インスタンスの生成
        rs.RFn()
        rs.GetBeta()
            #
        
この結果,以下の出力を確認する.
4.47213595499958

このように、LSFMクラスを継承した上で、__init__関数、仮想関数のgcalc、dGdXcalc関数を定義するだけで、限界状態関数法の計算が可能となる

例題2

限界状態関数や変数を文字列で定義し,平均値,標準偏差を指定する場合.最も簡単な利用法.

注意:変数として使用可能な文字は小文字のみです.


プログラムリスト

            g="r-s"
            var =['r','s']
            muX =[200,100]
            sigmmaX=[10,20]
            dist =["normal", "normal"]
            aa =ls.GeneralG(g,var,len(var),muX,sigmmaX,dist)
            aa.RFn()
            aa.GetBeta()
        
この結果,以下の出力を確認する.
            4.47213595499958

        

例題3

下記文献の検証 "Probability, Reliability and Statistical Methods
in Engineering Design" Achintya Haldar & Sankaran Mahadevan
P.218 Table 7.5, 7.6


プログラムリスト

            # 限界状態関数を文字列で与えて利用する場合
            g="As*fy*d*(1.0-eta*As*fy/b/d/fcd)-M"
            var =["As","fy","fcd","b","d","eta","M"]
            muX =[1.56, 47.7, 3.5, 8.0, 13.2, 0.59, 326.25]
            covX =[0.036, 0.15, 0.21, 0.045, 0.086, 0.05, 0.17]
            sigmmaX = list(np.array(covX)*np.array(muX))
            dist =["normal", "normal", "normal", "normal" ,"normal" ,"normal" ,"normal" ]
            aa =ls.GeneralG(g,var,len(var),muX,sigmmaX,dist)
            aa.RFn()
            a1=aa.GetBeta()
            dist[6]="lognormal"
            aa =ls.GeneralG(g,var,len(var),muX,sigmmaX,dist)
            aa.RFn()
            a2=aa.GetBeta()
            dist=["lognormal", "lognormal", "lognormal", "lognormal" ,"lognormal" ,"lognormal" ,"normal"]
            aa =ls.GeneralG(g,var,len(var),muX,sigmmaX,dist)
            aa.RFn()
            a3=aa.GetBeta()
            dist=["lognormal", "lognormal", "lognormal", "lognormal" ,"lognormal" ,"lognormal" ,"lognormal"]
            aa =ls.GeneralG(g,var,len(var),muX,sigmmaX,dist)
            aa.RFn()
            a4=aa.GetBeta()
            [a1,a2,a3,a4]
        
        この結果,以下の信頼性指標の出力を確認する.
        

[3.8330281658128675, 3.7612536656241864, 4.3876843910772845, 4.090647398473586]

例題4

例題3と同じ問題について直接限界状態関数を定義して利用する方法。PYTHONの数式処理機能を利用すると便利。
例題3よりは、処理速度が早くなる。


プログラムリスト

            from sympy import *
            import numpy as np
            class Gmulti(ls.LSFM):
                def __init__(self,n,muX,sigmmaX,dist):
                    As,fy,fcd,b,d,eta,M = symbols('As fy fcd b d eta M')
                    g=As*fy*d*(1.0-eta*As*fy/b/d/fcd)-M
                    #あらかじめ微分の文字列を数式処理で作っておく
                    self.gg=str(g)
                    #親クラスの初期化は、self.gg定義後に行うこと
                    super().__init__(n,muX,sigmmaX,dist)
                    self.d0=str(diff(g,As))
                    self.d1=str(diff(g,fy))
                    self.d2=str(diff(g,fcd))
                    self.d3=str(diff(g,b))
                    self.d4=str(diff(g,d))
                    self.d5=str(diff(g,eta))
                    self.d6=str(diff(g,M))
                def gcalc(self,X):
                    As=X[0]
                    fy=X[1]
                    fcd=X[2]
                    b=X[3]
                    d=X[4]
                    eta=X[5]
                    M=X[6]
                    g=eval(self.gg)
                    return g
                def dGdXcalc(self,X):
                    As=X[0]
                    fy=X[1]
                    fcd=X[2]
                    b=X[3]
                    d=X[4]
                    eta=X[5]
                    M=X[6]
                    dGdX=[0]*len(X)
                    #微分値の評価
                    dGdX[0]=eval(self.d0)
                    dGdX[1]=eval(self.d1)
                    dGdX[2]=eval(self.d2)
                    dGdX[3]=eval(self.d3)
                    dGdX[4]=eval(self.d4)
                    dGdX[5]=eval(self.d5)
                    dGdX[6]=eval(self.d6)
                    return dGdX
            dist =["normal", "normal", "normal", "normal" ,"normal" ,"normal" ,"normal" ]
            muX =[1.56, 47.7, 3.5, 8.0, 13.2, 0.59, 326.25]
            covX =[0.036, 0.15, 0.21, 0.045, 0.086, 0.05, 0.17]
            sigmmaX = list(np.array(covX)*np.array(muX))
            n=7
            rs =Gmulti(n,muX,sigmmaX,dist)
            rs.RFn()
            a1=rs.GetBeta()
            dist[6]="lognormal"
            rs=Gmulti(n,muX,sigmmaX,dist)
            rs.RFn()
            a2=rs.GetBeta()
            dist=["lognormal", "lognormal", "lognormal", "lognormal" ,"lognormal" ,"lognormal" ,"normal"]
            rs=Gmulti(n,muX,sigmmaX,dist)
            rs.RFn()
            a3=rs.GetBeta()
            dist=["lognormal", "lognormal", "lognormal", "lognormal" ,"lognormal" ,"lognormal" ,"lognormal"]
            rs=Gmulti(n,muX,sigmmaX,dist)
            rs.RFn()
            a4=rs.GetBeta()
            [a1,a2,a3,a4] 
        
            この結果,以下の信頼性指標の出力を確認する.
            

[3.8330281658128675, 3.7612536656241864, 4.3876843910772845, 4.090647398473586]

例題5

例題1と同じ問題について辞書型データでデータを与えて信頼性評価を行う。例題1やこの例題では、設計点探索のアルゴリズムとしてRackwitz Fiessler法を用いている。この場合、探索の開始点を指定する必要があるが、デフォールトとしては基準化空間の原点が指定されるようになっている。原点以外の任意点を指定する場合の例題は例題6に示してある。


プログラムリスト

            # RSモデル
            # 限界状態関数クラスを新規に定義して利用する場合
            class GRS(ls.LSFM):  #LSFMから継承する
                def __init__(self,n,muX,sigmmaX,dist):
                    super().__init__(n,muX,sigmmaX,dist)
                def gcalc(self,X): #g値を計算する仮想関数
                    R=X[0]
                    S=X[1]
                    g=R-S  #限界状態関数
                    return g  #必ずg値を戻す
                def dGdXcalc(self,X): #gの微分ベクトルを計算する仮想関数
                    R=X[0]
                    S=X[1]
                    dGdX=[0]*len(X) #Xと同じ大きさのリストを作る
                    dGdX[0] =1.0
                    dGdX[1] =-1.0
                    return dGdX #必ず微分ベクトルを戻す
            # main program #
            #入力データは辞書形式で表現
            data={"r":{"mean":200,"cov":0.05,"dist":"normal"},#辞書形式で与える入力データ
            "s":{"mean":100,"cov":0.2,"dist":"normal"}            }
            n,muX,sigmmaX,dist=ls.dict2data(data)#辞書型データの入力データへの変換
            rs=GRS(n,muX,sigmmaX,dist)
            print('val=',rs.gcalc(muX))#初期点に対する限界状態関数値
            rs.RFn()
            print('beta=',rs.GetBeta())#信頼性指標の取得
            print('alpha=',rs.GetAlpha())#感度の取得
            print('POF=',rs.GetPOF())#破損確率の取得             
        

例題6

例題5と同じであるが、スタート点を変更する例題。例題5やこの例題では、設計点探索のアルゴリズムとしてRackwitz Fiessler法を用いている。この場合、探索の開始点を指定する必要があるが、デフォールトとしては基準化空間の原点(平均点)が指定されるようになっている。しかし、場合によっては、原点以外の任意の座標点を開始点として指定したいこともある。以下にその例題を示す。### 1 ###と### 2 ###が変更点である


プログラムリスト

                class GRS(ls.LSFM):  #LSFMから継承する
                    def __init__(self,n,muX,sigmmaX,dist):
                        super().__init__(n,muX,sigmmaX,dist)
                    def gcalc(self,X): #g値を計算する仮想関数
                        R=X[0]
                        S=X[1]
                        g=R-S  #限界状態関数
                        return g  #必ずg値を戻す
                    def dGdXcalc(self,X): #gの微分ベクトルを計算する仮想関数
                        R=X[0]
                        S=X[1]
                        dGdX=[0]*len(X) #Xと同じ大きさのリストを作る
                        dGdX[0] =1.0
                        dGdX[1] =-1.0
                        return dGdX #必ず微分ベクトルを戻すam #
                #入力データは辞書形式で表現
                data={"r":{"mean":200,"cov":0.05,"dist":"normal"},#辞書形式で与える入力データ
                "s":{"mean":100,"cov":0.2,"dist":"normal"}            }
                n,muX,sigmmaX,dist=ls.dict2data(data)#辞書型データの入力データへの変換
                rs=GRS(n,muX,sigmmaX,dist)
                print('val=',rs.gcalc(muX))#muXに対する限界状態関数値
                ### 1 ### まず探索開始点のリストを定義。例えば[100,100]の場合について例示。
                nstart=[100,100]
                ### 2 ### RFnメソッドの引数startに'Coordinate'を指定し、Xstartにnstartを指定する
                rs.RFn(start='Coordinate',Xstart=nstart)#dataに対する信頼性評価
                #start='Origin'のとき、原点からスタート、start='Coordinate'のとき、Xstartで与える座標からスタートする。デフォールトは'Origin'
                print('beta=',rs.GetBeta())#信頼性指標の取得
                print('alpha=',rs.GetAlpha())#感度の取得
                print('POF=',rs.GetPOF())#破損確率の取得 
                           
            

例題7

設計点探索のアルゴリズムとしてRackwitz Fiessler法を用いている場合、local minimumに収束してしまう場合がある。このような事態を防ぐためには、探索のスタート点を広域から、徐々に絞り込んでいけばよい。最適化プログラムOptunaを使った例題を以下に示す。限界状態関数は例題6と同じものを使う。Optuna適用のために、まずclass Objectを用意する。ただし、この探索方法は一般に相当の時間を要する。local minimumへの収束の懸念がある場合にのみ行う。


プログラムリスト

                class GRS(ls.LSFM):  #LSFMから継承する
                    def __init__(self,n,muX,sigmmaX,dist):
                        super().__init__(n,muX,sigmmaX,dist)
                    def gcalc(self,X): #g値を計算する仮想関数
                        R=X[0]
                        S=X[1]
                        g=R-S  #限界状態関数
                        return g  #必ずg値を戻す
                    def dGdXcalc(self,X): #gの微分ベクトルを計算する仮想関数
                        R=X[0]
                        S=X[1]
                        dGdX=[0]*len(X) #Xと同じ大きさのリストを作る
                        dGdX[0] =1.0
                        dGdX[1] =-1.0
                        return dGdX #必ず微分ベクトルを戻すam #
                #入力データは辞書形式で表現
                data={"r":{"mean":200,"cov":0.05,"dist":"normal"},#辞書形式で与える入力データ
                "s":{"mean":100,"cov":0.2,"dist":"normal"}            }
                n,muX,sigmmaX,dist=ls.dict2data(data)#辞書型データの入力データへの変換
                import numpy as np
                import optuna
                    
                class Objective:
                    def __init__(self,data):
                        # 変数X,yの初期化
                        self.data=data
                    def __call__(self, trial):
                        n,muX,sigmmaX,dist=ls.dict2data(self.data)
                        rs=GRS(n,muX,sigmmaX,dist)
                        ### スタート点の調査範囲の指定
                        r = trial.suggest_uniform('r', 50,300)
                        s = trial.suggest_uniform('s', 50,300)
                        start=[r,s]
                        rs.RFn(start='Coordinate',Xstart=start)
                        return rs.GetBeta()  #信頼性指標を戻す
                # main program #
                #入力データは辞書形式で表現
                data={"r":{"mean":200,"cov":0.05,"dist":"normal"},#辞書形式で与える入力データ
                "s":{"mean":100,"cov":0.2,"dist":"normal"}            }
                optuna.logging.disable_default_handler() #optunaの出力を抑制する
                objective = Objective(data)
                study = optuna.create_study(direction='minimize')
                study.optimize(objective, timeout=60)
                
                # 最小の信頼性指標と、その値を与えたスタート点の出力
                print('params:', study.best_params,',best_value:',study.best_value)         
            
                出力例
                params: {'r': 107.86532411893185, 's': 126.05989917926681} ,best_value: 4.47213595499958