MPh-py / MPh

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

Chat #27

Closed john-hen closed 2 years ago

john-hen commented 3 years ago

Leave a comment here if you have general feedback, a question to ask, want to float an idea, share a user story, or have anything else to say that may not merit opening a new issue.

Please do not leave a comment here if you are reporting a bug. Then by all means do open a new issue.

john-hen commented 3 years ago

Thanks, glad to hear it. I can see how this is a step up from PyAutoGui, that's probably quite a fickle setup. Never even considered that, even though I suffered the shortcomings of the Matlab interface (or just Matlab, really) for several years and desperately wanted to move to Python. This only works thanks to JPype, bears repeating.

You find the DOI at the bottom of the project's front page, either here on GitHub, or on Read-the-Docs, or PyPI. It's just a "badge", not mentioned in the text, and links to the corresponding Zenodo page. Which is a service provided by CERN, for any kind of software, and let's you cite specific versions or the project as a whole. That's pretty much the extent of what I know about it.

jing-bi commented 3 years ago

I tried this package and I'd say this is just awesome, GOOD JOB. But I just have a different use case and wish to hear your option. I'm trying to control a compiled model with python but I suppose it needs some work around the application builder?

Is that possible that we can build up some inter-process communication(like sockets) as a COMSOL application builder method?

john-hen commented 3 years ago

Thank you for the compliment. As for your use case, I'm not sure I follow.

When you say "compiled model", do you mean you have a stand-alone application produced by the Comsol Compiler? If so, there is almost certainly nothing we can do. As that should be a monolithic executable that, probably by design, won't interact with external processes.

But maybe you mean a compiled Java model, produced with comsolcompile. (If you find that distinction somewhat confusing, you are not alone.) Even then, I wouldn't know how to interact with it, other than in the usual way: load it, run it, etc. So any inter-process communication would be one way, Python calling (standard) Java methods, but not the other way around. Though in this case I could be missing something. Depends on what these application builder methods can do. I'm not so familiar with the Java side of things. Do you want to call into Python from Java?

jing-bi commented 3 years ago

Thanks for the promote reply. I'm trying to send data from python to java.

By compiled model, I mean here at 1:06. I find it's possible that use the application builder method to read an external file as config, but it's just a one-time thing, I hope it to be interactive with python. For example, python sent config as JSON data to COMSOL then it loads the data then runs the model.

The main reason for this approach is that you don't need the license for the compiled model, you can run it wherever you want.

To be honest, I do get confused about the java model produced by comsolcompile and the one I showed above. Can you please elaborated more about their difference?

john-hen commented 3 years ago

You can save a .mph Comsol model as a .java Java source file, then run comsolcompile to get a compiled .class Java class file. The latter can then be run without the GUI, either via comsolbatch or directly via Java. But this still requires a Comsol license on the local machine and is not what you meant.

So you want to exchange JSON data with that compiled application. MPh won't be of any help there. And neither will be JPype, the underlying Java bridge. But your idea might still work if you figure out how to set up that TCP socket connection on both sides. Because that's language-agnostic. The Python side won't be the problem, you can just use the socket module. But I don't know how to do it on the Java side, from within the Application Builder, and there's a (good?) chance the Comsol developer's have put some restrictions in place.

jing-bi commented 3 years ago

Yes, you understand my ideas. I tried to find a way to set up the connection on the java side but didn't find anything useful, seems they limited everything to their GUI and don't want you to do this.

Anyway, thanks for helping, i might just give up this idea and stick to your package.

Thanks again for providing this awesome package!

max3-2 commented 3 years ago

@John-Hennig BTW jpype released 1.3 on PyPI. If you need any support with this or the other issues let me know..

john-hen commented 3 years ago

Yeah, I know. My tests with the final release were however not as successful as with the development version. Otherwise I would have already published 1.0.5 a week ago. So I'm a little bit stuck. I'll try to consolidate my local copy of the shutdown_fix branch and push that upstream for testing...

Thrameos commented 3 years ago

Please let me know if the shutdown fix didn't work. I removed one of the options as it was found to violate the JVM mechanics (you can't unload the JVM dll or the interrupt handlers will become unstable.) But otherwise, it should be exactly as we discussed.

john-hen commented 3 years ago

@Thrameos Will do, thanks. I'll report details in issue #38, later this week, but I'll ping. I need some more time to rerun the tests with the dev version vs. the new version. There's also the added complication of pyTest turning on fault handlers during shutdown, which (also) leads to seg faults on Windows, so I'm trying to find out what's what.

max3-2 commented 3 years ago

Any news on the jpype improvement? Any way I can support?

Thrameos commented 3 years ago

Wasn't the shutdown issue resolved with 1.3.0? Or is there further action required?

max3-2 commented 3 years ago

From ‘jpype‘ it was but the old workaround is still in here and @John-Hennig mentioned some issues left however up to now no update has been finalized so that’s why I asked.

max3-2 commented 3 years ago

So I tested with jpype=1.3 and monkey-patching removed on both Windows and macOS and it works for me (mostly). I will do some more tests these days, but it looks promising also seeming to remove errors as reported in #38. I have no idea however what John is up to right now haven't seen any activity in the recent past. Maybe on vacation...

@Thrameos The only thing that remains strange is that Im getting the following error somewhat intermittently, e.g. running the same test in lets say 60% of the time. Strangely only when running this test where other tests work flawlessly even though they use the same initialization of the jpype interface. This occurs right after calling jpype.shutdownJVM() which proceeds without issues.

