読者です 読者をやめる 読者になる 読者になる

倭算数理研究所

科学・数学・学習関連の記事を、「倭マン日記」とは別に書いていくのだ!

物理系の観測を簡単に

前回、SimulationBuilder を用いて反復シミュレーションを構築する方法を見ました。 そこでは物理系を表す CoolSystem とその系に対する物理量 CoolObservableSet を Groovy クラスとして定義していました。 ただし、多くのシミュレーションでは物理系に定義したフィールドはそのままデータとして出力したいことが多いので、CoolObservableSet を物理系とは別に定義するのはちょっと面倒です。 したがって、今回は物理系の @Dominant @State フィールドを物理量として簡単に登録する方法を見ていきます。

@State フィールドを物理量として登録する方法は次の2つあります:

  • systemObservableSet ノードで @State フィールドを物理量として登録する
  • AbstractObservableSystem クラスを用いて観測可能な物理系を実装する

それぞれの方法を見ていきましょう。

systemObservableSet ノードで @State フィールドを物理量として登録する


まずは systemObservableSet ノードを使用する方法。 この方法では SimulationBuilder でノードを構築する際に、observableSet ノードの変わりに systemObservableSet ノードを使うだけです。 ノードには特に属性や子ノードを渡す必要はありません。 SimulationBuilder によるシミュレーションの構築はこんな感じにします:

import org.waman.groops.builder.SimulationBuilder

def builder = new SimulationBuilder()
def sim = builder.simulation{
    system(new CoolSystem(), dt:0.1d, T_room:17.0d, r:1.0d)
    initialConditions(time:0d, T:82.3d)

    // CoolSystem の @State フィールドを物理量として登録
    systemObservableSet()
    // 前回は observableSet(new CoolObservableSet()) としてました

    count(total:10)
    console()
}

この systemObservableSet ノードによって、物理系(PhysicalSystem を実装したクラス)に定義した @State フィールドが物理量として登録されます。 @State フィールド以外にも観測したい物理量がある場合は、ObservableSet を実装したクラスを作成して observableSet ノードによって追加登録することもできます。

同様にして parameterObservableSet ノードを使用すると、物理系に定義した @Parameter フィールドを物理量として登録することができます:

    // CoolSystem の @Parameter フィールドを物理量として登録
    parameterObservableSet()

これらを踏まえたサンプルコードはこんな感じになります:

@GrabResolver('https://github.com/waman/groops-core/tree/master/repo')
@Grab('org.waman.groops:groops-core:0.1-beta')

import org.waman.groops.builder.SimulationBuilder
import org.waman.groops.simulation.system.*

def builder = new SimulationBuilder()
def sim = builder.simulation{
    system(new CoolSystem(), dt:0.1, T_room:17.0d, r:1.0d)
    initialConditions(time:0.0, T:82.3d)
    systemObservableSet()
    parameterObservableSet()

    count(total:10)
    console()
}

// シミュレーションの実行
sim.simulate()

/** Physical System subject to Newton's low of cooling. */
class CoolSystem extends AnnotationPhysicalSystem{

    @State BigDecimal time
    @State double T

    @Parameter BigDecimal dt
    @Parameter double T_room
    @Parameter double r

    @Override
    void evolve(Map<String, Object> params){
        time += dt
        T += -r*(T - T_room)*dt.doubleValue()
    }
}

さらに物理量を登録するのでない限り、ObservableSet を実装したクラスを作成する必要はありません。

AnnotationObservableSystem クラスを用いて観測可能な物理系を実装する


次は観測可能な物理系を実装する方法。 「観測可能な物理系」は PhysicalSystem インターフェースと ObservableSet インターフェースを実装したクラスで、このクラスを SimulationBuilder で物理系として渡した場合、物理系の @State フィールドが自動的に物理量として登録されます。 systemObservableSet ノードを使用する方法との違いは、ObservableSet を登録するノードをビルダーに書く必要がないところです(サンプルコード参照)。

観測可能な物理系を実装するには、AnnotationObservableSystem クラスを用いると簡単です:

class ObservableCoolSystem extends AnnotationObservableSystem<ObservableCoolSystem>{

    @State BigDecimal time
    @State double T

    @Parameter BigDecimal dt
    @Parameter double T_room
    @Parameter double r

    @Override
    void evolve(Map<String, Object> params){
        time += dt
        T += -r*(T - T_room)*dt.doubleValue()
    }
}

ほとんど物理系の実装と変わりませんね。 これを用いたサンプルはこんな感じ:

@GrabResolver('https://github.com/waman/groops-core/tree/master/repo')
@Grab('org.waman.groops:groops-core:0.1-beta')

import org.waman.groops.builder.SimulationBuilder
import org.waman.groops.simulation.helpers.AbstractObservableSystem
import org.waman.groops.simulation.annotation.*

def builder = new SimulationBuilder()
def sim = builder.simulation{
    system(new ObservableCoolSystem(), dt:0.1d, T_room:17.0d, r:1.0d)
    initialConditions(time:0d, T:82.3d)

    count(total:10)
    console()
}

// シミュレーションの実行
sim.simulate()

/** Physical System subject to Newton's low of cooling. */

class ObservableCoolSystem extends AbstractObservableSystem<ObservableCoolSystem>{

    @Dominant double time, T
    @Parameter double dt, T_room, r

    @Override
    void evolve(Map<String, Object> params){
        time += dt
        T += -r*(T - T_room)*dt.doubleValue()
    }
}

ビルダーに物理量を登録するノードを書く必要がなくなっています。

追記


Groops 0.1-beta 以降で少し互換性のない変更を加えました:

計算物理学入門

計算物理学入門

  • 作者: ハーベイゴールド,ジャントボチニク,Harvey Gould,Jan Tobochnik,鈴木増雄,石川正勝,溜渕継博,宮島佐介
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2000/12
  • メディア: 単行本
  • クリック: 5回
  • この商品を含むブログ (45件) を見る