GithubHelp home page GithubHelp logo

mph-py / mph Goto Github PK

View Code? Open in Web Editor NEW
263.0 13.0 66.0 1.9 MB

Pythonic scripting interface for Comsol Multiphysics

Home Page: https://mph.readthedocs.io

License: MIT License

Python 100.00%
comsol multiphysics finite-elements physics comsol-multiphysics simulation

mph's Introduction

MPh

Pythonic scripting interface for Comsol Multiphysics

Comsol is a commercial software application that is widely used in science and industry for research and development. It excels at modeling almost any (multi-)physics problem by solving the governing set of partial differential equations via the finite-element method. It comes with a modern graphical user interface to set up simulation models and can be scripted from Matlab or its native Java API.

MPh brings the dearly missing power of Python to the world of Comsol. It leverages the Java bridge provided by JPype to access the Comsol API and wraps it in a layer of pythonic ease-of-use. The Python wrapper covers common scripting tasks, such as loading a model from a file, modifying parameters, importing data, to then run the simulation, evaluate the results, and export them.

Comsol models are marked by their .mph file extension, which stands for multi-physics. Hence the name of this library. It is open-source and in no way affiliated with Comsol Inc., the company that develops and sells the simulation software.

Find the full documentation on Read-the-Docs.

release page download statistics scientific citation coverage report latest documentation

mph's People

Contributors

jacobfeder avatar john-hen avatar maederan201 avatar max3-2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mph's Issues

Chat

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.

`model.remove()` can fail silently

Hi,

the method model.remove() seems to fail silently if the tag is not available. While this does not break anything, it can lead to strange behavior.

Additionally, this only works in root groups defined in self_groups since sub groups won't always have .remove()

This could be fixed with a check if the tag is in the list of tags. Otherwise, I will post an example for hierarchy soon which, among others features solves this issue.

macOS support

MPh 0.8.0, released today, adds support for macOS. The same caveats as for Linux, detailed in issue #8, apply here as well. Both Linux and macOS are Unix-like operating systems, so the differences are small: see the documentation.

Though on top of that, the macOS implementation is completely untested, for lack of the required hardware, and therefore considered merely experimental. In other words, MPh might work on macOS, but probably won't. Though if it doesn't, it should be a fairly straightforward fix. Comment here if you are in a position to test this.

Builds fail on macOS

When using the deploy/build.py it creates

Traceback (most recent call last):
  File "deploy/build.py", line 17, in <module>
    move(root/'dist', root/'deploy'/'dist')
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/shutil.py", line 562, in move
    real_dst = os.path.join(dst, _basename(src))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/shutil.py", line 526, in _basename
    return os.path.basename(path.rstrip(sep))
AttributeError: 'PosixPath' object has no attribute 'rstrip'

Explanation should be here...
https://stackoverflow.com/questions/61327385/trying-to-use-on-path-object-python

Access material property groups

Hi, thanks for creating such a useful scripting tool!

I was wondering if a method of querying and changing material properties i.e. thermal conductivity could be implemented. Currently node.properties() on a material returns a dict of "display" properties such as color, etc. It would be nice to have access to material properties to allow parametric sweeps and optimization.

Appreciate it!

Modifying `create` function from `Client` class to add more model features

I saw it in the comment section of def load() in Client.py that we are able to add model features intended for Java. Is there an example of how we can implement java code in here? For example, is there a way to create new geometries and add dimensions? I read the comments in the def load() function, but still have trouble understanding how I can do this?

`AttributeError` raised when running multiple processes

Hey, dear john, thanks again for sharing this wonderful work!
I had run a orthogonal test in a script, to avoid the extremely long runtime but not raising exception during a iteration, I put the code "model.solve()" into Multiprocessing.Process just like following
def _solve():
global model
model.solve()

p = Multiprocessing.Process(_solve)
p.start()

The script raise
"""
File "", line 1, in
File "D:\anaconda\lib\multiprocessing\spawn.py", line 105, in spawn_main
exitcode = _main(fd)
File 'D:\anaconda\lib\multiprocessing\spawn.py', line 115, in _main
self = reduction.pickle.load(from_parent)
AttributeError: Can't get attribute '_solve' on <module 'mp_main' from {file}.>
"""

`UnsatisfiedLinkError` when loading model

Hi,

I'm creating a new issue as per #56--the following code results in the subsequent errors:

client = mph.start(cores=1)
model = client.load('my_file.mph')
  File "SourceFile", line 168, in com.comsol.model.util.ModelUtil.load
  File "SourceFile", line 134, in com.comsol.model.util.ServerModelUtil.load
  File "SourceFile", line 930, in com.comsol.model.util.ServerModelUtil.a
  File "SourceFile", line 636, in com.comsol.nativeutil.d.b.m
  File "SourceFile", line 22, in com.comsol.nativeutil.d.c.<clinit>
  File "SourceFile", line 166, in com.comsol.nativejni.util.FlLicense.getInstance
  File "SourceFile", line 71, in com.comsol.nativejni.util.FlLicense.<init>
  File "SourceFile", line -2, in com.comsol.nativejni.util.FlLicense.initWS0
Exception: Java Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File ".\runAcc.py", line 8, in <module>
    model = client.load('PEPPER-Sweep_CMNT_ACC_only.mph')
  File "C:\Users\PSPL_Workstation_1\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-package
s\Python38\site-packages\mph\client.py", line 324, in load
    model = Model(self.java.load(tag, str(file)))
java.lang.UnsatisfiedLinkError: java.lang.UnsatisfiedLinkError: 
com.comsol.nativejni.util.FlLicense.initWS0(Lcom/comsol/nativejni/CPointer;)V

I've referenced the edge case from #49, and the following lines do not result in any errors (when I run from a Windows machine using Powershell):

import jpype
jpype.startJVM('C:/Program Files/COMSOL/COMSOL56/Multiphysics/java/win64/jre/bin/server/jvm.dll')

I've also looked into the test suite and am able to run just about all the test_ scripts except for test_model.py, test_node.py, and test_standalone.py. Pasted below are the errors from test_model.py and test_standalone.py, respectively.

  File "SourceFile", line 90, in com.comsol.model.util.ModelUtil.createUnique
  File "SourceFile", line 83, in com.comsol.model.util.ModelUtil.create
  File "SourceFile", line 42, in com.comsol.model.util.ServerModelUtil.create
  File "SourceFile", line 636, in com.comsol.nativeutil.d.b.m
  File "SourceFile", line 22, in com.comsol.nativeutil.d.c.<clinit>
  File "SourceFile", line 166, in com.comsol.nativejni.util.FlLicense.getInstance
  File "SourceFile", line 71, in com.comsol.nativejni.util.FlLicense.<init>
  File "SourceFile", line -2, in com.comsol.nativejni.util.FlLicense.initWS0
Exception: Java Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File ".\test_model.py", line 694, in <module>
    setup_module()
  File ".\test_model.py", line 28, in setup_module
    model  = models.capacitor()
  File "C:\Users\PSPL_Workstation_1\SP\comsol\MPh-main\tests\models.py", line 10, in capacitor
    model = mph.session.client.create('capacitor')
  File "C:\Users\PSPL_Workstation_1\SP\comsol\MPh-main\mph\client.py", line 356, in create
    java = self.java.createUnique('model')
java.lang.UnsatisfiedLinkError: java.lang.UnsatisfiedLinkError: 
com.comsol.nativejni.util.FlLicense.initWS0(Lcom/comsol/nativejni/CPointer;)V
  File "SourceFile", line 90, in com.comsol.model.util.ModelUtil.createUnique
  File "SourceFile", line 83, in com.comsol.model.util.ModelUtil.create
  File "SourceFile", line 42, in com.comsol.model.util.ServerModelUtil.create
  File "SourceFile", line 636, in com.comsol.nativeutil.d.b.m
  File "SourceFile", line 22, in com.comsol.nativeutil.d.c.<clinit>
  File "SourceFile", line 166, in com.comsol.nativejni.util.FlLicense.getInstance
  File "SourceFile", line 71, in com.comsol.nativejni.util.FlLicense.<init>
  File "SourceFile", line -2, in com.comsol.nativejni.util.FlLicense.initWS0
