Menu

Defining Pipe Diameters using Python for Automation Process.

2023-09-19
2024-01-07
  • Danny Churchlover

    Hello there,

    I am trying to use a python script to connect 100 pipe segments together, with material steams connected between each other, as well as energy streams coming out of each pipe.

    I am trying to set the inner and outer diameter for all the pipes: 33mm for the outer and 27mm for the inner.

    I found possible functions here:
    https://dwsim.org/api_help/html/T_DWSIM_UnitOperations_UnitOperations_StandardPipeDiameter.htm

    and specifically:
    https://dwsim.org/api_help/html/P_DWSIM_UnitOperations_UnitOperations_StandardPipeDiameter_ExternalDiameter_Inches.htm

    https://dwsim.org/api_help/html/P_DWSIM_UnitOperations_UnitOperations_StandardPipeDiameter_InternalDiameter_Inches.htm

    I see that "StandardPipeDiameter" is a class with properties "ExternamDiameter_Inches" and "ExternamDiameter_Inches" takes the double data type.

    So I try to set the diameter using this single line code:

    UnitOperations.StandardPipeDiameter.ExternalDiameter_Inches(2)
    

    But I get this error in my terminal:

    UnitOperations.StandardPipeDiameter.ExternalDiameter_Inches(2)
    TypeError: 'PropertyObject' object is not callable

    As far as I know in my code, the UnitOperations class-object has been imported by the following code:

    from DWSIM.UnitOperations import UnitOperations
    

    I am a relative newbie when it comes to python scripting, so apologies in advance if this code appears to be amateurish.

    The full code is here. It works when you comment out
    UnitOperations.StandardPipeDiameter.ExternalDiameter_Inches(2)

    Wondering if there is anybody that could assist me?

    KR

    import pythoncom
    pythoncom.CoInitialize()
    
    import clr
    
    from System.IO import Directory, Path, File
    from System import String, Environment
    
    dwsimpath = "C:\\Users\\dc\\AppData\\Local\\DWSIM\\"
    
    clr.AddReference(dwsimpath + "CapeOpen.dll")
    clr.AddReference(dwsimpath + "DWSIM.Automation.dll")
    clr.AddReference(dwsimpath + "DWSIM.Interfaces.dll")
    clr.AddReference(dwsimpath + "DWSIM.GlobalSettings.dll")
    clr.AddReference(dwsimpath + "DWSIM.SharedClasses.dll")
    clr.AddReference(dwsimpath + "DWSIM.Thermodynamics.dll")
    clr.AddReference(dwsimpath + "DWSIM.UnitOperations.dll")
    clr.AddReference(dwsimpath + "DWSIM.Inspector.dll")
    clr.AddReference(dwsimpath + "System.Buffers.dll")
    
    from DWSIM.Interfaces.Enums.GraphicObjects import ObjectType
    from DWSIM.Thermodynamics import Streams, PropertyPackages
    from DWSIM.UnitOperations import UnitOperations
    from DWSIM.Automation import Automation3
    from DWSIM.GlobalSettings import Settings
    
    Directory.SetCurrentDirectory(dwsimpath)
    
    # create automation manager
    
    interf = Automation3()
    
    sim = interf.CreateFlowsheet()
    
    # add water
    
    water = sim.AvailableCompounds["Water"]
    
    sim.SelectedCompounds.Add(water.Name, water)
    
    # create and connect objects
    
    
    #############################
    ########SETGLOBALS START###########
    #############################
    
    number_of_pipes=50
    
    #############################
    ########SETGLOBAL END###########
    #############################
    
    # This will create all the material streams 
    materialinstanceName =['m'+str(i+1) for i in range (number_of_pipes+1)] # One extra stream for the last pipe
    # This will create all the pipe segments
    pipeinstanceName =['p'+str(i+1) for i in range (number_of_pipes)]
    # This will create all the energy streams
    energyinstanceName =['e'+str(i+1) for i in range (number_of_pipes)]
    
    
    #Empty lists for objects
    objme = []
    objmb = []
    
    objpa =[]
    objpb =[]
    
    objea =[]
    objeb =[]
    
    
    #CREATE MATERIAL STREAMS
    
    for i in materialinstanceName:
        objme.append(sim.AddObject(ObjectType.MaterialStream, 100, 100, i))
    
    for i in range(len(materialinstanceName)):
        objmb.append(objme[i].GetAsObject())
    
    #CREATE PIPE OBJECTS
    
    for i in pipeinstanceName:
        objpa.append(sim.AddObject(ObjectType.Pipe, 100, 100, i))
    
    for i in range(len(pipeinstanceName)):
        objpb.append(objpa[i].GetAsObject())
    
    #CREATE ENERGY STREAMS
    
    for i in energyinstanceName:
        objea.append(sim.AddObject(ObjectType.EnergyStream, 100, 100, i))
    
    for i in range(len(energyinstanceName)):
        objeb.append(objea[i].GetAsObject())
    
    #CONNECT MATERIAL STREAM MX with PIPEX and PIPEX WITH STREAM(X+1) (X =1, 2, 3, 4....)
    for i in range(number_of_pipes):
        sim.ConnectObjects(objmb[i].GraphicObject, objpb[i].GraphicObject, -1, -1)
        sim.ConnectObjects(objpb[i].GraphicObject, objmb[i+1].GraphicObject, -1, -1)
    
    #CONNECT ENERGY STREAM EX with PIPEX (X =1, 2, 3, 4....)
    
    for i in range(number_of_pipes):
        sim.ConnectObjects(objpb[i].GraphicObject, objeb[i].GraphicObject, -1, -1)
    
    
    # # steam tables property package
    
    steam_tables = PropertyPackages.SteamTablesPropertyPackage()
    sim.AddPropertyPackage(steam_tables)
    
    # # set inlet stream temperature
    # # default properties: T = 300 K, P = 6000000 Pa, Mass Flow = 100 kg/s
    
    objmb[0].SetTemperature(300.0) # K
    objmb[0].SetMassFlow(100.0) # kg/s
    objmb[0].SetPressure(6000000) # Pa
    
    
    #Set Diameter 
    UnitOperations.StandardPipeDiameter.ExternalDiameter_Inches(2)
    
    # # request a calculation
    
    Settings.SolverMode = 0
    
    errors = interf.CalculateFlowsheet2(sim)
    
    #  save file
    
    fileNameToSave = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "heatersample.dwxmz")
    
    interf.SaveFlowsheet(sim, fileNameToSave, True)
    
    # # save the pfd to an image and display it
    
    clr.AddReference(dwsimpath + "SkiaSharp.dll")
    clr.AddReference("System.Drawing")
    
    from SkiaSharp import SKBitmap, SKImage, SKCanvas, SKEncodedImageFormat
    from System.IO import MemoryStream
    from System.Drawing import Image
    from System.Drawing.Imaging import ImageFormat
    
    PFDSurface = sim.GetSurface()
    
    bmp = SKBitmap(7168, 4320)
    canvas = SKCanvas(bmp)
    canvas.Scale(1.0)
    PFDSurface.UpdateCanvas(canvas)
    d = SKImage.FromBitmap(bmp).Encode(SKEncodedImageFormat.Png, 100)
    str = MemoryStream()
    d.SaveTo(str)
    image = Image.FromStream(str)
    imgPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "pfd.png")
    image.Save(imgPath, ImageFormat.Png)
    str.Dispose()
    canvas.Dispose()
    bmp.Dispose()
    
    from PIL import Image
    
    im = Image.open(imgPath)
    im.show()
    
     
  • Daniel Medeiros

    Daniel Medeiros - 2023-09-22

    Assuming that "pipe" is your pipe object, this is the code to add a straight tube section to it:

    ps = Auxiliary.Pipe.PipeSection()
    
    ps.Indice = 1
    ps.Incrementos = 10
    ps.Quantidade = 1
    ps.DE = 33.0 / 25.4 # in
    ps.DI = 27.0 / 25.4 # in
    ps.TipoSegmento = "Straight Tube Section"
    ps.Material = "Carbon Steel"
    
    pipe.Profile.Sections.Add(ps)
    

    Sorry about the portuguese names, this part of DWSIM code is really old (+ 15 years) and I didn't know what I wanted at that time... haha

    Regards,
    Daniel

     
  • Danny Churchlover

    Hello Daniel,

    Thanks for providing the world such a powerful modeller in DWSIM :)

    I made a simpler case, with just one pipe segment to make sure that I can define pipe segment values with just one segment, before I define them for multiple segments.

    The code is here:

    import pythoncom
    pythoncom.CoInitialize()
    
    import clr
    
    from System.IO import Directory, Path, File
    from System import String, Environment
    
    dwsimpath = "C:\\Users\\dp\\AppData\\Local\\DWSIM\\"
    
    clr.AddReference(dwsimpath + "CapeOpen.dll")
    clr.AddReference(dwsimpath + "DWSIM.Automation.dll")
    clr.AddReference(dwsimpath + "DWSIM.Interfaces.dll")
    clr.AddReference(dwsimpath + "DWSIM.GlobalSettings.dll")
    clr.AddReference(dwsimpath + "DWSIM.SharedClasses.dll")
    clr.AddReference(dwsimpath + "DWSIM.Thermodynamics.dll")
    clr.AddReference(dwsimpath + "DWSIM.UnitOperations.dll")
    clr.AddReference(dwsimpath + "DWSIM.Inspector.dll")
    clr.AddReference(dwsimpath + "System.Buffers.dll")
    
    from DWSIM.Interfaces.Enums.GraphicObjects import ObjectType
    from DWSIM.Thermodynamics import Streams, PropertyPackages
    from DWSIM.UnitOperations import UnitOperations
    from DWSIM.Automation import Automation3
    from DWSIM.GlobalSettings import Settings
    
    Directory.SetCurrentDirectory(dwsimpath)
    
    # create automation manager
    
    interf = Automation3()
    
    sim = interf.CreateFlowsheet()
    
    # add water
    
    water = sim.AvailableCompounds["Water"]
    
    sim.SelectedCompounds.Add(water.Name, water)
    
    
    # create and connect objects
    m1 = sim.AddObject(ObjectType.MaterialStream, 50, 50, "inlet")
    m2 = sim.AddObject(ObjectType.MaterialStream, 150, 50, "outlet")
    e1 = sim.AddObject(ObjectType.EnergyStream, 100, 50, "power")
    pipe = sim.AddObject(ObjectType.Pipe, 200, 200, "pipe")
    
    
    
    sim.ConnectObjects(m1.GraphicObject, pipe.GraphicObject, -1, -1)
    sim.ConnectObjects(pipe.GraphicObject, m2.GraphicObject, -1, -1)
    sim.ConnectObjects(pipe.GraphicObject, e1.GraphicObject, -1, -1)
    
    sim.AutoLayout()
    
    
    ##### PUTTING PIPE SEGMENT PARAMETERS ##### 
    
    
    ps = UnitOperations.Auxiliary.Pipe.PipeSection()
    
    ps.Indice = 1
    ps.Incrementos = 10
    ps.Quantidade = 1
    ps.DE = 33.0 / 25.4 # in
    ps.DI = 27.0 / 25.4 # in
    ps.TipoSegmento = "Straight Tube Section"
    ps.Material = "Carbon Steel"
    
    pipe.PipeProfile.Sections.Add(ps)
    
    
    # # steam tables property package
    
    steam_tables = PropertyPackages.SteamTablesPropertyPackage()
    sim.AddPropertyPackage(steam_tables)
    
    
    # # request a calculation
    
    Settings.SolverMode = 0
    
    errors = interf.CalculateFlowsheet2(sim)
    
    #  save file
    
    fileNameToSave = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "pipe segment.dwxmz")
    
    interf.SaveFlowsheet(sim, fileNameToSave, True)
    
    # # save the pfd to an image and display it
    
    clr.AddReference(dwsimpath + "SkiaSharp.dll")
    clr.AddReference("System.Drawing")
    
    from SkiaSharp import SKBitmap, SKImage, SKCanvas, SKEncodedImageFormat
    from System.IO import MemoryStream
    from System.Drawing import Image
    from System.Drawing.Imaging import ImageFormat
    
    PFDSurface = sim.GetSurface()
    
    bmp = SKBitmap(7168, 4320)
    canvas = SKCanvas(bmp)
    canvas.Scale(1.0)
    PFDSurface.UpdateCanvas(canvas)
    d = SKImage.FromBitmap(bmp).Encode(SKEncodedImageFormat.Png, 100)
    str = MemoryStream()
    d.SaveTo(str)
    image = Image.FromStream(str)
    imgPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "pfd.png")
    image.Save(imgPath, ImageFormat.Png)
    str.Dispose()
    canvas.Dispose()
    bmp.Dispose()
    
    from PIL import Image
    
    im = Image.open(imgPath)
    im.show()
    

    I have added your code under ##### PUTTING PIPE SEGMENT PARAMETERS #####

    I have changed the "ps = Auxiliary.Pipe.PipeSection()" line of code that you have suggested, to" ps = UnitOperations.Auxiliary.Pipe.PipeSection()" because I was getting a "name 'Auxiliary' is not defined" error.

    However I get this error now: "AttributeError: 'ISimulationObject' object has no attribute 'Profile'"

    So it is saying to me that the pipe object, that was defined as pipe=sim.AddObject(ObjectType.Pipe, 200, 200, "pipe"), does not have the method/attribute "Profile"

    I tried to find "Profile" in the documentation, but I see PipeProfile() instead...

    Am I looking it in the wrong way?

    KR

     
  • Daniel Medeiros

    Daniel Medeiros - 2023-09-25

    Hi KR,

    Try this after creating the pipe object:

    pipe = pipe.GetAsObject()
    
     
  • Danny Churchlover

    Hello Daniel,

    I have added the "pipe = pipe.GetAsObject()" line of code after creating it using the sim.AddObject method.

    The "Attribute Error" message has now disappeared. But I get a type error now for the "pipe.Profile.Sections.Add(ps)" line of code:

    TypeError: No method matches given arguments for SortedDictionary`2.Add: (<class 'dwsim.unitoperations.unitoperations.auxiliary.pipe.pipesection'="">)</class>

    I copied your part exactly, according to this photo:
    https://imgur.com/61oiEih
    The only change is the addition of the "UnitOperations" object before "Auxiliary.Pipe.PipeSection()"

     

    Last edit: Danny Churchlover 2023-09-26
  • Serhii Krushnevych

    Hello,
    I tried to set pipeline lengths with the example shown above, but have the error AttributeError: 'Pipe' object has no attribute 'PipeProfile' on the line:
    pipe.PipeProfile.Sections.Add(ps)
    I tryed to add pipe = pipe.GetAsObject() but the same error

    Full code:

    import clr
    
    from System.IO import Directory, Path, File
    from System import String, Environment
    
    dwsimpath = "C:\\Users\\Serhii\\AppData\\Local\\DWSIM\\"
    Directory.SetCurrentDirectory(dwsimpath)
    
    clr.AddReference("DWSIM.UnitOperations")
    
    from DWSIM.UnitOperations import UnitOperations
    
    
    pipe = Flowsheet.GetFlowsheetSimulationObject('PIPE-1')
    
    ps = UnitOperations.Auxiliary.Pipe.PipeSection()
    
    ps.Indice = 1
    ps.Incrementos = 10
    ps.Quantidade = 1
    ps.DE = 33.0 / 25.4 # in
    ps.DI = 27.0 / 25.4 # in
    ps.TipoSegmento = "Straight Tube Section"
    ps.Material = "Carbon Steel"
    
    pipe = pipe.GetAsObject()
    pipe.PipeProfile.Sections.Add(ps) #here the error: "AttributeError: 'Pipe' object has no attribute 'PipeProfile'"
    

    Full error:

    [07.01.2024 17:48:33] Error running script '': Traceback (most recent call last):
      File "<string>", line 42, in <module>
    AttributeError: 'Pipe' object has no attribute 'PipeProfile'
    
     
    • Serhii Krushnevych

      This is work for me:

      pipe.Profile.Sections.Clear()
      pipe.Profile.Sections.Add(1,ps) 
      

      pipe.Profile.Sections.Add(1,ps) instead of pipe.PipeProfile.Sections.Add(ps)

       

      Last edit: Serhii Krushnevych 2024-01-07
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.