MCPcopy Create free account
hub / github.com/danieljfarrell/pvtrace / Material

Class Material

pvtrace/material/material.py:10–63  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

8
9
10class Material(object):
11 def __init__(self, refractive_index: float, surface=None, components=None):
12 self.refractive_index = refractive_index
13 self.surface = Surface() if surface is None else surface
14 self.components = [] if components is None else components
15
16 # Cache this function!
17 def total_attenutation_coefficient(self, wavelength: float) -> float:
18 coefs = [x.coefficient(wavelength) for x in self.components]
19 alpha = np.sum(coefs)
20 return alpha
21
22 def is_absorbed(self, ray, full_distance) -> Tuple[bool, float]:
23 distance = self.penetration_depth(ray.wavelength)
24 return (distance < full_distance, distance)
25
26 def penetration_depth(self, wavelength: float) -> float:
27 """ Monte-Carlo sampling to find penetration depth of ray due to total
28 attenuation coefficient of the material.
29
30 Arguments
31 --------
32 wavelength: float
33 The ray wavelength in nanometers.
34
35 Returns
36 -------
37 depth: float
38 The penetration depth in centimetres or `float('inf')`.
39 """
40 alpha = self.total_attenutation_coefficient(wavelength)
41 if np.isclose(alpha, 0.0):
42 return float("inf")
43 elif not np.isfinite(alpha):
44 return 0.0
45 # Sample exponential distribution
46 depth = -np.log(1 - np.random.uniform()) / alpha
47 return depth
48
49 def component(self, wavelength: float) -> Component:
50 """ Monte-Carlo sampling to find which component captures the ray.
51 """
52 coefs = np.array([x.coefficient(wavelength) for x in self.components])
53 if np.any(coefs < 0.0):
54 raise ValueError("Must be positive.")
55 count = len(self.components)
56 bins = list(range(0, count + 1))
57 cdf = np.cumsum(coefs)
58 pdf = cdf / max(cdf)
59 pdf = np.hstack([0, pdf[:]])
60 pdfinv_lookup = np.interp(np.random.uniform(), pdf, bins)
61 index = int(np.floor(pdfinv_lookup))
62 component = self.components[index]
63 return component

Callers 12

_make_sceneMethod · 0.90
test_initMethod · 0.90
test_iorMethod · 0.90
make_embedded_sceneFunction · 0.85
make_touching_sceneFunction · 0.85
hello_world.pyFile · 0.85
hello_box.pyFile · 0.85
cylinder.pyFile · 0.85

Calls

no outgoing calls

Tested by 7

test_initMethod · 0.72
test_iorMethod · 0.72
make_embedded_sceneFunction · 0.68
make_touching_sceneFunction · 0.68