Exception: Java Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File ".\test_standalone.py", line 57, in <module>
    test_start()
  File ".\test_standalone.py", line 26, in test_start
    model = client.create('empty')
  File "C:\Users\PSPL_Workstation_1\SP\comsol\MPh-main\mph\client.py", line 356, in create
    java = self.java.createUnique('model')
java.lang.UnsatisfiedLinkError: java.lang.UnsatisfiedLinkError: 
com.comsol.nativejni.util.FlLicense.initWS0(Lcom/comsol/nativejni/CPointer;)V

As was mentioned earlier, this is using an FNL license, though it is unlikely to be the source of the error. There seems to be an issue with the createUnique function but I am not too sure why it wouldn't work. Your assistance would be greatly appreciated.

Discovery requires Python>=3.8

Running discovery.py (or any module that depends) with Windows will lead to

Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import mph
>>> s = mph.Server()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\nnn\.pyenvs\t\lib\site-packages\mph\server.py", line 83, in __init__
    backend = discovery.backend(version)
  File "C:\Users\nnn\.pyenvs\t\lib\site-packages\mph\discovery.py", line 403, in backend
    backends = search_system()
  File "C:\Users\nnn\.pyenvs\t\lib\site-packages\mph\discovery.py", line 380, in search_system
    return search_Windows()
  File "C:\Users\nnn\.pyenvs\t\lib\site-packages\mph\discovery.py", line 141, in search_Windows
    creationflags=0x08000000)
  File "C:\Users\nnn\AppData\Local\Programs\Python\Python37\lib\subprocess.py", line 488, in run
    with Popen(*popenargs, **kwargs) as process:
  File "C:\Users\nnn\AppData\Local\Programs\Python\Python37\lib\subprocess.py", line 800, in __init__
    restore_signals, start_new_session)
  File "C:\Users\nnn\AppData\Local\Programs\Python\Python37\lib\subprocess.py", line 1148, in _execute_child
    args = list2cmdline(args)
  File "C:\Users\nnn\AppData\Local\Programs\Python\Python37\lib\subprocess.py", line 555, in list2cmdline
    needquote = (" " in arg) or ("\t" in arg) or not arg
TypeError: argument of type 'WindowsPath' is not iterable

which seems to be the issue here: https://bugs.python.org/issue33617

The exception is gone with updating python. However, the requirements state 3.6 which is not valid.

  1. str() cast the Path()?
  2. update requirements?

Best

Evaluation error: "Unknown property: solution"

Hi,

Im trying to run the evaluate method, where the dataset is a Cut Point 3D (I also tested surface) - this is what I get when I run model.evaluate('T', dataset='dataset_name'):

 File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/mph/model.py", line 394, in evaluate
    solution = self._solution(dataset.name())
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/mph/model.py", line 329, in _solution
    stag = dset.getString('solution')
com.comsol.util.exceptions.FlException: Exception:
	com.comsol.util.exceptions.FlException: Unknown property
