MPh-py / MPh

Pythonic scripting interface for Comsol Multiphysics
https://mph.readthedocs.io
MIT License
265 stars 67 forks source link

Evaluation of time dependent particle tracing studies #119

Closed wacht02 closed 1 year ago

wacht02 commented 1 year ago

Hello, I have some questions/issues with the data export that might also be linked to #112.

I want to do particle tracing simulations in COMSOL and then export all the data using MPH. To show the issue I am having I created a simple simulation available here: capacitor_trajectories.zip (The computation should onyl take a few seconds)

The simulation is just an electron that gets accelerated due to an electric field. I would later be interested in the poperties of the electron both during it's flight and when it hits a boundary. If you run the studies and then want to evaluate some expressions you will find some issues.

At first I wanted to evaluate the current time in the simulation. This can be done with model.evaluate('t', 'ns', 'solution trajectory'). There are no issues here which is good. If I now try to export the energy of the particle with model.evaluate('cpt.Ep', 'eV', 'solution trajectory') I get a long error report telling me that the expression can not be evaluated. As far as I know this is 'normal' in COMSOL. But this issue might be connected to #112 since I also found that only certain expressions get evaluated like exprected while others don't.

If you want to evaluate particle properties in a time dependent study you need to create a Particle Dataset. Here the evaluation of porperties like the energy or position of the particle works just fine. In my example model.evaluate('cpt.Ep', 'eV', 'Particle 1') does not raise any issues. When you create a simulation like this COMSOL also automatically generates this Particle Dataset.

If you now perform a parametric sweep you will find an additional issue. In the example file the parameter changed is the step size for the output time steps. So the different solutions all contain different amounts of data. But if I evaluate the data like in #112 with

model = client.load('capacitor_trajectories.mph')
(indices, values) = model.outer('Particle 2 Sweep')
for (index, value) in zip(indices, values):
    Energy = model.evaluate('cpt.Ep', 'eV', 'Particle 2 Sweep', outer = index)
    print(f'stepsize = {value}ns: {len(Energy[0,:])} time steps, final energy: {Energy[0,-1]}')

I get the following result:

stepsize = 1.0ns: 21 time steps, final energy: 251.02386778677953
stepsize = 0.1ns: 21 time steps, final energy: 251.02386778677953
stepsize = 0.01ns: 21 time steps, final energy: 251.02386778677953

Note that I evaluate the results on a Particle Dataset which should work as seen before. Aditionaly I think the selection of an outer solution doesn't work at all in this case as the final energy for all parameter values is the same, indicating that the same solution is evaluated each time.

So in conclusion there seems to be an issue with the evaluation depending on the combination of expression and dataset aswell as an issue with the evaluation of parametric sweeps.

I hope this explains the issue to a sufficient degree. If you need further information I am happy to provide what I can, as this is not the tutorial model.

john-hen commented 1 year ago

So in conclusion there seems to be an issue with the evaluation depending on the combination of expression and dataset aswell as an issue with the evaluation of parametric sweeps.

I think it is only the latter.

Everything else you describe strikes me as expected behavior. Namely, you need to evaluate particle properties along a trajectory on a "Particle" dataset that Comsol provides for just that purpose, not on the "Solution" dataset that is also produces. That's ultimately because particle tracing is not a pure "finite-element" simulation, but a "particle-in-cell" simulation that builds on top of that.

So then this looks very much like the same problem as #120. It's not exactly the same because, again, particle datasets are different from the "normal" datasets, and model.evaluate() handles them separately, i.e. in different code paths. Though ultimately we do handle them very similarly. Given that there's currently no solution for the other issue, this might also be the case here, unfortunately.

There is one difference: Comsol also has a "Particle (Evaluation)" feature, which we're currently not using. I haven't tried yet if that also shows this "weird" behavior (of not returning all time steps). But see little point in exploring that for as long as the other issue hasn't been solved.

FYI, particle tracing is already part of the test suite: test_model.py, line 370. But that test case is only time-dependent, not a parameter sweep. It covers that use case because it happens to be one I personally had in the past. Other than that, the documentation of model.evaluate() (currently) states:

Please note that this method, while broad in its intended scope, covers common use cases, but not all of them. In case it fails to return the expected results, consider using the Comsol API features directly via the .java attribute of this class, and refer to the “Results” chapter in the Comsol Programming Manual for guidance.

So rather than a bug, I'd consider this here a limitation (regarding evaluation of time-dependent parameter sweeps). And if we don't find a solution (via other Comsol API calls), I'll just update the documentation to reflect that more specifically: as a "known limitation". :shrug:

john-hen commented 1 year ago

Closed as: upstream bug. (I.e., bug in Comsol, for all we know. Much like #120, for the reason mentioned above.)