Getting Started =============== This guide explains how to interact with L-SURF and covers the key concepts you need to understand for successful ray tracing simulations. Interacting with L-SURF ----------------------- L-SURF provides three ways to run simulations: 1. **Command Line Interface (CLI)** - Recommended for production simulations 2. **Graphical User Interface (GUI)** - Recommended for exploration and learning 3. **Python Scripts** - For custom studies and advanced use cases CLI and GUI: The Preferred Approach ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For most users, the **CLI and GUI are the recommended ways** to interact with L-SURF: - **GUI** (``lsurf gui``): Best for learning, prototyping, and visualizing results. Provides immediate visual feedback and interactive configuration. - **CLI** (``lsurf run``): Best for production simulations, batch processing, and automation. Configurations are saved in portable YAML/TOML files. .. code-block:: bash # Start exploring with the GUI lsurf gui # Or build a configuration and run via CLI lsurf build -o my_simulation.yaml lsurf run my_simulation.yaml --progress Numbered Example Scripts ~~~~~~~~~~~~~~~~~~~~~~~~ The ``scripts/`` directory contains numbered example scripts (``01_basic.py``, ``02_sources.py``, etc.) that demonstrate specific features and techniques. **These scripts are intended as educational examples and references**, not as the primary way to run simulations. Use them when you need to: - Understand how a specific feature works - Create custom workflows not supported by the GUI/CLI - Run parameter sweeps or batch experiments - Integrate L-SURF into larger research pipelines .. note:: For standard simulations, prefer the GUI or CLI over writing custom scripts. The GUI/CLI handle configuration management, validation, and output automatically. Understanding Materials and Media --------------------------------- Material assignment is one of the most important concepts in L-SURF. Getting it right ensures physically accurate ray tracing results. What is a Medium? ~~~~~~~~~~~~~~~~~ A **medium** is a named reference to a material. Materials define optical properties like refractive index, absorption, and scattering. .. code-block:: python # Built-in materials from lsurf import VACUUM, AIR_STP, WATER, BK7_GLASS # Custom materials from lsurf import HomogeneousMaterial, ExponentialAtmosphere # Create a named medium builder.register_medium("atmosphere", ExponentialAtmosphere()) builder.register_medium("ocean", WATER) Why Use Named Media? ~~~~~~~~~~~~~~~~~~~~ Named media provide several benefits: 1. **Consistency** - Multiple surfaces referencing the same medium are guaranteed to use identical material properties 2. **Clarity** - Names like "atmosphere" and "ocean" are self-documenting 3. **Validation** - The builder can detect inconsistent material assignments 4. **Maintainability** - Change a material in one place, update everywhere Surface Material Assignment ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Each optical surface has two materials: **front** and **back**. - **Front** - The material on the positive normal side - **Back** - The material on the negative normal side .. code-block:: python from lsurf.surfaces import PlaneSurface, SurfaceRole # A water surface with air above and water below water_surface = PlaneSurface( point=(0, 0, 0), normal=(0, 0, 1), # Points "up" role=SurfaceRole.OPTICAL, name="water_interface", ) # When normal points up (+z): # - Front (positive normal) = above the surface = atmosphere # - Back (negative normal) = below the surface = ocean builder.add_surface(water_surface, front="atmosphere", back="ocean") The Background Medium ~~~~~~~~~~~~~~~~~~~~~ The **background medium** is the material where rays propagate between surfaces. It's typically the "ambient" medium of your simulation. .. code-block:: python # Rays travel through atmosphere until they hit a surface builder.set_background("atmosphere") .. important:: Rays always propagate through the background medium. When a ray crosses a surface, the material on that side determines refraction behavior, but propagation continues through the background. Material Checking and Validation -------------------------------- L-SURF includes automatic validation to catch common configuration errors. The Intersection Problem ~~~~~~~~~~~~~~~~~~~~~~~~ When two surfaces **intersect** (cross each other in space), they create ambiguous regions where it's unclear which material should apply. Consider two perpendicular planes at the origin: - Plane X: normal (1, 0, 0), front=air, back=water - Plane Y: normal (0, 1, 0), front=air, back=glass At the intersection line, which material is correct? This ambiguity causes validation to fail. When Validation Fails ~~~~~~~~~~~~~~~~~~~~~ The geometry builder raises ``IntersectingSurfacesError`` when: 1. Two surfaces intersect (are not parallel or nested), AND 2. They have different material assignments .. code-block:: python # This FAILS - intersecting planes with different materials builder.add_surface(plane_x, front="air", back="water") builder.add_surface(plane_y, front="air", back="glass") geometry = builder.build() # Raises IntersectingSurfacesError! When Validation Passes ~~~~~~~~~~~~~~~~~~~~~~ Intersecting surfaces are allowed when: 1. They have the **same material on all sides** (no optical discontinuity) .. code-block:: python # This WORKS - same material everywhere builder.add_surface(plane_x, front="air", back="air") builder.add_surface(plane_y, front="air", back="air") 2. They are **parallel** (never intersect) .. code-block:: python # This WORKS - parallel planes can have different materials builder.add_surface(plane1, front="air", back="water") builder.add_surface(plane2, front="water", back="glass") 3. They are **nested** (concentric spheres) .. code-block:: python # This WORKS - concentric spheres are nested, not intersecting builder.add_surface(inner_sphere, front="air", back="water") builder.add_surface(outer_sphere, front="water", back="air") Skipping Validation ~~~~~~~~~~~~~~~~~~~ For advanced use cases, validation can be disabled: .. code-block:: python # Skip validation (use with caution!) geometry = builder.build(validate=False) .. warning:: Disabling validation may result in physically inconsistent simulations. Only use this if you understand the implications. Cell-Based Geometry (Advanced) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For complex geometries with intersecting surfaces, use the cell-based API: .. code-block:: python # Define surfaces without materials builder.add_surface_only(plane_x) builder.add_surface_only(plane_y) # Define cells (regions) explicitly builder.add_cell("air", ("plane_x", True), ("plane_y", True)) # Quadrant 1 builder.add_cell("water", ("plane_x", False), ("plane_y", True)) # Quadrant 2 builder.add_cell("glass", ("plane_x", True), ("plane_y", False)) # Quadrant 3 builder.add_cell("vacuum", ("plane_x", False), ("plane_y", False)) # Quadrant 4 This explicitly defines which material applies in each region of space. Using the "Check Geometry" Feature ---------------------------------- In the GUI, the **Check Geometry** button validates your configuration: 1. Verifies all optical surfaces have materials assigned 2. Checks for intersecting surfaces with inconsistent materials 3. Reports warnings and errors Always check geometry before running large simulations to catch configuration problems early. Common Material Configurations ------------------------------ Air-Water Interface ~~~~~~~~~~~~~~~~~~~ .. code-block:: yaml media: air: type: air water: type: water surfaces: - name: water_surface type: plane front_medium: air # Above (positive normal) back_medium: water # Below (negative normal) params: point: [0, 0, 0] normal: [0, 0, 1] # Points up Atmospheric Simulation ~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: yaml media: atmosphere: type: exponential_atmosphere params: n_sea_level: 1.000293 scale_height: 8500.0 ocean: type: water surfaces: - name: ocean type: sphere front_medium: atmosphere # Above ocean back_medium: ocean # In ocean params: center: [0, 0, -6371000] # Earth center radius: 6371000 # Earth radius Glass Optics ~~~~~~~~~~~~ .. code-block:: yaml media: air: type: air glass: type: glass params: refractive_index: 1.52 surfaces: - name: lens_front type: sphere front_medium: air back_medium: glass params: center: [0, 0, 0.1] radius: 0.5 - name: lens_back type: sphere front_medium: glass # Inside lens back_medium: air # Outside lens params: center: [0, 0, -0.1] radius: 0.5 Next Steps ---------- - :doc:`cli_usage` - Complete CLI reference - :doc:`gui_usage` - GUI walkthrough - :doc:`materials` - Detailed material documentation - :doc:`simulation_workflow` - Advanced simulation techniques