Messages:
	Unknown property.
	- Property: solution
  1. Solution has been computed and is shown in model.solutions()
  2. Diving into the API and retrieving the dataset yields the following insights:
  • After dataset creation, there is the the property hasbeenevaluated which is not per-se true after creation. Maybe before evaluating, a call to dset.run() is useful (I just assume that) based on the value of getBooleean('hasbeenevaluated')
  • This however doe not fix the bug. For my specific case (3D model, computed, created dataset from UI, saved, loaded via Mph), a call to `sorted(list(dset.porperties())) yields (sorry for the ugly output) with no solution property present
['bndsnap', 'data', 'filename', 'gridx', 'gridx_vector_freqperdec', 'gridx_vector_function', 'gridx_vector_interval', 'gridx_vector_method', 'gridx_vector_numvalues', 'gridx_vector_start', 'gridx_vector_step', 'gridx_vector_stop', 'gridy', 'gridy_vector_freqperdec', 'gridy_vector_function', 'gridy_vector_interval', 'gridy_vector_method', 'gridy_vector_numvalues', 'gridy_vector_start', 'gridy_vector_step', 'gridy_vector_stop', 'gridz', 'gridz_vector_freqperdec', 'gridz_vector_function', 'gridz_vector_interval', 'gridz_vector_method', 'gridz_vector_numvalues', 'gridz_vector_start', 'gridz_vector_step', 'gridz_vector_stop', 'hasbeenevaluated', 'isdataexport', 'isexcel', 'ispreviewplot', 'issol', 'lastgrid', 'lastpoints', 'method', 'pointvar', 'pointx', 'pointx_vector_freqperdec', 'pointx_vector_function', 'pointx_vector_interval', 'pointx_vector_method', 'pointx_vector_numvalues', 'pointx_vector_start', 'pointx_vector_step', 'pointx_vector_stop', 'pointy', 'pointy_vector_freqperdec', 'pointy_vector_function', 'pointy_vector_interval', 'pointy_vector_method', 'pointy_vector_numvalues', 'pointy_vector_start', 'pointy_vector_step', 'pointy_vector_stop', 'pointz', 'pointz_vector_freqperdec', 'pointz_vector_function', 'pointz_vector_interval', 'pointz_vector_method', 'pointz_vector_numvalues', 'pointz_vector_start', 'pointz_vector_step', 'pointz_vector_stop', 'probetag', 'range', 'regulargridx', 'regulargridy', 'regulargridz', 'sheet']

Tested on macOS COMSOL 5.5

Discovery of Comsol 6.0 fails on Linux

Hi,
I've upgraded my comsol version to 6.0 and now mph is failing to locate comsol. I did a quick research and it seems that the following code is failing with comsol 6.0:
backends.append({ 'name': name, 'major': major, 'minor': minor, 'patch': patch, 'build': build, 'root': root, 'jvm': jvm, 'java': java, 'server': [comsol, 'mphserver'],
I've downgraded and it works as usual.
Louis

Exporting meshes as `.mphtxt` files

Hi,

Im currently writing a Python optimization script with which I want to vary geometric parametrs of a Comsol model using MPh and create and export Meshes of the Model.

Since I'm not running any actual Simulations on the Model and only want the Mesh, my only export Node is a Mesh export Node. With this export node I want to generate an .mphtxt file of my model. However, when I attempt to run the code I get the following error message:

TypeError: Node "exports/Mesh 1" is of the unexpected type "Mesh".

Is the exporting of Meshes not implmented or am I simply overlooking something? Attached are screenshots of my code.

Thanks in advance!
mph code
mph

macOS stand-alone client fails

With PR #11 initializing a Server object and connecting a client to this server works. However, when trying to build the Client as standalone, an exception is raised. Strangely, the path should be added (see client.py) and the file libiomp5.dylib is in the folder.

Exception                                 Traceback (most recent call last)
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in com.comsol.model.util.ModelUtil.initStandalone()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in com.comsol.model.util.ServerModelUtil.initStandalone()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in com.comsol.model.util.ServerModelUtil.initStandalone()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in java.security.AccessController.doPrivileged()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in com.comsol.model.util.ServerModelUtil$17.run()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in java.lang.System.load()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in java.lang.Runtime.load0()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in java.lang.ClassLoader.loadLibrary()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in java.lang.ClassLoader.loadLibrary0()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/_jpype.cpython-37m-darwin.so in java.lang.ClassLoader$NativeLibrary.load()

Exception: Java Exception

The above exception was the direct cause of the following exception:

java.lang.UnsatisfiedLinkError            Traceback (most recent call last)
<ipython-input-3-23d2b50bf9f8> in <module>
----> 1 c = mph.Client()

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/mph/client.py in __init__(self, cores, version, port, host)
    147             logger.info('Initializing stand-alone client.')
    148             graphics = True
--> 149             java.initStandalone(graphics)
    150             logger.info('Stand-alone client initialized.')
    151         # Otherwise skip stand-alone initialization and connect to server.

java.lang.UnsatisfiedLinkError: java.lang.UnsatisfiedLinkError: /Applications/COMSOL55/Multiphysics/lib/maci64/libcssystemutil.dylib: dlopen(/Applications/COMSOL55/Multiphysics/lib/maci64/libcssystemutil.dylib, 1): Library not loaded: @rpath/libiomp5.dylib
  Referenced from: /Applications/COMSOL55/Multiphysics/lib/maci64/libcssystemutil.dylib
  Reason: image not found

`model.save()` can fail with current `master`

John,

currently model save can fail if the argument is a single string, e.g. model.save('test.mph') - this occurs due to

        # Possibly deduce format from file ending.
        if format is None:
            suffix = path.suffix if path else '.mph'

where path is str and thus has no suffix. I think either a clear specification that a pathlib.Path needs to be supplied (complicated) or a typecast in model.save() is needed.

Best

RuntimeError: Could not locate any Comsol installation.

Hi, and thanks for making MPh.

I'm looking forward to using this, but, at the moment, I'm getting the error below, not sure how to fix this. Is there a way to directly specify where Comsol is installed?

In my case, I have comsol 6.0 installed on Ubuntu Linux 18.04 under

/usr/local/bin/comsol60/multiphysics/

Thanks

Python 3.6.9 (default, Dec  8 2021, 21:08:43) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> client = mph.start(cores=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'mph' is not defined
>>> import mph
>>> client = mph.start(cores=1)
Could not locate any Comsol installation.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/chaztikov/.local/lib/python3.6/site-packages/mph/session.py", line 102, in start
    server = Server(cores=cores, version=version, port=port)
  File "/home/chaztikov/.local/lib/python3.6/site-packages/mph/server.py", line 77, in __init__
    backend = discovery.backend(version)
  File "/home/chaztikov/.local/lib/python3.6/site-packages/mph/discovery.py", line 417, in backend
    raise RuntimeError(error)
RuntimeError: Could not locate any Comsol installation.
>>> 

Shutdown issues with exceptions

I have to "reopen" the issue with the JVM shutdown again.
Partly to document an underlying problem which might help someone else with debugging, partly to enforce the importance to fix the current solution.

With the current setup, atexit calls .exit(0). This shuts down the python interpreter with exit status 0. Additionally, as
stated in the atexit docs:

If an exception is raised during execution of the exit handlers, a traceback is printed (unless SystemExit is raised) and the exception information is saved. After all exit handlers have had a chance to run the last exception to be raised is re-raised.

Thus, any exception raised by actually ANY code after importing client will be printed, however is lost afterwards. A standard use case at least for me is building python script which then runs a model by loading, doing some adaptions, solving etc...Another case would be even running a script using subprocesses.
In both cases neither stderr nor the exit code are set. This is quite drastic...

Have you had an issue running on jpype regarding changes in between 0.75 and >1.0? I did a backward test and with 0.7.5 everything works smoothly as you stated in the original issues (this also holds on macOS)

Evaluation of complex-valued field data

I'm trying to evaluate an electric field at some pre-defined points, is there anyway to do this currently? The MATLAB version of what I want is [Et_x,Et_y,Et_z] = mphinterp(model,{'mf.Ex','mf.Ey','mf.Ez'},'coord',eval_points','Complexout','on');

I tried using something similar to (x, y, z, E) = model.evaluate(['x', 'y', 'z', 'mf.Ex']) as in the documentation and then evaluating the arrays 'x', 'y' and 'z' to find the corresponding field, but am receiving a few errors:

(x, y, z, E) = model.evaluate(['x', 'y', 'z', 'mf.Ex'])
ValueError: too many values to unpack (expected 4)

I got rid of the 'z' evaluation, which solves this particular error, but then how to get 3-D data?


The next problem is an issue with extracting complex field data, specifically the code segment in model

        if eval.isComplex():
            results += 1j * array(eval.getImagData())
            self.java.result().numerical().remove(etag)
            logger.info('Finished global evaluation.')

Which produces the error

results += 1j * array(eval.getImagData())
ValueError: non-broadcastable output operand with shape () doesn't match the broadcast shape

I saved the imaginary data to an excel file and found that it was extracting ~60000 different datasets for 10 different frequencies for a domain probe. There should only be one dataset. There was also an exception raised:

numpy.core._exceptions.UFuncTypeError: Cannot cast ufunc 'add' output from dtype('complex128') to dtype('int32') with casting rule 'same_kind'

image

I replaced the above code with the following, which fixed the issue, but is a bit of a bodge job, but did solve the problem of the different datatypes and of extracting a single dataset per frequency.

        if eval.isComplex():
            D = array(eval.getReal())+1j * array(eval.getImag())
            results = numpy.zeros((1,len(D[0,:])),dtype=numpy.complex_)
            results[0,:]=D[0,:]

Any idea on why so many different datasets are extracted for a domain probe?

all the best,

Joel.

Cryptic error when Comsol version is missing

John,

I stumbled across the following when starting the server with a wrong version, e.g. a typo or just a version not installed or not found, e.g server = Server(version=5.5.) will produce

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/mph/server.py", line 74, in __init__
    backend = discovery.backend(version)
  File "/usr/local/lib/python3.9/site-packages/mph/discovery.py", line 419, in backend
    return backends[names.index(version)]
ValueError: '5.4' is not in list

which I think is a bit cryptic. I suggest adding an e.g. logger.error('The specified version was not found)

Limited support for stand-alone clients on Linux/macOS

MPh 0.8.0, released today, adds support for Linux. That support is slightly limited in that it does not fully work out of the box. In order to start a stand-alone client (as opposed to running the Comsol session in client-server mode), it requires the user take an extra step and configure the search path for shared libraries as described in the documentation.

This is fine, but not ideal. For one thing, it's not just pip install and be done with it. And for another, it prevents users from easily selecting a specific Comsol version as the computation back-end, which is sometimes useful when reproducing earlier simulation results. So ideally, the manual configuration would not be necessary, but instead be done from Python code.

To perhaps track progress on this, or discuss a possible solution, here are some additional details. MPh now follows the instructions exactly as given in Comsol's Programming Manual (specifically, on pages 23 and 916) for running Java applications from the Eclipse IDE. That is, it sets up the environment in that same way before "initializing" the "stand-alone" client. (As opposed to a client-server connection, which works anyway, without any additional configuration.)

However, that alone does not do it. While all appears to be in working order as far as the Java Virtual Machine is concerned, in that it is aware of the locations of the external (native) libraries, these libraries themselves, which are dynamically loaded, have trouble finding each other, leading to a java.lang.UnsatisfiedLinkError. Which is odd: One would think that these child processes inherit the environment set up in the parent process.

To showcase all of this, I have added the demo script test_Linux to the sandbox branch.

Documentation build fails

...at least on macOS, it fails with

building [mo]: targets for 0 po files that are out of date
building [html]: targets for 10 source files that are out of date
updating environment: 10 added, 0 changed, 0 removed
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/recommonmark/parser.py:75: UserWarning: Container node skipped: type=document                                                              
  warn("Container node skipped: type={0}".format(mdnode.t))
reading sources... [ 20%] api/mph.Client                                                                                                                                                                                 
Exception occurred:
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sphinx/ext/autodoc/__init__.py", line 82, in members_option
    return [x.strip() for x in arg.split(',')]
AttributeError: 'bool' object has no attribute 'split'
The full traceback has been saved in /var/folders/xm/pwqx41ps2b90l8c4mtcpt6vxpkvkzm/T/sphinx-err-jwzdst9k.log, if you want to report the issue to the developers.
Please also report this if it was a user error, so that a better error message can be provided next time.
A bug report can be filed in the tracker at <https://github.com/sphinx-doc/sphinx/issues>. Thanks!

Extended shutdown delay of JVM with JPype >= 1.0.0

MPh depends on the Python-to-Java bridge JPype. As of JPype 1.0.0, released two days ago, the shutdown of the Java virtual machine (JVM) seems to be inexplicably delayed at the end of the Python session. At least under certain circumstances. Apparently if, and only if, the Comsol client has already loaded a model into memory, but not otherwise.

To corroborate this, what follows is the log output from runs of the test_client script, as found in the tests folder of the repository. Except that, for the sake of clarity, all unit tests after the third one, test_load(), were deactivated (commented out), as they add no further insight.

With JPype 0.7.5, the previous stable release, the output is this:

$ python test_client.py log
[22:20:49.988] Checking registry node "SOFTWARE\Comsol\COMSOL55".
[22:20:49.988] Checking installation folder "C:\programs\Comsol".
[22:20:50.220] Reported version info is "COMSOL Multiphysics 5.5.0.359".
[22:20:50.220] Assigned name "5.5" to this installation.
[22:20:50.220] JPype version is 0.7.5.
[22:20:50.220] Starting Java virtual machine.
[22:20:50.675] Java virtual machine has started.
[22:20:50.675] Initializing stand-alone client.
[22:20:52.061] Stand-alone client initialized.
[22:20:52.527] Running on 1 processor core.
[22:20:52.527] Loading model "capacitor.mph".
[22:21:03.076] Finished loading model.
[22:21:03.076] Shutting down the Java virtual machine.
[22:21:03.076] Java virtual machine has shut down.

Here, the JVM shuts down pretty much immediately, no delay whatsoever.

With the newer release, JPype 1.0.0, however, the same test runs like this:

$ python test_client.py log
[22:21:52.751] Checking registry node "SOFTWARE\Comsol\COMSOL55".
[22:21:52.751] Checking installation folder "C:\programs\Comsol".
[22:21:52.999] Reported version info is "COMSOL Multiphysics 5.5.0.359".
[22:21:52.999] Assigned name "5.5" to this installation.
[22:21:53.014] JPype version is 1.0.0.
[22:21:53.014] Starting Java virtual machine.
[22:21:54.572] Java virtual machine has started.
[22:21:54.572] Initializing stand-alone client.
[22:21:55.981] Stand-alone client initialized.
[22:21:56.265] Running on 1 processor core.
[22:21:56.280] Loading model "capacitor.mph".
[22:22:06.082] Finished loading model.
[22:22:06.082] Shutting down the Java virtual machine.
[22:23:06.044] Java virtual machine has shut down.

There is now a delay of almost exactly one minute (some tens of milliseconds less) between telling the JVM to shut down and it actually doing so. This is not just a usability issue, but also a performance hindrance when distributing simulation runs over multiple external worker processes.

The delay does not occur if the test_load() unit test, which loads a Comsol model into the client's memory, is deactivated:

$ python test_client.py log
[22:23:53.303] Checking registry node "SOFTWARE\Comsol\COMSOL55".
[22:23:53.303] Checking installation folder "C:\programs\Comsol".
[22:23:53.534] Reported version info is "COMSOL Multiphysics 5.5.0.359".
[22:23:53.534] Assigned name "5.5" to this installation.
[22:23:53.534] JPype version is 1.0.0.
[22:23:53.534] Starting Java virtual machine.
[22:23:55.070] Java virtual machine has started.
[22:23:55.070] Initializing stand-alone client.
[22:23:56.511] Stand-alone client initialized.
[22:23:56.914] Running on 1 processor core.
[22:23:56.914] Shutting down the Java virtual machine.
[22:23:56.930] Java virtual machine has shut down.

Again, the shutdown is pretty much immediate, also with the newer version of JPype.

This means that JPype alone cannot be the culprit. It must have something to do with the inner workings (memory management or something) of the Comsol client. Or, unlikely but not impossible either, something inside MPh's code base.

Make search for installation folder case-insensitive on Linux

Thanks for this great work, it works very well ! I just propose to make the Comsol installation folder search case-insensitive. In my case, the folder name is COMSOL56. A workaround, which is maybe not the most elegant is

folders = []
for dirname in ['Comsol', 'COMSOL', 'comsol']:
    item = [item for item in Path('/usr/local').glob(f'{dirname}*') if item.is_dir()]
    if item:
        folders.append(item[0])

line 209 of discovery.py.

Stack overflow when accessing property of scattering boundary condition

I'm working with the electromagnetic waves / frequency domain physics with COMSOL 5.3a, and very weirdly I can't inspect or otherwise work with scattering boundary conditions. Everything else seems to work fine. For example, if I define two nodes:

node_scattering = model/'physics/Electromagnetic Waves, Frequency Domain/Scattering'
node_ffd = model/'physics/Electromagnetic Waves, Frequency Domain/Far-Field Domain 1/Far-Field Calculation 1'

And then use the .properties() method on each, node_ffd has no problem executing while node_scattering raises a Java exception: 'java.lang.StackOverflowError: java.lang.StackOverflowError.' The same exception comes up when I use mph.inspect((node_scattering).java). Everything other than scattering boundary conditions seems to be fine; I've tried to delete the layer and add a new one, but if it's scattering it breaks no matter what.

I also made an extremely basic model that is literally just a cube with a scattering boundary condition, and the same exception occurs.

License error -5 No such product

Hi,

first of all thanks for MPh package! I tried to follow the documentation but I get this error message. I may add, that I have a 'Classkit' Comsol License and a 'Reasearchkit' License on the machine. To make it more complicated, there are two versions of Comsol installed 5.5 and 5.6., of each license. But I only have access to the 'Classkit' version. I don't know if the problem lays in the 'Research-kit' license or if the issue is of a different nature.

Lastly, even if I select a Comsol, say 5.6. the error changes to: ' LookupError: Could not locate Comsol 5.6 installation.'

It would be great, if you could help me with this issue. Thank you!!!

import mph
#client = mph.start(cores=1,version=5.6)
client = mph.start(cores=1)
model = client.load('capacitor.mph')
print(client.names())
Traceback (most recent call last):
  File "SourceFile", line 168, in com.comsol.model.util.ModelUtil.load
  File "SourceFile", line 139, in com.comsol.model.util.ServerModelUtil.load
  File "AccessController.java", line -2, in java.security.AccessController.doPrivileged
  File "SourceFile", line 1, in com.comsol.model.util.ServerModelUtil$39.run
  File "SourceFile", line 142, in com.comsol.model.util.ServerModelUtil$39.a
  File "SourceFile", line 312, in com.comsol.model.util.ModelInternalUtil.load
  File "SourceFile", line 326, in com.comsol.model.util.ModelInternalUtil.load
  File "SourceFile", line 1189, in com.comsol.model.util.ModelManager.loadModel
  File "SourceFile", line 961, in com.comsol.model.util.ModelManager.a
  File "SourceFile", line 984, in com.comsol.model.util.ModelManager.a
  File "SourceFile", line 1238, in com.comsol.model.util.ModelManager.a
  File "SourceFile", line 107, in com.comsol.model.util.saveload.AbstractModelLoader.load
  File "SourceFile", line 185, in com.comsol.model.util.saveload.AbstractMphLoader.a
  File "SourceFile", line 508, in com.comsol.model.util.saveload.AbstractModelLoader.a
  File "SourceFile", line 109, in com.comsol.model.util.saveload.AbstractModelLoader.a
  File "SourceFile", line 218, in com.comsol.model.util.saveload.AbstractMphLoader.b
  File "SourceFile", line 248, in com.comsol.model.util.saveload.AbstractMphLoader.c
  File "SourceFile", line 337, in com.comsol.model.util.saveload.AbstractMphLoader.a
  File "SourceFile", line 588, in com.comsol.model.util.saveload.AbstractMphLoader.d
  File "SourceFile", line 3143, in com.comsol.model.dbmodel.ModelDb.postLoadInitialize
  File "SourceFile", line 3275, in com.comsol.model.method.ModelMethod.doPostLoadInitialize
  File "SourceFile", line 2395, in com.comsol.model.method.ModelMethod.fullVariableUpdate
  File "SourceFile", line 1657, in com.comsol.model.method.ModelMethod.a
  File "SourceFile", line 142, in com.comsol.model.util.MultiphysicsLicenseManager.checkOutRequiredLicenses
  File "SourceFile", line 280, in com.comsol.nativeutil.d.b.e
  File "SourceFile", line 286, in com.comsol.nativeutil.d.b.a
  File "SourceFile", line 33, in com.comsol.nativeutil.d.c.a
  File "SourceFile", line 182, in com.comsol.nativejni.util.FlLicense.hasFeature
  File "SourceFile", line -2, in com.comsol.nativejni.util.FlLicense.hasFeature
  File "Detail: No such feature exists.
Feature:       COMSOL
License path:  C:\Program Files\COMSOL\COMSOL56\Multiphysics\license\license.dat;
FlexNet Licensing error:-5,412", line 0, in license.cpp. Row: 439
com.comsol.nativejni.FlNativeException: Exception:
        com.comsol.nativejni.FlNativeException: License error -5 No such product exists
Messages:
        License error -5 No such product exists


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "SourceFile", line 168, in com.comsol.model.util.ModelUtil.load
  File "SourceFile", line 139, in com.comsol.model.util.ServerModelUtil.load
  File "AccessController.java", line -2, in java.security.AccessController.doPrivileged
  File "SourceFile", line 1, in com.comsol.model.util.ServerModelUtil$39.run
  File "SourceFile", line 142, in com.comsol.model.util.ServerModelUtil$39.a
  File "SourceFile", line 312, in com.comsol.model.util.ModelInternalUtil.load
  File "SourceFile", line 326, in com.comsol.model.util.ModelInternalUtil.load
  File "SourceFile", line 1189, in com.comsol.model.util.ModelManager.loadModel
  File "SourceFile", line 961, in com.comsol.model.util.ModelManager.a
  File "SourceFile", line 984, in com.comsol.model.util.ModelManager.a
  File "SourceFile", line 1238, in com.comsol.model.util.ModelManager.a
  File "SourceFile", line 107, in com.comsol.model.util.saveload.AbstractModelLoader.load
  File "SourceFile", line 185, in com.comsol.model.util.saveload.AbstractMphLoader.a
  File "SourceFile", line 508, in com.comsol.model.util.saveload.AbstractModelLoader.a
  File "SourceFile", line 109, in com.comsol.model.util.saveload.AbstractModelLoader.a
  File "SourceFile", line 218, in com.comsol.model.util.saveload.AbstractMphLoader.b
  File "SourceFile", line 248, in com.comsol.model.util.saveload.AbstractMphLoader.c
  File "SourceFile", line 337, in com.comsol.model.util.saveload.AbstractMphLoader.a
  File "SourceFile", line 588, in com.comsol.model.util.saveload.AbstractMphLoader.d
  File "SourceFile", line 3143, in com.comsol.model.dbmodel.ModelDb.postLoadInitialize
  File "SourceFile", line 3275, in com.comsol.model.method.ModelMethod.doPostLoadInitialize
  File "SourceFile", line 2395, in com.comsol.model.method.ModelMethod.fullVariableUpdate
  File "SourceFile", line 1657, in com.comsol.model.method.ModelMethod.a
  File "SourceFile", line 142, in com.comsol.model.util.MultiphysicsLicenseManager.checkOutRequiredLicenses
  File "SourceFile", line 280, in com.comsol.nativeutil.d.b.e
  File "SourceFile", line 286, in com.comsol.nativeutil.d.b.a
  File "SourceFile", line 37, in com.comsol.nativeutil.d.c.a
Exception: Java Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "c:/Users/frsc03/py_coms/Comsol.py", line 9, in <module>
    model = client.load('capacitor.mph')
  File "c:\Users\frsc03\py_coms\mainenv\lib\site-packages\mph\client.py", line 324, in load
    model = Model(self.java.load(tag, str(file)))
com.comsol.util.exceptions.LicenseException: Exception:
        com.comsol.nativejni.FlNativeException: License error -5 No such product exists
        (rethrown as com.comsol.util.exceptions.LicenseException)
Messages:
        Could not obtain license for#COMSOL Multiphysics

        License error -5 No such product exists

Quit method for Java VM unclear

Hi,

first of all thanks for the great work. Can you elaborate on why you use your exit code instead if shutdownJVM()?

Background: Running

logger.info('Shutting down the Java virtual machine.')
jpype.java.lang.Runtime.getRuntime().exit(0)
logger.info('Java virtual machine has shut down.')

wont log the second part since my interpreter closes down at ...exit() with the JVM. This leads to some problems with pyqt, I try to build an UI around the package...

I tested using jpype.shutdownJVM() and found the following: Connecting a client to a server and / or running a server will allow subsequent shutdown with the above (or for that matter, just exiting the interpreter). As soon as COMSOL was active, e.g. loading or simply creating a model, it will block shutdownJVM() running indefinitely.

No preference with name `tempfiles.recovery.checkforrecoveries`

Hi there!
First of all thanks for the great work you've done !
I was trying to setup a simulation using your package, but I was not able to start any client...
I'm using Manjaro Linux as operating system, and the MATLAB livelink interface seems to work fairly well.
Here's the error report:

Exception                                 Traceback (most recent call last)
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in java.lang.Thread.run()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in java.util.concurrent.ThreadPoolExecutor$Worker.run()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in java.util.concurrent.ThreadPoolExecutor.runWorker()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in java.util.concurrent.FutureTask.run()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in com.comsol.bridge.command.j$3.call()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in com.comsol.bridge.command.j$3.a()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in com.comsol.bridge.command.j.a()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in com.comsol.bridge.command.j.d()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in com.comsol.bridge.command.i.execute()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in com.comsol.bridge.command.c.run()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in com.comsol.bridge.command.b.a()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in java.lang.reflect.Method.invoke()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in sun.reflect.DelegatingMethodAccessorImpl.invoke()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in sun.reflect.NativeMethodAccessorImpl.invoke()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in sun.reflect.NativeMethodAccessorImpl.invoke0()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in com.comsol.model.util.ModelUtil.setPreference()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in com.comsol.model.util.ServerModelUtil.setPreference()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in java.security.AccessController.doPrivileged()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in com.comsol.model.util.ServerModelUtil$21.run()
/usr/lib/python3.9/site-packages/_jpype.cpython-39-x86_64-linux-gnu.so in com.comsol.nativeutil.preferences.Preferences.setPreference()

Exception: Java Exception

The above exception was the direct cause of the following exception:

com.comsol.util.exceptions.FlException    Traceback (most recent call last)
<ipython-input-3-9a0936dc3385> in <module>
----> 1 client = mph.start(cores=1)

/usr/lib/python3.9/site-packages/mph/session.py in start(cores, version, port)
    104     elif session == 'client-server':
    105         server = Server(cores=cores, version=version, port=port)
--> 106         client = Client(cores=cores, version=version, port=server.port)
    107     else:
    108         error = f'Invalid session type "{session}".'

/usr/lib/python3.9/site-packages/mph/client.py in __init__(self, cores, version, port, host)
    138         java.setPreference('tempfiles.saving.warnifoverwriteolder', 'off')
    139         java.setPreference('tempfiles.recovery.autosave', 'off')
--> 140         java.setPreference('tempfiles.recovery.checkforrecoveries', 'off')
    141         java.setPreference('tempfiles.saving.optimize', 'filesize')
    142 

com.comsol.util.exceptions.FlException: Exception:
        com.comsol.util.exceptions.FlException: No preference with the name X was found#tempfiles.recovery.checkforrecoveries
Messages:
        No preference with the name 'tempfiles.recovery.checkforrecoveries' was found.

I really have no idea of what this exception is; I've read the 'Limitations' section in the documentation but this error seems different to the one reported there...
Any idea of what's happening ? Am I doing something wrong ?
Thanks!

Add "Connection success" message

John, I suggest including some sort of success message after connection is finished. I struggled a little to find out whether it was connected or not. For instance, I get the message:

>>> import mph
>>> client=mph.start()
Did not find Comsol executable.

Although the connection to the server was successful. I figured it out by running the discovery.py functions separately.

Evaluation error when dataset has slash in name

Hello, I was trying to retrieve some data from my .mph project but got error which I have no idea how to handle.
Is there way to fix it from my side?

import mph
client = mph.start(cores=1)
model = client.load("my_path")
sols = model.solutions()
dats = model.datasets()
print(sols)
print(dats)
for dat in dats:
    print(dat)
    s = model.outer(dat)
    print(s)

OUTPUT:

Traceback (most recent call last):
  File "C:/Users/n/Desktop/d/comsoltest.py", line 10, in <module>
    s = model.outer(dat)
  File "C:\Users\n\AppData\Local\Programs\Python\Python38\lib\site-packages\mph\model.py", line 407, in outer
    if not dataset.exists():
  File "C:\Users\n\AppData\Local\Programs\Python\Python38\lib\site-packages\mph\node.py", line 278, in exists
    return (self.java is not None)
  File "C:\Users\n\AppData\Local\Programs\Python\Python38\lib\site-packages\mph\node.py", line 212, in java
    return eval(self.groups.get(name))
TypeError: eval() arg 1 must be a string, bytes or code object
['Solution 1', 'Parametric Solutions 1', 'wl=1.15E-6']
['Study 1//Solution 1', 'Study 1//Parametric Solutions 1']
Study 1//Solution 1

Process finished with exit code 1

OSError: [WinError 193] %1 is not a valid Win32 application

when I use mph, it happens.

Traceback (most recent call last):
File "F:/python project/test_mph/test_model.py", line 268, in
setup_module()
File "F:/python project/test_mph/test_model.py", line 27, in setup_module
client = mph.Client()
File "C:\Users\Eify.conda\envs\pytorch160\lib\site-packages\mph\client.py", line 85, in init
main = backend.folder(version)
File "C:\Users\Eify.conda\envs\pytorch160\lib\site-packages\mph\backend.py", line 214, in folder
last = list(versions().keys())[-1]
File "C:\Users\Eify.conda\envs\pytorch160\lib\site-packages\mph\backend.py", line 125, in versions
process = run(f'{path} --version', stdout=PIPE, creationflags=flags)
File "C:\Users\Eify.conda\envs\pytorch160\lib\subprocess.py", line 488, in run
with Popen(*popenargs, **kwargs) as process:
File "C:\Users\Eify.conda\envs\pytorch160\lib\subprocess.py", line 800, in init
restore_signals, start_new_session)
File "C:\Users\Eify.conda\envs\pytorch160\lib\subprocess.py", line 1207, in _execute_child
startupinfo)
OSError: [WinError 193] %1 is not a valid Win32 application

how can i do for this?

python 3.7

Create model features and edit properties

As suggested by @max3-2 in #16, and further discussed there, it would be convenient to have an easy way to add certain model features, such as global functions or selections etc., and edit their properties. Currently, this is only possible by using the (pythonized) Java methods directly.

Properties are the options displayed on the "Settings" tab in the Comsol GUI. They are accessible through the Java API via various getter and setter methods, depending on the data type they require or return.

The (tentative) proposal is to add three new methods to the Model class:

  • create(category, feature) would add a new feature with the given name to a category of feature collections, such as "function" or "selection".
  • property(category, feature, name, value=None) would change or return a named property of a feature in one of the categories. The value (passed in or returned) might be anything from a string to an array.
  • remove(category, feature) would remove a named feature.

This only covers actual properties, defined as such by Comsol's API. Feature methods that trigger an action are not included.

Running `create_capacitor.py` in Comsol 5.2a

Hi,

running the create_capacitor.py script in Comsol 5.2a led to following error related to 'com.comsol.model.impl.ModelParamImpl'.

Do you have an idea how to fix this?

Thanks,
Philipp

mph.start() returning the existing client instance.
Traceback (most recent call last):
  File "..\create_capacitor.py", line 14, in <module>
    (parameters/'Parameters 1').rename('parameters')
  File "C:\Users\p\Anaconda3\lib\site-packages\mph\node.py", line 261, in rename
    java = self.java
  File "C:\Users\p\Anaconda3\lib\site-packages\mph\node.py", line 181, in java
    java = parent.java
  File "C:\Users\p\Anaconda3\lib\site-packages\mph\node.py", line 179, in java
    return eval(self.groups.get(name))
  File "<string>", line 1, in <module>
AttributeError: 'com.comsol.model.impl.ModelParamImpl' object has no attribute 'group'

Overloaded Java method with boolean and integer arguments

I'm currrently using MPH to access the Java Layer of COMSOL directly in order to change the parameters of a model.

So far, in order to change my model I've been saving my COMSOL model as a .java file and copying lines of code, then adding '.java' after 'model' and running the code in python.

So for example:

model.param().set("box_width", "100 [mm]");

becomes

model.java.param().set("box_width", "100 [mm]");

This works great for changing Geometry Parameters, however, I've run into a seemingly minor issue when attempting to change certain Options in Comsol:

grafik

Lets say I check the box marked 'Selections' in the image above and then copy the java code into my python script, I get

model.component("comp1").mesh("mesh1").export().set("selection", true);

which I can change to

model.java.component("comp1").mesh("mesh1").export().set("selection", true);

but get an error when running the code in python:

Because the boolean operators for python are capitalized ('True' instead of 'true'), this leads to python reading 'true' as an unnamed variable and results in an error. Changing the boolean operator to python Syntax results in a COMSOL error however:

model.java.component("comp1").mesh("mesh1").export().set("selection", true);

Traceback (most recent call last):

  File "C:\Users\me\Desktop\Mph_Test_Param.py", line 53, in <module>
    model.java.component("comp1").mesh("mesh1").export().set("selection", True);

TypeError: Ambiguous overloads found for com.comsol.model.impl.PropFeatureImpl.set(str,bool) between:
	public com.comsol.model.PropFeature com.comsol.model.impl.PropFeatureImpl.set(java.lang.String,boolean)
	public com.comsol.model.PropFeature com.comsol.model.impl.PropFeatureImpl.set(java.lang.String,int)

I've found a fix for this using JPype with the argument jpype.java.lang.Boolean(True):

model.java.component("comp1").mesh("mesh1").export().set("selection", jpype.java.lang.Boolean(True);

Just wanted to include this here incase anyone runs into the same issue.

Locating Comsol 5.0 installation fails

I may have missed something in the installation. When I run the program its not able to find my client, which is installed at C:\Program Files\COMSOL\COMSOL50\Multiphysics\COMSOL Launchers

import mph
client = mph.Client(cores=1, version = '5.0')

Could not locate any Comsol installation.


RuntimeError Traceback (most recent call last)
in
----> 1 client = mph.Client(cores=1, version = '5.0')

C:\Anaconda\envs\COMSOL\lib\site-packages\mph\client.py in init(self, cores, version, port, host)
83
84 # Determine relevant folders of the Comsol back-end.
---> 85 main = backend.folder(version)
86 arch = backend.architecture()
87 jre = main / 'java' / arch / 'jre' / 'bin'

C:\Anaconda\envs\COMSOL\lib\site-packages\mph\backend.py in folder(version)
206 """
207 if version is not None:
--> 208 if version not in versions():
209 error = f'Version {version} is not installed.'
210 logger.error(error)

C:\Anaconda\envs\COMSOL\lib\site-packages\mph\backend.py in versions()
184 error = 'Could not locate any Comsol installation.'
185 logger.error(error)
--> 186 raise RuntimeError(error)
187
188 # Sort versions by name.

RuntimeError: Could not locate any Comsol installation.

Evaluation of other dataset types

As pointed out by @max3-2 in #22 and briefly discussed in #16, the evaluate() method of the Model class should support the evaluation of expressions on all dataset types, or at least the most common ones.

Currently supported are expressions in domains from datasets that directly map to a solution (using Comsol's Eval feature), global evaluations (using Global in the numerical() branch of the Java API), and expressions on particle data (using EvalPoint).

Currently not supported are cut points and cut planes, and probably more. The proposal is to add support for these in evaluate(). Ideally, mapping to the adequate Comsol feature should be completely transparent to the MPh user. Use-case examples for these other dataset types should be added to the demonstration model capacitor.mph so that the implementation can be covered by the test suite.

Server does not start when language set to Chinese

Thanks for sharing this practical package.
On line 133 of 'server.py', the code:
match = regex(r'(?i)^Comsol.+?server.+?(\d+)$', line.strip())
it may cause loop while setting Chinese as the as the programming language in comsol.

Unicode errors with German COMSOL

When starting the server process on Windows with a German COMSOL installation, this will error out, server.py L92 :

process = start(server + arguments, stdin=PIPE, stdout=PIPE)

        # Wait for it to report the port number.
        t0 = now()
        while process.poll() is None:
            peek = process.stdout.peek().decode()
            if peek.startswith('Username:'):
                error = 'User name and password for Comsol server not set.'
                logger.critical(error)
                logger.info('Start it manually from a system console first:')
                logger.info(' '.join(str(part) for part in server))
                raise RuntimeError(error)
            line = process.stdout.readline().decode()

...since COMSOL prints the word abhören to STDOUT.

An easy fix would be adding ´...decode(errors='ignore')- this would drop the Umlauts but they do not contain any vital information here. Otherwise, switching tolatin_1` also works but seems to be more complicated and prone to errors to me.

