tmmcore 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,26 +5,22 @@
5
5
  srcset="https://raw.githubusercontent.com/aai2k/tmmcore/main/docs/img/banner-on-dark.png">
6
6
  <img alt="tmmcore"
7
7
  src="https://raw.githubusercontent.com/aai2k/tmmcore/main/docs/img/banner-on-light.png"
8
- width="640">
8
+ width="320">
9
9
  </picture>
10
10
 
11
11
  **Transfer-matrix method for multilayer thin-film optics, with exact analytic derivatives.**
12
12
 
13
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE)
13
+ [![npm](https://img.shields.io/npm/v/tmmcore)](https://www.npmjs.com/package/tmmcore) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE)
14
+
15
+ **[Documentation](https://aai2k.github.io/tmmcore/)** · **[Getting started](https://aai2k.github.io/tmmcore/getting-started/)** · **[API](https://aai2k.github.io/tmmcore/api/)** · **[Validation](https://aai2k.github.io/tmmcore/validation/)**
14
16
 
15
17
  </div>
16
18
 
17
- Takes a stack of layers and returns reflectance, transmittance and absorptance
18
- for absorbing and dispersive materials, at any angle of incidence, in s and p
19
- polarization. Alongside the spectra it returns the exact thickness Jacobian, the
20
- exact thickness Hessian, and the needle-insertion P-function, computed
21
- analytically rather than by finite differences.
19
+ Takes a stack of layers and returns reflectance, transmittance and absorptance for absorbing and dispersive materials, at any angle of incidence, in s and p polarization. Alongside the spectra it returns the exact thickness Jacobian, the exact thickness Hessian, and the needle-insertion P-function, computed analytically rather than by finite differences.
22
20
 
23
- Ships as JavaScript, as C, and as a WebAssembly build of the C. The JavaScript
24
- has no dependencies and works on import. WebAssembly is opt-in and roughly an
25
- order of magnitude faster.
21
+ It also computes phase, group delay, GDD and third-order dispersion, by carrying the same matrix in third-order Taylor arithmetic. Those come out analytically too, so they do not depend on the wavelength grid you sampled and there is no finite-difference step to tune. Their thickness gradients come along in the same call, which is what makes chirped-mirror design a gradient problem.
26
22
 
27
- **[Documentation](https://aai2k.github.io/tmmcore/)**
23
+ Ships as JavaScript, as C, and as a WebAssembly build of the C. The JavaScript has no dependencies and works on import. WebAssembly is opt-in and roughly an order of magnitude faster.
28
24
 
29
25
  ## Install
30
26
 
@@ -56,8 +52,7 @@ Layers run from the incident medium toward the substrate.
56
52
 
57
53
  ## Conventions
58
54
 
59
- Mismatched conventions are the most common cause of two TMM codes disagreeing,
60
- so check these first.
55
+ Mismatched conventions are the most common cause of two TMM codes disagreeing, so check these first.
61
56
 
62
57
  | | |
63
58
  |---|---|
@@ -68,31 +63,27 @@ so check these first.
68
63
  | Complex numbers | `[re, im]` pairs |
69
64
  | Layer order | incident medium → substrate |
70
65
 
71
- This is the complex conjugate of Macleod's convention. R, T and A are identical
72
- under conjugation; phase-sensitive quantities are not.
66
+ This is the complex conjugate of Macleod's convention. R, T and A are identical under conjugation; phase-sensitive quantities are not.
73
67
 
74
68
  ## Verify it yourself
75
69
 
76
- Two commands, neither needing anything but Node:
70
+ Three commands, none needing anything but Node:
77
71
 
78
72
  ```bash
79
- npm test # the JavaScript and the C agree, to float64 round-off
80
- npm run compare # and both agree with an independent implementation
73
+ node examples/01-single-layer.mjs # matches the closed-form solution
74
+ npm test # the JavaScript and the C agree
75
+ npm run compare # and both agree with an independent implementation
81
76
  ```
82
77
 
83
- The first drives both implementations with identical inputs across absorbing,
84
- dispersive and oblique-incidence cases and compares every returned quantity.
85
- 64,416 comparisons, worst disagreement 4.4e-16.
78
+ The first tests the equations rather than agreement, and is the only one here that does. A single quarter-wave layer at normal incidence has an exact solution (Macleod §3.2); tmmcore reproduces it to 1.4e-17, inside double-precision epsilon of 2.2e-16.
79
+
80
+ The second drives both implementations with identical inputs across absorbing, dispersive and oblique-incidence cases and compares every returned quantity. 64,416 comparisons, worst disagreement 4.4e-16. This is two implementations by the same author, so it catches porting bugs and establishes nothing beyond that.
81
+
82
+ The third checks them against [Steven Byrnes' `tmm`](https://github.com/sbyrnes321/tmm), written independently in Python under the same complex-index convention, so only the mathematics is under test. 12,352 values, worst disagreement 8.6e-14, which is float64 accumulation noise over a forty-layer matrix product.
86
83
 
87
- The second checks them against [Steven Byrnes'
88
- `tmm`](https://github.com/sbyrnes321/tmm), written independently in Python under
89
- the same complex-index convention, so only the mathematics is under test. 12,352
90
- values, worst disagreement 8.6e-14, which is float64 accumulation noise over a
91
- forty-layer matrix product.
84
+ [Validation](https://aai2k.github.io/tmmcore/validation/) sets out what each level does and does not establish, and lists what is not tested at all.
92
85
 
93
- Timing comparisons against four other packages are in the
94
- [documentation](https://aai2k.github.io/tmmcore/comparison/), and need a Python
95
- environment.
86
+ The [comparison with four other TMM packages](https://aai2k.github.io/tmmcore/comparison/) covers accuracy as well as speed, including which of them run in single precision. Reproducing the timings needs a Python environment; the accuracy table does not.
96
87
 
97
88
  ## Documentation
98
89
 
@@ -104,8 +95,7 @@ environment.
104
95
 
105
96
  ## Using the C directly
106
97
 
107
- `src/tmm_kernel.c` is C99 with no dependencies beyond libm. Drop it into a
108
- project and compile:
98
+ `src/tmm_kernel.c` is C99 with no dependencies beyond libm. Drop it into a project and compile:
109
99
 
110
100
  ```bash
111
101
  cc -std=c99 -O2 -c src/tmm_kernel.c
@@ -115,5 +105,4 @@ cc -std=c99 -O2 -c src/tmm_kernel.c
115
105
 
116
106
  [MIT](./LICENSE) © Andrey Achapovsky
117
107
 
118
- Built for and used by [TFStudio](https://github.com/aai2k/TFStudio), an
119
- open-source optical coating design application.
108
+ Built for and used by [TFStudio](https://github.com/aai2k/TFStudio), an open-source optical coating design application.
package/package.json CHANGED
@@ -1,12 +1,14 @@
1
1
  {
2
2
  "name": "tmmcore",
3
- "version": "0.1.0",
4
- "description": "Transfer-matrix method for multilayer thin-film optics, with exact analytic derivatives. JavaScript, C and WebAssembly.",
3
+ "version": "0.3.0",
4
+ "description": "Transfer-matrix method for multilayer thin-film optics, with exact analytic derivatives and phase dispersion. JavaScript, C and WebAssembly.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
7
7
  "exports": {
8
8
  ".": "./src/index.js",
9
9
  "./tmm.js": "./src/tmm.js",
10
+ "./phase.js": "./src/phase.js",
11
+ "./taylorJet.js": "./src/taylorJet.js",
10
12
  "./tmmWasm.js": "./src/tmmWasm.js",
11
13
  "./tmm_kernel.wasm": "./src/tmm_kernel.wasm",
12
14
  "./tmm_kernel.c": "./src/tmm_kernel.c",
@@ -18,10 +20,10 @@
18
20
  "LICENSE"
19
21
  ],
20
22
  "scripts": {
21
- "test": "node tests/equivalence.mjs",
23
+ "test": "node tests/equivalence.mjs && node tests/growing_equivalence.mjs && node tests/growing_eval_equivalence.mjs",
22
24
  "compare": "node benchmarks/compare.mjs",
23
- "examples": "node examples/01-single-layer.mjs && node examples/02-ar-coating.mjs && node examples/03-metal-mirror.mjs && node examples/04-refine.mjs",
24
- "build:wasm": "emcc src/tmm_kernel.c -O3 --no-entry -sSTANDALONE_WASM=1 -sALLOW_MEMORY_GROWTH=1 -sEXPORTED_FUNCTIONS=_tmm_one,_tmm_spectrum,_tmm_jacobian,_tmm_needle_scan,_tmm_hessian,_malloc,_free -o src/tmm_kernel.wasm",
25
+ "examples": "node examples/01-single-layer.mjs && node examples/02-ar-coating.mjs && node examples/03-metal-mirror.mjs && node examples/04-refine.mjs && node examples/05-angle-map.mjs && node examples/06-needle.mjs && node examples/07-jacobian-map.mjs && node examples/08-group-delay.mjs",
26
+ "build:wasm": "emcc src/tmm_kernel.c -O3 --no-entry -sSTANDALONE_WASM=1 -sALLOW_MEMORY_GROWTH=1 -sEXPORTED_FUNCTIONS=_tmm_one,_tmm_spectrum,_tmm_jacobian,_tmm_needle_scan,_tmm_hessian,_tmm_phase_one,_tmm_phase_spectrum,_tmm_phase_jacobian,_tmm_monitor_curve,_tmm_deposition_spectra,_tmm_growing_eval_create,_tmm_growing_eval_set_top,_tmm_growing_eval_sample,_tmm_growing_eval_free,_malloc,_free -o src/tmm_kernel.wasm",
25
27
  "build:native": "cc -std=c99 -pedantic -Wall -Wextra -O2 -c src/tmm_kernel.c -o tmm_kernel.o"
26
28
  },
27
29
  "keywords": [
@@ -34,7 +36,11 @@
34
36
  "reflectance",
35
37
  "transmittance",
36
38
  "photonics",
37
- "webassembly"
39
+ "webassembly",
40
+ "group-delay",
41
+ "dispersion",
42
+ "chirped-mirror",
43
+ "ultrafast"
38
44
  ],
39
45
  "license": "MIT",
40
46
  "author": "Andrey Achapovsky",
package/src/build.ps1 CHANGED
@@ -24,7 +24,7 @@
24
24
  param([switch]$InstallEmsdk)
25
25
 
26
26
  $ErrorActionPreference = 'Stop'
27
- $root = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
27
+ $root = Split-Path -Parent $PSScriptRoot
28
28
  Set-Location $root
29
29
 
30
30
  # --- Try to activate emsdk from a known root (returns $true if emcc appears) ---
@@ -111,11 +111,17 @@ $emccArgs = @(
111
111
  '--no-entry'
112
112
  '-sSTANDALONE_WASM=1'
113
113
  '-sALLOW_MEMORY_GROWTH=1'
114
- '-sEXPORTED_FUNCTIONS=_tmm_one,_tmm_spectrum,_tmm_jacobian,_tmm_needle_scan,_tmm_hessian,_malloc,_free'
114
+ '-sEXPORTED_FUNCTIONS=_tmm_one,_tmm_spectrum,_tmm_jacobian,_tmm_needle_scan,_tmm_hessian,_tmm_phase_one,_tmm_phase_spectrum,_tmm_phase_jacobian,_tmm_monitor_curve,_tmm_deposition_spectra,_tmm_growing_eval_create,_tmm_growing_eval_set_top,_tmm_growing_eval_sample,_tmm_growing_eval_free,_malloc,_free'
115
115
  '-o'
116
116
  'src/tmm_kernel.wasm'
117
117
  )
118
118
  & emcc @emccArgs
119
+ if ($LASTEXITCODE -ne 0) { Write-Error "emcc failed with exit code $LASTEXITCODE."; exit 1 }
119
120
 
120
121
  Write-Host "Built src/tmm_kernel.wasm"
121
122
  node tests/equivalence.mjs
123
+ if ($LASTEXITCODE -ne 0) { Write-Error "equivalence tests failed with exit code $LASTEXITCODE."; exit 1 }
124
+ node tests/growing_equivalence.mjs
125
+ if ($LASTEXITCODE -ne 0) { Write-Error "growing_equivalence tests failed with exit code $LASTEXITCODE."; exit 1 }
126
+ node tests/growing_eval_equivalence.mjs
127
+ if ($LASTEXITCODE -ne 0) { Write-Error "growing_eval_equivalence tests failed with exit code $LASTEXITCODE."; exit 1 }
package/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * tmmcore transfer-matrix method for multilayer thin films.
2
+ * tmmcore : transfer-matrix method for multilayer thin films.
3
3
  *
4
4
  * Two interchangeable implementations of the same physics:
5
5
  *
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * The JavaScript path works immediately on import. WebAssembly is opt-in: load
10
10
  * the `.wasm` bytes, instantiate, and call the instance methods. Results agree
11
- * to float64 round-off either way see `tests/equivalence.mjs`.
11
+ * to float64 round-off either way : see `tests/equivalence.mjs`.
12
12
  *
13
13
  * Conventions, which matter more than anything else here:
14
14
  * ñ = n + ik k ≥ 0 for absorbing media
@@ -32,4 +32,21 @@ export {
32
32
  matmul, rescaleMatrix, snellCosTheta, layerMatrix, cmatvec,
33
33
  } from './tmm.js';
34
34
 
35
+ export {
36
+ // Phase, group delay, GDD and TOD
37
+ tmmPhaseDispersion,
38
+ tmmPhaseThicknessJacobian,
39
+ // Coefficient jets, for callers wanting r and t rather than the phase
40
+ tmmCoefficientJets,
41
+ tmmCoefficientThicknessJets,
42
+ coefficientPhaseDispersion,
43
+ coefficientPhaseThicknessDerivatives,
44
+ // Unit helpers
45
+ C_NM_PER_FS, omegaFromLambdaNm,
46
+ } from './phase.js';
47
+
48
+ // Taylor-jet arithmetic. The phase functions take refractive indices as jets;
49
+ // these compose one from any dispersion formula you can write.
50
+ export * from './taylorJet.js';
51
+
35
52
  export * from './tmmWasm.js';