Source code for sionna.rt.radio_materials.itu_material

#
# SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
"""ITU radio materials"""

import mitsuba as mi
from typing import Tuple, Callable

from .itu import itu_material, ITU_MATERIALS_PROPERTIES
from .radio_material import RadioMaterial


[docs] class ITURadioMaterial(RadioMaterial): # pylint: disable=line-too-long r""" Class implementing the materials defined in the ITU-R P.2040-3 recommendation [ITU_R_2040_3]_ This class inherits from :class:`~sionna.rt.RadioMaterial`. The models from the ITU-R P.2040-3 recommendation are based on curve fitting to measurement results and assume non-ionized and non-magnetic materials (:math:`\mu_r = 1`). Frequency dependence is modeled by .. math:: \begin{align} \varepsilon_r &= a f_{\text{GHz}}^b\\ \sigma &= c f_{\text{GHz}}^d \end{align} where :math:`f_{\text{GHz}}` is the frequency in GHz, and the constants :math:`a`, :math:`b`, :math:`c`, and :math:`d` characterize the material. Note that the relative permittivity :math:`\varepsilon_r` and conductivity :math:`\sigma` of all materials are updated automatically when the frequency is set through the scene's property :class:`~.rt.Scene.frequency`. In addition to the following inputs, additional keyword arguments can be provided that will be passed to the scattering pattern as keyword arguments. :param name: Unique name of the material. Ignored if ``props`` is provided. :param itu_type: Type the ITU material. The available materials are listed in :ref:`the corresponding table <provided-materials>`. Ignored if ``props`` is provided. :param thickness: Thickness of the material [m]. Ignored if ``props`` is provided. :param scattering_coefficient: Scattering coefficient :math:`S\in[0,1]` as defined in :eq:`scattering_coefficient`. Ignored if ``props`` is provided. :param xpd_coefficient: Cross-polarization discrimination coefficient :math:`K_x\in[0,1]` as defined in :eq:`xpd`. Only relevant if ``scattering_coefficient`` is not equal to zero. Ignored if ``props`` is provided. :param scattering_pattern: Scattering pattern to use for diffuse reflection. Only relevant if ``scattering_coefficient`` is not equal to zero. Ignored if ``props`` is provided. Defaults to :func:`~sionna.rt.lambertian_pattern`. :param color: RGB (red, green, blue) color for the radio material as displayed in the previewer and renderer. Each RGB component must have a value within the range :math:`[0,1]`. If set to :py:class:`None`, then a random color is used. :param props: Mitsuba container storing the material properties, and used when loading a scene to initialize the radio material. """ # ITU material colors ITU_MATERIAL_COLORS = { "marble" : (0.701, 0.644, 0.485), "concrete" : (0.539, 0.539, 0.539), "wood" : (0.266, 0.109, 0.060), "metal" : (0.220, 0.220, 0.254), "brick" : (0.402, 0.112, 0.087), "glass" : (0.168, 0.139, 0.509), "floorboard" : (0.539, 0.386, 0.025), "ceiling_board" : (0.376, 0.539, 0.117), "chipboard" : (0.509, 0.159, 0.323), "plasterboard" : (0.051, 0.539, 0.133), "plywood" : (0.136, 0.076, 0.539), "very_dry_ground" : (0.539, 0.319, 0.223), "medium_dry_ground" : (0.539, 0.181, 0.076), "wet_ground" : (0.539, 0.027, 0.147) } # pylint: disable=line-too-long def __init__( self, name : str | None = None, itu_type : str | None = None, thickness : float | mi.Float | None = None, scattering_coefficient : float | mi.Float = 0.0, xpd_coefficient : float | mi.Float = 0.0, scattering_pattern : Callable[[mi.Vector3f, mi.Vector3f, ...], mi.Float] | None = None, color : Tuple[float, float, float] | None = None, props : mi.Properties | None = None, **kwargs): if props is not None: if props.has_property('type'): itu_type = props['type'] props.remove_property('type') else: raise ValueError(f"Missing ITU material type \"{itu_type}\"") if itu_type not in ITU_MATERIALS_PROPERTIES: raise ValueError(f"Invalid ITU material type \"{itu_type}\"") self._itu_type = itu_type if color is None: color = ITURadioMaterial.ITU_MATERIAL_COLORS[itu_type] if props: props["color"] = mi.ScalarColor3f(color) # Frequency update callback def cb(f: float): return itu_material(itu_type, f) if props is None: super().__init__(name=name, thickness=thickness, scattering_coefficient=scattering_coefficient, xpd_coefficient=xpd_coefficient, scattering_pattern=scattering_pattern, frequency_update_callback=cb, color=color, **kwargs) else: super().__init__(scattering_pattern=scattering_pattern, frequency_update_callback=cb, props=props, **kwargs) @property def itu_type(self): r""" Get the ITU type :type: :py:class:`str` """ return self._itu_type
[docs] def to_string(self) -> str: r""" Returns a string describing the object """ s = f"ITURadioMaterial type={self._itu_type}\n"\ f" eta_r={self._eta_r[0]:.3f}\n"\ f" sigma={self._sigma[0]:.3f}\n"\ f" thickness={self._d[0]:.3f}\n"\ f" scattering_coefficient={self._s[0]:.3f}\n"\ f" xpd_coefficient={self._kx[0]:.3f}" return s
mi.register_bsdf("itu-radio-material", lambda props: ITURadioMaterial(props=props))