I have the log below sorry its quite long

Error:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x0000000119a35910, pid=26451, tid=0x0000000000002a03
#
# JRE version: OpenJDK Runtime Environment (8.0_222-b10) (build 1.8.0_222-b10)
# Java VM: OpenJDK 64-Bit Server VM (25.222-b10 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.dylib+0x248910]
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /Users/.../hs_err_pid26451.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#
zsh: abort      python3 test_client.py log debug

Log: https://gist.github.com/max3-2/dd0c6612df0660a65e99a5960a9fdc1c

Thrameos commented 3 years ago

If we could replicate the situation it would be great. I am guessing that the test is creating a thread which was in a bad state at the time the shutdown and needs to be terminated before the shutdown call. But that is only a guess.

Nothing in the error log stood out for me in the first glance. I will look it over more when I have some additional time.

max3-2 commented 3 years ago

The only thing I see different is that in this test (test_client) a model is loaded from file and not created which is a little more data IO. However, changing that to a model created on the fly did not really made a difference. Im still a little confused why this specific test is causing issues and I will report back...

FWIW I patchen in a

    if not jpype.config.destroy_jvm:
        print('zZZz')
        time.sleep(1.)

at ll341 jpype._core and this makes the issue much less likely to pop up - maybe some thread needs more time to shut down if destroy_jvm is disabled?

Edit: OK I traced it down to test_remove() where models are removed from memory via client.remove() which in turn calls the java.remove() from the internal COMSOL library (black box). This seems to somehow cause lingering objects when the interpreter shuts down without destroying the jvm. Adding sleeps helps, but I have not found any reasonable "maximum" value

john-hen commented 3 years ago

Sorry for being AWOL. It's been a combination of vacation and... frustration. And then I had some other priorities. But I've now summarized what I know in a post in issue #38. I observe pretty much the same on Windows on Linux as Max does on macOS. (@max3-2, @Thrameos ).

max3-2 commented 3 years ago

I was wondering if COMSOL bough you out... ;) Ill continue in #38 think thats the correct place to discuss..

smick290 commented 3 years ago

Hi John,

first of all, kudos for the awesome job on this. the problem I'm currently facing is that running on a Ubuntu machine I'm able to start a client, load a model, solve but then when I try to use the model.export I get the following: Unable to init server: Could not connect: Connection refused

any idea? I have to say that the same code and model run just fine on my mac machine.

smick290 commented 3 years ago

Hi John,

first of all, kudos for the awesome job on this. the problem I'm currently facing is that running on a Ubuntu machine I'm able to start a client, load a model, solve but then when I try to use the model.export I get the following: Unable to init server: Could not connect: Connection refused

any idea? I have to say that the same code and model run just fine on my mac machine.

Just a follow up just in case someone runs into the same issue. The way I'm running is via a ssh that's is not forwarding the display and therefore crashes the moment the export has to display a plot. the easiest way to workaround is to disable plots by setting the client to : client.java.showPlots(0)

john-hen commented 3 years ago

Hi, @smick290. Thanks for sharing. I was not aware of this issue, but it seems you have found a solution.

I do test on Ubuntu (in a VM), but never via ssh. We do start the Comsol server process with the -graphics option enabled. Maybe it wouldn't crash without it. After all, the export never actually "displays" the plot, right? I don't think that option is strictly necessary, but there must have been a reason why I included it. I have run into all kinds of issues with the graphics library, which seems to be some version of ImageMagick that is somehow vendored in. But the way it's integrated into Comsol seems to be quite fragile.

It would be possible to make the -graphics option configurable, though I don't know to what extent that would help. We would have to test that. Also, a specific problem such as this one is best discussed in a dedicated issue. Users running into the same problem as you are unlikely to go through all the messages here in Chat.

SamF111 commented 3 years ago

I've been unable to scale my use of MPh to use other computers. I can confirm that a server is running on the other computer. On the client computer, I run

import mph
server_path = "xx.xx.xx.xx"
client = mph.Client(version="5.6",port="2036",host=server_path)

Which gives me

Traceback (most recent call last): File "xx\PycharmProjects\Calorimeter_COMSOL\Network_Test.py", line 8, in client = mph.Client(version="5.6",port="2036",host=server_path) File "xx\AppData\Roaming\Python\Python39\site-packages\mph\client.py", line 129, in init java.connect(host, port) TypeError: No matching overloads found for static com.comsol.model.util.ModelUtil.connect(str,str), options are: public static void com.comsol.model.util.ModelUtil.connect(java.lang.String,int,boolean) public static void com.comsol.model.util.ModelUtil.connect() public static void com.comsol.model.util.ModelUtil.connect(java.lang.String,int) public static void com.comsol.model.util.ModelUtil.connect(java.lang.String,int,boolean,java.lang.String,java.lang.String) public static void com.comsol.model.util.ModelUtil.connect(java.lang.String,int,java.lang.String,java.lang.String)

Is there something obvious that you can see that I'm doing wrong?

==============

edit: port needs to be an int not a string.

john-hen commented 3 years ago

I see you figured it out. Yeah, we're interfacing with Java, and as a strongly typed language, it is less forgiving than Python when it comes to type mismatches.

john-hen commented 2 years ago

Unpinned as it distracts from the open issues, and closed as we now have Discussions for general feedback.