Export of animations

Hi,

Currently, exporting animations specifying the filename is not working, mainly because animation don't use "filename" as a property, but different ones depending on the file type used.

I made a little workaround for my case. I'm exporting not animations but image sequences so i can load them later, so i modified very naively the export function so it can treat my accordingly. Here is the code so it can work as an inspiration hahaha

def export(self, node=None, file=None, anim = False):

    if node is None:
        for node in self/'exports':
            logger.info(f'Running export node "{node.name()}".')
            node.run()
            logger.info('Finished running export.')
    else:
        if isinstance(node, str):
            if '/' in node:
                node = self/node
            else:
                node = self/'exports'/node
        if not node.exists():
            error = f'Node "{node}" does not exist in model tree.'
            logger.error(error)
            raise ValueError(error)
        if file and anim:
            node.property('imagefilename', str(file))
        else:
            node.property('filename', str(file))
        logger.info(f'Running export node "{node.name()}".')
        node.run()
        logger.info('Finished running export.')

other filenames used by animation are "giffilename", "avifilename", "flashfilename", so there must by a way to tell the function which to use.

Cheers!

OSError: [WinError 193] JVM DLL not found

Hi,

Im trying to get a Simulation via Python in Comsol running.
My issue is, that the command "mph.start()" produces the error message:
"OSError: [WinError 193] JVM DLL not found"

