Contents of file 'magbragg/magbragg.w':
1 % File: magbragg.w [CWEB source code]
2 % Created: October 28, 2002 [v.1.0]
3 % Last change: December 18, 2011 [v.1.44]
4 % Author: Fredrik Jonsson
5 % Description: The CWEB source code for the MAGBRAGG simulator of nonlinear
6 % magneto-optical Bragg gratings. For information on the CWEB
7 % programming language, see http://www.literateprogramming.com.
8 % Compilation: Compile this program by using the enclosed Makefile, or use
9 % the blocks of the Makefile as listed in section five of the
10 % documentation (file magbragg.ps or magbragg.pdf). The C source
11 % code (as generated from this CWEB code) conforms to the ANSI
12 % standard for the C programming language (which is equivalent
13 % to the ISO C90/C99 standard for C).
14 %
15 % Copyright (C) 2002--2011, Fredrik Jonsson
16 %
17 \input epsf
18 \def\version{1.44}
19 \def\lastrevdate{January 10, 2007}
20 \font\eightcmr=cmr8
21 \font\tensc=cmcsc10
22 \font\eightcmssq=cmssq8
23 \font\eightcmssqi=cmssqi8
24 \font\twentycmcsc=cmcsc10 at 20 truept
25 \def\magbragg{{\eightcmr MAGBRAGG\spacefactor1000}}
26 \def\poincare{{\eightcmr POINCARE\spacefactor1000}}
27 \def\ANSI{{\eightcmr ANSI\spacefactor1000}} % The language standard we stick to
28 \def\SI{{\eightcmr SI\spacefactor1000}} % Another standard for physical units
29 \def\GNU{{\eightcmr GNU\spacefactor1000}} % GNU is Not Unix
30 \def\GCC{{\eightcmr GCC\spacefactor1000}} % The GNU C-compiler
31 \def\CEE{{\eightcmr C\spacefactor1000}} % The C programming language
32 \def\ANSICEE{{\eightcmr ANSI~C\spacefactor1000}}% The ANSI-C standard language
33 \def\CWEB{{\eightcmr CWEB\spacefactor1000}} % The CWEB programming language
34 \def\MATLAB{{\eightcmr MATLAB\spacefactor1000}} % The MATLAB ditto
35 \def\UNIX{{\eightcmr UNIX\spacefactor1000}}
36 \def\CYGWIN{{\eightcmr CYGWIN\spacefactor1000}}
37 \def\CTANGLE{{\eightcmr CTANGLE\spacefactor1000}}
38 \def\CWEAVE{{\eightcmr CWEAVE\spacefactor1000}}
39 \def\OSX{{OS\,X}}
40 \def\re{\mathop{\rm Re}\nolimits} % The real part of a complex number
41 \def\im{\mathop{\rm Im}\nolimits} % The imaginary part of a complex number
42 \def\dollar{\char'044} % The `$' character
43 \def\tothepower{\char'136} % The `^' character
44 \def\onehalf{{\textstyle{{1}\over{2}}}}
45 \def\threefourth{{\textstyle{{3}\over{4}}}}
46 \def\endalg{\vrule height 1.4ex width .6ex depth .4ex} % Rectangular bullet
47 \def\ie{i.\thinspace{e.}~\ignorespaces}
48 \def\eg{e.\thinspace{g.}~\ignorespaces}
49 \let\,\thinspace
50 %% \def\subsection[#1]{\goodbreak\noindent{\it #1}\par\nobreak\noindent}
51 %
52 % Define a handy macro for listing the steps of an algorithm.
53 %
54 \newdimen\aitemindent \aitemindent=26pt
55 \newdimen\aitemleftskip \aitemleftskip=36pt
56 \def\aitem[#1]{\smallbreak\noindent\hbox to 10pt{}%
57 \hbox to\aitemindent{\bf #1\hfill}%
58 \hangindent\aitemleftskip\ignorespaces}
59 %
60 % Define a handy macro for bibliographic references.
61 %
62 \newdimen\refitemindent \refitemindent=18pt
63 \def\refitem[#1]{\smallbreak\noindent%
64 \hbox to\refitemindent{[#1]\hfill}%
65 \hangindent\refitemindent\ignorespaces}
66 %
67 % Define a handy macro for nicely typeset variable descriptions.
68 %
69 \newdimen\varitemindent \varitemindent=100pt
70 \def\varitem[#1]#2{\smallbreak\noindent\hbox to 20pt{}%
71 \hbox to\varitemindent{#1\hfill}%
72 \hangindent 120pt\ignorespaces#2\par}
73 %
74 % Define a handy macro for the list of program revisions.
75 %
76 \newdimen\citemindent \citemindent=80pt
77 \newdimen\citemleftskip \citemleftskip=90pt
78 \def\citem[#1]{\smallbreak\noindent\hbox to 10pt{}%
79 \hbox to\citemindent{\bf #1\hfill}%
80 \hangindent\citemleftskip\ignorespaces}
81 \def\citindent{\smallbreak\noindent\hbox to 10pt{}%
82 \hbox to\citemindent{\hfil}%
83 \hangindent\citemleftskip\ignorespaces}
84 %
85 % Define the \beginvrulealign and \endvrulealign macros as described in
86 % Donald Knuth's The TeXbook, Appendix D: Dirty Tricks. These macros are
87 % used in typesetting nicely looking tables.
88 %
89 \def\beginvrulealign{\setbox0=\vbox\bgroup}
90 \def\endvrulealign{\egroup % now \box0 holds the entire alignment
91 \setbox0=\vbox{\setbox2=\hbox{\vrule height\ht0 depth\dp0 width0pt}
92 \unvbox0 \setbox0=\lastbox % now \box0 is the bottom row
93 \nointerlineskip \copy0 % put it back
94 \global\setbox1=\hbox{} % initialize box that will contain rules
95 \setbox4=\hbox{\unhbox0 % now open up the bottom row
96 \loop \skip0=\lastskip \unskip % remove tabskip glue
97 \advance\skip0 by-.4pt % rules are .4 pt wide
98 \divide\skip0 by 2
99 \global\setbox1=\hbox{\hskip\skip0\vrule\hskip\skip0
100 \unhbox2\unhbox1}%
101 \setbox2=\lastbox % remove alignment entry
102 \ifhbox2 \setbox2=\hbox{\kern\wd2}\repeat}}%
103 \hbox{\rlap{\box0}\box1}} % superimpose the alignment on the rules
104
105 \datethis
106
107 @*Introduction.
108 \vskip 120pt
109 \centerline{\twentycmcsc MagBragg}
110 \vskip 20pt
111 \centerline{A simulator of nonlinear magneto-optical Bragg gratings}
112 \vskip 2pt
113 \centerline{(Version \version\ of \lastrevdate)}
114 \vskip 10pt
115 \centerline{Written by Fredrik Jonsson}
116 \vskip 80pt
117 \noindent
118 This \CWEB\footnote{${}^\dagger$}{For information on the \CWEB\ programming
119 language by Donald E.~Knuth, as well as samples of \CWEB\ programs, see
120 \.{http://www-cs-faculty.stanford.edu/\~\ \kern -5pt knuth/cweb.html}.
121 For general information on literate programming, see
122 \.{http://www.literateprogramming.com}.} computer program calculates
123 reflection and transmission spectra of nonlinear magneto-optical Bragg
124 gratings, in a stratified geometry where the material parameters vary only
125 in one Cartesian coordinate.
126 The \magbragg\ program also simulates the propagation of the electromagnetic
127 field of an optical wave as it traverses a magneto-optical Bragg grating, in
128 linear as well as nonlinear optical regimes.
129
130 Strictly speaking, in a linear-optical domain a forward algorithm would just as
131 fine as a backward one; however, for nonlinear optical problems, it often (as
132 in this particular case) turns out that it is easier to compute the inverse
133 problem, that is to say, to compute the input that corresponds to a certain
134 given output. This is the case for, for example, optical bistability, where a
135 given input intensity and ellipticity of the input optical wave for certain
136 configurations correspond to a multiple-valued optical output. This means that
137 we are not always on safe ground when it comes to the evaluation of output as
138 function of input; meantime it makes perfectly sense to calculate the
139 single-valued input as function of optical output.
140 This program, in particular, is formulated in terms of the inverse problem, and
141 hence the input parameters to the program are partly given in terms of the
142 optical output of the magneto-optical Bragg grating.
143 The algorithm behind the program was published as F.~Jonsson and C.~Flytzanis,
144 Physical Review Letters {\bf 96}, 063902 (2006).
145 \bigskip
146 \noindent Copyright \copyright\ Fredrik Jonsson, 2002--2007.
147 All rights reserved.
148 \vfill
149
150 @*The CWEB programming language.
151 For the reader who might not be familiar with the concept of the
152 \CWEB\ programming language, the following citations hopefully will
153 be useful. For further information, as well as freeware compilers for
154 compiling \CWEB\ source code, see \.{http://www.literateprogramming.com}.
155 \bigskip
156
157 {\narrower\narrower\narrower\narrower\eightcmssqi\noindent
158 I believe that the time is ripe for significantly better documentation of
159 programs, and that we can best achieve this by considering programs to be
160 works of literature. Hence, my title: `Literate Programming.'
161
162 Let us change our traditional attitude to the construction of programs:
163 Instead of imagining that our main task is to instruct a computer what to
164 do, let us concentrate rather on explaining to human beings what we want
165 a computer to do.
166
167 The practitioner of literate programming can be regarded as an essayist,
168 whose main concern is with exposition and excellence of style. Such an
169 author, with thesaurus in hand, chooses the names of variables carefully
170 and explains what each variable means. He or she strives for a program
171 that is comprehensible because its concepts have been introduced in an
172 order that is best for human understanding, using a mixture of formal and
173 informal methods that reinforce each other.
174 \smallskip
175 {\eightcmssq --\,Donald Knuth,}
176 {\eightcmssqi The CWEB System of Structured Documentation}
177 {\eightcmssq (Addison-Wesley, Massachusetts, 1994)}
178 }
179 \bigskip
180
181 {\narrower\narrower\narrower\narrower\eightcmssqi\noindent
182 The philosophy behind CWEB is that an experienced system programmer, who
183 wants to provide the best possible documentation of his or her software
184 products, needs two things simultaneously: a language like \TeX\ for
185 formatting, and a language like C for programming. Neither type of language
186 can provide the best documentation by itself; but when both are appropriately
187 combined, we obtain a system that is much more useful than either language
188 separately.
189
190 The structure of a software program may be thought of as a `WEB' that is
191 made up of many interconnected pieces. To document such a program we want to
192 explain each individual part of the web and how it relates to its neighbors.
193 The typographic tools provided by \TeX\ give us an opportunity to explain the
194 local structure of each part by making that structure visible, and the
195 programming tools provided by languages like C make it possible for us to
196 specify the algorithms formally and unambiguously. By combining the two,
197 we can develop a style of programming that maximizes our ability to perceive
198 the structure of a complex piece of software, and at the same time the
199 documented programs can be mechanically translated into a working software
200 system that matches the documentation.
201
202 Besides providing a documentation tool, CWEB enhances the C language by
203 providing the ability to permute pieces of the program text, so that a
204 large system can be understood entirely in terms of small sections and
205 their local interrelationships. The CTANGLE program is so named because
206 it takes a given web and moves the sections from their web structure into
207 the order required by C; the advantage of programming in CWEB is that the
208 algorithms can be expressed in ``untangled'' form, with each section
209 explained separately. The CWEAVE program is so named because it takes a
210 given web and intertwines the \TeX\ and C portions contained in each
211 section, then it knits the whole fabric into a structured document.
212 \smallskip
213 {\eightcmssq --\,Donald Knuth, ``Literate Programming'', in}
214 {\eightcmssqi Literate Programming}
215 {\eightcmssq (CSLI Lecture Notes, Stanford, 1992)}
216 }
217
218 @*Theory of nonlinear magneto-optical Bragg gratings.
219 The algorithm used for the simulation is based on the inverse problem of
220 nonlinear optical gratings,
221 where the transmitted optical field is used as input to the algorithm,
222 which successively calculates the intra-grating optical fields backwards
223 through the structure, finally ending up with the corresponding incident field.
224 The analysis is here for the sake of simplicity restricted to infinite
225 plane waves under assumption of the slowly varying envelope approximation.
226 The conventions of notation for the discrete layers in the structure of
227 analysis are shown in Fig.~1, in which $N-1$ layers of nonlinear
228 magneto-optical media are separated by their boundaries at $z=z_1,\ldots,z_N$.
229
230 \bigskip
231 \centerline{\epsfxsize=86mm\epsfbox{figures/geom/geom.1}}\smallskip
232 {\narrower\narrower\noindent{\bf Figure 1.} The geometry of the discretized
233 model of the magneto-optical Bragg grating, in the Faraday configuration with
234 the static magnetic ${\bf B}_0=B^z_0{\bf e}_z$ applied in the direction of
235 wave propagation. The grating consists of $N$ optically homogeneous layers
236 with $N+1$ discrete interfaces located at spatial coordinates $z_k$, for
237 $k=1,2,\ldots,N$, with the optical properties of each layer described by the
238 optical susceptibility tensors $\chi^{\rm ee}_{ij}$ and
239 $\chi^{\rm eeee}_{ijkl}$ and their magneto-optical counter-parts
240 $\chi^{\rm eem}_{ijk}$ and $\chi^{\rm eeeem}_{ijklm}$.\par}
241 \bigskip
242
243 @ Discretization of the problem. In each homogeneous layer $z_k<z<z_{k+1}$,
244 $k=1,2,\ldots,N-1$, the components of the plane-parallel electromagnetic field
245 ${\bf E}(z,t)=\re[{\bf E}_{\omega}\exp(-i\omega t)]$ propagate collinearly
246 with an externally applied static magnetic field ${\bf B}_0=B^z_0{\bf e}_z$,
247 and the local constitutive relation for the electric polarization density
248 ${\bf P}(z,t)=\re[{\bf P}_{\omega}\exp(-i\omega t)]$ of the medium
249 is~[1]
250 $$
251 \eqalign{
252 {\bf P}_{\omega}=\varepsilon_0[&\chi^{{\rm ee}}_{xx} {\bf E}_{\omega}
253 +\chi^{{\rm eem}}_{xyz} {\bf E}_{\omega}\times{\bf B}_0\cr
254 &+(\chi^{{\rm eeee}}_{xxxx}-\chi^{{\rm eeee}}_{xyyx})
255 ({\bf E}_{\omega}\cdot{\bf E}^*_{\omega}){\bf E}_{\omega}
256 +\chi^{{\rm eeee}}_{xyyx}
257 ({\bf E}_{\omega}\cdot{\bf E}_{\omega}){\bf E}^*_{\omega}\cr
258 &+\chi^{{\rm eeeem}}_{xyyyz}
259 ({\bf E}_{\omega}\cdot{\bf E}^*_{\omega}){\bf E}_{\omega}\times{\bf B}_0
260 +\chi^{{\rm eeeem}}_{xxxyz}{\bf E}_{\omega}
261 ({\bf E}_{\omega}\cdot({\bf E}^*_{\omega}\times{\bf B}_0))].\cr
262 }
263 \eqno{(1)}
264 $$
265 In this expression, the spatial dependence of the fields and susceptibilities
266 is omitted in notation, as is also any slow temporal variation of the fields;
267 from now on each appearance of a field or susceptibility implicitly implies
268 evaluation in respective layer of context. In each layer, the envelope of the
269 electromagnetic field satisfies the autonomous nonlinear wave equation
270 $$
271 {{\partial^2{\bf E}_{\omega}}\over{\partial z^2}}
272 +(\omega/c)^2{\bf E}_{\omega}
273 =-\mu_0\omega^2{\bf P}_{\omega}.
274 \eqno{(2)}
275 $$
276 The field is in each layer expressed in a circularly polarized basis
277 ${\bf e}_{\pm}=({\bf e}_x \pm i{\bf e}_y)/\sqrt{2}$, with forward and
278 backward traveling modes as a superposition
279 $$
280 \eqalign{
281 {\bf E}_{\omega}&=
282 [{\bf e}_+ E^{\rm f}_{k_+}(z) + {\bf e}_- E^{\rm f}_{k_-}(z)]
283 \exp[i\omega n_k (z-z_k)/c]\cr
284 &\qquad+[{\bf e}^*_+ E^{\rm b}_{k_+}(z) + {\bf e}^*_- E^{\rm b}_{k_-}(z)]
285 \exp[-i\omega n_k (z-z_k)/c],\cr
286 }
287 \eqno{(3)}
288 $$
289 where $n_k=(1+\chi^{{\rm ee}}_{xx})^{1/2}$ are the linear refractive indices
290 of the layers.
291 We here adopt to the convention of circularly polarized field components
292 that when looking into the oncoming wave, a left circularly polarized wave
293 will have its vector of the electric field rotating with counterclockwise
294 motion, while the corresponding vector of a right circularly polarized field
295 will describe clockwise motion.
296 This convention applies irregardless of whether we are looking into a forward
297 propagating wave, that is to say looking in the negative $z$-direction, or
298 looking into a backward propagating wave, in which case we instead look in the
299 positive $z$-direction, along the $z$-axis. This convention conforms to the
300 classical one as commonly used in optics~[5].
301 Throughout this program, the notation $E^{\rm f}_{k_{\pm}}(z)$ is used to
302 denote the left/right circularly polarized components of the forward traveling
303 component of the electric field in the $k$th homogeneous layer, while
304 $E^{\rm b}_{k_{\pm}}(z)$ in an analogous manner is used to denote the
305 left/right circularly polarized components of the backward traveling component
306 of the electric field, taking into account the previously described convention
307 for circular polarization states.
308
309 @ General solutions in the homogeneous layers.
310 By inserting the form of the electric field as given by Eq.~(3) into the wave
311 equation as given by Eq.~(1) under the constitutive relation given by Eq.~(1)
312 and furthermore applying the slowly varying envelope approximation, the general
313 solutions for the field components in loss-less media become~[1]
314 $$
315 \eqalignno{
316 E^{\rm f}_{k_{\pm}}&=A^{\rm f}_{k_{\pm}}\exp[i(\omega/c)
317 (\eta^{\rm f}_{k_{\pm}}\pm g_k)(z-z_k)+i\psi^{\rm f}_{k_{\pm}}],
318 &(4{\rm a})\cr
319 E^{\rm b}_{k_{\pm}}&=A^{\rm b}_{k_{\pm}}\exp[-i(\omega/c)
320 (\eta^{\rm b}_{k_{\pm}}\mp g_k)(z-z_k)+i\psi^{\rm b}_{k_{\pm}}].
321 &(4{\rm b})\cr
322 }
323 $$
324 In these expressions $A^{\rm f,b}_{k_{\pm}}$ and $\psi^{\rm f,b}_{k_{\pm}}$
325 are real constants of integration, determined by the boundary conditions of
326 the $k$th layer, and $g_k=i\chi^{{\rm eem}}_{xyz}B^z_0/(2n_k)$ are the real
327 linear magneto-optical gyration coefficients.
328 In Eqs.~(4) the nonlinear optical and magneto-optical light-matter
329 interactions are described by the field-dependent parameters
330 $$
331 \eqalignno{
332 \eta^{\rm f}_{k_{\pm}}&=
333 p_{k_{\pm}}(A^{{\rm f}\,2}_{k_{\pm}}+2A^{{\rm b}\,2}_{k_{\mp}})
334 +q_{k_{\pm}}(A^{{\rm f}\,2}_{k_{\mp}}+A^{{\rm b}\,2}_{k_{\pm}}),
335 &(5{\rm b})\cr
336 \eta^{\rm b}_{k_{\pm}}&=
337 p_{k_{\mp}}(A^{{\rm b}\,2}_{k_{\pm}}+2A^{{\rm f}\,2}_{k_{\mp}})
338 +q_{k_{\mp}}(A^{{\rm b}\,2}_{k_{\mp}}+A^{{\rm f}\,2}_{k_{\pm}}),
339 &(5{\rm b})\cr
340 }
341 $$
342 where the coefficients $p_{k_{\pm}}$ and $q_{k_{\pm}}$ in the nonlinear
343 susceptibility formalism~[3] are expressed as
344 $$
345 \eqalignno{
346 p_{k_{\pm}}&=
347 {{3}\over{8n_k}}[\chi^{{\rm eeee}}_{xxxx}-\chi^{{\rm eeee}}_{xyyx}
348 \pm i(\chi^{{\rm eeeem}}_{xyyyz}-\chi^{{\rm eeeem}}_{xxxyz})B^z_0],
349 &(6{\rm b})\cr
350 q_{k_{\pm}}&=
351 {{3}\over{8n_k}}[\chi^{{\rm eeee}}_{xxxx}+\chi^{{\rm eeee}}_{xyyx}
352 \pm i(\chi^{{\rm eeeem}}_{xyyyz}+\chi^{{\rm eeeem}}_{xxxyz})B^z_0].
353 &(6{\rm b})\cr
354 }
355 $$
356
357 %\centerline{\epsfxsize=86mm\epsfbox{figures/geom/geom.2}}\smallskip
358 %{\narrower\narrower\noindent{\bf Figure 2.} Closeup of the geometry of the
359 %discretized model of the magneto-optical Bragg grating, illustrating the
360 %convention of notation for the electric field of the optical wave taken
361 %immediately to the left and right of the layer interfaces $z_k$.\par}
362
363 @ Rotation of the polarization state across the homogeneous layers.
364 The angle of rotation $\vartheta_k$ of the polarization ellipse of the
365 forward traveling components around the $z$-axis in each layer is then
366 $$
367 \eqalign{
368 \vartheta_k&={{\omega (z-z_k)}\over{2 n_k c}}[-i\chi^{{\rm eem}}_{xyz} B^z_0
369 +(3/4)\chi^{{\rm eeee}}_{xyyx}(A^{{\rm f}\,2}_{k_+}-A^{{\rm f}\,2}_{k_-})
370 %\cr&\quad
371 +(3/8)(\chi^{{\rm eeee}}_{xxxx}-3\chi^{{\rm eeee}}_{xyyx})
372 (A^{{\rm b}\,2}_{k_+}-A^{{\rm b}\,2}_{k_-})
373 \cr&\quad
374 %\cr&\quad
375 -(3/4)i\chi^{{\rm eeeem}}_{xyyyz}
376 (A^{{\rm f}\,2}_{k_+}+A^{{\rm f}\,2}_{k_-}) B^z_0
377 +(3/8)i(\chi^{{\rm eeeem}}_{xxxyz}-3\chi^{{\rm eeeem}}_{xyyyz})
378 (A^{{\rm b}\,2}_{k_+}+A^{{\rm b}\,2}_{k_-}) B^z_0].
379 }
380 \eqno{(7)}
381 $$ % (Equation counterchecked to be OK July 29, 2004.)
382 The first term in this expression describes linear Faraday rotation~[4] and
383 leads to an effective Zeeman-like polarization state splitting of the doubly
384 degenerate Bragg resonances. The second and third terms arise from optical
385 Kerr-effect and lead to photo-induced modification of the ellipse rotation for
386 forward and backward propagating waves respectively. Referring to the wave
387 equation given by Eqs.~(1)--(2) these terms effectively act as to give
388 photo-induced Stark-like shifts of the split Bragg resonances.
389 Finally the fourth and fifth terms describe photo-induced magneto-optic
390 Faraday rotation or equivalently photoinduced modification of the effective
391 Zeeman-like splitting of the Bragg resonances. We note by passing that the
392 third and fifth terms vanish whenever Kleinman symmetry~[3] holds.
393 Moreover, from Eq.~(7) one obtains the Verdet coefficient~$V$ of the medium as
394 $$
395 V={{\omega\im[\chi^{{\rm eem}}_{xyz}]}\over{2 n_k c}},
396 \eqno{(8)}
397 $$
398 describing the Faraday rotation angle per propagation length and static
399 magnetic field intensity.
400
401 @ Boundary conditions at the discrete interfaces. By neglecting any nonlinear
402 effects at the discrete interfaces between the homogeneous layers, the
403 continuity requirement of the transverse electromagnetic field across each
404 interface is formulated by the boundary conditions
405 $$
406 \eqalignno{
407 &E^{\rm f}_{k_{\pm}}(z_k)=
408 \tau_{k_{\pm}} E^{\rm f}_{{k-1}_{\pm}}(z_k)
409 \exp(i \omega n_{k-1} d_{k-1}/c)
410 +\rho'_{k_{\mp}} E^{\rm b}_{k_{\mp}}(z_k),&(9{\rm a})\cr
411 &E^{\rm b}_{k_{\mp}}(z_{k+1}) \exp(-i \omega n_k d_k/c)
412 =\tau'_{{k+1}_{\mp}} E^{\rm b}_{{k+1}_{\mp}}(z_{k+1})
413 +\rho_{{k+1}_{\pm}} E^{\rm f}_{k_{\pm}}(z_{k+1})
414 \exp(i \omega n_k d_k/c),&(9{\rm b})\cr
415 }
416 $$
417 for $k=1,2,\ldots,N-1$, where $d_k=z_{k+1}-z_k$ are the layer thicknesses,
418 and where
419 $$
420 \eqalignno{
421 \rho_{k_{\pm}}
422 &={{n_{k-1}-n_k\pm(g_{k-1}-g_k)}\over{n_{k-1}+n_k\pm(g_{k-1}+g_k)}}
423 =-\rho'_{k_{\mp}},
424 &(10{\rm a})\cr
425 \tau_{k_{\pm}}
426 &={{2(n_{k-1}\pm g_{k-1})}\over{n_{k-1}+n_k\pm (g_{k-1}+g_k)}},
427 &(10{\rm b})\cr
428 \tau'_{k_{\mp}}
429 &={{2(n_{k}\pm g_{k})}\over{n_{k-1}+n_k\pm (g_{k-1}+g_k)}},
430 &(10{\rm c})\cr
431 }
432 $$
433 are the reflection and transmission coefficients at the interfaces, with primed
434 coefficients relating to the backward travelling field components, and with all
435 coefficients including linear magneto-optical effects.
436 The reflection and transmission coefficients obey the Stokes relation
437 $$
438 \tau_{k_{\pm}}=(1-\rho^2_{k_{\pm}})/\tau'_{k_{\mp}},
439 $$
440 reflecting the polarization state dependence of the boundary conditions at the
441 layer interfaces.
442 This linear approximation of the boundary conditions can be assumed to hold
443 whenever processes such as the optical Kerr-effect gives a contribution to the
444 electric polarization density which is small compared to the one given by the
445 linear polarizability of the medium, or equivalently whenever the nonlinear
446 index of refraction is small compared to the linear one, which for a linearly
447 polarized optical wave can be formulated as the condition
448 $$
449 (3/4)\chi^{\rm eeee}_{xxxx}\vert E^x_{\omega}\vert^2
450 \ll 1+\chi^{\rm ee}_{xx}.
451 $$
452
453 @ Solving the equations of motion for the inverse problem of transmission.
454 In order to solve Eqs.~(4) and~(9) for the relation between incident ($k=0$)
455 and transmitted ($k=N$) fields, we impose the additional boundary condition
456 that the backward propagating field is zero at the exit end of the grating.
457 By iteratively using Eqs.~(9) and~(4) in the order $k=N-1,N-2,\ldots,1$,
458 consecutively solving for lower-indexed electric fields, we obtain an
459 algorithm for solving the inverse problem, calculating the incident and
460 reflected optical fields corresponding to a transmitted optical field.
461 This algorithm is explicitly described in Section~10, {\sl The algorithm of
462 computation}.
463
464 @ Interpretation of the solution in terms of the Stokes parameters.
465 The evolution of the optical field is conveniently expressed in terms of the
466 Stokes parameters~[5], which for the input light are taken as
467 $$
468 \eqalignno{
469 S_0&=\vert E^{\rm f}_{0_+}\vert^2+\vert E^{\rm f}_{0_-}\vert^2,\qquad
470 S_1=2\re[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}],&(11{\rm a,b})\cr
471 S_3&=\vert E^{\rm f}_{0_+}\vert^2-\vert E^{\rm f}_{0_-}\vert^2,\qquad
472 S_2=2\im[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}].&(11{\rm c,d})\cr
473 }
474 $$
475 The parameter $S_0$ is a measure of the intensity of the wave, and $S_3$ a
476 measure of the ellipticity of the polarization state, while the parameters
477 $S_1$ and $S_2$ indicate the amount of power contained in the $x$- and
478 $y$-directions, serving as to determine the orientation of the polarization
479 ellipse. Similarly, the Stokes parameters for the transmitted light are taken
480 as
481 $$
482 \eqalignno{
483 W_0&=\vert E^{\rm f}_{N_+}\vert^2+\vert E^{\rm f}_{N_-}\vert^2,\qquad
484 W_1=2\re[E^{{\rm f}*}_{N_+}E^{\rm f}_{N_-}],&(12{\rm a,b})\cr
485 W_3&=\vert E^{\rm f}_{N_+}\vert^2-\vert E^{\rm f}_{N_-}\vert^2,\qquad
486 W_2=2\im[E^{{\rm f}*}_{N_+}E^{\rm f}_{N_-}],&(12{\rm c,d})\cr
487 }
488 $$
489 and for the reflected light
490 $$
491 \eqalignno{
492 V_0&=\vert E^{\rm b}_{0_+}\vert^2+\vert E^{\rm b}_{0_-}\vert^2,\qquad
493 V_1=2\re[E^{{\rm b}*}_{0_+}E^{\rm b}_{0_-}],&(13{\rm a,b})\cr
494 V_3&=\vert E^{\rm b}_{0_+}\vert^2-\vert E^{\rm b}_{0_-}\vert^2,\qquad
495 V_2=2\im[E^{{\rm b}*}_{0_+}E^{\rm b}_{0_-}].&(13{\rm c,d})\cr
496 }
497 $$
498 In terms of $S_0$ and $W_0$, the incident, transmitted, and reflected
499 intensities in \SI\ units are $I_{\rm in}=\varepsilon_0 c S_0/2$,
500 $I_{\rm tr}=\varepsilon_0 c W_0/2$, and $I_{\rm re}=\varepsilon_0 c V_0/2$,
501 respectively.
502 These respective sets of Stokes parameters can be combined to form the reduced
503 Stokes vectors
504 $$
505 {\bf s}=(S_1,S_2,S_3)/S_0,\qquad
506 {\bf w}=(W_1,W_2,W_3)/W_0,\qquad
507 {\bf v}=(V_1,V_2,V_3)/V_0,
508 $$
509 which map the polarization states of the respective incident, transmitted, and
510 reflected light onto the unitary Poincar\'e sphere, with
511 $\vert{\bf s}\vert=\vert{\bf w}\vert=\vert{\bf v}\vert=1$,
512 as schematically illustrated in Fig.~2.
513 \bigskip
514 \centerline{\epsfxsize=122mm\epsfbox{figures/stoke/stoke.1}}\smallskip
515 {\narrower\narrower\noindent{\bf Figure 2.} The unitary Poincar\'e sphere, on
516 which the normalized Stokes vectors ${\bf s}=(S_1,S_2,S_3)/S_0$,
517 ${\bf w}=(W_1,W_2,W_3)/W_0$, or ${\bf v}=(V_1,V_2,V_3)/V_0$ provide
518 representations of the polarization state of the light. The auxiliary figures
519 show the paths traversed by the end point of the electric field vector as the
520 observer looks into an oncoming wave propagating in the positive $z$-direction.
521 At the upper pole of the sphere the light is left circularly polarized (LCP),
522 while it at the lower pole is right circularly polarized (RCP), with the
523 latitude there in between determining the ellipticity of the polarization
524 state.
525 At the equator, linearly polarized states of the light are represented, and
526 their orientations are determined by the meridian. The figure was adopted from
527 Ref.~[9].\par}
528 \bigskip
529 \noindent
530 The described algorithm of calculation as described by iteratively using
531 Eqs.~(4)--(9) can be applied to a wide range of magneto-optical gratings,
532 singly or multiply periodic, chirped, or even random without appreciable
533 complication, by employing a spatial oversampling of the continuous grating
534 profiles in terms of thin layers, so as to provide an efficient finite
535 difference scheme of computation.
536 Examples of computations performed on magneto-optical structures of continuous
537 spatial distribution of the optical and magneto-optical parameters can be found
538 in Refs.[6--8]
539
540 @*The algorithm of computation. With the theory outlined we are now in position
541 to explicitly describe the algorithm of computation of the transmission and
542 reflection properties of the grating, as obtained by
543 iteratively using Eqs.~(9) and~(4) in the order $k=N-1,N-2,\ldots,1$,
544 consecutively solving for lower-indexed electric fields.
545 This algorithm follows the one as described in Ref.~[2].
546
547 \medskip
548 \noindent{\bf Algorithm A}
549 ({\it Calculation of amplitude reflection and transmission spectra}).
550 The notation of geometry as used in the algorithm as here described refers to
551 Fig.~1.
552 Let ${E^{\rm f}_{N_{\pm}}(z_N)}$ be the complex-valued output optical
553 field from the grating structure, as taken a coordinate $z=z^+_N$ immediately
554 to the positive of the last interface $z_N$.
555 The magneto-optical grating structure is described by the material
556 parameters $n_k$, $g_k$, $p^{(k)}_{\pm}$, and
557 $q^{(k)}_{\pm}$, which all are constant within each homogeneous
558 layer $z_k\le z\le z_{k+1}$, $k=1,2,\ldots,N-1$.
559 The optical fields in the respective homogeneous layers are denoted as
560 ${E^{\rm f}_{k_{\pm}}(z)}$, for $z_k\le z\le z_{k+1}$, $k=1,2,\ldots,N-1$.
561
562 \aitem[{\bf A1.}][Set boundary condition.]
563 Apply the boundary condition $E^{\rm b}_{N_{\mp}}(z_N)=0$, that is to say,
564 that the backward propagating field is zero after the end of the grating.
565
566 \aitem[{\bf A2.}]{[Initialize forward field in layer $N-1$.]
567 Using Eq.~(9a) for $k=N$ and furthermore applying the boundary condition in
568 step A1 of the algorithm, set
569 $$
570 E^{\rm f}_{{N-1}_{\pm}}(z_N)\leftarrow
571 [E^{\rm f}_{N_{\pm}}(z_N)/\tau_{{N}_{\pm}}]
572 \exp[-i\omega n_{N-1}(z_N-z_{N-1})/c],
573 $$
574 where $\tau_{{N}_{\pm}}$ is the transmission coefficient as obtained from
575 Eq.~(10b).
576 }
577
578 \aitem[{\bf A3.}]{[Initialize backward field in layer $N-1$.]
579 Using Eq.~(9b) for $k=N-1$ and furthermore applying the boundary condition
580 from A1 and the field calculated in A2, set
581 $$
582 E^{\rm b}_{{N-1}_{\mp}}(z_N)\leftarrow
583 \rho_{{(N)}_{\pm}} E^{\rm f}_{{N-1}_{\pm}}(z_N)
584 \exp[2i\omega n_{N-1}(z_N-z_{N-1})/c],
585 $$
586 where $\rho_{{(N)}_{\pm}}$ is the reflection coefficient as obtained from
587 Eq.~(10a).
588 }
589
590 \aitem[{\bf A4.}]{[Initialize layer counter $k$.]
591 Set $k\leftarrow N-1$. This is the counter which we use to keep track of
592 the layers of the grating structure as this is traversed backwards, from the
593 last layer $(k=N-1)$ towards the first one $(k=1)$.
594 }
595
596 \aitem[{\bf A5.}]{[Calculate propagation constants in the $k$th layer.]
597 For a lossless medium the magnitudes of the circularly polarized field
598 components are left invariant under propagation over a homogeneous layer,
599 $$
600 \vert E^{\rm f,b}_{k_{\pm}}(z_k)\vert
601 =\vert E^{\rm f,b}_{k_{\pm}}(z_{k+1})\vert;
602 $$
603 and hence the field-dependent propagation constants $\eta^{\rm f}_{k_{\pm}}$
604 and $\eta^{\rm b}_{k_{\pm}}$ of the layer $z^+_k\le z \le z^-_{k+1}$ are
605 calculated using Eqs.~(5) as
606 $$
607 \eqalign{
608 \eta^{\rm f}_{k_{\pm}}&\leftarrow
609 p^{(k)}_{\pm}[\vert E^{\rm f}_{k_{\pm}}(z_{k+1})\vert^2
610 +2\vert E^{\rm b}_{k_{\mp}}(z_{k+1})\vert^2]
611 +q^{(k)}_{\pm}[\vert E^{\rm f}_{k_{\mp}}(z_{k+1})\vert^2
612 +\vert E^{\rm b}_{k_{\pm}}(z_{k+1})\vert^2],\cr
613 \eta^{\rm b}_{k_{\pm}}&\leftarrow
614 p^{(k)}_{\mp}[\vert E^{\rm b}_{k_{\pm}}(z_{k+1})\vert^2
615 +2\vert E^{\rm f}_{k_{\mp}}(z_{k+1})\vert^2]
616 +q^{(k)}_{\mp}[\vert E^{\rm b}_{k_{\mp}}(z_{k+1})\vert^2
617 +\vert E^{\rm f}_{k_{\pm}}(z_{k+1})\vert^2].\cr
618 }
619 $$
620 }
621
622 \aitem[{\bf A6.}]{[Propagate fields over the $k$th layer.]
623 From the obtained complex-valued fields $E^{\rm f}_{k_{\pm}}(z_{k+1})$
624 and $E^{\rm b}_{k_{\mp}}(z_{k+1})$, calculate the corresponding
625 fields at the beginning $z=z^+_k$ of the $k$th layer by using Eqs.~(4),
626 that is to say, set
627 $$
628 \eqalign{
629 A^{\rm f}_{k_{\pm}}&\leftarrow
630 \vert E^{\rm f}_{k_{\pm}}(z_{k+1})\vert,\cr
631 A^{\rm b}_{k_{\pm}}&\leftarrow
632 \vert E^{\rm b}_{k_{\pm}}(z_{k+1})\vert,\cr
633 \psi^{\rm f}_{k_{\pm}}&\leftarrow
634 \arg[E^{\rm f}_{k_{\pm}}(z_{k+1})]
635 -\omega (\eta^{\rm f}_{k_{\pm}}\pm g_k)(z_{k+1}-z_k)/c,\cr
636 \psi^{\rm b}_{k_{\pm}}&\leftarrow
637 \arg[E^{\rm b}_{k_{\pm}}(z_{k+1})]
638 +\omega (\eta^{\rm b}_{k_{\pm}}\mp g_k)(z_{k+1}-z_k)/c,\cr
639 }
640 $$
641 and construct the fields $E^{\rm f}_{k_{\pm}}(z_k)$ and
642 $E^{\rm b}_{k_{\pm}}(z_k)$ (taken immediately to the positive of $z_k$ in
643 the $k$th layer) as
644 $$
645 \eqalign{
646 E^{\rm f}_{k_{\pm}}(z_k)&\leftarrow
647 A^{\rm f}_{k_{\pm}}\exp(i\psi^{\rm f}_{k_{\pm}}),\cr
648 E^{\rm b}_{k_{\pm}}(z_k)&\leftarrow
649 A^{\rm b}_{k_{\pm}}\exp(i\psi^{\rm b}_{k_{\pm}}).
650 }
651 $$
652 }
653
654 \aitem[{\bf A7.}]{[Check if the whole grating structure is traversed.]
655 If the whole grating is traversed, that is to say if the layer counter has
656 reached $k=1$, then proceed to A11; otherwise continue with A8.
657 }
658
659 \aitem[{\bf A8.}]{[Propagate forward traveling field components over interface
660 located at $z=z_k$.]
661 From the obtained complex-valued optical fields $E^{\rm f}_{k_{\pm}}(z_k)$
662 and $E^{\rm b}_{k_{\mp}}(z_k)$, use Eq.~(9a) to calculate the corresponding
663 forward propagating field at the negative side of the interface, at
664 $z=z^-_k$, that is to say, set
665 $$
666 \eqalign{
667 E^{\rm f}_{{k-1}_{\pm}}(z_k)&\leftarrow[E^{\rm f}_{k_{\pm}}(z_k)
668 -\rho'_{{k}_{\mp}} E^{\rm b}_{k_{\mp}}(z_k)]
669 \exp[-i \omega n_{k-1}(z_k-z_{k-1})/c]/\tau^{(k)}_{\pm}.
670 }
671 $$
672 }
673
674 \aitem[{\bf A9.}]{[Propagate backward traveling field components over interface
675 located at $z=z_k$.]
676 From the obtained complex-valued optical fields $E^{\rm f}_{k_{\pm}}(z_k)$
677 and $E^{\rm b}_{k_{\mp}}(z_k)$, use Eq.~(9b) to calculate the corresponding
678 backward propagating field at the negative side of the interface, at
679 $z=z^-_k$, that is to say, set
680 $$
681 \eqalign{
682 &E^{\rm b}_{{k-1}_{\mp}}(z_k)\leftarrow
683 \tau^{(k)}_{\mp}{}' E^{\rm b}_{k_{\mp}}(z_k)
684 \exp[i \omega n_{k-1}(z_k-z_{k-1})/c]
685 +\rho^{(k)}_{\pm} E^{\rm f}_{{k-1}_{\pm}}(z_k)
686 \exp[2i \omega n_{k-1}(z_k-z_{k-1})/c].
687 }
688 $$
689 }
690
691 \aitem[{\bf A10.}]{[Decrease layer counter.]
692 Set $k\leftarrow k-1$ and return to A5.
693 }
694
695 \aitem[{\bf A11.}]{[Calculate input optical field.]
696 From the obtained forward and backward propagating optical fields in the
697 first ($k=1$) layer of the grating, calculate the corresponding input
698 (forward propagating) field, that is to say, set
699 $$
700 E^{\rm f}_{0_{\pm}}(z_1)\leftarrow
701 [E^{\rm f}_{1_{\pm}}(z_1)-\rho^{(1)}_{\mp}{}'E^{\rm b}_{1_{\mp}}(z_1)]
702 /\tau^{(1)}_{\pm}.
703 $$
704 }
705
706 \aitem[{\bf A12.}]{[Calculate reflected optical field.]
707 From the obtained forward and backward propagating optical fields in the
708 first ($k=1$) layer of the grating, and by using the calculated input optical
709 field of A11, calculate the reflected optical field at the beginning of the
710 grating, that is to say, set
711 $$
712 E^{\rm b}_{0_{\mp}}(z_1)\leftarrow
713 \tau^{(1)}_{\mp}{}' E^{\rm b}_{1_{\mp}}(z_1)
714 +\rho^{(1)}_{\pm} E^{\rm f}_{0_{\pm}}(z_1).
715 $$
716 }
717
718 \aitem[{\bf A13.}]{[Calculate reflection and transmission coefficients.]
719 Calculate any overall properties of the grating, such as the (intensity
720 and polarization-state dependent) reflection and transmission
721 $$
722 \eqalign{
723 R(\omega)&\leftarrow
724 {{\vert E^{\rm b}_{0_+}(z_1)\vert^2+\vert E^{\rm b}_{0_-}(z_1)\vert^2}
725 \over
726 {\vert E^{\rm f}_{0_+}(z_1)\vert^2+\vert E^{\rm f}_{0_-}(z_1)\vert^2}},
727 %\cr
728 \qquad
729 T(\omega)\leftarrow
730 {{\vert E^{\rm f}_{N_+}(z_N)\vert^2+\vert E^{\rm f}_{N_-}(z_N)\vert^2}
731 \over
732 {\vert E^{\rm f}_{0_+}(z_1)\vert^2+\vert E^{\rm f}_{0_-}(z_1)\vert^2}},\cr
733 }
734 $$
735 and terminate the algorithm.\quad\endalg}
736
737 @*The Butcher and Cotter convention.
738 As a ``recipe'' for the degeneracy factors in theoretical nonlinear optics,
739 Butcher and Cotter~[10] provide a very useful convention which is well worth
740 holding on to.
741 For a superposition of monochromatic waves, and by invoking the general
742 property of the intrinsic permutation symmetry, the monochromatic
743 form of the $n$th order polarization density can be written as
744 $$
745 (P^{(n)}_{\omega_{\sigma}})_{\mu}
746 =\varepsilon_0\sum_{\alpha_1}\cdots\sum_{\alpha_n}\sum_{\omega}
747 K(-\omega_{\sigma};\omega_1,\ldots,\omega_n)
748 \chi^{(n)}_{\mu\alpha_1\cdots\alpha_n}
749 (-\omega_{\sigma};\omega_1,\ldots,\omega_n)
750 (E_{\omega_1})_{\alpha_1}\cdots(E_{\omega_n})_{\alpha_n}.
751 \eqno{(14)}
752 $$
753 The first summations in Eq.~(14), over $\alpha_1,\ldots,\alpha_n$,
754 is simply an explicit way of stating that the Einstein convention
755 of summation over repeated indices holds.
756 The summation sign $\sum_{\omega}$, however, serves as a reminder
757 that the expression that follows is to be summed over
758 {\sl all distinct sets of $\omega_1,\ldots,\omega_n$}.
759 Because of the intrinsic permutation symmetry, the frequency arguments
760 appearing in Eq.~(14) may be written in arbitrary order.
761
762 By ``all distinct sets of $\omega_1,\ldots,\omega_n$'', we here mean
763 that the summation is to be performed, as for example in the case of
764 optical Kerr-effect, over the single set of nonlinear susceptibilities
765 that contribute to a certain angular frequency as
766 $(-\omega;\omega,\omega,-\omega)$ {\sl or} $(-\omega;\omega,-\omega,\omega)$
767 {\sl or} $(-\omega;-\omega,\omega,\omega)$.
768 In this example, each of the combinations are considered as {\sl distinct},
769 and it is left as an arbitary choice which one of these sets that are
770 most convenient to use (this is simply a matter of choosing notation,
771 and does not by any means change the description of the interaction).
772
773 In Eq.~(14), the degeneracy factor $K$ is formally described as
774 $$K(-\omega_{\sigma};\omega_1,\ldots,\omega_n)=2^{l+m-n}p$$
775 where
776 $$
777 \eqalign{
778 p&={\rm the\ number\ of\ {\sl distinct}\ permutations\ of}
779 \ \omega_1,\omega_2,\ldots,\omega_1,\cr
780 n&={\rm the\ order\ of\ the\ nonlinearity},\cr
781 m&={\rm the\ number\ of\ angular\ frequencies}\ \omega_k
782 \ {\rm that\ are\ zero,\ and}\cr
783 l&=\bigg\lbrace\matrix{1,\qquad{\rm if}\ \omega_{\sigma}\ne 0,\cr
784 0,\qquad{\rm otherwise}.}\cr
785 }
786 $$
787 In other words, $m$ is the number of DC electric fields present, and $l=0$ if
788 the nonlinearity we are analyzing gives a static, or DC, polarization density,
789 such as in the previously (in the spring model) described case of optical
790 rectification in the presence of second harmonic fields (SHG).
791
792 A list of frequently encountered nonlinear phenomena in nonlinear optics,
793 including the degeneracy factors as conforming to the above convention, is
794 given by Butcher and Cotter~[10], Table 2.1.
795
796 @ Note on the complex representation of the optical field.
797 Since the observable electric field of the light, in Butcher and
798 Cotters notation taken as
799 $$
800 {\bf E}({\bf r},t)={{1}\over{2}}\sum_{\omega_k\ge 0}
801 [{\bf E}_{\omega_k}\exp(-i\omega_k t)+{\bf E}^*_{\omega_k}\exp(i\omega_k t)],
802 $$
803 is a real-valued quantity, it follows that negative frequencies in the
804 complex notation should be interpreted as the complex conjugate of the
805 respective field component, or
806 $$
807 {\bf E}_{-\omega_k}={\bf E}^*_{\omega_k}.
808 $$
809
810 @ Example of degeneracy factor: The Optical Kerr-effect.
811 Assume a monochromatic optical wave (containing forward and/or backward
812 propagating components) polarized in the $xy$-plane,
813 $$
814 {\bf E}(z,t)=\re[{\bf E}_{\omega}(z)\exp(-i\omega t)]\in{\bf R}^3,
815 $$
816 with all spatial variation of the field contained in
817 $$
818 {\bf E}_{\omega}(z)={\bf e}_x E^x_{\omega}(z)
819 +{\bf e}_y E^y_{\omega}(z)\in{\bf C}^3.
820 $$
821 Optical Kerr-effect is in isotropic media described by the third order
822 susceptibility
823 $$
824 \chi^{(3)}_{\mu\alpha\beta\gamma}(-\omega;\omega,\omega,-\omega),
825 $$
826 with nonzero components of interest for the $xy$-polarized beam given in
827 Appendix 3.3 of Butcher and Cotters book as
828 $$
829 \chi^{(3)}_{xxxx}=\chi^{(3)}_{yyyy},\quad
830 \chi^{(3)}_{xxyy}=\chi^{(3)}_{yyxx}
831 =\bigg\{\matrix{{\rm intr.\ perm.\ symm.}\cr
832 (\alpha,\omega)\rightleftharpoons(\beta,\omega)\cr}\bigg\}=
833 \chi^{(3)}_{xyxy}=\chi^{(3)}_{yxyx},\quad
834 \chi^{(3)}_{xyyx}=\chi^{(3)}_{yxxy},
835 $$
836 with
837 $$
838 \chi^{(3)}_{xxxx}=\chi^{(3)}_{xxyy}+\chi^{(3)}_{xyxy}+\chi^{(3)}_{xyyx}.
839 $$
840 The degeneracy factor $K(-\omega;\omega,\omega,-\omega)$ is calculated as
841 $$
842 K(-\omega;\omega,\omega,-\omega)=2^{l+m-n}p=2^{1+0-3}3=3/4.
843 $$
844 From this set of nonzero susceptibilities, and using the calculated
845 value of the degeneracy factor in the convention of Butcher and Cotter,
846 we hence have the third order electric polarization density at
847 $\omega_{\sigma}=\omega$ given as ${\bf P}^{(n)}({\bf r},t)=
848 \re[{\bf P}^{(n)}_{\omega}\exp(-i\omega t)]$, with
849 $$
850 \eqalign{
851 {\bf P}^{(3)}_{\omega}
852 &=\sum_{\mu}{\bf e}_{\mu}(P^{(3)}_{\omega})_{\mu}\cr
853 &=\{{\rm Using\ the\ convention\ of\ Butcher\ and\ Cotter}\}\cr
854 &=\sum_{\mu}{\bf e}_{\mu}
855 \bigg[\varepsilon_0{{3}\over{4}}\sum_{\alpha}\sum_{\beta}\sum_{\gamma}
856 \chi^{(3)}_{\mu\alpha\beta\gamma}(-\omega;\omega,\omega,-\omega)
857 (E_{\omega})_{\alpha}(E_{\omega})_{\beta}(E_{-\omega})_{\gamma}\bigg]\cr
858 &=\{{\rm Evaluate\ the\ sums\ over\ } (x,y,z)
859 {\rm\ for\ field\ polarized\ in\ the\ }xy{\rm\ plane}\}\cr
860 &=\varepsilon_0{{3}\over{4}}\{
861 {\bf e}_x[
862 \chi^{(3)}_{xxxx} E^x_{\omega} E^x_{\omega} E^x_{-\omega}
863 +\chi^{(3)}_{xyyx} E^y_{\omega} E^y_{\omega} E^x_{-\omega}
864 +\chi^{(3)}_{xyxy} E^y_{\omega} E^x_{\omega} E^y_{-\omega}
865 +\chi^{(3)}_{xxyy} E^x_{\omega} E^y_{\omega} E^y_{-\omega}]\cr
866 &\qquad\quad
867 +{\bf e}_y[
868 \chi^{(3)}_{yyyy} E^y_{\omega} E^y_{\omega} E^y_{-\omega}
869 +\chi^{(3)}_{yxxy} E^x_{\omega} E^x_{\omega} E^y_{-\omega}
870 +\chi^{(3)}_{yxyx} E^x_{\omega} E^y_{\omega} E^x_{-\omega}
871 +\chi^{(3)}_{yyxx} E^y_{\omega} E^x_{\omega} E^x_{-\omega}]\}\cr
872 &=\{{\rm Make\ use\ of\ }{\bf E}_{-\omega}={\bf E}^*_{\omega}
873 {\rm\ and\ relations\ }\chi^{(3)}_{xxyy}=\chi^{(3)}_{yyxx},
874 {\rm\ etc.}\}\cr
875 &=\varepsilon_0{{3}\over{4}}\{
876 {\bf e}_x[
877 \chi^{(3)}_{xxxx} E^x_{\omega} \vert E^x_{\omega}\vert^2
878 +\chi^{(3)}_{xyyx} E^{y\,2}_{\omega} E^{x*}_{\omega}
879 +\chi^{(3)}_{xyxy} \vert E^y_{\omega}\vert^2 E^x_{\omega}
880 +\chi^{(3)}_{xxyy} E^x_{\omega} \vert E^y_{\omega}\vert^2]\cr
881 &\qquad\quad
882 +{\bf e}_y[
883 \chi^{(3)}_{xxxx} E^y_{\omega} \vert E^y_{\omega}\vert^2
884 +\chi^{(3)}_{xyyx} E^{x\,2}_{\omega} E^{y*}_{\omega}
885 +\chi^{(3)}_{xyxy} \vert E^x_{\omega}\vert^2 E^y_{\omega}
886 +\chi^{(3)}_{xxyy} E^y_{\omega} \vert E^x_{\omega}\vert^2]\}\cr
887 &=\{{\rm Make\ use\ of\ intrinsic\ permutation\ symmetry}\}\cr
888 &=\varepsilon_0{{3}\over{4}}\{
889 {\bf e}_x[
890 (\chi^{(3)}_{xxxx} \vert E^x_{\omega}\vert^2
891 +2\chi^{(3)}_{xxyy} \vert E^y_{\omega}\vert^2) E^x_{\omega}
892 +(\chi^{(3)}_{xxxx}-2\chi^{(3)}_{xxyy})
893 E^{y\,2}_{\omega} E^{x*}_{\omega}\cr
894 &\qquad\quad
895 {\bf e}_y[
896 (\chi^{(3)}_{xxxx} \vert E^y_{\omega}\vert^2
897 +2\chi^{(3)}_{xxyy} \vert E^x_{\omega}\vert^2) E^y_{\omega}
898 +(\chi^{(3)}_{xxxx}-2\chi^{(3)}_{xxyy})
899 E^{x\,2}_{\omega} E^{y*}_{\omega}.\cr
900 }
901 $$
902 For the optical field being linearly polarized, say in the $x$-direction,
903 the expression for the polarization density is significantly simplified,
904 to yield
905 $$
906 {\bf P}^{(3)}_{\omega}=\varepsilon_0(3/4){\bf e}_x
907 \chi^{(3)}_{xxxx} \vert E^x_{\omega}\vert^2 E^x_{\omega},
908 $$
909 i.~e.~taking a form that can be interpreted as an intensity-dependent
910 ($\sim\vert E^x_{\omega}\vert^2$) contribution to the refractive index
911 (cf.~Butcher and Cotter \S 6.3.1).
912
913 @*Rigorous theory of wave propagation in isotropic media.
914
915 @ The tensor form of the electric polarizability.
916 In the nonlinear susceptibility formalism, with the real-valued electric field
917 and polarization density of the medium taken according to
918 $$
919 {\bf E}(z,t)=\re[{\bf E}_{\omega}\exp(-i\omega t)],\qquad
920 {\bf P}(z,t)=\re[{\bf P}_{\omega}\exp(-i\omega t)]
921 $$
922 respectively, the complex-valued envelope for the polarization density is here
923 given by the expression
924 $$
925 \eqalign{
926 {\bf P}_{\omega}=&\varepsilon_0[
927 {\bf e}_{\mu}\chi^{{\rm ee}}_{\mu\alpha}E^{\alpha}_{\omega}
928 +{\bf e}_{\mu}\chi^{{\rm eem}}_{\mu\alpha\beta}
929 E^{\alpha}_{\omega}B^{\beta}_0
930 +{\bf e}_{\mu}K\chi^{{\rm eeee}}_{\mu\alpha\beta\gamma}
931 E^{\alpha}_{\omega}E^{\beta}_{\omega}E^{\gamma*}_{\omega}
932 +{\bf e}_{\mu}K\chi^{{\rm eeeem}}_{\mu\alpha\beta\gamma\delta}
933 E^{\alpha}_{\omega}E^{\beta}_{\omega}E^{\gamma*}_{\omega}B^{\delta}_0],
934 \cr
935 }
936 \eqno{(15)}
937 $$
938 in which the complex conjugated field components are to be associated with
939 negative angular frequencies, as following from the reality condition
940 ${\bf E}_{-\omega}={\bf E}^*_{\omega}$, and where $K=3/4$ is the degeneracy
941 factor as explicitly included in the Butcher and Cotter convention of nonlinear
942 optical susceptibilities~[10], as described in the previous section.
943 For isotropic media, in particular then homogeneous layers of stacked gratings
944 or elements of a discretized continuous-profile grating, the tensor elements
945 involved in this expression are for arbitrary frequencies of the electric
946 and magnetic fields listed in Table 1.
947 \medskip
948 \noindent{\bf Table 1.} Optical and magneto-optical susceptibilities of
949 isotropic nonlinear magneto-optical media, for arbitrary angular frequency
950 arguments of the tensors
951 $\chi^{\rm ee}_{\alpha\beta}(-\omega_{\sigma};\omega_{\sigma})$,
952 $\chi^{\rm eem}_{\alpha\beta\gamma}(-\omega_{\sigma};\omega_1,\omega_2)$,
953 $\chi^{\rm eeee}_{\alpha\beta\gamma\delta}
954 (-\omega_{\sigma};\omega_1,\omega_2,\omega_3)$, and
955 $\chi^{\rm eeeem}_{\alpha\beta\gamma\delta\epsilon}
956 (-\omega_{\sigma};\omega_1,\omega_2,\omega_3,\omega_4)$.
957 In the table, $M$ denotes the number of nonzero elements while $N$ denotes
958 the number of nonzero and independent elements.
959 \smallskip
960 \noindent{\hrule width 467pt}\vskip1pt
961 \beginvrulealign
962 \tabskip=0pt
963 \halign{
964 \hbox to 34pt{\hfil\vphantom{gP}#\hfil}% first column is centered
965 &\hbox to 34pt{\hfil#\hfil}% second column is centered
966 &\hbox to 28pt{\hfil#\hfil}% third column is centered
967 &\hbox to 28pt{\hfil#\hfil}% fourth column is centered
968 &\hbox to 343pt{\ \ #\hfil}\cr% fifth column is left aligned
969 \noalign{{\hrule width 467pt}\vskip 2pt}
970 Order&Source&$M$ & $N$ & Nonzero tensor elements\cr
971 \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
972 1st &[1]&3&1&
973 $\chi^{\rm ee}_{xx}=\chi^{\rm ee}_{yy}=\chi^{\rm ee}_{zz}$\cr
974 \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
975 2nd &[1]&6&1&
976 $\chi^{\rm eem}_{xyz}=\chi^{\rm eem}_{zxy}=\chi^{\rm eem}_{yzx}
977 =-\chi^{\rm eem}_{xzy}=-\chi^{\rm eem}_{zyx}=-\chi^{\rm eem}_{yxz}$\cr
978 \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
979 3rd &[2]&21&3&
980 $\chi^{\rm eeee}_{xxxx}=\chi^{\rm eeee}_{yyyy}=\chi^{\rm eeee}_{zzzz}
981 =\chi^{\rm eeee}_{xxyy}+\chi^{\rm eeee}_{xyxy}+\chi^{\rm eeee}_{xyyx}$,\cr
982 &&&&
983 $\chi^{\rm eeee}_{yyzz}=\chi^{\rm eeee}_{zzyy}=\chi^{\rm eeee}_{zzxx}
984 =\chi^{\rm eeee}_{xxzz}=\chi^{\rm eeee}_{xxyy}=\chi^{\rm eeee}_{yyxx}$,\cr
985 &&&&
986 $\chi^{\rm eeee}_{yzyz}=\chi^{\rm eeee}_{zyzy}=\chi^{\rm eeee}_{zxzx}
987 =\chi^{\rm eeee}_{xzxz}=\chi^{\rm eeee}_{xyxy}=\chi^{\rm eeee}_{yxyx}$,\cr
988 &&&&
989 $\chi^{\rm eeee}_{yzzy}=\chi^{\rm eeee}_{zyyz}=\chi^{\rm eeee}_{zxxz}
990 =\chi^{\rm eeee}_{xzzx}=\chi^{\rm eeee}_{xyyx}=\chi^{\rm eeee}_{yxxy}$\cr
991 \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
992 4th&[3]&60&6&
993 $\chi^{\rm eeeem}_{xxxyz}
994 =\chi^{\rm eeeem}_{yyyzx}
995 =\chi^{\rm eeeem}_{zzzxy}
996 = -\chi^{\rm eeeem}_{xxxzy}
997 = -\chi^{\rm eeeem}_{yyyxz}
998 = -\chi^{\rm eeeem}_{zzzyx}$\cr
999 &&&&\qquad\quad\,\,\,\,\,
1000 $= \chi^{\rm eeeem}_{xxyzx}
1001 +\chi^{\rm eeeem}_{xyxzx}
1002 +\chi^{\rm eeeem}_{yxxzx}$\cr
1003 &&&&
1004 $\chi^{\rm eeeem}_{xxyxz}
1005 =\chi^{\rm eeeem}_{yyzyx}
1006 =\chi^{\rm eeeem}_{zzxzy}
1007 = -\chi^{\rm eeeem}_{xxzxy}
1008 = -\chi^{\rm eeeem}_{yyxyz}
1009 = -\chi^{\rm eeeem}_{zzyzx}$\cr
1010 &&&&\qquad\quad\,\,\,\,\,
1011 $= -\chi^{\rm eeeem}_{xxyzx}
1012 +\chi^{\rm eeeem}_{xyzxx}
1013 +\chi^{\rm eeeem}_{yxzxx}$\cr
1014 &&&&
1015 $\chi^{\rm eeeem}_{xyxxz}
1016 =\chi^{\rm eeeem}_{yzyyx}
1017 =\chi^{\rm eeeem}_{zxzzy}
1018 = -\chi^{\rm eeeem}_{xzxxy}
1019 = -\chi^{\rm eeeem}_{yxyyz}
1020 = -\chi^{\rm eeeem}_{zyzzx}$\cr
1021 &&&&\qquad\quad\,\,\,\,\,
1022 $= -\chi^{\rm eeeem}_{xyxzx}
1023 -\chi^{\rm eeeem}_{xyzxx}
1024 +\chi^{\rm eeeem}_{yzxxx}$\cr
1025 &&&&
1026 $\chi^{\rm eeeem}_{yxxxz}
1027 =\chi^{\rm eeeem}_{zyyyx}
1028 =\chi^{\rm eeeem}_{xzzzy}
1029 = -\chi^{\rm eeeem}_{zxxxy}
1030 = -\chi^{\rm eeeem}_{xyyyz}
1031 = -\chi^{\rm eeeem}_{yzzzx}$\cr
1032 &&&&\qquad\quad\,\,\,\,\,
1033 $= -\chi^{\rm eeeem}_{yxxzx}
1034 -\chi^{\rm eeeem}_{yxzxx}
1035 -\chi^{\rm eeeem}_{yzxxx}$\cr
1036 &&&&
1037 $\chi^{\rm eeeem}_{xxyzx}
1038 =\chi^{\rm eeeem}_{yyzxy}
1039 =\chi^{\rm eeeem}_{zzxyz}
1040 = -\chi^{\rm eeeem}_{yyxzy}
1041 = -\chi^{\rm eeeem}_{zzyxz}
1042 = -\chi^{\rm eeeem}_{xxzyx}$\cr
1043 &&&&
1044 $\chi^{\rm eeeem}_{xyxzx}
1045 =\chi^{\rm eeeem}_{yzyxy}
1046 =\chi^{\rm eeeem}_{zxzyz}
1047 = -\chi^{\rm eeeem}_{xzxyx}
1048 = -\chi^{\rm eeeem}_{yxyzy}
1049 = -\chi^{\rm eeeem}_{zyzxz}$\cr
1050 &&&&
1051 $\chi^{\rm eeeem}_{yxxzx}
1052 =\chi^{\rm eeeem}_{zyyxy}
1053 =\chi^{\rm eeeem}_{xzzyz}
1054 = -\chi^{\rm eeeem}_{zxxyx}
1055 = -\chi^{\rm eeeem}_{xyyzy}
1056 = -\chi^{\rm eeeem}_{yzzxz}$\cr
1057 &&&&
1058 $\chi^{\rm eeeem}_{xyzxx}
1059 =\chi^{\rm eeeem}_{yzxyy}
1060 =\chi^{\rm eeeem}_{zxyzz}
1061 = -\chi^{\rm eeeem}_{xzyxx}
1062 = -\chi^{\rm eeeem}_{yxzyy}
1063 = -\chi^{\rm eeeem}_{zyxzz}$\cr
1064 &&&&
1065 $\chi^{\rm eeeem}_{yxzxx}
1066 =\chi^{\rm eeeem}_{zyxyy}
1067 =\chi^{\rm eeeem}_{xzyzz}
1068 = -\chi^{\rm eeeem}_{zxyxx}
1069 = -\chi^{\rm eeeem}_{xyzyy}
1070 = -\chi^{\rm eeeem}_{yzxzz}$\cr
1071 &&&&
1072 $\chi^{\rm eeeem}_{yzxxx}
1073 =\chi^{\rm eeeem}_{zxyyy}
1074 =\chi^{\rm eeeem}_{xyzzz}
1075 = -\chi^{\rm eeeem}_{zyxxx}
1076 = -\chi^{\rm eeeem}_{xzyyy}
1077 = -\chi^{\rm eeeem}_{yxzzz}$\cr
1078 }\endvrulealign
1079 \vskip-9.55pt
1080 {\hskip-.4pt\hrule width 467pt}\vskip 1pt
1081 \noindent{\hskip-.2pt\hrule width 467pt}
1082 \medskip
1083
1084 \vfill\eject
1085
1086 \medskip
1087 \noindent{\bf Table 2.} Optical and magneto-optical susceptibilities of
1088 isotropic nonlinear magneto-optical media, corresponding to those as listed
1089 in Table~1, but for angular frequency arguments corresponding to the
1090 particular choice of optical Kerr-effect and photo-induced Faraday rotation
1091 in presence of a static magnetic field, % ${\bf B}_0$, with
1092 $\chi^{\rm ee}_{\alpha\beta}(-\omega;\omega)$,
1093 $\chi^{\rm eem}_{\alpha\beta\gamma}(-\omega;\omega,0)$,
1094 $\chi^{\rm eeee}_{\alpha\beta\gamma\delta}
1095 (-\omega;\omega,\omega,-\omega)$, and
1096 $\chi^{\rm eeeem}_{\alpha\beta\gamma\delta\epsilon}
1097 (-\omega;\omega,\omega,-\omega,0)$.
1098 As in Table~1, $M$ denotes the number of nonzero elements while $N$ denotes
1099 the number of nonzero and independent elements.
1100 \smallskip
1101 \noindent{\hrule width 467pt}\vskip1pt
1102 \beginvrulealign
1103 \tabskip=0pt
1104 \halign{
1105 \hbox to 34pt{\hfil\vphantom{gP}#\hfil}% first column is centered
1106 &\hbox to 34pt{\hfil#\hfil}% second column is centered
1107 &\hbox to 28pt{\hfil#\hfil}% third column is centered
1108 &\hbox to 28pt{\hfil#\hfil}% fourth column is centered
1109 &\hbox to 343pt{\ \ #\hfil}\cr% fifth column is left aligned
1110 \noalign{{\hrule width 467pt}\vskip 2pt}
1111 Order&Source&$M$ & $N$ & Nonzero tensor elements\cr
1112 \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
1113 1st &[1]&3&1&
1114 $\chi^{\rm ee}_{xx}=\chi^{\rm ee}_{yy}=\chi^{\rm ee}_{zz}$\cr
1115 \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
1116 2nd &[1]&6&1&
1117 $\chi^{\rm eem}_{xyz}=\chi^{\rm eem}_{zxy}=\chi^{\rm eem}_{yzx}
1118 =-\chi^{\rm eem}_{xzy}=-\chi^{\rm eem}_{zyx}=-\chi^{\rm eem}_{yxz}$\cr
1119 \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
1120 3rd &[2]&21&3&
1121 $\chi^{\rm eeee}_{xxxx}=\chi^{\rm eeee}_{yyyy}=\chi^{\rm eeee}_{zzzz}
1122 =\chi^{\rm eeee}_{xxyy}+\chi^{\rm eeee}_{xyxy}+\chi^{\rm eeee}_{xyyx}$,\cr
1123 &&&&
1124 $\chi^{\rm eeee}_{yyzz}=\chi^{\rm eeee}_{zzyy}=\chi^{\rm eeee}_{zzxx}
1125 =\chi^{\rm eeee}_{xxzz}=\chi^{\rm eeee}_{xxyy}=\chi^{\rm eeee}_{yyxx}$,\cr
1126 &&&&
1127 $\chi^{\rm eeee}_{yzyz}=\chi^{\rm eeee}_{zyzy}=\chi^{\rm eeee}_{zxzx}
1128 =\chi^{\rm eeee}_{xzxz}=\chi^{\rm eeee}_{xyxy}=\chi^{\rm eeee}_{yxyx}$,\cr
1129 &&&&
1130 $\chi^{\rm eeee}_{yzzy}=\chi^{\rm eeee}_{zyyz}=\chi^{\rm eeee}_{zxxz}
1131 =\chi^{\rm eeee}_{xzzx}=\chi^{\rm eeee}_{xyyx}=\chi^{\rm eeee}_{yxxy}$\cr
1132 \noalign{\vskip .4pt{\hrule width 467pt}\vskip 1pt}
1133 4th&[3]&60&6&
1134 $\chi^{\rm eeeem}_{xxxyz}
1135 =\chi^{\rm eeeem}_{yyyzx}
1136 =\chi^{\rm eeeem}_{zzzxy}
1137 = -\chi^{\rm eeeem}_{xxxzy}
1138 = -\chi^{\rm eeeem}_{yyyxz}
1139 = -\chi^{\rm eeeem}_{zzzyx}$\cr
1140 &&&&\qquad\quad\,\,\,\,\,
1141 $= \chi^{\rm eeeem}_{xxyzx}
1142 +\chi^{\rm eeeem}_{xyxzx}
1143 +\chi^{\rm eeeem}_{yxxzx}$\cr
1144 &&&&
1145 $\chi^{\rm eeeem}_{xxyxz}
1146 =\chi^{\rm eeeem}_{yyzyx}
1147 =\chi^{\rm eeeem}_{zzxzy}
1148 = -\chi^{\rm eeeem}_{xxzxy}
1149 = -\chi^{\rm eeeem}_{yyxyz}
1150 = -\chi^{\rm eeeem}_{zzyzx}$\cr
1151 &&&&\qquad\quad\,\,\,\,\,
1152 $= -\chi^{\rm eeeem}_{xxyzx}
1153 +\chi^{\rm eeeem}_{xyzxx}
1154 +\chi^{\rm eeeem}_{yxzxx}$\cr
1155 &&&&
1156 $\chi^{\rm eeeem}_{xyxxz}
1157 =\chi^{\rm eeeem}_{yzyyx}
1158 =\chi^{\rm eeeem}_{zxzzy}
1159 = -\chi^{\rm eeeem}_{xzxxy}
1160 = -\chi^{\rm eeeem}_{yxyyz}
1161 = -\chi^{\rm eeeem}_{zyzzx}$\cr
1162 &&&&\qquad\quad\,\,\,\,\,
1163 $= -\chi^{\rm eeeem}_{xyxzx}
1164 -\chi^{\rm eeeem}_{xyzxx}
1165 +\chi^{\rm eeeem}_{yzxxx}$\cr
1166 &&&&
1167 $\chi^{\rm eeeem}_{yxxxz}
1168 =\chi^{\rm eeeem}_{zyyyx}
1169 =\chi^{\rm eeeem}_{xzzzy}
1170 = -\chi^{\rm eeeem}_{zxxxy}
1171 = -\chi^{\rm eeeem}_{xyyyz}
1172 = -\chi^{\rm eeeem}_{yzzzx}$\cr
1173 &&&&\qquad\quad\,\,\,\,\,
1174 $= -\chi^{\rm eeeem}_{yxxzx}
1175 -\chi^{\rm eeeem}_{yxzxx}
1176 -\chi^{\rm eeeem}_{yzxxx}$\cr
1177 &&&&
1178 $\chi^{\rm eeeem}_{xxyzx}
1179 =\chi^{\rm eeeem}_{yyzxy}
1180 =\chi^{\rm eeeem}_{zzxyz}
1181 = -\chi^{\rm eeeem}_{yyxzy}
1182 = -\chi^{\rm eeeem}_{zzyxz}
1183 = -\chi^{\rm eeeem}_{xxzyx}$\cr
1184 &&&&
1185 $\chi^{\rm eeeem}_{xyxzx}
1186 =\chi^{\rm eeeem}_{yzyxy}
1187 =\chi^{\rm eeeem}_{zxzyz}
1188 = -\chi^{\rm eeeem}_{xzxyx}
1189 = -\chi^{\rm eeeem}_{yxyzy}
1190 = -\chi^{\rm eeeem}_{zyzxz}$\cr
1191 &&&&
1192 $\chi^{\rm eeeem}_{yxxzx}
1193 =\chi^{\rm eeeem}_{zyyxy}
1194 =\chi^{\rm eeeem}_{xzzyz}
1195 = -\chi^{\rm eeeem}_{zxxyx}
1196 = -\chi^{\rm eeeem}_{xyyzy}
1197 = -\chi^{\rm eeeem}_{yzzxz}$\cr
1198 &&&&
1199 $\chi^{\rm eeeem}_{xyzxx}
1200 =\chi^{\rm eeeem}_{yzxyy}
1201 =\chi^{\rm eeeem}_{zxyzz}
1202 = -\chi^{\rm eeeem}_{xzyxx}
1203 = -\chi^{\rm eeeem}_{yxzyy}
1204 = -\chi^{\rm eeeem}_{zyxzz}$\cr
1205 &&&&
1206 $\chi^{\rm eeeem}_{yxzxx}
1207 =\chi^{\rm eeeem}_{zyxyy}
1208 =\chi^{\rm eeeem}_{xzyzz}
1209 = -\chi^{\rm eeeem}_{zxyxx}
1210 = -\chi^{\rm eeeem}_{xyzyy}
1211 = -\chi^{\rm eeeem}_{yzxzz}$\cr
1212 &&&&
1213 $\chi^{\rm eeeem}_{yzxxx}
1214 =\chi^{\rm eeeem}_{zxyyy}
1215 =\chi^{\rm eeeem}_{xyzzz}
1216 = -\chi^{\rm eeeem}_{zyxxx}
1217 = -\chi^{\rm eeeem}_{xzyyy}
1218 = -\chi^{\rm eeeem}_{yxzzz}$\cr
1219 }\endvrulealign
1220 \vskip-9.55pt
1221 {\hskip-.4pt\hrule width 467pt}\vskip 1pt
1222 \noindent{\hskip-.2pt\hrule width 467pt}
1223 \medskip
1224
1225 @ The vectorial form of the polarization density.
1226 By expanding the tensorial form of the polarization denisty as given by
1227 Eq.~(15) and using the nonzero elements of the susceptibility tensors as
1228 given in Table~2, one after some straightforward algebra obtains the
1229 polarization density of the medium in a vectorial form as
1230 $$
1231 \eqalign{
1232 {\bf P}_{\omega}=&\varepsilon_0[\chi^{{\rm ee}}_{xx} {\bf E}_{\omega}
1233 +\chi^{{\rm eem}}_{xyz} {\bf E}_{\omega}\times{\bf B}_0
1234 +\threefourth
1235 (\chi^{{\rm eeee}}_{xxxx}-\chi^{{\rm eeee}}_{xyyx})
1236 ({\bf E}_{\omega}\cdot{\bf E}^*_{\omega}){\bf E}_{\omega}
1237 +\threefourth\chi^{{\rm eeee}}_{xyyx}
1238 ({\bf E}_{\omega}\cdot{\bf E}_{\omega}){\bf E}^*_{\omega}\cr
1239 &+\threefourth\chi^{{\rm eeeem}}_{xyyyz}
1240 ({\bf E}_{\omega}\cdot{\bf E}^*_{\omega}){\bf E}_{\omega}\times{\bf B}_0
1241 +\threefourth\chi^{{\rm eeeem}}_{xxxyz}{\bf E}_{\omega}
1242 ({\bf E}_{\omega}\cdot({\bf E}^*_{\omega}\times{\bf B}_0))],\cr
1243 }
1244 \eqno{(16)}
1245 $$
1246 where the degeneracy factor $K=3/4$ was explicitly stated with its numerical
1247 value.
1248
1249 @ The Polarization density in the Faraday configuration.
1250 In the Faraday configuration~[1], the optical field propagates collinearly
1251 with an externally applied static magnetic field ${\bf B}_0$.
1252 Taking the direction of propagation as the $z$-axis in a Cartesian coordinate
1253 system $({\bf e}_x,{\bf e}_y,{\bf e}_z)$ and furthermore assuming the infinite
1254 plane wave approximation to hold for the transverse profile of the waves,
1255 the probem of wave propagation becomes a one-dimensional nonlinear system.
1256
1257 As a convention for circular polarization states, we employ the circularly
1258 polarized basis vectors
1259 $$
1260 {\bf e}_{\pm}=({\bf e}_x\pm i{\bf e}_y)/\sqrt{2},
1261 $$
1262 which possesses the properties
1263 $$
1264 {\bf e}_{\pm}\times{\bf e}_z=\pm i{\bf e}_{\pm},\qquad
1265 {\bf e}^*_{\pm}\cdot{\bf e}_{\pm}=1,\qquad
1266 {\bf e}^*_{\pm}\cdot{\bf e}_{\mp}=0.
1267 $$
1268 In the circularly polarized basis, the fields are hence taken as ${\bf B}_0=
1269 {\bf e}_z B^z_0$ and ${\bf E}_{\omega}={\bf e}_+ E^+_{\omega}+{\bf e}_-
1270 E^-_{\omega}$, in which the electric field is the total one, including any
1271 forward or backward traveling components. As this is inserted into Eq.~(2),
1272 the electric polarization density of the medium hence becomes
1273 $$
1274 \eqalign{
1275 {\bf e}^*_{\pm}\cdot{\bf P}_{\omega}&=
1276 \varepsilon_0\{
1277 (\chi^{\rm ee}_{xx}\pm i\chi^{\rm eem}_{xyz}B^z_0)E^{\pm}_{\omega}
1278 +\threefourth[
1279 (\chi^{\rm eeee}_{xxxx}-\chi^{\rm eeee}_{xyyx})
1280 \vert E^{\pm}_{\omega}\vert^2+
1281 (\chi^{\rm eeee}_{xxxx}+\chi^{\rm eeee}_{xyyx})
1282 \vert E^{\mp}_{\omega}\vert^2]
1283 E^{\pm}_{\omega}
1284 \cr&\qquad
1285 \pm\threefourth[
1286 i(\chi^{\rm eeeem}_{xyyyz}-\chi^{\rm eeeem}_{xxxyz})B^z_0
1287 \vert E^{\pm}_{\omega}\vert^2+
1288 i(\chi^{\rm eeeem}_{xyyyz}+\chi^{\rm eeeem}_{xxxyz})B^z_0
1289 \vert E^{\mp}_{\omega}\vert^2]
1290 E^{\pm}_{\omega}
1291 \}\cr
1292 }
1293 $$
1294 From now on, the susceptibility tensor elements will for the sake of simplicity
1295 in notation be incorporated into the index of refraction
1296 $n=(1+\chi^{\rm ee}_{xx})^{1/2}$, the gyration coefficient
1297 $\gamma=\chi^{\rm eem}_{xyz}B^z_0$, and the nonlinear optical and
1298 magneto-optical parameters $p_{\pm}$ and $q_{\pm}$, defined as
1299 $$
1300 \eqalignno{
1301 p_{\pm}&={{3}\over{8 n_{\pm}}}
1302 [(\chi^{\rm eeee}_{xxxx}-\chi^{\rm eeee}_{xyyx})
1303 \pm i(\chi^{\rm eeeem}_{xyyyz}-\chi^{\rm eeeem}_{xxxyz})B^z_0],
1304 &(2{\rm a})\cr
1305 q_{\pm}&={{3}\over{8 n_{\pm}}}
1306 [(\chi^{\rm eeee}_{xxxx}+\chi^{\rm eeee}_{xyyx})
1307 \pm i(\chi^{\rm eeeem}_{xyyyz}+\chi^{\rm eeeem}_{xxxyz})B^z_0],
1308 &(2{\rm b})\cr
1309 }
1310 $$
1311 where $n_{\pm}=(n^2\pm\gamma)^{1/2}$ are the effective refractive indices
1312 for the circularly polarized components of the light,
1313 to give the polarization density in Eq.~(1) in the simpler form
1314 $$
1315 {\bf e}^*_{\pm}\cdot{\bf P}_{\omega}=\varepsilon_0[n^2_{\pm}-1
1316 +2n_{\pm}(p_{\pm}\vert E^{\pm}_{\omega}\vert^2
1317 +q_{\pm}\vert E^{\mp}_{\omega}\vert^2)]E^{\pm}_{\omega}.
1318 \eqno{(5)}
1319 $$
1320 The reason for includingthe refractive index in the particular scaling of the
1321 nonlinear coefficients as apparing in $p_{\pm}$ and $q_{\pm}$ will become
1322 obvious as the analysis proceeds with the wave equation.
1323 As the polarization density given by Eq.~(5) is inserted into the wave
1324 equation for the electric field inside the medium, one obtains the equation
1325 of motion
1326 $$
1327 {{\partial^2 E^{\pm}_{\omega}}\over{\partial z^2}}
1328 +{{\omega^2 n^2_{\pm}}\over{c^2}} E^{\pm}_{\omega}
1329 +2n_{\pm}{{\omega^2}\over{c^2}}(p_{\pm}\vert E^{\pm}_{\omega}\vert^2
1330 +q_{\pm}\vert E^{\mp}_{\omega}\vert^2)E^{\pm}_{\omega}=0.
1331 \eqno{(5)}
1332 $$
1333 This equation determines the spatial evolution of the total electromagnetic
1334 field, which may be composed of forward as well as backward traveling
1335 components of arbitrary polarization state.
1336 The task that now lies ahead is the separation of these components so as
1337 to form a system which provides the basis for further analytical investigation.
1338
1339 @ Separation into forward and traveling components.
1340 It may from Eq.~(5) be noticed that in the absence of the nonlinear source
1341 terms, the general solutions for the left and right circularly polarized
1342 components of a forward traveling wave become
1343 $$
1344 E^+_{\omega}=E^{\rm f}_+\exp(in_+\omega z/c),\qquad
1345 E^-_{\omega}=E^{\rm f}_-\exp(in_-\omega z/c),
1346 $$
1347 respectively,
1348 where $E^{\rm f}_+$ and $E^{\rm f}_-$ are constants determined by the initial
1349 conditions at some arbitrary point along the direction of propagation.
1350 Meanwhile, the solution for the left/right circularly polarized components
1351 of a backward traveling wave becomes
1352 $$
1353 E^+_{\omega}=E^{\rm b}_+\exp(in_-\omega z/c),\qquad
1354 E^-_{\omega}=E^{\rm b}_-\exp(in_+\omega z/c),
1355 $$
1356 in which we here emphasize the change of effective refractive indices as
1357 experienced compared to the forward traveling component.
1358 This change is due to the fact that a backward traveling wave will experience
1359 the applied static magnetic field as pointing in the opposite direction as
1360 compared to the forward traveling wave, and hence the birefringence experienced
1361 from the Faraday effect will be different in sign.
1362 For a linearly polarized wave, this is manifested in that the polarization
1363 state of the backward traveling wave will rotate in opposite direction around
1364 the axis pointing in the direction of propagation, as compared to the forward
1365 traveling wave.
1366 Hence, by employing a separation according to
1367 $$
1368 \eqalign{
1369 {\bf E}_{\omega}=
1370 {\bf e}_+ &E^{\rm f}_+\exp(in_+\omega z/c)
1371 +{\bf e}_- E^{\rm f}_-\exp(in_-\omega z/c)\cr
1372 &+{\bf e}^*_+ E^{\rm b}_+\exp(-in_-\omega z/c)
1373 +{\bf e}^*_- E^{\rm b}_-\exp(-in_+\omega z/c),\cr
1374 }
1375 \eqno{(6)}
1376 $$
1377 or equivalently in the scalar form
1378 $$
1379 E^{\pm}_{\omega}=E^{\rm f}_{\pm}\exp(i n_{\pm}\omega z/c)+
1380 E^{\rm b}_{\mp}\exp(-in_{\pm}\omega z/c),
1381 \eqno{(6)}
1382 $$
1383 the wave equation for the envelopes $E^{\rm f}_{\pm}$ and $E^{\rm b}_{\pm}$,
1384 which generally are dependent on the coordinate $z$, naturally relaxes towards
1385 the solution to the linear wave propagation problem, with $E^{\rm f}_{\pm}$
1386 and $E^{\rm b}_{\pm}$ becoming constants whenever the nonlinear terms may be
1387 neglected.
1388 In addition, due to the separation of the linear phase evolution in this one
1389 may also expect the field envelopes to be slowly varying functions of the
1390 spatial coordinate $z$ under any reasonable nonlinear effects.
1391
1392 By inserting Eq.~(6) into The polarization density given in Eq.~(5), the wave
1393 equation (0) takes the form
1394 $$
1395 \eqalign{
1396 \Big\{&{{\partial^2 E^{\rm f}_{\pm}}\over{\partial z^2}}
1397 +2ik_{\pm}{{\partial E^{\rm f}_{\pm}}\over{\partial z}}
1398 +2{{\omega^2 n_{\pm}}\over{c^2}}
1399 [p_{\pm}(\vert E^{\rm f}_{\pm}\vert^2+2\vert E^{\rm b}_{\mp}\vert^2)
1400 +q_{\pm}(\vert E^{\rm f}_{\mp}\vert^2+\vert E^{\rm b}_{\pm}\vert^2)]
1401 E^{\rm f}_{\pm}
1402 \Big\}\exp(ik_{\pm}z)\cr
1403 &+\Big\{{{\partial^2 E^{\rm b}_{\mp}}\over{\partial z^2}}
1404 -2ik_{\pm}{{\partial E^{\rm b}_{\mp}}\over{\partial z}}
1405 +2{{\omega^2 n_{\pm}}\over{c^2}}
1406 [p_{\pm}(\vert E^{\rm b}_{\mp}\vert^2+2\vert E^{\rm f}_{\pm}\vert^2)
1407 +q_{\pm}(\vert E^{\rm b}_{\pm}\vert^2+\vert E^{\rm f}_{\mp}\vert^2)]
1408 E^{\rm b}_{\mp}
1409 \Big\}\exp(-ik_{\pm}z)\cr
1410 &+2{{\omega^2 n_{\pm}}\over{c^2}}p_{\pm}
1411 [E^{\rm f\,2}_{\pm}E^{\rm b*}_{\mp}\exp(3ik_{\pm}z)
1412 +E^{\rm b\,2}_{\mp}E^{\rm f*}_{\pm}\exp(-3ik_{\pm}z)]\cr
1413 &+2{{\omega^2 n_{\pm}}\over{c^2}}q_{\pm}
1414 [E^{\rm f}_{\pm}E^{\rm f}_{\mp}E^{\rm b*}_{\pm}
1415 \exp(i(k_{\pm}+2k_{\mp})z)
1416 +E^{\rm b}_{\mp}E^{\rm b}_{\pm}E^{\rm f*}_{\mp}
1417 \exp(-i(k_{\pm}+2k_{\mp})z)]\cr
1418 &+2{{\omega^2 n_{\pm}}\over{c^2}}q_{\pm}
1419 [E^{\rm f}_{\mp}E^{\rm b}_{\mp}E^{\rm b*}_{\pm}
1420 \exp(i(2k_{\mp}-k_{\pm})z)
1421 +E^{\rm b}_{\pm}E^{\rm f}_{\pm}E^{\rm f*}_{\mp}
1422 \exp(-i(2k_{\mp}-k_{\pm})z)]=0,\cr
1423 }
1424 \eqno{(7)}
1425 $$
1426 where the notation $k_{\pm}\equiv\omega n_{\pm}/c$ was introduced for the
1427 sake of algebraic simplicity.
1428 In this equation, it may me noticed that the linear terms of the polarization
1429 density have been eliminated, due to the particular choice of separation of
1430 variables according to Eq.~(6).
1431 However, in this form the wave propagation problem is extremely complex in its
1432 analysis, and in order to proceed, two general approximations may be employed
1433 without loosing much of generality. These are the slowly varying envelope
1434 approximation and the method of projecting out spatially phase mismatched
1435 terms.
1436 The slowly varying envelope approximation simply assumes that the second-order
1437 spatial derivative of the field envelope is much smaller in magnitude than
1438 the first-order derivative multiplied by the wavevector, or in terms of the
1439 here employed variables,
1440 $$
1441 \Big\vert{{\partial^2 E^{\rm f}_{\pm}}\over{\partial z^2}}\Big\vert\ll
1442 2k_{\pm}\Big\vert{{\partial E^{\rm f}_{\pm}}\over{\partial z}}\Big\vert,
1443 \qquad
1444 \Big\vert{{\partial^2 E^{\rm b}_{\mp}}\over{\partial z^2}}\Big\vert\ll
1445 2k_{\pm}\Big\vert{{\partial E^{\rm b}_{\mp}}\over{\partial z}}\Big\vert.
1446 $$
1447 By applying this approximation to Eq.~(7), one obtains the slightly simpler
1448 system of equations
1449 $$
1450 \eqalign{
1451 \Big\{&{{\partial E^{\rm f}_{\pm}}\over{\partial z}}
1452 -i{{\omega}\over{c}}
1453 [p_{\pm}(\vert E^{\rm f}_{\pm}\vert^2+2\vert E^{\rm b}_{\mp}\vert^2)
1454 +q_{\pm}(\vert E^{\rm f}_{\mp}\vert^2+\vert E^{\rm b}_{\pm}\vert^2)]
1455 E^{\rm f}_{\pm}
1456 \Big\}\exp(ik_{\pm}z)\cr
1457 &-\Big\{
1458 {{\partial E^{\rm b}_{\mp}}\over{\partial z}}
1459 +i{{\omega}\over{c}}
1460 [p_{\pm}(\vert E^{\rm b}_{\mp}\vert^2+2\vert E^{\rm f}_{\pm}\vert^2)
1461 +q_{\pm}(\vert E^{\rm b}_{\pm}\vert^2+\vert E^{\rm f}_{\mp}\vert^2)]
1462 E^{\rm b}_{\mp}
1463 \Big\}\exp(-ik_{\pm}z)\cr
1464 &-i{{\omega}\over{c}}p_{\pm}
1465 [E^{\rm f\,2}_{\pm}E^{\rm b*}_{\mp}\exp(3ik_{\pm}z)
1466 +E^{\rm b\,2}_{\mp}E^{\rm f*}_{\pm}\exp(-3ik_{\pm}z)]\cr
1467 &-i{{\omega}\over{c}}q_{\pm}
1468 [E^{\rm f}_{\pm}E^{\rm f}_{\mp}E^{\rm b*}_{\pm}
1469 \exp(i(k_{\pm}+2k_{\mp})z)
1470 +E^{\rm b}_{\mp}E^{\rm b}_{\pm}E^{\rm f*}_{\mp}
1471 \exp(-i(k_{\pm}+2k_{\mp})z)]\cr
1472 &-i{{\omega}\over{c}}q_{\pm}
1473 [E^{\rm f}_{\mp}E^{\rm b}_{\mp}E^{\rm b*}_{\pm}
1474 \exp(i(2k_{\mp}-k_{\pm})z)
1475 +E^{\rm b}_{\pm}E^{\rm f}_{\pm}E^{\rm f*}_{\mp}
1476 \exp(-i(2k_{\mp}-k_{\pm})z)]=0.\cr
1477 }
1478 \eqno{(8)}
1479 $$
1480 Next step is now to project out terms which are closely phase matched, and in
1481 particular then the terms related to the envelopes of the forward and backward
1482 traveling components.
1483 This is for the forward traveling parts done by multiplying Eq.~(8) by
1484 $\exp(-ik_{\pm}z)$ and average the resulting equation over a few spatial
1485 periods, assuming slowly varying field envelopes.
1486 In performing this averaging, essentially two levels of approximation may be
1487 applied: Either we keep also terms which are closely phase matched, that is
1488 to say the term involving the exponent $\exp(i(2k_{\mp}-k_{\pm})z)$, or we
1489 may assume that also this terms is averaged out for a sufficiently strong
1490 Faraday effect.
1491 This is in many cases a fully adequate approximation, in particular since
1492 the main contribution to effects such as the ellipse rotation, optcal
1493 Kerr-effect and photo-induced Faraday effect anyway are dominated by the
1494 terms involving the absolute magnitude of the fields.
1495 In the rigorous theory as here developed, however, these terms are kept for
1496 the time being, so as to fully encounter for any effects introduced by these.
1497 This method of projecting out the forward components is analogously applied
1498 to the backward traveling ones, but for this case by instead multiplying the
1499 equation by $\exp(ik_{\pm}z)$ prior to the averaging.
1500 The resulting system of coupled equations for the envelopes of the forward
1501 and backward traveling components of the field envelopes yield
1502 $$
1503 \eqalignno{
1504 {{\partial E^{\rm f}_{\pm}}\over{\partial z}}
1505 &=i{{\omega}\over{c}}\{
1506 [p_{\pm}(\vert E^{\rm f}_{\pm}\vert^2+2\vert E^{\rm b}_{\mp}\vert^2)
1507 +q_{\pm}(\vert E^{\rm f}_{\mp}\vert^2+\vert E^{\rm b}_{\pm}\vert^2)]
1508 E^{\rm f}_{\pm}
1509 +q_{\pm}E^{\rm f}_{\mp}E^{\rm b}_{\mp}E^{\rm b*}_{\pm}
1510 \exp(\mp i\eta z)\}=0,&(9{\rm a})\cr
1511 {{\partial E^{\rm b}_{\mp}}\over{\partial z}}
1512 &=-i{{\omega}\over{c}}\{
1513 [p_{\pm}(\vert E^{\rm b}_{\mp}\vert^2+2\vert E^{\rm f}_{\pm}\vert^2)
1514 +q_{\pm}(\vert E^{\rm b}_{\pm}\vert^2+\vert E^{\rm f}_{\mp}\vert^2)]
1515 E^{\rm b}_{\mp}
1516 +q_{\pm}E^{\rm b}_{\pm}E^{\rm f}_{\pm}E^{\rm f*}_{\mp}
1517 \exp(\pm i\eta z)\}=0,&(9{\rm b})\cr
1518 }
1519 $$
1520 where the notation $\eta\equiv2(k_+-k_-)$ was introduced.
1521
1522
1523 @ Separation of amplitude and phase of the field envelopes.
1524 In order to proceed with Eqs.~(7), it is convenient to separate the wave
1525 propagation into parts affecting the phase and amplitude of the forward and
1526 backward traveling field envelopes.
1527 In order to do so, the amplitude and phase of the field envelopes are taken
1528 according to
1529 $$
1530 E^{\rm f,b}_{\pm}(z)=A^{\rm f,b}_{\pm}(z)\exp(i\psi^{\rm f,b}_{\pm}(z)),
1531 $$
1532 where $A^{\rm f,b}_{\pm}(z)\equiv\vert E^{\rm f,b}_{\pm}(z)\vert$ are the
1533 amplitudes and $\psi^{\rm f,b}_{\pm}(z)$ the corresponding phases of
1534 $E^{\rm f,b}_{\pm}(z)$.
1535 This ansatz leads to Eqs.~(7) assuming the form
1536 $$
1537 \eqalignno{
1538 \Big({{\partial A^{\rm f}_{\pm}}\over{\partial z}}
1539 +iA^{\rm f}_{\pm}{{\partial\psi^{\rm f}_{\pm}}\over{\partial z}}\Big)
1540 \exp(i\psi^{\rm f}_{\pm})
1541 &=i{{\omega}\over{c}}\{
1542 [p_{\pm}(A^{\rm f\,2}_{\pm}+2A^{\rm b\,2}_{\mp})
1543 +q_{\pm}(A^{\rm f\,2}_{\mp}+A^{\rm b\,2}_{\pm})]
1544 A^{\rm f}_{\pm}\exp(i\psi^{\rm f}_{\pm})
1545 \cr&\hskip 50pt
1546 +q_{\pm}A^{\rm f}_{\mp}A^{\rm b}_{\mp}A^{\rm b}_{\pm}
1547 \exp(\mp i\eta z+i\psi^{\rm f}_{\mp}+i\psi^{\rm b}_{\mp}
1548 -i\psi^{\rm b}_{\pm})\},&(11{\rm a})\cr
1549 \Big({{\partial A^{\rm b}_{\mp}}\over{\partial z}}
1550 +iA^{\rm b}_{\mp}{{\partial\psi^{\rm b}_{\mp}}\over{\partial z}}\Big)
1551 \exp(i\psi^{\rm b}_{\mp})
1552 &=-i{{\omega}\over{c}}\{
1553 [p_{\pm}(A^{\rm b\,2}_{\mp}+2A^{\rm f\,2}_{\pm})
1554 +q_{\pm}(A^{\rm b\,2}_{\pm}+A^{\rm f\,2}_{\mp})]
1555 A^{\rm b}_{\mp}\exp(i\psi^{\rm b}_{\mp})
1556 \cr&\hskip 50pt
1557 +q_{\pm}A^{\rm b}_{\pm}A^{\rm f}_{\pm}A^{\rm f}_{\mp}
1558 \exp(\pm i\eta z+i\psi^{\rm b}_{\pm}+i\psi^{\rm f}_{\pm}
1559 -i\psi^{\rm f}_{\mp})\},&(11{\rm b})\cr
1560 }
1561 $$
1562 or equivalently
1563 $$
1564 \eqalignno{
1565 {{\partial A^{\rm f}_{\pm}}\over{\partial z}}
1566 +iA^{\rm f}_{\pm}{{\partial\psi^{\rm f}_{\pm}}\over{\partial z}}
1567 &=i{{\omega}\over{c}}\{
1568 [p_{\pm}(A^{\rm f\,2}_{\pm}+2A^{\rm b\,2}_{\mp})
1569 +q_{\pm}(A^{\rm f\,2}_{\mp}+A^{\rm b\,2}_{\pm})]A^{\rm f}_{\pm}
1570 +q_{\pm}A^{\rm f}_{\mp}A^{\rm b}_{\mp}A^{\rm b}_{\pm}
1571 \exp(\mp i\psi)\},&(12{\rm a})\cr
1572 {{\partial A^{\rm b}_{\mp}}\over{\partial z}}
1573 +iA^{\rm b}_{\mp}{{\partial\psi^{\rm b}_{\mp}}\over{\partial z}}
1574 &=-i{{\omega}\over{c}}\{
1575 [p_{\pm}(A^{\rm b\,2}_{\mp}+2A^{\rm f\,2}_{\pm})
1576 +q_{\pm}(A^{\rm b\,2}_{\pm}+A^{\rm f\,2}_{\mp})]A^{\rm b}_{\mp}
1577 +q_{\pm}A^{\rm b}_{\pm}A^{\rm f}_{\pm}A^{\rm f}_{\mp}
1578 \exp(\pm i\psi)\},&(12{\rm b})\cr
1579 }
1580 $$
1581 where the phase differences between the fields were incorporated into the
1582 single variable $\psi=\psi(z)$, defined as
1583 $$
1584 \psi(z)\equiv\eta z+\psi^{\rm f}_+(z)-\psi^{\rm f}_-(z)
1585 +\psi^{\rm b}_+(z)-\psi^{\rm b}_-(z).
1586 \eqno{(13)}
1587 $$
1588 By multiplying Eqs.~(12) by respective amplitudes $A^{\rm f}_{\pm}$ and
1589 $A^{\rm b}_{\mp}$, extracting the real parts of the left and right hand
1590 sides of Eqs.~(12), and assumin a nonresonant medium in which $p_{\pm}$
1591 and $q_{\pm}$ are real-valued quantities, one obtains the amplitude equations
1592 $$
1593 \eqalignno{
1594 {{\partial A^{\rm f\,2}_{\pm}}\over{\partial z}}
1595 =&\pm2({{\omega}/{c}})q_{\pm} A^{\rm f}_+ A^{\rm f}_-
1596 A^{\rm b}_+ A^{\rm b}_- \sin(\psi),&(14{\rm a})\cr
1597 {{\partial A^{\rm b\,2}_{\mp}}\over{\partial z}}
1598 =&\pm2({{\omega}/{c}})q_{\pm} A^{\rm f}_+ A^{\rm f}_-
1599 A^{\rm b}_+ A^{\rm b}_- \sin(\psi),&(14{\rm b})\cr
1600 }
1601 $$
1602 while the analogous extraction of the imaginary parts instead provides the
1603 phase equations
1604 $$
1605 \eqalignno{
1606 A^{\rm f\,2}_{\pm}{{\partial\psi^{\rm f}_{\pm}}\over{\partial z}}
1607 =&{{\omega}\over{c}}
1608 [p_{\pm}(A^{\rm f\,2}_{\pm}+2A^{\rm b\,2}_{\mp})
1609 +q_{\pm}(A^{\rm f\,2}_{\mp}+A^{\rm b\,2}_{\pm})]A^{\rm f\,2}_{\pm}
1610 +{{\omega}\over{c}}q_{\pm}A^{\rm f}_+ A^{\rm f}_-
1611 A^{\rm b}_+ A^{\rm b}_- \cos(\psi(z)),&(15{\rm a})\cr
1612 A^{\rm b\,2}_{\mp}{{\partial\psi^{\rm b}_{\mp}}\over{\partial z}}
1613 =&-{{\omega}\over{c}}
1614 [p_{\pm}(A^{\rm b\,2}_{\mp}+2A^{\rm f\,2}_{\pm})
1615 +q_{\pm}(A^{\rm b\,2}_{\pm}+A^{\rm f\,2}_{\mp})]A^{\rm b\,2}_{\mp}
1616 -{{\omega}\over{c}}q_{\pm} A^{\rm f}_+ A^{\rm f}_-
1617 A^{\rm b}_+ A^{\rm b}_- \cos(\psi(z)).&(15{\rm b})\cr
1618 }
1619 $$
1620 The inclusion of the phases as differences into the single variable $\psi(z)$
1621 is not, as one at a first glance might think, only just a matter of convenient
1622 and compact notation.
1623 In fact, by differentiating $\psi(z)$ with respect to $z$ and using the
1624 phase evolution according to Eqs.~(10), it actually turns out that the
1625 individual phases of the components of the optical wave can be eliminated
1626 in favour of the single variable $\psi(z)$, hence providing an effective
1627 reduction of the dimensionality of the problem, as will be shown in the
1628 following sections.
1629
1630 @ Invariants of motion.
1631 As a short side track to the analysis, before proceeding with actually solving
1632 the derived equations of motion for the amplitudes and phases of the field
1633 components, we will now consider a few important points regarding conserved
1634 quantities. These are important in the final stage when we separate out one
1635 single differentail equation for one single field variable from the so far
1636 complex and coupled system.
1637 From the spatial evolution of the amplitudes as given in Eqs.~(14), one finds
1638 that the magnitudes of the envelopes obey the invariants of motion
1639 $$
1640 {{\partial}\over{\partial z}}(A^{\rm f\,2}_+ - A^{\rm b\,2}_-)=0,\qquad
1641 {{\partial}\over{\partial z}}(A^{\rm f\,2}_- - A^{\rm b\,2}_+)=0.
1642 \eqno{(16)}
1643 $$
1644 Similarly, one also finds that the respective forward and backward traveling
1645 circularly polarized components obey the invariants of motion
1646 $$
1647 {{\partial}\over{\partial z}}
1648 (q_- A^{\rm f\,2}_+ + q_+ A^{\rm f\,2}_-)=0,\qquad
1649 {{\partial}\over{\partial z}}
1650 (q_+ A^{\rm b\,2}_+ + q_- A^{\rm b\,2}_-)=0.
1651 \eqno{(17)}
1652 $$
1653 The invariants of motion given by Eqs.~(16) and~(17) can hence be summarized as
1654 $$
1655 \eqalignno{
1656 A^{\rm f\,2}_+ - A^{\rm b\,2}_-&={\ \rm const.\ }
1657 \equiv C_+/q_-,&(18{\rm a})\cr
1658 A^{\rm f\,2}_- - A^{\rm b\,2}_+&={\ \rm const.\ }
1659 \equiv C_-/q_+,&(18{\rm b})\cr
1660 q_- A^{\rm f\,2}_+ + q_+ A^{\rm f\,2}_-&={\ \rm const.\ }\equiv
1661 I_{\rm f},&(18{\rm c})\cr
1662 q_+ A^{\rm b\,2}_+ + q_- A^{\rm b\,2}_-&={\ \rm const.\ }\equiv
1663 I_{\rm b}.&(18{\rm d})\cr
1664 }
1665 $$
1666 The reason for this particular choice of the form of the constants of motion,
1667 with $C_+$ and $C_-$ scaled to be in units of $q_-$ and $q_+$, respectively,
1668 is motivated later on by simplifying the notation when it comes to choosing
1669 a normalized form for the equations of motion in the final stage of their
1670 solving.
1671 As Eqs.~(18) imply that the invariants of motion for the general, $z$-dependent
1672 envelopes can be formulated as the linear algebraic system
1673 $$
1674 \pmatrix{
1675 q_-&0&0&-q_-\cr
1676 0&q_+&-q_+&0\cr
1677 q_-&q_+&0&0\cr
1678 0&0&q_+&q_-\cr
1679 }
1680 \pmatrix{A^{\rm f\,2}_+(z)\cr A^{\rm f\,2}_-(z)\cr
1681 A^{\rm b\,2}_+(z)\cr A^{\rm b\,2}_-(z)\cr}
1682 =\pmatrix{C_+\cr C_-\cr I_{\rm f}\cr I_{\rm b}\cr},
1683 \eqno{(19)}
1684 $$
1685 one may be tempted to draw the conclusion that all envelopes
1686 are constant with respect to the spatial coordinate~$z$.
1687 However, this is a wrong conclusion, as one easily can verify that the
1688 system~(18) is underdetermined, with a zero determinant of the system matrix,
1689 as appearing in Eq.~(19).
1690
1691
1692 @ Elimination of absolute phase dependence.
1693 In order to reduce the algebraic complexity of Eqs.~(14) and~(15), which is
1694 necessary in order proceed with the analytical theory of their evolution, we
1695 will now eliminate the absolute phases of the fields in favour of the single
1696 variable $\psi=\psi(z)$, which describes the phase difference between the
1697 four field components $E^{\rm f}_+$, $E^{\rm f}_-$, $E^{\rm b}_+$ and
1698 $E^{\rm b}_-$.
1699 This will reduce the dimension of of the problem from the original eight
1700 variables present in Eqs.~(14) and~(15), down to a total of five coupled
1701 variables and equations.
1702 By differentiating the variable $\psi(z)$ with respect to $z$ and using
1703 Eqs.~(10) one finds
1704 $$
1705 \eqalign{
1706 {{\partial\psi}\over{\partial z}}
1707 &=\eta
1708 +{{\partial\psi^{\rm f}_+}\over{\partial z}}
1709 -{{\partial\psi^{\rm f}_-}\over{\partial z}}
1710 +{{\partial\psi^{\rm b}_+}\over{\partial z}}
1711 -{{\partial\psi^{\rm b}_-}\over{\partial z}}\cr
1712 &=\eta
1713 +{{\omega}\over{c}}[p_+(A^{\rm f\,2}_++2A^{\rm b\,2}_-)
1714 +q_+(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]
1715 +{{\omega}\over{c}}q_+
1716 {{A^{\rm f}_- A^{\rm b}_- A^{\rm b}_+}\over{A^{\rm f}_+}}
1717 \cos(\psi)
1718 \cr&\qquad\qquad
1719 -{{\omega}\over{c}}[p_-(A^{\rm f\,2}_-+2A^{\rm b\,2}_+)
1720 +q_-(A^{\rm f\,2}_++A^{\rm b\,2}_-)]
1721 -{{\omega}\over{c}}q_-
1722 {{A^{\rm f}_+ A^{\rm b}_+ A^{\rm b}_-}\over{A^{\rm f}_-}}
1723 \cos(\psi)
1724 \cr&\qquad\qquad
1725 -{{\omega}\over{c}}[p_-(A^{\rm b\,2}_++2A^{\rm f\,2}_-)
1726 +q_-(A^{\rm b\,2}_-+A^{\rm f\,2}_+)]
1727 -{{\omega}\over{c}}q_-
1728 {{A^{\rm b}_- A^{\rm f}_- A^{\rm f}_+}\over{A^{\rm b}_+}}
1729 \cos(\psi)
1730 \cr&\qquad\qquad
1731 +{{\omega}\over{c}}[p_+(A^{\rm b\,2}_-+2A^{\rm f\,2}_+)
1732 +q_+(A^{\rm b\,2}_++A^{\rm f\,2}_-)]
1733 +{{\omega}\over{c}}q_+
1734 {{A^{\rm b}_+ A^{\rm f}_+ A^{\rm f}_-}\over{A^{\rm b}_-}}
1735 \cos(\psi)\cr
1736 &=\eta
1737 +{{\omega}\over{c}}[3p_+(A^{\rm f\,2}_++A^{\rm b\,2}_-)
1738 +2q_+(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]
1739 -{{\omega}\over{c}}[3p_-(A^{\rm f\,2}_-+A^{\rm b\,2}_+)
1740 +2q_-(A^{\rm f\,2}_++A^{\rm b\,2}_-)]
1741 \cr&\qquad\qquad
1742 +{{\omega}\over{c}}\Big(
1743 q_+ {{A^{\rm f}_- A^{\rm b}_- A^{\rm b}_+}\over{A^{\rm f}_+}}
1744 -q_- {{A^{\rm f}_+ A^{\rm b}_+ A^{\rm b}_-}\over{A^{\rm f}_-}}
1745 -q_- {{A^{\rm b}_- A^{\rm f}_- A^{\rm f}_+}\over{A^{\rm b}_+}}
1746 +q_+ {{A^{\rm b}_+ A^{\rm f}_+ A^{\rm f}_-}\over{A^{\rm b}_-}}\Big)
1747 \cos(\psi)\cr
1748 &=\big\{{\rm\ Use\ Eqs.~(14)\ in\ substituting\ for\ terms\ in\ the\
1749 second\ line\ }\big\}\cr
1750 &=\eta
1751 +{{\omega}\over{c}}[(3p_+-2q_-)(A^{\rm f\,2}_++A^{\rm b\,2}_-)
1752 -(3p_--2q_+)(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]
1753 \cr&\qquad\qquad
1754 +\Big(
1755 {{1}\over{A^{\rm f}_+}}{{\partial A^{\rm f}_+}\over{\partial z}}
1756 +{{1}\over{A^{\rm f}_-}}{{\partial A^{\rm f}_-}\over{\partial z}}
1757 +{{1}\over{A^{\rm b}_+}}{{\partial A^{\rm b}_+}\over{\partial z}}
1758 +{{1}\over{A^{\rm b}_-}}{{\partial A^{\rm b}_-}\over{\partial z}}
1759 \Big){{\cos(\psi)}\over{\sin(\psi)}}\cr
1760 &=\bigg\{{\rm\ Use\ }{{1}\over{A^{\rm f\,b}_{\pm}}}
1761 {{\partial A^{\rm f,b}_{\pm}}\over{\partial z}}
1762 ={{\partial}\over{\partial z}}\ln A^{\rm f,b}_{\pm}{\rm\ and\ }
1763 \cos(\psi)/\sin(\psi)\equiv\cot(\psi)\bigg\}\cr
1764 &=\eta
1765 +{{\omega}\over{c}}[(3p_+-2q_-)(A^{\rm f\,2}_++A^{\rm b\,2}_-)
1766 -(3p_--2q_+)(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]
1767 \cr&\qquad\qquad
1768 +\Big(
1769 {{\partial}\over{\partial z}}\ln A^{\rm f}_+
1770 +{{\partial}\over{\partial z}}\ln A^{\rm f}_-
1771 +{{\partial}\over{\partial z}}\ln A^{\rm b}_+
1772 +{{\partial}\over{\partial z}}\ln A^{\rm b}_-
1773 \Big)\cot(\psi)\cr
1774 &=\eta
1775 +{{\omega}\over{c}}[(3p_+-2q_-)(A^{\rm f\,2}_++A^{\rm b\,2}_-)
1776 -(3p_--2q_+)(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]
1777 +\cot(\psi){{\partial}\over{\partial z}}
1778 \ln(A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-).\cr
1779 }
1780 $$
1781 Thus, by returning to the amplitude evolution described by Eqs.~(14) and by
1782 defining the short-hand notation
1783 $$
1784 r_{\pm}\equiv(3p_{\pm}-2q_{\mp})
1785 $$
1786 for the coefficients of the nonlinear terms, the evolution of the optical
1787 field can be summarized with the considerably simplified system of coupled
1788 and nonlinear differential equations
1789 $$
1790 \eqalignno{
1791 &{{\partial A^{\rm f\,2}_{\pm}}\over{\partial z}}
1792 =\pm2({{\omega}/{c}})q_{\pm} A^{\rm f}_+ A^{\rm f}_-
1793 A^{\rm b}_+ A^{\rm b}_- \sin(\psi),&(19{\rm a})\cr
1794 &{{\partial A^{\rm b\,2}_{\mp}}\over{\partial z}}
1795 =\pm2({{\omega}/{c}})q_{\pm} A^{\rm f}_+ A^{\rm f}_-
1796 A^{\rm b}_+ A^{\rm b}_- \sin(\psi),&(19{\rm b})\cr
1797 &{{\partial\psi}\over{\partial z}}
1798 =\eta+({{\omega}/{c}})[r_+(A^{\rm f\,2}_++A^{\rm b\,2}_-)
1799 -r_-(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]
1800 +\cot(\psi){{\partial}\over{\partial z}}
1801 \ln(A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-).&(19{\rm c})\cr
1802 }
1803 $$
1804 Notice that the absolute phases of the field components now have been entirely
1805 eliminated in favour of $\psi=\psi(z)$, as was the goal outset in the beginning
1806 of this section.
1807 The next step in the analysis is to eliminate also the relative phase from the
1808 equations of motion, so as to provide an autonomous system only involving the
1809 field amplitudes $A^{\rm f}_{\pm}$ and $A^{\rm b}_{\pm}$.
1810
1811 @ Elimination of the relative phase.
1812 The equations of motion given by Eqs.~(19) are considerably reduced in their
1813 algebraic complexity as compared to the original ones, as given by Eqs.~(1).
1814 However, there are still some simplifications which can be applied to further
1815 reduce the complexity, in particular then the elimination of the phase
1816 altogether, as will now be shown.
1817
1818 The trick to apply is to first multiply the left and right hand sides of
1819 Eq.~(19{\rm c}) with
1820 $A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-\sin(\psi)$, expanding the
1821 spatial derivative on the right hand side, and rearrange the terms to obtain
1822 $$
1823 \eqalign{
1824 &\cos(\psi){{\partial}\over{\partial z}}
1825 (A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-)
1826 -A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-
1827 \sin(\psi){{\partial\psi}\over{\partial z}}
1828 \cr&\qquad\qquad
1829 =-\{\eta
1830 +({{\omega}/{c}})[r_+(A^{\rm f\,2}_++A^{\rm b\,2}_-)
1831 -r_-(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]\}
1832 A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-\sin(\psi).\cr
1833 }
1834 \eqno{(20)}
1835 $$
1836 In this equation, we immediately find that the left hand side is the
1837 spatial derivative of
1838 $A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-\cos(\psi)$, so we may start
1839 looking for rewriting the right hand side as a spatial derivative as well,
1840 in which case we would end up with an integrable equation.
1841 In this search for a form of the right hand side which could be integrated,
1842 the appearance of the factor $A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-
1843 \sin(\psi)$ leads to using either of Eqs.~(19{\rm a}) or~(19{\rm b}) to
1844 express this term as a derivative of the amplitudes instead, hopefully leading
1845 to the right hand side as a polynomial form which is easily integrated.
1846 Thus, Eq.~(20) can be rewritten as
1847 $$
1848 \eqalign{
1849 {{\partial}\over{\partial z}}
1850 (A^{\rm f}_+ &A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-\cos(\psi))\cr
1851 &=-\{\eta+({{\omega}/{c}})[r_+(A^{\rm f\,2}_++A^{\rm b\,2}_-)
1852 -r_-(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]\}
1853 A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-\sin(\psi).\cr
1854 &=\big\{{\rm\ Use\ Eq.~(19a)\ in\ substituting\ for\ the\ factor\ }
1855 A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-\sin(\psi)\ \big\}\cr
1856 &=-\{\eta+({{\omega}/{c}})[r_+(A^{\rm f\,2}_++A^{\rm b\,2}_-)
1857 -r_-(A^{\rm f\,2}_-+A^{\rm b\,2}_+)]\}
1858 {{1}\over{2({{\omega}/{c}})q_+}}
1859 {{\partial A^{\rm f\,2}_+}\over{\partial z}}\cr
1860 &=\big\{{\rm\ Eliminate\ backward\ traveling\ components\ using\
1861 Eqs.~(18a)\ and ~(18b)}\ \big\}\cr
1862 &=-{{1}\over{q_+}}\Big\{{{\eta}\over{2({{\omega}/{c}})}}
1863 +\onehalf
1864 [r_+(2A^{\rm f\,2}_+-C_+/q_-)-r_-(2A^{\rm f\,2}_--C_-/q_+)]\Big\}
1865 {{\partial A^{\rm f\,2}_+}\over{\partial z}}\cr
1866 &=\big\{{\rm\ Eliminate\ }A^{\rm f\,2}_-{\rm\ using\ Eq.~(18c)}\ \big\}\cr
1867 &=-{{1}\over{q_+}}\Big\{{{\eta}\over{2({{\omega}/{c}})}}
1868 +\onehalf
1869 [r_+(2q_-A^{\rm f\,2}_+-C_+)/q_--r_-(2(I_{\rm f}-q_-A^{\rm f\,2}_+)
1870 -C_-)/q_+]\Big\}
1871 {{\partial A^{\rm f\,2}_+}\over{\partial z}}\cr
1872 &=\big\{{\rm\ Collect\ terms\ in\ powers\ of\ }A^{\rm f\,2}_+\ \big\}\cr
1873 &=-{{1}\over{q_+}}\Big\{\Big(
1874 {{\eta}\over{2({{\omega}/{c}})}}
1875 -{{(q_+r_+C_+-q_-r_-C_-)}\over{2q_+q_-}}
1876 -{{r_-I_{\rm f}}\over{q_+}}\Big)
1877 +{{(q_+r_++q_-r_-)}\over{q_+q_-}}q_-A^{\rm f\,2}_+
1878 \Big\} {{\partial A^{\rm f\,2}_+}\over{\partial z}}\cr
1879 &=\big\{{\rm\ Identify\ as\ differential\ of\ polynomial\ of\ form\ }
1880 p(A^{\rm f\,2}_+)\ \big\}\cr
1881 &=-{{1}\over{q_+}}{{\partial}\over{\partial z}}\Big\{\Big(
1882 {{\eta}\over{2({{\omega}/{c}})}}
1883 -{{(q_+r_+C_+-q_-r_-C_-)}\over{2q_+q_-}}
1884 -{{r_-I_{\rm f}}\over{q_+}}\Big)A^{\rm f\,2}_+
1885 +{{(q_+r_++q_-r_-)}\over{2q_+q_-}}q_-A^{\rm f\,4}_+
1886 \Big\}\cr
1887 }
1888 \eqno{(21)}
1889 $$
1890 which directly integrates to yield
1891 $$
1892 \eqalign{
1893 q_+ A^{\rm f}_+ A^{\rm f}_- A^{\rm b}_+ A^{\rm b}_-\cos(\psi)
1894 &=\Gamma/q_--\Big[\Big(
1895 {{\eta}\over{2({{\omega}/{c}})}}
1896 -{{(q_+r_+C_+-q_-r_-C_-)}\over{2q_+q_-}}
1897 -{{r_-I_{\rm f}}\over{q_+}}\Big)A^{\rm f\,2}_+
1898 +{{(q_+r_++q_-r_-)}\over{2q_+q_-}}q_-A^{\rm f\,4}_+
1899 \Big]\cr
1900 &=\Gamma/q_- -aA^{\rm f\,2}_+ - bq_-A^{\rm f\,4}_+,\cr
1901 }
1902 \eqno{(22)}
1903 $$
1904 where $\Gamma$ is a yet undetermined constant of integration, to be determined
1905 later on by the boundary conditions of the homogeneous domain, and where the
1906 short-hand notations
1907 $$
1908 a\equiv{{\eta}\over{2({{\omega}/{c}})}}
1909 -{{(q_+r_+C_+-q_-r_-C_-)}\over{2q_+q_-}}
1910 -{{r_-I_{\rm f}}\over{q_+}},\qquad
1911 b\equiv{{(q_+r_++q_-r_-)}\over{2q_+q_-}},
1912 \eqno{(24)}
1913 $$
1914 were introduced.
1915 The relative phase $\psi$ is now from Eq.~(22) determined in terms of the
1916 field amplitudes, and in order to get an expression for the factor $\sin(\psi)$
1917 which appears in the amplitude equations, for example in Eq.~(19a), we may
1918 employ the trigonometric identity $\sin^2(\psi)+\cos^2(\psi)=1$, from which
1919 we obtain Eq.~(19a) as
1920 $$
1921 \eqalign{
1922 &{{\partial A^{\rm f\,2}_+}\over{\partial z}}=(-1)^k 2({{\omega}/{c}})
1923 [q^2_+ A^{\rm f\,2}_+ A^{\rm f\,2}_- A^{\rm b\,2}_+ A^{\rm b\,2}_-
1924 -(\Gamma/q_- -aA^{\rm f\,2}_+ - bq_-A^{\rm f\,4}_+)^2]^{1/2},\cr
1925 }
1926 \eqno{(23)}
1927 $$
1928 where the undeterminacy of the sign of $\sin(\psi)=\pm(1-\cos^2(\psi))^{1/2}$
1929 is included in the factor $(-1)^k$, with~$k$ being a yet undetermined integer.
1930 In this nonlinear differential equation, also the relative phase~$\psi$ is
1931 eliminated, and the mathematical dimension of the problem at hand has been
1932 reduced from in total eight variables to the present four ones given by the
1933 linearly independent field amplitudes.
1934 It may be observed that in deriving Eq.~(23), the invariants of motion given
1935 by Eqs.~~(18) had to be employed, in order to be able to write the right-hand
1936 side as a total derivative.
1937 As the invariants of motion equally well still can be employed to further
1938 reduce the dimensionality of the problem by eliminating $A^{\rm f\,2}_-$,
1939 $A^{\rm b\,2}_+$ and $A^{\rm b\,2}_-$, we can at this stage easily see the
1940 outline to finally formulate the problem of wave propagation as one single
1941 differential equation involving only the single variable $A^{\rm f\,2}_+$.
1942
1943 @ Elimination of redundant field amplitudes.
1944 In this section, the dimensionality of the wave propagation problem is
1945 finally reduced to yield a one-dimensional problem in one single variable
1946 $A^{\rm f\,2}_+$.
1947 By eliminating the field amplitudes $A^{\rm f\,2}_-$,
1948 $A^{\rm b\,2}_+$ and $A^{\rm b\,2}_-$ with the use of the
1949 invariants of motion as given by Eqs.~(18), one obtains Eq.~(23) as
1950 $$
1951 \eqalign{
1952 {{\partial A^{\rm f\,2}_+}\over{\partial z}}
1953 &=(-1)^k 2({{\omega}/{c}})[q^2_+ A^{\rm f\,2}_+
1954 \underbrace{{q^{-1}_+}(I_{\rm f}-q_- A^{\rm f\,2}_+)
1955 }_{=A^{\rm f\,2}_-(z)}
1956 \underbrace{{q^{-1}_+}(I_{\rm f}-q_- A^{\rm f\,2}_+ - C_-)
1957 }_{=A^{\rm b\,2}_+(z)}
1958 \underbrace{{q^{-1}_-}(q_-A^{\rm f\,2}_+ - C_+)
1959 }_{=A^{\rm b\,2}_-(z)}
1960 \cr&\hskip270pt
1961 -{q^{-2}_-}(\Gamma -aq_-A^{\rm f\,2}_+ - bq^2_-A^{\rm f\,4}_+)^2]^{1/2}\cr
1962 &=(-1)^k 2{{({{\omega}/{c}})}\over{q_-}}[q_-A^{\rm f\,2}_+
1963 (I_{\rm f}-q_- A^{\rm f\,2}_+)
1964 (I_{\rm f}-q_- A^{\rm f\,2}_+ - C_-)
1965 (q_-A^{\rm f\,2}_+ - C_+)
1966 -(\Gamma -aq_-A^{\rm f\,2}_+ - bq^2_-A^{\rm f\,4}_+)^2]^{1/2}.\cr
1967 }
1968 \eqno{(24)}
1969 $$
1970 Hence, by taking the normalized and dimensionless field amplitude variable
1971 $v$ and the normalized and dimensionless coordinate $\zeta$ according to
1972 $$
1973 v\equiv q_-A^{\rm f\,2}_+,\qquad\zeta\equiv 2\omega z/c,\eqno{(25)}
1974 $$
1975 we obtain the normalized equation for the amplitude of the left circularly
1976 polarized forward traveling field component as
1977 $$
1978 {{\partial v}\over{\partial\zeta}}=(-1)^k
1979 [v(I_{\rm f}-v)(I_{\rm f}-v-C_-)(v-C_+)-(\Gamma-av-bv^2)^2]^{1/2}.
1980 \eqno{(26)}
1981 $$
1982 This nonlinear ordinary differential equation is now well suited for numerical
1983 evaluation, or even analytical as will be shown next. It should however be
1984 noticed that the field amplitudes $A^{\rm f}_+$, $A^{\rm f}_-$, $A^{\rm b}_+$,
1985 and $A^{\rm b}_-$ are all involved implicitly through the invariants of motion
1986 $I_{\rm f}$, $C_+$, and $C_-$, as given by Eqs.~(18), and also via the
1987 introduced short-hand notations $a$ and $b$ as introduced in Eq.~(24); also
1988 the relative phase $\psi$ of the fields evaluated at some coordinate $\zeta_0$
1989 enters as one parameter to encounter for, via the integration constant $\Gamma$
1990 and Eq.~(22).
1991
1992
1993 @ Formulation in terms of an elliptic integral.
1994 The nonlinear ordinary differential equation~(26) for $v=v(\zeta)$ can be
1995 formulated as
1996 $$
1997 {{\partial v}\over{\partial\zeta}}=(-1)^k[f(v)]^{1/2},\eqno{(27)}
1998 $$
1999 where
2000 $$
2001 f(v)\equiv a_4v^4+4a_3v^3+6a_2v^2+4a_1v+a_0
2002 $$
2003 is a quartic polynomial in the normalized field amplitudes $v$, and in which
2004 the coefficients $a_j$, for $j=1,\ldots,4$, are explicitly given in terms of
2005 the previously used algebraic symbols as
2006 $$
2007 \eqalignno{
2008 a_0&=-\Gamma^2,&(28{\rm a})\cr
2009 a_1&=(2\Gamma a-I^2_{\rm f}C_+ +I_{\rm f}C_+C_-)/4,&(28{\rm b})\cr
2010 a_2&=(I^2_{\rm f}+2\Gamma b+2I_{\rm f}C_+-I_{\rm f}C_-
2011 -a^2-C_+C_-)/6,&(28{\rm c})\cr
2012 a_3&=(-2I_{\rm f}+C_- -C_--2ab)/4,&(28{\rm d})\cr
2013 a_4&=1-b^2.&(28{\rm e})\cr
2014 }
2015 $$
2016 The solution $v(\zeta)$ is then from Eq.~(27) given by the integral equation
2017 $$
2018 \int^{v(\zeta)}_{v(\zeta_0)}
2019 {{dx}\over{(a_4x^4+4a_3x^3+6a_2x^2+4a_1x+a_0)^{1/2}}}
2020 =(-1)^k\int^{\zeta}_{\zeta_0}\,d\zeta=(-1)^k(\zeta-\zeta_0),
2021 \eqno{(29)}
2022 $$
2023 where $v_0\equiv v(\zeta_0)$ with $\zeta_0$ being an arbitrarily chosen
2024 reference coordinate $\zeta_0$ along the axis of wave propagation.
2025
2026 The left-hand side of Eq.~(29) constitutes an elliptic integral which
2027 principally can be reduced to the Legendre-Jacobi normal form by means
2028 of suitable homographic substitutions and the use of Jacobian elliptic
2029 functions.
2030 This implies the solving for the roots of the characteristic polynomial
2031 equation $f(v)=0$ which, however perfectly well analytically solvable,
2032 though is an algebraically very cumbersome task.
2033
2034 A more convenient method is to instead employ notation and method of solution
2035 by Weierstrass, which turns out to considerably simplify the algebra, and which
2036 provides an analytic solution which can be computed analytically in terms of
2037 the Weierstrass elliptic function~[11--13] $\wp(\zeta)=\wp(\zeta;g_2,g_3)$ with
2038 the quartic invariants $g_2$ and $g_3$ as
2039 $$
2040 \eqalign{
2041 g_2&\equiv a_0a_4-4a_1a_3+3a^2_2,
2042 \qquad % &\cr
2043 g_3\equiv
2044 \left\vert\matrix{a_0&a_1&a_2\cr a_1&a_2&a_3\cr a_2&a_3&a_4\cr}\right\vert
2045 =a_0a_2a_4+2a_1a_2a_3-a^3_2-a_0a^2_3-a^2_1a_4.\cr
2046 }
2047 $$
2048 The solution $v(\zeta)$ of Eq.~(29) is then explicitly given as
2049 $$
2050 v(\zeta)=v_0+
2051 {{\sqrt{f(v_0)}\wp'(\zeta)+{\textstyle{{1}\over{2}}}f'(v_0)
2052 [\wp(\zeta)-{\textstyle{{1}\over{24}}}f''(v_0)]
2053 +{\textstyle{{1}\over{24}}}f(v_0)f'''(v_0)}
2054 \over{2[\wp(\zeta)-{\textstyle{{1}\over{24}}}f''(v_0)]^2
2055 -{\textstyle{{1}\over{48}}}f(v_0)f^{\rm (iv)}(v_0)}}.
2056 \eqno{(30)}
2057 $$
2058 That the solution given by Eq.~(30) actually {\sl is} a solution to the
2059 differential equation~(27) can easily be verified using the MapleV code
2060 \medskip
2061 \leftskip=15mm
2062 {\obeyspaces\obeylines\tt
2063 restart:
2064 f:=a[0]*v{\tothepower}4+4*a[1]*v{\tothepower}3+6*a[2]*v{\tothepower}2%
2065 +4*a[3]*v+a[4];
2066 g[2]:=a[0]*a[4]-4*a[1]*a[3]+3*a[2]{\tothepower}2;
2067 g[3]:=a[0]*a[2]*a[4]+2*a[1]*a[2]*a[3]-a[2]{\tothepower}3-a[0]*a[3]%
2068 {\tothepower}2-a[1]{\tothepower}2*a[4];
2069 df[0]:=eval(f,v=v0):
2070 df[1]:=eval(diff(f,v{\dollar}1),v=v0):
2071 df[2]:=eval(diff(f,v{\dollar}2),v=v0):
2072 df[3]:=eval(diff(f,v{\dollar}3),v=v0):
2073 df[4]:=eval(diff(f,v{\dollar}4),v=v0):
2074 tmp[1]:=sqrt(df[0])*WeierstrassPPrime(z,g[2],g[3]):
2075 tmp[2]:=(1/2)*df[1]*(WeierstrassP(z,g[2],g[3])-(1/24)*df[2]):
2076 tmp[3]:=(1/24)*df[0]*df[3]:
2077 tmp[4]:=2*(WeierstrassP(z,g[2],g[3])-(1/24)*df[2]){\tothepower}2:
2078 tmp[5]:=(1/48)*df[0]*df[4]:
2079 v:=v0+(tmp[1]+tmp[2]+tmp[3])/(tmp[4]-tmp[5]):
2080 p:=a[0]*v{\tothepower}4+4*a[1]*v{\tothepower}3+6*a[2]*v{\tothepower}2%
2081 +4*a[3]*v+a[4]:
2082 testfunc:=(diff(v,z)){\tothepower}2-p:
2083 testfunc:=simplify(testfunc);\par}
2084 \leftskip=0mm
2085 \medskip
2086
2087 @ Boundary conditions.
2088
2089 @*Revision history of the program.
2090 \medskip
2091
2092 \citem[2002-10-28]{[v.1.0]} \.{<fredrik.jonsson@@proximion.com>}\hfill\break
2093 First properly working version of the \magbragg\ program, written in plain
2094 (\ANSI-conformant) \CEE.
2095
2096 \citem[2002-11-15]{[v.1.1]} \.{<fredrik.jonsson@@proximion.com>}\hfill\break
2097 Minor changes to the blocks of the program for the generation of reflection
2098 spectra, providing data for a talk at the MRS 2002 Fall Meeting
2099 [F.~Jonsson and C.~Flytzanis, {\sl Theoretical model for magneto-optical Bragg
2100 gratings}, Talk O4.7 presented at the 2002 Materials Research
2101 Society (MRS) Fall Meeting, Boston, United States (December 2--6, 2002)].
2102
2103 \citem[2003-02-18]{[v.1.2]} \.{<fredrik.jonsson@@proximion.com>}\hfill\break
2104 Modified the part of the program that writes the spatial optical field
2105 distribution along the grating to file, so that both forward and backward
2106 left and right circularly polarized components of the propagating fields are
2107 written to file (using the \.{--fieldevolution} command line option).
2108
2109 \citem[2003-02-25]{[v.1.3]} \.{<fredrik.jonsson@@proximion.com>}\hfill\break
2110 Transferred all source code of the \magbragg\ program from \CEE\ to \CWEB.
2111 For information on the \CWEB\ programming language, see
2112 \.{http://www.literateprogramming.com}.
2113
2114 \citem[2003-04-18]{[v.1.4]} \.{<fredrik.jonsson@@proximion.com>}\hfill\break
2115 Added the \.{--modifylayer} option, enabling the user to manually modify
2116 an arbitrary layer of the grating structure in linear as well as nonlinear
2117 optical parameters, or modifying the layer thickness.
2118
2119 \citem[2003-04-28]{[v.1.5]} \.{<fredrik.jonsson@@proximion.com>}\hfill\break
2120 Added the \.{--intensityevolution} option.
2121
2122 \citem[2003-07-15]{[v.1.6]} \.{<hakkasberra@@hotmail.com>}\hfill\break
2123 Added some points in the documentation regarding the philosophy behind
2124 creating two-dimensional plots from topological graphs of Stokes-parameter
2125 hypersurfaces.
2126
2127 \citem[2003-07-22]{[v.1.7]} \.{<hakkasberra@@hotmail.com>}\hfill\break
2128 Added the possibility of specifiying whether the electrical field displacement
2129 or Stokes parameters should be written to file, when saving the intra-grating
2130 field distribution via the \.{--fieldevolution} command line option.
2131
2132 \citem[2003-07-23]{[v.1.8]} \.{<hakkasberra@@hotmail.com>}\hfill\break
2133 Changed the reference phase of the calculated, final intra-grating optical
2134 field, so that the main axis of the polarization ellipse always is directed
2135 along the $x$-axis (corresponding to $S_2=0$ in a Stokes parameter
2136 description) at the beginning of the grating, at $z=0$.
2137 (The naturally appearing reference phase is relative the output field, at the
2138 end of the grating, since $z=L$ is the spatial starting point in the inverse
2139 algorithm.)
2140
2141 \citem[2003-08-04]{[v.1.9]} \.{<hakkasberra@@hotmail.com>}\hfill\break
2142 Added the \.{--normalize\_length\_to\_um} option, which causes the program
2143 to write spatial distances in micrometers instead of meters.
2144 Useful for pre-normalizing data prior to importing it into programs
2145 for making graphs of the spatial intra-grating distribution of intensity
2146 or polarization state.
2147 Also added the \.{--normalize\_intensity} option, which causes the program
2148 to write the intensity-related Stoke parameter $S_0(z)$ as the quote
2149 with the input intensity instead, as $S_0(z)/S_0(0)$.
2150
2151 \citem[2003-08-07]{[v.1.10]} \.{<hakkasberra@@hotmail.com>}\hfill\break
2152 Added the \.{--intensityspectrumfile} option, to save a regular intensity
2153 spectrum as function of wavelength, and not only just the complex reflection
2154 and transmission spectra.
2155 Using this option, the character string following it will be used as the base
2156 filename for the generated intensity reflection spectrum, which will be named
2157 $\langle$basename$\rangle${\tt{.irsp.dat}}, and the intensity transmission
2158 spectrum, which will be named $\langle$basename$\rangle${\tt{.itsp.dat}}.
2159 The format of these files are simply that the first column is the vacuum
2160 wavelength in nanometers, and the second column the reflection or transmission
2161 coefficients.
2162 In addition to these two files, an additional file
2163 $\langle$basename$\rangle${\tt{.chec.dat}} will be generated, containing
2164 the sum of the respective reflection and transmission coefficients.
2165 Ideally, the second column of this file should be identically one;
2166 any deviation from this is an artefact of the limited numerical precision
2167 in the simulation, and can be taken as a measure on the correctness
2168 of the obtained data.
2169
2170 \citem[2003-08-19]{[v.1.11]} \.{<hakkasberra@@hotmail.com>}\hfill\break
2171 Added the \.{--normalize\_ellipticity} option, which switch the program
2172 to writing the normalized ellipticity $S_3/S_0$ (with a numerical value
2173 between $-1$ and~$1$) instead of the third Stokes parameter, whenever it
2174 is to be written to disk.
2175 Also added the \.{--scale\_stokesparams} $\langle a\rangle$ option, which
2176 at the stage of saving the Stokes parameters to disk divides the sets
2177 $(S_0,S_1,S_2,S_3)$, $(W_0,W_1,W_2,W_3)$, and $(V_0,V_1,V_2,V_3)$ by the
2178 scalefactor $\langle a\rangle$ prior to writing them to disk.
2179 This is typically a good thing to do if the program that is to post-analyze
2180 the generated data has a poor way of handling large numbers (typically larger
2181 than $\sim 10^{14}$ for the squared amplitudes of the components of the
2182 electric field).
2183
2184 \citem[2003-08-20]{[v.1.12]} \.{<hakkasberra@@hotmail.com>}\hfill\break
2185 Modified the \.{Makefile} to provide a somewhat more intelligent check on
2186 which files that need to be updated on compilation. Also updated section five,
2187 {\it Compiling the source code}, of the documentation of the program.
2188
2189 \citem[2003-08-23]{[v.1.13]} \.{<hakkasberra@@hotmail.com>}\hfill\break
2190 Added a check in the blocks that saves the full grating structure to file,
2191 so that the program now fully recognizes the \.{--normalize\_length\_to\_um}
2192 option.
2193
2194 \citem[2003-10-06]{[v.1.14]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
2195 Added a few clarifying paragraphs on the conventions used for the
2196 magneto-optical material parameters and the exact conventions for the
2197 circularly polarized modes as here used.
2198
2199 \citem[2003-12-10]{[v.1.15]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
2200 Added a few clarifying paragraphs on the scaling of the Stokes parameters
2201 that are written to file after the finished calculations.
2202 As a default, and as a matter of convention in electrodynamics in \SI\ units,
2203 all Stokes parameters are given in ${\rm V}^2/{\rm m}^2$, through their
2204 definition.
2205 For example, the incident field (which is calculated by the program in
2206 this inverse formulation of the problem) is expressed in terms of the Stokes
2207 parameters as
2208 $$
2209 \eqalign{
2210 S_0&=\vert E^{\rm f}_{0_+}\vert^2+\vert E^{\rm f}_{0_-}\vert^2,\qquad
2211 S_1=2\re[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}],\cr
2212 S_3&=\vert E^{\rm f}_{0_+}\vert^2-\vert E^{\rm f}_{0_-}\vert^2,\qquad
2213 S_2=2\im[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}].\cr
2214 }
2215 $$
2216 However, the direct interpretation of these quantities in terms of squared
2217 Volts per square metres is sometimes somewhat inconvenient; therefore, those
2218 parameters can be scaled to give an interpretation of the intensity (in regular
2219 \SI\ units measured in Watts per square metres),
2220 as $S'_k=(\varepsilon_0 c/2)S_k$, or explicitly
2221 $$
2222 \eqalign{
2223 S'_0&=(\varepsilon_0 c/2)
2224 [\vert E^{\rm f}_{0_+}\vert^2+\vert E^{\rm f}_{0_-}\vert^2],\qquad
2225 S'_1=(\varepsilon_0 c/2)
2226 2\re[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}],\cr
2227 S'_3&=(\varepsilon_0 c/2)
2228 [\vert E^{\rm f}_{0_+}\vert^2-\vert E^{\rm f}_{0_-}\vert^2],\qquad
2229 S'_2=(\varepsilon_0 c/2)
2230 2\im[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}].\cr
2231 }
2232 $$
2233 In this representation, $S'_0$ is now identical to the incident intensity
2234 $I_{\rm in}$ [${\rm W}/{\rm m}^2$].
2235 In order to have those scaled Stokes parameters $S'_k$ written to file,
2236 rather than the default ones, one convenient possibility is to use the
2237 previously added \.{--scale\_stokesparams} option, to include
2238 \.{--scale\_stokesparams 1.327209e-3} at the command line when invoking
2239 the program. This numerical value of the scaling is obtained from
2240 $$
2241 \eqalign{
2242 \varepsilon_0 c/2
2243 &=(8.854187817\ldots\times 10^{-12}\ {\rm F}/{\rm m})
2244 \times(2.99792458\times 10^8\ {\rm m}/{\rm s})/2\cr
2245 &\approx 1.327209\times 10^{-3}\ {\rm F}/{\rm s}.\cr
2246 }
2247 $$
2248 In regular \SI\ units as here used, the physical dimension of the
2249 quantity $\varepsilon_0 c/2$ is $[({\rm A}\cdot{\rm s})/({\rm V}\cdot{\rm m})]
2250 \cdot[{\rm m}/{\rm s}]=[{\rm A}/{\rm V}]$, so the physical dimension of
2251 $(\varepsilon_0 c/2)S_k$ is hence $[{\rm A}/{\rm V}]\cdot[{\rm V}^2/{\rm m}^2]
2252 =[{\rm W}/{\rm m}^2]$, as expected for an intensity measure (power per unit
2253 area in the plane orthogonal to the direction of wave propagation).
2254
2255 \citem[2003-12-10]{[v.1.16]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
2256 Added the \.{--intensityinfo} option, in order to track down the maximum
2257 optical intensity that is present inside (or outside) the magneto-optical
2258 grating structure.
2259
2260 \citem[2003-12-17]{[v.1.17]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
2261 Added the \.{--trmtraject} option, in order to check the polarization
2262 state evolution of the transmitted light for a varying incident intensity,
2263 keeping the incident polarization state fixed.
2264 Typically, we use two-dimensional interpolation to get the trajectory
2265 of the transmitted polarization state as function of the incident light
2266 (the incident light typically being of a fixed polarization state, with
2267 a varying intensity). This trajectory can now be used as input to the
2268 \magbragg\ program in the invserse formulation of the problem, for the
2269 generation of Poincar\'e maps corresponding to cases with constant incident
2270 polarization states and varying input intensity.
2271
2272 \citem[2004-03-10]{[v.1.18]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
2273 Last week in Stockholm I bought a new computer, a silvery Apple Macintosh
2274 Powerbook~G4 running Apple \OSX\ (10.3 Panther). As I recompiled the
2275 \CWEB\ source for the \magbragg\ program, still using the \GNU\ \CEE-compiler
2276 (\GCC) for the executable file, I got complaints about the definition of the
2277 \.{cabs} routine as shadowing a previously defined function.
2278 This is a complaint that I never previously had with \GCC\ under \CYGWIN\ and
2279 Windows 2000, and it is obvious that the \.{math.h} header file of \GCC\ has
2280 been slightly changed lately.
2281 However, after globally changing the routine name from \.{cabs} to
2282 \.{cdabs} (which anyway is better since the new name also indicates that
2283 it takes complex numbers in {\sl double}\/ precision as input), there
2284 were no more complaints, and the program now executes as expected in the
2285 \OSX\ environment.
2286
2287 \citem[2004-04-23]{[v.1.19]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
2288 Fixed a bug in the initialization of chirped modulation of magneto-optical
2289 parameters, for which the last $z$-coordinate of the discretized grating,
2290 $z_N$, never was set.
2291
2292 \citem[2004-04-24]{[v.1.20]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
2293 Added the \.{--gyroperturb} option in order to provide a way of locally
2294 manipulating and perturbing the gyration constant of the medium. This option
2295 was added since I got this idea that a perturbation introduced by external
2296 means, for example via a current carrying wire oriented orthogonally to the
2297 direction of propagation of light in the Faraday configuration, could be used
2298 for opening up a window in the transmission window of a chirped Bragg grating.
2299 The syntax of the \.{--gyroperturb} option is simply \.{--gyroperturb}
2300 $\langle z_{\rm p}\rangle$ $\langle a_{\rm p}\rangle$
2301 $\langle w_{\rm p}\rangle$, where $\langle z_{\rm p}\rangle$ is the centre
2302 position, $\langle a_{\rm p}\rangle$ is the zero-to-peak amplitude of change of
2303 the gyration constant $g$, and $\langle w_{\rm p}\rangle$ is the corresponding
2304 full width half maximum of the perturbation.
2305
2306 \citem[2004-04-26]{[v.1.21]} \.{<jonsson@@uni-wuppertal.de>}\hfill\break
2307 Added the \.{--stokesspectrum} option, so that it is possible to generate
2308 full Poincar\'e maps of the spectral properties of a magneto-optical Bragg
2309 grating. However, after having introduced this option, I get the following
2310 message from \CWEAVE:
2311 \citindent
2312 {\obeyspaces\obeylines\tt
2313 ~ cweave magbragg
2314 ~ This is CWEAVE, Version 3.64 (Web2C 7.5.2)
2315 ~ *1*3*4*5*6*7*36*37*38*55*60*67*68*70
2316 ~ Writing the output file...*1*3*4*5*6*7*36*37*38*55*60
2317 ~ ! Sorry, scrap/token/text capacity exceeded. (l. 2912)
2318 ~ sprintf(outfilename\_w1,"\%s\%s",
2319 ~ outfilename,".w1.dat");
2320 ~ (That was a fatal error, my friend.)
2321 ~ make: *** [magbragg.tex] Error 1}
2322 \medskip
2323 \citindent
2324 The \CEE\ code generated by \CTANGLE\ compiles and executes perfectly, but
2325 obviously something is obstructing \CWEAVE\ to properly generating the
2326 \TeX\ code for the documentation. Most annoying.
2327
2328 \citem[2004-05-07]{[v.1.22]} \.{<fredrik.jonsson@@nmrc.ie>}\hfill\break
2329 Added the \.{--displaysurrmedia}, which toggles if the program should write
2330 also the surrounding media to saved grating profiles or not.
2331 This is useful if one wish to just generate some part of a grating for a figure
2332 illustrating a particular refractive index distribution, cut exactly to the
2333 specified spatial interval of interest.
2334 As default, the \magbragg\ program writes also the surrounding media to the
2335 ends of the grating file, so by using this option only once at the command
2336 line forces the program to cut the grating file exactly to the specified
2337 spatial interval.
2338 The annoying compilation error from 2004-04-26 is still present, preventing
2339 me from generating the documentation.
2340
2341 \citem[2004-07-03]{[v.1.23]} \.{<fredrik.jonsson@@nmrc.ie>}\hfill\break
2342 I am in Germany for laboratory work in Wuppertal during two weeks, and this
2343 free Saturday morning I decided to once and for all trace down and eliminate
2344 the annoying parsing error that \CWEAVE\ produces.
2345 (I am currently writing this entry at Starbucks in Cologne, being the only
2346 caf\'e in town with a non-smoking policy $\ldots$)
2347 Since this particular error seemed to stem from the block related to parsing
2348 of the command line options, and since this block anyway by now has grown
2349 over any reasonable size, I decided split it into several smaller blocks
2350 instead. Having done so, \CWEAVE\ immediately accepted the \CWEB\ source
2351 and extracted the \TeX\ source, which subsequently were compiled without
2352 any errors. It thus seems like I on April 26th must have passed some upper
2353 size limit on the source allowed in one single \CWEB\ block.
2354 Not that I really expected such a built-in constraint in \CWEB, but in some
2355 sense I can agree on that by putting some hard upper limit, one will at least
2356 force the programmer to structure the code into smaller blocks, probably
2357 increasing the readability.
2358 As of today, the \CWEB\ source for the \magbragg\ program (source file
2359 \.{magbragg.w}) comprises 171418 bytes and 4138 lines of code.
2360 The size of the compiled executable is 70340 bytes, and the PostScript
2361 documentation is 808345 bytes (92 pages of A4 output in 10pt).
2362
2363 \citem[2004-11-14]{[v.1.24]} \.{<fredrik.jonsson@@nmrc.ie>}\hfill\break
2364 Added the \.{--apodize} option, to be able to get rid of some unwanted Gibbs
2365 oscillations at the ends of the reflectance band of spectra generated for
2366 chirped gratings, aimed to generate nice spectra for a talk to be presented at
2367 the MRS 2004 Fall Meeting [F.~Jonsson and C.~Flytzanis, {\sl Artificially
2368 Induced Perturbations in Chirped Magneto-Optical {Bragg} Gratings}, in
2369 {\sl Magneto-Optical Materials for Photonics and Recording}, Eds.~{Koji Ando,
2370 W. Challener, R. Gambino and M. Levy}, Mater. Res. Soc. Symp. Proc. {\bf 834},
2371 J1.8 ({Materials Research Society}, {Warrendale}, 2005)].
2372 Also added the \.{--phasejump} option (short form \.{-j}) to allow
2373 specification of a discrete phase jump to appear in sinusoidal or chirped
2374 grating structures.
2375 In adding these options, the same error as of April 26th appeared again,
2376 in the block related to the parsing of command line options.
2377 Since this block has again grown over any reasonably readable size, I hence
2378 started to split this block into smaller \CWEB\ sub-blocks, after which there
2379 were no further complaints from \CWEAVE\ in extracting the \TeX\ documentation
2380 of the program.
2381 As of today, the \CWEB\ source for the \magbragg\ program (source file
2382 \.{magbragg.w}) comprises 179296 bytes and 4312 lines of code.
2383 The size of the compiled executable is 74436 bytes, and the PostScript
2384 documentation is 835671 bytes (95 pages of A4 output in 10pt).
2385
2386 \citem[2004-12-04]{[v.1.25]} \.{<fredrik.jonsson@@nmrc.ie>}\hfill\break
2387 Changed the way of output of Stokes parameters to file. Previously, the
2388 program always opened files with extensions \.{.s0.dat},$\ldots$,
2389 \.{.s3.dat} for output of the incident $S_k$ parameters (and similarly
2390 for the reflected and transmitted Stokes parameters $V_k$ and $W_k$),
2391 irregardless of the number of sampling points in intensity and ellipticity.
2392 However, for sampling of spectral characteristics we most often only encounter
2393 a simulation performed at one single intensity and ellipticity ($M_{\rm i}=1$
2394 and $M_{\rm e}=1$), which means that, previously, twelve empty files were
2395 opened and closed for each simulation. This is now changed so that the
2396 program only opens those files for output in ``topological'' mode of
2397 operation, in which $M_{\rm i}\ge2$ and $M_{\rm e}\ge2$. Compiling the
2398 \CEE\ code with \GCC\ then caused some novel complaints using the
2399 \.{--pedantic} option, regarding the risk of using the associated file
2400 pointers uninitialized. That this complaint appear at all might be an
2401 indicator that \GCC\ is not that strict in checking the logical state of
2402 the program in which the file pointers were to be used, since I verified
2403 that there was no reason whatsoever for the warnings.
2404 The ``quick-and-dirty'' solution to get rid of the annoying and non-justified
2405 warnings was to simply initialize all file pointers to \.{NULL} at the
2406 beginning of the program.
2407 Also started to write a separate section on all command line options currently
2408 supported by \magbragg. The documentation has now for quite a while been in
2409 urgent need of such a section, since the number of options have grown quite
2410 a lot during the last year. As a start, the documentation for the
2411 \.{--grating}, \.{--phasejump}, and \.{--apodize} options was updated.
2412 As of today, the \CWEB\ source for the \magbragg\ program (source file
2413 \.{magbragg.w}) comprises 192945 bytes and 4611 lines of code.
2414 The size of the compiled executable is 74436 bytes, and the PostScript
2415 documentation is 873757 bytes (102 pages of A4 output in 10pt).
2416
2417 \citem[2004-12-05]{[v.1.26]} \.{<fredrik.jonsson@@nmrc.ie>}\hfill\break
2418 Added the feature that the program now uses \.{time.h} to extrapolate
2419 what the estimated time of arrival (ETA) of the simulation is.
2420 This is useful for predicting the total simulation time for large numbers of
2421 sampled layers, such in long sinusoidal or chirped gratings. The estimation
2422 is simply done via linear extrapolation as
2423 $$
2424 t_{\rm ETA}=t_0+{{t-t_0}\over{\{\%\,{\rm finished}\}}}\times100,
2425 $$
2426 to produce run-time messages of the form
2427 \medskip
2428 \leftskip=35mm
2429 {\obeyspaces\obeylines\tt
2430 Program execution started Sun Dec 5 20:55:27 2004
2431 ----------------------------------------------------------------
2432 ~...10 percent finished... ETA: Sun Dec 5 21:44:57 2004
2433 ~...20 percent finished... ETA: Sun Dec 5 21:42:12 2004
2434 ~...30 percent finished... ETA: Sun Dec 5 21:41:17 2004
2435 ~...40 percent finished... ETA: Sun Dec 5 21:40:49 2004
2436 ~...50 percent finished... ETA: Sun Dec 5 21:40:33 2004
2437 ~...60 percent finished... ETA: Sun Dec 5 21:40:20 2004
2438 ~...70 percent finished... ETA: Sun Dec 5 21:40:12 2004
2439 ~...80 percent finished... ETA: Sun Dec 5 21:40:05 2004
2440 ~...90 percent finished... ETA: Sun Dec 5 21:40:01 2004
2441 ~...done. Elapsed execution time: 2644 s
2442 ----------------------------------------------------------------
2443 Program execution closed Sun Dec 5 21:39:31 2004\par}
2444 \leftskip=0mm
2445 \medskip
2446 \citindent
2447 Also wrote documentation on command-line specifications of chirped gratings,
2448 and cleaned up the declarations of local variables somewhat.
2449 As of today, the \CWEB\ source for the \magbragg\ program (source file
2450 \.{magbragg.w}) comprises 203691 bytes and 4830 lines of code.
2451 The size of the compiled executable is 74532 bytes, and the PostScript
2452 documentation is 898974 bytes (105 pages of A4 output in 10pt).
2453
2454 \citem[2004-12-11]{[v.1.27]} \.{<fredrik.jonsson@@nmrc.ie>}\hfill\break
2455 Added two schematic figures to the documentation on the discretization
2456 of the grating.
2457
2458 \citem[2005-04-22]{[v.1.28]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2459 Removed an unused block in the code for saving spectra to file, after having
2460 thoroughly checked that it would have no affect on the backward compatibility
2461 of the program to earlier data generated. Also increased the numerical
2462 precision of the data written to file for the intensity reflection and
2463 transmission spectra, which now yields \.{\%-10.8f} in floating point
2464 conversion as conforming to \ANSICEE.
2465
2466 \citem[2005-04-28]{[v.1.29]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2467 Added four blocks of text in the documentation of command line options.
2468
2469 \citem[2005-06-08]{[v.1.30]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2470 In Stockholm for two months. Added the standard \CEE\ library function
2471 |fflush()| for enforcement in writing of all buffered calculated data to file.
2472 This in order to be able to follow the process of calculation more direct by
2473 file inspection. When executing \magbragg\ under the new distribution of
2474 \CYGWIN\ for Windows~XP, the block for the displaying of status of calculation
2475 suddenly behaves odd, showing estimated execution times well below any
2476 reasonable estimated time of arrival, and also going well beyond the maximum
2477 100 percent in relative execution progress. This will have to be checked, and
2478 has never previously appeared when compiling with \GCC, neither under Apple
2479 \OSX (BSD), nor under \CYGWIN.
2480
2481 \citem[2005-08-10]{[v.1.31]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2482 Back in Southampton again with my family after a hot summer. Wrote the code
2483 for the |strip_away_path()| routine originally for the \poincare\ program and
2484 immediately decided to adopt the code also into the \magbragg\ program in
2485 order to finally solve the problem with long path strings that appear in
2486 the program name string whenever poincare is called with an explicit path
2487 specified at the command line. The call to the |strip_away_path()| routine
2488 is located in the beginning of the block for command line parsing.
2489 As of today, the \CWEB\ source for the \magbragg\ program (source file
2490 \.{magbragg.w}) comprises 219666 bytes and 5172 lines of code.
2491 The size of the compiled (\CYGWIN) executable is 96647 bytes, and the
2492 PostScript documentation is 967813 bytes (112 pages of A4 output in 10pt).
2493
2494 \citem[2005-08-11]{[v.1.32]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2495 Cleaned up the blocks for displaying on-screen help messages. Wrote two
2496 routines |hl()| and |fhl()| to assist a coherent style in displaying help on
2497 command-line options.
2498
2499 \citem[2005-08-19]{[v.1.33]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2500 Fixed two remaining bugs in the |hl()| and |fhl()|, in which \GCC\ under \OSX\
2501 this evening complained that long unsigned integers were sent to standard
2502 terminal output using the regular integer conversion of standard \CEE.
2503 This warning did not show as the code was compiled with \GCC\ under \CYGWIN,
2504 hence there seem to be some discrepancy between different ports of the
2505 otherwise reliable compilator.
2506
2507 \citem[2005-09-15]{[v.1.34]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2508 Corrected an error in the documentation of the options concerning
2509 specifications of chirped sinusoidal grating structures. The chirp parameter
2510 is now properly defined and described by example.
2511
2512 \citem[2005-12-31]{[v.1.35]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2513 The theoretical description of the algorithm behind the solving of the inverse
2514 problem in the \magbragg\ program is included in an article which today has
2515 been accepted for publication in Physical Review Letters.
2516 Added a section on the theoretical basis for the algorithm behind the program,
2517 deriving the algorithm from the electromagnetic wave equation in a manner
2518 similar to the description which soon will appear in the published article.
2519
2520 \citem[2006-01-22]{[v.1.36]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2521 Added a section on the Butcher and Cotter convention of degeneracy factors in
2522 nonlinear optics, picked from my {\sl Lecture Notes on Nonlinear Optics} from
2523 the course I gave at the Royal Institute of Technology in 2003. Also edited the
2524 section on the theoretical basis for the algorithm of calculation and added a
2525 figure describing the representation of the polarization state on the
2526 Poincar\'e sphere.
2527 As of today, the \CWEB\ source for the \magbragg\ program (source file
2528 \.{magbragg.w}) comprises 252108 bytes and 5937 lines of code.
2529 The size of the compiled (\OSX) executable is 78808 bytes, and the
2530 PostScript documentation is 1651977 bytes (122 pages of A4 output in 10pt).
2531
2532 \citem[2006-01-24]{[v.1.37]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2533 Added a significant number of comments on the use of variables and their
2534 initialization. Also cleaned up and added more instructive text on the actual
2535 compilation of the \CWEB\ source code.
2536 As of today, the \CWEB\ source for the \magbragg\ program (source file
2537 \.{magbragg.w}) comprises 261933 bytes and 6086 lines of code.
2538 The size of the compiled (\OSX) executable is 78828 bytes, and the
2539 PostScript documentation is 1673601 bytes (125 pages of A4 output in 10pt).
2540
2541 \citem[2006-02-09]{[v.1.38]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2542 As I now for a longer time of period have sketched on implementing the exact
2543 methodology of solution for the waves inside the homogeneous elements of the
2544 discretized medium, I today added the first sections on the theoretical part
2545 of a rigorous theory of wave propagation.
2546 As of today, the \CWEB\ source for the \magbragg\ program (source file
2547 \.{magbragg.w}) comprises 305905 bytes and 7095 lines of code.
2548 The size of the compiled (\OSX) executable is 88002 bytes, and the
2549 PostScript documentation is 1778021 bytes (135 pages of A4 output in 10pt).
2550
2551 \citem[2006-02-11]{[v.1.39]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2552 Added two sections on how the amplitude evolution in the rigorous theory
2553 of wave propagation actually can be reduced to the evaluation of an elliptic
2554 function of the standard form
2555 $$
2556 \int^{v(\zeta)}_{v(\zeta_0)}{{dv}
2557 \over{({a_4v^4+a_3v^3+a_2v^2+a_1v+a_0})^{1/2}}},
2558 $$
2559 with its solution $v(z)$ expressed in terms of the Weierstrass elliptic
2560 function $\wp(\zeta;g_2,g_3)$ with the invariants $g_2$ and $g_3$
2561 explicitly expressed in terms of $a_0$, $a_1$, $a_2$, $a_3$, and $a_4$.
2562
2563 \citem[2006-03-13]{[v.1.40]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2564 After having spent some considerable time trying to verify that the integral
2565 equation
2566 $$
2567 \int^{v(\zeta)}_{v(\zeta_0)}{{dv}
2568 \over{({a_4v^4+4a_3v^3+6a_2v^2+4a_1v+a_0})^{1/2}}},
2569 $$
2570 which naturally appear in the rigorous theory of cross-phase modulation in
2571 nonlinear magneto-optical media, really has the explicit solution
2572 $$
2573 v(\zeta)=v_0+
2574 {{\sqrt{f(v_0)}\wp'(\zeta)+{\textstyle{{1}\over{2}}}f'(v_0)
2575 [\wp(\zeta)-{\textstyle{{1}\over{24}}}f''(v_0)]
2576 +{\textstyle{{1}\over{24}}}f(v_0)f'''(v_0)}
2577 \over{2[\wp(\zeta)-{\textstyle{{1}\over{24}}}f''(v_0)]^2
2578 -{\textstyle{{1}\over{48}}}f(v_0)f^{\rm (iv)}(v_0)}}.
2579 $$
2580 with quartic invariants
2581 $$
2582 g_2\equiv a_0a_4-4a_1a_3+3a^2_2,\qquad
2583 g_3\equiv
2584 \left\vert\matrix{a_0&a_1&a_2\cr a_1&a_2&a_3\cr a_2&a_3&a_4\cr}\right\vert
2585 =a_0a_2a_4+2a_1a_2a_3-a^3_2-a_0a^2_3-a^2_1a_4,
2586 $$
2587 I today realized that the first edition of E.~T. Whittaker's {\sl A Course of
2588 Modern Analysis} (Cambridge University Press, Cambridge, 1902) actually has
2589 a printing error in one of the terms in the denominator of the solution.
2590 This error has obviously been fixed in later editions of the book, for example
2591 in E.~T.~Whittaker and G.~N.~Watson, {\sl A Course of Modern Analysis}, 4th
2592 Reprinted Edn. (Cambridge University Press, Cambridge, 1996), ISBN
2593 0-521-58807-3, but it caused be a considerable nuisance before I was able to
2594 track the error down. The verification of the solution was checked using the
2595 following blocks of MapleV code:
2596 \medskip
2597 \leftskip=30mm
2598 {\obeyspaces\obeylines\tt
2599 restart:
2600 f:=a[0]*v{\tothepower}4+4*a[1]*v{\tothepower}3+6*a[2]*v{\tothepower}2%
2601 +4*a[3]*v+a[4];
2602 g[2]:=a[0]*a[4]-4*a[1]*a[3]+3*a[2]{\tothepower}2;
2603 g[3]:=a[0]*a[2]*a[4]+2*a[1]*a[2]*a[3]-a[2]{\tothepower}3-a[0]*a[3]%
2604 {\tothepower}2-a[1]{\tothepower}2*a[4];
2605 df[0]:=eval(f,v=v0):
2606 df[1]:=eval(diff(f,v{\dollar}1),v=v0):
2607 df[2]:=eval(diff(f,v{\dollar}2),v=v0):
2608 df[3]:=eval(diff(f,v{\dollar}3),v=v0):
2609 df[4]:=eval(diff(f,v{\dollar}4),v=v0):
2610 tmp[1]:=sqrt(df[0])*WeierstrassPPrime(z,g[2],g[3]):
2611 tmp[2]:=(1/2)*df[1]*(WeierstrassP(z,g[2],g[3])-(1/24)*df[2]):
2612 tmp[3]:=(1/24)*df[0]*df[3]:
2613 tmp[4]:=2*(WeierstrassP(z,g[2],g[3])-(1/24)*df[2]){\tothepower}2:
2614 tmp[5]:=(1/48)*df[0]*df[4]:
2615 v:=v0+(tmp[1]+tmp[2]+tmp[3])/(tmp[4]-tmp[5]):
2616 p:=a[0]*v{\tothepower}4+4*a[1]*v{\tothepower}3+6*a[2]*v{\tothepower}2%
2617 +4*a[3]*v+a[4]:
2618 testfunc:=(diff(v,z)){\tothepower}2-p:
2619 testfunc:=simplify(testfunc);\par}
2620 \leftskip=0mm
2621 \medskip
2622 \citindent
2623 As this result was the only missing link in the formulation of an explicit
2624 solution to the wave propagation problem in nonlinear magneto-optical media,
2625 taking into account also weakly phase-mismatched nonlinear source terms, the
2626 only task remaining now is to formulate the algorithm for solving the inverse
2627 problem using this more stringent method.
2628
2629 \citem[2006-03-20]{[v.1.41]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2630 Added a few paragraphs on the rigorous theory of wave propagation, clarifying
2631 the role of the constant of integration $\Gamma$ and its calculation from the
2632 phase of the transmitted field and the amplitude-related invariants of
2633 propagation. This now interconnects more naturally to the formulation of the
2634 wave propagation as an inverse problem, being the natural mode of solving
2635 for reflectances as well as transmittances.
2636 I also took the opportunity to write an email to MathWorld, pointing out that
2637 their solution to the Weierstrass form of the integral equation,
2638 \.{http://mathworld.wolfram.com/EllipticIntegral.html}, Eqs. (51)--(56),
2639 actually contains errors; of course I could not resist the opportunity to
2640 provide the MapleV blocks I used for my own verification, rather than using
2641 Mathematica code!
2642
2643 \citem[2006-05-01]{[v.1.42]} \.{<fj@@phys.soton.ac.uk>}\hfill\break
2644 Added support for initialization of the grating structure as a fractal set,
2645 of the Cantor fractal type. This possibility is in the program now accessed
2646 via the command-line option \.{--grating fractal cantor [options]}.
2647 The initialization is done using recursion with the function
2648 |init_cantor_fractal_grating()|, which was finished today.
2649 As of today, the \CWEB\ source for the \magbragg\ program (source file
2650 \.{magbragg.w}) comprises 335649 bytes and 7753 lines of code.
2651 The size of the compiled (\CYGWIN) executable is 95217 bytes, and the
2652 PostScript documentation is 1874643 bytes (148 pages of A4 output in 10pt).
2653
2654 \citem[2007-01-10]{[v.1.43]} \.{<http://jonsson.eu>}\hfill\break
2655 Seefeld, Austria. Midnight. Cleaned up the theoretical part preceeding the
2656 algorithm of computation and merged all bibliographical references into one
2657 separate section at the end of the document.
2658
2659 \citem[2011-12-18]{[v.1.44]} \.{<http://jonsson.eu>}\hfill\break
2660 Updated \.{Makefile}:s for the generation of figures. Also corrected a rather
2661 stupid way of removing preceeding paths of file names.
2662
2663 @*Compiling the source code. The program is written in \CWEB, generating
2664 \ANSICEE\ (ISO C90) conforming source code and documentation as plain
2665 \TeX-source, and is to be compiled using the sequences as outlined in the
2666 \.{Makefile} listed below.
2667 \bigskip
2668 {\obeylines\obeyspaces\tt
2669 \#
2670 \# Makefile designed for use with ctangle, cweave, gcc, and plain TeX.
2671 \#
2672 \# The CTANGLE program converts a CWEB source document into a C program which
2673 \# may be compiled in the usual way. The CWEAVE program converts the same CWEB
2674 \# file into a TeX file that may be formatted and printed in the usual way.
2675 \#
2676 \# Copyright (C) 2002-2006, Fredrik Jonsson <fj@@phys.soton.ac.uk>
2677 \#
2678 CTANGLE = ctangle
2679 CWEAVE = cweave
2680 CC = gcc
2681 CCOPTS = -O2 -Wall -ansi -std=iso9899:1990 -pedantic
2682 LNOPTS = -lm
2683 TEX = tex
2684 DVIPS = dvips
2685 DVIPSOPTS = -ta4 -D1200
2686 METAPOST = mp
2687 ~ ~
2688 all: magbragg magbragg.ps
2689 ~ ~
2690 magbragg: magbragg.o
2691 ~ \$(CC) \$(CCOPTS) -o magbragg magbragg.o \$(LNOPTS)
2692 ~ ~
2693 magbragg.o: magbragg.w
2694 ~ \$(CTANGLE) magbragg
2695 ~ \$(CC) \$(CCOPTS) -c magbragg.c
2696 ~ ~
2697 magbragg.ps: magbragg.dvi
2698 ~ \$(DVIPS) \$(DVIPSOPTS) magbragg.dvi -o magbragg.ps
2699 ~ ~
2700 magbragg.dvi: magbragg.w
2701 ~ make -C figures/
2702 ~ \$(CWEAVE) magbragg
2703 ~ \$(TEX) magbragg.tex
2704 ~ ~
2705 clean:
2706 ~ make clean -ik -C figures/
2707 ~ -rm -Rf magbragg *~ *.c *.o *.exe *.dat *.tgz *.pdf
2708 ~ -rm -Rf *.tex *.aux *.log *.toc *.idx *.scn *.dvi *.ps
2709 ~ ~
2710 archive:
2711 ~ make -ik clean
2712 ~ tar --gzip --directory=../ -cf magbragg.tgz magbragg
2713 }
2714 \bigskip
2715 This \.{Makefile} essentially executes two major calls. First, the \CTANGLE\
2716 program parses the \CWEB\ source document \.{magbragg.w} to extract a \CEE\
2717 source file \.{magbragg.c} which may be compiled in the usual way using any
2718 \ANSICEE\ conformant compiler. The output source file includes \.{\#line}
2719 specifications so that any debugging can be done conveniently in terms of
2720 the original \CWEB\ source file.
2721 Second, the \CWEAVE\ program parses the same \CWEB\ source file to extract a
2722 plain \TeX\ source file \.{magbragg.tex} which may be compiled in the usual
2723 way.
2724 It takes appropriate care of typographic details like page layout and the use
2725 of indentation, italics, boldface, and so on, and it supplies extensive
2726 cross-index information that it gathers automatically.
2727
2728 After having executed \.{make} in the same catalogue where the files
2729 \.{magbragg.w} and \.{Makefile} are located, one is left with an
2730 executable file \.{magbragg}, being the ready-to-use compiled program,
2731 and a PostScript file \.{magbragg.ps}
2732 which contains the full documentation of the program, that is to say the
2733 document you currently are reading.
2734 Notice that on platforms running Windows NT, Windows 2000, Windows ME, or any
2735 other operating system by Microsoft, the executable file will instead
2736 automatically be called \.{magbragg.exe}.
2737 This convention also applies to programs compiled under the \UNIX-like
2738 environment \CYGWIN.
2739
2740 @*Running the program. The program is entirely controlled by the command
2741 line options supplied when invoking the program. Since the command line
2742 for some problems tend to be quite lengthy, since all material parameters
2743 and optical field inputs to the program must be specified, it is convenient
2744 to put blocks for the program calls into a Makefile, which makes it easy to
2745 maintain a structure in the simulations, as well as ensuring traceability
2746 of the steps in the generation of graphs.
2747
2748 As an example of such a call, the following block is included as an example
2749 in the enclosed Makefile:
2750 \bigskip
2751 {\obeyspaces\obeylines\tt
2752 ~ testsimulation:
2753 ~ @@for g in 0.0 1.0 2.0; do {\char'134}
2754 ~ ./magbragg --verbose --outputfile fig1-\$\$g {\char'134}
2755 ~ --spectrumfile fig1-\$\$g.rsp.dat {\char'134}
2756 ~ --gratinglength 7.326376e-6 -N 1800 {\char'134}
2757 ~ --grating sinusoidal n 2.0550 0.1250 366.3188e-9 {\char'134}
2758 ~ g \$\$g'e-3' 0.0 1.0 {\char'134}
2759 ~ pe 0.0 0.0 1.0 {\char'134}
2760 ~ pm 0.0 0.0 1.0 {\char'134}
2761 ~ qe 0.0 0.0 1.0 {\char'134}
2762 ~ qm 0.0 0.0 1.0 {\char'134}
2763 ~ --refindsurr 2.0550 -M 2000 {\char'134}
2764 ~ --lambdastart 1300.0e-9 --lambdastop 1700.0e-9 {\char'134}
2765 ~ --trmintensity 7.0e8 7.0e8 1 {\char'134}
2766 ~ --trmellipticity 0.0 0.0 1 ;{\char'134}
2767 ~ done
2768 }
2769
2770 In the following sections, a complete listing of all command line options
2771 accepted by the \magbragg\ program is presented.
2772
2773 @*Specifying grating types.
2774 The \magbragg\ program currently accepts specifications of three different
2775 main types of gratings:
2776 stepwise gratings, sinusoidal gratings, and chirped sinusoidal gratings.
2777 The stepwise gratings are simply stacks of homogeneous layers, stacked to
2778 form a grating, and these gratings can be composed of two or more different
2779 materials. As an important subclass of the stepwise gratings, the binary
2780 gratings are probably the most important ones, being composed of alternating
2781 layers of only two types of media.
2782
2783 Throughout the program, the following definitions of the material parameters
2784 apply, to the refractive index $n(z)$, gyration coefficient $g(z)$,
2785 nonlinear optical parameters $p^{({\rm e})}(z)$ and $q^{({\rm e})}(z)$,
2786 and nonlinear magneto-optical parameters $p^{({\rm m})}(z)$ and
2787 $q^{({\rm m})}(z)$,
2788 $$
2789 \eqalign{
2790 |n[k]|&=n_k=[1+\chi^{({\rm ee})}_{xx}]^{1/2},\cr
2791 |g[k]|&=g_k=i\chi^{({\rm eem})}_{xyz} B^z_0 /(2 n_k),\cr
2792 |pe[k]|&=p^{({\rm e})}_k
2793 =\chi^{\rm eeee}_{xxxx}-\chi^{\rm eeee}_{xyyx},\cr
2794 |qe[k]|&=q^{({\rm e})}_k
2795 =\chi^{\rm eeee}_{xxxx}+\chi^{\rm eeee}_{xyyx},\cr
2796 |pm[k]|&=p^{({\rm m})}_k
2797 =i(\chi^{\rm eeeem}_{xyyyz}-\chi^{\rm eeeem}_{xxxyz})B^z_0,\cr
2798 |qm[k]|&=q^{({\rm m})}_k
2799 =i(\chi^{\rm eeeem}_{xyyyz}+\chi^{\rm eeeem}_{xxxyz})B^z_0,\cr
2800 }
2801 $$
2802 where |n[k]|, |g[k]|, |pe[k]|, |qe[k]|, |pm[k]|, |qm[k]| denote the variables
2803 as internally used in the \magbragg\ program to store the corresponding
2804 material data for the $N-1$ homogeneous segments $z_k\le z<z_{k+1}$,
2805 $k=1,2,\ldots,N-1$.
2806
2807 In terms of the Verdet constant $V_k$ of a homogeneous layer, as being the
2808 commonly used measure of the linear magneto-optical rotational strength of
2809 the material, the $g$-parameter of the \magbragg\ program is expressed as
2810 $$
2811 g_k=V_k B^z_0 c/\omega,
2812 $$
2813 which simply follows from the general relation
2814 $$
2815 i\chi^{({\rm eem})}_{xyz}=2 n c V/\omega.
2816 $$
2817 \medskip
2818
2819 @ Stepwise grating structures.
2820 The stepwise grating structures are specified using the command line option
2821 \smallskip
2822 \centerline{\hbox to 40pt{}%
2823 \.{--grating stepwise} [\.{twolevel}$\langle\ldots\rangle$%
2824 $\vert$\.{threelevel}$\langle\ldots\rangle$]\hfill}
2825 \smallskip\noindent
2826 where \.{twolevel}, \.{threelevel} etc., states the number of materials
2827 used in the stacking of the layers.
2828 For the \.{twolevel} (binary) type of gratings, the syntax is
2829 \smallskip
2830 \centerline{\hbox to 40pt{}%
2831 \.{--grating stepwise twolevel t1} $\langle{t_1}\rangle$
2832 \.{t2} $\langle{t_2}\rangle$
2833 \.{n1} $\langle{n_1}\rangle$ \.{n2} $\langle{n_2}\rangle$
2834 \.{g1} $\langle{g_1}\rangle$ \.{g2} $\langle{g_2}\rangle$
2835 \hfill}
2836 \centerline{\hbox to 80pt{}%
2837 \.{pe1} $\langle{p^{({\rm e})}_1}\rangle$
2838 \.{pe2} $\langle{p^{({\rm e})}_2}\rangle$
2839 \.{pm1} $\langle{p^{({\rm m})}_1}\rangle$
2840 \.{pm2} $\langle{p^{({\rm m})}_2}\rangle$
2841 \hfill}
2842 \centerline{\hbox to 80pt{}%
2843 \.{qe1} $\langle{q^{({\rm e})}_1}\rangle$
2844 \.{qe2} $\langle{q^{({\rm e})}_2}\rangle$
2845 \.{qm1} $\langle{q^{({\rm m})}_1}\rangle$
2846 \.{qm2} $\langle{q^{({\rm m})}_2}\rangle$
2847 \hfill}
2848 \smallskip\noindent
2849 where $t_1$ and $t_2$ are the geometrical layer thicknesses of the
2850 first two layers $0\le z\le t_1$ and $t_1\le z\le t_1+t_2$, and
2851 $n_1$ and $n_2$ are the corresponding refractive indices of these
2852 layers, respectively.
2853
2854 The grating is then composed by repeating the basic pair of layers,
2855 to give a grating composed of in total $N-1$ homogeneous layers, as
2856 specified with the \.{-N} option.
2857 Notice that if the total number of layers $N-1$ is an odd number
2858 (\ie specifying an even number of interfaces $N$), the last
2859 layer will possess the same material properties and geometrical
2860 thickness as the first layer.
2861 \medskip
2862
2863 @ Sinusoidal structures.
2864 The sinusoidal grating structures are specified using the command line option
2865 \smallskip
2866 \centerline{\hbox to 40pt{}%
2867 \.{--grating sinusoidal}
2868 \.{n} $\langle{n_0}\rangle$ $\langle{\Delta n}\rangle$
2869 $\langle{\Lambda_{n}}\rangle$
2870 \.{g} $\langle{g_0}\rangle$ $\langle{\Delta g}\rangle$
2871 $\langle{\Lambda_{g}}\rangle$\hfill}
2872 \centerline{\hbox to 80pt{}%
2873 \.{pe} $\langle{p^{({\rm e})}_0}\rangle$
2874 $\langle{\Delta p^{({\rm e})}_0}\rangle$
2875 $\langle{\Lambda^{({\rm e})}_{\rm p}}\rangle$
2876 \.{pm} $\langle{p^{({\rm m})}_0}\rangle$
2877 $\langle{\Delta p^{({\rm m})}_0}\rangle$
2878 $\langle{\Lambda^{({\rm m})}_{\rm p}}\rangle$\hfill}
2879 \centerline{\hbox to 80pt{}%
2880 \.{qe} $\langle{q^{({\rm e})}_0}\rangle$
2881 $\langle{\Delta q^{({\rm e})}_0}\rangle$
2882 $\langle{\Lambda^{({\rm e})}_{\rm q}}\rangle$
2883 \.{qm} $\langle{q^{({\rm m})}_0}\rangle$
2884 $\langle{\Delta q^{({\rm m})}_0}\rangle$
2885 $\langle{\Lambda^{({\rm m})}_{\rm q}}\rangle$\hfill}
2886 \smallskip\noindent
2887 In terms of the supplied command line options, the resulting grating structure
2888 is then described by the continuous distribution of refractive index,
2889 gyration coefficient, and nonlinear optical and magneto-optical coefficients as
2890 $$
2891 \eqalign{
2892 n(z)&=n_0+\Delta n\sin(2\pi z/\Lambda_{n}),\cr
2893 g(z)&=g_0+\Delta g\sin(2\pi z/\Lambda_{g}),\cr
2894 p^{({\rm e})}(z)&=p^{({\rm e})}_0+\Delta p^{({\rm e})}
2895 \sin(2\pi z/\Lambda^{({\rm e})}_{\rm p}),\cr
2896 q^{({\rm e})}(z)&=q^{({\rm e})}_0+\Delta q^{({\rm e})}
2897 \sin(2\pi z/\Lambda^{({\rm e})}_{\rm q}),\cr
2898 p^{({\rm m})}(z)&=p^{({\rm m})}_0+\Delta p^{({\rm m})}
2899 \sin(2\pi z/\Lambda^{({\rm m})}_{\rm p}),\cr
2900 q^{({\rm m})}(z)&=q^{({\rm m})}_0+\Delta q^{({\rm m})}
2901 \sin(2\pi z/\Lambda^{({\rm m})}_{\rm q}),\cr
2902 }
2903 $$
2904 which in the discretized and oversampled model as used in the internal
2905 representration of the \magbragg\ program hence becomes
2906 $$
2907 \eqalign{
2908 n_j&=n_0+\Delta n\sin(2\pi z_j/\Lambda_{n}),\cr
2909 g_j&=g_0+\Delta g\sin(2\pi z_j/\Lambda_{g}),\cr
2910 p^{({\rm e})}_j&=p^{({\rm e})}_0+\Delta p^{({\rm e})}
2911 \sin(2\pi z_j/\Lambda^{({\rm e})}_{\rm p}),\cr
2912 q^{({\rm e})}_j&=q^{({\rm e})}_0+\Delta q^{({\rm e})}
2913 \sin(2\pi z_j/\Lambda^{({\rm e})}_{\rm q}),\cr
2914 p^{({\rm m})}_j&=p^{({\rm m})}_0+\Delta p^{({\rm m})}
2915 \sin(2\pi z_j/\Lambda^{({\rm m})}_{\rm p}),\cr
2916 q^{({\rm m})}_j&=q^{({\rm m})}_0+\Delta q^{({\rm m})}
2917 \sin(2\pi z_j/\Lambda^{({\rm m})}_{\rm q}),\cr
2918 }
2919 $$
2920 for $j=1,2,\ldots,N-1$.
2921 For sinusoidal gratings, discrete phase jumps of the refractive index
2922 distribution can also be applied, by using the \.{--phasejump} command
2923 line option. Subsequent apodization of the structure can also be applied,
2924 using the {--apodize} option.
2925 \medskip
2926
2927 @ Sinusoidal chirped structures.
2928 The chirped grating structures, being sinusoidal gratings with a spatially
2929 varying grating period, are specified using the somewhat extensive command
2930 line option
2931 \smallskip
2932 \centerline{\hbox to 40pt{}%
2933 \.{--grating chirped}
2934 \.{n} $\langle{n_0}\rangle$ $\langle{\Delta n}\rangle$
2935 $\langle{\Lambda_{n}}\rangle$ $\langle{\eta_{n}}\rangle$
2936 \.{g} $\langle{g_0}\rangle$ $\langle{\Delta g}\rangle$
2937 $\langle{\Lambda_{g}}\rangle$ $\langle{\eta_{g}}\rangle$\hfill}
2938 \centerline{\hbox to 80pt{}%
2939 \.{pe} $\langle{p^{({\rm e})}_0}\rangle$
2940 $\langle{\Delta p^{({\rm e})}_0}\rangle$
2941 $\langle{\Lambda^{({\rm e})}_{\rm p}}\rangle$
2942 $\langle{\eta^{({\rm e})}_{\rm p}}\rangle$
2943 \.{pm} $\langle{p^{({\rm m})}_0}\rangle$
2944 $\langle{\Delta p^{({\rm m})}_0}\rangle$
2945 $\langle{\Lambda^{({\rm m})}_{\rm p}}\rangle$
2946 $\langle{\eta^{({\rm m})}_{\rm p}}\rangle$\hfill}
2947 \centerline{\hbox to 80pt{}%
2948 \.{qe} $\langle{q^{({\rm e})}_0}\rangle$
2949 $\langle{\Delta q^{({\rm e})}_0}\rangle$
2950 $\langle{\Lambda^{({\rm e})}_{\rm q}}\rangle$
2951 $\langle{\eta^{({\rm e})}_{\rm q}}\rangle$
2952 \.{qm} $\langle{q^{({\rm m})}_0}\rangle$
2953 $\langle{\Delta q^{({\rm m})}_0}\rangle$
2954 $\langle{\Lambda^{({\rm m})}_{\rm q}}\rangle$
2955 $\langle{\eta^{({\rm m})}_{\rm q}}\rangle$\hfill}
2956 \smallskip\noindent
2957 Here $\langle{n_0}\rangle$ is the bias refractive index across the grating,
2958 $\langle{\Delta n}\rangle$ the modulation of the refractive index around the
2959 bias value, that is to say half the bottom-to-peak value of the modulated
2960 index of refraction, $\langle{\Lambda_{n}}\rangle$ is the initial geometrical
2961 grating period at $z=0$,
2962 and $\langle{\eta_{n}}\rangle$ the chirp of the grating, being the
2963 relative change of the grating period over the length of the grating.
2964 The other grating parameters are specified analogously, for gyration
2965 coefficient and nonlinear optical and magneto-optical coefficients.
2966 The chirp parameter is here defined as the change in geometrical grating period
2967 per unit geometrical distance along the grating, or
2968 $$
2969 \eta_{n}={{\Lambda(L)-\Lambda(0)}\over{L}}
2970 $$
2971 where $\Lambda(z)$ denotes the geometrical grating period as function of
2972 the spatial coordinate $z$ along the grating.
2973
2974 To illustrate the meaning of the chirp parameter, consider a chirped refractive
2975 index distribution over a geometrical distance $L$ and with a bias refractive
2976 index $n_0$. To give a resonance in reflection ranging from vacuum wavelength
2977 $\lambda_{\rm a}$ to $\lambda_{\rm b}$, say, the grating period could be either
2978 increasing or decreasing with spatial coordinate $z$. By choosing the initial
2979 part of the grating (at $z=0$) to be resonant in reflection for a vacuum
2980 wavelength $\lambda_{\rm a}$, the initial grating period $\Lambda_{n}$ should
2981 be chosen as half the optical period at resonance, or
2982 $$
2983 \Lambda_{n}={{\lambda_{\rm a}}\over{2 n_0}}.
2984 $$
2985 With this initial grating period the chirp parameter should, in order to give
2986 a final resonance in reflection at vacuum wavelength $\lambda_{\rm b}$ at the
2987 end of the grating (at $z=L$), then simply be chosen as
2988 $$
2989 \eta_{n}={{\lambda_{\rm b}-\lambda_{\rm a}}\over{2 n_0 L}}.
2990 $$
2991 Notice that whenever $\lambda_{\rm b}<\lambda_{\rm a}$, the chirp parameter
2992 is negative, indicating a grating period which is decreasing with increasing
2993 spatial coordinate $z$. This convention of sign for the chirp parameter is
2994 consistently kept throughout the algorithms of the \magbragg\ program.
2995
2996 In terms of the supplied command line options, the resulting chirped grating
2997 structure is described by the continuous distribution of refractive index,
2998 gyration coefficient, and nonlinear optical and magneto-optical coefficients as
2999 $$
3000 \eqalign{
3001 n(z)&=n_0+\Delta n\sin((2\pi/\eta_{n})\ln(1+\eta_{n}z/\Lambda_{n})),\cr
3002 g(z)&=g_0+\Delta g\sin((2\pi/\eta_{g})\ln(1+\eta_{g}z/\Lambda_{g})),\cr
3003 p^{({\rm e})}(z)&=p^{({\rm e})}_0+\Delta p^{({\rm e})}
3004 \sin((2\pi/\eta^{({\rm e})}_{\rm p})
3005 \ln(1+\eta^{({\rm e})}_{\rm p}z/\Lambda^{({\rm e})}_{\rm p})),\cr
3006 p^{({\rm m})}(z)&=p^{({\rm m})}_0+\Delta p^{({\rm m})}
3007 \sin((2\pi/\eta^{({\rm m})}_{\rm p})
3008 \ln(1+\eta^{({\rm m})}_{\rm p}z/\Lambda^{({\rm m})}_{\rm p})),\cr
3009 q^{({\rm e})}(z)&=q^{({\rm e})}_0+\Delta q^{({\rm e})}
3010 \sin((2\pi/\eta^{({\rm e})}_{\rm q})
3011 \ln(1+\eta^{({\rm e})}_{\rm q}z/\Lambda^{({\rm e})}_{\rm q})),\cr
3012 q^{({\rm m})}(z)&=q^{({\rm m})}_0+\Delta q^{({\rm m})}
3013 \sin((2\pi/\eta^{({\rm m})}_{\rm q})
3014 \ln(1+\eta^{({\rm m})}_{\rm q}z/\Lambda^{({\rm m})}_{\rm q})),\cr
3015 }
3016 $$
3017 which in the discretized and oversampled model as used in the internal
3018 representration of the \magbragg\ program hence becomes
3019 $$
3020 \eqalign{
3021 n_j&=n_0+\Delta n\sin((2\pi/\eta_{n})\ln(1+\eta_{n}z_j/\Lambda_{n})),\cr
3022 g_j&=g_0+\Delta g\sin((2\pi/\eta_{g})\ln(1+\eta_{g}z_j/\Lambda_{g})),\cr
3023 p^{({\rm e})}_j&=p^{({\rm e})}_0+\Delta p^{({\rm e})}
3024 \sin((2\pi/\eta^{({\rm e})}_{\rm p})
3025 \ln(1+\eta^{({\rm e})}_{\rm p}z_j/\Lambda^{({\rm e})}_{\rm p})),\cr
3026 p^{({\rm m})}_j&=p^{({\rm m})}_0+\Delta p^{({\rm m})}
3027 \sin((2\pi/\eta^{({\rm m})}_{\rm p})
3028 \ln(1+\eta^{({\rm m})}_{\rm p}z_j/\Lambda^{({\rm m})}_{\rm p})),\cr
3029 q^{({\rm e})}_j&=q^{({\rm e})}_0+\Delta q^{({\rm e})}
3030 \sin((2\pi/\eta^{({\rm e})}_{\rm q})
3031 \ln(1+\eta^{({\rm e})}_{\rm q}z_j/\Lambda^{({\rm e})}_{\rm q})),\cr
3032 q^{({\rm m})}_j&=q^{({\rm m})}_0+\Delta q^{({\rm m})}
3033 \sin((2\pi/\eta^{({\rm m})}_{\rm q})
3034 \ln(1+\eta^{({\rm m})}_{\rm q}z_j/\Lambda^{({\rm m})}_{\rm q})),\cr
3035 }
3036 $$
3037 for $j=1,2,\ldots,N-1$.
3038
3039 Notice that the geometrical period of any of the optical/physical properties
3040 described by the above distributions is given by
3041 $$
3042 {{2\pi}\over{\{{\rm geometrical\ period}\}}}=
3043 {{\partial}\over{\partial z}}\{{\rm argument\ of\ }\sin(\ldots)\}.
3044 $$
3045 For example, the refractive index distribution
3046 $$
3047 n(z)=n_0+\Delta n\sin((2\pi/\eta_{n})\ln(1+\eta_{n}z/\Lambda_{n}))
3048 $$
3049 has its spatially varying local grating period $\Lambda_{\rm loc}(z)$ given by
3050 $$
3051 \eqalign{
3052 {{2\pi}\over{\Lambda_{\rm loc}(z)}}
3053 &={{\partial}\over{\partial z}}
3054 [({{2\pi}/{\eta_{n}}})\ln(1+{{\eta_{n}z}/{\Lambda_{n}}})]%\cr
3055 =({{2\pi}/{\eta_{n}}})
3056 {{{{\eta_{n}}/{\Lambda_{n}}}}\over{(1+{{\eta_{n}z}/{\Lambda_{n}}})}}%\cr
3057 ={{2\pi}\over{(\Lambda_{n}+\eta_{n}z)}}%\cr
3058 }
3059 $$
3060 that is to say, the geometrical local period is given as a linear function
3061 which in terms of the vacuum resonance wavelengths $\lambda_{\rm a}$ and
3062 $\lambda_{\rm b}$ becomes
3063 $$
3064 \eqalign{
3065 \Lambda_{\rm loc}(z)&=\Lambda_n+\eta z
3066 ={{\lambda_{\rm a}}\over{2n_0}}
3067 +{{(\lambda_{\rm b}-\lambda_{\rm a})}\over{2n_0L}}z
3068 ={{1}\over{2n_0}}(\lambda_{\rm a}+(\lambda_{\rm b}-\lambda_{\rm a})z/L).
3069 }
3070 $$
3071 For the sake of consistency with the discussion earlier in this section,
3072 $\lambda_{\rm a}$ is taken as the vacuum resonance wavelength at $z=0$,
3073 while $\lambda_{\rm b}$ is the corresponding wavelength of resonance at $z=L$.
3074 For chirped gratings, as well as for the sinusoidal gratings, discrete phase
3075 jumps of the refractive index distribution can also be applied, by using the
3076 \.{--phasejump} command line option. Subsequent apodization of the structure
3077 can also be applied, using the {--apodize} option.
3078 \medskip
3079
3080 @ Fractal structures.
3081
3082 [TEXT STILL TO BE WRITTEN]
3083
3084 @ Discrete phase jumps.
3085 Discrete phase jumps in sinusoidal type gratings (of sinusoidal of chirped
3086 type as previously described)
3087 can be specified using the \.{--phasejump} option, with syntax
3088 \smallskip
3089 \centerline{\hbox to 40pt{}%
3090 \.{--phasejump} $\langle{\varphi_{\rm jump}}\rangle$
3091 $\langle{z_{\rm jump}}\rangle$\hfill}
3092 \smallskip\noindent
3093 where $\varphi_{\rm jump}$ is the phase shift in radians to be applied for
3094 the grating at all spatial coordinates $z\ge z_{\rm jump}$.
3095 For sinusoidal type gratings, the effect is that the refractive index and
3096 gyration coefficient distributions become
3097 $$
3098 \eqalign{
3099 n(z)&=n_0+\Delta n\sin(2\pi z/\Lambda_{n}+\varphi(z)),\cr
3100 g(z)&=g_0+\Delta g\sin(2\pi z/\Lambda_{g}+\varphi(z)),\cr
3101 }
3102 $$
3103 where
3104 $$
3105 \varphi(z)=\cases{0,&$z<z_{\rm jump}$\cr
3106 \varphi_{\rm jump},&$z\ge z_{\rm jump}$\cr},
3107 $$
3108 Notice that the parameters supplied with the \.{--phasejump} option
3109 only affects the (linear) refractive index and gyration coefficient
3110 distributions $n(z)$ and $g(z)$; all other (nonlinear) material parameters
3111 are left unaffected, irregardless of potential spatial modulation schemes.
3112
3113 @ The refractive index surrounding the grating.
3114 The refractive index surrounding the grating is specified using the command
3115 line option
3116 \smallskip
3117 \centerline{\hbox to 40pt{}\.{--refindsurr}
3118 $\langle n_{\rm ext}\rangle$\hfill}
3119 \smallskip\noindent
3120 where $\langle n_{\rm ext}\rangle$ is the refractive index surrounding the
3121 grating.
3122 If the surrounding refractive index is not specified at the command line
3123 at execution of the program, a default value of $n_{\rm ext}=1.0$ (vacuum)
3124 is used in the simulation.
3125
3126 @ Apodization of the grating.
3127 Apodization of the grating structure is typically applied
3128 in order to get rid of any occurring Gibbs oscillations due to a rapid
3129 change of the index modulation at the ends of the grating.
3130 For a more detailed description of Gibbs oscillations, see for example
3131 Refs.~[14,15].
3132 By applying apodization, the \magbragg\ program force a smoother
3133 transition between modulated and non-modulated regions of the grating.
3134 The apodization is invoked by the \.{--apodize}
3135 option, with syntax
3136 \smallskip
3137 \centerline{\hbox to 40pt{}%
3138 \.{--apodize} $\langle{L_{\rm apod}}\rangle$\hfill}
3139 \smallskip\noindent
3140 where $L_{\rm apod}$ is the apodization length at each end of the grating.
3141 The apodization is performed at the ends of the grating according to a
3142 multiplicative factor of the modulation amplitudes of the
3143 refractive index and gyration coefficient, of the form
3144 $$
3145 f(z)=\cases{
3146 [1-\cos(\pi z/L_{\rm apod})]/2,&$0\le z\le L_{\rm apod}$,\cr
3147 1,&$L_{\rm apod}<z<L-L_{\rm apod}$,\cr
3148 [1-\cos(\pi(z-L)/L_{\rm apod})]/2,&$L-L_{\rm apod}\le z\le L$,\cr
3149 }
3150 $$
3151 and otherwise $f(z)=0$, for any $z$ outside the above domains of definition,
3152 where $L_{\rm apod}$ is the effective apodization length, being the floating
3153 point parameter specified after the \.{--apodize} option, and $L$ the
3154 geometrical overall length of the grating, \eg as specified with the
3155 \.{--gratinglength} option.
3156 Notice that as in the previously described \.{--phasejump} option,
3157 the parameter supplied with the \.{--apodize} option
3158 only apodizes the (linear) refractive index and gyration coefficient
3159 distributions $n(z)$ and $g(z)$; all other (nonlinear) material parameter
3160 distributions are left unaffected.
3161
3162 @ Specifying transmitted intensity.
3163 The generated data relating a specified optical output to an optical input can
3164 in the program automatically be iterated over a range of values of the
3165 transmitted optical intensity, expressed in regular \SI\ units as Watts per
3166 square meter (${\rm W}/{\rm m}^2$).
3167 The command line syntax for specifying that the
3168 program should generate the inverse relation for $M_{\rm i}$ discrete values of
3169 the transmitted optical intensity in a range from $I_{\rm start}$ to
3170 $I_{\rm stop}$ is
3171 \smallskip
3172 \centerline{\hbox to 40pt{}\.{--trmintensity}
3173 $\langle I_{\rm start}\rangle$ $\langle I_{\rm stop}\rangle$
3174 $\langle M_{\rm i}\rangle$\hfill}
3175 \smallskip\noindent
3176 Notice that parameters throughout the program are to be specified in terms
3177 of regular \SI\ units. In case the in optical physics quite commonly used
3178 quantity of gigawatts per square centimeter is preferred, just use the
3179 conversion $1\,{\rm G}{\rm W}/{\rm cm}^2=10^{13}\,{\rm W}/{\rm m}^2$.
3180 \smallskip\noindent
3181
3182 @ Specifying transmitted ellipticity.
3183 The command line syntax for specification of the range of ellipticity of the
3184 transmitted polarization state is analogous to that of the transmitted
3185 intensity, as
3186 \smallskip
3187 \centerline{\hbox to 40pt{}\.{--trmellipticity}
3188 $\langle \epsilon_{\rm start}\rangle$ $\langle \epsilon_{\rm stop}\rangle$
3189 $\langle M_{\rm e}\rangle$\hfill}
3190 \smallskip\noindent
3191 where $\langle \epsilon_{\rm start}\rangle$ and
3192 $\langle \epsilon_{\rm stop}\rangle$ are the start and stop values for the
3193 normalized transmitted ellipticity~$\epsilon$, which in terms of the
3194 transmitted Stokes parameters is defined as $\epsilon\equiv W_3/W_0$.
3195 (For the definitions of the Stokes parameters in terms of the electric
3196 field of the light wave, see the corresponding separate section included
3197 in this documentation.)
3198 Here $\epsilon=-1$ corresponds to right circular polarization (RCP) while
3199 $\epsilon=1$ corresponds to left circular polarization (LCP), with
3200 $\epsilon=0$ corresponding to linear polarization.
3201 Values intermediate of those give the various degrees of elliptic polarization
3202 states. As in the case of specification of the transmitted intensity,
3203 $\langle M_{\rm e}\rangle$ is the number of discrete steps of the ellipticity
3204 that will be iterated over in the simulation.
3205
3206 @ Specifying optical vacuum wavelength interval to be scanned.
3207 For the sampling of optical spectra, with the reflectance and transmittance
3208 sampled as function of optical vacuum wavelength, the interval of computation
3209 is specified using the syntax
3210 \smallskip
3211 \centerline{\hbox to 40pt{}
3212 \.{--lambdastart} $\langle \lambda_{\rm start}\rangle$
3213 \.{--lambdastop} $\langle \lambda_{\rm stop}\rangle$\hfill}
3214 \smallskip\noindent
3215 where $\lambda_{\rm start}$ and $\lambda_{\rm stop}$ specifies the wavelength
3216 domain. The number of samples $M$ to be calculated is specified using the
3217 syntax
3218 \smallskip
3219 \centerline{\hbox to 40pt{}
3220 \.{-M} $\langle M\rangle$\hfill}
3221 \smallskip\noindent
3222 The specific discrete vacuum wavelength $\lambda_k$ at which the computation
3223 is performed are
3224 $$
3225 \lambda_k=\lambda_{\rm start}+{{(k-1)}\over{(M-1)}}
3226 (\lambda_{\rm stop}-\lambda_{\rm start}),
3227 $$
3228 for $k=1,2,\ldots,M$.
3229
3230 @ Scaling of Stokes parameters to yield optical intensity.
3231 To force the output Stokes parameters to be expressed in terms of optical
3232 intensity units of Watts per square meter, rather than the regular square
3233 Volts per meter, use the command line option
3234 \smallskip
3235 \centerline{\hbox to 40pt{}\.{--scale\_stokesparams 1.327209e-3}\hfil}
3236 \smallskip\noindent
3237 forcing the program to save the scaled Stokes parameters
3238 $S'_k=1.327209\times10^{-3}S_k$ to file instead of the original $S_k$,
3239 $k=0,1,2,3$.
3240 As a default, and as a matter of convention of electrodynamics in \SI\ units,
3241 all Stokes parameters are given in ${\rm V}^2/{\rm m}^2$, through their
3242 definition.
3243 For example, the incident field (which is calculated by the program in
3244 this inverse formulation of the problem) is expressed in terms of the Stokes
3245 parameters as
3246 $$
3247 \eqalign{
3248 S_0&=\vert E^{\rm f}_{0_+}\vert^2+\vert E^{\rm f}_{0_-}\vert^2,\qquad
3249 S_1=2\re[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}],\cr
3250 S_3&=\vert E^{\rm f}_{0_+}\vert^2-\vert E^{\rm f}_{0_-}\vert^2,\qquad
3251 S_2=2\im[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}].\cr
3252 }
3253 $$
3254 However, the direct interpretation of these quantities in terms of squared
3255 Volts per square metres is sometimes somewhat inconvenient; therefore, those
3256 parameters can be scaled to give an interpretation of the intensity (in regular
3257 \SI\ units measured in Watts per square metres),
3258 as $S'_k=(\varepsilon_0 c/2)S_k$, or explicitly
3259 $$
3260 \eqalign{
3261 S'_0&=(\varepsilon_0 c/2)
3262 [\vert E^{\rm f}_{0_+}\vert^2+\vert E^{\rm f}_{0_-}\vert^2],\qquad
3263 S'_1=(\varepsilon_0 c/2)
3264 2\re[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}],\cr
3265 S'_3&=(\varepsilon_0 c/2)
3266 [\vert E^{\rm f}_{0_+}\vert^2-\vert E^{\rm f}_{0_-}\vert^2],\qquad
3267 S'_2=(\varepsilon_0 c/2)
3268 2\im[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}].\cr
3269 }
3270 $$
3271 In this representation, $S'_0$ is now identical to the incident intensity
3272 $I_{\rm in}$ [${\rm W}/{\rm m}^2$].
3273 In order to have those scaled Stokes parameters $S'_k$ written to file,
3274 rather than the default ones, one convenient possibility is to use the
3275 previously added \.{--scale\_stokesparams} option, to include
3276 \.{--scale\_stokesparams 1.327209e-3} at the command line when invoking
3277 the program.
3278 The numerical value of this scaling was obtained
3279 from
3280 $$
3281 \eqalign{
3282 \varepsilon_0 c/2
3283 &=(8.854187817\ldots\times 10^{-12}\ {\rm F}/{\rm m})
3284 \times(2.99792458\times 10^8\ {\rm m}/{\rm s})/2\cr
3285 &\approx 1.327209\times 10^{-3}\ {\rm F}/{\rm s}.\cr
3286 }
3287 $$
3288 In regular \SI\ units as here used, the physical dimension of the
3289 quantity $\varepsilon_0 c/2$ is $[({\rm A}\cdot{\rm s})/({\rm V}\cdot{\rm m})]
3290 \cdot[{\rm m}/{\rm s}]=[{\rm A}/{\rm V}]$, so the physical dimension of
3291 $(\varepsilon_0 c/2)S_k$ is hence $[{\rm A}/{\rm V}]\cdot[{\rm V}^2/{\rm m}^2]
3292 =[{\rm W}/{\rm m}^2]$, as expected for an intensity measure (energy flow per
3293 unit area in the plane orthogonal to the direction of wave propagation).
3294 For any other scaling factor of the Stokes parameters, use the general syntax
3295 \smallskip
3296 \centerline{\hbox to 40pt{}\.{--scale\_stokesparams}
3297 $\langle a\rangle$\hfill}
3298 \smallskip\noindent
3299 which forces the program to save the scaled Stokes parameters
3300 $S'_k=a S_k$ to file instead of the original $S_k$, $k=0,1,2,3$.
3301
3302 @ Saving intra-grating spatial evolution of optical field and intensity.
3303 The optical intensity and/or general spatial evolution of the electromagnetic
3304 field inside the grating can be saved to file using the command line option
3305 of syntax
3306 \smallskip
3307 \centerline{\hbox to 40pt{}
3308 \.{-M} $\langle M\rangle$\hfill}
3309 \smallskip\noindent
3310
3311 The data for the field evolution is written to file in the format
3312 \smallskip
3313 \centerline{\hbox to 20pt{}
3314 $z_1$\quad
3315 $\langle E^{\rm f}_+(z_1)\rangle$\quad
3316 $\langle E^{\rm f}_-(z_1)\rangle$\quad
3317 $\langle E^{\rm b}_+(z_1)\rangle$\quad
3318 $\langle E^{\rm b}_-(z_1)\rangle$\quad
3319 \hfill}
3320 \centerline{\hbox to 20pt{}
3321 $z_2$\quad
3322 $\langle E^{\rm f}_+(z_2)\rangle$\quad
3323 $\langle E^{\rm f}_-(z_2)\rangle$\quad
3324 $\langle E^{\rm b}_+(z_2)\rangle$\quad
3325 $\langle E^{\rm b}_-(z_2)\rangle$\quad
3326 \hfill}
3327 \centerline{\hbox to 20pt{}
3328 $\vdots$\hskip 80pt$\vdots$\hskip 80pt$\vdots$
3329 \hfill}
3330 \centerline{\hbox to 20pt{}
3331 $z_N$\quad
3332 $\langle E^{\rm f}_+(z_N)\rangle$\quad
3333 $\langle E^{\rm f}_-(z_N)\rangle$\quad
3334 $\langle E^{\rm b}_+(z_N)\rangle$\quad
3335 $\langle E^{\rm b}_-(z_N)\rangle$\quad
3336 \hfill}
3337 \smallskip\noindent
3338 where each blank space-separated entry $\langle E^{\rm f}_+(z_k)\rangle$,
3339 $\langle E^{\rm f}_-(z_k)\rangle$, $\langle E^{\rm b}_+(z_k)\rangle$, or
3340 $\langle E^{\rm b}_-(z_k)\rangle$ for an electric field component constitutes
3341 the pair of its real and imaginary parts,
3342 $$
3343 \langle E^{\rm f}_+(z_k)\rangle\equiv
3344 \langle{\re}[E^{\rm f}_+(z_k)]\rangle\quad
3345 \langle{\im}[E^{\rm f}_+(z_k)]\rangle,
3346 $$
3347 where each number $\langle{\re}[E^{\rm f}_+(z_k)]\rangle$ or
3348 $\langle{\im}[E^{\rm f}_+(z_k)]\rangle$ in the pair in the saved file
3349 is represented in plain ASCII by 16 significant digits.
3350
3351 [TEXT STILL TO BE WRITTEN]
3352
3353 @ Saving the spatial profile of grating structure.
3354 The spatial distribution of the refractive index, gyration coefficient, and
3355 nonlinear optical and magneto-optical parameters can in the progress of the
3356 simulation be written to file using the command line option
3357 \smallskip
3358 \centerline{\hbox to 40pt{}\.{--writegratingfile}
3359 $\langle {\rm filename}\rangle$\hfill}
3360 \smallskip\noindent
3361 [TEXT STILL TO BE WRITTEN]
3362
3363 @ Intragrating intensity information.
3364 In many cases the density distribution of optical intensity inside the medium
3365 is of particular interest, since cavity-effects or other resonant phenomena
3366 can considerably increase the intensity locally along the grating.
3367 The program can automatically track down the maximum present intensity in the
3368 grating and the corresponding location, presenting the information either at
3369 the terminal window in which the program was started or written to file.
3370 The syntax for getting this information calculated and displayed in the
3371 terminal window is simply
3372 \smallskip
3373 \centerline{\hbox to 40pt{}\.{--intensityinfo}.\hfill}
3374 \smallskip\noindent
3375 To get the information instead written to file, use
3376 \smallskip
3377 \centerline{\hbox to 40pt{}\.{--intensityinfologfile}
3378 $\langle{\rm filename}\rangle$,\hfill}
3379 \smallskip\noindent
3380 where $\langle{\rm filename}\rangle$ is the name of the destination file.
3381
3382 @*Postprocessing of the data to get the direct relation.
3383 The data generated by the program naturally relate the inverse relation between
3384 the incident and transmitted (or reflected) optical fields.
3385 In other words, the input data are typically equidistantly spaced in the
3386 transmitted intensity and/or ellipticity, while the spacing of the
3387 calculated data (the incident optical field) is ....
3388
3389 For topological mappings of the data, such as in Fig.~X [FIGURE TO BE
3390 INSERTED], it is for most cases of no importance whether it is the
3391 direct relation (transmitted or reflected field as function of incident field)
3392 or its inverse (incident or reflected field as function of transmitted field)
3393 that is described by the set of data.
3394 However, in many cases we are interested in a maping that corresponds to
3395 a direct experimental setup. For example, whenever we have a linearly
3396 polarized incident light in the experimental setup of evaluation, the
3397 transmitted polarization state generally differ from the input one, and
3398 we must take into account that the input data will ....
3399
3400 [TEXT STILL TO BE WRITTEN]
3401
3402 @*The main program. Here follows the general outline of the main program.
3403
3404 @c
3405 @<Library inclusions@>@;
3406 @<Global definitions@>@;
3407 @<Data structure definitions@>@;
3408 @<Global variables@>@;
3409 @<Subroutines@>@;
3410
3411 int main(int argc, char *argv[])
3412 {
3413 @<Declaration of local variables@>@;
3414 @<Initialize variables@>@;
3415 @<Parse command line for parameter values@>@;
3416 @<Check for specified trajectory of transmitted Stokes parameters@>@;
3417 @<Open files for output@>@;
3418 @<Allocate optical field vectors@>@;
3419 @<Initiate grating structure@>@;
3420 @<Initiate surrounding medium@>@;
3421 @<Calculate intragrating layer reflectances@>@;
3422 @<Calculate incident optical field spectrum@>@;
3423 @<Print information on maximum optical intensity in grating@>@;
3424 @<Deallocate optical field vectors@>@;
3425 @<Close output files@>@;
3426 return(SUCCESS);
3427 }
3428
3429 @ The standard \ANSICEE\ libraries included in this program are:\par
3430 \varitem[\.{math.h}]{For access to mathematical functions.}
3431 \varitem[\.{time.h}]{For time stamps and estimation of computation time.}
3432 \varitem[\.{stdio.h}]{For file access and any block involving |fprintf|.}
3433 \varitem[\.{stdlib.h}]{For memory allocation, |malloc|, |exit|, |free| etc.}
3434 \varitem[\.{string.h}]{For string manipulation, |strcpy|, |strcmp| etc.}
3435 \varitem[\.{ctype.h}]{For access to the |isalnum| routine.}
3436
3437 @<Library inclusions@>=
3438 #include <math.h>
3439 #include <time.h>
3440 #include <stdio.h>
3441 #include <stdlib.h>
3442 #include <string.h>
3443 #include <ctype.h>
3444
3445 @ Global definitions.
3446 There are just a few global definitions present in the \magbragg\ program:\par
3447 \varitem[\.{VERSION}]{The current program revision number.}
3448 \varitem[\.{COPYRIGHT}]{The copyright banner.}
3449 \varitem[\.{SUCCESS}]{The return code for successful program termination.}
3450 \varitem[\.{FAILURE}]{The return code for unsuccessful program termination.}
3451 \varitem[\.{NCHMAX}]{The maximum number of characters allowed in strings for
3452 storing file names, including path.}
3453
3454 @<Global definitions@>=
3455 #define VERSION "1.43"
3456 #define COPYRIGHT "Copyright (C) 2002-2007, Fredrik Jonsson"
3457 #define SUCCESS (0)
3458 #define FAILURE (1)
3459 #define NCHMAX (256)
3460
3461 @ Data structure definitions.
3462 The |dcomplex| data structure contains real and imaginary parts in
3463 double precision, and is also the basic data structure used for the
3464 allocation of complex valued vectors of double precision.
3465
3466 @<Data struct...@>=
3467 typedef struct DCOMPLEX {double r,i;} dcomplex;
3468
3469 @ Declaration of global variables. The only global variables allowed in
3470 my programs are |optarg|, which is a pointer to the the string of characters
3471 that specified the call from the command line, and |progname|, which simply
3472 is a pointer to the string containing the name of the program, as it was
3473 invoked from the command line.
3474
3475 @<Global variables@>=
3476 extern char *optarg;
3477 char *progname;
3478
3479 @ Listing of subroutines called by the main program.
3480
3481 @<Subroutines@>=
3482 @<Routine for checking for numerical characters@>@;
3483 @<Routine for initialization of Cantor type fractal gratings@>@;
3484 @<Routines for removing preceding path of filenames@>@;
3485 @<Routines for memory allocation of vectors@>@;
3486 @<Routines for generation of random numbers@>@;
3487 @<Routines for complex arithmetics@>@;
3488 @<Routines for displaying help message@>@;
3489
3490 @*Declaration of local variables of the main program.
3491 In \CWEB\ one has the option of adding variables along the program, for example
3492 by locally adding temporary variables related to a given sub-block of code.
3493 However, my philosophy in the \magbragg\ program is to keep all variables of
3494 the |main| section collected together, so as to simplify tasks as, for example,
3495 tracking down a given variable type definition.
3496
3497 [ADD A LIST OF VARIABLE DESCRIPTIONS WITH THE 'VARITEM' MACRO]
3498
3499 \varitem[|somevariable|]{Some description of |somevariable|.}
3500
3501 @<Declaration of local variables@>=
3502 @<Physical and mathematical constants@>@;
3503 @<Time variables@>@;
3504 @<Declaration of complex arrays storing the electrical field distribution@>@;
3505 @<Declaration of Boolean variables for execution control@>@;
3506 @<Discretization parameters@>@;
3507 @<Grating parameters@>@;
3508 @<Declaration of file pointers@>@;
3509 @<Declaration of strings and file names@>@;
3510 @<Declaration of local dummy variables@>@;
3511 long nne,jje,mmtraject;
3512 long ranseed; /* seed for random number generator */
3513 long maxintens_layer=0;
3514 int fractal_level=0; /* The recursion level in construction of Cantor-type fractal gratings */
3515 int maximum_fractal_level=0; /* The maximum allowed recursion level in
3516 construction of Cantor-type fractal gratings */
3517 double *w0traj=NULL,*w3traj=NULL;
3518 double lambdastart; /* The start vacuum wavelength $\lambda_{\rm start}$
3519 of the spectrum to be sampled */
3520 double lambdastop; /* The stop vacuum wavelength $\lambda_{\rm stop}$
3521 of the spectrum to be sampled */
3522 double lambda; /* Dummy variable to hold the vacuum wavelength at a
3523 discrete spectral sample */
3524 double omega; /* Ditto for the angular frequency
3525 $\omega\equiv 2\pi/\lambda$ */
3526 double ievolambda;
3527 double apolength; /* Length $L_{\rm apod}$ over which each end of the
3528 grating should be apodized */
3529 double phasejumpangle; /* The magnitude of the phase discontinuity
3530 $\varphi_{\rm jump}$ measured in radians */
3531 double phasejumpposition; /* The position $z_{\rm jump}$ in metres of the
3532 phase discontinuity $\varphi_{\rm jump}$ */
3533 double phi; /* Dummy variable to hold the reference phase over the spatial
3534 extent of the grating */
3535 double gyroperturb_position; /* The position $z_{\rm p}$ in metres of the
3536 peak of the added Lorentzian perturbation $\Delta g(z)$ of the gyration
3537 coefficient $g(z)$ */
3538 double gyroperturb_amplitude; /* The zero-to-peak amplitude $a_{\rm p}$ of
3539 the added Lorentzian perturbation $\Delta g(z)$ of the gyration
3540 coefficient $g(z)$ */
3541 double gyroperturb_width; /* The full width at half maximum $w_{\rm p}$ of
3542 the added Lorentzian perturbation $\Delta g(z)$ of the gyration
3543 coefficient $g(z)$ */
3544 double nsurr; /* The linear index of refraction of the medium surrounding
3545 the grating */
3546 double n1,n2,t1,t2,nper,ncrp,g1,g2,gper,gcrp,
3547 pe1,pe2,peper,pecrp,pm1,pm2,pmper,pmcrp,
3548 qe1,qe2,qeper,qecrp,qm1,qm2,qmper,qmcrp;
3549 double modn1,modt1,modg1,modpe1,modpm1,modqe1,modqm1,
3550 aafp2,aafm2,aabp2,aabm2;
3551 double trmintensity,trmintenstart,trmintenstop,
3552 trmellipticity,trmellipstart,trmellipstop,stoke_scalefactor;
3553 static double nndef=600; /* Number of samples in spectrum */
3554 static double mmdef=1000; /* Number of samples in grating */
3555 static double mmedef=1; /* Number of samples in ellipticity */
3556 static double mmidef=1; /* Number of samples in intensity */
3557 static double lldef=0.050; /* Length of grating in metres */
3558 static double nsurrdef=1.0; /* Default surrounding refractive index */
3559 static double lambdastartdef=1536.0e-9,lambdastopdef=1546.0e-9;
3560
3561 @ Declaration of numerical values of physical constants. All calculations
3562 performed by this program are done in \SI\ units, in which the fundamental
3563 physical constants take the values below.
3564
3565 @<Physical and mathematical constants@>=
3566 static double pi=3.1415926535897932384626433832795; /* $\pi$ */
3567 static double twopi=2.0*3.1415926535897932384626433832795; /* $2\pi$ */
3568 static double c=2.997925e8; /* Speed of light in vacuum, $c$ [m/s] */
3569 static double epsilon0=8.854e-12; /* Permittivity of vacuum, $\varepsilon_0$ [As/Vm] */
3570
3571 @ Declaration of time variables. Here any variables related to timing and
3572 estimation of computing performance are declared. The significance of the
3573 variables are as follows:
3574 \varitem[|initime|]{The time at which the \magbragg\ program is initialized.
3575 This variable is initialized already in its declaration.}
3576 \varitem[|now|]{Dummy variable for extraction of current time from the system.}
3577 \varitem[|eta|]{Estimated time of arrival (ETA, not to be confused with the
3578 Greek letter $\eta$) of successful termination of the \magbragg\ program.}
3579
3580 @<Time variables@>=
3581 time_t initime=time(NULL), now=time(NULL), eta=time(NULL);
3582
3583 @ Declaration of pointers to arrays of fields of |dcomplex| class, holding the
3584 intra-grating electrical field distribution.
3585 These pointers will after the memory allocation for complex-valued vectors
3586 hold the spatial distribution of the electric field inside the grating.
3587 The significance of the variables are as follows:\par
3588 \varitem[{$|efp|[k]\equiv E^{\rm f}_+(z^+_k),$}]{The left circularly polarized
3589 forward traveling field component at $z=z_k$ taken in the $k$th homogeneous
3590 layer of the discretized grating.}
3591 \varitem[{$|efm|[k]\equiv E^{\rm f}_-(z^+_k),$}]{The right circularly polarized
3592 forward traveling field component at $z=z_k$ taken in the $k$th homogeneous
3593 layer of the discretized grating.}
3594 \varitem[{$|ebp|[k]\equiv E^{\rm b}_+(z^+_k),$}]{The left circularly polarized
3595 backward traveling field component at $z=z_k$ taken in the $k$th homogeneous
3596 layer of the discretized grating.}
3597 \varitem[{$|ebm|[k]\equiv E^{\rm b}_-(z^+_k),$}]{The right circularly polarized
3598 backward traveling field component at $z=z_k$ taken in the $k$th homogeneous
3599 layer of the discretized grating.}
3600 \medskip
3601 \noindent
3602 that is to say, in a loss-less medium in which the nonlinear correction to the
3603 linear refractive index is determined by the magnitude of the circularly
3604 polarized components of the field envelopes, these arrays hold the full complex
3605 spatial evolution of the electric field.
3606
3607 @<Declaration of complex arrays storing the electrical field distribution@>=
3608 dcomplex *efp,*efm,*ebp,*ebm;
3609
3610 @ Declaration of Boolean variables. The Boolean variables are used as flags
3611 that internally are set and recognized by the \magbragg\ program, for example
3612 to determine states or modes of operation as specified by the user via command
3613 line options.
3614 In the \magbragg\ program, we use integer variables of |short| precision for
3615 storing Boolean values, with the value~0 corresponding to the ``false'' state
3616 and~1 corresponding to the ``true'' state.
3617
3618 @<Declaration of Boolean variables for execution control@>=
3619 short verbose; /* If nonzero, display information at terminal output during
3620 program execution */
3621 short randomdistribution; /* If nonzero, use random layer thicknesses of
3622 a binary-type grating */
3623 short writegratingtofile; /* If nonzero, save the grating structure to
3624 file */
3625 short scale_stokesparams; /* If nonzero, then scale Stokes parameters by
3626 |stoke_scalefactor| */
3627 short normalize_length_to_micrometer; /* If nonzero, */
3628 short normalize_intensity; /* If nonzero, */
3629 short normalize_ellipticity; /* If nonzero, */
3630 short normalize_internally; /* If nonzero, */
3631 short odd_layer; /* Keeps track of odd and even grating layers in initialization */
3632 short chirpflag; /* If nonzero, then apply chirp to periodicity of
3633 sinusoidal grating structures */
3634 short apodize; /* If nonzero, apply apodization to the ends of the grating */
3635 short phasejump; /* If nonzero, apply at least one discrete phase
3636 discontinuity of the grating profile */
3637 short fieldevoflag; /* If nonzero, then save spatial field distribution to file */
3638 short fieldevoflag_efield; /* If nonzero while |fieldevoflag| is nonzero,
3639 then save the complex electric field as the spatial field distribution */
3640 short intensityevoflag; /* If nonzero while |fieldevoflag| is nonzero, then
3641 save the field intensity as the spatial field distribution */
3642 short fieldevoflag_stoke; /* If nonzero while |fieldevoflag| is nonzero,
3643 then save the Stokes parameters as the spatial field distribution */
3644 short intensityinfo; /* If nonzero, then display the maximum and minimum
3645 field intensities found within the grating at terminal output before
3646 closing the program */
3647 short saveintensityinfologfile; /* If nonzero, then also save the displayed
3648 maximum and minimum intensities to a log file */
3649 short trmtraject_specified; /* If nonzero, */
3650 short save_dbspectra; /* If nonzero, then save any transmission spectrum in
3651 logarithmic (dB) scale */
3652 short stokes_parameter_spectrum;/* If nonzero, then save any transmission
3653 spectrum in terms of the corresponding Stokes parameters */
3654 short display_surrounding_media; /* If nonzero, then append also the
3655 surrounding medium when saving the spatial grating profile to file */
3656 short perturbed_gyration_constant; /* If nonzero, */
3657
3658 @ Declaration of discretization parameters. These parameters determine the
3659 discretization of the problem at hand, such as the number of points in
3660 intensity, ellipticity or wavelength to be scanned.
3661 The significance of the variables are as follows:\par
3662 \varitem[|mm|]{The number of points $M$ to be sampled in the spectrum between
3663 vacuum wavelengths $\lambda_{\rm start}$ and $\lambda_{\rm stop}$.}
3664 \varitem[|mme|]{The number $M_{\rm e}$ of ellipticities $\varepsilon_{\rm tr}$
3665 of the transmitted light to be sampled in the interval
3666 $\varepsilon_{\rm tr,start}\le\varepsilon\le\varepsilon_{\rm tr,stop}$.}
3667 \varitem[|mmi|]{The number $M_{\rm i}$ of intensities $I_{\rm tr}$ of the
3668 transmitted light to be sampled in the interval
3669 $I_{\rm tr,start}\le I_{\rm tr}\le I_{\rm tr,stop}$.}
3670
3671 @<Discretization parameters@>=
3672 long mm, mme, mmi;
3673
3674 @ Declaration of grating parameters. These parameters fully describe the
3675 geometry and material properties of the medium in which the wave propagation
3676 is to be performed. The significance of the variables are as follows:\par
3677 \varitem[|ll|]{Geometrical length $L$ of the grating measured in metres.}
3678 \varitem[|nn|]{The number $N$ of discrete interfaces separating the $N-1$
3679 homogeneous layers of the grating and the surrounding medium.}
3680 \varitem[|modnum|]{If positive, this is the number of a manually modified
3681 layer, for instance a defect or cavity layer possessing different geometrical
3682 or optical properties than the rest of the structure described by any of the
3683 standard grating options.}
3684 \varitem[|*z|]{Pointer to an array of $N$ elements for storing the coordinates
3685 of the discrete interfaces $z_1,\ldots,z_N$ between homogeneous layers of
3686 the grating.}
3687 \varitem[|*dz|]{Pointer to an array of $N-1$ elements containing the layer
3688 thicknesses $|dz|[k]\equiv z_{k+1}-z_k$, $k=1,\ldots,N-1$.}
3689 \varitem[|*n|, |*g|]{Pointers to arrays of $N-1$ elements containing the
3690 refractive indices $|n[k]|=n_k$ and magneto-optical gyration coefficients
3691 $|g[k]|=g_k=i\chi^{({\rm eem})}_{xyz}B^z_0 /(2 n_k)$ of the homogeneous
3692 layers.}
3693 \varitem[|*pe|, |*qe|]{Pointers to arrays of $N-1$ elements containing the
3694 nonlinear optical coefficients
3695 $|pe[k]|=\chi^{\rm eeee}_{xxxx}-\chi^{\rm eeee}_{xyyx}$ and
3696 $|qe[k]|=\chi^{\rm eeee}_{xxxx}+\chi^{\rm eeee}_{xyyx}$ of the homogeneous
3697 layers.}
3698 \varitem[|*pm|, |*qm|]{Pointers to arrays of $N-1$ elements containing the
3699 nonlinear magneto-optical coefficients
3700 $|pm[k]|=i(\chi^{\rm eeeem}_{xyyyz}-\chi^{\rm eeeem}_{xxxyz})B^z_0$ and
3701 $|qm[k]|=i(\chi^{\rm eeeem}_{xyyyz}+\chi^{\rm eeeem}_{xxxyz})B^z_0$ of the
3702 layers.}
3703 \varitem[|*etafp|, |*etafm|]{Pointers to arrays of $N-1$ elements for storing
3704 the nonlinear coefficients of propagation $\eta^{\rm f}_+$ related to the
3705 phase evolution of forward (f) traveling left ($+$) and right ($-$)
3706 circularly polarized components of in respective layer $z_j<z<z_{j+1}$, with
3707 $|etafp|[j]=\eta^{\rm f}_+(z^+_j)$ and $|etafm|[j]=\eta^{\rm f}_-(z^+_j)$.}
3708 \varitem[|*etabp|, |*etabm|]{Analogous to |*etafp| and |*etafm| but instead for
3709 the nonlinear phase contributions $|etabp|[j]=\eta^{\rm b}_+(z^+_j)$ and
3710 $|etabm|[j]=\eta^{\rm b}_-(z^+_j)$ for backward traveling field components.}
3711 \varitem[|*taup|, |*taum|]{Pointers to arrays of $N$ elements for storing the
3712 forward intra-grating layer transmittances $\tau_{k_+}$ and $\tau_{k_-}$.}
3713 \varitem[|*taupp|, |*taupm|]{Pointers to arrays of $N$ elements for storing
3714 the backward intra-grating layer transmittances $\tau'_{k_+}$ and
3715 $\tau'_{k_-}$.}
3716 \varitem[|*rhop|, |*rhom|]{Pointers to arrays of $N$ elements for storing the
3717 forward intra-grating layer reflectances $\rho_{k_+}$ and $\rho_{k_-}$.}
3718 \varitem[|*rhopp|, |*rhopm|]{Pointers to arrays of $N$ elements for storing the
3719 backward intra-grating layer reflectances $\rho'_{k_+}$ and $\rho'_{k_-}$.}
3720 \medskip
3721 For the definitions of the intra-grating layer reflectances and transmittances,
3722 see the separate section {\it Calculation of intra-grating layer reflectances}.
3723
3724 @<Grating parameters@>=
3725 long nn, modnum;
3726 double ll,*z,*dz,*n,*g,*pe,*pm,*qe,*qm,*etafp,*etafm,*etabp,*etabm;
3727 double *taup,*taum,*taupp,*taupm,*rhop,*rhom,*rhopp,*rhopm;
3728
3729 @ Declaration of file pointers.
3730
3731 @<Declaration of file pointers@>=
3732 FILE *fp_s0,*fp_s1,*fp_s2,*fp_s3; /* Stokes parameters of incident wave */
3733 FILE *fp_v0,*fp_v1,*fp_v2,*fp_v3; /* Stokes parameters of reflected wave */
3734 FILE *fp_w0,*fp_w1,*fp_w2,*fp_w3; /* Stokes params. of transmitted wave */
3735 FILE *fp_evo=NULL,*fp_ievo=NULL,*fp_spec=NULL,*fp_traject=NULL;
3736 FILE *fp_irspec=NULL,*fp_itspec=NULL,*fp_icspec=NULL,*fp_gr=NULL;
3737 FILE *fp_evo_s0=NULL,*fp_evo_s1=NULL,*fp_evo_s2=NULL,*fp_evo_s3=NULL;
3738 FILE *intensinfologfile=NULL;
3739
3740 @ Declaration of character strings holding file names.
3741 Generally in this program, the maximum number of characters a file name
3742 string can contain is |NCHMAX|, as defined in the definitions section
3743 of the program.
3744
3745 @<Declaration of strings and file names@>=
3746 char gratingtype[NCHMAX],gratingsubtype[NCHMAX];
3747 char fieldevofilename[NCHMAX],intensityevofilename[NCHMAX];
3748 char spectrumfilename[NCHMAX],trmtraject_filename[NCHMAX];
3749 char intensity_reflection_spectrumfilename[NCHMAX],
3750 intensity_transmission_spectrumfilename[NCHMAX],
3751 intensity_check_spectrumfilename[NCHMAX];
3752 char fieldevofilename_s0[NCHMAX],fieldevofilename_s1[NCHMAX],
3753 fieldevofilename_s2[NCHMAX],fieldevofilename_s3[NCHMAX];
3754 char intensinfologfilename[NCHMAX];
3755 char outfilename[NCHMAX],gratingfilename[NCHMAX];
3756 char outfilename_s0[NCHMAX],outfilename_s1[NCHMAX],
3757 outfilename_s2[NCHMAX],outfilename_s3[NCHMAX];
3758 char outfilename_v0[NCHMAX],outfilename_v1[NCHMAX],
3759 outfilename_v2[NCHMAX],outfilename_v3[NCHMAX];
3760 char outfilename_w0[NCHMAX],outfilename_w1[NCHMAX],
3761 outfilename_w2[NCHMAX],outfilename_w3[NCHMAX];
3762
3763 @ Declaration of dummy variables. Here dummy and temporary variables are
3764 declared, where the ``dummy'' variables typically are integer counters
3765 for iteration over wavelength, ellipticity, intensity and so on, while the
3766 temporary variables are internally used for in some cases saving computational
3767 time, and also for the sake of increasing the readability of the program
3768 somewhat.
3769
3770 @<Declaration of local dummy variables@>=
3771 dcomplex tmpfp,tmpfm,tmpbp,tmpbm;
3772 double tmp,zt,s0,s1,s2,s3,v0,v1,v2,v3,w0,w1,w2,w3,stn,
3773 maxintens=0.0,maxintens_inintens=0.0,maxintens_inellip=0.0,
3774 maxintens_trintens=0.0,maxintens_trellip=0.0;
3775 int no_arg,status=0,tmpch;
3776 long j,k,ke,ki;
3777
3778 @*Initialization of variables.
3779
3780 @<Initialize variables@>=
3781 trmtraject_specified=0; /* Is a trajectory of $(W_0,W_3)$ specified? */
3782 intensityinfo=0; /* Printing basic intensity info to stdout; default: off */
3783 saveintensityinfologfile=0; /* Printing basic intensity info to file */
3784 randomdistribution=0; /* Random shuffling of layers; default: off */
3785 writegratingtofile=0; /* Save spatial grating structure; default: off */
3786 scale_stokesparams=0; /* Scale Stokes parameters by |stoke_scalefactor|; default: off */
3787 stoke_scalefactor=1.0; /* Scale factor to be used for Stokes parameters */
3788 normalize_length_to_micrometer=0;
3789 normalize_intensity=0;/* Write normalized intensity to file; default: off */
3790 normalize_ellipticity=0;/* Ditto for the ellipticity */
3791 ranseed=1097; /* Seed for random number generator */
3792 modnum=-1; /* If positive, the manually modified layer number */
3793 verbose=0; /* Verbose mode is off by default */
3794 apodize=0; /* Apodization is off by default */
3795 phasejump=0; /* Discrete phase jump is off by default */
3796 normalize_internally=0; /* Default state of internal normalization is off */
3797 odd_layer=0; /* Counter flag for odd and even grating layers */
3798 chirpflag=1;
3799 save_dbspectra=0;
3800 stokes_parameter_spectrum=0;
3801 display_surrounding_media=1; /* Append also the
3802 surrounding medium when saving the spatial grating profile to file;
3803 default: on */
3804 perturbed_gyration_constant=0;
3805 fieldevoflag=0; /* Save spatial field distribution to file; default: off */
3806 fieldevoflag_efield=0; /* Save as complex electric field; default: off */
3807 fieldevoflag_stoke=0; /* Save as Stokes parameters; default: off */
3808 intensityevoflag=0; /* Save spatial intensity distribution; default: off */
3809 mm=mmdef; /* Number of sampling points in optical spectrum */
3810 nn=nndef; /* Number of layer interfaces of grating; num of layers is nn-1 */
3811 mme=mmedef; /* Number of sampling points in transmitted ellipticity */
3812 mmi=mmidef; /* Number of sampling points in transmitted intensity */
3813 nne=1; /* Default number extra, intra-layer sampling points */
3814 ll=lldef; /* Default physical length of the grating structure */
3815 lambdastart=lambdastartdef;
3816 lambdastop=lambdastopdef;
3817 phasejumpangle=0.0; /* Discrete phase jump is off by default */
3818 phasejumpposition=0.0; /* Discrete phase jump is off by default */
3819 phi=0.0; /* Discrete phase jump is off by default */
3820 nsurr=nsurrdef; /* Default index of refraction of the surrounding medium */
3821 strcpy(outfilename,"out.stok"); /* Default output file basename */
3822 strcpy(fieldevofilename,"out.fevo.dat"); /* Default output file basename */
3823 strcpy(fieldevofilename_s0,"out.fevo.s0.dat");
3824 strcpy(fieldevofilename_s1,"out.fevo.s1.dat");
3825 strcpy(fieldevofilename_s2,"out.fevo.s2.dat");
3826 strcpy(fieldevofilename_s3,"out.fevo.s3.dat");
3827 strcpy(spectrumfilename,"out.rsp.dat"); /* Default output file name */
3828 strcpy(intensity_reflection_spectrumfilename,"out.irsp.dat");
3829 strcpy(intensity_transmission_spectrumfilename,"out.trsp.dat");
3830 strcpy(intensity_check_spectrumfilename,"out.chec.dat");
3831 fp_s0=NULL; fp_s1=NULL; fp_s2=NULL; fp_s3=NULL;
3832 fp_v0=NULL; fp_v1=NULL; fp_v2=NULL; fp_v3=NULL;
3833 fp_w0=NULL; fp_w1=NULL; fp_w2=NULL; fp_w3=NULL;
3834
3835 @*Memory allocation.
3836 Allocate memory for the temporary storage of the spatial distribution of
3837 material parameters of the grating structure and internal, complex-valued
3838 electromagnetic fields.
3839 In \TeX-style notation, the parameters are interpreted in terms
3840 of the optical and magneto-optical susceptibilities [Fredrik Jonsson,
3841 {\it The Nonlinear Optics of Magneto-Optic Media}, PhD thesis
3842 (The Royal Institute of Technology, Stockholm, 2000)] as follows,
3843 starting with the all-optical (electric-dipolar related) parameters
3844 $$
3845 \eqalign{
3846 |n[k]|&=n_k=[1+\chi^{({\rm ee})}_{xx}]^{1/2},\cr
3847 |pe[k]|
3848 &=\chi^{\rm eeee}_{xxxx}-\chi^{\rm eeee}_{xyyx},\cr
3849 |qe[k]|
3850 &=\chi^{\rm eeee}_{xxxx}+\chi^{\rm eeee}_{xyyx},\cr
3851 }
3852 $$
3853 where all susceptibilities of the right-hand sides are to be evaluated in the
3854 domains $z_k<z<z_{k+1}$, $k=1,2,\ldots N-1$. In addition to the all-optical
3855 parameters, the magneto-optical (magnetic-dipolar related) parameters are
3856 defined as
3857 $$
3858 \eqalign{
3859 |g[k]|&=g_k=i\chi^{({\rm eem})}_{xyz} B^z_0 /(2 n_k),\cr
3860 |pm[k]|
3861 &=i(\chi^{\rm eeeem}_{xyyyz}-\chi^{\rm eeeem}_{xxxyz})B^z_0,\cr
3862 |qm[k]|
3863 &=i(\chi^{\rm eeeem}_{xyyyz}+\chi^{\rm eeeem}_{xxxyz})B^z_0,\cr
3864 }
3865 $$
3866 using the same conventions of evaluation for the involved susceptibilities in
3867 the righ-hand sides.
3868 With these definitions, the left circularly polarized (LCP) and right
3869 circularly polarized (RCP) modes that propagate in the forward direction in
3870 the $k$th layer will experience the linear, field-independent refractive
3871 indices $n_{k_+}$ and $n_{k_-}$, respectively, with
3872 $$
3873 \eqalignno{
3874 n_{k_+}&=n_k[1+i\chi^{({\rm eem})}_{xyz} B^z_0 /(2 n^2_k)]
3875 =n_k+g_k,&{\rm(LCP)}\cr
3876 n_{k_-}&=n_k[1-i\chi^{({\rm eem})}_{xyz} B^z_0 /(2 n^2_k)]
3877 =n_k-g_k.&{\rm(RCP)}\cr
3878 }
3879 $$
3880 For backward propagating light, the experienced indices of refraction are
3881 reversed, that is to say, backward propagating left circularly polarized
3882 light experience $n_-$ as the refractive index, while the right circularly
3883 polarized experience $n_+$.
3884
3885 We here throughout adopt to common standard definition of circularly polarized
3886 light, that when looking into an oncoming wave propagating in the positive
3887 $z$-direction, the vector of the LCP electric field component $E^{\rm f}_+$
3888 of the wave describes counterclockwise motion, while it for the RCP field
3889 component $E^{\rm f}_-$ instead describes clockwise motion.
3890 This convention conforms to the classical one as used in
3891 optics~[J.~D.~Jackson, {Classical Electrodynamics} (Wiley, New York, 1975);
3892 M.~Born and E.~Wolf, {Principles of Optics} (Cambridge University Press,
3893 Cambridge, 1980)].
3894 Similarly, by looking into an oncoming wave propagating in the negative
3895 $z$-direction, the vector of the LCP electric field component $E^{\rm b}_+$
3896 describes counterclockwise motion, while it for the RCP field component
3897 $E^{\rm b}_-$ describes clockwise motion.
3898
3899 In the following allocation of memory, the $k$th element of respective vector
3900 contains the numerical value for the respective material parameter evaluated
3901 in the domain $z_k < z < z_{k+1}$, for $k=1,2,\ldots,N-1$, while the vectors
3902 containing the electrical field components contain the respective component
3903 evaluated at the ``beginning'' of respective layer, at $z=z^+_k$.
3904 From material parameters such as the linear refractive indices $n_k$ and
3905 the magneto-optical gyration constants $g_k$ of the compound structure,
3906 derived numerical quantities, such as the transmission coefficients
3907 $\tau_{k_{\pm}}$ and $\tau'_{k_{\pm}}$ and the reflection coefficients
3908 $\rho_{k_{\pm}}$ and $\rho'_{k_{\pm}}$ across the interfaces at $z_k$,
3909 are later on calculated and stored in vectors that here are allocated.
3910
3911 @<Allocate optical field vectors@>=
3912 {
3913 z=dvector(1,nn); /* Spatial coordinate $z_k$ along the Bragg grating */
3914 dz=dvector(1,nn-1); /*$|dz|[k]\equiv|z|[k+1]-|z|[k]$, $k=1,2,...,|nn|-1$*/
3915 efp=dcvector(0,nn); /* Equals $E^f_{k_+}$ in \TeX-style notation */
3916 efm=dcvector(0,nn); /* Equals $E^f_{k_-}$ in \TeX-style notation */
3917 ebp=dcvector(0,nn); /* Equals $E^b_{k_+}$ in \TeX-style notation */
3918 ebm=dcvector(0,nn); /* Equals $E^b_{k_-}$ in \TeX-style notation */
3919 taup=dvector(1,nn); /* Forward LCP transmission coefficient $\tau_{k_+}$ */
3920 taum=dvector(1,nn); /* Forward RCP transmission coefficient $\tau_{k_+}$ */
3921 taupp=dvector(1,nn); /* Backward LCP transmission coeff.~ $\tau'_{k_+}$ */
3922 taupm=dvector(1,nn); /* Backward RCP transmission coeff.~$\tau'_{k_-}$ */
3923 rhop=dvector(1,nn); /* Forward LCP reflection coeff.~$\rho_{k_+}$ */
3924 rhom=dvector(1,nn); /* Forward RCP reflection coeff.~$\rho_{k_-}$ */
3925 rhopp=dvector(1,nn); /* Backward LCP reflection coeff.~$\rho'_{k_+}$ */
3926 rhopm=dvector(1,nn); /* Backward RCP reflection coeff.~$\rho'_{k_-}$ */
3927 n=dvector(0,nn); /* Linear electric-dipolar refractive index $n(z)$ */
3928 g=dvector(0,nn); /* Linear magneto-optical contribution to $n(z)$ */
3929 pe=dvector(1,nn-1); /* Nonlinear all-optical contribution to $n(z)$ */
3930 pm=dvector(1,nn-1); /* Nonlinear magneto-optical contribution to $n(z)$ */
3931 qe=dvector(1,nn-1); /* Nonlinear all-optical contribution to $n(z)$ */
3932 qm=dvector(1,nn-1); /* Nonlinear magneto-optical contribution to $n(z)$ */
3933 etafp=dvector(1,nn-1); /* Nonlinear LCP forward contribution to $n(z)$ */
3934 etabp=dvector(1,nn-1); /* Nonlinear LCP backward contribution to $n(z)$ */
3935 etafm=dvector(1,nn-1); /* Nonlinear RCP forward contribution to $n(z)$ */
3936 etabm=dvector(1,nn-1); /* Nonlinear RCP backward contribution to $n(z)$ */
3937 }
3938
3939 @ At the end of the program, we would also like to properly deallocate
3940 the memory occupied by the previously allocated real- and complex-valued
3941 vectors that have been used in the simulation. This is done by executing
3942 the following block.
3943
3944 @<Deallocate optical field vectors@>=
3945 {
3946 free_dcvector(efp,0,nn);
3947 free_dcvector(efm,0,nn);
3948 free_dcvector(ebp,0,nn);
3949 free_dcvector(ebm,0,nn);
3950 free_dvector(taup,1,nn);
3951 free_dvector(taum,1,nn);
3952 free_dvector(taupp,1,nn);
3953 free_dvector(taupm,1,nn);
3954 free_dvector(rhop,1,nn);
3955 free_dvector(rhom,1,nn);
3956 free_dvector(rhopp,1,nn);
3957 free_dvector(rhopm,1,nn);
3958 free_dvector(n,0,nn);
3959 free_dvector(g,0,nn);
3960 free_dvector(pe,1,nn-1);
3961 free_dvector(pm,1,nn-1);
3962 free_dvector(qe,1,nn-1);
3963 free_dvector(qm,1,nn-1);
3964 free_dvector(etafp,1,nn-1);
3965 free_dvector(etabp,1,nn-1);
3966 free_dvector(etafm,1,nn-1);
3967 free_dvector(etabm,1,nn-1);
3968 if (trmtraject_specified) {
3969 free_dvector(w0traj,1,mmtraject);
3970 free_dvector(w3traj,1,mmtraject);
3971 }
3972 }
3973
3974 @*Initialization of the grating structure.
3975 Using the previously allocated memory for the temporary storage of the
3976 spatially distributed grating structure, initiate the material parameters
3977 of the interior of the grating.
3978 If the user via the command line options has specified that a perturbation
3979 of the gyration constant should be present somewhere along the grating, then
3980 add a perturbation in the functional form of a magneto-optical effect that
3981 would arise due to a current carrying wire, placed orthogonal to the direction
3982 of propagation, and in a close vicinity of the medium.
3983
3984 @<Initiate grating structure@>=
3985 {
3986 if(!strcmp(gratingtype,"stepwise")) {
3987 @<Initiate binary grating structure@>;
3988 } else if(!strcmp(gratingtype,"sinusoidal")) {
3989 @<Initiate sinusoidal grating structure@>;
3990 } else if(!strcmp(gratingtype,"chirped")) {
3991 @<Initiate chirped grating structure@>;
3992 } else if(!strcmp(gratingtype,"fractal")) {
3993 @<Initiate fractal grating structure@>;
3994 } else{
3995 fprintf(stderr,
3996 "%s: Error: Specified grating type is invalid.\n",progname);
3997 showsomehelp();
3998 exit(FAILURE);
3999 }
4000 if (perturbed_gyration_constant) {
4001 @<Add perturbation of gyration constant along grating structure@>;
4002 }
4003 }
4004
4005 @ For the binary type of stepwise gratings, with the refractive index and
4006 all other material parameters of the medium spatially alternating between
4007 two distinct values, the odd layers (i.e. $z_k<z<z_{k+1}$, with $k$ being
4008 an odd integer) have all the layer thickness given by the parameter |t1|,
4009 while all even layers (i.e. $z_k<z<z_{k+1}$, with $k$ being an even integer)
4010 have the layer thickness given by |t2|.
4011 This means that in this case the total length of the grating is given as
4012 $$
4013 L = \{{\rm the\ number\ of\ odd\ layers}\}\times|t1|
4014 + \{{\rm the\ number\ of\ even\ layers}\}\times|t2|,
4015 $$
4016 and hence the value of any specified grating length (by using the
4017 \.{--gratinglength} option) will be neglected for the \.{twolevel}
4018 stepwise type of grating.
4019
4020 The material parameters |pe|, |qe|, |pm|, and |qm|, are (as previously)
4021 defined as
4022 $$
4023 \eqalign{
4024 |pe[k]|&=\chi^{\rm eeee}_{xxxx}(-\omega;\omega,\omega,-\omega)
4025 -\chi^{\rm eeee}_{xyyx}(-\omega;\omega,\omega,-\omega),\cr
4026 |qe[k]|&=\chi^{\rm eeee}_{xxxx}(-\omega;\omega,\omega,-\omega)
4027 +\chi^{\rm eeee}_{xyyx}(-\omega;\omega,\omega,-\omega),\cr
4028 |pm[k]|&=i(\chi^{\rm eeeem}_{xyyyz}(-\omega;\omega,\omega,-\omega,0)
4029 -\chi^{\rm eeeem}_{xxxyz}(-\omega;\omega,\omega,-\omega,0))B^z_0,\cr
4030 |qm[k]|&=i(\chi^{\rm eeeem}_{xyyyz}(-\omega;\omega,\omega,-\omega,0)
4031 +\chi^{\rm eeeem}_{xxxyz}(-\omega;\omega,\omega,-\omega,0))B^z_0,\cr
4032 }
4033 $$
4034 where $\chi^{\rm eeee}_{\mu\alpha\beta\gamma}
4035 (-\omega;\omega,\omega,-\omega)$ and
4036 $\chi^{\rm eeeem}_{\mu\alpha\beta\gamma\delta}
4037 (-\omega;\omega,\omega,-\omega,0)$
4038 are the nonlinear optical and magneto-optical susceptibility tensors
4039 governing the intensity-dependent refractive index and Faraday effect,
4040 respectively, taken in a notation conforming to P.~N.~Butcher and D.~Cotter
4041 [P.~N.~Butcher and D.~Cotter, {\it The Elements of Nonlinear Optics}
4042 (Cambridge University Press, New York, 1990)], and to be evaluated in
4043 respective layer $z_k<z<z_{k+1}$, $k=1,2,\ldots,N-1$.
4044
4045 When initializing the binary type of stepwise gratings, the program will check
4046 if the |randomdistribution| flag (a numerical integer) was set through the
4047 command line parameters. If so (i.~e.~if $|randomdistribution|=1$), then the
4048 layers of different indices and material parameters will be randomly ordered.
4049
4050 @<Initiate binary grating structure@>=
4051 {
4052 if(!strcmp(gratingsubtype,"twolevel")) {
4053 if (randomdistribution) {
4054 for (j=1;j<=nn-1;j++) {
4055 if (j==modnum) {
4056 if (j==1) z[j]=0.0;
4057 z[j+1]=z[j]+modt1;
4058 dz[j]=modt1;
4059 n[j]=modn1;
4060 g[j]=modg1;
4061 pe[j]=modpe1;
4062 pm[j]=modpm1;
4063 qe[j]=modqe1;
4064 qm[j]=modqm1;
4065 } else {
4066 ranseed=ranseed+j;
4067 if (ran1(&ranseed)>0.5) {
4068 if (verbose) fprintf(stdout,"Random number: 1\n");
4069 if (j==1) z[j]=0.0;
4070 z[j+1]=z[j]+t1;
4071 dz[j]=t1;
4072 n[j]=n1;
4073 g[j]=g1;
4074 pe[j]=pe1;
4075 pm[j]=pm1;
4076 qe[j]=qe1;
4077 qm[j]=qm1;
4078 } else {
4079 if (verbose) fprintf(stdout,"Random number: 0\n");
4080 if (j==1) z[j]=0.0;
4081 z[j+1]=z[j]+t2;
4082 dz[j]=t2;
4083 n[j]=n2;
4084 g[j]=g2;
4085 pe[j]=pe2;
4086 pm[j]=pm2;
4087 qe[j]=qe2;
4088 qm[j]=qm2;
4089 }
4090 }
4091 }
4092 } else { /* else, if non-random distribution */
4093 if (modnum<0) { /* if no modified layer of the grating, ... */
4094 for (j=1;j<=nn-1;j=j+2) { /* all odd layers, $|j|=1,3,5,\ldots$ */
4095 z[j]=0.5*((double)(j-1))*(t1+t2);
4096 dz[j]=t1;
4097 n[j]=n1;
4098 g[j]=g1;
4099 pe[j]=pe1;
4100 pm[j]=pm1;
4101 qe[j]=qe1;
4102 qm[j]=qm1;
4103 if (j==nn-1) z[nn]=z[nn-1]+t1;
4104 }
4105 for (j=2;j<=nn-1;j=j+2) { /* all even layers, $|j|=2,4,6,\ldots$ */
4106 z[j]=z[j-1]+t1;
4107 dz[j]=t2;
4108 n[j]=n2;
4109 g[j]=g2;
4110 pe[j]=pe2;
4111 pm[j]=pm2;
4112 qe[j]=qe2;
4113 qm[j]=qm2;
4114 if (j==nn-1) z[nn]=z[nn-1]+t2;
4115 }
4116 } else { /* ... else, if at least one modified layer of the grating */
4117 for (j=1;j<=nn-1;j++) {
4118 if (j==1) z[j]=0.0;
4119 if (j==modnum) { /* the modified layer */
4120 z[j+1]=z[j]+modt1;
4121 dz[j]=modt1;
4122 n[j]=modn1;
4123 g[j]=modg1;
4124 pe[j]=modpe1;
4125 pm[j]=modpm1;
4126 qe[j]=modqe1;
4127 qm[j]=modqm1;
4128 } else {
4129 tmp=((double)j)/((double)2);
4130 if (tmp-floor(tmp)>0.25) { /* if |j| odd */
4131 z[j+1]=z[j]+t1;
4132 dz[j]=t1;
4133 n[j]=n1;
4134 g[j]=g1;
4135 pe[j]=pe1;
4136 pm[j]=pm1;
4137 qe[j]=qe1;
4138 qm[j]=qm1;
4139 } else { /* if |j| even */
4140 z[j+1]=z[j]+t2;
4141 dz[j]=t2;
4142 n[j]=n2;
4143 g[j]=g2;
4144 pe[j]=pe2;
4145 pm[j]=pm2;
4146 qe[j]=qe2;
4147 qm[j]=qm2;
4148 }
4149 }
4150 }
4151 }
4152 }
4153 } else{
4154 fprintf(stderr,"%s: Error.\n",progname);
4155 fprintf(stderr,"%s: (No valid grating subtype found).\n",progname);
4156 exit(FAILURE);
4157 }
4158 }
4159
4160 @ For the sinusoidal type gratings, the grating structure is spatially
4161 oversampled and modelled as a large number of thin homogeneous slices,
4162 as in the oversampling in some algorithms for calculation of
4163 transmission properties of fiber Bragg gratings. In the oversampling,
4164 the thickness of each of the layers is equal, using an equidistanly
4165 spaced spatial increment in the beam propagation performed across each
4166 of the layers.
4167 Here, |nper| is the physical, spatial period of the refractive index
4168 distribution $n(z)$, while |gper| is the spatial period of the linear
4169 magneto-optical gyration constant $g(z)$, etc.
4170
4171 For sinusoidal type gratings, any stated apodization profile will also
4172 be applied,
4173 in order to get rid of any occurring Gibbs oscillations due to a rapid
4174 change of the index modulation at the ends of the grating.
4175 From a user perspective, the \.{--apodize}
4176 option is used at startup time of the program for specifying a smoother
4177 transition between modulated and non-modulated regions of the grating.
4178 The apodization is performed at the ends of the grating according to a
4179 multiplicative factor of the |n2| and |g2| modulation amplitudes of the
4180 refractive index and gyration coefficient, of the form
4181 $$
4182 f(z)=\Bigg\lbrace
4183 \matrix{[1-\cos(\pi z/a)]/2,&\ 0\le z\le a,\cr
4184 1,&\ a<z<L-a,\cr
4185 [1-\cos(\pi(z-L)/a)]/2,&\ L-a\le z\le L,}
4186 $$
4187 and otherwise $f(z)=0$, for any $z$ outside the above domains of definition,
4188 where $a$ is the effective apodization length, being the floating point
4189 parameter specified after the \.{--apodize} option, and $L$ as usual the
4190 geometrical overall length of the grating.
4191
4192 In the generation of the sinusoidal grating structure, we also include any
4193 possible discrete spatial phase jump, as specified by the \.{--phasejump}
4194 command line option.
4195
4196 @<Initiate sinusoidal grating structure@>=
4197 {
4198 t1=ll/((double)(nn-1));
4199 for (j=1;j<=nn-1;j++) {
4200 z[j]=((double)(j-1))*t1;
4201 dz[j]=t1;
4202 if (apodize) {
4203 if ((0.0<=z[j])&&(z[j]<=apolength)) {
4204 tmp=(1.0-cos(pi*z[j]/apolength))/2.0;
4205 } else if ((apolength<=z[j])&&(z[j]<=ll-apolength)) {
4206 tmp=1.0;
4207 } else if ((ll-apolength<=z[j])&&(z[j]<=ll)) {
4208 tmp=(1.0-cos(pi*(z[j]-ll)/apolength))/2.0;
4209 } else {
4210 tmp=0.0;
4211 fprintf(stderr,
4212 "%s: Impossible apodization event occurred.",progname);
4213 fprintf(stderr,
4214 "%s: (Please check grating initialization.)",progname);
4215 }
4216 }
4217 if (phasejump) {
4218 if (z[j]>=phasejumpposition) {
4219 phi=phasejumpangle;
4220 } else {
4221 phi=0.0;
4222 }
4223 }
4224 if (apodize) {
4225 n[j]=n1+n2*tmp*sin(twopi*z[j]/nper+phi);
4226 g[j]=g1+g2*tmp*sin(twopi*z[j]/gper+phi);
4227 } else {
4228 n[j]=n1+n2*sin(twopi*z[j]/nper+phi);
4229 g[j]=g1+g2*sin(twopi*z[j]/gper+phi);
4230 }
4231 pe[j]=pe1+pe2*sin(twopi*z[j]/peper);
4232 pm[j]=pm1+pm2*sin(twopi*z[j]/pmper);
4233 qe[j]=qe1+qe2*sin(twopi*z[j]/qeper);
4234 qm[j]=qm1+qm2*sin(twopi*z[j]/qmper);
4235 }
4236 z[nn]=ll;
4237 }
4238
4239 @ Just as for the sinusoidal type gratings, the chirped grating structure
4240 is spatially oversampled and modelled as a large number of thin homogeneous
4241 slices of equal thickness.
4242 As in the case of a pure sinusoidal grating, we here also check whether an
4243 apodization should be applied to the grating profile, subsequently applying
4244 the apodization.
4245 In the generation of the chirped grating structure, we also include any
4246 possible discrete spatial phase jump, as specified by the \.{--phasejump}
4247 command line option.
4248
4249 @<Initiate chirped grating structure@>=
4250 {
4251 t1=ll/((double)(nn-1));
4252 for (j=1;j<=nn-1;j++) {
4253 z[j]=((double)(j-1))*t1;
4254 dz[j]=t1;
4255 if (apodize) {
4256 if ((0.0<=z[j])&&(z[j]<=apolength)) {
4257 tmp=(1.0-cos(pi*z[j]/apolength))/2.0;
4258 } else if ((apolength<=z[j])&&(z[j]<=ll-apolength)) {
4259 tmp=1.0;
4260 } else if ((ll-apolength<=z[j])&&(z[j]<=ll)) {
4261 tmp=(1.0-cos(pi*(z[j]-ll)/apolength))/2.0;
4262 } else {
4263 tmp=0.0;
4264 fprintf(stderr,
4265 "%s: Impossible apodization event occurred.",progname);
4266 fprintf(stderr,
4267 "%s: (Please check grating initialization.)",progname);
4268 }
4269 }
4270 if (phasejump) {
4271 if (z[j]>=phasejumpposition) {
4272 phi=phasejumpangle;
4273 } else {
4274 phi=0.0;
4275 }
4276 }
4277 if (apodize) {
4278 if (fabs(ncrp)>0.0) /* if nonzero chirp of $n(z)$ */
4279 n[j]=n1+n2*tmp*sin((twopi/ncrp)*log(1.0+ncrp*z[j]/nper)+phi);
4280 else
4281 n[j]=n1+n2*tmp*sin(twopi*z[j]/nper+phi);
4282 if (fabs(gcrp)>0.0) /* if nonzero chirp of $g(z)$ */
4283 g[j]=g1+g2*tmp*sin((twopi/gcrp)*log(1.0+gcrp*z[j]/gper)+phi);
4284 else
4285 g[j]=g1+g2*tmp*sin(twopi*z[j]/gper+phi);
4286 } else {
4287 if (fabs(ncrp)>0.0) /* if nonzero chirp of $n(z)$ */
4288 n[j]=n1+n2*sin((twopi/ncrp)*log(1.0+ncrp*z[j]/nper)+phi);
4289 else
4290 n[j]=n1+n2*sin(twopi*z[j]/nper+phi);
4291 if (fabs(gcrp)>0.0) /* if nonzero chirp of $g(z)$ */
4292 g[j]=g1+g2*sin((twopi/gcrp)*log(1.0+gcrp*z[j]/gper)+phi);
4293 else
4294 g[j]=g1+g2*sin(twopi*z[j]/gper+phi);
4295 }
4296 if (fabs(pecrp)>0.0) /* if nonzero chirp of $p_{\rm e}(z)$ */
4297 pe[j]=pe1+pe2*sin((twopi/pecrp)*log(1.0+pecrp*z[j]/peper));
4298 else
4299 pe[j]=pe1+pe2*sin(twopi*z[j]/peper);
4300 if (pmcrp*pmcrp>0.0) /* if nonzero chirp of $p_{\rm m}(z)$ */
4301 pm[j]=pm1+pm2*sin((twopi/pmcrp)*log(1.0+pmcrp*z[j]/pmper));
4302 else
4303 pm[j]=pm1+pm2*sin(twopi*z[j]/pmper);
4304 if (fabs(qecrp)>0.0) /* if nonzero chirp of $q_{\rm e}(z)$ */
4305 qe[j]=qe1+qe2*sin((twopi/qecrp)*log(1.0+qecrp*z[j]/qeper));
4306 else
4307 qe[j]=qe1+qe2*sin(twopi*z[j]/qeper);
4308 if (fabs(qmcrp)>0.0) /* if nonzero chirp of $q_{\rm m}(z)$ */
4309 qm[j]=qm1+qm2*sin((twopi/qmcrp)*log(1.0+qmcrp*z[j]/qmper));
4310 else
4311 qm[j]=qm1+qm2*sin(twopi*z[j]/qmper);
4312 }
4313 z[nn]=ll;
4314 }
4315
4316 @ For the fractal type gratings, the grating structure is composed of a
4317 self-similar structure with certain scaling properties.
4318 Currently only the Cantor-type fractal is possible to apply to the grating
4319 structure.
4320
4321 The initialization of the Cantor-type grating is performed by one single call
4322 to |init_cantor_fractal_grating()|, which intiates the positions $z_k$ at
4323 which the interfaces between media of different properties are located.
4324 The |init_cantor_fractal_grating()| routine then makes recursive calls to
4325 itself, until the bottom level of the fractal initialization is reached.
4326 After this, the material parameters of these regions are set sequentially
4327 in the same way as for binary type gratings.
4328
4329 In the initialization of the Cantor-type fractal grating, the program uses
4330 the vector |z[1..N]| with upper bound determined by the `level' $p$ of the
4331 fractal as $N=2^p$. The value of $N$ is calculated and set immediately after
4332 the program has parsed the level from the command line options, and hence
4333 any additional specifications of $N$ are superfluous, as this is set by the
4334 fractal level.
4335 If the number of elements in |z| is {\sl not} an integer power of two, then
4336 the call to |init_cantor_fractal_grating()| will fail, leaving the error
4337 message of this routine on exit.
4338 This will happen if, for example, a command line option specifying $N$ appears
4339 after the specification of the fractal type grating, if the specified value
4340 for $N$ does not conform with the convention that $N=2^p$.
4341
4342 @<Initiate fractal grating structure@>=
4343 {
4344 tmp=1.0;
4345 for (j=1;j<=fractal_level-1;j++) tmp=2.0*tmp;
4346 for (j=1;j<=maximum_fractal_level-fractal_level;j++) tmp=3.0*tmp;
4347 /* leaves $|tmp|=2^(p-1)3^(p_{\rm max}-p)$ */
4348 ll=tmp*t1-tmp*t2;
4349 tmp=1.0;
4350 for (j=1;j<=maximum_fractal_level-1;j++) tmp=3.0*tmp;
4351 ll=ll+tmp*t2;
4352 if (verbose) {
4353 fprintf(stdout,"%s: Minimum layer thickness at maximum recursion depth:\n",
4354 progname);
4355 fprintf(stdout,"%s: t2=%f [nm]\n",progname,t1*1.0e9);
4356 fprintf(stdout,"%s: t2=%f [nm]\n",progname,t2*1.0e9);
4357 fprintf(stdout,"%s: Fractal grating length calculated as L=%e [m]\n",
4358 progname,ll);
4359 fprintf(stdout,
4360 "%s: Based on fractal recursion of %d out of a maximum of %d levels.\n",
4361 progname,fractal_level,maximum_fractal_level);
4362 }
4363 init_cantor_fractal_grating(z,1,nn,0.0,ll,n1,n2);
4364 for (j=1;j<=nn-1;j++) {
4365 dz[j]=z[j+1]-z[j];
4366 if (j==1) {
4367 odd_layer=1;
4368 } else {
4369 odd_layer=(odd_layer?0:1);
4370 }
4371 n[j]=(odd_layer?n1:n2);
4372 g[j]=(odd_layer?g1:g2);
4373 pe[j]=(odd_layer?pe1:pe2);
4374 pm[j]=(odd_layer?pm1:pm2);
4375 qe[j]=(odd_layer?qe1:qe2);
4376 qm[j]=(odd_layer?qm1:qm2);
4377 }
4378 }
4379
4380 @ Adding any present perturbation of gyration constant.
4381 If the user via the command line has specified that a perturbation of the
4382 gyration constant should be added to the present spatial distribution,
4383 then |perturbed_gyration_constant| will be set to unity (true), and a
4384 perturbation of the profile corresponding to the magnetic field strength
4385 of a current carrying wire, orthogonal to the direction of propagation of
4386 light, will be added.
4387 The added perturbation $\Delta g(z)$ will be a ``bump'' of the Lorentzian
4388 spatial shape
4389 $$
4390 \Delta g(z)={{a_{\rm p}}\over{1+4(z-z_{\rm p})^2/w^2_{\rm p}}},
4391 $$
4392 where $z_{\rm p}$ is the position, $a_{\rm p}$ is the zero-to-peak amplitude,
4393 and $w_{\rm p}$ the full width half maximum of the perturbation.
4394 This form of perturbation applied to chirped sinusoidal magneto-optical Bragg
4395 gratings has in a linear optical regime been analyzed for spectral windowing
4396 and filtering, in [F.~Jonsson and C.~Flytzanis, JOSAB (2005);
4397 F.~Jonsson and C.~Flytzanis, Proc. MRS Fall meeting (2005)].
4398
4399
4400 @<Add perturbation of gyration constant along grating structure@>={
4401 for (j=1;j<=nn-1;j++) {
4402 tmp=2.0*(z[j]-gyroperturb_position)/gyroperturb_width;
4403 g[j]+=gyroperturb_amplitude/(1.0+tmp*tmp);
4404 }
4405 }
4406
4407 @ Set the refractive index of the medium surrounding the magneto-optical
4408 Bragg grating.
4409 The first and last elements of the double vectors |n[0,nn]| and |g[0,nn]|
4410 are defined according to the convention
4411 $$
4412 \eqalign{
4413 |n[0]|&\equiv n(z^-_0),\qquad
4414 |n[nn]|\equiv n(z^+_N),\cr
4415 |g[0]|&\equiv g(z^-_0),\qquad
4416 |g[nn]|\equiv g(z^+_N),\cr
4417 }
4418 $$
4419 and the surrounding medium is here assumed to be linear,
4420 $$
4421 p_{\rm e,m}(z^-_0)=p_{\rm e,m}(z^+_N)
4422 =q_{\rm e,m}(z^-_0)=q_{\rm e,m}(z^+_N)=0,
4423 $$
4424 and non-gyrotropic ($g_0=g_N=0$).
4425
4426 @<Initiate surrounding medium@>=
4427 {
4428 n[0]=nsurr; /* $n(z^-_0)$ */
4429 n[nn]=nsurr; /* $n(z^+_N)$ */
4430 g[0]=0.0; /* $g(z^-_0)$ */
4431 g[nn]=0.0; /* $g(z^+_N)$ */
4432 }
4433
4434 @*Calculation of intra-grating layer reflectances.
4435 Calculate the intrinsic reflectances over the layer interfaces prior to
4436 entering the algorithm of calculation of field distributions or reflection and
4437 transmission coefficients.
4438 The reflectance and transmission coefficients across the layers are calculated
4439 in terms of their linear optical and magneto-optical material parameters as
4440 $$
4441 \eqalign{
4442 taup[j]&=\tau_+(z_j)
4443 ={{2(n_{j-1}+g_{j-1})}\over{(n_{j-1}+n_j+g_{j-1}+g_j)}},\qquad
4444 taum[j]=\tau_-(z_j)
4445 ={{2(n_{j-1}-g_{j-1})}\over{(n_{j-1}+n_j-g_{j-1}-g_j)}},\cr
4446 taupp[j]&=\tau'_+(z_j)
4447 ={{2(n_j-g_j)}\over{(n_{j-1}+n_j-g_{j-1}-g_j)}},\qquad
4448 taupm[j]=\tau'_-(z_j)
4449 ={{2(n_j+g_j)}\over{(n_{j-1}+n_j+g_{j-1}+g_j)}},\cr
4450 rhop[j]&=\rho_+(z_j)
4451 ={{(n_{j-1}-n_j+g_{j-1}-g_j)}\over{(n_{j-1}+n_j+g_{j-1}+g_j)}},\qquad
4452 rhom[j]=\rho_-(z_j)
4453 ={{(n_{j-1}-n_j-g_{j-1}+g_j)}\over{(n_{j-1}+n_j-g_{j-1}-g_j)}},\cr
4454 rhopp[j]&=\rho'_+(z_j)=-\rho_-(z_j),\hskip 60pt
4455 rhopm[j]=\rho'_-(z_j)=-\rho_+(z_j),\cr
4456 }
4457 $$
4458 for interface $z=z_j$, $j=1,2,\ldots,|nn|$, where $n_j$ and $g_j$ are the
4459 respective refractive indices and gyration constants of the layers
4460 $z_j<z<z_{j+1}$.
4461 Outside the grating a zero gyration coefficient is assumed while the refractive
4462 indices are specified by $n_0=n_N=|nsurr|$, as given through the command line
4463 options.
4464
4465 In these expressions, $\tau_{\pm}(z_j)$ are the layer reflectances for
4466 forward propagating left/right circularly polarized light
4467 (i.~e.~for light coming from the negative $z$-direction), while
4468 $\tau'_{\pm}(z_j)$ are the layer reflectances for backward propagating
4469 left/right circularly polarized light
4470 (i.~e.~for light coming from the positive $z$-direction).
4471
4472 These polarization selective amplitude reflectances satisfy the Stokes
4473 relations
4474 $$
4475 \rho_{\pm}(z_j)=-\rho'_{\mp}(z_j),\qquad
4476 \tau_{\pm}(z_j)\tau'_{\mp}(z_j)=1-\rho^2_{\pm}(z_j),
4477 $$
4478 in this particular case generalized to interfaces between magneto-optic media.
4479 Notice the reversed order of the subscripts of the reflectances in the Stokes
4480 relations, reflecting the nonreciprocity of the magneto-optical contributions
4481 to the refractive index.
4482
4483 @<Calculate intragrating layer reflectances@>=
4484 {
4485 for (j=1;j<=nn;j++) {
4486 taup[j]=2.0*(n[j-1]+g[j-1])/(n[j-1]+n[j]+g[j-1]+g[j]);
4487 taum[j]=2.0*(n[j-1]-g[j-1])/(n[j-1]+n[j]-g[j-1]-g[j]);
4488 taupp[j]=2.0*(n[j]-g[j])/(n[j-1]+n[j]-g[j-1]-g[j]);
4489 taupm[j]=2.0*(n[j]+g[j])/(n[j-1]+n[j]+g[j-1]+g[j]);
4490 rhop[j]=(n[j-1]-n[j]+g[j-1]-g[j])/(n[j-1]+n[j]+g[j-1]+g[j]);
4491 rhom[j]=(n[j-1]-n[j]-g[j-1]+g[j])/(n[j-1]+n[j]-g[j-1]-g[j]);
4492 rhopp[j]=-rhom[j];
4493 rhopm[j]=-rhop[j];
4494 }
4495 }
4496
4497 @*Calculating the electrical field distribution inside the grating.
4498 Having constructed all data needed for the analysis of optical wave
4499 propagation in the grating structure, in linear as well as nonlinear,
4500 all-optically as well as magneto-optically, we are now in position of
4501 entering the actual electromagnetic field calculations.
4502 The field calculation is performed for a set of vacuum wavelengths within
4503 the spectral range specified by |lambdastart| and |lambdastop|.
4504 The spectrum is sampled using equidistantly spaced wavelength increments.
4505
4506 If the user instead of stating equidistantly spaced transmitted intensities
4507 and ellipticities has specified a file where to find the trajectory of
4508 Stokes parameters $(W_0,W_3)$ for the transmitted light, by using the
4509 \.{--trmtraject} option, then |mme| is set to be equal to the number of
4510 points |mmtraject| on this trajectory, and |mmi| set to one. For this case,
4511 for every value of $|ke|=1,2,3,\ldots,|mme|$, the |trmintensity| and
4512 |trmellipticity| variables will be set according to the data supplied
4513 in the specified trajectory file.
4514
4515 @<Calculate incident optical field spectrum@>=
4516 {
4517 for (k=1;k<=mm;k++) { /* for all wavelengths in the spectrum window */
4518 if (mm>1) { /* if more than one sampling point in the spectrum */
4519 lambda=lambdastart+(((double)(k-1))/((double)(mm-1)))
4520 *(lambdastop-lambdastart);
4521 } else {
4522 lambda=lambdastart;
4523 }
4524 omega=twopi*c/lambda; /*angular frequency of the light */
4525 if (trmtraject_specified) {
4526 mme=mmtraject;
4527 mmi=1;
4528 }
4529 @<Scan transmitted optical field in ellipticity and intensity@>;
4530 }
4531 if (verbose) @<Display elapsed execution time@>;
4532 }
4533
4534 @ Display the total execution time consumed by the simulation. This is the last
4535 block to be executed by the program, and employs the |difftime| routine of the
4536 standard \CEE\ library \.{time.h}.
4537
4538 @<Display elapsed execution time@>=
4539 {
4540 fprintf(stdout," ...done. ");
4541 now=time(NULL);
4542 fprintf(stdout,"Elapsed execution time: %d s\n",
4543 ((int)difftime(now,initime)));
4544 for (k=1;k<=64;k++) fprintf(stdout,(k<64?"-":"\n"));
4545 fprintf(stdout,"Program execution closed %s",ctime(&now));
4546 }
4547
4548 @ For a specified range of the intensity and ellipticity of polarization state
4549 of the transmitted optical field, calculate the corresponding incident fields
4550 in this inverse formulation of the electromagnetic wave propagation problem.
4551 The range of the ellipticity $\varepsilon_{\rm T}$ of the polarization state
4552 of the transmitted optical field is given as
4553 $$\varepsilon_{\rm T}\in[|trmellipstart|,|trmellipstop|],$$
4554 where |trmellipstart| and |trmellipstop| are the parameters provided at
4555 startup of the program through the command line option
4556 \.{--trmellipticity} $\langle|trmellipstart|\rangle$
4557 $\langle|trmellipstop|\rangle$ $\langle|mme|\rangle$.
4558 Via the definition of the normalized ellipticity $\varepsilon_{\rm T}$,
4559 the |trmellipstart| and |trmellipstop| parameters are bound to
4560 $$-1\le|trmellipstart|\le|trmellipstop|\le 1.$$
4561
4562 @<Scan transmitted optical field in ellipticity and intensity@>=
4563 {
4564 for (ke=1;ke<=mme;ke++) {
4565 if (trmtraject_specified) {
4566 trmellipticity=w3traj[ke]/w0traj[ke];
4567 } else {
4568 if (mme>1) {
4569 trmellipticity=trmellipstart+(((double)(ke-1))/((double)(mme-1)))
4570 *(trmellipstop-trmellipstart);
4571 } else {
4572 trmellipticity=trmellipstart;
4573 }
4574 }
4575 @<Scan transmitted optical field in intensity@>;
4576 }
4577 }
4578
4579 @ For a specified range of the intensity of the transmitted optical field,
4580 calculate the corresponding incident fields in this inverse formulation of
4581 the electromagnetic wave propagation problem.
4582 The range of the intensity $I_{\rm T}$ of the transmitted optical field is
4583 given as $$I_{\rm T}\in[|trmintenstart|,|trmintenstop|],$$
4584 where |trmintenstart| and |trmintenstop| are the parameters provided at
4585 startup of the program through the command line option
4586 \.{--trmintensity} $\langle|trmintenstart|\rangle$
4587 $\langle|trmintenstop|\rangle$ $\langle|mmi|\rangle$.
4588
4589 @<Scan transmitted optical field in intensity@>=
4590 {
4591 for (ki=1;ki<=mmi;ki++) {
4592 if (trmtraject_specified) {
4593 trmintensity=(epsilon0*c/2.0)*w0traj[ke];
4594 } else {
4595 if (mmi>1) {
4596 trmintensity=trmintenstart
4597 +(((double)(ki-1))/((double)(mmi-1)))
4598 *(trmintenstop-trmintenstart);
4599 } else {
4600 trmintensity=trmintenstart;
4601 }
4602 }
4603 @<Set boundary conditions at end of grating@>;
4604 @<Calculate optical field in last layer of the grating@>;
4605 @<Propagate optical fields from last to first layer of the grating@>;
4606 @<Write Stokes parameters and reflection coefficients to file@>;
4607 @<Write intragrating field evolution to file@>;
4608 @<Write intragrating intensity evolution to file@>;
4609 @<Write spatial grating structure to file@>;
4610 }
4611 }
4612
4613 @ In this inverse formulation of the algorithm, apply the boundary condition
4614 that the backward propagating wave at the end of the grating is zero,
4615 $$
4616 E^{\rm b}_{N_{\pm}}(z_N)\equiv E^{\rm b}_{\pm}(z^+_N)=0,
4617 $$
4618 and that the forward propagating field is a given quantity, specified
4619 in terms of intensity and ellipticity of the polarization state, as
4620 $$
4621 \eqalign{
4622 E^{\rm f}_{N_+}(z_N)\equiv E^{\rm f}_+(z^+_N)
4623 &=\left[(1+\varepsilon_{\rm T})I_{\rm T}/(\varepsilon_0 c)\right]^{1/2},\cr
4624 E^{\rm f}_{N_-}(z_N)\equiv E^{\rm f}_-(z^+_N)
4625 &=\left[(1-\varepsilon_{\rm T})I_{\rm T}/(\varepsilon_0 c)\right]^{1/2},\cr
4626 }
4627 $$
4628 with values of transmitted intensity and ellipticity in the range specified
4629 by parameters parsed from the command line options, supplied during startup
4630 of the program.
4631 Here the transmitted intensity $I_{\rm T}$ (in the program described by the
4632 variable |trmintensity|) is expressed in regular \SI\ units,
4633 in ${\rm W}/{\rm m}^2$ (Watts per square meter), as
4634 $$
4635 I_{\rm T}=(c\varepsilon_0/2)
4636 (\vert E^{\rm f}_+(z^+_N)\vert^2+\vert E^{\rm f}_-(z^+_N)\vert^2),
4637 $$
4638 and the normalized transmitted ellipticity $\varepsilon_{\rm T}$ of the
4639 transmitted polarization state (in the program described by the
4640 variable |trmellipticity|)
4641 $$
4642 \varepsilon_{\rm T}
4643 ={{\vert E^{\rm f}_+(z^+_N)\vert^2-\vert E^{\rm f}_-(z^+_N)\vert^2}
4644 \over{\vert E^{\rm f}_+(z^+_N)\vert^2+\vert E^{\rm f}_-(z^+_N)\vert^2}},
4645 $$
4646 is a number in the range from $-1$ to $1$, with $-1$ corresponding to right
4647 circularly polarized (RCP), $0$ to linearly polarized, and $1$ left circularly
4648 polarized (LCP) light.
4649
4650 @<Set boundary conditions at end of grating@>=
4651 {
4652 ebp[nn]=complex(0.0,0.0);
4653 ebm[nn]=complex(0.0,0.0);
4654 efp[nn]=complex(sqrt((1.0+trmellipticity)*trmintensity/(c*epsilon0)),0.0);
4655 efm[nn]=complex(sqrt((1.0-trmellipticity)*trmintensity/(c*epsilon0)),0.0);
4656 }
4657
4658 @ Having applied the boundary conditions at the end of the grating, calculate
4659 the optical fields in the last layer, for which $j=N-1$. These fields are
4660 taken immediately next to the last interface, at $z=z^-_N$.
4661
4662 @<Calculate optical field in last layer of the grating@>=
4663 {
4664 efp[nn-1]=cmul(crdiv(efp[nn],taup[nn]),crexpi(-omega*n[nn-1]*dz[nn-1]/c));
4665 efm[nn-1]=cmul(crdiv(efm[nn],taum[nn]),crexpi(-omega*n[nn-1]*dz[nn-1]/c));
4666 ebp[nn-1]=cmul(rcmul(rhom[nn],efm[nn-1]),
4667 crexpi(2.0*omega*n[nn-1]*dz[nn-1]/c));
4668 ebm[nn-1]=cmul(rcmul(rhop[nn],efp[nn-1]),
4669 crexpi(2.0*omega*n[nn-1]*dz[nn-1]/c));
4670 }
4671
4672 @ Given the right and left circularly polarized components of the forward
4673 and backward propagating optical fields in the last layer, iterate the
4674 propagation over the whole grating structure in order to find the
4675 corresponding input optical fields. This is done in an iterative manner
4676 over all the layers $z_j$, starting with the last layer (for which $j=N-1$)
4677 and ending up at the first layer (for which $j=1$), successively propagating
4678 the optical field over one layer at the time.
4679
4680 As we enter the loop in the order $j=N-1,N-2,...,1$, the forward and backward
4681 propagating optical field components immediately to the ``left'' of $z_{j+1}$
4682 are contained in the complex vector elements |efp[j]|, |efm[j]|, |ebp[j]|, and
4683 |ebm[j]|, with
4684 $$
4685 \eqalign{
4686 |efp[j]|&=E^f_{j_+}(z^-_{j+1}),\qquad
4687 |efm[j]|=E^f_{j_-}(z^-_{j+1}),\qquad
4688 |ebp[j]|=E^b_{j_+}(z^-_{j+1}),\qquad
4689 |ebm[j]|=E^b_{j_-}(z^-_{j+1}),\cr
4690 }
4691 $$
4692 where $z=z^-_j$ denotes the position immediately to the ``left''
4693 of $z=z_j$. We will now propagate the fields from $z_{j+1}$ to $z_j$,
4694 for $j=N-1,N-2,...,1$ (in that order), by first calculating the
4695 nonlinear (optical field-dependent) propagation constants of the current
4696 layer $z_j < z < z_{j+1}$.
4697
4698 This block of code also deals with displaying information on the progress of
4699 calculation, using the standard \ANSICEE\ time library for the calculation
4700 of ``estimated time of arrival'' (ETA) for the finishing of execution.
4701
4702 @<Propagate optical fields from last to first layer of the grating@>=
4703 {
4704 for (j=nn-1;j>=1;j--) {
4705 @<Calculate nonlinear propagation constants of layer@>;
4706 @<Propagate fields over homogeneous layer@>;
4707 @<Propagate fields over interface to next layer@>;
4708 if (verbose) {
4709 @<Display simulation status and estimated time of arrival@>;
4710 }
4711 }
4712 }
4713
4714 @ Calculate the nonlinear, optical field- and polarization-dependent
4715 contributions to the refractive index, including electric dipolar
4716 (all-optical) as well as magetic dipolar (magneto-optical) contributions.
4717
4718 Here the local variables are defined as
4719 $$
4720 \eqalign{
4721 |aafp2|&=\vert E^f_{j_+}(z_j)\vert^2,
4722 \qquad|etafp[j]|=\eta^{\rm f}_+(z_j)\cr
4723 |aafm2|&=\vert E^f_{j_-}(z_j)\vert^2,
4724 \qquad|etafm[j]|=\eta^{\rm f}_-(z_j)\cr
4725 |aabp2|&=\vert E^b_{j_+}(z_j)\vert^2,
4726 \qquad|etabp[j]|=\eta^{\rm b}_+(z_j)\cr
4727 |aabm2|&=\vert E^b_{j_-}(z_j)\vert^2,
4728 \qquad|etabm[j]|=\eta^{\rm b}_-(z_j)\cr
4729 }
4730 $$
4731 and the optical field-dependent propagation constants $\eta^{\rm f}_{\pm}$
4732 and $\eta^{\rm b}_{\pm}$ are given in terms of the optical fields and
4733 material parameters of the layer $z_j<z<z_{j+1}$ as
4734 $$
4735 \eqalign{
4736 etafp[j]&={{3}\over{8 n_j}}
4737 ((pe[j]+pm[j])
4738 (\vert E^f_{j_+}(z_j)\vert^2+2\vert E^b_{j_-}(z_j)\vert^2)
4739 +(qe[j]+qm[j])
4740 (\vert E^f_{j_-}(z_j)\vert^2+\vert E^b_{j_+}(z_j)\vert^2)),\cr
4741 etafm[j]&={{3}\over{8 n_j}}
4742 ((pe[j]-pm[j])
4743 (\vert E^f_{j_-}(z_j)\vert^2+2\vert E^b_{j_+}(z_j)\vert^2)
4744 +(qe[j]-qm[j])
4745 (\vert E^f_{j_+}(z_j)\vert^2+\vert E^b_{j_-}(z_j)\vert^2)),\cr
4746 etabp[j]&={{3}\over{8 n_j}}
4747 ((pe[j]-pm[j])
4748 (\vert E^b_{j_+}(z_j)\vert^2+2\vert E^f_{j_-}(z_j)\vert^2)
4749 +(qe[j]-qm[j])
4750 (\vert E^b_{j_-}(z_j)\vert^2+\vert E^f_{j_+}(z_j)\vert^2)),\cr
4751 etabm[j]&={{3}\over{8 n_j}}
4752 ((pe[j]+pm[j])
4753 (\vert E^b_{j_-}(z_j)\vert^2+2\vert E^f_{j_+}(z_j)\vert^2)
4754 +(qe[j]+qm[j])
4755 (\vert E^b_{j_+}(z_j)\vert^2+\vert E^f_{j_-}(z_j)\vert^2)).\cr
4756 }
4757 $$
4758 For a more strict derivation of these parameters, as governing the phase
4759 evolution of light in homogeneous nonlinear magneto-optical Kerr-media,
4760 see F.~Jonsson and C.~Flytzanis, {\it Phys.~Rev.~Lett.}~{\bf 82}, 1426 (1999).
4761
4762 @<Calculate nonlinear propagation constants of layer@>=
4763 {
4764 aafp2=cdabs(efp[j]);
4765 aafm2=cdabs(efm[j]);
4766 aabp2=cdabs(ebp[j]);
4767 aabm2=cdabs(ebm[j]);
4768 aafp2*=aafp2; /* equals $\vert E^f_{j_+}(z_j)\vert^2$ */
4769 aafm2*=aafm2; /* equals $\vert E^f_{j_-}(z_j)\vert^2$ */
4770 aabp2*=aabp2; /* equals $\vert E^b_{j_+}(z_j)\vert^2$ */
4771 aabm2*=aabm2; /* equals $\vert E^b_{j_-}(z_j)\vert^2$ */
4772 tmp=3.0/(8.0*n[j]);
4773 etafp[j]=tmp*((pe[j]+pm[j])*(aafp2+2.0*aabm2)
4774 +(qe[j]+qm[j])*(aafm2+aabp2));
4775 etafm[j]=tmp*((pe[j]-pm[j])*(aafm2+2.0*aabp2)
4776 +(qe[j]-qm[j])*(aafp2+aabm2));
4777 etabp[j]=tmp*((pe[j]-pm[j])*(aabp2+2.0*aafm2)
4778 +(qe[j]-qm[j])*(aabm2+aafp2));
4779 etabm[j]=tmp*((pe[j]+pm[j])*(aabm2+2.0*aafp2)
4780 +(qe[j]+qm[j])*(aabp2+aafm2));
4781 }
4782
4783 @ Having calculated the nonlinear propagation constants of the layer, now
4784 propagate the optical fields to the next interface in the negative
4785 $z$-direction. This wave propagation in homogeneous slices of the medium
4786 is performed using the analytical solution for loss-less propagation as
4787 published in F.~Jonsson and C.~Flytzanis, Phys.~Rev.~Lett.~{\bf 82},
4788 1426 (1999).
4789
4790 After this propagation over the homogeneous slice (layer), the temporary
4791 variables |tmpfp|, |tmpfm|, |tmpbp|, and |tmpbm| contain the forward and
4792 backward travelling optical fields taken at the ``beginning'' of the current,
4793 homogeneous segment.
4794
4795 @<Propagate fields over homogeneous layer@>=
4796 {
4797 tmpfp=cmul(efp[j],crexpi(-omega*(etafp[j]+g[j])*dz[j]/c));
4798 tmpfm=cmul(efm[j],crexpi(-omega*(etafm[j]-g[j])*dz[j]/c));
4799 tmpbp=cmul(ebp[j],crexpi(omega*(etabp[j]-g[j])*dz[j]/c));
4800 tmpbm=cmul(ebm[j],crexpi(omega*(etabm[j]+g[j])*dz[j]/c));
4801 }
4802
4803 @ Make the passage over the interface to the next layer. The infinitesimal
4804 propagation of the waves over the interfaces between homogeneous layers is
4805 performed by using the previously calculated reflection and transmission
4806 coefficients, taking the linear magneto-optical effect into account as well.
4807
4808 @<Propagate fields over interface to next layer@>=
4809 {
4810 if (j>1) {
4811 efp[j-1]=crdiv(cmul(csub(tmpfp,rcmul(rhopm[j],tmpbm)),
4812 crexpi(-omega*n[j-1]*dz[j-1]/c)),taup[j]);
4813 efm[j-1]=crdiv(cmul(csub(tmpfm,rcmul(rhopp[j],tmpbp)),
4814 crexpi(-omega*n[j-1]*dz[j-1]/c)),taum[j]);
4815 ebp[j-1]=cadd(rcmul(taupp[j],
4816 cmul(tmpbp,crexpi(omega*n[j-1]*dz[j-1]/c))),
4817 rcmul(rhom[j],
4818 cmul(efm[j-1],crexpi(2.0*omega*n[j-1]*dz[j-1]/c))));
4819 ebm[j-1]=cadd(rcmul(taupm[j],
4820 cmul(tmpbm,crexpi(omega*n[j-1]*dz[j-1]/c))),
4821 rcmul(rhop[j],
4822 cmul(efp[j-1],crexpi(2.0*omega*n[j-1]*dz[j-1]/c))));
4823 } else {
4824 efp[0]=crdiv(csub(tmpfp,rcmul(rhopm[1],tmpbm)),taup[1]);
4825 efm[0]=crdiv(csub(tmpfm,rcmul(rhopp[1],tmpbp)),taum[1]);
4826 ebp[0]=cadd(rcmul(taupp[1],tmpbp),rcmul(rhom[1],efm[0]));
4827 ebm[0]=cadd(rcmul(taupm[1],tmpbm),rcmul(rhop[1],efp[0]));
4828 }
4829 }
4830
4831 @ Display the real-time progress in the simulation and calculate the estimated
4832 time of arrival for finishing of the simulation. The completeness of the
4833 simulation is displayed for every ten percent up to successful termination of
4834 the program at one hundred percent.
4835
4836 The formula for calculation of the progress is
4837 $$
4838 \Big\{\matrix{{\rm progress\ in}\cr{\rm percent}\cr}\Big\}=
4839 100\times{{(N-j-1)+(k_{\rm i}-1)(N-1)+k_{\rm e}M_{\rm i}(N-1)+(k-1)M_{\rm e}
4840 M_{\rm i}(N-1)}\over{M M_{\rm e} M_{\rm e}(N-1)}},
4841 $$
4842 where
4843 $$
4844 \eqalign{
4845 1\le j\le N&\qquad{\rm [Layer\ counter\ index]}\cr
4846 1\le k\le M&\qquad{\rm [Wavelength\ counter\ index]}\cr
4847 1\le k_{\rm i}\le M_{\rm i}&\qquad{\rm [Intensity\ counter\ index]}\cr
4848 1\le k_{\rm e}\le M_{\rm e}&\qquad{\rm [Ellipticity\ counter\ index]}\cr
4849 }
4850 $$
4851
4852 @<Display simulation status and estimated time of arrival@>=
4853 {
4854 modf(100.0*((float)((nn-j-1)+(ki-1)*(nn-1)
4855 +(ke-1)*mmi*(nn-1)+(k-1)*mme*mmi*(nn-1)))
4856 /((float)(mm*mme*mmi*(nn-1))),&stn);
4857 if (stn>status+10) {
4858 status=status+10;
4859 now=time(NULL);
4860 eta=initime
4861 +((int)((100.0/((double)status))*difftime(now,initime)));
4862 fprintf(stdout," ...%2d percent finished... ",status);
4863 fprintf(stdout," ETA: %s",ctime(&eta));
4864 }
4865 }
4866
4867 @ Having calculated the input electromagnetic field from the given output
4868 field (as in this case, using the implicit way of calculating the
4869 transmission characteristics of a nonlinear magneto-optical Bragg grating),
4870 now calculate the corresponding incident $(S_0,S_1,S_2,S_3)$, transmitted
4871 $(W_0,W_1,W_2,W_3)$, and reflected $(V_0,V_1,V_2,V_3)$ Stokes parameters
4872 of the optical fields.
4873 Notice that in this inverse formulation of the algorithm, the transmitted
4874 Stokes parameters are not really calculated in a strict sense, since they
4875 follow directly from the given input to the program -- the transmitted
4876 optical field.
4877
4878 The Stokes parameters are defined as conforming to the standard definition in
4879 J.~D.~Jackson's {\it Classical Electrodynamics} (Wiley, New York, 1975), as
4880 $$
4881 \eqalign{
4882 S_0&=\vert{E^f_+(z^-_0)}\vert^2+\vert{E^f_-(z^-_0)}\vert^2,\qquad\qquad
4883 S_1=2\re[E^{f*}_+(z^-_0)E^f_-(z^-_0)],\cr
4884 S_3&=\vert{E^f_+(z^-_0)}\vert^2-\vert{E^f_-(z^-_0)}\vert^2,\qquad\qquad
4885 S_2=2\im[E^{f*}_+(z^-_0)E^f_-(z^-_0)],\cr
4886 }
4887 $$
4888 for the incident wave,
4889 $$
4890 \eqalign{
4891 W_0&=\vert{E^f_+(z^+_N)}\vert^2+\vert{E^f_-(z^+_N)}\vert^2,\qquad\qquad
4892 W_1=2\re[E^{f*}_+(z^+_N)E^f_-(z^+_N)],\cr
4893 W_3&=\vert{E^f_+(z^+_N)}\vert^2-\vert{E^f_-(z^+_N)}\vert^2,\qquad\qquad
4894 W_2=2\im[E^{f*}_+(z^+_N)E^f_-(z^+_N)],\cr
4895 }
4896 $$
4897 for the transmitted wave, and finally
4898 $$
4899 \eqalign{
4900 V_0&=\vert{E^b_+(z^-_0)}\vert^2+\vert{E^b_-(z^-_0)}\vert^2,\qquad\qquad
4901 V_1=2\re[E^{b*}_+(z^-_0)E^b_-(z^-_0)],\cr
4902 V_3&=\vert{E^b_+(z^-_0)}\vert^2-\vert{E^b_-(z^-_0)}\vert^2,\qquad\qquad
4903 V_2=2\im[E^{b*}_+(z^-_0)E^b_-(z^-_0)],\cr
4904 }
4905 $$
4906 for the reflected wave of the grating structure. These parameters fully
4907 specify the reflection and transmission characteristics for the nonlinear
4908 magneto-optical grating structure, in a linear as well as nonlinear optical
4909 domain. In particular, the intensity transmission and reflection coefficients
4910 are expressed in as $T=W_0/S_0$ and $R=V_0/S_0$, respectively.
4911
4912 In this calculation, a check is being performed regarding if the simulation
4913 is being performed for a multiple set of intensities and ellipticities of the
4914 transmitted light; if found to be so, then the set of Stokes parameters
4915 are calculated in order to create topological graphs as in F.~Jonsson and
4916 C.~Flytzanis, {\it Phys.~Rev.~Lett.}~{\bf 82}, 1426 (1999), in which case only
4917 one particular wavelength should being considered for the simulation
4918 (otherwise we would end up with too many topological graphs to keep track of);
4919 otherwise the complex-valued amplitude reflection and transmission
4920 coefficients,
4921 $$
4922 \rho_{\pm}(\omega)=E^{\rm b}_{0_{\mp}}(z_0)/E^{\rm f}_{0_{\pm}}(z_0),
4923 \qquad\tau_{\pm}(\omega)=E^{\rm f}_{N_{\pm}}(z_N)/E^{\rm f}_{0_{\pm}}(z_0),
4924 $$
4925 are calculated, in order to create graphs of the spectral reflection and
4926 transmission properties of the magneto-optical grating for circularly
4927 polarized fields (in which case $k>1$ is implicitly assumed).
4928
4929 If Stokes parameters are generated as data ouput,
4930 the resulting output files (named according to the suffix convention
4931 |outfilename|{\tt.s0.dat}, |outfilename|{\tt.s1.dat}, $\ldots$
4932 |outfilename|{\tt.v0.dat}, $\ldots$, etc.),
4933 can after the simulation be used for creating topological graphs.
4934
4935 For instance, by mapping the contents of Stokes parameter files
4936 |outfilename|{\tt.s0.dat}, |outfilename|{\tt.s3.dat},
4937 and |outfilename|{\tt.w0.dat}
4938 (using, for example, the \MATLAB\ command \.{mesh(s0,s3./s0,w0)},
4939 assuming that the variables \.{s0}, \.{s3}, and \.{w0} were loaded
4940 using the \MATLAB\ commands
4941 \.{s0=load(|outfilename|.s0.dat);} \.{s3=load(|outfilename|.s3.dat);}
4942 \.{w0=load(|outfilename|.w0.dat);}),
4943 one gets a topological graph showing (|s0|,|s3|,|w0|) as defining a surface
4944 showing the transmitted intensity |w0| as function of the input intensity
4945 |s0| and input ellipticity |s3|.
4946
4947 Similarly, two-dimensional graphs can be generated by, as an example,
4948 instead using the \MATLAB\ command \.{contour(s3./s0,w3./w0,s0)},
4949 to get graphs of the transmitted ellipticity \.{w3./w0} ($|w3|/|w0|$,
4950 the ``$y$-coordinate'') as function of the input ellipticity \.{s3./s0}
4951 ($|s3|/|s0|$, the ``$x$-coordinate''), for various values of the input
4952 intensity \.{s0} ($|s0|$, the ``$z$-coordinate'').
4953 This way of creating two-dimensional graphs from a parametric hypersurface
4954 of Stokes-parameters might seem to be a cumbersome
4955 way of generating a visible output; however, it actually turns out to be
4956 a very convenient method. Once one has adopted to this somewhat topologically
4957 directed way of thinking, any element of the Stokes vector is easily
4958 visualized as function of any of the other variables, and one avoids the
4959 difficulty that arise whenever the parameter of interest is a multivalued
4960 function of the other parameters (particularly appreciated when considering,
4961 for example, optically bistable behaviour of the structure, since one for
4962 those cases carefully must sort out data that belong to different state
4963 branches).
4964
4965 As a default, and as a matter of convention of electrodynamics, all Stokes
4966 parameters are given in ${\rm V}^2/{\rm m}^2$, through their definition.
4967 For example, the incident field (which is calculated by the program in
4968 this inverse formulation of the problem) is expressed in terms of the Stokes
4969 parameters as
4970 $$
4971 \eqalign{
4972 S_0&=\vert E^{\rm f}_{0_+}\vert^2+\vert E^{\rm f}_{0_-}\vert^2,\qquad
4973 S_1=2\re[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}],\cr
4974 S_3&=\vert E^{\rm f}_{0_+}\vert^2-\vert E^{\rm f}_{0_-}\vert^2,\qquad
4975 S_2=2\im[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}].\cr
4976 }
4977 $$
4978 However, the direct interpretation of these quantities in terms of squared
4979 Volts per square metres is sometimes somewhat inconvenient; therefore, those
4980 parameters can be scaled to give an interpretation of the intensity (in regular
4981 \SI\ units measured in Watts per square metres),
4982 as $S'_k=(\varepsilon_0 c/2)S_k$, or explicitly
4983 $$
4984 \eqalign{
4985 S'_0&=(\varepsilon_0 c/2)
4986 [\vert E^{\rm f}_{0_+}\vert^2+\vert E^{\rm f}_{0_-}\vert^2],\qquad
4987 S'_1=(\varepsilon_0 c/2)
4988 2\re[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}],\cr
4989 S'_3&=(\varepsilon_0 c/2)
4990 [\vert E^{\rm f}_{0_+}\vert^2-\vert E^{\rm f}_{0_-}\vert^2],\qquad
4991 S'_2=(\varepsilon_0 c/2)
4992 2\im[E^{{\rm f}*}_{0_+}E^{\rm f}_{0_-}].\cr
4993 }
4994 $$
4995 In this representation, $S'_0$ is now identical to the incident intensity
4996 $I_{\rm in}$ [${\rm W}/{\rm m}^2$].
4997 In order to have those scaled Stokes parameters $S'_k$ written to file,
4998 rather than the default ones, one convenient possibility is to use the
4999 previously added \.{--scale\_stokesparams} option, to include
5000 \.{--scale\_stokesparams 1.327209e-3} at the command line when invoking
5001 the program.
5002 The numerical value of this scaling was obtained from\footnote{$\dagger$}{In
5003 regular \SI\ units, the physical dimension of the quantity $\varepsilon_0 c/2$
5004 is $[{\rm F}/{\rm s}]=[{\rm C}/({\rm V}\cdot{\rm s})]$,
5005 so the physical dimension of $(\varepsilon_0 c/2)S_k$ is easily verified as
5006 $[{\rm C}/({\rm V}\cdot{\rm s})][{\rm V}^2/{\rm m}^2]
5007 =[{\rm C}\cdot{\rm V}/({\rm m}^2\cdot{\rm s})]
5008 =[{\rm J}/({\rm m}^2\cdot{\rm s})]
5009 =[{\rm W}/{\rm m}^2]$, as expected for a physical quantity describing an
5010 energy flow per unit area.
5011 }
5012 $$
5013 \eqalign{
5014 \varepsilon_0 c/2
5015 &=(8.854187817\ldots\times 10^{-12}\ {\rm F}/{\rm m})
5016 \times(2.99792458\times 10^8\ {\rm m}/{\rm s})/2\cr
5017 &\approx 1.327209\times 10^{-3}\ {\rm F}/{\rm s}.\cr
5018 }
5019 $$
5020
5021 @<Write Stokes parameters and reflection coefficients to file@>=
5022 {
5023 /* Scan the grating spatially for the maximum intra-grating intensity. */
5024 /* This is performed with the original, unscaled Stokes parameters. */
5025 if (intensityinfo) {
5026 for (j=0;j<=nn;j++) {
5027 tmp=(epsilon0*n[j]*c/2)*(cabs2(efp[j])+cabs2(efm[j]));
5028 if (maxintens < tmp) {
5029 maxintens=tmp;
5030 maxintens_layer=j;
5031 maxintens_inintens=(epsilon0*nsurr*c/2)
5032 *(cabs2(efp[0])+cabs2(efm[0]));
5033 maxintens_inellip=(cabs2(efp[0])-cabs2(efm[0]))
5034 /(cabs2(efp[0])+cabs2(efm[0]));
5035 maxintens_trintens=(epsilon0*nsurr*c/2)
5036 *(cabs2(efp[nn])+cabs2(efm[nn]));
5037 maxintens_trellip=(cabs2(efp[nn])-cabs2(efm[nn]))
5038 /(cabs2(efp[nn])+cabs2(efm[nn]));
5039 }
5040 }
5041 }
5042 if ((mme>1)&&(mmi>1)) { /* ``topological'' mode */
5043 /* Stokes parameters of input optical wave */
5044 s0=cabs2(efp[0])+cabs2(efm[0]);
5045 s1=2.0*cmul(conjg(efp[0]),efm[0]).r;
5046 s2=2.0*cmul(conjg(efp[0]),efm[0]).i;
5047 s3=cabs2(efp[0])-cabs2(efm[0]);
5048 if (scale_stokesparams) {
5049 s0=s0*stoke_scalefactor;
5050 s1=s1*stoke_scalefactor;
5051 s2=s2*stoke_scalefactor;
5052 s3=s3*stoke_scalefactor;
5053 }
5054 if (normalize_ellipticity) s3=s3/s0;
5055 fprintf(fp_s0,"%16.12e ",s0);
5056 fprintf(fp_s1,"%16.12e ",s1);
5057 fprintf(fp_s2,"%16.12e ",s2);
5058 fprintf(fp_s3,"%16.12e ",s3);
5059 fflush(fp_s0);
5060 fflush(fp_s1);
5061 fflush(fp_s2);
5062 fflush(fp_s3);
5063
5064 /* Stokes parameters of reflected optical wave */
5065 v0=cabs2(ebp[0])+cabs2(ebm[0]);
5066 v1=2.0*cmul(conjg(ebp[0]),ebm[0]).r;
5067 v2=2.0*cmul(conjg(ebp[0]),ebm[0]).i;
5068 v3=cabs2(ebp[0])-cabs2(ebm[0]);
5069 if (scale_stokesparams) {
5070 v0=v0*stoke_scalefactor;
5071 v1=v1*stoke_scalefactor;
5072 v2=v2*stoke_scalefactor;
5073 v3=v3*stoke_scalefactor;
5074 }
5075 if (normalize_ellipticity) v3=v3/v0;
5076 fprintf(fp_v0,"%16.12e ",v0);
5077 fprintf(fp_v1,"%16.12e ",v1);
5078 fprintf(fp_v2,"%16.12e ",v2);
5079 fprintf(fp_v3,"%16.12e ",v3);
5080 fflush(fp_v0);
5081 fflush(fp_v1);
5082 fflush(fp_v2);
5083 fflush(fp_v3);
5084
5085 /* Stokes parameters of transmitted optical wave */
5086 w0=cabs2(efp[nn])+cabs2(efm[nn]);
5087 w1=2.0*cmul(conjg(efp[nn]),efm[nn]).r;
5088 w2=2.0*cmul(conjg(efp[nn]),efm[nn]).i;
5089 w3=cabs2(efp[nn])-cabs2(efm[nn]);
5090 if (scale_stokesparams) {
5091 w0=w0*stoke_scalefactor;
5092 w1=w1*stoke_scalefactor;
5093 w2=w2*stoke_scalefactor;
5094 w3=w3*stoke_scalefactor;
5095 }
5096 if (normalize_ellipticity) w3=w3/w0;
5097 fprintf(fp_w0,"%16.12e ",w0);
5098 fprintf(fp_w1,"%16.12e ",w1);
5099 fprintf(fp_w2,"%16.12e ",w2);
5100 fprintf(fp_w3,"%16.12e ",w3);
5101 fflush(fp_w0);
5102 fflush(fp_w1);
5103 fflush(fp_w2);
5104 fflush(fp_w3);
5105 } else { /* ``spectrum'' mode */
5106 if (stokes_parameter_spectrum) { /* spectrum of Stokes parameters */
5107 /* Stokes parameters of input optical wave */
5108 s0=cabs2(efp[0])+cabs2(efm[0]);
5109 s1=2.0*cmul(conjg(efp[0]),efm[0]).r;
5110 s2=2.0*cmul(conjg(efp[0]),efm[0]).i;
5111 s3=cabs2(efp[0])-cabs2(efm[0]);
5112 fprintf(fp_spec,"%16.12e %16.12e %16.12e %16.12e %16.12e\n",
5113 lambda,omega,s1/s0,s2/s0,s3/s0);
5114 fflush(fp_spec);
5115
5116 /* Stokes parameters of reflected optical wave */
5117 v0=cabs2(ebp[0])+cabs2(ebm[0]);
5118 v1=2.0*cmul(conjg(ebp[0]),ebm[0]).r;
5119 v2=2.0*cmul(conjg(ebp[0]),ebm[0]).i;
5120 v3=cabs2(ebp[0])-cabs2(ebm[0]);
5121 /* CODE FOR WRITING TO BE INSERTED HERE */
5122
5123 /* Stokes parameters of transmitted optical wave */
5124 w0=cabs2(efp[nn])+cabs2(efm[nn]);
5125 w1=2.0*cmul(conjg(efp[nn]),efm[nn]).r;
5126 w2=2.0*cmul(conjg(efp[nn]),efm[nn]).i;
5127 w3=cabs2(efp[nn])-cabs2(efm[nn]);
5128 /* CODE FOR WRITING TO BE INSERTED HERE */
5129 }
5130 if (save_dbspectra) { /* spectrum in dB */
5131 tmp=(cabs2(ebp[0])+cabs2(ebm[0]))/(cabs2(efp[0])+cabs2(efm[0]));
5132 fprintf(fp_irspec,"%-10.8f %-10.8f\n",lambda*1.0e9,10.0*log10(tmp));
5133 fprintf(fp_itspec,"%-10.8f %-10.8f\n",lambda*1.0e9,10.0*log10(1.0-tmp));
5134 fflush(fp_irspec);
5135 fflush(fp_itspec);
5136 } else { /* linear scale between zero and unity */
5137 fprintf(fp_irspec,"%-10.8f %-10.8f\n",lambda*1.0e9,
5138 (cabs2(ebp[0])+cabs2(ebm[0]))/(cabs2(efp[0])+cabs2(efm[0])));
5139 fprintf(fp_itspec,"%-10.8f %-10.8f\n",lambda*1.0e9,
5140 (cabs2(efp[nn])+cabs2(efm[nn]))/(cabs2(efp[0])+cabs2(efm[0])));
5141 fflush(fp_irspec);
5142 fflush(fp_itspec);
5143 }
5144 fprintf(fp_icspec,"%-10.8f %-10.8f\n",lambda*1.0e9,
5145 (cabs2(ebp[0])+cabs2(ebm[0]))/(cabs2(efp[0])+cabs2(efm[0]))
5146 +(cabs2(efp[nn])+cabs2(efm[nn]))/(cabs2(efp[0])+cabs2(efm[0])));
5147 fflush(fp_icspec);
5148 }
5149
5150 if(ki>=mmi) { /* Write linefeed at and of each scan of intensity */
5151 if ((mme>1)&&(mmi>1)) {
5152 fprintf(fp_s0,"\n");
5153 fprintf(fp_s1,"\n");
5154 fprintf(fp_s2,"\n");
5155 fprintf(fp_s3,"\n");
5156 fprintf(fp_v0,"\n");
5157 fprintf(fp_v1,"\n");
5158 fprintf(fp_v2,"\n");
5159 fprintf(fp_v3,"\n");
5160 fprintf(fp_w0,"\n");
5161 fprintf(fp_w1,"\n");
5162 fprintf(fp_w2,"\n");
5163 fprintf(fp_w3,"\n");
5164 }
5165 }
5166 }
5167
5168 @ Check if the user has specified a filename for saving the electromagnetic
5169 field as it propagates through the grating structure, with |nne| being the
5170 number of discrete sampling points within each homogeneous layer.
5171 (This is quite useful since we otherwise just would get samples of the
5172 intra grating electromagnetic field at the boundaries of the homogeneous
5173 layers of the model; for twolevel grating types with comparatively thick
5174 layers this would otherwise, for example, cause unwanted discrete jumps
5175 in the plots of the polarization state evolution in the grating structure.)
5176 If so, write the full information of the electromagnetic field to file, to
5177 be used for later graphs (not necessarily just in terms of Stokes parameters).
5178
5179 @<Write intragrating field evolution to file@>=
5180 {
5181 if (fieldevoflag) {
5182 if (fieldevoflag_efield) {
5183 if (verbose)
5184 fprintf(stdout,
5185 "Writing spatial field evolution to file.\n");
5186 if (fp_evo!=NULL) {
5187 for (j=1;j<=nn-1;j++) {
5188 for (jje=1;jje<=nne;jje++) {
5189 if (nne>1) {
5190 zt=z[j]+((double)(jje-1))*dz[j]/((double)(nne));
5191 } else {
5192 zt=z[j];
5193 }
5194 tmpfp=cmul(efp[j],
5195 crexpi(omega*(etafp[j]+g[j])*(zt-z[j])/c));
5196 tmpfm=cmul(efm[j],
5197 crexpi(omega*(etafm[j]-g[j])*(zt-z[j])/c));
5198 tmpbp=cmul(ebp[j],
5199 crexpi(-omega*(etabp[j]-g[j])*(zt-z[j])/c));
5200 tmpbm=cmul(ebm[j],
5201 crexpi(-omega*(etabm[j]+g[j])*(zt-z[j])/c));
5202 if (normalize_length_to_micrometer) {
5203 fprintf(fp_evo,"%16.12e %16.12e %16.12e %16.12e"
5204 " %16.12e %16.12e %16.12e %16.12e"
5205 " %16.12e\n",zt*1.0e6,
5206 tmpfp.r,tmpfp.i,tmpfm.r,tmpfm.i,
5207 tmpbp.r,tmpbp.i,tmpbm.r,tmpbm.i);
5208 } else {
5209 fprintf(fp_evo,"%16.12e %16.12e %16.12e %16.12e"
5210 " %16.12e %16.12e %16.12e %16.12e"
5211 " %16.12e\n",zt,
5212 tmpfp.r,tmpfp.i,tmpfm.r,tmpfm.i,
5213 tmpbp.r,tmpbp.i,tmpbm.r,tmpbm.i);
5214 }
5215 }
5216 }
5217 if (normalize_length_to_micrometer) {
5218 fprintf(fp_evo,"%16.12e %16.12e %16.12e %16.12e %16.12e"
5219 " %16.12e %16.12e %16.12e %16.12e\n",
5220 z[nn]*1.0e6,efp[nn].r,efp[nn].i,efm[nn].r,efm[nn].i,
5221 ebp[nn].r,ebp[nn].i,ebm[nn].r,ebm[nn].i);
5222 } else {
5223 fprintf(fp_evo,"%16.12e %16.12e %16.12e %16.12e %16.12e"
5224 " %16.12e %16.12e %16.12e %16.12e\n",
5225 z[nn],efp[nn].r,efp[nn].i,efm[nn].r,efm[nn].i,
5226 ebp[nn].r,ebp[nn].i,ebm[nn].r,ebm[nn].i);
5227 }
5228 } else {
5229 fprintf(stderr,"%s: Could not write to file %s!\n",
5230 progname,fieldevofilename);
5231 exit(FAILURE);
5232 }
5233 } else if (fieldevoflag_stoke) {
5234 if (verbose)
5235 fprintf(stdout,
5236 "Writing spatial evolution of Stokes parameters to file.\n");
5237 if ((fp_evo_s0!=NULL)&&(fp_evo_s1!=NULL)
5238 &&(fp_evo_s2!=NULL)&&(fp_evo_s3!=NULL)) {
5239 for (j=1;j<=nn-1;j++) {
5240 for (jje=1;jje<=nne;jje++) {
5241 if (nne>1) {
5242 zt=z[j]+((double)(jje-1))*dz[j]/((double)(nne));
5243 } else {
5244 zt=z[j];
5245 }
5246 tmpfp=cmul(efp[j],
5247 crexpi(omega*(etafp[j]+g[j])*(zt-z[j])/c));
5248 tmpfm=cmul(efm[j],
5249 crexpi(omega*(etafm[j]-g[j])*(zt-z[j])/c));
5250 tmpbp=cmul(ebp[j],
5251 crexpi(-omega*(etabp[j]-g[j])*(zt-z[j])/c));
5252 tmpbm=cmul(ebm[j],
5253 crexpi(-omega*(etabm[j]+g[j])*(zt-z[j])/c));
5254 s0=cabs2(tmpfp)+cabs2(tmpfm);
5255 s1=2.0*cmul(conjg(tmpfp),tmpfm).r;
5256 s2=2.0*cmul(conjg(tmpfp),tmpfm).i;
5257 s3=cabs2(tmpfp)-cabs2(tmpfm);
5258 if (normalize_intensity) s0=s0/(cabs2(efp[1])+cabs2(efm[1]));
5259 if (normalize_length_to_micrometer) {
5260 fprintf(fp_evo_s0,"%16.12e %16.12e\n",zt*1.0e6,s0);
5261 fprintf(fp_evo_s1,"%16.12e %16.12e\n",zt*1.0e6,s1);
5262 fprintf(fp_evo_s2,"%16.12e %16.12e\n",zt*1.0e6,s2);
5263 fprintf(fp_evo_s3,"%16.12e %16.12e\n",zt*1.0e6,s3);
5264 } else {
5265 fprintf(fp_evo_s0,"%16.12e %16.12e\n",zt,s0);
5266 fprintf(fp_evo_s1,"%16.12e %16.12e\n",zt,s1);
5267 fprintf(fp_evo_s2,"%16.12e %16.12e\n",zt,s2);
5268 fprintf(fp_evo_s3,"%16.12e %16.12e\n",zt,s3);
5269 }
5270 }
5271 }
5272 s0=cabs2(efp[nn])+cabs2(efm[nn]);
5273 s1=2.0*cmul(conjg(efp[nn]),efm[nn]).r;
5274 s2=2.0*cmul(conjg(efp[nn]),efm[nn]).i;
5275 s3=cabs2(efp[nn])-cabs2(efm[nn]);
5276 if (normalize_intensity) s0=s0/(cabs2(efp[1])+cabs2(efm[1]));
5277 if (normalize_length_to_micrometer) {
5278 fprintf(fp_evo_s0,"%16.12e %16.12e\n",z[nn]*1.0e6,s0);
5279 fprintf(fp_evo_s1,"%16.12e %16.12e\n",z[nn]*1.0e6,s1);
5280 fprintf(fp_evo_s2,"%16.12e %16.12e\n",z[nn]*1.0e6,s2);
5281 fprintf(fp_evo_s3,"%16.12e %16.12e\n",z[nn]*1.0e6,s3);
5282 } else {
5283 fprintf(fp_evo_s0,"%16.12e %16.12e\n",z[nn],s0);
5284 fprintf(fp_evo_s1,"%16.12e %16.12e\n",z[nn],s1);
5285 fprintf(fp_evo_s2,"%16.12e %16.12e\n",z[nn],s2);
5286 fprintf(fp_evo_s3,"%16.12e %16.12e\n",z[nn],s3);
5287 }
5288 } else {
5289 fprintf(stderr,"%s: Could not write to file %s, %s, %s, or %s!\n",
5290 progname,fieldevofilename_s0,fieldevofilename_s1,
5291 fieldevofilename_s2,fieldevofilename_s3);
5292 exit(FAILURE);
5293 }
5294 } else {
5295 fprintf(stderr,"%s: Unknown field evolution flag.\n"
5296 "%s: (This cannot happen)\n",progname,progname);
5297 exit(FAILURE);
5298 }
5299 }
5300 }
5301
5302 @ Check if the user has specified a filename for saving the electromagnetic
5303 intensity distribution inside the grating structure, with |nne| being the
5304 number of discrete sampling points within each homogeneous layer.
5305
5306 @<Write intragrating intensity evolution to file@>=
5307 {
5308 if (intensityevoflag) {
5309 if (fabs(ievolambda-lambda)
5310 <fabs(lambdastop-lambdastart)/((double)(mm))) {
5311 if (verbose)
5312 fprintf(stdout,"%s: Saving intensity evolution at lambda=%8.4e\n",
5313 progname,lambda);
5314 if(strcmp(intensityevofilename,"")) {
5315 if (fp_ievo!=NULL) {
5316 for (j=1;j<=nn-1;j++) {
5317 if (normalize_length_to_micrometer) {
5318 fprintf(fp_ievo,"%16.12e %16.12e\n",z[j]*1.0e6,
5319 (cdabs(efp[j])*cdabs(efp[j])+cdabs(efm[j])*cdabs(efm[j]))
5320 /(cdabs(efp[1])*cdabs(efp[1])+cdabs(efm[1])*cdabs(efm[1])));
5321 fprintf(fp_ievo,"%16.12e %16.12e\n",z[j+1]*1.0e6,
5322 (cdabs(efp[j])*cdabs(efp[j])+cdabs(efm[j])*cdabs(efm[j]))
5323 /(cdabs(efp[1])*cdabs(efp[1])+cdabs(efm[1])*cdabs(efm[1])));
5324 } else {
5325 fprintf(fp_ievo,"%16.12e %16.12e\n",z[j],
5326 (cdabs(efp[j])*cdabs(efp[j])+cdabs(efm[j])*cdabs(efm[j]))
5327 /(cdabs(efp[1])*cdabs(efp[1])+cdabs(efm[1])*cdabs(efm[1])));
5328 fprintf(fp_ievo,"%16.12e %16.12e\n",z[j+1],
5329 (cdabs(efp[j])*cdabs(efp[j])+cdabs(efm[j])*cdabs(efm[j]))
5330 /(cdabs(efp[1])*cdabs(efp[1])+cdabs(efm[1])*cdabs(efm[1])));
5331 }
5332 }
5333 } else {
5334 fprintf(stderr,"%s: Could not write to file %s!\n",
5335 progname,intensityevofilename);
5336 exit(FAILURE);
5337 }
5338 }
5339 }
5340 }
5341 }
5342
5343 @ Check if the user has specified a filename for saving the spatial grating
5344 structure to. If so, save the whole grating structure to disk; this is
5345 useful as reference in graphs of the intragrating intensity and polarization
5346 state evolution.
5347
5348 @<Write spatial grating structure to file@>=
5349 {
5350 if (writegratingtofile) {
5351 if ((fp_gr=fopen(gratingfilename,"w"))==NULL) {
5352 fprintf(stderr,"%s: Could not open file %s for output!\n",
5353 progname,gratingfilename);
5354 exit(FAILURE);
5355 }
5356 if (normalize_length_to_micrometer) { /* length $z$ in micrometer */
5357 if (display_surrounding_media) {
5358 fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
5359 " %16.12e %16.12e %16.12e\n",
5360 (z[1]-0.1*(z[nn]-z[1]))*1.0e6,nsurr,0.0,0.0,0.0,0.0,0.0);
5361 fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
5362 " %16.12e %16.12e %16.12e\n",
5363 z[1]*1.0e6,nsurr,0.0,0.0,0.0,0.0,0.0);
5364 }
5365 for (j=1;j<=nn-1;j++) {
5366 fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
5367 " %16.12e %16.12e %16.12e\n",
5368 z[j]*1.0e6,n[j],g[j],pe[j],pm[j],qe[j],qm[j]);
5369 fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
5370 " %16.12e %16.12e %16.12e\n",
5371 z[j+1]*1.0e6,n[j],g[j],pe[j],pm[j],qe[j],qm[j]);
5372 }
5373 if (display_surrounding_media) {
5374 fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
5375 " %16.12e %16.12e %16.12e\n",
5376 z[nn]*1.0e6,nsurr,0.0,0.0,0.0,0.0,0.0);
5377 fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
5378 " %16.12e %16.12e %16.12e\n",
5379 (z[nn]+0.1*(z[nn]-z[1]))*1.0e6,nsurr,0.0,0.0,0.0,0.0,0.0);
5380 }
5381 } else { /* length $z$ in meter */
5382 if (display_surrounding_media) {
5383 fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
5384 " %16.12e %16.12e %16.12e\n",
5385 z[1]-0.1*(z[nn]-z[1]),nsurr,0.0,0.0,0.0,0.0,0.0);
5386 fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
5387 " %16.12e %16.12e %16.12e\n",
5388 z[1],nsurr,0.0,0.0,0.0,0.0,0.0);
5389 }
5390 for (j=1;j<=nn-1;j++) {
5391 fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
5392 " %16.12e %16.12e %16.12e\n",
5393 z[j],n[j],g[j],pe[j],pm[j],qe[j],qm[j]);
5394 fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
5395 " %16.12e %16.12e %16.12e\n",
5396 z[j+1],n[j],g[j],pe[j],pm[j],qe[j],qm[j]);
5397 }
5398 if (display_surrounding_media) {
5399 fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
5400 " %16.12e %16.12e %16.12e\n",
5401 z[nn],nsurr,0.0,0.0,0.0,0.0,0.0);
5402 fprintf(fp_gr,"%16.12e %16.12e %16.12e %16.12e"
5403 " %16.12e %16.12e %16.12e\n",
5404 z[nn]+0.1*(z[nn]-z[1]),nsurr,0.0,0.0,0.0,0.0,0.0);
5405 }
5406 }
5407 fclose(fp_gr);
5408 }
5409 }
5410
5411 @ Display the maximum optical intensity detected in the grating.
5412
5413 @<Print information on maximum optical intensity in grating@>=
5414 {
5415 if (intensityinfo) {
5416 for (k=1;k<=64;k++) fprintf(stdout,(k<64?"-":"\n"));
5417 fprintf(stdout,"Summary of intra-grating intensities:\n");
5418 fprintf(stdout,
5419 "The maximum intensity %1.4e [W/m^2] (%1.4f GW/cm^2) was detected\n",
5420 maxintens,maxintens*1.0e-13);
5421 fprintf(stdout,
5422 "in layer %ld. The maximum intensity was detected at a transmitted\n",
5423 maxintens_layer);
5424 fprintf(stdout,
5425 "intensity of %1.4e [W/m^2] (%1.4f GW/cm^2), and at a transmitted\n",
5426 maxintens_trintens,maxintens_trintens*1.0e-13);
5427 fprintf(stdout,
5428 "normalized ellipticity of S3/S0=%1.4f. ",maxintens_trellip);
5429 fprintf(stdout,"(where S3/S0=1 for LCP, and -1\n""for RCP).");
5430 fprintf(stdout,
5431 "At this state, the calculated optical intensity incident to the\n");
5432 fprintf(stdout,
5433 "crystal was %1.4e [W/m^2] (%1.4f GW/cm^2), or %1.1f percent\n",
5434 maxintens_inintens,maxintens_inintens*1.0e-13,
5435 100.0*maxintens_inintens/maxintens);
5436 fprintf(stdout,"of the maximum intra-grating optical intensity.\n");
5437 fprintf(stdout,
5438 "The calculated normalized incident ellipticity was %1.4f.\n",
5439 maxintens_inellip);
5440 fprintf(stdout,
5441 "The intensity transmission was for this state %1.1f percent.\n",
5442 100.0*maxintens_trintens/maxintens_inintens);
5443 for (k=1;k<=64;k++) fprintf(stdout,(k<64?"-":"\n"));
5444 if (saveintensityinfologfile) { /* also save log to file */
5445 if ((intensinfologfile=fopen(intensinfologfilename,"w"))==NULL) {
5446 fprintf(stderr,"%s: Could not open %s for intensity log!\n",
5447 progname,intensinfologfilename);
5448 exit(FAILURE);
5449 }
5450 for (k=1;k<=32;k++) fprintf(intensinfologfile,(k<32?"-":"\n"));
5451 fprintf(intensinfologfile,"Summary of intra-grating intensities:\n");
5452 fprintf(intensinfologfile,
5453 "Maximum intensity %1.4e [W/sq.m] (%1.4f GW/sq.cm) was detected\n",
5454 maxintens,maxintens*1.0e-13);
5455 fprintf(intensinfologfile,
5456 "in layer %ld. Maximum intensity was detected at a transmitted\n",
5457 maxintens_layer);
5458 fprintf(intensinfologfile,
5459 "intensity of %1.4e [W/sq.m] (%1.4f GW/sq.cm), and at transmitted\n",
5460 maxintens_trintens,maxintens_trintens*1.0e-13);
5461 fprintf(intensinfologfile,
5462 "normalized ellipticity of S3/S0=%1.4f. ",maxintens_trellip);
5463 fprintf(intensinfologfile,
5464 "(where S3/S0=1 for LCP, and -1\n""for RCP). ");
5465 fprintf(intensinfologfile,
5466 "At this state, the calculated optical intensity incident to the\n");
5467 fprintf(intensinfologfile,
5468 "crystal was %1.4e [W/sq.m] (%1.4f GW/sq.cm), or %1.1f percent\n",
5469 maxintens_inintens,maxintens_inintens*1.0e-13,
5470 100.0*maxintens_inintens/maxintens);
5471 fprintf(intensinfologfile,
5472 "of the maximum intra-grating optical intensity.\n");
5473 fprintf(intensinfologfile,
5474 "The calculated normalized incident ellipticity was %1.4f.\n",
5475 maxintens_inellip);
5476 fprintf(intensinfologfile,
5477 "The intensity transmission was for this state %1.1f percent.\n",
5478 100.0*maxintens_trintens/maxintens_inintens);
5479 fclose(intensinfologfile);
5480 for (k=1;k<=32;k++) fprintf(intensinfologfile,(k<32?"-":"\n"));
5481 }
5482 }
5483 }
5484
5485 @* Routine for checking for numerical characters.
5486 The |numeric()| routine takes one character |ch| as argument, and
5487 returns 1 (``true'') if the character is a sign or numeric,
5488 otherwise 0 (``false'') is returned. Notice that numerical fields
5489 of the form ``.314159'' are not allowed or recognized here.
5490
5491 @<Routine for checking for numerical characters@>=
5492 int numeric(char ch) {
5493 if ((ch=='0')||(ch=='1')||(ch=='2')||(ch=='3')||(ch=='4')||(ch=='5')
5494 ||(ch=='6')||(ch=='7')||(ch=='8')||(ch=='9')||(ch=='+')||(ch=='-')) {
5495 return(1); /* yes, this is a sign or numeric character */
5496 } else {
5497 return(0); /* no, this is not a sign or numeric character */
5498 }
5499 }
5500
5501 @*Routine for initialization of Cantor type fractal gratings.
5502
5503 @<Routine for initialization of Cantor type fractal gratings@>=
5504 void init_cantor_fractal_grating(double *z,int indxmin,int indxmax,
5505 double llmin,double llmax,double n1,double n2) {
5506 int indxmid;
5507 double dll;
5508 if (indxmax-indxmin==1) {
5509 z[indxmin]=llmin;
5510 z[indxmax]=llmax;
5511 } else if (indxmax-indxmin>=3) {
5512 indxmid=(indxmin+indxmax)/2;
5513 dll=(n2/(n1+2*n2))*(llmax-llmin);
5514 init_cantor_fractal_grating(z,indxmin,indxmid,llmin,llmin+dll,n1,n2);
5515 init_cantor_fractal_grating(z,indxmid+1,indxmax,llmax-dll,llmax,n1,n2);
5516 } else {
5517 fprintf(stderr,"%s: Error in indexes detected in routine %s",progname,
5518 "init_cantor_fractal_grating()!\n");
5519 fprintf(stderr,"%s: Please verify that the number of discrete layers\n",
5520 progname);
5521 fprintf(stderr,"%s: in the grating is N-1, where N is an integer"
5522 " power of 2.\n",progname);
5523 exit(FAILURE);
5524 }
5525 }
5526
5527 @* Routines for removing preceding path of filenames.
5528 In this block all routines related to removing preceding path strings go.
5529 Not really fancy programming, and no contribution to any increase of numerical
5530 efficiency or precision; just for the sake of keeping a tidy terminal output
5531 of the program. The |strip_away_path()| routine is typically called when
5532 initializing the program name string |progname| from the command line string
5533 |argv[0]|, and is typically located in the blocks related to parsing of the
5534 command line options.
5535
5536 @<Routines for removing preceding path of filenames@>=
5537 @<Routine for checking valid path characters@>@;
5538 @<Routine for stripping away path string@>@;
5539
5540 @ Checking for a valid path character.
5541 The |pathcharacter| routine takes one character |ch| as argument, and returns
5542 1 (``true'') if the character is valid character of a path string, otherwise 0
5543 (``false'') is returned. The |isalnum| requires \.{ctype.h}.
5544
5545 @<Routine for checking valid path characters@>=
5546 short pathcharacter(int ch) {
5547 return(isalnum(ch)||(ch=='.')||(ch=='/')||(ch=='\\')||(ch=='_')||
5548 (ch=='-')||(ch=='+'));
5549 }
5550
5551 @ Stripping path string from a file name.
5552 The |strip_away_path| routine takes a character string |filename| as
5553 argument, and returns a pointer to the same string but without any
5554 preceding path segments. This routine is, for example, useful for
5555 removing paths from program names as parsed from the command line.
5556
5557 @<Routine for stripping away path string@>=
5558 char *strip_away_path(char filename[]) {
5559 int j,k=0;
5560 while (pathcharacter(filename[k])) k++;
5561 j=(--k); /* this is the uppermost index of the full path+file string */
5562 while (isalnum((int)(filename[j]))) j--;
5563 j++; /* this is the lowermost index of the stripped file name */
5564 return(&filename[j]);
5565 }
5566
5567 @* Routines for generation of random numbers. The |ran1()| routine is
5568 taken from Numerical Recipes in C, 2nd ed.~(Cambridge University Press,
5569 New York, 1994).
5570
5571 @<Routines for generation of random numbers@>=
5572 #define IA 16807
5573 #define IM 2147483647
5574 #define AM (1.0/IM)
5575 #define IQ 127773
5576 #define IR 2836
5577 #define NTAB 32
5578 #define NDIV (1+(IM-1)/NTAB)
5579 #define EPS 1.2e-7
5580 #define RNMX (1.0-EPS)
5581
5582 float ran1(long *idum)
5583 {
5584 int j;
5585 long k;
5586 static long iy=0;
5587 static long iv[NTAB];
5588 float temp;
5589
5590 if (*idum <= 0 || !iy) {
5591 if (-(*idum) < 1) *idum=1;
5592 else *idum = -(*idum);
5593 for (j=NTAB+7;j>=0;j--) {
5594 k=(*idum)/IQ;
5595 *idum=IA*(*idum-k*IQ)-IR*k;
5596 if (*idum < 0) *idum += IM;
5597 if (j < NTAB) iv[j] = *idum;
5598 }
5599 iy=iv[0];
5600 }
5601 k=(*idum)/IQ;
5602 *idum=IA*(*idum-k*IQ)-IR*k;
5603 if (*idum < 0) *idum += IM;
5604 j=iy/NDIV;
5605 iy=iv[j];
5606 iv[j] = *idum;
5607 if ((temp=AM*iy) > RNMX) return RNMX;
5608 else return temp;
5609 }
5610 #undef IA
5611 #undef IM
5612 #undef AM
5613 #undef IQ
5614 #undef IR
5615 #undef NTAB
5616 #undef NDIV
5617 #undef EPS
5618 #undef RNMX
5619
5620 @* Routines for doing complex arithmetics. By using the data structure
5621 |dcomplex|, which here is the basic construct for complex numbers,
5622 containing real and imaginary parts in double precision, several
5623 routines for doing arithmetics with this representation have been
5624 implemented.
5625
5626 @<Routines for complex arithmetics@>=
5627 @<Complex number@>@;
5628 @<Complex conjugation@>@;
5629 @<Absolute value of complex number@>@;
5630 @<Squared absolute value of complex number@>@;
5631 @<Complex addition@>@;
5632 @<Complex subtraction@>@;
5633 @<Complex multiplication@>@;
5634 @<Complex division@>@;
5635 @<Complex square root@>@;
5636 @<Complex exponentiation@>@;
5637
5638 @ The function |complex(a,b)| takes two real valued arguments |a| and |b|
5639 as input, and returns the complex number $|c|=|a|+i|b|$.
5640 This basic construct is useful for storing temporary results, and
5641 for internal use in routines dealing with complex arithmetics.
5642
5643 @<Complex number@>=
5644 dcomplex complex(double re, double im) {
5645 dcomplex c;
5646 c.r=re;
5647 c.i=im;
5648 return c;
5649 }
5650
5651 @ The function |conjg(z)| takes a complex valued argument |z| of
5652 type |dcomplex| as input, and returns the complex conjugate
5653 $\bar{|z|}=\re(|z|)-i\im(|z|)$.
5654
5655 @<Complex conjugation@>=
5656 dcomplex conjg(dcomplex z) {
5657 dcomplex c;
5658 c.r=z.r;
5659 c.i=-z.i;
5660 return c;
5661 }
5662
5663 @ The function |cdabs(z)| takes a complex valued argument |z| as input,
5664 and returns the absolute value
5665 $\vert|z|\vert=[\re(|z|)^2+\im(|z|)^2]^{1/2}$.
5666
5667 @<Absolute value of complex number@>=
5668 double cdabs(dcomplex z) {
5669 double x,y,c,tmp;
5670 x=fabs(z.r);
5671 y=fabs(z.i);
5672 if (x==0.0)
5673 c=y;
5674 else if (y==0.0)
5675 c=x;
5676 else if (x>y) {
5677 tmp=y/x;
5678 c=x*sqrt(1.0+tmp*tmp);
5679 } else {
5680 tmp=x/y;
5681 c=y*sqrt(1.0+tmp*tmp);
5682 }
5683 return c;
5684 }
5685
5686 @ The function |cabs2(z)| takes a complex valued argument |z| as input, and
5687 returns the squared absolute value $\vert|z|\vert^2=\re(|z|)^2+\im(|z|)^2$.
5688 This function is identical to the |cdabs(z)| function, with the exception that
5689 the squared result is returned.
5690
5691 @<Squared absolute value of complex number@>=
5692 double cabs2(dcomplex z) {
5693 double x,y,c,tmp;
5694 x=fabs(z.r);
5695 y=fabs(z.i);
5696 if (x==0.0)
5697 c=y*y;
5698 else if (y==0.0)
5699 c=x*x;
5700 else if (x>y) {
5701 tmp=y/x;
5702 c=x*x*(1.0+tmp*tmp);
5703 } else {
5704 tmp=x/y;
5705 c=y*y*(1.0+tmp*tmp);
5706 }
5707 return c;
5708 }
5709
5710 @ The function |cadd(a,b)| takes complex valued arguments |a| and |b|
5711 as inputs, and returns the complex valued sum $|a|+|b|$.
5712
5713 @<Complex addition@>=
5714 dcomplex cadd(dcomplex a, dcomplex b) {
5715 dcomplex c;
5716 c.r=a.r+b.r;
5717 c.i=a.i+b.i;
5718 return c;
5719 }
5720
5721 @ The function |csub(a,b)| takes complex valued arguments |a| and |b| as
5722 inputs, and returns the complex valued difference $|a|-|b|$.
5723
5724 @<Complex subtraction@>=
5725 dcomplex csub(dcomplex a, dcomplex b) {
5726 dcomplex c;
5727 c.r=a.r-b.r;
5728 c.i=a.i-b.i;
5729 return c;
5730 }
5731
5732 @ When dealing with multiplication involving complex numbers, the case
5733 where one of the numbers is entirely real is distinguished from the
5734 general multiplication by two complex valued numbers, in order to speed
5735 up the multiplication somewhat.
5736
5737 @<Complex multiplication@>=
5738 @<Multiplication by two complex numbers@>@;
5739 @<Multiplication by real and complex numbers@>@;
5740
5741 @ The function |cmul(a,b)| takes complex valued arguments |a| and |b|
5742 as inputs, and returns the complex valued product |ab|.
5743
5744 @<Multiplication by two complex numbers@>=
5745 dcomplex cmul(dcomplex a, dcomplex b) {
5746 dcomplex c;
5747 c.r=a.r*b.r-a.i*b.i;
5748 c.i=a.i*b.r+a.r*b.i;
5749 return c;
5750 }
5751
5752 @ The function |rcmul(a,b)| takes a real valued argument |a| and
5753 a complex valued arguments |b| as inputs, and returns the
5754 complex valued product $|ab| = |a|\re(|b|) + i|a|\im(|b|)$.
5755
5756 @<Multiplication by real and complex numbers@>=
5757 dcomplex rcmul(double a, dcomplex b) {
5758 dcomplex c;
5759 c.r=a*b.r;
5760 c.i=a*b.i;
5761 return c;
5762 }
5763
5764 @ When dealing with division involving complex numbers, the case
5765 where the denominator is entirely real is distinguished from the
5766 general division by two complex valued numbers, in order to speed
5767 up the division somewhat.
5768
5769 @<Complex division@>=
5770 @<Division by complex numbers@>@;
5771 @<Division by complex and real number@>@;
5772
5773 @ The function |cdiv(a,b)| takes complex valued arguments |a| and |b|
5774 as inputs, and returns the complex valued quote $|a|/|b|$.
5775 If the denominator is found to be real, this routine speed up the
5776 division in similar to the |crdiv| routine, by instead applying the rules
5777 of real-valued division.
5778
5779 @<Division by complex numbers@>=
5780 dcomplex cdiv(dcomplex a, dcomplex b) {
5781 dcomplex c;
5782 double r,den;
5783 if (cdabs(b)>0.0) {
5784 if (fabs(b.i)==0.0) {
5785 c.r=a.r/b.r;
5786 c.i=a.i/b.r;
5787 } else {
5788 if (fabs(b.r) >= fabs(b.i)) {
5789 r=b.i/b.r;
5790 den=b.r+r*b.i;
5791 c.r=(a.r+r*a.i)/den;
5792 c.i=(a.i-r*a.r)/den;
5793 } else {
5794 r=b.r/b.i;
5795 den=b.i+r*b.r;
5796 c.r=(a.r*r+a.i)/den;
5797 c.i=(a.i*r-a.r)/den;
5798 }
5799 }
5800 } else {
5801 fprintf(stderr,"Error in cdiv(): Division by zero!\n");
5802 exit(FAILURE);
5803 }
5804 return c;
5805 }
5806
5807 @ The function |crdiv(a,b)| takes a complex valued argument |a| of
5808 and a real valued argument |b| as inputs, and returns the complex
5809 valued quote $|a|/|b| = \re(|a|)/|b| + i\im(|a|)/|b|$.
5810
5811 @<Division by complex and real number@>=
5812 dcomplex crdiv(dcomplex a, double b) {
5813 dcomplex c;
5814 if (fabs(b)>0.0) {
5815 c.r=a.r/b;
5816 c.i=a.i/b;
5817 } else {
5818 fprintf(stderr,"Error in crdiv(): Division by zero!\n");
5819 exit(FAILURE);
5820 }
5821 return c;
5822 }
5823
5824 @ The function |csqrt(z)| takes a complex valued argument |z| as input
5825 and returns the complex valued square root $|z|{}^{1/2}$.
5826
5827 @<Complex square root@>=
5828 dcomplex csqrt(dcomplex z) {
5829 dcomplex c;
5830 double x,y,w,r;
5831 if ((z.r==0.0)&&(z.i==0.0)) {
5832 c.r=0.0;
5833 c.i=0.0;
5834 return c;
5835 } else {
5836 x=fabs(z.r);
5837 y=fabs(z.i);
5838 if (x>=y) {
5839 r=y/x;
5840 w=sqrt(x)*sqrt(0.5*(1.0+sqrt(1.0+r*r)));
5841 } else {
5842 r=x/y;
5843 w=sqrt(y)*sqrt(0.5*(r+sqrt(1.0+r*r)));
5844 }
5845 if (z.r>=0.0) {
5846 c.r=w;
5847 c.i=0.5*z.i/w;
5848 } else {
5849 c.i=((z.i>=0)?w:-w);
5850 c.r=0.5*z.i/c.i;
5851 }
5852 return c;
5853 }
5854 }
5855
5856 @ For complex exponentiation, we distinguish between the case when
5857 the argument is complex valued, with nonzero real and imaginary parts,
5858 and the case where the argument is entirely imaginary.
5859 In the former case, the |cexp| routine should be used, while in
5860 the latter case, the |crexpi| routine is more appropriate.
5861
5862 @<Complex exponentiation@>=
5863 @<Exponentiation by complex number@>@;
5864 @<Exponentiation by imaginary number@>@;
5865
5866 @ The function |cexp(a)| takes a complex valued argument |a| as input
5867 and returns the complex valued ex\-po\-nen\-tial
5868 $\exp(a)=\exp(\re(a))[\cos(\im(|a|))+i\sin(\im(|a|))]$.
5869
5870 @<Exponentiation by complex number@>=
5871 dcomplex cexp(dcomplex a) {
5872 dcomplex c;
5873 double tmp=exp(a.r);
5874 c.r=tmp*cos(a.i);
5875 c.i=tmp*sin(a.i);
5876 return c;
5877 }
5878
5879 @ The function |crexpi(a)| takes a real valued argument |a| as input and
5880 returns the complex valued expo\-nen\-tial $\exp(i|a|)=\cos(|a|)+i\sin(|a|)$.
5881
5882 @<Exponentiation by imaginary number@>=
5883 dcomplex crexpi(double a) {
5884 dcomplex c;
5885 c.r=cos(a);
5886 c.i=sin(a);
5887 return c;
5888 }
5889
5890 @*Subroutines for memory allocation. Here follows the routines for memory
5891 allocation and deallocation of double precision real and complex valued
5892 vectors, as used for storing the optical field distribution in the grating,
5893 the refractive index distribution of the grating, etc.
5894
5895 @<Routines for memory allocation of vectors@>=
5896 @<Allocation of real-valued vectors@>@;
5897 @<Allocation of complex-valued vectors@>@;
5898 @<Deallocation of real-valued vectors@>@;
5899 @<Deallocation of complex-valued vectors@>@;
5900
5901 @ The |dvector| routine allocate a real-valued vector of double precision,
5902 with vector index ranging from |nl| to |nh|, while the |dcvector|
5903 routine allocate a complex-valued vector of double precision, with
5904 vector index ranging from |nl| to |nh|.
5905
5906 @<Allocation of real-valued vectors@>=
5907 double *dvector(long nl, long nh) {
5908 double *v;
5909 v=(double *)malloc((size_t) ((nh-nl+2)*sizeof(double)));
5910 if (!v) {
5911 fprintf(stderr,"Error: Allocation failure in dvector()\n");
5912 exit(FAILURE);
5913 }
5914 return v-nl+1;
5915 }
5916
5917 @ The |dcvector| routine allocate a complex-valued vector of double
5918 precision, with vector index ranging from |nl| to |nh|. The basic
5919 building type of the obtained complex valued vector is the globally
5920 declarated |dcomplex| data structure.
5921
5922 @<Allocation of complex-valued vectors@>=
5923 dcomplex *dcvector(long nl, long nh) {
5924 dcomplex *v;
5925 v=(dcomplex *)malloc((size_t) ((nh-nl+2)*sizeof(dcomplex)));
5926 if (!v) {
5927 fprintf(stderr,"Error: Allocation failure in dcvector()\n");
5928 exit(FAILURE);
5929 }
5930 return v-nl+1;
5931 }
5932
5933 @ The |free_dvector| routine release the memory occupied by the
5934 real-valued vector |v[nl..nh]|.
5935
5936 @<Deallocation of real-valued vectors@>=
5937 void free_dvector(double *v, long nl, long nh) {
5938 free((char*) (v+nl-1));
5939 }
5940
5941 @ The |free_dcvector| routine release the memory occupied by the
5942 complex-valued vector |v[nl..nh]|.
5943
5944 @<Deallocation of complex-valued vectors@>=
5945 void free_dcvector(dcomplex *v, long nl, long nh) {
5946 free((char*) (v+nl-1));
5947 }
5948
5949 @*Parsing command line options. All input parameters are passed to the
5950 program through command line options and arguments to the program.
5951 The syntax of command line options is listed
5952 whenever the program is invoked without any options, or whenever any of the
5953 \.{--help} or \.{-h} options are specified at startup.
5954
5955 @<Parse command line for parameter values@>=
5956 {
5957 progname=strip_away_path(argv[0]);
5958 fprintf(stdout,"This is %s v.%s. %s\n",progname,VERSION,COPYRIGHT);
5959 no_arg=argc;
5960 while(--argc) {
5961 if(!strcmp(argv[no_arg-argc],"-o") ||
5962 !strcmp(argv[no_arg-argc],"--outputfile")) {
5963 --argc;
5964 strcpy(outfilename,argv[no_arg-argc]);
5965 } else if(!strcmp(argv[no_arg-argc],"-w") ||
5966 !strcmp(argv[no_arg-argc],"--writegratingfile")) {
5967 --argc;
5968 strcpy(gratingfilename,argv[no_arg-argc]);
5969 writegratingtofile=1;
5970 } else if(!strcmp(argv[no_arg-argc],"--displaysurrmedia")) {
5971 display_surrounding_media=(display_surrounding_media?0:1);
5972 } else if(!strcmp(argv[no_arg-argc],"-a") ||
5973 !strcmp(argv[no_arg-argc],"--apodize")) {
5974 @<Parse apodization options@>;
5975 } else if(!strcmp(argv[no_arg-argc],"--phasejump")) {
5976 @<Parse phase jump options@>;
5977 } else if(!strcmp(argv[no_arg-argc],"--fieldevolution")) {
5978 @<Parse field evolution saving options@>;
5979 } else if(!strcmp(argv[no_arg-argc],"--intensityevolution")) {
5980 --argc;
5981 if(!sscanf(argv[no_arg-argc],"%lf",&ievolambda)) {
5982 fprintf(stderr,"%s: Error in '--intensityevolution' option.\n",
5983 progname);
5984 exit(FAILURE);
5985 }
5986 --argc;
5987 strcpy(intensityevofilename,argv[no_arg-argc]);
5988 intensityevoflag=1;
5989 } else if(!strcmp(argv[no_arg-argc],"--spectrumfile")) {
5990 --argc;
5991 strcpy(spectrumfilename,argv[no_arg-argc]);
5992 } else if(!strcmp(argv[no_arg-argc],"--stokesspectrum")) {
5993 stokes_parameter_spectrum=1;
5994 } else if(!strcmp(argv[no_arg-argc],"--trmtraject")) {
5995 --argc;
5996 strcpy(trmtraject_filename,argv[no_arg-argc]);
5997 trmtraject_specified=1;
5998 } else if(!strcmp(argv[no_arg-argc],"--intensityspectrumfile")) {
5999 --argc;
6000 strcpy(intensity_reflection_spectrumfilename,argv[no_arg-argc]);
6001 strcpy(intensity_transmission_spectrumfilename,argv[no_arg-argc]);
6002 strcpy(intensity_check_spectrumfilename,argv[no_arg-argc]);
6003 sprintf(intensity_reflection_spectrumfilename,"%s.irsp.dat",
6004 intensity_reflection_spectrumfilename);
6005 sprintf(intensity_transmission_spectrumfilename,"%s.itsp.dat",
6006 intensity_transmission_spectrumfilename);
6007 sprintf(intensity_check_spectrumfilename,"%s.chec.dat",
6008 intensity_check_spectrumfilename);
6009
6010 } else if(!strcmp(argv[no_arg-argc],"--logarithmicspectrum")) {
6011 save_dbspectra=1;
6012
6013 } else if(!strcmp(argv[no_arg-argc],"-v") ||
6014 !strcmp(argv[no_arg-argc],"--verbose")) {
6015 verbose=(verbose?0:1);
6016
6017 } else if(!strcmp(argv[no_arg-argc],"--scale_stokesparams")) {
6018 scale_stokesparams=1;
6019 --argc;
6020 if(!sscanf(argv[no_arg-argc],"%lf",&stoke_scalefactor)) {
6021 fprintf(stderr,"%s: Error in '--scale_stokesparams' option.\n",\
6022 progname);
6023 exit(FAILURE);
6024 }
6025 } else if(!strcmp(argv[no_arg-argc],"--intensityinfo")) {
6026 intensityinfo=(intensityinfo?0:1);
6027 } else if(!strcmp(argv[no_arg-argc],"--intensityinfologfile")) {
6028 intensityinfo=1;
6029 saveintensityinfologfile=1;
6030 --argc;
6031 strcpy(intensinfologfilename,argv[no_arg-argc]);
6032 } else if(!strcmp(argv[no_arg-argc],"--gyroperturb")) {
6033 @<Parse gyration constant perturbation options@>;
6034 } else if(!strcmp(argv[no_arg-argc],"--normalize_length_to_um")) {
6035 normalize_length_to_micrometer=(normalize_length_to_micrometer?0:1);
6036 } else if(!strcmp(argv[no_arg-argc],"--normalize_intensity")) {
6037 normalize_intensity=(normalize_intensity?0:1);
6038 } else if(!strcmp(argv[no_arg-argc],"--normalize_ellipticity")) {
6039 normalize_ellipticity=(normalize_ellipticity?0:1);
6040 } else if(!strcmp(argv[no_arg-argc],"--normalizedrepresentation")) {
6041 normalize_internally=(normalize_internally?0:1);
6042 } else if(!strcmp(argv[no_arg-argc],"-r") ||
6043 !strcmp(argv[no_arg-argc],"--random")) {
6044 randomdistribution=(randomdistribution?0:1);
6045 } else if(!strcmp(argv[no_arg-argc],"-h") ||
6046 !strcmp(argv[no_arg-argc],"--help")) {
6047 showsomehelp();
6048 } else if(!strcmp(argv[no_arg-argc],"-g") ||
6049 !strcmp(argv[no_arg-argc],"--grating")) {
6050 --argc;
6051 if(!strcmp(argv[no_arg-argc],"stepwise")) {
6052 @<Parse for stepwise grating options@>@;
6053 } else if(!strcmp(argv[no_arg-argc],"sinusoidal")) {
6054 @<Parse for sinusoidal grating options@>@;
6055 } else if(!strcmp(argv[no_arg-argc],"chirped")) {
6056 @<Parse for chirped grating options@>@;
6057 } else if(!strcmp(argv[no_arg-argc],"fractal")) {
6058 @<Parse for fractal grating options@>@;
6059 } else {
6060 fprintf(stderr,"%s: Error in '-g' or '--grating' option.\n",
6061 progname);
6062 fprintf(stderr,"%s: (No valid grating type found!)\n",progname);
6063 exit(FAILURE);
6064 }
6065 } else if((!strcmp(argv[no_arg-argc],"-L"))||
6066 (!strcmp(argv[no_arg-argc],"--gratinglength"))) {
6067 --argc;
6068 if(!sscanf(argv[no_arg-argc],"%lf",&ll)) {
6069 fprintf(stderr,"%s: Error in '-L' option.\n",progname);
6070 exit(FAILURE);
6071 }
6072 } else if(!strcmp(argv[no_arg-argc],"--modifylayer")) {
6073 @<Parse for options for modified layer of grating structure@>@;
6074 } else if(!strcmp(argv[no_arg-argc],"--refindsurr")) {
6075 --argc;
6076 if(!sscanf(argv[no_arg-argc],"%lf",&nsurr)) {
6077 fprintf(stderr,"%s: Error in '--refindsurr' option.\n",progname);
6078 exit(FAILURE);
6079 }
6080 } else if(!strcmp(argv[no_arg-argc],"--trmintensity")) {
6081 @<Parse the command line for transmitted intensity range@>@;
6082 } else if(!strcmp(argv[no_arg-argc],"--trmellipticity")) {
6083 @<Parse the command line for transmitted ellipticity range@>@;
6084 } else if(!strcmp(argv[no_arg-argc],"--lambdastart")) {
6085 --argc;
6086 if(!sscanf(argv[no_arg-argc],"%lf",&lambdastart)) {
6087 fprintf(stderr,"%s: Error in '--lambdastart' option.\n",progname);
6088 exit(FAILURE);
6089 }
6090 } else if(!strcmp(argv[no_arg-argc],"--lambdastop")) {
6091 --argc;
6092 if(!sscanf(argv[no_arg-argc],"%lf",&lambdastop)) {
6093 fprintf(stderr,"%s: Error in '--lambdastop' option.\n",progname);
6094 exit(FAILURE);
6095 }
6096 } else if(!strcmp(argv[no_arg-argc],"--wlenlinz")) {
6097 chirpflag=1;
6098 } else if(!strcmp(argv[no_arg-argc],"--freqlinz")) {
6099 chirpflag=0;
6100 } else if(!strcmp(argv[no_arg-argc],"-N")) {
6101 --argc;
6102 if(!sscanf(argv[no_arg-argc],"%ld",&nn)) {
6103 fprintf(stderr,"%s: Error in '-N' option.\n",progname);
6104 exit(FAILURE);
6105 }
6106 } else if(!strcmp(argv[no_arg-argc],"-M")) {
6107 --argc;
6108 if(!sscanf(argv[no_arg-argc],"%ld",&mm)) {
6109 fprintf(stderr,"%s: Error in '-M' option.\n",progname);
6110 exit(FAILURE);
6111 }
6112 } else {
6113 fprintf(stderr,"%s: Specified option invalid!\n",progname);
6114 showsomehelp();
6115 exit(FAILURE);
6116 }
6117 }
6118 @<Create outfile suffixes@>@;
6119 @<Display parameters parsed from the command line@>@;
6120 }
6121
6122 @ Create suffixes for output filenames. The output files for the Stokes
6123 parameters are named according to the convention that....
6124
6125 @<Create outfile suffixes@>=
6126 {
6127 sprintf(outfilename_s0,"%s.s0.dat",outfilename);
6128 sprintf(outfilename_s1,"%s.s1.dat",outfilename);
6129 sprintf(outfilename_s2,"%s.s2.dat",outfilename);
6130 sprintf(outfilename_s3,"%s.s3.dat",outfilename);
6131 sprintf(outfilename_v0,"%s.v0.dat",outfilename);
6132 sprintf(outfilename_v1,"%s.v1.dat",outfilename);
6133 sprintf(outfilename_v2,"%s.v2.dat",outfilename);
6134 sprintf(outfilename_v3,"%s.v3.dat",outfilename);
6135 sprintf(outfilename_w0,"%s.w0.dat",outfilename);
6136 sprintf(outfilename_w1,"%s.w1.dat",outfilename);
6137 sprintf(outfilename_w2,"%s.w2.dat",outfilename);
6138 sprintf(outfilename_w3,"%s.w3.dat",outfilename);
6139 }
6140
6141 @ Parse the command line for options related to apodization~[15] of the spatial
6142 modulation of the refractive index and gyration coefficient.
6143
6144 @<Parse apodization options@>=
6145 {
6146 apodize=1;
6147 --argc;
6148 if(!sscanf(argv[no_arg-argc],"%lf",&apolength)) {
6149 fprintf(stderr,"%s: Error in '--apodize' option.\n",progname);
6150 exit(FAILURE);
6151 }
6152 }
6153
6154 @ Parse the command line for options related to discrete phase jump in
6155 the spatial modulation of the refractive index and gyration coefficient.
6156
6157 @<Parse phase jump options@>=
6158 {
6159 phasejump=1;
6160 --argc;
6161 if(!sscanf(argv[no_arg-argc],"%lf",&phasejumpangle)) {
6162 fprintf(stderr,"%s: Error in 1st arg of '--phasejump' option.\n",
6163 progname);
6164 exit(FAILURE);
6165 }
6166 --argc;
6167 if(!sscanf(argv[no_arg-argc],"%lf",&phasejumpposition)) {
6168 fprintf(stderr,"%s: Error in 2nd arg of '--phasejump' option.\n",
6169 progname);
6170 exit(FAILURE);
6171 }
6172 }
6173
6174 @ Parse the command line for options related to a Lorentzian perturbation
6175 of the magneto-optical gyration coefficient of the grating.
6176
6177 @<Parse gyration constant perturbation options@>=
6178 {
6179 perturbed_gyration_constant=1;
6180 --argc;
6181 if(!sscanf(argv[no_arg-argc],"%lf",&gyroperturb_position)) {
6182 fprintf(stderr,"%s: Error in '--gyroperturb' option.\n",progname);
6183 exit(FAILURE);
6184 }
6185 --argc;
6186 if(!sscanf(argv[no_arg-argc],"%lf",&gyroperturb_amplitude)) {
6187 fprintf(stderr,"%s: Error in '--gyroperturb' option.\n",progname);
6188 exit(FAILURE);
6189 }
6190 --argc;
6191 if(!sscanf(argv[no_arg-argc],"%lf",&gyroperturb_width)) {
6192 fprintf(stderr,"%s: Error in '--gyroperturb' option.\n",progname);
6193 exit(FAILURE);
6194 }
6195 }
6196
6197 @ Parse the command line for options related to saving the intra grating
6198 optical field spatial evolution to file.
6199 If Stokes parameters are preferred for the output of the spatial
6200 intra-grating field evolution, the specified filename will be
6201 used as the base name for the output file; the suffixes
6202 \.{.s0.dat}, \.{.s1.dat}, \.{.s2.dat}, and \.{.s3.dat} will then be
6203 appended to the base name in order to keep track of them.
6204
6205 @<Parse field evolution saving options@>=
6206 {
6207 --argc;
6208 if (!strcmp(argv[no_arg-argc],"efield")) {
6209 fieldevoflag_efield=1;
6210 } else if (!strcmp(argv[no_arg-argc],"stoke")) {
6211 fieldevoflag_stoke=1;
6212 } else {
6213 fprintf(stderr,
6214 "%s: Unknown field evolution flag '%s' in second argument of\n"
6215 " --fieldevolution option.\n",progname,argv[no_arg-argc]);
6216 exit(FAILURE);
6217 }
6218 --argc;
6219 if(!sscanf(argv[no_arg-argc],"%ld",&nne)) {
6220 fprintf(stderr,"%s: Error in '--fieldevolution' option.\n",
6221 progname);
6222 exit(FAILURE);
6223 }
6224 --argc;
6225 strcpy(fieldevofilename,argv[no_arg-argc]);
6226 fieldevoflag=1; /* Indicate that the field evolution shold be saved */
6227 if (fieldevoflag_stoke) { /* Stokes parameter output preferred */
6228 sprintf(fieldevofilename_s0,"%s.s0.dat",fieldevofilename);
6229 sprintf(fieldevofilename_s1,"%s.s1.dat",fieldevofilename);
6230 sprintf(fieldevofilename_s2,"%s.s2.dat",fieldevofilename);
6231 sprintf(fieldevofilename_s3,"%s.s3.dat",fieldevofilename);
6232 }
6233 }
6234
6235 @ Parse the command line for options related to the initiation of a stepwise
6236 grating, consisting of a set of stacked layers.
6237
6238 @<Parse for stepwise grating options@>=
6239 {
6240 strcpy(gratingtype,argv[no_arg-argc]);
6241 --argc;
6242 if(!strcmp(argv[no_arg-argc],"twolevel")) {
6243 strcpy(gratingsubtype,argv[no_arg-argc]);
6244 --argc;
6245 if(strcmp(argv[no_arg-argc],"t1")) {
6246 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6247 fprintf(stderr,"%s: (Expecting string 't1').\n",progname);
6248 exit(FAILURE);
6249 }
6250 --argc;
6251 if(!sscanf(argv[no_arg-argc],"%lf",&t1)) {
6252 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6253 fprintf(stderr,"%s: (Could not read data for t1).\n",progname);
6254 exit(FAILURE);
6255 }
6256 --argc;
6257 if(strcmp(argv[no_arg-argc],"t2")) {
6258 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6259 fprintf(stderr,"%s: (Expecting string 't2').\n",progname);
6260 exit(FAILURE);
6261 }
6262 --argc;
6263 if(!sscanf(argv[no_arg-argc],"%lf",&t2)) {
6264 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6265 fprintf(stderr,"%s: (Could not read data for t2).\n",progname);
6266 exit(FAILURE);
6267 }
6268 --argc;
6269 if(strcmp(argv[no_arg-argc],"n1")) {
6270 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6271 fprintf(stderr,"%s: (Expecting string 'n1').\n",progname);
6272 exit(FAILURE);
6273 }
6274 --argc;
6275 if(!sscanf(argv[no_arg-argc],"%lf",&n1)) {
6276 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6277 fprintf(stderr,"%s: (Could not read data for n1).\n",progname);
6278 exit(FAILURE);
6279 }
6280 --argc;
6281 if(strcmp(argv[no_arg-argc],"n2")) {
6282 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6283 fprintf(stderr,"%s: (Expecting string 'n2').\n",progname);
6284 exit(FAILURE);
6285 }
6286 --argc;
6287 if(!sscanf(argv[no_arg-argc],"%lf",&n2)) {
6288 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6289 fprintf(stderr,"%s: (Could not read data for n2).\n",progname);
6290 exit(FAILURE);
6291 }
6292 --argc;
6293 if(strcmp(argv[no_arg-argc],"g1")) {
6294 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6295 fprintf(stderr,"%s: (Expecting string 'g1').\n",progname);
6296 exit(FAILURE);
6297 }
6298 --argc;
6299 if(!sscanf(argv[no_arg-argc],"%lf",&g1)) {
6300 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6301 fprintf(stderr,"%s: (Could not read data for g1).\n",progname);
6302 exit(FAILURE);
6303 }
6304 --argc;
6305 if(strcmp(argv[no_arg-argc],"g2")) {
6306 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6307 fprintf(stderr,"%s: (Expecting string 'g2').\n",progname);
6308 exit(FAILURE);
6309 }
6310 --argc;
6311 if(!sscanf(argv[no_arg-argc],"%lf",&g2)) {
6312 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6313 fprintf(stderr,"%s: (Could not read data for g2).\n",progname);
6314 exit(FAILURE);
6315 }
6316 --argc;
6317 if(strcmp(argv[no_arg-argc],"pe1")) {
6318 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6319 fprintf(stderr,"%s: (Expecting string 'pe1').\n",progname);
6320 exit(FAILURE);
6321 }
6322 --argc;
6323 if(!sscanf(argv[no_arg-argc],"%lf",&pe1)) {
6324 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6325 fprintf(stderr,"%s: (Could not read data for pe1).\n",progname);
6326 exit(FAILURE);
6327 }
6328 --argc;
6329 if(strcmp(argv[no_arg-argc],"pe2")) {
6330 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6331 fprintf(stderr,"%s: (Expecting string 'pe2').\n",progname);
6332 exit(FAILURE);
6333 }
6334 --argc;
6335 if(!sscanf(argv[no_arg-argc],"%lf",&pe2)) {
6336 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6337 fprintf(stderr,"%s: (Could not read data for pe2).\n",progname);
6338 exit(FAILURE);
6339 }
6340 --argc;
6341 if(strcmp(argv[no_arg-argc],"pm1")) {
6342 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6343 fprintf(stderr,"%s: (Expecting string 'pm1').\n",progname);
6344 exit(FAILURE);
6345 }
6346 --argc;
6347 if(!sscanf(argv[no_arg-argc],"%lf",&pm1)) {
6348 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6349 fprintf(stderr,"%s: (Could not read data for pm1).\n",\
6350 progname);
6351 exit(FAILURE);
6352 }
6353 --argc;
6354 if(strcmp(argv[no_arg-argc],"pm2")) {
6355 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6356 fprintf(stderr,"%s: (Expecting string 'pm2').\n",progname);
6357 exit(FAILURE);
6358 }
6359 --argc;
6360 if(!sscanf(argv[no_arg-argc],"%lf",&pm2)) {
6361 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6362 fprintf(stderr,"%s: (Could not read data for pm2).\n",\
6363 progname);
6364 exit(FAILURE);
6365 }
6366 --argc;
6367 if(strcmp(argv[no_arg-argc],"qe1")) {
6368 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6369 fprintf(stderr,"%s: (Expecting string 'qe1').\n",progname);
6370 exit(FAILURE);
6371 }
6372 --argc;
6373 if(!sscanf(argv[no_arg-argc],"%lf",&qe1)) {
6374 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6375 fprintf(stderr,"%s: (Could not read data for qe1).\n",\
6376 progname);
6377 exit(FAILURE);
6378 }
6379 --argc;
6380 if(strcmp(argv[no_arg-argc],"qe2")) {
6381 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6382 fprintf(stderr,"%s: (Expecting string 'qe2').\n",progname);
6383 exit(FAILURE);
6384 }
6385 --argc;
6386 if(!sscanf(argv[no_arg-argc],"%lf",&qe2)) {
6387 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6388 fprintf(stderr,"%s: (Could not read data for qe2).\n",progname);
6389 exit(FAILURE);
6390 }
6391 --argc;
6392 if(strcmp(argv[no_arg-argc],"qm1")) {
6393 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6394 fprintf(stderr,"%s: (Expecting string 'qm1').\n",progname);
6395 exit(FAILURE);
6396 }
6397 --argc;
6398 if(!sscanf(argv[no_arg-argc],"%lf",&qm1)) {
6399 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6400 fprintf(stderr,"%s: (Could not read data for qm1).\n",progname);
6401 exit(FAILURE);
6402 }
6403 --argc;
6404 if(strcmp(argv[no_arg-argc],"qm2")) {
6405 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6406 fprintf(stderr,"%s: (Expecting string 'qm2').\n",progname);
6407 exit(FAILURE);
6408 }
6409 --argc;
6410 if(!sscanf(argv[no_arg-argc],"%lf",&qm2)) {
6411 fprintf(stderr,"%s: Error in 'twolevel' option.\n",progname);
6412 fprintf(stderr,"%s: (Could not read data for qm2).\n",progname);
6413 exit(FAILURE);
6414 }
6415 } else {
6416 fprintf(stderr,"%s: Error in '-g' or '--grating' option.\n",progname);
6417 fprintf(stderr,"%s: (No valid stepwise grating type found!)\n",progname);
6418 exit(FAILURE);
6419 }
6420 }
6421
6422 @ Parse the command line for options related to the initiation of a sinusoidal
6423 grating, consisting of a set of stacked layers.
6424
6425 @<Parse for sinusoidal grating options@>=
6426 {
6427 strcpy(gratingtype,argv[no_arg-argc]);
6428 --argc;
6429 if(strcmp(argv[no_arg-argc],"n")) {
6430 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6431 fprintf(stderr,"%s: (Expecting string 'n').\n",progname);
6432 exit(FAILURE);
6433 }
6434 --argc;
6435 if(!sscanf(argv[no_arg-argc],"%lf",&n1)) {
6436 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6437 fprintf(stderr,"%s: (Could not read data for n [1st arg]).\n",progname);
6438 exit(FAILURE);
6439 }
6440 --argc;
6441 if(!sscanf(argv[no_arg-argc],"%lf",&n2)) {
6442 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6443 fprintf(stderr,"%s: (Could not read data for n [2nd arg]).\n",progname);
6444 exit(FAILURE);
6445 }
6446 --argc;
6447 if(!sscanf(argv[no_arg-argc],"%lf",&nper)) {
6448 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6449 fprintf(stderr,"%s: (Could not read data for n [3rd arg]).\n",progname);
6450 exit(FAILURE);
6451 }
6452 --argc;
6453 if(strcmp(argv[no_arg-argc],"g")) {
6454 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6455 fprintf(stderr,"%s: (Expecting string 'g').\n",progname);
6456 exit(FAILURE);
6457 }
6458 --argc;
6459 if(!sscanf(argv[no_arg-argc],"%lf",&g1)) {
6460 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6461 fprintf(stderr,"%s: (Could not read data for g [1st arg]).\n",progname);
6462 exit(FAILURE);
6463 }
6464 --argc;
6465 if(!sscanf(argv[no_arg-argc],"%lf",&g2)) {
6466 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6467 fprintf(stderr,"%s: (Could not read data for g [2nd arg]).\n",progname);
6468 exit(FAILURE);
6469 }
6470 --argc;
6471 if(!sscanf(argv[no_arg-argc],"%lf",&gper)) {
6472 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6473 fprintf(stderr,"%s: (Could not read data for g [3rd arg]).\n",progname);
6474 exit(FAILURE);
6475 }
6476 --argc;
6477 if(strcmp(argv[no_arg-argc],"pe")) {
6478 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6479 fprintf(stderr,"%s: (Expecting string 'pe').\n",progname);
6480 exit(FAILURE);
6481 }
6482 --argc;
6483 if(!sscanf(argv[no_arg-argc],"%lf",&pe1)) {
6484 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6485 fprintf(stderr,"%s: (Could not read data for pe [1st arg]).\n",progname);
6486 exit(FAILURE);
6487 }
6488 --argc;
6489 if(!sscanf(argv[no_arg-argc],"%lf",&pe2)) {
6490 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6491 fprintf(stderr,"%s: (Could not read data for pe [2nd arg]).\n",progname);
6492 exit(FAILURE);
6493 }
6494 --argc;
6495 if(!sscanf(argv[no_arg-argc],"%lf",&peper)) {
6496 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6497 fprintf(stderr,"%s: (Could not read data for pe [3rd arg]).\n",progname);
6498 exit(FAILURE);
6499 }
6500 --argc;
6501 if(strcmp(argv[no_arg-argc],"pm")) {
6502 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6503 fprintf(stderr,"%s: (Expecting string 'pm').\n",progname);
6504 exit(FAILURE);
6505 }
6506 --argc;
6507 if(!sscanf(argv[no_arg-argc],"%lf",&pm1)) {
6508 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6509 fprintf(stderr,"%s: (Could not read data for pm [1st arg]).\n",progname);
6510 exit(FAILURE);
6511 }
6512 --argc;
6513 if(!sscanf(argv[no_arg-argc],"%lf",&pm2)) {
6514 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6515 fprintf(stderr,"%s: (Could not read data for pm [2nd arg]).\n",progname);
6516 exit(FAILURE);
6517 }
6518 --argc;
6519 if(!sscanf(argv[no_arg-argc],"%lf",&pmper)) {
6520 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6521 fprintf(stderr,"%s: (Could not read data for pm [3rd arg]).\n",progname);
6522 exit(FAILURE);
6523 }
6524 --argc;
6525 if(strcmp(argv[no_arg-argc],"qe")) {
6526 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6527 fprintf(stderr,"%s: (Expecting string 'qe').\n",progname);
6528 exit(FAILURE);
6529 }
6530 --argc;
6531 if(!sscanf(argv[no_arg-argc],"%lf",&qe1)) {
6532 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6533 fprintf(stderr,"%s: (Could not read data for qe [1st arg]).\n",progname);
6534 exit(FAILURE);
6535 }
6536 --argc;
6537 if(!sscanf(argv[no_arg-argc],"%lf",&qe2)) {
6538 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6539 fprintf(stderr,"%s: (Could not read data for qe [2nd arg]).\n",progname);
6540 exit(FAILURE);
6541 }
6542 --argc;
6543 if(!sscanf(argv[no_arg-argc],"%lf",&qeper)) {
6544 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6545 fprintf(stderr,"%s: (Could not read data for qe [3rd arg]).\n",progname);
6546 exit(FAILURE);
6547 }
6548 --argc;
6549 if(strcmp(argv[no_arg-argc],"qm")) {
6550 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6551 fprintf(stderr,"%s: (Expecting string 'qm').\n",progname);
6552 exit(FAILURE);
6553 }
6554 --argc;
6555 if(!sscanf(argv[no_arg-argc],"%lf",&qm1)) {
6556 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6557 fprintf(stderr,"%s: (Could not read data for qm [1st arg]).\n",progname);
6558 exit(FAILURE);
6559 }
6560 --argc;
6561 if(!sscanf(argv[no_arg-argc],"%lf",&qm2)) {
6562 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6563 fprintf(stderr,"%s: (Could not read data for qm [2nd arg]).\n",progname);
6564 exit(FAILURE);
6565 }
6566 --argc;
6567 if(!sscanf(argv[no_arg-argc],"%lf",&qmper)) {
6568 fprintf(stderr,"%s: Error in 'sinusoidal' option.\n",progname);
6569 fprintf(stderr,"%s: (Could not read data for qm [3rd arg]).\n",progname);
6570 exit(FAILURE);
6571 }
6572 }
6573
6574 @ Parse the command line for options related to the initiation of a sinusoidal
6575 grating, consisting of a set of stacked layers.
6576
6577 @<Parse for chirped grating options@>=
6578 {
6579 strcpy(gratingtype,argv[no_arg-argc]);
6580 --argc;
6581 if(strcmp(argv[no_arg-argc],"n")) {
6582 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6583 fprintf(stderr,"%s: (Expecting string 'n').\n",progname);
6584 exit(FAILURE);
6585 }
6586 --argc;
6587 if(!sscanf(argv[no_arg-argc],"%lf",&n1)) {
6588 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6589 fprintf(stderr,"%s: (Could not read data for n [1st arg]).\n",progname);
6590 exit(FAILURE);
6591 }
6592 --argc;
6593 if(!sscanf(argv[no_arg-argc],"%lf",&n2)) {
6594 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6595 fprintf(stderr,"%s: (Could not read data for n [2nd arg]).\n",progname);
6596 exit(FAILURE);
6597 }
6598 --argc;
6599 if(!sscanf(argv[no_arg-argc],"%lf",&nper)) {
6600 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6601 fprintf(stderr,"%s: (Could not read data for n [3rd arg]).\n",progname);
6602 exit(FAILURE);
6603 }
6604 --argc;
6605 if(!sscanf(argv[no_arg-argc],"%lf",&ncrp)) {
6606 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6607 fprintf(stderr,"%s: (Could not read data for n [4th arg]).\n",progname);
6608 exit(FAILURE);
6609 }
6610 --argc;
6611 if(strcmp(argv[no_arg-argc],"g")) {
6612 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6613 fprintf(stderr,"%s: (Expecting string 'g').\n",progname);
6614 exit(FAILURE);
6615 }
6616 --argc;
6617 if(!sscanf(argv[no_arg-argc],"%lf",&g1)) {
6618 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6619 fprintf(stderr,"%s: (Could not read data for g [1st arg]).\n",progname);
6620 exit(FAILURE);
6621 }
6622 --argc;
6623 if(!sscanf(argv[no_arg-argc],"%lf",&g2)) {
6624 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6625 fprintf(stderr,"%s: (Could not read data for g [2nd arg]).\n",progname);
6626 exit(FAILURE);
6627 }
6628 --argc;
6629 if(!sscanf(argv[no_arg-argc],"%lf",&gper)) {
6630 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6631 fprintf(stderr,"%s: (Could not read data for g [3rd arg]).\n",progname);
6632 exit(FAILURE);
6633 }
6634 --argc;
6635 if(!sscanf(argv[no_arg-argc],"%lf",&gcrp)) {
6636 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6637 fprintf(stderr,"%s: (Could not read data for g [4th arg]).\n",progname);
6638 exit(FAILURE);
6639 }
6640 --argc;
6641 if(strcmp(argv[no_arg-argc],"pe")) {
6642 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6643 fprintf(stderr,"%s: (Expecting string 'pe').\n",progname);
6644 exit(FAILURE);
6645 }
6646 --argc;
6647 if(!sscanf(argv[no_arg-argc],"%lf",&pe1)) {
6648 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6649 fprintf(stderr,"%s: (Could not read data for pe [1st arg]).\n",progname);
6650 exit(FAILURE);
6651 }
6652 --argc;
6653 if(!sscanf(argv[no_arg-argc],"%lf",&pe2)) {
6654 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6655 fprintf(stderr,"%s: (Could not read data for pe [2nd arg]).\n",progname);
6656 exit(FAILURE);
6657 }
6658 --argc;
6659 if(!sscanf(argv[no_arg-argc],"%lf",&peper)) {
6660 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6661 fprintf(stderr,"%s: (Could not read data for pe [3rd arg]).\n",progname);
6662 exit(FAILURE);
6663 }
6664 --argc;
6665 if(!sscanf(argv[no_arg-argc],"%lf",&pecrp)) {
6666 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6667 fprintf(stderr,"%s: (Could not read data for pe [4th arg]).\n",progname);
6668 exit(FAILURE);
6669 }
6670 --argc;
6671 if(strcmp(argv[no_arg-argc],"pm")) {
6672 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6673 fprintf(stderr,"%s: (Expecting string 'pm').\n",progname);
6674 exit(FAILURE);
6675 }
6676 --argc;
6677 if(!sscanf(argv[no_arg-argc],"%lf",&pm1)) {
6678 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6679 fprintf(stderr,"%s: (Could not read data for pm [1st arg]).\n",progname);
6680 exit(FAILURE);
6681 }
6682 --argc;
6683 if(!sscanf(argv[no_arg-argc],"%lf",&pm2)) {
6684 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6685 fprintf(stderr,"%s: (Could not read data for pm [2nd arg]).\n",progname);
6686 exit(FAILURE);
6687 }
6688 --argc;
6689 if(!sscanf(argv[no_arg-argc],"%lf",&pmper)) {
6690 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6691 fprintf(stderr,"%s: (Could not read data for pm [3rd arg]).\n",progname);
6692 exit(FAILURE);
6693 }
6694 --argc;
6695 if(!sscanf(argv[no_arg-argc],"%lf",&pmcrp)) {
6696 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6697 fprintf(stderr,"%s: (Could not read data for pm [4th arg]).\n",progname);
6698 exit(FAILURE);
6699 }
6700 --argc;
6701 if(strcmp(argv[no_arg-argc],"qe")) {
6702 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6703 fprintf(stderr,"%s: (Expecting string 'qe').\n",progname);
6704 exit(FAILURE);
6705 }
6706 --argc;
6707 if(!sscanf(argv[no_arg-argc],"%lf",&qe1)) {
6708 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6709 fprintf(stderr,"%s: (Could not read data for qe [1st arg]).\n",progname);
6710 exit(FAILURE);
6711 }
6712 --argc;
6713 if(!sscanf(argv[no_arg-argc],"%lf",&qe2)) {
6714 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6715 fprintf(stderr,"%s: (Could not read data for qe [2nd arg]).\n",progname);
6716 exit(FAILURE);
6717 }
6718 --argc;
6719 if(!sscanf(argv[no_arg-argc],"%lf",&qeper)) {
6720 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6721 fprintf(stderr,"%s: (Could not read data for qe [3rd arg]).\n",progname);
6722 exit(FAILURE);
6723 }
6724 --argc;
6725 if(!sscanf(argv[no_arg-argc],"%lf",&qecrp)) {
6726 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6727 fprintf(stderr,"%s: (Could not read data for qe [4th arg]).\n",progname);
6728 exit(FAILURE);
6729 }
6730 --argc;
6731 if(strcmp(argv[no_arg-argc],"qm")) {
6732 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6733 fprintf(stderr,"%s: (Expecting string 'qm').\n",progname);
6734 exit(FAILURE);
6735 }
6736 --argc;
6737 if(!sscanf(argv[no_arg-argc],"%lf",&qm1)) {
6738 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6739 fprintf(stderr,"%s: (Could not read data for qm [1st arg]).\n",progname);
6740 exit(FAILURE);
6741 }
6742 --argc;
6743 if(!sscanf(argv[no_arg-argc],"%lf",&qm2)) {
6744 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6745 fprintf(stderr,"%s: (Could not read data for qm [2nd arg]).\n",progname);
6746 exit(FAILURE);
6747 }
6748 --argc;
6749 if(!sscanf(argv[no_arg-argc],"%lf",&qmper)) {
6750 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6751 fprintf(stderr,"%s: (Could not read data for qm [3rd arg]).\n",progname);
6752 exit(FAILURE);
6753 }
6754 --argc;
6755 if(!sscanf(argv[no_arg-argc],"%lf",&qmcrp)) {
6756 fprintf(stderr,"%s: Error in 'chirped' grating option.\n",progname);
6757 fprintf(stderr,"%s: (Could not read data for qm [4th arg]).\n",progname);
6758 exit(FAILURE);
6759 }
6760 }
6761
6762 @ Parse the command line for options related to the initiation of a fractal
6763 grating, consisting of a set of stacked homogeneous layers of thicknesses
6764 corresponding to a Cantor-set fractal.
6765
6766 @<Parse for fractal grating options@>=
6767 {
6768 strcpy(gratingtype,argv[no_arg-argc]);
6769 --argc;
6770 if(!strcmp(argv[no_arg-argc],"cantor")) {
6771 strcpy(gratingsubtype,argv[no_arg-argc]);
6772 --argc;
6773 if(strcmp(argv[no_arg-argc],"fractal_level")) {
6774 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6775 fprintf(stderr,"%s: (Expecting string 'fractal_level').\n",progname);
6776 exit(FAILURE);
6777 }
6778 --argc;
6779 if(!sscanf(argv[no_arg-argc],"%d",&fractal_level)) {
6780 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6781 fprintf(stderr,"%s: (Could not read data for fractal_level).\n",
6782 progname);
6783 exit(FAILURE);
6784 }
6785 --argc;
6786 if(strcmp(argv[no_arg-argc],"maximum_fractal_level")) {
6787 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6788 fprintf(stderr,"%s: (Expecting string 'maximum_fractal_level').\n",
6789 progname);
6790 exit(FAILURE);
6791 }
6792 --argc;
6793 if(!sscanf(argv[no_arg-argc],"%d",&maximum_fractal_level)) {
6794 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6795 fprintf(stderr,"%s: (Could not read data for maximum_fractal_level).\n",
6796 progname);
6797 exit(FAILURE);
6798 }
6799 nn=1;
6800 for (j=1;j<=fractal_level;j++) nn=2*nn;
6801 --argc;
6802 if(strcmp(argv[no_arg-argc],"t1")) {
6803 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6804 fprintf(stderr,"%s: (Expecting string 't1').\n",progname);
6805 exit(FAILURE);
6806 }
6807 --argc;
6808 if(!sscanf(argv[no_arg-argc],"%lf",&t1)) {
6809 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6810 fprintf(stderr,"%s: (Could not read data for t1).\n",progname);
6811 exit(FAILURE);
6812 }
6813 --argc;
6814 if(strcmp(argv[no_arg-argc],"t2")) {
6815 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6816 fprintf(stderr,"%s: (Expecting string 't2').\n",progname);
6817 exit(FAILURE);
6818 }
6819 --argc;
6820 if(!sscanf(argv[no_arg-argc],"%lf",&t2)) {
6821 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6822 fprintf(stderr,"%s: (Could not read data for t2).\n",progname);
6823 exit(FAILURE);
6824 }
6825 --argc;
6826 if(strcmp(argv[no_arg-argc],"n1")) {
6827 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6828 fprintf(stderr,"%s: (Expecting string 'n1').\n",progname);
6829 exit(FAILURE);
6830 }
6831 --argc;
6832 if(!sscanf(argv[no_arg-argc],"%lf",&n1)) {
6833 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6834 fprintf(stderr,"%s: (Could not read data for n1).\n",progname);
6835 exit(FAILURE);
6836 }
6837 --argc;
6838 if(strcmp(argv[no_arg-argc],"n2")) {
6839 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6840 fprintf(stderr,"%s: (Expecting string 'n2').\n",progname);
6841 exit(FAILURE);
6842 }
6843 --argc;
6844 if(!sscanf(argv[no_arg-argc],"%lf",&n2)) {
6845 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6846 fprintf(stderr,"%s: (Could not read data for n2).\n",progname);
6847 exit(FAILURE);
6848 }
6849 --argc;
6850 if(strcmp(argv[no_arg-argc],"g1")) {
6851 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6852 fprintf(stderr,"%s: (Expecting string 'g1').\n",progname);
6853 exit(FAILURE);
6854 }
6855 --argc;
6856 if(!sscanf(argv[no_arg-argc],"%lf",&g1)) {
6857 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6858 fprintf(stderr,"%s: (Could not read data for g1).\n",progname);
6859 exit(FAILURE);
6860 }
6861 --argc;
6862 if(strcmp(argv[no_arg-argc],"g2")) {
6863 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6864 fprintf(stderr,"%s: (Expecting string 'g2').\n",progname);
6865 exit(FAILURE);
6866 }
6867 --argc;
6868 if(!sscanf(argv[no_arg-argc],"%lf",&g2)) {
6869 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6870 fprintf(stderr,"%s: (Could not read data for g2).\n",progname);
6871 exit(FAILURE);
6872 }
6873 --argc;
6874 if(strcmp(argv[no_arg-argc],"pe1")) {
6875 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6876 fprintf(stderr,"%s: (Expecting string 'pe1').\n",progname);
6877 exit(FAILURE);
6878 }
6879 --argc;
6880 if(!sscanf(argv[no_arg-argc],"%lf",&pe1)) {
6881 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6882 fprintf(stderr,"%s: (Could not read data for pe1).\n",progname);
6883 exit(FAILURE);
6884 }
6885 --argc;
6886 if(strcmp(argv[no_arg-argc],"pe2")) {
6887 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6888 fprintf(stderr,"%s: (Expecting string 'pe2').\n",progname);
6889 exit(FAILURE);
6890 }
6891 --argc;
6892 if(!sscanf(argv[no_arg-argc],"%lf",&pe2)) {
6893 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6894 fprintf(stderr,"%s: (Could not read data for pe2).\n",progname);
6895 exit(FAILURE);
6896 }
6897 --argc;
6898 if(strcmp(argv[no_arg-argc],"pm1")) {
6899 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6900 fprintf(stderr,"%s: (Expecting string 'pm1').\n",progname);
6901 exit(FAILURE);
6902 }
6903 --argc;
6904 if(!sscanf(argv[no_arg-argc],"%lf",&pm1)) {
6905 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6906 fprintf(stderr,"%s: (Could not read data for pm1).\n",\
6907 progname);
6908 exit(FAILURE);
6909 }
6910 --argc;
6911 if(strcmp(argv[no_arg-argc],"pm2")) {
6912 fprintf(stderr,"%s: Error.\n",progname);
6913 fprintf(stderr,"%s: (Expecting string 'pm2').\n",progname);
6914 exit(FAILURE);
6915 }
6916 --argc;
6917 if(!sscanf(argv[no_arg-argc],"%lf",&pm2)) {
6918 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6919 fprintf(stderr,"%s: (Could not read data for pm2).\n",\
6920 progname);
6921 exit(FAILURE);
6922 }
6923 --argc;
6924 if(strcmp(argv[no_arg-argc],"qe1")) {
6925 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6926 fprintf(stderr,"%s: (Expecting string 'qe1').\n",progname);
6927 exit(FAILURE);
6928 }
6929 --argc;
6930 if(!sscanf(argv[no_arg-argc],"%lf",&qe1)) {
6931 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6932 fprintf(stderr,"%s: (Could not read data for qe1).\n",\
6933 progname);
6934 exit(FAILURE);
6935 }
6936 --argc;
6937 if(strcmp(argv[no_arg-argc],"qe2")) {
6938 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6939 fprintf(stderr,"%s: (Expecting string 'qe2').\n",progname);
6940 exit(FAILURE);
6941 }
6942 --argc;
6943 if(!sscanf(argv[no_arg-argc],"%lf",&qe2)) {
6944 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6945 fprintf(stderr,"%s: (Could not read data for qe2).\n",progname);
6946 exit(FAILURE);
6947 }
6948 --argc;
6949 if(strcmp(argv[no_arg-argc],"qm1")) {
6950 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6951 fprintf(stderr,"%s: (Expecting string 'qm1').\n",progname);
6952 exit(FAILURE);
6953 }
6954 --argc;
6955 if(!sscanf(argv[no_arg-argc],"%lf",&qm1)) {
6956 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6957 fprintf(stderr,"%s: (Could not read data for qm1).\n",progname);
6958 exit(FAILURE);
6959 }
6960 --argc;
6961 if(strcmp(argv[no_arg-argc],"qm2")) {
6962 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6963 fprintf(stderr,"%s: (Expecting string 'qm2').\n",progname);
6964 exit(FAILURE);
6965 }
6966 --argc;
6967 if(!sscanf(argv[no_arg-argc],"%lf",&qm2)) {
6968 fprintf(stderr,"%s: Error in 'cantor' grating option.\n",progname);
6969 fprintf(stderr,"%s: (Could not read data for qm2).\n",progname);
6970 exit(FAILURE);
6971 }
6972 } else {
6973 fprintf(stderr,"%s: Error in 'fractal' grating option.\n",progname);
6974 fprintf(stderr,"%s: (No valid fractal type found!)\n",progname);
6975 fprintf(stderr,"%s: (Currently only Cantor type implemented)\n",progname);
6976 exit(FAILURE);
6977 }
6978 }
6979
6980 @ Parse the command line for options related to the manual modification of an
6981 arbitrary discrete layer of the grating structure (which may be of type
6982 stepwise twolevel, sinusoidal, chirped, or any other, arbitrary type).
6983
6984 @<Parse for options for modified layer of grating structure@>=
6985 {
6986 --argc;
6987 if(strcmp(argv[no_arg-argc],"num")) {
6988 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
6989 fprintf(stderr,"%s: (Expecting string 'num' after '--modifylayer').\n",
6990 progname);
6991 exit(FAILURE);
6992 }
6993 --argc;
6994 if(!sscanf(argv[no_arg-argc],"%ld",&modnum)) {
6995 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
6996 fprintf(stderr,"%s: (Could not read data for num).\n",progname);
6997 exit(FAILURE);
6998 }
6999 --argc;
7000 if(strcmp(argv[no_arg-argc],"t")) {
7001 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
7002 fprintf(stderr,"%s: (Expecting string 't' [for layer thickness]).\n",
7003 progname);
7004 exit(FAILURE);
7005 }
7006 --argc;
7007 if(!sscanf(argv[no_arg-argc],"%lf",&modt1)) {
7008 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
7009 fprintf(stderr,"%s: (Could not read data for t [layer thickness]).\n",
7010 progname);
7011 exit(FAILURE);
7012 }
7013 --argc;
7014 if(strcmp(argv[no_arg-argc],"n")) {
7015 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
7016 fprintf(stderr,"%s: (Expecting string 'n' [for refractive index]).\n",
7017 progname);
7018 exit(FAILURE);
7019 }
7020 --argc;
7021 if(!sscanf(argv[no_arg-argc],"%lf",&modn1)) {
7022 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
7023 fprintf(stderr,"%s: (Could not read data for n [refractive index]).\n",
7024 progname);
7025 exit(FAILURE);
7026 }
7027 --argc;
7028 if(strcmp(argv[no_arg-argc],"g")) {
7029 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
7030 fprintf(stderr,"%s: (Expecting string 'g' [for gyration constant]).\n",
7031 progname);
7032 exit(FAILURE);
7033 }
7034 --argc;
7035 if(!sscanf(argv[no_arg-argc],"%lf",&modg1)) {
7036 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
7037 fprintf(stderr,"%s: (Could not read data for g [gyration constant]).\n",
7038 progname);
7039 exit(FAILURE);
7040 }
7041 --argc;
7042 if(strcmp(argv[no_arg-argc],"pe")) {
7043 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
7044 fprintf(stderr,"%s: (Expecting string 'pe').\n",progname);
7045 exit(FAILURE);
7046 }
7047 --argc;
7048 if(!sscanf(argv[no_arg-argc],"%lf",&modpe1)) {
7049 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
7050 fprintf(stderr,"%s: (Could not read data for pe).\n",progname);
7051 exit(FAILURE);
7052 }
7053 --argc;
7054 if(strcmp(argv[no_arg-argc],"pm")) {
7055 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
7056 fprintf(stderr,"%s: (Expecting string 'pm').\n",progname);
7057 exit(FAILURE);
7058 }
7059 --argc;
7060 if(!sscanf(argv[no_arg-argc],"%lf",&modpm1)) {
7061 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
7062 fprintf(stderr,"%s: (Could not read data for pm).\n",progname);
7063 exit(FAILURE);
7064 }
7065 --argc;
7066 if(strcmp(argv[no_arg-argc],"qe")) {
7067 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
7068 fprintf(stderr,"%s: (Expecting string 'qe').\n",progname);
7069 exit(FAILURE);
7070 }
7071 --argc;
7072 if(!sscanf(argv[no_arg-argc],"%lf",&modqe1)) {
7073 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
7074 fprintf(stderr,"%s: (Could not read data for qe).\n",progname);
7075 exit(FAILURE);
7076 }
7077 --argc;
7078 if(strcmp(argv[no_arg-argc],"qm")) {
7079 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
7080 fprintf(stderr,"%s: (Expecting string 'qm').\n",progname);
7081 exit(FAILURE);
7082 }
7083 --argc;
7084 if(!sscanf(argv[no_arg-argc],"%lf",&modqm1)) {
7085 fprintf(stderr,"%s: Error in '--modifylayer'.\n",progname);
7086 fprintf(stderr,"%s: (Could not read data for qm).\n",progname);
7087 exit(FAILURE);
7088 }
7089 }
7090
7091 @ Parse the command line for options specifying the transmitted optical
7092 intensity range.
7093 The command line syntax for specification of the transmitted optical intensity
7094 range is
7095 \smallskip
7096 \centerline{\hbox to 40pt{}\.{--trmintensity}
7097 $\langle I_{\rm start}\rangle$ $\langle I_{\rm stop}\rangle$
7098 $\langle M_{\rm i}\rangle$\hfill}
7099 \smallskip\noindent
7100 where the numerical values supplied are internally kept by the variables
7101 |trmintenstart|, |trmintenstop|, and |mmi|, respectively.
7102
7103 @<Parse the command line for transmitted intensity range@>=
7104 {
7105 --argc;
7106 if(!sscanf(argv[no_arg-argc],"%lf",&trmintenstart)) {
7107 fprintf(stderr,"%s: Error in '--trmintensity' option.\n",\
7108 progname);
7109 exit(FAILURE);
7110 }
7111 --argc;
7112 if(!sscanf(argv[no_arg-argc],"%lf",&trmintenstop)) {
7113 fprintf(stderr,"%s: Error in '--trmintensity' option.\n",\
7114 progname);
7115 exit(FAILURE);
7116 }
7117 --argc;
7118 if(!sscanf(argv[no_arg-argc],"%ld",&mmi)) {
7119 fprintf(stderr,"%s: Error in '--trmintensity' option.\n",\
7120 progname);
7121 exit(FAILURE);
7122 }
7123 }
7124
7125 @ Parse the command line for options specifying the ellipticity range of the
7126 transmitted polarization state. The command line syntax for specification of
7127 the ellipticity of the transmitted polarization state is analogous to that
7128 of the transmitted intensity,
7129 \smallskip
7130 \centerline{\hbox to 40pt{}\.{--trmellipticity}
7131 $\langle \epsilon_{\rm start}\rangle$ $\langle \epsilon_{\rm stop}\rangle$
7132 $\langle M_{\rm e}\rangle$\hfill}
7133 \smallskip\noindent
7134 where the numerical values supplied are internally kept by the variables
7135 |trmellipstart|, |trmellipstop|, and |mme|, respectively.
7136
7137 @<Parse the command line for transmitted ellipticity range@>=
7138 {
7139 --argc;
7140 if(!sscanf(argv[no_arg-argc],"%lf",&trmellipstart)) {
7141 fprintf(stderr,"%s: Error in '--trmellipticity' option.\n",progname);
7142 exit(FAILURE);
7143 }
7144 --argc;
7145 if(!sscanf(argv[no_arg-argc],"%lf",&trmellipstop)) {
7146 fprintf(stderr,"%s: Error in '--trmellipticity' option.\n",progname);
7147 exit(FAILURE);
7148 }
7149 --argc;
7150 if(!sscanf(argv[no_arg-argc],"%ld",&mme)) {
7151 fprintf(stderr,"%s: Error in '--trmellipticity' option.\n",progname);
7152 exit(FAILURE);
7153 }
7154 }
7155
7156 @ If the flag |verbose| is set to true (|1| in C), then display the information
7157 parsed from the command line, such as output filenames, indices of refraction,
7158 grating period, etc. This is useful for later on creating log files of
7159 sessions with the executable program \magbragg.
7160
7161 @<Display parameters parsed from the command line@>=
7162 {
7163 if (verbose) {
7164 for (k=1;k<=64;k++) fprintf(stdout,(k<64?"-":"\n"));
7165 fprintf(stdout,"Input parameters:\n");
7166 fprintf(stdout,
7167 "Grating type: %s\n",gratingtype);
7168 if (!strcmp(gratingtype,"sinusoidal")) {
7169 fprintf(stdout,
7170 "Bias refractive index: %10.6e\n",n1);
7171 fprintf(stdout,
7172 "Refractive index modulation: %10.6e\n",n2);
7173 fprintf(stdout,
7174 "Modulation period: %10.6e [m]\n",nper);
7175 } else if (!strcmp(gratingtype,"chirped")) {
7176 } else if (!strcmp(gratingtype,"stepwise")) {
7177 } else if (!strcmp(gratingtype,"fractal")) {
7178 } else {
7179 fprintf(stdout,"%s: Error: Unknown grating type '%s'\n",
7180 progname,gratingtype);
7181 }
7182 fprintf(stdout,"Geometrical length: "
7183 "L=%10.6e [m]\n",ll);
7184 fprintf(stdout,"Surrounding refractive index: "
7185 "nsurr=%10.6e\n",nsurr);
7186 fprintf(stdout,"Begin wavelength of spectrum: "
7187 "lambda_start=%10.6e [m]\n",lambdastart);
7188 fprintf(stdout,"End wavelength of spectrum: "
7189 "lambda_stop=%10.6e [m]\n",lambdastop);
7190 fprintf(stdout,"Number of samples in spectrum: "
7191 "M=%-12ld\n",mm);
7192 fprintf(stdout,"Number of discrete layers: "
7193 "N=%-12ld\n",nn);
7194 if (trmtraject_specified) {
7195 fprintf(stdout,"Trajectory for transmitted Stokes parameters: %s\n",
7196 trmtraject_filename);
7197 } else {
7198 fprintf(stdout,"Number of samples in output intensity: "
7199 "mmi=%-12ld\n",mmi);
7200 fprintf(stdout,"Number of samples in output ellipticity: "
7201 "mme=%-12ld\n",mme);
7202 }
7203 fprintf(stdout,"Stokes parameters will be written to files:\n");
7204 fprintf(stdout," %s [S0 (incident wave)],\n",outfilename_s0);
7205 fprintf(stdout," %s [S1 (incident wave)],\n",outfilename_s1);
7206 fprintf(stdout," %s [S2 (incident wave)],\n",outfilename_s2);
7207 fprintf(stdout," %s [S3 (incident wave)],\n",outfilename_s3);
7208 fprintf(stdout," %s [V0 (reflected wave)],\n",outfilename_v0);
7209 fprintf(stdout," %s [V1 (reflected wave)],\n",outfilename_v1);
7210 fprintf(stdout," %s [V2 (reflected wave)],\n",outfilename_v2);
7211 fprintf(stdout," %s [V3 (reflected wave)],\n",outfilename_v3);
7212 fprintf(stdout," %s [W0 (transmitted wave)],\n",outfilename_w0);
7213 fprintf(stdout," %s [W1 (transmitted wave)],\n",outfilename_w1);
7214 fprintf(stdout," %s [W2 (transmitted wave)],\n",outfilename_w2);
7215 fprintf(stdout," %s [W3 (transmitted wave)],\n",outfilename_w3);
7216 if (fieldevoflag) {
7217 if (fieldevoflag_efield) {
7218 if(strcmp(fieldevofilename,"")) {
7219 fprintf(stdout,"Intra grating optical field evolution will "
7220 "be written to file:\n");
7221 fprintf(stdout," %s\n",fieldevofilename);
7222 } else {
7223 fprintf(stderr,
7224 "%s: Error: No file name specified for saving spatial\n"
7225 "field evolution. (efield option)\n",progname);
7226 exit(FAILURE);
7227 }
7228 fprintf(stdout,
7229 "(Intra grating field evolution will be presented in terms of\n"
7230 "the electrical field displacement.)\n");
7231 } else if (fieldevoflag_stoke) {
7232 if(strcmp(fieldevofilename_s0,"")
7233 &&strcmp(fieldevofilename_s1,"")
7234 &&strcmp(fieldevofilename_s2,"")
7235 &&strcmp(fieldevofilename_s3,"")) {
7236 fprintf(stdout,"Intra grating optical field evolution will "
7237 "be written to files:\n");
7238 fprintf(stdout," %s\n %s\n %s\n %s\n",
7239 fieldevofilename_s0,fieldevofilename_s1,
7240 fieldevofilename_s2,fieldevofilename_s3);
7241 } else {
7242 fprintf(stderr,
7243 "%s: Error: No file name specified for saving spatial\n"
7244 "field evolution. (stoke option)\n",progname);
7245 exit(FAILURE);
7246 }
7247 fprintf(stdout,
7248 "(Intra grating field evolution will be presented in terms of\n"
7249 "the Stokes parameters of the forward propagating field.)\n");
7250 } else {
7251 fprintf(stderr,"%s: Unknown field evolution flag.\n",progname);
7252 exit(FAILURE);
7253 }
7254 fprintf(stdout,
7255 "Number of intermediate samples within each layer: %-12ld\n",nne);
7256 }
7257 if (intensityevoflag) {
7258 if(strcmp(intensityevofilename,"")) {
7259 fprintf(stdout,"Intra grating optical intensity evolution will "
7260 "be written to file:\n");
7261 fprintf(stdout," %s\n",intensityevofilename);
7262 }
7263 }
7264 fprintf(stdout,"Program execution started %s",ctime(&initime));
7265 for (k=1;k<=64;k++) fprintf(stdout,(k<64?"-":"\n"));
7266 }
7267 }
7268
7269 @ Routines for displaying help message to standard terminal output.
7270
7271 @<Routines for displaying help message@>=
7272 @<Display split help line@>@;
7273 @<Display full help line@>@;
7274 @<Display help message@>@;
7275
7276 @ Routine for proper display of split help lines. This is a very simple
7277 routine just to keep the |fprintf(stderr,"...","...")| statements to a
7278 minimum. The routine also checks that the full length of the diplayed
7279 line does not exceed 80 characters, as conforming to normal line length
7280 of terminal output.
7281
7282 @<Display split help line@>=
7283 void hl(char firststring[],char secondstring[]) {
7284 if (strlen(firststring)>25) {
7285 fprintf(stderr,"%s:******* Error in hl() routine! *******\n",progname);
7286 fprintf(stderr,"%s: The first string argument is too long:\n",progname);
7287 fprintf(stderr,"%s: '%s'\n",progname,firststring);
7288 fprintf(stderr,"%s: String lengths is %d characters\n",
7289 progname,(int)strlen(firststring));
7290 fprintf(stderr,"%s: (Maximum 25 characters for first argument.)\n",
7291 progname);
7292 fprintf(stderr,"%s:******** End of error message *********\n",progname);
7293 exit(FAILURE);
7294 }
7295 if (strlen(secondstring)>55) {
7296 fprintf(stderr,"%s:******* Error in hl() routine! *******\n",progname);
7297 fprintf(stderr,"%s: The second string argument is too long:\n",progname);
7298 fprintf(stderr,"%s: '%s'\n",progname,secondstring);
7299 fprintf(stderr,"%s: String lengths is %d characters\n",
7300 progname,(int)strlen(secondstring));
7301 fprintf(stderr,"%s: (Maximum 55 characters for second argument.)\n",
7302 progname);
7303 fprintf(stderr,"%s:******** End of error message *********\n",progname);
7304 exit(FAILURE);
7305 }
7306 fprintf(stderr,"%-25.25s%1.55s\n",firststring,secondstring);
7307 }
7308
7309 @ Routine for proper display of full help lines. This is similar to the |hl()|
7310 routine, with the only difference being that a full line of text is flushed
7311 instead of a line split into two parts.
7312
7313 @<Display full help line@>=
7314 void fhl(char linestring[]) {
7315 if (strlen(linestring)>80) {
7316 fprintf(stderr,"%s:******* Error in fhl() routine! *******\n",progname);
7317 fprintf(stderr,"%s: The following help line is too long:\n",progname);
7318 fprintf(stderr,"%s: '%s'\n",progname,linestring);
7319 fprintf(stderr,"%s: String is %d characters\n",
7320 progname,(int)strlen(linestring));
7321 fprintf(stderr,"%s: (Maximum 80 characters per help line is allowed.)\n",
7322 progname);
7323 fprintf(stderr,"%s:******** End of error message *********\n",progname);
7324 exit(FAILURE);
7325 }
7326 fprintf(stderr,"%s\n",linestring);
7327 }
7328
7329 @ Show a help message at the screen, giving the full syntax of the
7330 command line options that are accepted by the program.
7331
7332 @<Display help message@>=
7333 void showsomehelp(void) {
7334 fprintf(stderr," Usage: %s [options]\n",progname);
7335 fhl(" Options:");
7336 hl(" -h, --help","Display this help message and exit clean.");
7337 hl(" -N <int>","");
7338 hl(" -M <int>","");
7339 hl(" -v, --verbose","");
7340 hl(" -o, --outputfile <str>","");
7341 fhl(" --fieldevolution {efield|stoke} <n> <str>");
7342 fhl(" --intensityevolution <lambda> <str>");
7343 fhl(" --normalize_length_to_um");
7344 hl(" --normalize_intensity","");
7345 hl("","When saving the spatial evolution of the intra-");
7346 hl("","grating intensity, normalize the intensity with");
7347 hl("","respect to the intensity at z=0, inside the");
7348 hl("","grating (that is to say, normalize with respect");
7349 hl("","to the initial intra-grating intensity). This");
7350 hl("","option *only* affects the fields saved with the");
7351 hl("","--intensityevolution or --fieldevolution");
7352 hl("","options.");
7353 hl(" -r, --random","");
7354 hl(" -a, --apodize <real>","");
7355 hl("","Apodize the grating structure over geometrical");
7356 hl("","distance <real> at each end of the grating.");
7357 hl("","The option only applies to gratings with sinus-");
7358 hl("","oidal modulation of refractive index and");
7359 hl("","gyration coefficient, in constant or chirped");
7360 hl("","periodic configurations, as specified with the");
7361 hl("","'--grating sinusoidal' or '--grating chirped'");
7362 hl("","options respectively.");
7363 hl(""," The apodization is applied to the refractive");
7364 hl("","index modulation and, in cases where the linear");
7365 hl("","magneto-optical is spatially modulated as well,");
7366 hl("","to the linear gyration coefficient.");
7367 fhl(" -j, --phasejump <r1 (angle)> <r2 (position)>");
7368 hl("","Apply discrete phase jump in the spatial phase");
7369 hl("","of the grating profile. This option adds the");
7370 hl("","real number <r1> to the argument of the sinus-");
7371 hl("","oidal function for the grating profile for all");
7372 hl("","spatial coordinates z >= <r2>.");
7373 hl(""," As in the case of apodization, this option");
7374 hl("","only applies to gratings with sinusoidal modu-");
7375 hl("","lation of refractive index and gyration coeffi-");
7376 hl("","cient, in constant or chirped periodic configu-");
7377 hl("","rations, as specified with the '--grating");
7378 hl("","sinusoidal' or '--grating chirped' options");
7379 hl("","respectively. The discrete phase jump applies");
7380 hl("","to the linear linear refractive index modula-");
7381 hl("","tion and, in cases where the linear magneto-");
7382 hl("","optical interaction is spatially modulated as");
7383 hl("","well, also to the linear gyration coefficient.");
7384 fhl(" -w, --writegratingfile <str>");
7385 hl(" --spectrumfile <str>","");
7386 hl("","Generates the complex reflectance as function");
7387 hl("","of the vacuum wavelength in meters, and save");
7388 hl("","the spectrum in file named according to the");
7389 hl("","supplied character string <str>.");
7390 fhl(" --intensityspectrumfile <str>");
7391 hl("","Generates the intensity reflectance as function");
7392 hl("","of the vacuum wavelength in meters, and save");
7393 hl("","the spectrum in file named according to the");
7394 hl("","supplied character string <str>.");
7395 fhl(" -g, --grating <grating options>");
7396 hl("","Specifies the grating type, where");
7397 hl("","<grating options> = ");
7398 hl(""," [stepwise <stepwise options> |");
7399 hl(""," sinusoidal <sinusoidal options> |");
7400 hl(""," chirped <chirped options>]");
7401 hl("","<stepwise options> = ");
7402 hl(""," twolevel t1 <f> t2 <f>");
7403 hl(""," n1 <f> n2 <f> g1 <f> g2 <f>");
7404 hl(""," pe1 <f> pe2 <f> pm1 <f> pm2 <f>");
7405 hl(""," qe1 <f> qe2 <f> qm1 <f> qm2 <f>");
7406 hl("","<sinusoidal options> = ");
7407 hl(""," n <n0> <dn> <nper>");
7408 hl(""," g <g0> <dg> <gper>");
7409 hl(""," pe <pe0> <dpe> <peper>");
7410 hl(""," pm <pm0> <dpm> <pmper>");
7411 hl(""," qe <qe0> <dqe> <qeper>");
7412 hl(""," qm <qm0> <dqm> <qmper>");
7413 hl("","<chirped options> = ");
7414 hl(""," n <n0> <dn> <nper> <ncrp>");
7415 hl(""," g <g0> <dg> <gper> <gcrp>");
7416 hl(""," pe <pe0> <dpe> <peper> <pecrp>");
7417 hl(""," pm <pm0> <dpm> <pmper> <pmcrp>");
7418 hl(""," qe <qe0> <dqe> <qeper> <qecrp>");
7419 hl(""," qm <qm0> <dqm> <qmper> <qmcrp>");
7420 hl(" -L,--gratinglength <f>","Physical length of grating in meter [m]");
7421 fhl(" --refindsurr <f>");
7422 fhl(" --trmtraject <str>");
7423 fhl(" --trmintensity <istart> <istop> <mmi>");
7424 fhl(" (intensity measured in Watts per square meter)");
7425 fhl(" --trmellipticity <estart> <estop> <mme>");
7426 fhl(" --lambdastart <lambda>");
7427 fhl(" (start vacuum wavelength measured in meter)");
7428 fhl(" --lambdastop <lambda>");
7429 fhl(" (stop vacuum wavelength measured in meter)");
7430 exit(FAILURE);
7431 }
7432
7433 @*Check for specified trajectory of transmitted Stokes parameters.
7434
7435 @<Check for specified trajectory of transmitted Stokes parameters@>=
7436 {
7437 mmtraject=0;
7438 if (trmtraject_specified) { /* Was a trajectory specified at all? */
7439 if ((fp_traject=fopen(trmtraject_filename,"r"))==NULL) {
7440 fprintf(stderr,
7441 "%s: Could not open file %s for reading Stokes parameter"
7442 " trajectory of transmitted wave!\n",
7443 progname,trmtraject_filename);
7444 exit(FAILURE);
7445 }
7446 fseek(fp_traject,0L,SEEK_SET);
7447
7448 /* Scan the specified file for the number of points of the trajectory */
7449 while((tmpch=getc(fp_traject))!=EOF) {
7450 ungetc(tmpch,fp_traject);
7451 fscanf(fp_traject,"%lf",&tmp); /* Read away the $W_0$ parameter */
7452 fscanf(fp_traject,"%lf",&tmp); /* Read away the $W_3$ parameter */
7453 mmtraject++;
7454
7455 /* Read away blanks and linefeeds */
7456 tmpch=getc(fp_traject);
7457 while ((tmpch!=EOF)&&(!numeric(tmpch))) {
7458 tmpch=getc(fp_traject);
7459 }
7460 if (tmpch!=EOF) ungetc(tmpch,fp_traject);
7461 }
7462
7463 if (verbose) {
7464 fprintf(stdout,
7465 "%s: I have now pre-parsed the specified trajectory of transmitted\n"
7466 "Stokes parameters (W0,W3) in file %s, and I found %-ld points.\n",
7467 progname,trmtraject_filename,mmtraject);
7468 fprintf(stdout,
7469 "%s: Now allocating the vectors for the transmitted trajectory...",
7470 progname);
7471 }
7472
7473 fseek(fp_traject,0L,SEEK_SET); /* Rewind the file for reading */
7474 w0traj=dvector(1,mmtraject); /* Allocate memory for |w0traj| */
7475 w3traj=dvector(1,mmtraject); /* Allocate memory for |w3traj| */
7476 for (ke=1;ke<=mmtraject;ke++) {
7477 fscanf(fp_traject,"%le",&w0traj[ke]); /* Read the $W_0$ parameter */
7478 fscanf(fp_traject,"%le",&w3traj[ke]); /* Read the $W_3$ parameter */
7479 }
7480
7481 if(0==1) {
7482 for (ke=1;ke<=mmtraject;ke++)
7483 fprintf(stdout,"w0=%e w3=%e\n",w0traj[ke],w3traj[ke]);
7484 }
7485
7486 fclose(fp_traject);
7487 }
7488 }
7489
7490 @*Opening and closing files for data output.
7491 Open output files, to be used later on for saving Stokes parameters on disk.
7492 The naming convention of the files is that the |outfilename| string (at the
7493 command line specified using the \.{-o} $\langle|outfilename|\rangle$
7494 or \.{--outputfile} $\langle|outfilename|\rangle$ option) is the base
7495 name, with suffixes \.{.s0.dat}, \.{.s1.dat}, etc., indicating the
7496 actual Stoke parameter which was written to respective file.
7497
7498 The following string variables contain the filenames of the files where to
7499 store the calculated data:
7500 \varitem[{$|outfilename_s0|$}]{The $S_0$ Stokes parameter of the incident
7501 optical wave, governing the optical intensity.}
7502 \varitem[{$|outfilename_s1|$}]{The $S_1$ Stokes parameter of the incident
7503 optical wave, together with $S_2$ governing the orientation of the main
7504 axis of the polarization ellipse.}
7505 \varitem[{$|outfilename_s2|$}]{The $S_2$ Stokes parameter of the incident
7506 optical wave, together with $S_1$ governing the orientation of the main
7507 axis of the polarization ellipse.}
7508 \varitem[{$|outfilename_s3|$}]{The $S_3$ Stokes parameter of the incident
7509 optical wave, governing the polarization state ellipticity.}
7510 \varitem[{$|outfilename_v0|$}]{The $V_0$ Stokes parameter of the reflected
7511 optical wave, governing the optical intensity.}
7512 \varitem[{$|outfilename_v1|$}]{The $V_1$ Stokes parameter of the reflected
7513 optical wave, together with $V_2$ governing the orientation of the main
7514 axis of the polarization ellipse.}
7515 \varitem[{$|outfilename_v2|$}]{The $V_2$ Stokes parameter of the reflected
7516 optical wave, together with $V_1$ governing the orientation of the main
7517 axis of the polarization ellipse.}
7518 \varitem[{$|outfilename_v3|$}]{The $V_3$ Stokes parameter of the reflected
7519 optical wave, governing the polarization state ellipticity.}
7520 \varitem[{$|outfilename_w0|$}]{The $W_0$ Stokes parameter of the transmitted
7521 optical wave, governing the optical intensity.}
7522 \varitem[{$|outfilename_w1|$}]{The $W_1$ Stokes parameter of the transmitted
7523 optical wave, together with $W_2$ governing the orientation of the main
7524 axis of the polarization ellipse.}
7525 \varitem[{$|outfilename_w2|$}]{The $W_2$ Stokes parameter of the transmitted
7526 optical wave, together with $W_1$ governing the orientation of the main
7527 axis of the polarization ellipse.}
7528 \varitem[{$|outfilename_w3|$}]{The $W_3$ Stokes parameter of the transmitted
7529 optical wave, governing the polarization state ellipticity.}
7530 \medskip
7531 \noindent
7532 The reason for using separate files for the Stokes parameters is that
7533 in many cases sets or matrices of Stokes parameters will be generated
7534 for certain material or geometrical parameters, resulting in several different
7535 topological
7536 surfaces of, for example, transmitted intensity $W_0$ as function of
7537 input intensity $S_0$ and ellipticity $S_3/S_0$, in which case it is
7538 convenient to load separate Stokes parameters from separate files.
7539
7540 @<Open files for output@>=
7541 {
7542 if ((mme>1)&&(mmi>1)) {
7543 if ((fp_s0=fopen(outfilename_s0,"w"))==NULL) {
7544 fprintf(stderr,"%s: Could not open %s for saving incident wave!\n",
7545 progname,outfilename_s0);
7546 exit(FAILURE);
7547 }
7548 if ((fp_s1=fopen(outfilename_s1,"w"))==NULL) {
7549 fprintf(stderr,"%s: Could not open %s for saving incident wave!\n",
7550 progname,outfilename_s1);
7551 exit(FAILURE);
7552 }
7553 if ((fp_s2=fopen(outfilename_s2,"w"))==NULL) {
7554 fprintf(stderr,"%s: Could not open %s for saving incident wave!\n",
7555 progname,outfilename_s2);
7556 exit(FAILURE);
7557 }
7558 if ((fp_s3=fopen(outfilename_s3,"w"))==NULL) {
7559 fprintf(stderr,"%s: Could not open %s for saving incident wave!\n",
7560 progname,outfilename_s3);
7561 exit(FAILURE);
7562 }
7563 if ((fp_v0=fopen(outfilename_v0,"w"))==NULL) {
7564 fprintf(stderr,"%s: Could not open %s for saving reflected wave!\n",
7565 progname,outfilename_v0);
7566 exit(FAILURE);
7567 }
7568 if ((fp_v1=fopen(outfilename_v1,"w"))==NULL) {
7569 fprintf(stderr,"%s: Could not open %s for saving reflected wave!\n",
7570 progname,outfilename_v1);
7571 exit(FAILURE);
7572 }
7573 if ((fp_v2=fopen(outfilename_v2,"w"))==NULL) {
7574 fprintf(stderr,"%s: Could not open %s for saving reflected wave!\n",
7575 progname,outfilename_v2);
7576 exit(FAILURE);
7577 }
7578 if ((fp_v3=fopen(outfilename_v3,"w"))==NULL) {
7579 fprintf(stderr,"%s: Could not open %s for saving reflected wave!\n",
7580 progname,outfilename_v3);
7581 exit(FAILURE);
7582 }
7583 if ((fp_w0=fopen(outfilename_w0,"w"))==NULL) {
7584 fprintf(stderr,"%s: Could not open %s for saving transmitted wave!\n",
7585 progname,outfilename_w0);
7586 exit(FAILURE);
7587 }
7588 if ((fp_w1=fopen(outfilename_w1,"w"))==NULL) {
7589 fprintf(stderr,"%s: Could not open %s for saving transmitted wave!\n",
7590 progname,outfilename_w1);
7591 exit(FAILURE);
7592 }
7593 if ((fp_w2=fopen(outfilename_w2,"w"))==NULL) {
7594 fprintf(stderr,"%s: Could not open %s for saving transmitted wave!\n",
7595 progname,outfilename_w2);
7596 exit(FAILURE);
7597 }
7598 if ((fp_w3=fopen(outfilename_w3,"w"))==NULL) {
7599 fprintf(stderr,"%s: Could not open %s for saving transmitted wave!\n",
7600 progname,outfilename_w3);
7601 exit(FAILURE);
7602 }
7603 }
7604 if ((mme>1)&&(mmi>1)) {
7605 fseek(fp_s0,0L,SEEK_SET);
7606 fseek(fp_s1,0L,SEEK_SET);
7607 fseek(fp_s2,0L,SEEK_SET);
7608 fseek(fp_s3,0L,SEEK_SET);
7609 fseek(fp_v0,0L,SEEK_SET);
7610 fseek(fp_v1,0L,SEEK_SET);
7611 fseek(fp_v2,0L,SEEK_SET);
7612 fseek(fp_v3,0L,SEEK_SET);
7613 fseek(fp_w0,0L,SEEK_SET);
7614 fseek(fp_w1,0L,SEEK_SET);
7615 fseek(fp_w2,0L,SEEK_SET);
7616 fseek(fp_w3,0L,SEEK_SET);
7617 }
7618 if (fieldevoflag) {
7619 if (fieldevoflag_efield) {
7620 if(strcmp(fieldevofilename,"")) {
7621 if ((fp_evo=fopen(fieldevofilename,"w"))==NULL) {
7622 fprintf(stderr,
7623 "%s: Could not open file %s for fieldevo output!\n",
7624 progname,fieldevofilename);
7625 exit(FAILURE);
7626 }
7627 }
7628 } else if (fieldevoflag_stoke) {
7629 if(strcmp(fieldevofilename_s0,"")) {
7630 if ((fp_evo_s0=fopen(fieldevofilename_s0,"w"))==NULL) {
7631 fprintf(stderr,
7632 "%s: Could not open file %s for saving spatial S0"
7633 " distribution!\n",progname,fieldevofilename);
7634 exit(FAILURE);
7635 }
7636 } else {
7637 fprintf(stderr,
7638 "%s: A name for the file for saving spatial S0 distribution"
7639 " is required!\n",progname);
7640 exit(FAILURE);
7641 }
7642 if(strcmp(fieldevofilename_s1,"")) {
7643 if ((fp_evo_s1=fopen(fieldevofilename_s1,"w"))==NULL) {
7644 fprintf(stderr,
7645 "%s: Could not open file %s for saving spatial S1"
7646 " distribution!\n",progname,fieldevofilename);
7647 exit(FAILURE);
7648 }
7649 } else {
7650 fprintf(stderr,
7651 "%s: A name for the file for saving spatial S1 distribution"
7652 " is required!\n",progname);
7653 exit(FAILURE);
7654 }
7655 if(strcmp(fieldevofilename_s2,"")) {
7656 if ((fp_evo_s2=fopen(fieldevofilename_s2,"w"))==NULL) {
7657 fprintf(stderr,
7658 "%s: Could not open file %s for saving spatial S2"
7659 " distribution!\n",progname,fieldevofilename);
7660 exit(FAILURE);
7661 }
7662 } else {
7663 fprintf(stderr,
7664 "%s: A name for the file for saving spatial S2 distribution"
7665 " is required!\n",progname);
7666 exit(FAILURE);
7667 }
7668 if(strcmp(fieldevofilename_s3,"")) {
7669 if ((fp_evo_s3=fopen(fieldevofilename_s3,"w"))==NULL) {
7670 fprintf(stderr,
7671 "%s: Could not open file %s for saving spatial S3"
7672 " distribution!\n",progname,fieldevofilename);
7673 exit(FAILURE);
7674 }
7675 } else {
7676 fprintf(stderr,
7677 "%s: A name for the file for saving spatial S3 distribution"
7678 " is required!\n",progname);
7679 exit(FAILURE);
7680 }
7681 } else {
7682 fprintf(stderr,"%s: Unknown field evolution flag.\n",progname);
7683 exit(FAILURE);
7684 }
7685 }
7686 if (intensityevoflag) {
7687 if(strcmp(intensityevofilename,"")) {
7688 if ((fp_ievo=fopen(intensityevofilename,"w"))==NULL) {
7689 fprintf(stderr,
7690 "%s: Could not open file %s for intensityevo output!\n",
7691 progname,intensityevofilename);
7692 exit(FAILURE);
7693 }
7694 }
7695 }
7696 if (!((mme>1)&&(mmi>1))) {
7697 if ((fp_spec=fopen(spectrumfilename,"w"))==NULL) {
7698 fprintf(stderr,"%s: Could not open file %s for spectrum output!\n",
7699 progname,spectrumfilename);
7700 exit(FAILURE);
7701 }
7702 if ((fp_irspec=fopen(intensity_reflection_spectrumfilename,"w"))==NULL) {
7703 fprintf(stderr,
7704 "%s: Could not open %s for intensity reflection spectrum!\n",
7705 progname,intensity_reflection_spectrumfilename);
7706 exit(FAILURE);
7707 }
7708 if ((fp_itspec=fopen(intensity_transmission_spectrumfilename,"w"))==NULL) {
7709 fprintf(stderr,
7710 "%s: Could not open %s for intensity transmission spectrum!\n",
7711 progname,intensity_transmission_spectrumfilename);
7712 exit(FAILURE);
7713 }
7714 if ((fp_icspec=fopen(intensity_check_spectrumfilename,"w"))==NULL) {
7715 fprintf(stderr,
7716 "%s: Could not open %s for checking spectra!\n",
7717 progname,intensity_check_spectrumfilename);
7718 exit(FAILURE);
7719 }
7720 }
7721 }
7722
7723 @ Close all open files.
7724
7725 @<Close output files@>=
7726 {
7727 if ((mme>1)&&(mmi>1)) {
7728 fclose(fp_s0);
7729 fclose(fp_s1);
7730 fclose(fp_s2);
7731 fclose(fp_s3);
7732 fclose(fp_v0);
7733 fclose(fp_v1);
7734 fclose(fp_v2);
7735 fclose(fp_v3);
7736 fclose(fp_w0);
7737 fclose(fp_w1);
7738 fclose(fp_w2);
7739 fclose(fp_w3);
7740 }
7741 if (fieldevoflag) if(strcmp(fieldevofilename,"")) fclose(fp_evo);
7742 if (intensityevoflag) if(strcmp(intensityevofilename,"")) fclose(fp_ievo);
7743 if (!((mme>1)&&(mmi>1))) {
7744 fclose(fp_spec);
7745 fclose(fp_irspec);
7746 fclose(fp_itspec);
7747 fclose(fp_icspec);
7748 }
7749 }
7750
7751 @*References.
7752
7753 \refitem[1]{{F.\,Jonsson} and {C.\,Flytzanis}, {\sl Polarization
7754 State Controlled Multistability of a Nonlinear Magneto-optic Cavity},
7755 Phys. Rev. Lett. {\bf 82}, 1426 (1999).}
7756
7757 \refitem[2]{{F.\,Jonsson} and {C.\,Flytzanis}, {\sl Nonlinear Magneto-Optical
7758 Bragg Gratings}, Phys. Rev. Lett. {\bf 96}, 063902 (2006).}
7759
7760 \refitem[3]{Y.\thinspace{R.}~Shen, {\sl The Principles of Nonlinear Optics}
7761 (Wiley, New York, 1984), {ISBN\thinspace0-471-88998-9}.
7762
7763 \refitem[4]{A.\thinspace{K.}~Zvezdin and V.\thinspace{A.}~Kotov, {\sl Modern
7764 Magnetooptics and Magnetooptical Materials}, (In\-sti\-tute of Phy\-sics
7765 Pub\-lish\-ing, London, 1997), {ISBN\thinspace0-7503-0362-X}.}
7766
7767 \refitem[5]{{J.\thinspace{D.}~Jackson},
7768 {\sl Classical Electrodynamics}, 2nd Ed.~(Wiley, New York, 1975)
7769 {ISBN\thinspace0-471-43132-X}.}
7770
7771 \refitem[6]{{F.\,Jonsson} and {C.\,Flytzanis}, {\sl Optical amplitude and phase
7772 evolution in nonlinear magneto-optical Bragg gratings}, J.~Nonlin.~Opt.
7773 Physics and Materials {\bf 13}, 129 (2004).}
7774
7775 \refitem[7]{{F.\,Jonsson} and {C.\,Flytzanis}, {\sl Spectral windowing with
7776 chirped magneto-optical Bragg gratings}, {J.~Opt. Soc. Am. B} {\bf 22}, 293
7777 (2005).}
7778
7779 \refitem[8]{{F.\,Jonsson} and {C.\,Flytzanis}, {\sl Artificially Induced
7780 Perturbations in Chirped Magneto-Optical {Bragg} Gratings}, in
7781 {\sl Magneto-Optical Materials for Photonics and Recording}, Eds.~{Koji Ando,
7782 W. Challener, R. Gambino and M. Levy}, Mater. Res. Soc. Symp. Proc. {\bf 834},
7783 J1.8 ({Materials Research Society}, {Warrendale}, 2005).}
7784
7785 \refitem[9]{{F.\,Jonsson}, {\sl The Nonlinear Optics of Magneto-Optic Media},
7786 PhD Thesis (Royal Institute of Technology, Stockholm, 2000),
7787 {ISBN\thinspace91-7170-575-9}.}
7788
7789 \refitem[10]{P.~N. Butcher and D. Cotter, {\sl The Elements of Nonlinear
7790 Optics} (Cambridge University Press, New York, 1990),
7791 {ISBN\thinspace0-521-42424-0}.}
7792
7793 \refitem[11]{E.~T.~Whittaker, {\sl A Course of Modern Analysis--An Introduction
7794 to the General Theory of Infinite Processes and of Analytic Functions; With
7795 an Account of the Principal Transcendental Functions}, 1st Edn.
7796 (Cambridge University Press, Cambridge, 1902).}
7797
7798 \refitem[12]{E.~T.~Whittaker and G.~N.~Watson, {\sl A Course of Modern
7799 Analysis--An Introduction to the General Theory of Infinite Processes and
7800 of Analytic Functions; With an Account of the Principal Transcendental
7801 Functions}, 4th Reprinted Edn. (Cambridge University Press, Cambridge, 1996),
7802 ISBN 0-521-58807-3.}
7803
7804 \refitem[13]{P.~F. Byrd and M.~D. Friedman, {\sl Handbook of Elliptic Integrals
7805 for Engineers and Scientists}, 2nd Edn. (Springer--Verlag, Berlin, 1971),
7806 ISBN 3-540-05318-2.}
7807
7808 \refitem[14]{M.~McCall, J.~Light\-wave Technol.~{\bf 18}, 236 (2000).}
7809
7810 \refitem[15]{A.~Othonos and K.~Kalli, {\sl Fiber {Bragg} Gratings}
7811 (Artech House, Boston, 1999), ISBN\thinspace0-89006-344-3.}
7812
7813 @*Index.
7814
Generated by ::viewsrc::