The perpetually want a set of requirements. And they get upset if a new requirement is added later. I see software as a way to explore a space. Model it. Determine what more modeling is needed. You are constantly trying to do something that usually is beyond what is computationally possible so you have to figure out what approximation is going to work
Which is exactly why you should leave the science part of the work to scientists, have them prototype a solution, work it out along the way and improving it, until it meets its scientific requirements. Then, at set points, you should leave it to the software engineers to productize the prototype based on the set of scientific requirements currently implemented, and keep those fixed as long as possible. If the target is moving, settle on a release schedule for the productized code that allows planned functional updates. This way the science work and the software engineering work can be done independently and both sides can be happen.
In reality, this often means you will end up with 2 implementations, which implies you need capable software engineers who know how to do regression testing and qualification of the software probably.
Where I work, we have physicists, mechanical engineers and construction engineers prototype solutions in Matlab, they love that tool, they can try out new ways of solving their problems quickly, prototype the hell out of them, graph and plot the results, etc. It's a great tool for scientists really. When it comes to productize the resulting solutions (simulation models, mainly) and integrate them in the (extremely expensive) hardware they will be used in, the software engineers (me, amongst others), get a functional specification, a test specification and a test report, all based on the QA'ed Matlab code, and we re-implement it in the target language best suited for the application (C++ or Python, mostly). This usually involves isolating the 'meat' of the algorithm and designing a maintainable, flexible software architecture around it, that allows deployment for other applications, adding scripting interfaces on top of the models, better regression testing, etc.
It may sound like a stupid idea to keep 2 implementation of the same idea around, but it's not, trying to productize a moving target and having two sides of the problem implemented in one piece of code will take more time, more risks, and more annoyances between the involved parties.
The way we solved it for my job works great for everyone, the only annoying thing here is middle management, who like to think they can do a better job at both the science and the software engineering work, and sometimes decide we 'have to have to productize the Matlab code', we 'have to have 1 implementation only', or 'we don't need to allocate a lot of time productizing because if the functionality is done, translating it to a usable software component is easy'. :-/