Strange things:

  1. the jvm.dll is in the correct folder
  2. "JVM DLL not found" correspondes to [WinError 126] as far as I know. (when i move jvm.dll to another folder the error message shows: "OSError: [WinError 126] JVM DLL not found" )
  3. for [WinError 193] I can only find the message "%1 is not a valid Win32 application" in other issues: OS and all programms are 64bit, so I don't know what the problem is.

Maybe anybody knows how to fix this?

Incompatability when using mix of 32-bit python and 64-bit OS

Can't read registry when using 32 bit python and 64 bit registry.

Line 72 in backend should be changed to:
main = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path_main, access=winreg.KEY_READ | winreg.KEY_WOW64_64KEY)

Line 99 should be changed to:
node = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path_node, 0, winreg.KEY_READ | winreg.KEY_WOW64_64KEY)

https://stackoverflow.com/questions/30932831/winreg-openkey-throws-filenotfound-error-for-existing-registry-keys

This stops the MPh scripts from working.

Feature improvements for the `Model` class

I think the model class can get some extended features. As @John-Hennig stated this should be kept as general as possible, especially since class inheritance allows easy extension. I will just start by listing some features I use often and add some small explanation and either +0- depending on my thoughts if they should be implemented.

  1. Inspection with tags: Currently inspection returns the names of objects. Since most of the advanced features are references by tags, I think those should return a list of tuples with ‘(name, tag)’ +
  2. Description of parameters: Adding / editing this field should be supported +
  3. Interpolation functions: This seems to be a common way to send data to COMSOL. Addding and editing those should be enabled +
  4. Toggling boundary conditions: This can be useful (on/off) but since then will be under a physics node may be hard to generalize 0
  5. Generating surfaces from selections: This can help automate exports. Is fairly easy to generalize but I do not know how often this is needed from the API. 0
  6. Adding exports: This is Handy but due to the need to specify the variables this can get very specific. Or we allow an API with ‘dict’ which easily creates exceptions I guess -
  7. Tracking loaded files: This should be very useful for working with many models to reduce slow IO especially when working with remote servers. I suggest initial tracking by file name and tag, maybe add via a class attribute ‘dict’ +

