Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add blower bc function #3872

Merged
merged 23 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9ae3cfb
Add recirculation boundary create and edit
lorenzovecchietti Nov 10, 2023
974cb65
add assign_recirculation_opening
lorenzovecchietti Nov 10, 2023
4f64a03
add recirculation test
lorenzovecchietti Nov 11, 2023
7c13063
update name in example
lorenzovecchietti Nov 11, 2023
0c315b8
add dictionary support
lorenzovecchietti Nov 11, 2023
c563012
improve input arguments handling
lorenzovecchietti Nov 11, 2023
193fe93
add dictionary test
lorenzovecchietti Nov 11, 2023
fc01017
add "blower" in create and update functions
lorenzovecchietti Nov 11, 2023
5e44875
add functions to create blower
lorenzovecchietti Nov 11, 2023
e4c78ac
add blower tests
lorenzovecchietti Nov 11, 2023
5b0e564
Merge branch 'main' into Enhancement/blower_bc
lorenzovecchietti Nov 13, 2023
e217a21
Merge branch 'main' into Enhancement/blower_bc
lorenzovecchietti Nov 13, 2023
d1257d7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Nov 13, 2023
501e528
add pragma nocover
lorenzovecchietti Nov 13, 2023
2ec5417
Merge remote-tracking branch 'origin/Enhancement/blower_bc' into Enha…
lorenzovecchietti Nov 13, 2023
1df3f58
update docstring
lorenzovecchietti Nov 14, 2023
dbec2bb
Merge branch 'main' into Enhancement/blower_bc
lorenzovecchietti Nov 14, 2023
f83a6f2
fix indentation
lorenzovecchietti Nov 14, 2023
2fcf737
add no cover to GrpcApiError
lorenzovecchietti Nov 14, 2023
43e82ef
Merge remote-tracking branch 'origin/Enhancement/blower_bc' into Enha…
lorenzovecchietti Nov 14, 2023
de2e152
Update pyaedt/icepak.py
Samuelopez-ansys Nov 14, 2023
df2022f
Update pyaedt/icepak.py
Samuelopez-ansys Nov 14, 2023
5dbbd34
Merge branch 'main' into Enhancement/blower_bc
Samuelopez-ansys Nov 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions _unittest/test_98_Icepak.py
Original file line number Diff line number Diff line change
Expand Up @@ -1337,3 +1337,16 @@ def test_69_recirculation_boundary(self):
thermal_specification="Temperature",
flow_assignment=flow_dict,
)

