excel - 将蒙特卡罗计算从 VBA 代码更改为 MATLAB
问题描述
我正在尝试将此子句因子蒙特卡罗计算代码(用 Visual Basic 编写):https://descanso.jpl.nasa.gov/SciTechBook/series1/Goebel_AppG_Clausing.pdf 转换为 MATLAB 代码。
当我尝试在 Excel 中运行此代码时,它总是在第一次运行时返回一致的值。但是当我在 MATLAB 中实现时,它会随机返回子句因子。您能否帮我编写 MATLAB 代码,以便它可以像在 VBA 中那样做。
我在 VBA 代码中谈论的值是Range("C11") = (rBottom ^ 2) * iescape / npart
这是我解决 clausingFactor 的 MATLAB 代码
thickScreen = 0.5;
thickAccel = 1;
rScreen = 0.8;
rAccel = 0.5;
gridSpace = 1;
npart = 313;
Pi = 3.14159265358979;
%assumes rTop = 1
rBottom = rScreen/rAccel;
lenBottom = (thickScreen + gridSpace)/rAccel;
lenTop = thickAccel / rAccel;
Length = lenTop + lenBottom;
iescape = 0;
maxcount = 0;
icount = 0;
nlost = 0;
vztot = 0;
vz0tot = 0;
for ipart = 1: npart
%launch form bottom
notgone = true;
r0 = rBottom * sqrt(rand());
z0 = 0;
costheta = sqrt(1 - rand());
if (costheta > 0.99999)
costheta = 0.99999;
end
Phi = 2 * Pi * rand();
sintheta = sqrt(1 - costheta);
vx = cos(Phi) * sintheta;
vy = sin(Phi) * sintheta;
vz = costheta;
rf = rBottom;
t = (vx * r0 + sqrt((vx^2 + vy^2) * rf^2 - (vy * r0)^2)) / (vx^2 + vy^2);
z = z0 + vz * t;
vz0tot = vz0tot + vz;
icount = 0;
while notgone
icount = icount +1;
if (z < lenBottom)
%hit wall of bottom cylinder and is re-emitted
r0 = rBottom;
z0 = z;
costheta = sqrt(1-rand());
if (costheta > 0.99999)
costheta = 0.99999;
end
Phi = 2 * Pi * rand();
sintheta = sqrt(1 - costheta^2);
vz = cos(Phi) * sintheta;
vy = sin(Phi) * sintheta;
vx = costheta;
rf = rBottom;
t = (vx * r0 + sqrt((vx^2 + vy^2) * rf^2 - (vy * r0)^2)) / (vx^2 + vy^2);
z = z0 + t * vz;
end %bottom cylinder re-emission
if ((z >= lenBottom) && (z0 < lenBottom))
%emitted below but going up
%find radius at lenBottom
t = (lenBottom - z0) / vz;
r = sqrt((r0 - vx * t)^2 + (vy * t)^2);
if (r <= 1)
%continuing upward
rf = 1;
t = (vx * r0 + sqrt((vx^2 + vy^2) * rf^2 - (vy * r0)^2)) / (vx^2 + vy^2);
z = z0 + vz*t;
else
% hit the upstram side of the accel grid and is
% re-emitted downward
r0 = r;
z0 = lenBottom;
costheta = sqrt(1 - rand());
if (costheta > 0.99999)
costheta = 0.99999;
end
Phi = 2 * Pi * rand();
sintheta = sqrt(1 - costheta^2);
vz = cos(Phi) * sintheta;
vy = sin(Phi) * sintheta;
vx = costheta;
rf = rBottom;
t = (vx * r0 + sqrt((vx^2 + vy^2) * rf^2 - (vy * r0)^2)) / (vx^2 + vy^2);
z = z0 + t * vz;
end
end %end upward
if ((z >= lenBottom) && (z<= Length))
%hit the upper cylinder wall and is re-emitted
r0 = 1;
z0 = z;
costheta = sqrt(1 - rand());
if (costheta > 0.99999)
costheta = 0.99999;
end
Phi = 2 * Pi * rand();
sintheta = sqrt(1 - costheta^2);
vz = cos(Phi) * sintheta;
vy = sin(Phi) * sintheta;
vx = costheta;
rf = 1;
t = (vx * r0 + sqrt((vx^2 + vy^2) * rf^2 - (vy * r0)^2)) / (vx^2 + vy^2);
z = z0 + t * vz;
if (z < lenBottom)
%find z when particle hits the bottom cylinder
rf = rBottom;
if ((vx^2 + vy^2) * rf^2 - (vy * r0)^2 < 0 )
t = (vx * r0) / (vx^2 + vy^2);
%if sqrt argument is less than 0 then set sqr term
%to 0 12 May 2004
else
t = (vx * r0 + sqrt((vx^2 + vy^2) * rf^2 - (vy * r0)^2)) / (vx^2 + vy^2);
end
z = z0 + vz * t;
end
end %end upper cylinder emission
if (z < 0)
notgone = false;
end
if (z > Length)
iescape = iescape + 1;
vztot = vztot + vz;
notgone = false;
end
if (icount > 1000)
notgone = false;
icount = 0;
nlost = nlost + 1;
end
end
if (maxcount < icount)
maxcount = icount;
end
end
clausingFactor = (rBottom^2) * iescape / npart;
vz0av = vz0tot / npart;
vzav = vztot / iescape;
DenCor = vz0av / vzav;
谢谢你。
解决方案
推荐阅读
- java - 我正在尝试为我的应用程序构建 gradle,但构建失败
- python - Python 在多个子目录中搜索文件以查找特定字符串并返回文件路径(如果存在)
- java - ATM使用方法java
- javascript - 如何使用js重新加载特定元素
- spring-boot - 级联持久性中“字段列表”中的未知列
- c++ - Visual Studio C++ 项目 Linker2019 错误
- mysql - 我想从“AnställningsID”中提取特定信息,它会根据我选择的“AnställningsID”更新“AnställningsID 和“Fnamn”
- javascript - 有没有办法改变日期的显示
- nginx - 设置 Nginx:端口显示为未打开
- opencv - 使用 GUI 的 Haar 级联训练器