Skip to content

FIX: Add mesh link wrong source design solution selection #6133

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

Merged
merged 14 commits into from
May 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions doc/changelog.d/6133.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add mesh link wrong source design solution selection
71 changes: 38 additions & 33 deletions src/ansys/aedt/core/modules/solve_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -888,7 +888,7 @@
Parameters
----------
design : str
Name of the source design.
Name of the source design from which the mesh is imported.
solution : str, optional
Name of the source design solution in the format ``"name : solution_name"``.
If ``None``, the default value is taken from the nominal adaptive solution.
Expand Down Expand Up @@ -921,72 +921,77 @@
Examples
--------
>>> from ansys.aedt.core import Maxwell3d
>>> m3d = Maxwell3d(design="source_design")
>>> m3d.create_setup(name="setup1")
The target design is duplicated from the source design and made it active design.
>>> m3d.duplicate_design(name="source_design", save_after_duplicate=True)
The mesh link is assigned to the target design analysis setup.
>>> m3d.setups[0].add_mesh_link(design="source_design", solution=m3d.nominal_adaptive)
>>> m3d = Maxwell3d(design="target_design")
>>> target_setup = m3d.create_setup(name="target_setup")
The target design is duplicated and made it active.
The duplicated design will be the source design from which the mesh is imported.
>>> m3d.duplicate_design(name="target_design", save_after_duplicate=True)
>>> m3d.rename_design(name="source_design")
>>> m3d.create_setup(name="source_setup")
Activate the target design.
>>> m3d.set_active_design("target_design")
The mesh link is assigned to the target design.
>>> target_setup.add_mesh_link("source_design")
>>> m3d.release_desktop()

