(
function: ngs.CoefficientFunction,
start_region: Optional[ngs.Region] = None,
mesh: Optional[ngs.Mesh] = None,
start_points: Optional[list] = None,
num_lines: int = 100,
length: float = 0.5,
name: str = "fieldlines",
max_points_per_line: float = 500,
thickness: float = 0.0015,
tolerance: float = 0.0005,
direction: int = 0,
)
| 563 | return data |
| 564 | |
| 565 | def FieldLines( |
| 566 | function: ngs.CoefficientFunction, |
| 567 | start_region: Optional[ngs.Region] = None, |
| 568 | mesh: Optional[ngs.Mesh] = None, |
| 569 | start_points: Optional[list] = None, |
| 570 | num_lines: int = 100, |
| 571 | length: float = 0.5, |
| 572 | name: str = "fieldlines", |
| 573 | max_points_per_line: float = 500, |
| 574 | thickness: float = 0.0015, |
| 575 | tolerance: float = 0.0005, |
| 576 | direction: int = 0, |
| 577 | ): |
| 578 | assert start_region or (mesh and start_points), "Either start_region or mesh and start_points must be provided" |
| 579 | rules = {} |
| 580 | # use 5th order integration rule for all element types as potential starting points |
| 581 | for et in [ |
| 582 | ngs.ET.TRIG, |
| 583 | ngs.ET.QUAD, |
| 584 | ngs.ET.TET, |
| 585 | ngs.ET.HEX, |
| 586 | ngs.ET.PRISM, |
| 587 | ngs.ET.PYRAMID, |
| 588 | ngs.ET.SEGM |
| 589 | ]: |
| 590 | rules[et] = ngs.IntegrationRule(et, 5) |
| 591 | |
| 592 | if function.is_complex: |
| 593 | num_lines = num_lines // 10 |
| 594 | |
| 595 | if start_points is not None: |
| 596 | all_mapped_points = mesh(start_points[:,0], start_points[:,1], start_points[:,2]) |
| 597 | else: |
| 598 | mesh = start_region.mesh |
| 599 | all_mapped_points = mesh.MapToAllElements(rules, start_region) |
| 600 | |
| 601 | num_angles = 100 if function.is_complex else 1 |
| 602 | for a in range(num_angles): |
| 603 | phi = 2 * np.pi * a / num_angles |
| 604 | |
| 605 | if function.is_complex: |
| 606 | cf = ngs.cos(phi) * function.real - ngs.sin(phi) * function.imag |
| 607 | else: |
| 608 | cf = function |
| 609 | |
| 610 | # randomize starting points to choose approx num_lines, higher function values increase selection probability |
| 611 | values = ngs.Norm(cf)(all_mapped_points).flatten() |
| 612 | sum_values = sum(values) |
| 613 | |
| 614 | rand_values = np.random.rand(len(values)) |
| 615 | selection = np.where(values > sum_values/num_lines * rand_values) |
| 616 | mapped_points = all_mapped_points[selection] |
| 617 | |
| 618 | # generate raw staring point coordinates and call low_level interface routing |
| 619 | points = ngs.CF((ngs.x, ngs.y, ngs.z))(mapped_points) |
| 620 | |
| 621 | data = cf._BuildFieldLines( |
| 622 | mesh, |
nothing calls this directly
no test coverage detected