MPh-py / MPh

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

NotImplementedError: Only one client can be instantiated at a time. #37

Closed gdsantos160792 closed 3 years ago

gdsantos160792 commented 3 years ago

Hi! Firstly, I would like to give my congrats to the makers for this incredible work! I am trying to run multiple times my mph file by the Spyder compiler. However, always in the second time, I have gotten this error:

"NotImplementedError: Only one client can be instantiated at a time."

As far I have solved it by closing the Spyder compiler and open it again. So, my question is: Is there a way to run my code without I need to close the compiler and without getting this error?

My code: import mph import numpy as np import matplotlib.pyplot as plt import pyswarms as ps

client = mph.Client()

server = mph.Server()

model = client.load('test.mph') model.solve() Corrente=model.evaluate('comp1.cir.R1_i')

plt.plot(Corrente) plt.ylabel('Corrente Resistor (A)') plt.xlabel('tempo (ms)') plt.grid() plt.show()

max3-2 commented 3 years ago

Due to limitation in jpype, we can only run one JVM at a time. So the error most certainly occurs in the client = mph.Client() call. Quick ideas:

1) Use client = mph.start() for more convenience if you do not need to specify a server explicitly. 2) Do not start the client each time you run the code. There is no need to do so. Start it once and it will handle your tasks as long as the interpreter is running. 3) If you use spyder in a very interactive way and you lust like to hit F5 to rerun your codes, you would need to protect the call to mph.Client() (or mph.start() for that matter) in a try...except... which should not interfere with the rest of your code since the client stored in client will stay available.

Best!

john-hen commented 3 years ago

I've never considered this before. Spyder seems to keep the Python session alive between restarts. IDLE for example does not do that, it always starts from a clean slate. So yeah, like Max says, you need to work around that issue, but it's solvable.

@max3-2 Maybe we should have a function mph.running(), which would basically just be an alias for jpype.isJVMStarted(). Just so users could avoid the try-except clause if they wanted to.

@gdsantos160792 I've learned from your code example that you're intending to use pySwarms. First of all, thanks, I didn't know about this package and it sounds very interesting. Particle-swarm optimization, or any kind of optimization really, is exactly the thing MPh is built for.

Only then, again, you might run into this issue here: that you cannot run more than one Comsol client in the same Python process. Because, I assume, you'll want one client session per particle in the swarm. It's a limitation that can't be avoided unfortunately, so you'll have to work around it. Find some inspiration in the docs section "Multiple processes" and feel free to open a new issue if you run into problems so we can brainstorm together. Or, if you got it to work, it would be nice to just let us know in Chat.

gdsantos160792 commented 3 years ago

@max3-2 Thank you so much for your explanation! I will try to solve the problem in spyder compiler as you suggest and if I have success, I will post my solution for the community. @John-Hennig Yeah, my idea is use the pySwarms to try to optimize my problem. If I can do that I pass my experience here. Just a warning about the pySwarms, it does not have a MOPSO. It still has the necessity to be created.
Best regards,

john-hen commented 3 years ago

@gdsantos160792 As suggested by @max3-2 in a follow-up in Chat (#27), mph.start() now returns the existing client instance if a client is already running. That is, as of version 1.0.3, released today, you no longer need to add a try-except clause when running your scripts from the Spyder IDE. Except that there will be a warning (which could be suppressed if you disable logging). The warning is there to remind users that it's the same old client, not a new instance. Also note, I'm only talking about mph.start(). If the Client class is instantiated directly, as in the original code example, then that will still raise NotImplementedError.