"""

dkp = self._app.desktop_class
source_design = design
auto_update = self.auto_update
try:
self.auto_update = False
meshlinks = self.props["MeshLink"]
mesh_link = self.props["MeshLink"]
# design type
if self._app.design_type == "Mechanical":
design_type = "ElectronicsDesktop"
elif self._app.design_type == "Maxwell 2D" or self._app.design_type == "Maxwell 3D":
design_type = "Maxwell"
if self._app.design_type in ["Mechanical", "Maxwell 2D", "Maxwell 3D"]:
design_type = "ElectronicsDesktop" if self._app.design_type == "Mechanical" else self._app.design_type
else:
design_type = self._app.design_type
meshlinks["Product"] = design_type
mesh_link["Product"] = design_type
# design name
if design not in self._app.design_list:
raise ValueError("Design does not exist in current project.")
else:
meshlinks["Design"] = design
mesh_link["Design"] = design
# project name
if project != "This Project*":
if os.path.exists(project):
meshlinks["Project"] = project
meshlinks["PathRelativeTo"] = "SourceProduct"
mesh_link["Project"] = project
mesh_link["PathRelativeTo"] = "SourceProduct"
else:
raise ValueError("Project file path provided does not exist.")
else:
meshlinks["Project"] = project
meshlinks["PathRelativeTo"] = "TargetProject"
# if self._app.solution_type == "SBR+":
meshlinks["ImportMesh"] = True
mesh_link["Project"] = project
mesh_link["PathRelativeTo"] = "TargetProject"

mesh_link["ImportMesh"] = True
# solution name
app = dkp[[self._app.project_name, source_design]]
if solution is None:
meshlinks["Soln"] = self._app.nominal_adaptive
elif solution.split()[0] not in self._app.setup_names:
mesh_link["Soln"] = app.nominal_adaptive
elif solution.split()[0] not in app.setup_names:
raise ValueError("Setup does not exist in current design.")
elif solution:
mesh_link["Soln"] = solution
# parameters
meshlinks["Params"] = {}
mesh_link["Params"] = {}

nominal_values = self._app.available_variations.get_independent_nominal_values()

if parameters is None:
parameters = nominal_values
parameters = self._app.available_variations.nominal_w_values_dict
for el in parameters:
meshlinks["Params"][el] = el
mesh_link["Params"][el] = el
else:
for el in parameters:
if el in list(nominal_values.keys()):
meshlinks["Params"][el] = el
mesh_link["Params"][el] = el
else:
meshlinks["Params"][el] = parameters[el]
mesh_link["Params"][el] = parameters[el]

Check warning on line 988 in src/ansys/aedt/core/modules/solve_setup.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/aedt/core/modules/solve_setup.py#L988

Added line #L988 was not covered by tests

meshlinks["ForceSourceToSolve"] = force_source_to_solve
meshlinks["PreservePartnerSoln"] = preserve_partner_solution
meshlinks["ApplyMeshOp"] = apply_mesh_operations
mesh_link["ForceSourceToSolve"] = force_source_to_solve
mesh_link["PreservePartnerSoln"] = preserve_partner_solution
mesh_link["ApplyMeshOp"] = apply_mesh_operations
if self._app.design_type not in ["Maxwell 2D", "Maxwell 3D"]:
meshlinks["AdaptPort"] = adapt_port
mesh_link["AdaptPort"] = adapt_port
self.update()
self.auto_update = auto_update
return True
Expand Down
191 changes: 93 additions & 98 deletions tests/system/general/test_29_Mechanical.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,139 +31,134 @@
from ansys.aedt.core.internal.errors import AEDTRuntimeError
import pytest

from tests.system.general.conftest import config

test_project_name = "coax_Mech"


@pytest.fixture(scope="class")
@pytest.fixture()
def aedtapp(add_app):
app = add_app(application=Mechanical, solution_type="Thermal")
return app
yield app
app.close_project(app.project_name)


@pytest.fixture()
def hfss(add_app):
app = add_app(application=Hfss)
yield app
app.close_project(app.project_name)


@pytest.fixture()
def ipk(add_app):
app = add_app(application=Icepak, solution_type="SteadyState")
yield app
app.close_project(app.project_name)


class TestClass:
@pytest.fixture(autouse=True)
def init(self, aedtapp, local_scratch):
self.aedtapp = aedtapp
self.local_scratch = local_scratch

def test_01_save(self):
test_project = os.path.join(self.local_scratch.path, test_project_name + ".aedt")
self.aedtapp.save_project(test_project)
def test_save_project(self, aedtapp, local_scratch):
test_project = os.path.join(local_scratch.path, "coax_Mech" + ".aedt")
aedtapp.save_project(test_project)
assert os.path.exists(test_project)

def test_02_create_primitive(self):
udp = self.aedtapp.modeler.Position(0, 0, 0)
def test_create_primitive(self, aedtapp):
udp = aedtapp.modeler.Position(0, 0, 0)
coax_dimension = 30
o = self.aedtapp.modeler.create_cylinder(
self.aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, "MyCylinder", "brass"
)
o = aedtapp.modeler.create_cylinder(aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, "MyCylinder", "brass")
assert isinstance(o.id, int)

def test_03_assign_convection(self):
face = self.aedtapp.modeler["MyCylinder"].faces[0].id
assert self.aedtapp.assign_uniform_convection(face, 3)
def test_assign_convection(self, aedtapp):
aedtapp.modeler.create_cylinder(orientation="Z", origin=[0, 0, 0], radius=0.8, height=20, name="MyCylinder")
face = aedtapp.modeler["MyCylinder"].faces[0].id
assert aedtapp.assign_uniform_convection(face, 3)

def test_04_assign_temperature(self):
face = self.aedtapp.modeler["MyCylinder"].faces[1].id
bound = self.aedtapp.assign_uniform_temperature(face, "35deg")
def test_assign_temperature(self, aedtapp):
aedtapp.modeler.create_cylinder(orientation="Z", origin=[0, 0, 0], radius=0.8, height=20, name="MyCylinder")
face = aedtapp.modeler["MyCylinder"].faces[1].id
bound = aedtapp.assign_uniform_temperature(face, "35deg")
assert bound.props["Temperature"] == "35deg"

def test_05_assign_load(self, add_app):
hfss = add_app(application=Hfss)
udp = self.aedtapp.modeler.Position(0, 0, 0)
def test_assign_load(self, aedtapp, hfss):
udp = aedtapp.modeler.Position(0, 0, 0)
coax_dimension = 30
hfss.modeler.create_cylinder(self.aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, "MyCylinder", "brass")
hfss.modeler.create_cylinder(aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, "MyCylinder", "brass")
setup = hfss.create_setup()
freq = "1GHz"
setup.props["Frequency"] = freq
assert self.aedtapp.assign_em_losses(hfss.design_name, hfss.setups[0].name, "LastAdaptive", freq)
aedtapp.modeler.create_cylinder(orientation="Z", origin=[0, 0, 0], radius=0.8, height=20, name="MyCylinder")
assert aedtapp.assign_em_losses(hfss.design_name, hfss.setups[0].name, "LastAdaptive", freq)

def test_06a_create_setup(self):
assert not self.aedtapp.assign_2way_coupling()
mysetup = self.aedtapp.create_setup()
def test_create_setup(self, aedtapp):
assert not aedtapp.assign_2way_coupling()
mysetup = aedtapp.create_setup()
mysetup.props["Solver"] = "Direct"
assert mysetup.update()
assert aedtapp.assign_2way_coupling()

def test_06b_two_way(self):
assert self.aedtapp.assign_2way_coupling()

@pytest.mark.skipif(config["desktopVersion"] < "2021.2", reason="Skipped on versions lower than 2021.2")
def test_07_assign_thermal_loss(self, add_app):
ipk = add_app(application=Icepak, solution_type=self.aedtapp.SOLUTIONS.Icepak.SteadyState)
udp = self.aedtapp.modeler.Position(0, 0, 0)
def test_assign_thermal_loss(self, aedtapp, ipk):
udp = aedtapp.modeler.Position(0, 0, 0)
coax_dimension = 30
ipk.modeler.create_cylinder(ipk.PLANE.XY, udp, 3, coax_dimension, 0, "MyCylinder", "brass")
ipk.create_setup()
self.aedtapp.oproject.InsertDesign("Mechanical", "MechanicalDesign1", "Structural", "")
self.aedtapp.set_active_design("MechanicalDesign1")
self.aedtapp.create_setup()
self.aedtapp.modeler.create_cylinder(self.aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, "MyCylinder", "brass")
assert self.aedtapp.assign_thermal_map("MyCylinder", ipk.design_name)

def test_07_assign_mechanical_boundaries(self):
udp = self.aedtapp.modeler.Position(0, 0, 0)
aedtapp.oproject.InsertDesign("Mechanical", "MechanicalDesign1", "Structural", "")
aedtapp.set_active_design("MechanicalDesign1")
aedtapp.create_setup()
aedtapp.modeler.create_cylinder(aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, "MyCylinder", "brass")
assert aedtapp.assign_thermal_map("MyCylinder", ipk.design_name)

def test_assign_mechanical_boundaries(self, aedtapp):
udp = aedtapp.modeler.Position(0, 0, 0)
coax_dimension = 30
self.aedtapp.oproject.InsertDesign("Mechanical", "MechanicalDesign2", "Modal", "")
self.aedtapp.set_active_design("MechanicalDesign2")
self.aedtapp.modeler.create_cylinder(self.aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, "MyCylinder", "brass")
self.aedtapp.create_setup()
assert self.aedtapp.assign_fixed_support(self.aedtapp.modeler["MyCylinder"].faces[0].id)
assert self.aedtapp.assign_frictionless_support(self.aedtapp.modeler["MyCylinder"].faces[1].id)
self.aedtapp.oproject.InsertDesign("Mechanical", "MechanicalDesign3", "Thermal", "")
self.aedtapp.set_active_design("MechanicalDesign3")
self.aedtapp.modeler.create_cylinder(self.aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, "MyCylinder", "brass")
aedtapp.oproject.InsertDesign("Mechanical", "MechanicalDesign2", "Modal", "")
aedtapp.set_active_design("MechanicalDesign2")
aedtapp.modeler.create_cylinder(aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, "MyCylinder", "brass")
aedtapp.create_setup()
assert aedtapp.assign_fixed_support(aedtapp.modeler["MyCylinder"].faces[0].id)
assert aedtapp.assign_frictionless_support(aedtapp.modeler["MyCylinder"].faces[1].id)
aedtapp.oproject.InsertDesign("Mechanical", "MechanicalDesign3", "Thermal", "")
aedtapp.set_active_design("MechanicalDesign3")
aedtapp.modeler.create_cylinder(aedtapp.PLANE.XY, udp, 3, coax_dimension, 0, "MyCylinder", "brass")
with pytest.raises(AEDTRuntimeError, match="This method works only in a Mechanical Structural analysis."):
self.aedtapp.assign_fixed_support(self.aedtapp.modeler["MyCylinder"].faces[0].id)
aedtapp.assign_fixed_support(aedtapp.modeler["MyCylinder"].faces[0].id)
with pytest.raises(AEDTRuntimeError, match="This method works only in a Mechanical Structural analysis."):
self.aedtapp.assign_frictionless_support(self.aedtapp.modeler["MyCylinder"].faces[0].id)

def test_08_mesh_settings(self):
assert self.aedtapp.mesh.initial_mesh_settings
assert self.aedtapp.mesh.initial_mesh_settings.props

def test_09_assign_heat_flux(self):
self.aedtapp.insert_design("Th1", "Thermal")
self.aedtapp.modeler.create_box([0, 0, 0], [10, 10, 3], "box1", "copper")
b2 = self.aedtapp.modeler.create_box([20, 20, 2], [10, 10, 3], "box2", "copper")
hf1 = self.aedtapp.assign_heat_flux(["box1"], heat_flux_type="Total Power", value="5W")
hf2 = self.aedtapp.assign_heat_flux([b2.top_face_x.id], heat_flux_type="Surface Flux", value="25mW_per_m2")
aedtapp.assign_frictionless_support(aedtapp.modeler["MyCylinder"].faces[0].id)

def test_mesh_settings(self, aedtapp):
assert aedtapp.mesh.initial_mesh_settings
assert aedtapp.mesh.initial_mesh_settings.props

def test_assign_heat_flux(self, aedtapp):
aedtapp.insert_design("Th1", "Thermal")
aedtapp.modeler.create_box([0, 0, 0], [10, 10, 3], "box1", "copper")
b2 = aedtapp.modeler.create_box([20, 20, 2], [10, 10, 3], "box2", "copper")
hf1 = aedtapp.assign_heat_flux(["box1"], heat_flux_type="Total Power", value="5W")
hf2 = aedtapp.assign_heat_flux([b2.top_face_x.id], heat_flux_type="Surface Flux", value="25mW_per_m2")
assert hf1.props["TotalPower"] == "5W"
assert hf2.props["SurfaceFlux"] == "25mW_per_m2"

def test_10_assign_heat_generation(self):
self.aedtapp.insert_design("Th2", "Thermal")
self.aedtapp.modeler.create_box([40, 40, 2], [10, 10, 3], "box3", "copper")
hg1 = self.aedtapp.assign_heat_generation(["box3"], value="1W", name="heatgenBC")
def test_assign_heat_generation(self, aedtapp):
aedtapp.insert_design("Th2", "Thermal")
aedtapp.modeler.create_box([40, 40, 2], [10, 10, 3], "box3", "copper")
hg1 = aedtapp.assign_heat_generation(["box3"], value="1W", name="heatgenBC")
assert hg1.props["TotalPower"] == "1W"

def test_11_add_mesh_link(self):
self.aedtapp.save_project(self.aedtapp.project_file)
self.aedtapp.set_active_design("MechanicalDesign1")
assert self.aedtapp.setups[0].add_mesh_link(design="MechanicalDesign2")
meshlink_props = self.aedtapp.setups[0].props["MeshLink"]
def test_add_mesh_link(self, aedtapp, local_scratch):
setup = aedtapp.create_setup()
aedtapp.insert_design("MechanicalDesign2")
aedtapp.create_setup()
assert setup.add_mesh_link(design="MechanicalDesign2")
meshlink_props = setup.props["MeshLink"]
assert meshlink_props["Project"] == "This Project*"
assert meshlink_props["PathRelativeTo"] == "TargetProject"
assert meshlink_props["Design"] == "MechanicalDesign2"
assert meshlink_props["Soln"] == self.aedtapp.nominal_adaptive
assert meshlink_props["Params"] == self.aedtapp.available_variations.nominal_values
assert not self.aedtapp.setups[0].add_mesh_link(design="")
assert not self.aedtapp.setups[0].add_mesh_link(
design="MechanicalDesign2", solution="Setup_Test : LastAdaptive"
)

assert self.aedtapp.setups[0].add_mesh_link(
design="MechanicalDesign2", parameters=self.aedtapp.available_variations.nominal_values
)
assert self.aedtapp.setups[0].add_mesh_link(design="MechanicalDesign2", solution="MySetupAuto : LastAdaptive")
example_project = os.path.join(self.local_scratch.path, test_project_name + ".aedt")
example_project_copy = os.path.join(self.local_scratch.path, test_project_name + "_copy.aedt")
assert meshlink_props["Soln"] == aedtapp.nominal_adaptive
assert meshlink_props["Params"] == aedtapp.available_variations.nominal_values
assert not setup.add_mesh_link(design="")
assert not setup.add_mesh_link(design="MechanicalDesign2", solution="Setup_Test : LastAdaptive")

assert setup.add_mesh_link(design="MechanicalDesign2", parameters=aedtapp.available_variations.nominal_values)
assert setup.add_mesh_link(design="MechanicalDesign2", solution="MySetupAuto : LastAdaptive")
example_project = os.path.join(local_scratch.path, "test.aedt")
aedtapp.save_project(example_project)
example_project_copy = os.path.join(local_scratch.path, "test_copy.aedt")
shutil.copyfile(example_project, example_project_copy)
assert self.aedtapp.setups[0].add_mesh_link(design="MechanicalDesign2", project=example_project_copy)
assert setup.add_mesh_link(design="MechanicalDesign2", project=example_project_copy)
os.remove(example_project_copy)

def test_12_transient_thermal(self):
mech = Mechanical(solution_type="Transient Thermal")
setup = mech.create_setup()
assert "Stop Time" in setup.props