Skip to content

Conversation

@marcorudolphflex
Copy link
Contributor

@marcorudolphflex marcorudolphflex commented Dec 16, 2025

Previously, we just took the geometry bounds to construct adjoint monitors. This PR uses the plane intersection in 2D simulations.

Greptile Overview

Greptile Summary

This PR improves adjoint monitor sizing in 2D simulations by using planar geometry intersections instead of full bounding boxes. In 2D simulations (detected via self.size.count(0.0) == 1), the code now calls geometry.intersections_plane() to compute tight monitor bounds based on the actual geometry cross-section at the simulation plane.

Key changes:

  • simulation.py:4887 detects 2D simulations and passes plane info to structure monitor generation
  • structure.py:328-352 implements _box_from_plane_intersection() that computes monitor bounds from plane intersections with multi-level fallback (geometry → bounding box → full bounding box)
  • Comprehensive tests validate behavior for spheres, meshes, cylinders, boxes, and polyslabs in both 2D and 3D cases
  • Changelog entry added under 'Fixed' section

The implementation handles edge cases through a cascading fallback strategy and maintains backward compatibility for 3D simulations.

Confidence Score: 5/5

  • This PR is safe to merge with comprehensive test coverage and proper fallback handling
  • The changes are well-tested with multiple geometry types, include proper fallback logic for edge cases, maintain backward compatibility for 3D simulations, and fix an actual bug where adjoint monitors were oversized in 2D simulations. Code follows established patterns and includes appropriate documentation.
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
CHANGELOG.md 5/5 Added changelog entry under 'Fixed' section documenting adjoint monitor cropping in 2D simulations
tests/test_components/autograd/test_adjoint_monitors.py 5/5 New comprehensive test file covering 2D and 3D adjoint monitor sizing with various geometries
tidy3d/components/simulation.py 5/5 Detects 2D simulations and passes plane info to structure monitor generation
tidy3d/components/structure.py 4/5 Implements plane intersection logic for 2D adjoint monitors, with fallback to bounding box

Sequence Diagram

sequenceDiagram
    participant Sim as Simulation
    participant Struct as Structure
    participant Geom as Geometry
    participant BoxCls as Box

    Note over Sim: User calls _make_adjoint_monitors
    Sim->>Sim: Check if 2D via size.count(0.0) == 1
    alt Is 2D simulation
        Sim->>Sim: sim_plane = self
    else Is 3D simulation
        Sim->>Sim: sim_plane = None
    end
    
    loop For each structure
        Sim->>Struct: _make_adjoint_monitors(freqs, index, field_keys, plane)
        
        alt plane is not None (2D case)
            Struct->>Struct: Call _box_from_plane_intersection
            Struct->>Geom: geometry.intersections_plane
            Geom-->>Struct: Return intersection shapes
            
            alt Intersections found
                Struct->>Struct: Compute union of bounds
            else No intersections
                Struct->>Geom: geom_box.intersections_plane
                alt Box intersections found
                    Struct->>Struct: Compute union of bounds
                else Still no intersections
                    Struct->>Struct: Use geom_box as fallback
                end
            end
            
            Struct->>BoxCls: Box.from_bounds(rmin, rmax)
            BoxCls-->>Struct: Return planar box
        else plane is None (3D case)
            Struct->>Struct: box = geom_box
        end
        
        Struct->>Struct: Create FieldMonitor with box
        Struct->>Struct: Create PermittivityMonitor with box
        Struct-->>Sim: Return monitors
    end
    
    Sim-->>Sim: Collect all monitors
Loading

Note

Improves adjoint monitor sizing for 2D simulations by cropping to the simulation plane’s geometry intersection; 3D behavior unchanged.

  • Simulation passes a planar context to structures in _make_adjoint_monitors; structures compute monitor Box via geometry.intersections_plane(...) with robust fallbacks
  • New tests validate 2D plane-cropped bounds (spheres, meshes incl. disjoint components) and confirm 3D still uses bounding_box
  • CHANGELOG updated; minor deterministic test data tweak (random seed)

Written by Cursor Bugbot for commit 119c999. This will update automatically on new commits. Configure here.

@marcorudolphflex
Copy link
Contributor Author

@greptile

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@marcorudolphflex marcorudolphflex force-pushed the FXC-4563-use-2-d-intersections-for-adjoint-monitor-sizes-in-2-d-simulations branch from 4c5b691 to 2ecf314 Compare December 16, 2025 12:40
@marcorudolphflex
Copy link
Contributor Author

@greptile

@marcorudolphflex marcorudolphflex force-pushed the FXC-4563-use-2-d-intersections-for-adjoint-monitor-sizes-in-2-d-simulations branch from 2ecf314 to b1d5083 Compare December 16, 2025 12:43
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@marcorudolphflex marcorudolphflex force-pushed the FXC-4563-use-2-d-intersections-for-adjoint-monitor-sizes-in-2-d-simulations branch 2 times, most recently from 1e0bc03 to 481b3fa Compare December 16, 2025 12:47
@marcorudolphflex marcorudolphflex marked this pull request as ready for review December 16, 2025 12:47
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@marcorudolphflex marcorudolphflex force-pushed the FXC-4563-use-2-d-intersections-for-adjoint-monitor-sizes-in-2-d-simulations branch from 481b3fa to bd8e561 Compare December 16, 2025 14:27
Copy link
Collaborator

@yaugenst-flex yaugenst-flex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sort of an edge case but nice to have, thanks @marcorudolphflex

@marcorudolphflex marcorudolphflex force-pushed the FXC-4563-use-2-d-intersections-for-adjoint-monitor-sizes-in-2-d-simulations branch from bd8e561 to 489b67d Compare January 8, 2026 12:35
@marcorudolphflex marcorudolphflex force-pushed the FXC-4563-use-2-d-intersections-for-adjoint-monitor-sizes-in-2-d-simulations branch from 489b67d to 119c999 Compare January 8, 2026 12:36
@github-actions
Copy link
Contributor

github-actions bot commented Jan 8, 2026

Diff Coverage

Diff: origin/develop...HEAD, staged and unstaged changes

  • tidy3d/components/simulation.py (100%)
  • tidy3d/components/structure.py (87.5%): Missing lines 336-337,339

Summary

  • Total: 25 lines
  • Missing: 3 lines
  • Coverage: 88%

tidy3d/components/structure.py

Lines 332-343

  332 
  333             intersections = geometry.intersections_plane(**{axis_char: plane_position})
  334             bounds = [shape.bounds for shape in intersections if not shape.is_empty]
  335             if len(bounds) == 0:
! 336                 intersections = geom_box.intersections_plane(**{axis_char: plane_position})
! 337                 bounds = [shape.bounds for shape in intersections if not shape.is_empty]
  338             if len(bounds) == 0:  # fallback
! 339                 return geom_box
  340 
  341             min_plane = (min(b[0] for b in bounds), min(b[1] for b in bounds))
  342             max_plane = (max(b[2] for b in bounds), max(b[3] for b in bounds))

@marcorudolphflex marcorudolphflex added this pull request to the merge queue Jan 8, 2026
Merged via the queue into develop with commit f6e3d0f Jan 8, 2026
33 of 37 checks passed
@marcorudolphflex marcorudolphflex deleted the FXC-4563-use-2-d-intersections-for-adjoint-monitor-sizes-in-2-d-simulations branch January 8, 2026 14:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants