Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chat #27

Closed
john-hen opened this issue Mar 10, 2021 · 74 comments
Closed

Chat #27

john-hen opened this issue Mar 10, 2021 · 74 comments
Labels
general General ideas and feedback.

Comments

@john-hen
Copy link
Collaborator

john-hen commented Mar 10, 2021

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 john-hen added the general General ideas and feedback. label Mar 10, 2021
@john-hen john-hen pinned this issue Mar 10, 2021
@john-hen
Copy link
Collaborator Author

john-hen commented Mar 10, 2021

As mentioned in #16, the next feature release, version 0.9, will be out soon, pending more tests and a few updates to the documentation.

As of 0.9, the preferred way to start a local Comsol session is calling mph.start(). This function is new. Previously, we had to instantiate mph.Client.

mph.start() creates a stand-alone client on Windows, and a local client and server on Linux and macOS. The latter is due to the platform limitations explained in #8. The former is for backward compatibility and for performance reasons too. The stand-alone client spins up in about half the time compared to a server process. And it's probably the more robust setup as well, as it avoids the fickle communication over the local, and dynamically assigned, TCP socket.

It has always been my goal for release 0.9 to have support for all three platforms. Release 1.0 should follow when operation is proven to be stable and to work in multi-processing mode. That is, when it's clear that separate Python subprocesses can be reliably run from one parent process, so that we can have multiple workers contributing to a single job queue, say for (programmable) parameter sweeps, or even optimization algorithms that can be parallelized, such as the "genetic algorithm".

@john-hen
Copy link
Collaborator Author

I also noticed that I forgot to publish the last bug-fix release 0.8.2 here on GitHub. I'll take care of that at the same time. The release date will be wrong, but the release page here is mainly there for keeping the change-log. Actual release dates are those displayed on PyPI.

@john-hen
Copy link
Collaborator Author

I just uploaded a demo script that has a pool of workers solve a parameter sweep in parallel. It uses the multiprocessing module from the standard library.

As half-expected, this works without a hitch on Windows, where we run the session with a stand-alone client. But doesn't work on Linux, where we use client-server mode. The problem is the port assignment, as the different server processes get in each other's way as they start up, all trying to grab the same TCP port, 2036. It helps to introduce artificial delays, but that's not only an ugly hack, it would also be a performance hindrance on machines with many cores.

@gwiederhecker
Copy link

John, this sounds really cool. Worked out of the box on Catalina and I excited to test all the features. Congrats on the initiative!

@john-hen
Copy link
Collaborator Author

Thanks, Gustavo, glad to hear! Feel free to post feedback and questions here as you go along.

@john-hen
Copy link
Collaborator Author

john-hen commented Mar 16, 2021

Status update...

The multiprocessing demo worker_pool.py works now and is also documented. We have to manually assign server ports via mph.start() when using client-server mode (Linux and macOS) to create multiple processes at once. Version 1.0 will be released once the (basic) support for feature creation and property changes, discussed in #25, has been implemented.

@max3-2
Copy link
Contributor

max3-2 commented Mar 17, 2021

I think I do have two more things to throw in the ring:

  1. Add a connect() method to client. Two reasons: First, theres disconnect() in the API, thus connect makes sense. Secondly, a practical reason would be loading a model locally, performing some tasks, namely IO which is faster local, and then moving to a remote to perform calculation without exiting the interpreter.
    If this is an option we should check if we need to clear() in disconnect() or if this is done by default. Or if the models can even be transfered to a new server.

  2. The savemehod could allow to specify the ending (optional argument) to allow file conversion to MATLAB, java or vba as supported by COMSOL.

@john-hen
Copy link
Collaborator Author

john-hen commented Mar 17, 2021

First of all, sure, there can be more things. Release 1.0 would take us out of beta and into production/stable territory, so I'm all for waiting a bit longer before pulling the trigger. Could be that our tests will reveal more bugs to fix, which would be a good thing.

  1. Yes, connect() makes sense because there's already disconnect(). But connect() is implicitly called by __init()__ if port is passed, so this would be more like "reconnect". I'm not sure this is feasible, especially without breaking the internal logic, where we also support stand-alone clients. And I've never encountered use cases where time spent on I/O operations comes anywhere close to simulation times. (I'm talking an hour here for solving, or hours, plural, maybe even days.) Also, I have no way of testing this, as I don't own a networking license. But if you do, and you can make this work seamlessly, go ahead.

  2. That's perfectly reasonable. Maybe we just don't enforce the file ending at all. I can see a use case here. If Comsol's save() method supports this behavior (I've never bothered to check), then we can just pass on the goodies.

@max3-2
Copy link
Contributor

max3-2 commented Mar 18, 2021

Regarding

  1. It needed a little workaround since the signature of java.save changes slightly. Please take a look at master...max3-2:m32-modelSaveTypes

@john-hen
Copy link
Collaborator Author

I looked at this the other day and wasn't sure if we want to have this new argument type, or if it wouldn't be more "pythonic" to case-select depending on the file's .suffix. But then couldn't really decide if I like one way or the other. But you can create a PR for this (too), I will merge it once I've made up my mind.

@john-hen
Copy link
Collaborator Author

john-hen commented Mar 24, 2021

I just released 0.9.1 with the latest changes that were in master. These are basically all bug fixes, therefore the modest version bump. Will get to the new features in the open PRs next.

@john-hen
Copy link
Collaborator Author

john-hen commented Apr 1, 2021

FYI, I've removed the sandbox folder from master and put it in a separate branch named sandbox. Something to keep in mind when rebasing on master.

@john-hen
Copy link
Collaborator Author

john-hen commented Apr 4, 2021

I've renamed the master branch to main, see github/renaming.

@john-hen
Copy link
Collaborator Author

john-hen commented Apr 5, 2021

We're getting closer to release 1.0. I'm planning to then get a DOI from Zenodo in case anyone ever wants to cite MPh in a paper. So testing, more than anything else, is the order of business until that release.

By the way, the docs at mph.readthedocs.io always point to the stable release, which is 0.9.1 at this point. But the latest version, i.e. the development version in main, is also available there. One just has to open the version pop-up menu at the bottom left. The docs badge on the GitHub repo's main page links to that latest version directly.

@max3-2
Copy link
Contributor

max3-2 commented Apr 5, 2021

So testing, more than anything else, is the order of business until that release.

I will do just that the next days. Got some COMSOL on my table anyway.

get a DOI from Zenode

Please do that. I work in Academia and many around me use COMSOL and are not happy with the scripting, so there will some users I guess. I will obviously spread the 1.0 word

@john-hen
Copy link
Collaborator Author

john-hen commented Apr 5, 2021

If you find bugs with the latest additions, you can just report them here in chat or in the other issue. No need to track them separately if they don't concern a past release.

One thing I already know: The wheel doesn't build at the moment. That's because I put an α in the version number, which flit doesn't like. But this will sort itself out when the release is final.

I work in Academia and many around me use COMSOL and are not happy with the scripting

Not just in academia. I think the first bullet point in the release notes will be some variation of: "We now offer you the best API Comsol has ever seen! 🎉"

@Chadwick4
Copy link

Hello,

First, thanks for making this great API. I was very excited and this should help with some coupled modelling I hope to do. I have been struggling with evaluating my results however. I am running a PEMFC simulation very similar to this one

