DynamicalMatrix is not designed for your intention, but you can work around it. It is however designed to be interruptable, which is why it doesn't do what you want. Let me explain.
The dynamical matrix can take very long to calculate. If something happens along the way (network outage, computer crashes, whatever) you don't want to rerun the whole thing, but start from where it broke. This is possible with the DynamicalMatrix study object - to restart, you just run the script again. This is also why there is no need for a nlsave() statement, as the results are stored in "filename" along the way.
But this also means that when you come around the second time in the loop, since the filename is the same, the code will just check if the file exists already, and try to start from where it finished. Since it actually completed, it will just exit.
So I think (without having checked) that the solution is as simple as using unique "filename" for each step in the loop. This of course means all objects are saved to different files, but you can just add an explicit nlsave statement after DynamicalMatrix (within the loop), to store all objects in the same file.
I would suggest testing a script like this with a forcefield before trying with DFT, which could takes days. Even if the results are not good, at least it will test the workflow.