スクリプト言語 (Python,Scilab,Matlab) のインタフェース¶
GetFEM の簡略化された (しかしかなり完全な) インターフェイスが提供されています.これによりいくつかのスクリプト言語で getfem を使用することができます.
説明¶
すべてのソースは interface/src ディレクトリにあります.インターフェイスは,1つの大規模なライブラリ getfemint (getfem interactionの略) で構成され, GetFEM ライブラリ上のレイヤーとして機能します. python , matlab と scilab のインターフェイスに使用されています.
(swigなどのツールを使用することも可能ですが,)このインターフェイスは,c++ ソースから自動的に生成されているものではありません.このインターフェースは getfem のために簡素化され,一貫性のあるインターフェイスとして設計されています.(言語が密な配列操作の構造を提供しているのならば)新しい言語を追加することはとても簡単です.
ファイル¶
ディレクトリ interface/src 内のすべてのファイル.主なファアイルについて簡単に説明します.
getfem_interface.cc.これは,スクリプト言語と getfem インターフェイスの間のBridgeです.関数 getfem_interface_main は
extern "C"関数としてエクスポートされます.これはスクリプト言語と getfem インターフェイスの間の c++ が起こす障害です (Cインターフェイスのみをエクスポートすると,多くの複雑な問題が回避されます).matlab/gfm_mex.c.matlab インターフェイス. getfem のインターフェースに関連するファイルは
getfem_interface.hのみです.python/getfem_python.c.python インターフェイス. getfem のインターフェースに関連するファイルは
getfem_interface.hのみです.gfi_array.h,gfi_array.c.gfm_mex.cとgetfem_python.cはどちらもgetfem_interface_main()から配列とオブジェクトハンドルを送受信する方法に簡単な規則が必要です.このファイルはそのような機能を提供します.getfemint_gsparse.h,getfemint_gprecond.h,getfemint_gmumps.h, など.必要に応じて,インタフェースオブジェクトに固有のファイルを出力します.(getfemint_gsparse は,異なる種類のストレージの切り替えが可能ないくつかの種類の可変疎行列と複素要素の実数部分をエクスポートします) .
gf_workspace.cc,gf_delete.cc.getfem オブジェクトのメモリ管理を行います.たとえば
meshとmesh_femの間の依存関係を処理するレイヤがあります.これを使用して別の getfem_object がまだある間,そのオブジェクトが破壊されていないことを監視します.その目的は,ユーザーが getfem インターフェイスに不正な引数を渡すことによって getfem (およびホストプログラム,matlab,scilab または python) をクラッシュさせることができないようにすることです.また,(matlab は "object destructors" を持っていないので) matlab では多数の getfem オブジェクトのハンドリングとクリーニングを簡素化するように設計されたworkspaceのスタックのようなものを提供しています.
getfemint.h,getfemint.cc.入力と出力の引数のリストを getfem インターフェイス関数でパースするための
mexarg_in,mexarg_outクラスを定義します. "mex" への参照がgfm_mex.cに移されたので,名前空間はもう必要ありません.gf_mesh.cc,gf_mesh_get.cc,gf_mesh_set.cc,gf_fem.cc, など.エクスポートされるすべての関数は,オブジェクトの種類 (
gf_mesh*,gf_mesh_fem*,gf_fem*) で並べ替えられた getfem インターフェイスになります.オブジェクトのコンストラクト (gf_mesh) ,オブジェクトの変更 (gf_mesh_set) ,オブジェクトの参照 (gf_mesh_get) .これらの各ファイルには,mexargs_inとmexargs_outの引数スタックを受け取る main 関数が1つ含まれています.解析の後,通常最初の引数をサブ関数 (matlab でgf_mesh_get('nbpts'),または python でMesh.nbpts()) の名前として解釈します.matlab/gfm_rpx_mexint.c.--enable-matlab-rpcが./configureスクリプトに渡されるときに使用されるgfm_mex.cの代替ファイルです.その場合, matlab インターフェイスは "getfem_server" プログラムでソケットを介して通信するので,そのサーバープログラムをデバッグすることが可能です.メモリリークまたは matlab の何かを混乱させず識別するインターフェイスをデバッグするのがこのファイルの主な用途です(デバッグは苦痛です).python/getfem.py.python インタフェースは python スクリプト "
bin/extract_doc.py" によってコンパイル中に生成される "getfem.py" ファイルで利用可能です.
インターフェイスのオブジェクト,メソッド,および関数¶
インターフェイスによって操作される主なものは, (Fem, Mesh, MeshFem, Model ...などの)いくつかのオブジェクト,関連するメソッド,およびこれらのオブジェクトで定義されている関数です.
サポートしている各スクリプト言語 (Python,Scilab,Octave,Matlab) で別々に対応することなく,インターフェイスに新しいオブジェクト,メソッド,および関数を容易に追加できるようにするために工夫をしています.
さまざまなオブジェクト,メソッド,および関数のインターフェイスを構築するために必要なすべての情報は,ファイル interface/src/gf*.cc に含まれています.python スクリプト (bin/extract_doc) は,そこから全ての必要な情報を取得しファイルを生成します.生成されるのは python ファイル getfem.py と, matlab の m-ファイルによる個別の関数やオブジェクト (サブディレクトリを含む) と,自動ドキュメンテーションの出力ファイルです.
すべてを自動で動作させるには,一定のルールを尊重する必要があります.
オブジェクトはインターフェイス上の3つのファイルで定義する必要があります.
gf_objectname.cc: オブジェクトのコンストラクタが含まれています.gf_objectname_get.cc: (存在する場合) オブジェクトに関する情報を取得するメソッドが含まれています.gf_objectname_set.cc: (存在する場合) オブジェクトを変換するメソッドが含まれています.
関数のリストは全て
gf_commandname.ccで定義されています.このファイルにはサブコマンドのリストが含まれています.各ファイルについて,関数またはメソッドのリストに関する主な解説は,タグ '/@GFDOC' と '@/' で区切られています.オブジェクトのコンストラクタに対応するファイルの場合,注釈はオブジェクトの説明としてください.
それぞれの重要なファイル gf_*.cc には,オブジェクトまたはサブコマンドのメソッドを定義できるマクロが含まれています.特に,このシステムは,呼び出されたメソッド/関数の効率的な検索をすることができます.このマクロでは,次の構文を使用して新しいメソッド/関数を宣言できます.
/*@GET val = ('method-name', params, ...) Documention of the method/function. @*/ sub_command ("method-name", 0, 0, 0, 1, ... body of the method/function ... );
最初の3行は,特別な構文でメソッド/関数の呼び出しを記述し,また,ドキュメントに含まれるメソッド/関数の C++ に関する解説です.これは Python,Octave,Matlab と Scilab のための適切なインターフェイスを生成するために使用されるため,この解説の最初の行は重要です.
メソッド/関数の呼び出しの説明の構文は次のとおりです.
/*@の後には,特別なキーワードを記入する必要があります.これは,INIT,GET,SET,RDATTRまたはFUNCのいずれかです.キーワードINITは,これがオブジェクトのコンストラクタの記述であることを意味します.RDATTRは,オブジェクト属性を得る短いメソッドです.GETは,変更をしないオブジェクトのメソッドです.SETはオブジェクトを変更するメソッドのためのもので,FUNCは関数リストのサブコマンドです.メソッド/関数が値を返す場合は,
=に続いて(任意の)戻り値の名前が返されます.メソッド/関数のパラメータについて説明します.メソッドの場合,オブジェクト自体についての言及は行いません.最初のパラメーターはメソッドまたは単一引用符で示すサブコマンド名である必要があります (この名前がドットで始まる特別な場合もあります.これは,コマンド名が不要なメソッド/関数であることを意味します).
その他のパラメーターがある場合は,型を使用して宣言します.定義済みの型は次のとおりです.
@CELL: セルの配列,@imat: 整数の行列,@ivec: 整数のベクトル,@cvec: 複素数値のベクトル,@dcvec: 複素数値のベクトル,@dvec: 実数値のベクトル,@vec: 実数または複素数値のベクトル,@dmat: 実数値の行列,@mat: 実数または複素数値の行列,@str: 文字列,@int: 整数,@bool: boolean型,@real: 実数値,@scalar: 実数または複素数値,@list: リスト.
さらに,
@tobjはインタフェースによって定義されているオブジェクトを参照します.たとえば,@tmesh,@tmesh_fem,@tfem, などを参照できます.いくつかの略語が使用可能です.@tcont_structは@tcs@tmesh_femは@tmf@tgeotransは@tgt@tglobal_functionは@tgf@tmesher_objectは@tmo@tmesh_levelsetは@tmls@tmesh_imは@tmim@tlevelsetは@tls@tsliceは@tsl@tspmatは@tsp@tprecondは@tpre@tmumps_contextは@tmct
パラメータリスト (
...) の末尾にある3つの点は,追加のパラメータが可能であることを意味します.省略可能なパラメーターは,角かっこで記述します.たとえば,/*@SET v = ('name'[, @int i])です.しかし,python インターフェイスを構築する際には,extract_docスクリプトによってどのように解釈されるか注意してください.マクロの2から5番目のパラメーターは,入力引数の最小数,最大値,出力引数の最小数,および出力引数の最大数にそれぞれ対応しています.これらは動的に検証されています.
関数リストの追加パラメータ...
原因不明の理由により,関数の本体には
int a, b;などの複数の宣言を含めることができません(c++ でマクロの追加パラメーターであると解釈されてしまいます).
c++ の解説に含まれているドキュメントの部分は, reStructuredText 形式である必要があります.特に,数式は :math:`f(x) = 3x^2+2x+4` かもしくは次のように含めることができます.
.. math:: f(x) = 3x^2+2x+4
記号
INIT::OBJNAME('method-name', ...),GET::OBJNAME('method-name', ...),SET::OBJNAME('method-name', ...),FUNC::FUNCNAME('subcommand-name', ...)を使用して,インターフェイスの別のメソッドまたは関数を参照することができます.これは言語 (Octave,Matlab,Scilab または Python) に応じて正しく置き換えられます.ドキュメンテーションでは,特定の言語に応じて
@MATLAB{specific part ...},@SCILAB{specific part ...}および@PYTHON{specific part ...}を追加します.メソッド/サブコマンドがインタフェースに固有である場合,例えば Matlab の場合, MATLABFUNC を使うことで GET を MATLABGET, FUNC などで置き換えることができます.この追加機能に特定のコードが必要な場合は,タグ/*@MATLABEXT,/*@SCILABEXT,/*@PYTHONEXTで追加することができます.たとえば,gf_mesh_fem_get.ccを参照してください.Python と Matlab オブジェクトの場合, SET メソッドの名前が GET メソッドと同じならば, SET メソッドの先頭に set_ が付けられます.
getfem インターフェイスへの新しい関数またはオブジェクトメソッドの追加¶
新しい関数 gf_mesh_get(m, "foobar", .), を追加したい場合, 変更するメインファイルは gf_mesh_get.cc です.ユーザーがその関数を使用するときに Scilab,Octave,Matlab または Python をクラッシュさせないようにするために,関数に渡されるすべての引数をチェックしてください.関数を追加するには, gf_mesh_get.cc で定義されているマクロを使用します.
gf_mesh_get.cc 内の関数のドキュメントを忘れずに追加してください.これは, Octave/Matlab/Scilab/Python のヘルプファイル(matlab のプロンプトで "help gf_mesh_get" とタイプしたときにヘルプファイルに表示されるドキュメントです), そして getfem_python の自動生成ドキュメントに反映されます.
重要.配列のインデックスは,Python では0から始まり,Octave,Matlab と Scilab では1から始まることに注意してください.次のような特定の関数の場合,
config::base_index()
インデックスとインデックスの配列を交換する際には python では0, Octave , Matlab と Scilab では1を使用しなければなりません.補正を2回しないように気をつけてください.インデックスのいくつかの配列は自動的にシフトされています.
getfem インターフェイスへの新しいオブジェクトの追加¶
インターフェイスに新しいオブジェクトを追加するには,それに対応する新しいソース gf_obj.cc, gf_obj_get.cc と gf_obj_set.cc を作成する必要があります.もちろん,モデルとして既存のものを使うこともできます.
オブジェクトを管理するために, getfemint.h の最初にクラスを宣言する必要があります(アルファベット順になるように注意してください).そして3つの関数を宣言します.
bool is_"name"_object(const mexarg_in &p);
id_type store_"name"_object(const std::shared_ptr<object_class> &shp);
object_class *to_"name"_object(const mexarg_in &p);
ここで, "name" はインターフェイス内のオブジェクトの名前であり, object_class は getfem のクラス名です(たとえば,メッシュオブジェクトの場合は getfem::mesh ).また, GetFEM で共有ポインタによって操作されるオブジェクトの場合,3番目の関数は共有ポインタを返します.
重要: インタフェースを作成するためには, GetFEM オブジェクトは dal::static_stored_object を使用しなければなりません.一方,そのようにしない場合には,ラッパークラスを bgeot::base_poly のように定義します (getfemint.h の末尾を参照してください).
前の3つの関数は, getfemint.cc の末尾に実装する必要があります. getfemint.cc で定義されている2つのマクロのいずれかを使用することができます.最初のマクロは標準的な目的のためであり, GetFEM の共有ポインタで操作するために2番目のオブジェクトを使用します.
getfemint.cc の最後に name_of_getfemint_class_id と class_id_of_object という関数も追加する必要があります.
getfem_interface.cc にインターフェイス関数の呼び出しを追加する必要があります.そしてファイル bin/extract_doc を変更し設定ファイルを実行します.
メソッド get('char') と get('display') は,各オブジェクトに対して定義する必要があります.最初のメソッドでは,文字列によりオブジェクトをファイルに保存するできるようにし,2番目のメソッドでは文字列によりオブジェクトに関するいくつかの情報を与えるようにします.さらに,文字列による構築では,ファイルからオブジェクトを読み込む必要があります.
Scilab インターフェイスのためにファイル sci_gateway/c/builder_gateway_c.sce.in とディレクトリ macros/overload 内のファイルを変更する必要があります.
状態¶
展望¶
インターフェイスは GetFEM と連動して成長しています. GetFEM の主な関数群のインタフェースは実装されています.