Skip to content

Commit

Permalink
Merge branch 'main' into release/0.8
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuelopez-ansys committed Feb 23, 2024
2 parents 8aae57f + bce31ff commit 69e41d8
Show file tree
Hide file tree
Showing 4 changed files with 347 additions and 334 deletions.
2 changes: 2 additions & 0 deletions pyaedt/application/Analysis3D.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ def post(self):
if self._post is None:
if is_ironpython: # pragma: no cover
from pyaedt.modules.PostProcessor import PostProcessor
elif self.design_type == "Icepak":
from pyaedt.modules.AdvancedPostProcessing import IcepakPostProcessor as PostProcessor
else:
from pyaedt.modules.AdvancedPostProcessing import PostProcessor
self._post = PostProcessor(self)
Expand Down
2 changes: 0 additions & 2 deletions pyaedt/icepak.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
from pyaedt.modules.Boundary import NativeComponentObject
from pyaedt.modules.Boundary import NetworkObject
from pyaedt.modules.Boundary import _create_boundary
from pyaedt.modules.PostProcessor import IcepakPostProcessor
from pyaedt.modules.monitor_icepak import Monitor


Expand Down Expand Up @@ -168,7 +167,6 @@ def __init__(
)
self._monitor = Monitor(self)
self._configurations = ConfigurationsIcepak(self)
self._post = IcepakPostProcessor(self)

def _init_from_design(self, *args, **kwargs):
self.__init__(*args, **kwargs)
Expand Down
345 changes: 345 additions & 0 deletions pyaedt/modules/AdvancedPostProcessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,20 @@

from __future__ import absolute_import # noreorder

import csv
import os
import re
import warnings

from pyaedt import generate_unique_name
from pyaedt import settings
from pyaedt.generic.general_methods import is_ironpython
from pyaedt.generic.general_methods import open_file
from pyaedt.generic.general_methods import pyaedt_function_handler
from pyaedt.generic.plot import ModelPlotter
from pyaedt.modules.PostProcessor import FieldSummary
from pyaedt.modules.PostProcessor import PostProcessor as Post
from pyaedt.modules.PostProcessor import TOTAL_QUANTITIES

if not is_ironpython:
try:
Expand Down Expand Up @@ -1005,3 +1011,342 @@ def plot_scene(
scene.convert_fields_in_db = convert_fields_in_db
scene.log_multiplier = log_multiplier
scene.animate()


class IcepakPostProcessor(PostProcessor, object):
def __init__(self, app):
PostProcessor.__init__(self, app)

@pyaedt_function_handler()
def create_field_summary(self):
return FieldSummary(self._app)

@pyaedt_function_handler()
def get_fans_operating_point(self, export_file=None, setup_name=None, timestep=None, design_variation=None):
"""
Get the operating point of the fans in the design.
Parameters
----------
export_file : str, optional
Name of the file to save the operating point of the fans to. The default is
``None``, in which case the filename is automatically generated.
setup_name : str, optional
Setup name to determine the operating point of the fans. The default is
``None``, in which case the first available setup is used.
timestep : str, optional
Time, with units, at which to determine the operating point of the fans. The default
is ``None``, in which case the first available timestep is used. This parameter is
only relevant in transient simulations.
design_variation : str, optional
Design variation to determine the operating point of the fans from. The default is
``None``, in which case the nominal variation is used.
Returns
-------
list
First element of the list is the CSV filename. The second and third elements
are the quantities with units describing the operating point of the fans.
The fourth element is a dictionary with the names of the fan instances
as keys and lists with volumetric flow rates and pressure rise floats associated
with the operating point as values.
References
----------
>>> oModule.ExportFanOperatingPoint
Examples
--------
>>> from pyaedt import Icepak
>>> ipk = Icepak()
>>> ipk.create_fan()
>>> filename, vol_flow_name, p_rise_name, op_dict= ipk.get_fans_operating_point()
"""

if export_file is None:
path = self._app.temp_directory
base_name = "{}_{}_FanOpPoint".format(self._app.project_name, self._app.design_name)
export_file = os.path.join(path, base_name + ".csv")
while os.path.exists(export_file):
file_name = generate_unique_name(base_name)
export_file = os.path.join(path, file_name + ".csv")
if setup_name is None:
setup_name = "{} : {}".format(self._app.get_setups()[0], self._app.solution_type)
if timestep is None:
timestep = ""
if self._app.solution_type == "Transient":
self._app.logger.warning("No timestep is specified. First timestep is exported.")
else:
if not self._app.solution_type == "Transient":
self._app.logger.warning("Simulation is steady-state. Timestep argument is ignored.")
timestep = ""
if design_variation is None:
design_variation = ""
self._app.osolution.ExportFanOperatingPoint(
[
"SolutionName:=",
setup_name,
"DesignVariationKey:=",
design_variation,
"ExportFilePath:=",
export_file,
"Overwrite:=",
True,
"TimeStep:=",
timestep,
]
)
with open(export_file, "r") as f:
reader = csv.reader(f)
for line in reader:
if "Fan Instances" in line:
vol_flow = line[1]
p_rise = line[2]
break
var = {line[0]: [float(line[1]), float(line[2])] for line in reader}
return [export_file, vol_flow, p_rise, var]

@pyaedt_function_handler
def _parse_field_summary_content(self, fs, setup_name, design_variation, quantity_name):
content = fs.get_field_summary_data(sweep_name=setup_name, design_variation=design_variation)
pattern = r"\[([^]]*)\]"
match = re.search(pattern, content["Quantity"][0])
if match:
content["Unit"] = [match.group(1)]
else: # pragma: no cover
content["Unit"] = [None]

if quantity_name in TOTAL_QUANTITIES:
return {i: content[i][0] for i in ["Total", "Unit"]}
return {i: content[i][0] for i in ["Min", "Max", "Mean", "Stdev", "Unit"]}

@pyaedt_function_handler()
def evaluate_faces_quantity(
self,
faces_list,
quantity_name,
side="Default",
setup_name=None,
design_variation=None,
ref_temperature="",
):
"""Export the field surface output.
Parameters
----------
faces_list : list
List of faces to apply.
quantity_name : str
Name of the quantity to export.
side : str, optional
Which side of the mesh face to use. The default is ``Default``.
Options are ``"Adjacent"``, ``"Combined"``, and ``"Default"``.
setup_name : str, optional
Name of the setup and name of the sweep. For example, ``"IcepakSetup1 : SteatyState"``.
The default is ``None``, in which case the active setup and active sweep are used.
design_variation : dict, optional
Dictionary of parameters defined for the specific setup with values. The default is ``{}``.
ref_temperature: str, optional
Reference temperature to use for heat transfer coefficient computation. The default is ``""``.
Returns
-------
dict
Output dictionary, which depending on the quantity chosen, contains one
of these sets of keys:
- ``"Min"``, ``"Max"``, ``"Mean"``, ``"Stdev"``, and ``"Unit"``
- ``"Total"`` and ``"Unit"``
References
----------
>>> oModule.ExportFieldsSummary
"""
if design_variation is None:
design_variation = {}
name = generate_unique_name(quantity_name)
self._app.modeler.create_face_list(faces_list, name)
fs = self.create_field_summary()
fs.add_calculation("Object", "Surface", name, quantity_name, side=side, ref_temperature=ref_temperature)
return self._parse_field_summary_content(fs, setup_name, design_variation, quantity_name)

@pyaedt_function_handler()
def evaluate_boundary_quantity(
self,
boundary_name,
quantity_name,
side="Default",
volume=False,
setup_name=None,
design_variation=None,
ref_temperature="",
):
"""Export the field output on a boundary.
Parameters
----------
boundary_name : str
Name of boundary to perform the computation on.
quantity_name : str
Name of the quantity to export.
side : str, optional
Side of the mesh face to use. The default is ``"Default"``.
Options are ``"Adjacent"``, ``"Combined"``, and ``"Default"``.
volume : bool, optional
Whether to compute the quantity on the volume or on the surface.
The default is ``False``, in which case the quantity will be evaluated
only on the surface .
setup_name : str, optional
Name of the setup and name of the sweep. For example, ``"IcepakSetup1 : SteatyState"``.
The default is ``None``, in which case the active setup and active sweep are used.
design_variation : dict, optional
Dictionary of parameters defined for the specific setup with values. The default is ``{}``.
ref_temperature: str, optional
Reference temperature to use for heat transfer coefficient computation. The default is ``""``.
Returns
-------
dict
Output dictionary, which depending on the quantity chosen, contains one
of these sets of keys:
- ``"Min"``, ``"Max"``, ``"Mean"``, ``"Stdev"``, and ``"Unit"``
- ``"Total"`` and ``"Unit"``
References
----------
>>> oModule.ExportFieldsSummary
"""
if design_variation is None:
design_variation = {}
fs = self.create_field_summary()
fs.add_calculation(
"Boundary",
["Surface", "Volume"][int(volume)],
boundary_name,
quantity_name,
side=side,
ref_temperature=ref_temperature,
)
return self._parse_field_summary_content(fs, setup_name, design_variation, quantity_name)

@pyaedt_function_handler()
def evaluate_monitor_quantity(
self,
monitor_name,
quantity_name,
side="Default",
setup_name=None,
design_variation=None,
ref_temperature="",
):
"""Export monitor field output.
Parameters
----------
monitor_name : str
Name of monitor to perform the computation on.
quantity_name : str
Name of the quantity to export.
side : str, optional
Side of the mesh face to use. The default is ``"Default"``.
Options are ``"Adjacent"``, ``"Combined"``, and ``"Default"``.
setup_name : str, optional
Name of the setup and name of the sweep. For example, ``"IcepakSetup1 : SteatyState"``.
The default is ``None``, in which case the active setup and active sweep are used.
design_variation : dict, optional
Dictionary of parameters defined for the specific setup with values. The default is ``{}``.
ref_temperature: str, optional
Reference temperature to use for heat transfer coefficient computation. The default is ``""``.
Returns
-------
dict
Output dictionary, which depending on the quantity chosen, contains one
of these sets of keys:
- ``"Min"``, ``"Max"``, ``"Mean"``, ``"Stdev"``, and ``"Unit"``
- ``"Total"`` and ``"Unit"``
References
----------
>>> oModule.ExportFieldsSummary
"""
if design_variation is None:
design_variation = {}
if settings.aedt_version < "2024.1":
raise NotImplementedError("Monitors are not supported in field summary in versions earlier than 2024 R1.")
else: # pragma: no cover
if self._app.monitor.face_monitors.get(monitor_name, None):
field_type = "Surface"
elif self._app.monitor.point_monitors.get(monitor_name, None):
field_type = "Volume"
else:
raise AttributeError("Monitor {} is not found in the design.".format(monitor_name))
fs = self.create_field_summary()
fs.add_calculation(
"Monitor", field_type, monitor_name, quantity_name, side=side, ref_temperature=ref_temperature
)
return self._parse_field_summary_content(fs, setup_name, design_variation, quantity_name)

@pyaedt_function_handler()
def evaluate_object_quantity(
self,
object_name,
quantity_name,
side="Default",
volume=False,
setup_name=None,
design_variation=None,
ref_temperature="",
):
"""Export the field output on or in an object.
Parameters
----------
object_name : str
Name of object to perform the computation on.
quantity_name : str
Name of the quantity to export.
side : str, optional
Side of the mesh face to use. The default is ``"Default"``.
Options are ``"Adjacent"``, ``"Combined"``, and ``"Default"``.
volume : bool, optional
Whether to compute the quantity on the volume or on the surface. The default is ``False``.
setup_name : str, optional
Name of the setup and name of the sweep. For example, ``"IcepakSetup1 : SteatyState"``.
The default is ``None``, in which case the active setup and active sweep are used.
design_variation : dict, optional
Dictionary of parameters defined for the specific setup with values. The default is ``{}``.
ref_temperature: str, optional
Reference temperature to use for heat transfer coefficient computation. The default is ``""``.
Returns
-------
dict
Output dictionary, which depending on the quantity chosen, contains one
of these sets of keys:
- ``"Min"``, ``"Max"``, ``"Mean"``, ``"Stdev"``, and ``"Unit"``
- ``"Total"`` and ``"Unit"``
References
----------
>>> oModule.ExportFieldsSummary
"""
if design_variation is None:
design_variation = {}
fs = self.create_field_summary()
fs.add_calculation(
"Boundary",
["Surface", "Volume"][int(volume)],
object_name,
quantity_name,
side=side,
ref_temperature=ref_temperature,
)
return self._parse_field_summary_content(fs, setup_name, design_variation, quantity_name)
Loading

0 comments on commit 69e41d8

Please sign in to comment.