Contributing to Prismo

Thank you for your interest in contributing to Prismo! This guide will help you get started.

Quick Start

# 1. Fork and clone the repository
git clone https://github.com/YOUR_USERNAME/prismo.git
cd prismo

# 2. Install development dependencies
pip install -e ".[dev]"

# 3. Create a branch for your changes
git checkout -b feature/my-new-feature

# 4. Make your changes and test
pytest tests/
black src/prismo/
ruff check src/prismo/

# 5. Commit and push
git add .
git commit -m "Add my new feature"
git push origin feature/my-new-feature

# 6. Open a pull request on GitHub

Development Setup

Prerequisites

  • Python 3.9+

  • Git

  • (Optional) CUDA for GPU support

Installation

# Clone repository
git clone https://github.com/rithulkamesh/prismo.git
cd prismo

# Create virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install in editable mode with dev dependencies
pip install -e ".[dev,docs]"

# Verify installation
pytest tests/ -v

Code Style

We follow strict code style guidelines:

Python Style

  • PEP 8 compliance

  • Type hints for all public functions

  • NumPy docstrings format

  • Maximum line length: 88 characters (Black default)

Formatting Tools

# Auto-format with Black
black src/prismo/

# Check with ruff
ruff check src/prismo/

# Type checking with mypy
mypy src/prismo/

# All checks
make lint

Example

def compute_overlap(
    Ex: np.ndarray,
    Ey: np.ndarray,
    mode: WaveguideMode,
    dx: float,
    dy: float,
) -> complex:
    """
    Compute mode overlap integral.

    Parameters
    ----------
    Ex, Ey : ndarray
        Electric field components.
    mode : WaveguideMode
        Waveguide mode for overlap.
    dx, dy : float
        Grid spacing.

    Returns
    -------
    complex
        Overlap coefficient.

    Examples
    --------
    >>> overlap = compute_overlap(Ex, Ey, mode, 1e-8, 1e-8)
    >>> assert abs(overlap) <= 1.0
    """
    # Implementation with type hints and clear logic
    overlap = 0.5 * np.sum((Ex * np.conj(mode.Ey) - Ey * np.conj(mode.Ex))) * dx * dy
    return complex(overlap)

Testing

Running Tests

# Run all tests
pytest

# Run specific test file
pytest tests/test_modes.py

# Run with coverage
pytest --cov=prismo --cov-report=html

# Run only fast tests
pytest -m "not slow"

Writing Tests

Every new feature must include tests:

import pytest
import numpy as np
from prismo.modes.solver import ModeSolver

class TestModeSolver:
    """Test mode solver functionality."""

    @pytest.fixture
    def simple_waveguide(self):
        """Create a simple test waveguide."""
        x = np.linspace(-2e-6, 2e-6, 50)
        y = np.linspace(-2e-6, 2e-6, 50)
        epsilon = np.ones((50, 50)) * 1.5**2
        return x, y, epsilon

    def test_mode_solver_creation(self, simple_waveguide):
        """Test that ModeSolver can be created."""
        x, y, eps = simple_waveguide
        solver = ModeSolver(1.55e-6, x, y, eps)
        assert solver is not None

    def test_fundamental_mode(self, simple_waveguide):
        """Test solving for fundamental mode."""
        x, y, eps = simple_waveguide
        solver = ModeSolver(1.55e-6, x, y, eps)
        modes = solver.solve(num_modes=1)

        assert len(modes) > 0
        assert modes[0].neff.real > 1.0
        assert modes[0].neff.real < 3.5

Test Categories

Use markers for different test types:

@pytest.mark.slow
def test_large_simulation():
    """This test takes a while."""
    pass

@pytest.mark.gpu
def test_gpu_backend():
    """Requires GPU."""
    pass

@pytest.mark.integration
def test_full_workflow():
    """Tests multiple components together."""
    pass

Documentation

Docstring Format

Use NumPy style docstrings:

def function_name(param1: type, param2: type) -> return_type:
    """
    Short one-line summary.

    Longer description explaining what the function does,
    how it works, and any important details.

    Parameters
    ----------
    param1 : type
        Description of param1.
    param2 : type
        Description of param2.

    Returns
    -------
    return_type
        Description of return value.

    Raises
    ------
    ValueError
        When invalid input is provided.

    See Also
    --------
    related_function : Related functionality.

    Examples
    --------
    >>> result = function_name(1.0, 2.0)
    >>> print(result)
    3.0

    Notes
    -----
    Additional mathematical or implementation details.

    References
    ----------
    .. [1] Author, "Title", Journal, Year.
    """
    pass

Building Documentation

# Build HTML documentation
cd docs
make html

# View documentation
open build/html/index.html  # macOS
xdg-open build/html/index.html  # Linux
start build/html/index.html  # Windows

# Clean and rebuild
make clean html

Pull Request Process

1. Before Submitting

  • Code follows style guidelines (Black, Ruff)

  • All tests pass (pytest)

  • New tests added for new features

  • Documentation updated

  • CHANGELOG.md updated (if applicable)

  • Type hints added

  • No linter warnings

2. PR Description

Include:

  • What: Brief description of changes

  • Why: Motivation for changes

  • How: Technical approach

  • Testing: How you tested

  • Screenshots: If UI/visualization changes

Example:

## Add Mode Port Boundary Condition

### What

Implements mode port boundaries for waveguide simulations with mode injection and extraction.

### Why

Enables accurate S-parameter calculations for waveguide devices.

### How

- Created `ModePort` class in `boundaries/mode_port.py`
- Implemented mode overlap integrals
- Added S-parameter extraction methods

### Testing

- Unit tests in `tests/validation/test_mode_ports.py`
- Validated against analytical waveguide solution
- Example in `examples/mode_port_demo.py`

### Related Issues

Closes #6

3. Review Process

  1. Automated checks run (CI/CD)

  2. Maintainer review

  3. Address feedback

  4. Merge when approved

Commit Messages

Follow conventional commits:

type(scope): subject

body

footer

Types:

  • feat: New feature

  • fix: Bug fix

  • docs: Documentation only

  • style: Code style (formatting, etc.)

  • refactor: Code refactoring

  • test: Adding/updating tests

  • chore: Maintenance tasks

Examples:

feat(modes): add mode port boundary condition

Implement mode ports for waveguide S-parameter extraction.
Includes mode injection, extraction, and overlap integrals.

Closes #6

---

fix(solver): correct Courant condition for 3D

The 3D Courant limit calculation was incorrect.
Now properly accounts for all three dimensions.

---

docs(tutorials): add S-parameter extraction tutorial

New tutorial showing how to extract S-parameters using
mode expansion monitors.

Code Review Guidelines

When reviewing PRs:

What to Look For

  • Correctness: Does it work as intended?

  • Tests: Are there adequate tests?

  • Documentation: Is it well documented?

  • Performance: Any performance concerns?

  • Style: Follows code style?

  • Breaking changes: Any API changes?

Providing Feedback

Be constructive and specific:

Good:

The mode overlap calculation looks correct, but could be optimized
by pre-computing the mode normalization. Consider moving line 45
to the __init__ method.

Not as helpful:

This is slow.

Feature Requests

Proposing New Features

  1. Check existing issues/PRs

  2. Open a feature request issue

  3. Describe use case and proposed API

  4. Discuss with maintainers

  5. Implement after approval

Template

## Feature Request: [Feature Name]

### Use Case

Describe what you want to accomplish.

### Proposed API

```python
# Example of how it would be used
sim.add_feature(...)
```

Alternatives Considered

Other approaches you’ve thought about.

Additional Context

Any other relevant information.


## Getting Help

- **Documentation**: Check docs first
- **Discussions**: Use GitHub Discussions for questions
- **Issues**: Report bugs via GitHub Issues
- **Chat**: Join our developer chat (if available)

## Code of Conduct

- Be respectful and inclusive
- Provide constructive feedback
- Focus on the code, not the person
- Help newcomers feel welcome

## License

By contributing, you agree that your contributions will be licensed under the MIT License.

## Recognition

Contributors are recognized in:
- README.md contributors section
- Release notes
- Documentation credits

Thank you for contributing to Prismo! 🎉