def test_70_blower_boundary(self):
cylinder = self.aedtapp.modeler.create_cylinder(cs_axis="X", position=[0, 0, 0], radius=10, height=1)
curved_face = [f for f in cylinder.faces if not f.is_planar]
planar_faces = [f for f in cylinder.faces if f.is_planar]
assert not self.aedtapp.assign_blower_type1(curved_face + planar_faces, planar_faces, [10, 5, 0], [0, 1, 2, 4])
blower = self.aedtapp.assign_blower_type1(
[f.id for f in curved_face + planar_faces], [f.id for f in planar_faces], [10, 5, 0], [0, 2, 4]
)
assert blower
assert blower.update()
box = self.aedtapp.modeler.create_box([5, 5, 5], [1, 2, 3], "BlockBoxEmpty", "copper")
assert self.aedtapp.assign_blower_type2([box.faces[0], box.faces[1]], [box.faces[0]], [10, 5, 0], [0, 2, 4])
212 changes: 186 additions & 26 deletions pyaedt/icepak.py
Original file line number Diff line number Diff line change
Expand Up @@ -4880,44 +4880,45 @@ def assign_recirculation_opening(self, face_list, extract_face, thermal_specific
Parameters
----------
face_list : list
List of modeler.cad.elements3d.FacePrimitive or of integers
containing faces ids.
List of face primitive objects or a list of integers
containing faces IDs.
extract_face : modeler.cad.elements3d.FacePrimitive, int
Face of the face on the extract side.
ID of the face on the extract side.
thermal_specification : str, optional
Type of the thermal assignment across the two recirculation
faces. Options are ``"Conductance"``, ``"Heat Input"`` and
``"Temperature"``. Default is ``"Temperature"``.
faces. The default is ``"Temperature"``. Options are
``"Conductance"``, ``"Heat Input"``, and ``"Temperature"``.
assignment_value : str or dict, optional
String with value and units of the thermal assignment. For a
transient assignment, a dictionary can be used. The dictionary
should contain two keys: ``"Function"`` and ``"Values"``.
- For the ``"Function"`` key, acceptable values are
- For the ``"Function"`` key, options are
``"Exponential"``, ``"Linear"``, ``"Piecewise Linear"``,
``"Power Law"``, ``"Sinusoidal"``, and ``"Square Wave"``.
- For the ``"Values"`` key, a list of strings containing the
- For the ``"Values"`` key, provide a list of strings containing the
parameters required by the ``"Function"`` key selection. For
example, when``"Linear"`` is set as the ``"Function"`` key, two
example, when ``"Linear"`` is set as the ``"Function"`` key, two
parameters are required: the value of the variable at t=0 and the
slope of the line. For the parameters required by each
``"Function"`` key selection, see the Icepak documentation.
slope of the line. For the parameters required by each ``"Function"``
key selection, see the Icepak documentation.
The parameters must contain the units where needed.
The default value is ``"0cel"``.
conductance_external_temperature : str, optional
External temperature value, needed if ``thermal_specification``
is set to ``"Conductance"``. Default is ``None``.
External temperature value, which is needed if
``thermal_specification`` is set to ``"Conductance"``.
The default is ``None``.
flow_specification : str, optional
Flow specification for the recirculation zone. Available
options are: ``"Mass Flow"``, ``"Mass Flux"``, and
``"Volume Flow"``. The default value is ``"Mass Flow"``.
Flow specification for the recirculation zone. The default is
``"Mass Flow"``. Options are: ``"Mass Flow"``, ``"Mass Flux"``,
and ``"Volume Flow"``.
flow_assignment : str or dict, optional
String with value and units of the flow assignment. For a
String with the value and units of the flow assignment. For a
transient assignment, a dictionary can be used. The dictionary
should contain two keys: ``"Function"`` and ``"Values"``.
- For the ``"Function"`` key, acceptable values are
- For the ``"Function"`` key, options are
``"Exponential"``, ``"Linear"``, ``"Piecewise Linear"``,
``"Power Law"``, ``"Sinusoidal"``, and ``"Square Wave"``.
- For the ``"Values"`` key, a list of strings containing the
- For the ``"Values"`` key, provide a list of strings containing the
parameters required by the ``"Function"`` key selection. For
example, when``"Linear"`` is set as the ``"Function"`` key, two
parameters are required: the value of the variable at t=0 and the
Expand All @@ -4927,13 +4928,13 @@ def assign_recirculation_opening(self, face_list, extract_face, thermal_specific
The default value is ``"0kg_per_s_m2"``.
flow_direction : list, optional
Flow direction enforced at the recirculation zone. The default value
is ``None`` in which case the normal direction is used.
is ``None``, in which case the normal direction is used.
start_time : str, optional
Start of the time interval. Relevant only if the simulation is
transient. The default value is ``"0s"``.
Start of the time interval. This parameter is relevant only if the
simulation is transient. The default value is ``"0s"``.
end_time : str, optional
End of the time interval. Relevant only if the simulation is
transient. The default value is ``"0s"``.
End of the time interval. This parameter is relevant only if the
simulation is transient. The default value is ``"0s"``.
boundary_name : str, optional
Name of the recirculation boundary. The default is ``None``, in
which case the boundary is automatically generated.
Expand Down Expand Up @@ -4964,15 +4965,15 @@ def assign_recirculation_opening(self, face_list, extract_face, thermal_specific
return False
if conductance_external_temperature is not None and thermal_specification is not "Conductance":
self.logger.warning(
'``conductance_external_temperature`` will not have any effect unless the ``thermal_specification`` '
'``conductance_external_temperature`` does not have any effect unless the ``thermal_specification`` '
'is ``"Conductance"``.')
if conductance_external_temperature is not None and thermal_specification is not "Conductance":
self.logger.warning(
'``conductance_external_temperature`` needs to be specified when ``thermal_specification`` '
'``conductance_external_temperature`` must be specified when ``thermal_specification`` '
'is ``"Conductance"``. Setting ``conductance_external_temperature`` to ``"AmbientTemp"``.')
if (start_time is not None or end_time is not None) and not self.solution_type == "Transient":
self.logger.warning(
'``start_time`` and ``end_time`` will not have any effect unless for steady-state simulations.')
'``start_time`` and ``end_time`` only effect steady-state simulations.')
elif self.solution_type == "Transient" and not (start_time and end_time):
self.logger.warning(
'``start_time`` and ``end_time`` should be declared for transient simulations. Setting them to "0s".')
Expand Down Expand Up @@ -5046,5 +5047,164 @@ def assign_recirculation_opening(self, face_list, extract_face, thermal_specific
return bound
else: # pragma: no cover
raise SystemExit
except (GrpcApiError, SystemExit): # pragma : no cover
return None

@pyaedt_function_handler()
def assign_blower_type1(self, faces, inlet_face, fan_curve_pressure, fan_curve_flow, blower_power="0W", blade_rpm=0,
blade_angle="0rad", fan_curve_pressure_unit="n_per_meter_sq",
fan_curve_flow_unit="m3_per_s", boundary_name=None):
"""Assign blower type 1.

Parameters
----------
faces : list
List of modeler.cad.elements3d.FacePrimitive or of integers
containing faces ids.
inlet_face : modeler.cad.elements3d.FacePrimitive, int or list
Inlet faces.
fan_curve_pressure : list
List of the fan curve pressure values. Only floats should
be included in the list as their unit can be modified with
fan_curve_pressure_unit argument.
fan_curve_flow : list
List of the fan curve flow value. Only floats should be
included in the list as their unit can be modified with
fan_curve_flow_unit argument.
blower_power : str, optional
blower power expressed as a string containing the value and unit.
Default is "0W".
blade_rpm : float, optional
Blade RPM value. Default is 0.
blade_angle : str, optional
Blade angle expressed as a string containing value and the unit.
Default is "0rad".
fan_curve_pressure_unit : str, optional
Fan curve pressure unit. Default is "n_per_meter_sq".
fan_curve_flow_unit : str, optional
Fan curve flow unit. Default is "m3_per_s".
boundary_name : str, optional
Name of the recirculation boundary. The default is ``None``, in
which case the boundary is automatically generated.


Returns
-------
:class:`pyaedt.modules.Boundary.BoundaryObject`
Boundary object when successful or ``None`` when failed.

References
----------

>>> oModule.AssignBlowerBoundary

Examples
--------
>>> from pyaedt import Icepak
>>> ipk = Icepak()
>>> cylinder = self.aedtapp.modeler.create_cylinder(cs_axis="X", position=[0,0,0], radius=10, height=1)
>>> curved_face = [f for f in cylinder.faces if not f.is_planar]
>>> planar_faces = [f for f in cylinder.faces if f.is_planar]
>>> cylinder.solve_inside=False
>>> blower = self.aedtapp.assign_blower_type1([f.id for f in curved_face+planar_faces],
>>> [f.id for f in planar_faces], [10, 5, 0], [0, 2, 4])

"""
props = {}
props["Blade RPM"] = blade_rpm
props["Fan Blade Angle"] = blade_angle
props["Blower Type"] = "Type 1"
return self._assign_blower(props, faces, inlet_face, fan_curve_flow_unit, fan_curve_pressure_unit,
fan_curve_flow, fan_curve_pressure, blower_power, boundary_name)

@pyaedt_function_handler()
def assign_blower_type2(self, faces, inlet_face, fan_curve_pressure, fan_curve_flow, blower_power="0W",
exhaust_angle="0rad", fan_curve_pressure_unit="n_per_meter_sq",
fan_curve_flow_unit="m3_per_s", boundary_name=None):
"""Assign blower type 2.

Parameters
----------
faces : list
List of modeler.cad.elements3d.FacePrimitive or of integers
containing faces ids.
inlet_face : modeler.cad.elements3d.FacePrimitive, int or list
Inlet faces.
fan_curve_pressure : list
List of the fan curve pressure values. Only floats should
be included in the list as their unit can be modified with
fan_curve_pressure_unit argument.
fan_curve_flow : list
List of the fan curve flow value. Only floats should be
included in the list as their unit can be modified with
fan_curve_flow_unit argument.
blower_power : str, optional
blower power expressed as a string containing the value and unit.
Default is "0W".
exhaust_angle : float, optional
Exhaust angle expressed as a string containing value and the unit.
Default is "0rad".
fan_curve_pressure_unit : str, optional
Fan curve pressure unit. Default is "n_per_meter_sq".
fan_curve_flow_unit : str, optional
Fan curve flow unit. Default is "m3_per_s".
boundary_name : str, optional
Name of the recirculation boundary. The default is ``None``, in
which case the boundary is automatically generated.


Returns
-------
:class:`pyaedt.modules.Boundary.BoundaryObject`
Boundary object when successful or ``None`` when failed.

References
----------

>>> oModule.AssignBlowerBoundary

Examples
--------
>>> from pyaedt import Icepak
>>> ipk = Icepak()
>>> box = ipk.modeler.create_box([5, 5, 5], [1, 2, 3], "BlockBoxEmpty", "copper")
>>> box.solve_inside=False
>>> blower = self.aedtapp.assign_blower_type2([box.faces[0], box.faces[1]],
>>> [box.faces[0]], [10, 5, 0], [0, 2, 4])

"""
props = {}
props["Exhaust Exit Angle"] = exhaust_angle
props["Blower Type"] = "Type 2"
return self._assign_blower(props, faces, inlet_face, fan_curve_flow_unit, fan_curve_pressure_unit,
fan_curve_flow, fan_curve_pressure, blower_power, boundary_name)

@pyaedt_function_handler()
def _assign_blower(self, props, faces, inlet_face, fan_curve_flow_unit, fan_curve_pressure_unit, fan_curve_flow,
fan_curve_pressure, blower_power, boundary_name):
if isinstance(faces[0], int):
props["Faces"] = faces
else:
props["Faces"] = [f.id for f in faces]
if not isinstance(inlet_face, list):
inlet_face = [inlet_face]
if not isinstance(inlet_face[0], int):
props["InletFace"] = [f.id for f in inlet_face]
props["Blower Power"] = blower_power
props["DimUnits"] = [fan_curve_flow_unit, fan_curve_pressure_unit]
if len(fan_curve_flow) != len(fan_curve_pressure):
self.logger.error("``fan_curve_flow`` and ``fan_curve_pressure`` must have the same length.")
return False
props["X"] = [str(pt) for pt in fan_curve_flow]
props["Y"] = [str(pt) for pt in fan_curve_pressure]
if not boundary_name:
boundary_name = generate_unique_name("Blower")
bound = BoundaryObject(self, boundary_name, props, "Blower")
try:
if bound.create():
self._boundaries[bound.name] = bound
return bound
else: # pragma : no cover
raise SystemExit
except (GrpcApiError, SystemExit): # pragma: no cover
return None
4 changes: 4 additions & 0 deletions pyaedt/modules/Boundary.py
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,8 @@ def create(self):
self._app.oboundary.AssignGrilleBoundary(self._get_args())
elif bound_type == "Block":
self._app.oboundary.AssignBlockBoundary(self._get_args())
elif bound_type == "Blower":
self._app.oboundary.AssignBlowerBoundary(self._get_args())
elif bound_type == "SourceIcepak":
self._app.oboundary.AssignSourceBoundary(self._get_args())
elif bound_type == "Opening":
Expand Down Expand Up @@ -748,6 +750,8 @@ def update(self):
self._app.oboundary.EditEMLoss(self._boundary_name, self._get_args()) # pragma: no cover
elif bound_type == "Block":
self._app.oboundary.EditBlockBoundary(self._boundary_name, self._get_args())
elif bound_type == "Blower":
self._app.oboundary.EditBlowerBoundary(self._boundary_name, self._get_args())
elif bound_type == "SourceIcepak":
self._app.oboundary.EditSourceBoundary(self._boundary_name, self._get_args())
elif bound_type == "HeatFlux":
Expand Down
Loading