I can help implement some / most of the stuff. But I will sit for your input @John-Hennig before...

Geometry position Base option

I wished to put my query as chat instead of issue of this superb software while I could not do that. I apologize if my post is a bad post.

I wanted to transfer my transmon qubit geometry developed in python into comsol for modal EM simulation. While designing the aluminium layer (CPW) on the sapphire substrate, I found that I coudl not position the geometry with comsol position/base/center option. I could not find equivalent option in java.

Also I found that if I have another issue. If I have any issue in geometry or other parts, I need to restart from importing of modules. Is there any shortcut to delete model and restart from model definition subpart e.g. start from Model geometry?

I am using Ubuntu 20.04

Custom Comsol install locations on Linux

Discussed in #61

Originally posted by louisreg November 5, 2021
Hi,
First of all many thanks for MPh-py. This is a great tool and it is very useful for us.
We managed to get MPh-py running without any issue on our laptop. However, we tried to get it running on a dedicated linux server but we're having some issues because MPh-py does not find comsol-server. This is mainly because the installation directory is located in a weird location but we can't do anything about that. We managed to get it working by modifying your code and by writing the absolute path of comsol-server in your code. However this is not very convenient, especially if you release new versions of this code.
Is it possible to put the absolute path as an argument of a function instead of letting the code finding itself? If not, would it be possible to add this feature? that would be very useful for us!
Many thanks in advance
best
Louis

