Re: [mmc-users] Question About Fluence Dip at Source Position

4 views
Skip to first unread message

Qianqian Fang

unread,
Sep 1, 2026, 6:40:58 PMSep 1
to mmc-...@googlegroups.com, Xiuxiu Zhang, mcx-users

hi Xiuxiu,

this is exactly what I had warned in the previous replies - you can't just run widefield MMC simulations without calling mmcaddsrc() to extend the mesh for a non-point source. again, see the built-in example scripts I linked in my last post.

the reason is simple - mmc algorithm relies on the premise that the photon's current enclosing tet element must be always known, including the time of launch.

that's why you must either pre-compute cfg.e0: the 1-based index to the enclosing element of the source position (cfg.srcpos), or if you ignore it, mmclab will compute it for you internally.

but this does not work for widefield (area or volumetric) sources, which launches photon not just from srcpos, but an area defined by srcpos/srcparam1/2. The single enclosing element indicated by cfg.e0 won't actually enclose most of the launched photons, causing the ray-tracing to derail from the very beginning. As a matter of fact, the CPU based mmc (cfg.gpuid=-1) will raise an error when such situation happens, but currently the GPU version of mmc silently failed and produce wrong distributions based on the incorrect cfg.e0, as you saw from your screenshot.

also, if you directly call mmcaddsrc() for your source, it will fail. this is because your src aperture is exactly along the box's top surface. the mesh generator call in mmcaddsrc (same for most mesh generators) can not handle merging co-planar triangles. To make the mesh retesselation work, you will have to move your source above the box surface, and then call mmcaddsrc, like in my above mentioned sample codes. 

Qianqian


PS: I am sure you started using AI coding tools in your research. One of the powerful ways to troubleshoot your mmclab problem is to ask such AI tools to read your code and mmc's source code, and pinpoint the issue.

I tried this with Claude Code (Opus 5 model) pretending that I don't know the answer - I simply save your sample code in the current folder, and also git clone the full mmc source code. Then I started Claude, and post this single question:

❯ in mmc_test.m, I wrote a simple mmc/mmclab simulation. However it does not generate the expected photon distribution. I've cloned mmc's source code in the mmc/        
  folder. please read the mmc/mmclab code and understand the requirements for such simulation and let me know what my code was doing wrong            


I turned on the "auto mode" by pressing Shift+Tab 3 times.  After 8 minutes of carefully reading all materials and testing, Claude was able to precisely pin point the issue, and return a detailed explanation why it went wrong, and also provide a fixed script. Not just fixing the source issue, it also picked up 4x bugs in the code that deserve attention.

If you haven't tried it this way to start using mmc/mcx, I highly recommend it for beginners (or advanced users trying to implement complex features). 

For anyone who want to try using Claude to learn/optimize your mmc/mcx simulations, please never rely on its pre-trained knowledge regarding these simulators. You MUST provide the latest code and let it learn on the spot. This is critical. otherwise, it will return non-sense responses. That's why you can't directly post the script on a chatbot and expect it to tell you something useful.



On 8/31/26 13:01, Xiuxiu Zhang wrote:
Hi Dr. Fang, 

I am attaching my code here:

cfg.nphoton = 1e8;
[node, face, elem] = meshabox([0 0 0],[40 40 40],0.05,1);
elem(:,5)= 1;
cfg.node = node;
cfg.elem = elem;
cfg.detpos = [20 20 40 0.08];
% planar source on the top surface
cfg.srcdir = [0, 0, -1,0]; % colimated light going down
cfg.srctype = 'planar';
cfg.srcpos = [10, 10, 40];
cfg.srcparam1 = [20 0.0 0.0 0];
cfg.srcparam2 = [0 20 0.0 0];
cfg.tstart = 0;
cfg.tend = 5e-9;
cfg.tstep = 5e-9;
cfg.method = 'elem';
cfg.issaveexit = 1; % save detected photon exit position and angles
cfg.issaveref = 1;
cfg.isreflect = 1; % refractive index mismatch
cfg.maxdetphoton = 1e8; % max detection
cfg.elemprop = cfg.elem(:, 5);
cfg.prop = [0 0 1 1;
0.63 23.3 0.9 1.40];% 470 nm brain
newcfg = mmclab(cfg, 'prep');
newcfg.optlevel = 1;
tic;
[fluence,detphoton] = mmclab(newcfg);
toc;
Since my source is on the surface of the mesh, I didn't run mmcaddsrc because I thought that was only for any source outside of the mesh domain. To further investigate, I also moved the source down:
cfg.srcpos = [10, 10, 30];
cfg.srcparam1 = [20 0.0 0.0 0];
cfg.srcparam2 = [0 20 0.0 0];

And here is what y = x plane looks like :
Screenshot 2026-08-31 at 11.41.28 AM.png

Please let me know if you are getting a similar result after running the code attached. 

Best,
Xiuxiu


On Sunday, August 30, 2026 at 4:18:22 PM UTC-4 q.fang wrote:

hi Xiuxiu,

I read your last message while traveling. I thought I wrote a short reply, apparently, it wasn't sent.

first, I've never seen this type of artifact. please share your code how you get this so I can reproduce.

did you run mesh retesselation first (mmcaddsrc) before running mmclab? did you plot the extended mesh and verify it looks correct?

please also compare with other built-in examples where a widefield fourier or disk source is used, such as

https://github.com/fangq/mmc/blob/master/mmclab/example/demo_sfdi_2layer.m
https://github.com/fangq/mmc/blob/master/mmclab/example/demo_mcxyz_skinvessel.m

and see how the mesh retesselation codes differ.

Qianqian

On 8/7/26 16:40, Xiuxiu Zhang wrote:


Hope you are doing well!

I have a question about a fluence pattern I am seeing in my Monte Carlo simulations. I created a configuration with a (40*40*40) mm cube and a planar source at (z = 40) covering the entire top surface. When I launch (10^8) photons, the fluence distribution shows a noticeable dip at the location where the initial cfg.srcpos is defined.

I also tested a disk source centered at (x = 20), (y = 20), (z = 40), and I again see a dip exactly at the source anchor position.

Since I set the source direction to be collimated and pointing straight downward, I expected the fluence near the surface to be relatively uniform laterally, especially for the planar source. Could you let me know if I am misunderstanding how cfg.srcpos is treated for planar and disk sources, or if there is another reason this local dip might appear?

Thank you!

XiuxiuScreenshot 2026-08-07 at 4.39.13 PM.pngScreenshot 2026-08-07 at 4.39.54 PM.png

--
You received this message because you are subscribed to the Google Groups "mmc-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mmc-users+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/mmc-users/d489ca27-2bc2-4266-9e33-b38c5f78fb90n%40googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "mmc-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mmc-users+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/mmc-users/08dfd833-aa28-4ea4-b54a-1bafa7b08cb9n%40googlegroups.com.
2026-09-01-183954-in-mmctestm-i-wrote-a-simple-mmcmmclab-simula.txt
Reply all
Reply to author
Forward
0 new messages