Skip to content
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/7053.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Wrap AssignFarFieldWave
108 changes: 108 additions & 0 deletions src/ansys/aedt/core/hfss.py
Original file line number Diff line number Diff line change
Expand Up @@ -6720,6 +6720,114 @@ def plane_wave(
inc_wave_args.update(props)
return self._create_boundary(name, inc_wave_args, "Plane Incident Wave")

@pyaedt_function_handler()
def far_field_wave(
self,
assignment: Union[str, "Hfss"],
setup: Optional[str] = None,
simulate_source: bool = True,
preserve_source_solution: bool = True,
coordinate_system: str = "Global",
name: Optional[str] = None,
) -> BoundaryObject:
"""Create a far field wave excitation.

Parameters
----------
assignment : ansys.aedt.core.Hfss or str
Source HFSS object from which to link the far field data, or path to an external
far field data file (.ffd file).
setup : optional
Name of the setup. The default is ``None``, in which
case a name is automatically assigned.
This parameter is only used when ``assignment`` is an HFSS object.
simulate_source : bool, optional
Whether to force the source design to solve. The default is ``True``.
This parameter is only used when ``assignment`` is an HFSS object.
preserve_source_solution : bool, optional
Whether to preserve the source solution. The default is ``True``.
This parameter is only used when ``assignment`` is an HFSS object.
coordinate_system : str, optional
Coordinate system to use for the source. The default is ``"Global"``.
name : str, optional
Name of the excitation. The default is ``None``, in which
case a name is automatically assigned.

Returns
-------
:class:`ansys.aedt.core.modules.boundary.common.BoundaryObject`
Far field boundary object.

References
----------
>>> oModule.AssignFarFieldWave

Examples
--------
Create a far field wave excitation from another design in the same project.

>>> from ansys.aedt.core import Hfss
>>> target = Hfss(project="target_project.aedt")
>>> source = Hfss(project="target_project.aedt", design="Source_Design")
>>> setup = source.create_setup("Setup1", Frequency="10GHz")
>>> far_field_wave_src = target.far_field_wave(assignment=source, setup=setup)

Create a far field wave excitation from an external project.

>>> target = Hfss(project="target_project.aedt")
>>> source = Hfss(project="source_project.aedt", design="Array_Design")
>>> setup = source.create_setup("Setup1", Frequency="10GHz")
>>> far_field_wave_src = target.far_field_wave(assignment=source, setup=setup)

Create a far field wave excitation from an external data file.

>>> target = Hfss(project="target_project.aedt")
>>> far_field_wave_src = target.far_field_wave(assignment="/path/to/farfield.ffd")
"""
name = self._get_unique_source_name(name, "IncFFWave")

if isinstance(assignment, str):
# Use external data file
props = {
"IsFarField": True,
"UseDataLink": False,
"ExternalDataFile": assignment,
"SourceCoordSystem": coordinate_system,
}
else:
# Use data link to another design
if assignment.project_name == self.project_name:
project_name = "This Project*"
else:
project_name = Path(assignment.project_path) / (assignment.project_name + ".aedt")

design_name = assignment.design_name

if not setup.get_sweep():
setup = assignment.nominal_adaptive

params = {}
pars = assignment.available_variations.get_independent_nominal_values()
for el in pars:
params[el] = pars[el]

props = {
"IsFarField": True,
"UseDataLink": True,
"ExternalDataFile": "",
"Project": str(project_name),
"Product": "HFSS",
"Design": design_name,
"Soln": setup,
"Params": params,
"ForceSourceToSolve": simulate_source,
"PreservePartnerSoln": preserve_source_solution,
"PathRelativeTo": "TargetProject",
"SourceCoordSystem": coordinate_system,
}

return self._create_boundary(name, props, "Far Field Wave")

@pyaedt_function_handler()
def hertzian_dipole_wave(
self,
Expand Down
2 changes: 2 additions & 0 deletions src/ansys/aedt/core/modules/boundary/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,8 @@ def create(self):
self._app.oboundary.AssignFluxTangential(self._get_args())
elif bound_type == "Plane Incident Wave":
self._app.oboundary.AssignPlaneWave(self._get_args())
elif bound_type == "Far Field Wave":
self._app.oboundary.AssignFarFieldWave(self._get_args())
elif bound_type == "Hertzian Dipole Wave":
self._app.oboundary.AssignHertzianDipoleWave(self._get_args())
elif bound_type == "ResistiveSheet":
Expand Down
59 changes: 59 additions & 0 deletions tests/system/general/test_hfss.py
Original file line number Diff line number Diff line change
Expand Up @@ -1992,6 +1992,65 @@ def test_plane_wave(aedt_app):
assert new_plane_wave.name in aedt_app.excitation_names


def test_far_field(aedt_app, add_app, test_tmp_dir):
# Create simple geometry in target design
_ = aedt_app.modeler.create_box([0, 0, 0], [10, 10, 10], "TargetBox")

# Create a source design in the same project
source_design = add_app(application=Hfss, design="FarFieldSource", close_projects=False)
source_design.solution_type = "Modal"

setup = source_design.create_setup("Setup1", Frequency="10GHz")
setup.props["MaximumPasses"] = 2

# Test far field with assignment from same project
far_field_boundary = aedt_app.far_field_wave(
assignment=source_design, setup=setup, coordinate_system="Global", name="FarField1"
)
assert far_field_boundary is not None
assert far_field_boundary.name == "FarField1"
assert far_field_boundary.name in aedt_app.excitation_names
assert far_field_boundary.type == "Far Field Wave"

# Test far field with external data file
ffd_file_original = TESTS_GENERAL_PATH / "example_models" / "T04" / "test.ffd"
ffd_file = shutil.copy2(ffd_file_original, test_tmp_dir / "test.ffd")

far_field_ext = aedt_app.far_field_wave(
assignment=str(ffd_file), coordinate_system="Global", name="FarFieldExternal"
)
assert far_field_ext is not None
assert far_field_ext.name == "FarFieldExternal"
assert far_field_ext.name in aedt_app.excitation_names

# Test with different properties
far_field_boundary2 = aedt_app.far_field_wave(
assignment=source_design,
setup=setup,
coordinate_system="Global",
simulate_source=False,
preserve_source_solution=False,
)
assert far_field_boundary2 is not None
assert far_field_boundary2.name in aedt_app.excitation_names

# Test far field with external project
external_source = add_app(
application=Hfss, project="ExternalProject", design="ExternalSource", close_projects=False
)
external_source.solution_type = "Modal"
external_setup = external_source.create_setup("Setup1", Frequency="10GHz")
external_setup.props["MaximumPasses"] = 2

far_field_external_project = aedt_app.far_field_wave(
assignment=external_source, setup=external_setup, coordinate_system="Global", name="FarFieldExternalProject"
)
external_source.close_project()
assert far_field_external_project is not None
assert far_field_external_project.name == "FarFieldExternalProject"
assert far_field_external_project.name in aedt_app.excitation_names


def test_export_on_completion(aedt_app, test_tmp_dir):
assert aedt_app.export_touchstone_on_completion()
assert aedt_app.export_touchstone_on_completion(export=True, output_dir=test_tmp_dir)
Expand Down
Loading