No preference with name `tempfiles.saving.warnifoverwriteolder`

Hi,

First of all, thanks for sharing the great project MPh! I am looking forward to using it.

Today I tried to set it up on my system (Win 10 Enterprise, 64-bit).
The installation via pip worked but I encountered some problems when using mph.start() as described in the tutorial.

Please find the log below - do you have an idea how to fix this issue?

This would be much appreciated, thank you.

Kind regards,

Philipp


In [2]: import mph

In [3]: client = mph.start(cores=1)
Traceback (most recent call last):
File "SourceFile", line 396, in com.comsol.model.util.ModelUtil.setPreference
File "SourceFile", line 619, in com.comsol.model.util.ServerModelUtil.setPreference
File "AccessController.java", line -2, in java.security.AccessController.doPrivileged 
File "SourceFile", line 622, in com.comsol.model.util.ServerModelUtil$19.run
File "SourceFile", line 2530, in com.comsol.nativeutil.preferences.Preferences.setPreference
Exception: Java Exception

The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<ipython-input-3-9a0936dc3385>", line 1, in <module>
client = mph.start(cores=1)
File "C:\Users\p\Anaconda3\lib\site-packages\mph\session.py", line 103, in start
client = Client(cores=cores, version=version)
File "C:\Users\p\Anaconda3\lib\site-packages\mph\client.py", line 141, in __init__
java.setPreference('tempfiles.saving.warnifoverwriteolder', 'off')
com.comsol.util.exceptions.FlException: Exception:
com.comsol.util.exceptions.FlException: No preference with the name X was found#tempfiles.saving.warnifoverwriteolder
Messages:
No preference with the name X was found#tempfiles.saving.warnifoverwriteolder

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

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()

