私はシンプルなコードを持っています。これは、円柱で囲まれた領域にノードをフラグします。コードを実装すると、結果は90度のシリンダ観測ケースの軽い傾きになります。Fortran丸め誤差
実際の問題: 上記のアルゴリズムはFortranで実装されています。コードは、円柱の内部にある場合、デカルトグリッドの点をチェックします。テストケースに続いて: シリンダは、y軸に対してyz平面内で90度の角度をなします。したがって、方位ベクトル$ \ vec {o} $は(0,1,0)です。
ケース1: オリエンテーションベクタは、$ \ vec {o} =(0.0,1.0,0.0)$で直接割り当てられます。 0.0(= 配向ベクトルが$ \ VEC {O}と倍精度精度dsin
とdcos
と固有Fortranの機能を指定します。これは、$の\シータ= 90 $
ケース2と完全シリンダをもたらします、\ sin(\ pi/2.0)、\ cos(\ pi/2.0))$ $ pi $の値には、20以上の重要な小数点が割り当てられています。結果として得られる円柱は軽度の傾斜を生じる。
強調表示された領域は、デカルト軸に対する円柱の傾きによる余分な材料を示します。私も試したarchitecture specific maximum precision "pi" value.これも同じ問題が発生します。
これは、シリンダによる実際の角度が90度ではないことを示しています。誰もこの問題の有効な解決策を提案することができます。私は任意の角度のためのinbuilt三角関数を使用し、正確なセルのフラグを立てる方法を探している必要があります。
注:すべての操作は倍精度の精度で行われます。
実際の機能は以下のとおりです。 rk
値と8
pure logical function in_particle(p,px,x)
type(md_particle_type),intent(in) :: p
real(kind=rk),intent(in) :: px(3),x(3)
real(kind=rk) :: r(3),rho(3),rop(2),ro2,rdiff,u
rop = particle_radii(p) ! (/R_orth,R_para/)
ro2 = rop(1)**2
rdiff = rop(2) - rop(1)
r = x-px
! Case 1:
! u = dot_product((/0.0_rk,-1.0_rk,0.0_rk/),r)
! rho = r-u*(/0.0_rk,-1.0_rk,0.0_rk/)
! Case 2:
u = dot_product((/0.0_rk,-dsin(pi/2.0_rk),dcos(pi/2.0_rk)/),r)
rho = r-u*(/0.0_rk,-dsin(pi/2.0_rk),dcos(pi/2.0_rk)/)
if((u.le.rdiff).and.(u.ge.-rdiff)) then
in_particle = dot_product(rho,rho) < ro2
else
in_particle = .false.
end if
end function in_particle
注パラメータが定義される:三角の操作は、より良い問題を説明するために、コード内で行われます。しかし、元のコードは、ユーザからベクタ形式で方向を読み取ります。次に、この情報を粒子 - 粒子衝突操作のための四元数に変換する。クォータニオンを方向ベクトルに戻すと、この誤差はさらに大きくなります。衝突の開始前であっても、気筒の向きは2つの格子セルによって方向を変えられる傾向がある。
コードを表示してください。 –
@AlexanderVogt:コードを更新しました。 –
上記のコードで予期しない結果が得られるのに対して、「ケース2」の下の2行をコメントし、「ケース1」の下の2行をコメント解除すると、期待した結果が得られますか? 'print *、dsin(pi/2.0_rk);のような行を挿入するとどうなるでしょうか? (pIの値がOKであることを確認するために)停止しますか? – roygvib