Source code for nanohubpadre.region

"""
Region definition for PADRE simulations.

Defines material regions within the device mesh.
"""

from typing import Optional, Union
from .base import PadreCommand


[docs] class Region(PadreCommand): """ Define a material region in the device mesh. Every element in the mesh must be assigned to some material region. Parameters ---------- number : int Region number identifier material : str, optional Material name (e.g., "silicon", "gaas", "sio2", "si3n4") semiconductor : bool, optional Mark region as semiconductor (carrier transport computed) insulator : bool, optional Mark region as insulator (only displacement currents) Position by indices (for rectangular meshes): ix_low, ix_high : int, optional X index bounds iy_low, iy_high : int, optional Y index bounds Position by coordinates: x_min, x_max : float, optional X coordinate bounds (microns) y_min, y_max : float, optional Y coordinate bounds (microns) z_min, z_max : float, optional Z coordinate bounds (microns) newnum : int, optional Assign a new region number to this subregion Predefined materials (for backward compatibility): silicon, gaas, germanium, oxide, nitride, sapphire Example ------- >>> # Silicon substrate region >>> r1 = Region(number=1, material="silicon", semiconductor=True, ... ix_low=1, ix_high=25, iy_low=4, iy_high=20) >>> >>> # Gate oxide >>> r2 = Region(number=2, material="sio2", insulator=True, ... x_min=0, x_max=1, y_min=-0.04, y_max=0) """ command_name = "REGION" # Known PADRE materials SEMICONDUCTORS = {"silicon", "gaas", "germanium", "poly", "sige", "iga53", "aga45"} INSULATORS = {"sio2", "oxide", "si3n4", "nitride", "sapphire"}
[docs] def __init__( self, number: int, material: Optional[str] = None, semiconductor: Optional[bool] = None, insulator: Optional[bool] = None, # Index-based position ix_low: Optional[int] = None, ix_high: Optional[int] = None, iy_low: Optional[int] = None, iy_high: Optional[int] = None, # Coordinate-based position x_min: Optional[float] = None, x_max: Optional[float] = None, y_min: Optional[float] = None, y_max: Optional[float] = None, z_min: Optional[float] = None, z_max: Optional[float] = None, # Special newnum: Optional[int] = None, # Legacy material flags silicon: bool = False, gaas: bool = False, germanium: bool = False, oxide: bool = False, nitride: bool = False, sapphire: bool = False, ): super().__init__() self.number = number self.material = material self.semiconductor = semiconductor self.insulator = insulator # Position self.ix_low = ix_low self.ix_high = ix_high self.iy_low = iy_low self.iy_high = iy_high self.x_min = x_min self.x_max = x_max self.y_min = y_min self.y_max = y_max self.z_min = z_min self.z_max = z_max self.newnum = newnum # Legacy flags self.silicon = silicon self.gaas = gaas self.germanium = germanium self.oxide = oxide self.nitride = nitride self.sapphire = sapphire
[docs] def to_padre(self) -> str: params = {"NUM": self.number} flags = [] # Position - indices first (matches original format) if self.ix_low is not None: params["IX.L"] = self.ix_low if self.ix_high is not None: params["IX.H"] = self.ix_high if self.iy_low is not None: params["IY.L"] = self.iy_low if self.iy_high is not None: params["IY.H"] = self.iy_high # Material if self.material: params["NAME"] = self.material # Position - coordinates if self.x_min is not None: params["X.MIN"] = self.x_min if self.x_max is not None: params["X.MAX"] = self.x_max if self.y_min is not None: params["Y.MIN"] = self.y_min if self.y_max is not None: params["Y.MAX"] = self.y_max if self.z_min is not None: params["Z.MIN"] = self.z_min if self.z_max is not None: params["Z.MAX"] = self.z_max # Special if self.newnum is not None: params["NEW"] = self.newnum # Type flags and legacy material flags come AFTER name= (Rappture convention) if self.semiconductor: flags.append("SEMI") if self.insulator: flags.append("INS") if self.silicon: flags.append("SILICON") if self.gaas: flags.append("GAAS") if self.germanium: flags.append("GERMANIUM") if self.oxide: flags.append("OXIDE") if self.nitride: flags.append("NITRIDE") if self.sapphire: flags.append("SAPPHIRE") cmd = self._build_command(params, []) if flags: suffix = " ".join(f.lower() for f in flags) cmd = cmd + " " + suffix return cmd
[docs] @classmethod def silicon(cls, number: int, **kwargs) -> "Region": """Create a silicon semiconductor region.""" return cls(number=number, material="silicon", semiconductor=True, **kwargs)
[docs] @classmethod def oxide(cls, number: int, **kwargs) -> "Region": """Create an SiO2 insulator region.""" return cls(number=number, material="sio2", insulator=True, **kwargs)
[docs] @classmethod def gaas(cls, number: int, **kwargs) -> "Region": """Create a GaAs semiconductor region.""" return cls(number=number, material="gaas", semiconductor=True, **kwargs)