Java `InterruptedException` at end of Python session

On Linux and macOS, we occasionally encounter this error:

WARN:oejuc.AbstractLifeCycle:FAILED ClientWebSocketCommandManager.factory{0<=0<=0/0,0}:
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.doStop(QueuedThreadPool.java:122)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:89)
    at org.eclipse.jetty.util.component.AggregateLifeCycle.doStop(AggregateLifeCycle.java:107)
    at org.eclipse.jetty.websocket.WebSocketClientFactory.doStop(WebSocketClientFactory.java:221)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.stop(AbstractLifeCycle.java:89)
    at com.comsol.client.interfaces.ClientWebSocketCommandManager$c.run(SourceFile:551)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

The error is harmless, in that it occurs at the very end of the Python session, but never during simulations or any other normal interaction with Comsol. It is not 100% reproducible, though it does occur about half the time the test suite is run on Linux. The error happens when the client disconnects from the server during the shutdown sequence of the Python/Java session. A regular disconnect, pre-shutdown, does not produce the error.

All of this points to some kind of race condition in JPype's shutdown sequence of the Java VM. JPype pull request #937 would fix this, as repeated tests have shown, but work on JPype is currently on hold and it is unclear when that fix will be released. Hence this notice here.

Licence error

Hi,

I have tried to follow the tutorial using the file 'heat_radiation_1d.mph' from the application library (instead of capacitor.
The Managing models commands like client.clear() and client.names() worked fine.

As the heat_radiation_1d model doesn't contain any parameters I created one using the GUI to test the Inspecting models commands. However, this lead to some licence error stated below. Could that somehow be connected to opening the model using the GUI? Just wondering as it was not raised before.

Thanks, Philipp

Traceback (most recent call last):
  File "Thread.java", line 745, in java.lang.Thread.run
  File "ThreadPoolExecutor.java", line 617, in java.util.concurrent.ThreadPoolExecutor$Worker.run
  File "ThreadPoolExecutor.java", line 1142, in java.util.concurrent.ThreadPoolExecutor.runWorker
  File "FutureTask.java", line 266, in java.util.concurrent.FutureTask.run
  File "SourceFile", line 169, in com.comsol.model.clientserver.ClientManager$1.call
  File "SourceFile", line 1, in com.comsol.model.internal.impl.FunctionFeatureListImpl$2.execute
  File "SourceFile", line 115, in com.comsol.model.internal.impl.FunctionFeatureListImpl$2.a
  File "SourceFile", line 129, in com.comsol.model.internal.impl.FunctionFeatureListImpl.a_
  File "SourceFile", line 166, in com.comsol.model.internal.impl.PropFeatureListImpl.a
  File "SourceFile", line 69, in com.comsol.model.method.PropFeatureListMethod.create
  File "SourceFile", line 1, in com.comsol.model.internal.impl.PropFeatureListImpl.internalAddFeature
  File "SourceFile", line 176, in com.comsol.model.internal.impl.PropFeatureListImpl.internalAddFeature
  File "SourceFile", line 1615, in com.comsol.model.internal.impl.ModelEntityImpl.initialize
  File "SourceFile", line 142, in com.comsol.model.internal.impl.PropFeatureImpl.doInitialize
  File "SourceFile", line 579, in com.comsol.model.internal.impl.FunctionFeatureImpl.bY_
  File "SourceFile", line 260, in com.comsol.model.method.FunctionFeatureMethod.postCreateInit
  File "SourceFile", line 1440, in com.comsol.applapi.variables.af.updateVariables
  File "SourceFile", line 111, in com.comsol.model.util.MultiphysicsLicenseManager.checkOutRequiredLicenses
  File "SourceFile", line 259, in com.comsol.nativeutil.e.b.g
  File "SourceFile", line 265, in com.comsol.nativeutil.e.b.a
  File "SourceFile", line 34, in com.comsol.nativeutil.e.c.a
  File "SourceFile", line 134, in com.comsol.nativejni.util.FlLicense.hasFeature
  File "SourceFile", line -2, in com.comsol.nativejni.util.FlLicense.hasFeature
  File "Detail: License file does not support this version.
Feature:       COMSOL
Application version > License version: 5.21 > 3.5
License path:  C:\Program Files\COMSOL\COMSOL52\Multiphysics\license\license.dat;
FlexNet Licensing error:-21,126
For further information, refer to the FlexNet Licensing documentation,
available at "www.flexerasoftware.com".", line 0, in license.cpp. Row: 323
com.comsol.nativejni.FlNativeException: Exception:
	com.comsol.nativejni.FlNativeException: License error
Messages:
	License error

The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "Thread.java", line 745, in java.lang.Thread.run
  File "ThreadPoolExecutor.java", line 617, in java.util.concurrent.ThreadPoolExecutor$Worker.run
  File "ThreadPoolExecutor.java", line 1142, in java.util.concurrent.ThreadPoolExecutor.runWorker
  File "FutureTask.java", line 266, in java.util.concurrent.FutureTask.run
  File "SourceFile", line 169, in com.comsol.model.clientserver.ClientManager$1.call
  File "SourceFile", line 1, in com.comsol.model.internal.impl.FunctionFeatureListImpl$2.execute
  File "SourceFile", line 115, in com.comsol.model.internal.impl.FunctionFeatureListImpl$2.a
  File "SourceFile", line 129, in com.comsol.model.internal.impl.FunctionFeatureListImpl.a_
  File "SourceFile", line 166, in com.comsol.model.internal.impl.PropFeatureListImpl.a
  File "SourceFile", line 69, in com.comsol.model.method.PropFeatureListMethod.create
  File "SourceFile", line 1, in com.comsol.model.internal.impl.PropFeatureListImpl.internalAddFeature
  File "SourceFile", line 176, in com.comsol.model.internal.impl.PropFeatureListImpl.internalAddFeature
  File "SourceFile", line 1615, in com.comsol.model.internal.impl.ModelEntityImpl.initialize
  File "SourceFile", line 142, in com.comsol.model.internal.impl.PropFeatureImpl.doInitialize
  File "SourceFile", line 579, in com.comsol.model.internal.impl.FunctionFeatureImpl.bY_
  File "SourceFile", line 260, in com.comsol.model.method.FunctionFeatureMethod.postCreateInit
  File "SourceFile", line 1440, in com.comsol.applapi.variables.af.updateVariables
  File "SourceFile", line 111, in com.comsol.model.util.MultiphysicsLicenseManager.checkOutRequiredLicenses
  File "SourceFile", line 259, in com.comsol.nativeutil.e.b.g
  File "SourceFile", line 265, in com.comsol.nativeutil.e.b.a
  File "SourceFile", line 38, in com.comsol.nativeutil.e.c.a
Exception: Java Exception

The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "<ipython-input-9-ddf9f4169796>", line 1, in <module>
    model = client.load('heat_radiation_1d.mph')
  File "C:\Users\p\Anaconda3\lib\site-packages\mph\client.py", line 212, in load
    model = Model(self.java.load(tag, str(file)))
com.comsol.util.exceptions.LicenseException: Exception:
	com.comsol.nativejni.FlNativeException: License error
	(rethrown as com.comsol.util.exceptions.LicenseException)
Messages:
	Could not obtain license for#COMSOL Multiphysics
	License error

Complex numbers in parameter assignments

There seems to be a problem with complex-valued parameters. If I call:

` model.parameter("x", 1+1j)

in version 1.0.0 with Comsol 5.6 I get the following error:

Traceback (most recent call last):
File "xyz", line 73, in
model.parameter("x", 1+1j)
File "C:\Python37\lib\site-packages\mph\model.py", line 583, in parameter
self.java.param().set(name, value)
TypeError: can't convert complex to float

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.