Basically, I am on this kick of using multiple buffers. For example, you have a buffer for water, a buffer for sand, and a buffer for immovable objects. The water moves and it checks above and below. If there is a space below on all buffers, move down. Otherwise, check left/right and do the same trick. If there is still no room, check up. If the sand buffer has a pixel on swap the pixel locations. You then have similar rules for other particles
The only issues you might have from there is that you don't easily get pressure or temp involved. For that, you would need to modify the algorithms for each pixel, slightly. Then you can create an array for each pixel on the screen for pressure. If I were doing this, I would do 1 nibble per pixels where each bit in the nibble corresponded to a direction. 1 means pressure in that direction and 0 means no pressure. This would help decide the primary directions for a particle to move and then secondary directions, and further.
EDIT: For the Prizm, if we work in a 128x128 region, it would require 2KB per layer and 64KB for the pressure buffer. The Prizm has 2MB, so that should be fine
with 10 particle types, that would be 84KB of RAM used.