BFECCはSemi-Lagrangian法においてバックトレースする際に,フォワードトレースにより誤差を求め, その誤差を修正することで高精度に移流を行う方法である. BFECCの最初のアイデアは ((T. Dupont, Y. Liu, "Back and forth error compensation and correction methods for removing errors induced by uneven gradients of the level set function", J. Comput. Phys. 190(1) (2003) pp.311-324.)) で提案され, 2005年にCG分野で移流方程式へ適用された ((B.-M. Kim, Y. Liu, I. Llamas, J. Rossignac, "Using BFECC for fluid simulation", Eurographics Workshop on Natural Phenomena 2005, 2005.)), ((B.-M. Kim, Y. Liu, I. Llamas, J. Rossignac, "Advections with significantly reduced dissipation and diffusion", IEEE Trans. Vis. Comput. Graph. 13(1), pp.135-144, 2007.)). Semi-Lagrangian法のバックトレースによる&ref(eqa_phi.gif,,70%);の更新を以下の式で表す. Semi-Lagrangian法のバックトレースによる&ref(eqa_phi.gif,nolink,70%);の更新を以下の式で表す. #ref(eqa_bfecc1.gif,,70%) #ref(eqa_bfecc1.gif,nolink,70%) Lは直線を使った1次精度のバックトレース,uは速度場を表す.~ BFECCの場合,上式は以下のようになる. #ref(eqa_bfecc2.gif,,70%) #ref(eqa_bfecc2.gif,nolink,70%) ここで, #ref(eqa_bfecc3.gif,,70%) #ref(eqa_bfecc3.gif,nolink,70%) ~ -BFECCの考え方 #ref(BFECC.gif,,80%) #ref(BFECC.gif,,80%,BFECCの概念図) BFECCの式を上の図を使って説明する.~ まず,A点を計算点xとする. もし,特徴曲線に完璧に沿ってバックトレースしたならば,バックトレース点はBになるはずである. だが,実際には直線でトレースしているのでC点になっている(&ref(eqa_bfecc4.gif,,70%);). このとき,B点とC点の間の&ref(eqa_phi.gif,,70%);の値の違い(誤差)をeとする.~ だが,実際には直線でトレースしているのでC点になっている(&ref(eqa_bfecc4.gif,nolink,70%);). このとき,B点とC点の間の&ref(eqa_phi.gif,nolink,70%);の値の違い(誤差)をeとする.~ C点からさらにフォワードトレースした位置Dは,A点からの誤差2eを含んでいる(誤差なしならA点に戻る). D点での関数値を&ref(eqa_barphi.gif,,70%);とすると, #ref(eqa_bfecc5.gif,,70%) D点での関数値を&ref(eqa_barphi.gif,nolink,70%);とすると, #ref(eqa_bfecc5.gif,nolink,70%) となる.上式から,誤差eは以下のように求められる. #ref(eqa_bfecc6.gif,,70%) より正確な&ref(eqa_phin+1.gif,,70%);は,&ref(eqa_phin.gif,,70%);からeを引いた場&ref(eqa_bfecc7.gif,,70%);より得られる. #ref(eqa_bfecc8.gif,,70%) #ref(eqa_bfecc6.gif,nolink,70%) より正確な&ref(eqa_phin+1.gif,nolink,70%);は,&ref(eqa_phin.gif,nolink,70%);からeを引いた場&ref(eqa_bfecc7.gif,nolink,70%);より得られる. #ref(eqa_bfecc8.gif,nolink,70%) -BFECCの実装 ++&ref(eqa_phin.gif,,70%);をバックトレース #ref(eqa_bfecc9.gif,,70%) ++&ref(eqa_phia.gif,,70%);をフォワードトレース #ref(eqa_bfecc10.gif,,70%) ++誤差eを引いた&ref(eqa_phiaa.gif,,70%);を計算 #ref(eqa_bfecc11.gif,,70%) ++&ref(eqa_phiaa.gif,,70%);をバックトレースして,&ref(eqa_phin+1.gif,,70%);を算出 #ref(eqa_bfecc12.gif,,70%) ++&ref(eqa_phin.gif,nolink,70%);をバックトレース #ref(eqa_bfecc9.gif,nolink,70%) ++&ref(eqa_phia.gif,nolink,70%);をフォワードトレース #ref(eqa_bfecc10.gif,nolink,70%) ++誤差eを引いた&ref(eqa_phiaa.gif,nolink,70%);を計算 #ref(eqa_bfecc11.gif,nolink,70%) ++&ref(eqa_phiaa.gif,nolink,70%);をバックトレースして,&ref(eqa_phin+1.gif,nolink,70%);を算出 #ref(eqa_bfecc12.gif,nolink,70%)