MPh-py / MPh

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

`UnsatisfiedLinkError` on Linux: `libimf.so` missing #100

Closed qigesmn closed 1 year ago

qigesmn commented 1 year ago

Hi, dear john. I'm trying to deploy a task of Equivalent circuit model(ECM). Your magical package worked pretty well when I developed and tested the task in Windows, but raised Exception while migrating to the Linux server. The code is below:

  import pandas as pd
  import mph
  import os
  import sys
  import argparse

  class LoadFromFile(argparse.Action):
      def __call__(self, parser, namespace, values, option_string=None):
            with values as f:
                parser.parse_args(f.read().split(), namespace)

  def main_func(
          norminal_capacity: float = 31,  # str
          input_soctemp_path: str = '',
          input_ocv_path: str = '',
          input_resitance_path: str = '',
  ):
      client = mph.start(cores=2)
      para_input = pd.read_excel(input_soctemp_path)  # file 1
      soc_init = np.asarray(para_input['soc'])
      soc_init = soc_init[~np.isnan(soc_init)]
      temp_init_fah = np.asarray(para_input['temp'])
      temp_init = temp_init_fah + 273.15
      temp_init = temp_init[~np.isnan(temp_init)]
      output_final = np.zeros([len(temp_init), len(soc_init)])
      save_path = os.path.dirname(os.path.abspath(__file__))  # abs folder_dir

    for i in range(len(soc_init)):
        for j in range(len(temp_init)):
            model = client.load(os.path.join(save_path,'ecm_continuous_charge.mph'))  
            #
            node_OCV = model / "functions" / "插值 1"  # equal to model / "functions" /"Interpolation 1"
            node_OCV.java.set('filename', input_ocv_path)  # file 2
            node_R0 = model / "functions" / "插值 2"  # equal to model / "functions" /"Interpolation 2"
            node_R0.java.set('filename', input_resitance_path)  # file 3
            node_R1 = model / "functions" / "插值 3"  # equal to model / "functions" /"Interpolation 3"
            node_R1.java.set('filename', input_resitance_path)
            node_R2 = model / "functions" / "插值 4"   # equal to model / "functions" /"Interpolation 4"
            node_R2.java.set('filename', input_resitance_path)
            node_C1 = model / "functions" / "插值 5"  # equal to model / "functions" /"Interpolation 5"
            node_C1.java.set('filename', input_resitance_path)
            node_C2 = model / "functions" / "插值 6"  # # equal to model / "functions" /"Interpolation 5"
            node_C2.java.set('filename', input_resitance_path)
            model.parameter("SOC_init", str(soc_init[i]))
            model.parameter("T_init", str(temp_init[j]) + "[K]")
            model.parameter('Q0', str(norminal_capacity) + '[Ah]')
            node_table = model / "exports" / "table 1"
            node_table.java.set("filename", os.path.join(save_path,'output.csv'))
            try:
                model.solve()
                model.export()
                result_export = pd.read_csv(os.path.join(save_path,'output.csv'))
                output_final[j, i] = result_export.iloc[-1, 0]
            except:
                output_final[j, i] = -100
            client.clear()

    # part 3:result export
    df = pd.DataFrame(output_final)
    columns_name = []
    for i in range(len(soc_init)):
        columns_name.append(str(soc_init[i]))
    df.columns = columns_name
    index_name = []
    for i in range(len(temp_init)):
        index_name.append(str(temp_init[i]))
    df.index = index_name
    df.to_csv(os.path.join(save_path, "continuous_charge.csv")) 
    return

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='test_221028')  # define
    parser.add_argument('--norminal_capacity', type=float, default=30, help='')  # add command para
    parser.add_argument('--input_soctemp_path', type=str, default='', help='')
    parser.add_argument('--input_ocv_path', type=str, default='', help='')
    parser.add_argument('--input_resistance_path', type=str, default='', help='')
    args = parser.parse_args()
    norminal_capacity = args.norminal_capacity  # print(norminal_capacity)
    input_soctemp_path = args.input_soctemp_path  # print(input_soctemp_path)
    input_ocv_path = args.input_ocv_path  # print(input_ocv_path)
    input_resistance_path = args.input_resistance_path  # print(input_resistance_path)
    main_func(norminal_capacity, input_soctemp_path, input_ocv_path, input_resistance_path)

The Exception logging is below:

Exception in thread "pool-1-thread-1" java.lang.UnsatisfiedLinkError: /usr/local/comsol60/multiphysics/lib/glnxa64/libcsutil.so: libimf.so: 无法打开共享对象文件: 没有那个文件或目录
    at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
    at java.base/java.lang.ClassLoader$NativeLibrary.load(Unknown Source)
    at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(Unknown Source)
    at java.base/java.lang.ClassLoader.loadLibrary0(Unknown Source)
    at java.base/java.lang.ClassLoader.loadLibrary(Unknown Source)
    at java.base/java.lang.Runtime.load0(Unknown Source)
    at java.base/java.lang.System.load(Unknown Source)
    at com.comsol.nativejni.FlNativeUtil.a(SourceFile:164)
    at com.comsol.nativejni.FlNativeUtil.loadLibrary(SourceFile:142)
    at com.comsol.nativejni.util.ExcelUtil.a(SourceFile:31)
    at com.comsol.nativejni.util.ExcelUtil.queryFeatureVersion(SourceFile:232)
    at com.comsol.nativebasicutil.a.a.e(SourceFile:319)
    at com.comsol.nativebasicutil.a.a.a(SourceFile:35)
    at com.comsol.client.communicationutil.ClientFileManager.b(SourceFile:706)
    at com.comsol.client.communicationutil.ClientFileManager.a(SourceFile:182)
    at com.comsol.client.interfaces.z.a(SourceFile:93)
    at com.comsol.client.interfaces.z.a(SourceFile:90)
    at com.comsol.client.interfaces.z$1.run(SourceFile:83)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.base/java.lang.Thread.run(Unknown Source)

I'm fresh in java. Is there a problem with my mph file, or is the mph package temporarily unable to modify the attr 'filename' on the Linux.

john-hen commented 1 year ago

Hi,

I don't think there's anything wrong with your model. And that error occurs in Java, i.e. in Comsol. So this is not a problem with MPh per se. If anything, it would be in the way Comsol is started by MPh, but I've never seen that error before, on Ubuntu, and cannot reproduce it, so I have no way of debugging this.

It's not clear to me from the error message which line actually triggers it. You seem to think it's node_table.java.set("filename", ...). I see nothing wrong with it, that just sets a string attribute.

What the error message does mention is that it cannot find the libimf.so library. That's the Intel Math Library, which Comsol (unsurprisingly) seems to depend on. I would expect the Comsol installer to check that that library is actually available. And it should be. Maybe you can find a way to check independently, or install it with your Linux package manager. But again, I have never seen this be an issue on Linux before, so I'm just guessing.

qigesmn commented 1 year ago

Hi, Thanks for your reply. I will check the libimf.so and so on. Ummmmm, it may take a little time for me. Thanks again for this wonderful pkg.