One of the key results, current, is acquired via a volume integration however, as far as I know I can only extract the local current per volume relative to x, y, and z coordinates. I think I can find the integrated value by summing the local current per volume multiplied by the element the current per volume is assigned to, however it is quite difficulty to pin-point exactly which elements correspond to which current. This is particularly difficult since I think the points align with element boundaries rather than say the centre of the elements. If I go with this method is there a way to extract the mesh information (volume of each element, indices of element boundaries etc.?

The best thing for me would be if there is a way to access table values created within COMSOL. Is that possible through this API? Otherwise do you have any other method I could try to get the value I'm after? Please let me know if you need any more info. Any insight into this would be greatly appreciated!

Cheers,

Eric

@max3-2
Copy link
Contributor

max3-2 commented Apr 10, 2021

Eric,

let me try to help you here: In general, the evaluate functionality is not that mature. There are few dataset types that are supported - I guess yours is not as we focused on editing and adding model features as you can see from the issues. Currently, I see a few possibilites:

  • You can always export the data as vtu and pull it in again, e.g. paraview or python. If you need help with loading vtu I can give you some ideas. However, this will create an unstructured mesh in the domains. Postprocessing would then be done in another software
  • You can access all functionality via the java objects. Currently, this is model.java and then go on from there. I encourage you to try the new main where we have nodes implemented and you can do Node(‚path/in/comsol/tree‘).java to quickly get the java object. In your case this would point to your table you have set up. Then take a look at the COMSOL API Reference what you can to with tables, Chapter 2 model.results(), and then look for model.results().table() for methods. The latter will be your Node.java.
  • If you dont use the new main and need to batch script, take a reference model and save it as matlab oder java. You will then see how the model is built and you can use the model.java object to reproduce arbitrary functionality.

As soon as nodes are working safely (Release 1.0.presumably) working with tables is easier, see bullet 2. This is why I encourage you to try it with the current main.

At last - if its not confidential - feel free to upload a stripped model and let me know what you need in more detail

@john-hen
Copy link
Collaborator Author

john-hen commented Apr 10, 2021

Hi Eric, I'm glad you like the API. It will only get better in the upcoming release.

As Max explained, MPh does not replicate the entire Comsol API. Tables, for example, are not covered by MPh, and neither are certain results types, such as "volume integration" (accessible under "Derived Values" in the GUI). But if push comes to shove, you can always access the Comsol API directly, from Python, see section "Creating models" in the documentation.

I don't think that's necessary in this case. First of all, you should certainly let Comsol do the volume integration. Comsol knows its finite elements better than any of us, no need to try and recreate that in Python. What I would do here, I would define an integration coupling operator (under Definitions→Variables near the top of the model tree) and then use that in a global evaluation in post-processing. Global evaluations are supported by MPh, you can just pass the same expression to model.evaluate() that you would enter in the GUI.

Generally, this is the recommended way to automate post-processing: You define what you need in the model itself and then just trigger the evaluation or export via MPh.

@Chadwick4
Copy link

HI Max and John,

Thank you both for the quick replies! As I was figuring out how to do John's solution, I realized I already had global evaluations in the form of a domain probe and that's how I was getting my results in COMSOL in the first place. I just did not realize the results of the evaluations had expressions I could call with model.evaluation(). Thanks again! I look forward to new releases and hope to cite this API in a paper at some point!

Cheers,

Eric

@john-hen
Copy link
Collaborator Author

john-hen commented Apr 10, 2021

Also with the 1.0 release, I'm planning to move the repository to the GitHub "organization" MPh-py, which I've just created for that very purpose. Mostly to have shorter/nicer URLs when linking to the repo. I don't think we need the organization features. But lots of other projects use such a structure, JPype for example, so I figure this can't be wrong.

I hope all existing URLs will be redirected, as the GitHub documentation promises, so that old documentation builds of MPh don't suddenly link to dead targets when referring to the GitHub repo. Forks will automatically point to the new location and issues will be transferred. Only local clones may need to be reconfigured to push to the new upstream repo.

I will hold off on that until the release is final, because the meta information on PyPI would also need updating, and that can only happen when a release is published.

@Joel-H-dot
Copy link

Hi all,

I thought I would share a new function that I adapted from the evaluate code:

` def interp(self, expression, coord=None, unit=None, dataset=None,
inner=None, outer=None):

    # Get dataset and solution (Java) objects.
    dataset = self._dataset(dataset)
    logger.info(f'Evaluating {expression} on "{dataset.name()}" dataset.')
    solution = self._solution(dataset.name())

    # Make sure solution has actually been computed.
    if solution.isEmpty():
        error = 'The solution has not been computed.'
        logger.critical(error)
        raise RuntimeError(error)

    # Validate solution arguments.
    if not (inner is None
            or (isinstance(inner, str)
                and inner in ('first', 'last'))
            or (isinstance(inner, list)
                and all(isinstance(index, int) for index in inner))
            or (isinstance(inner, numpy.ndarray)
                and inner.dtype == 'int')):
        error = ('Argument "inner", if specified, must be either '
                 '"first", "last", or a list/array of integers.')
        logger.critical(error)
        raise ValueError(error)
    if not (outer is None
            or isinstance(outer, int)
            or (hasattr(outer, 'dtype')
                and issubclass(outer.dtype.type, numpy.integer)
                and not outer.shape)):
        error = 'Argument "outer", if specified, must be an integer index.'
        logger.critical(error)
        raise ValueError(error)

    etag = self.java.result().numerical().uniquetag('eval')
    eval = self.java.result().numerical().create(etag, 'Interp')
    # Set the expression(s) to be evaluated.
    eval.set('expr', expression)

    # Set the unit(s), if specified.
    if unit is not None:
        eval.set('unit', unit)

    # Select an outer solution, i.e. parameter index, if specified.
    if outer is not None:
        eval.set('outersolnum', jtypes.JInt(outer))

    if coord is not None:
        eval.set('coord', coord)

    # Retrieve the data.
    logger.info('Retrieving data.')

    dtype = str(dataset.getType()).lower()

    # Retrieve the data.
    logger.info('Retrieving data.')
    if dtype == 'particle':
        results = array(eval.getReal())
        if eval.isComplex():
            results += 1j * array(eval.getImag())
        if isinstance(expression, (tuple, list)):
            shape = results.shape[1:]
            results = results.reshape(len(expression), -1, *shape)
    else:
        results = array(eval.getReal)

        if eval.isComplex():


            results = array(eval.getReal())+1j * array(eval.getImag())
        if inner is None:
            pass
        elif inner == 'first':
            results = results[:, 0, :]
        elif inner == 'last':
            results = results[:, -1, :]
        else:
            results = results[:, inner, :]
    logger.info('Finished retrieving data.')

    # Remove the temporary evaluation node we added to the model.
    self.java.result().numerical().remove(etag)

    # Squeeze out singleton array dimensions.
    results = results.squeeze()

    # Return array of results.
    return results`

With this I was able to pass co-ordinates where I want some field values. An example call might be:

` x = np.linspace((0.12 / xy_points) / 2, 0.12 - (0.12 / xy_points) / 2, xy_points)
y = np.linspace((0.12 / xy_points) / 2, 0.12 - (0.12 / xy_points) / 2, xy_points)
X,Y = np.meshgrid(x,y)
X_flatten = np.reshape(X,(1,no_elements_xy))
Y_flatten = np.reshape(Y,(1,no_elements_xy))

    grid = np.concatenate((X_array,Y_array,Z_array))
    (E_x) = model.interp('mf.Ex', coord=grid.tolist())

`

This has worked a treat for me.

@john-hen
Copy link
Collaborator Author

Thanks for sharing, Joel. It will have to wait until after release 1.0, which is imminent. But we'll get to that eventually. See also feature request #26.

@john-hen
Copy link
Collaborator Author

Release 1.0 is out now. 🎉

Thanks a lot for all your help, Max! The new features we discussed in #25 turned out much better than I had ever hoped they would. My original plan was just to be stable on all three platforms by 1.0. But this deserves the version bump even more. Cheers. 🥂

@max3-2
Copy link
Contributor

max3-2 commented Apr 14, 2021

Thank you for the work you put in the project. Let's see how the new features work out and how much is reported back. I will presumably use it myself in the coming weeks, quite a lot.
I'm happy to continue supporting in the future (however just now the semester started and I will have substantially less time for coding in the coming weeks)

@ssackMWL
Copy link

Hello,
Thanks for the great work. Keep it up.

I have updated mph from version 0.8 to 1.0. It seems that if I use the model.parameter function with a complex value, it truncates the imaginary part in the newer version. Can you please advise what to do?

@john-hen
Copy link
Collaborator Author

Hi, thanks for bringing this up. I've never tested complex values, but could easily add that to the test suite. Can you please open a new issue and provide a code example? Just the call to model.parameter() that used to work in 0.8 and now no longer does.

@max3-2
Copy link
Contributor

max3-2 commented Apr 29, 2021

John, I have seen you keep on improving the current setup, nice work. I hope you haven't had to type the tags json by hand 🙃.
Just an idea, I place this here since I am actually not aware if we have discussed this already. I had a co-worker of mine use the package and they suggested that Nodes could be accessible in a dict style notation from the model, eg. model['node/path']. This in mainly motivated by the idea that not everyone is used to the pathlib advantages (yet?) but dicts are quite common. There's also contains so this also leads the user to try the dict notation.

@john-hen
Copy link
Collaborator Author

john-hen commented Jun 2, 2021

Oh, come on, like you owe us an apology. This project here wouldn't exist without JPype. I am, quite frankly, in awe how complicated it is to get Python and Java to play nice with each other. It's ready when it's ready and we'll wait. Plan is to have one more bug-fix release (1.0.5) in the 1.0 series, which will require JPype >=1.3 for the extra stability, before moving on to adding features for 1.1.

@SamF111
Copy link

SamF111 commented Jun 8, 2021

Just dropping by to say thanks for this project. I was using pyautogui to automatically script COMSOL before I found this, and this is so easy to use in comparson. I plan to cite MPh in future work, so please let me know if you get a DOI!

@john-hen
Copy link
Collaborator Author

john-hen commented Jun 8, 2021

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
Copy link

jing-bi commented Jun 9, 2021

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
Copy link
Collaborator Author

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
Copy link

jing-bi commented Jun 10, 2021

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
Copy link
Collaborator Author

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
Copy link

jing-bi commented Jun 10, 2021

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
Copy link
Contributor

max3-2 commented Jun 15, 2021

@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
Copy link
Collaborator Author

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
Copy link

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
Copy link
Collaborator Author

@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
Copy link
Contributor

max3-2 commented Jul 12, 2021

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

@Thrameos
Copy link

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

@max3-2
Copy link
Contributor

max3-2 commented Jul 12, 2021

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
Copy link
Contributor

max3-2 commented Jul 19, 2021

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:
#   https://bugreport.java.com/bugreport/crash.jsp
#
zsh: abort      python3 test_client.py log debug

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

@Thrameos
Copy link

Thrameos commented Jul 19, 2021 via email

@max3-2
Copy link
Contributor

max3-2 commented Jul 20, 2021

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
Copy link
Collaborator Author

john-hen commented Aug 1, 2021

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
Copy link
Contributor

max3-2 commented Aug 3, 2021

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

@smick290
Copy link

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
Copy link

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
Copy link
Collaborator Author

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
Copy link

SamF111 commented Sep 8, 2021

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
Copy link
Collaborator Author

john-hen commented Sep 8, 2021

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 john-hen unpinned this issue Oct 7, 2021
@john-hen john-hen closed this as completed Oct 7, 2021
@john-hen
Copy link
Collaborator Author

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

@MPh-py MPh-py locked and limited conversation to collaborators Oct 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
general General ideas and feedback.
Projects
None yet
Development

No branches or pull requests