source: documentation/user_manual/anuga_user_manual.tex @ 2422

Last change on this file since 2422 was 2422, checked in by steve, 19 years ago

Picked a few typos in user_manual

  • Property svn:keywords set to LastChangedDate LastChangedRevision LastChangedBy HeadURL Id
File size: 24.7 KB
Line 
1% Complete documentation on the extended LaTeX markup used for Python
2% documentation is available in ``Documenting Python'', which is part
3% of the standard documentation for Python.  It may be found online
4% at:
5%
6%     http://www.python.org/doc/current/doc/doc.html
7
8
9\input{definitions}
10
11
12\documentclass{manual}
13
14\title{\anuga User Manual}
15\author{Howard Silcock, Ole Nielsen, Duncan Gray, Jane Sexton}
16
17% Please at least include a long-lived email address;
18% the rest is at your discretion.
19\authoraddress{Geoscience Australia \\
20  Email: \email{ole.nielsen@ga.gov.au}
21}
22
23%Draft date
24\date{\today}                   % update before release!
25                % Use an explicit date so that reformatting
26                % doesn't cause a new date to be used.  Setting
27                % the date to \today can be used during draft
28                % stages to make it easier to handle versions.
29
30\release{1.0}           % release version; this is used to define the
31                % \version macro
32
33\makeindex          % tell \index to actually write the .idx file
34%\makemodindex          % If this contains a lot of module sections.
35
36
37
38\begin{document}
39\maketitle
40
41% This makes the contents more accessible from the front page of the HTML.
42\ifhtml
43\chapter*{Front Matter\label{front}}
44\fi
45
46%Subversion keywords:
47%
48%$LastChangedDate: 2006-02-16 09:29:56 +0000 (Thu, 16 Feb 2006) $
49%$LastChangedRevision: 2422 $
50%$LastChangedBy: steve $
51
52\input{copyright}
53
54
55\begin{abstract}
56
57\noindent
58\anuga\index{AnuGA} is a hydrodynamic modelling tool that
59allows users to model realistic flow problems in complex
60geometries. Examples include dam breaks or the effects of natural
61hazards such as riverine flooding, storm surges and tsunami.
62
63The user must specify a study area represented by a mesh of triangular
64cells, the topography and bathymetry, frictional resistance, initial
65values for water level (called \emph{stage}\index{stage} within \anuga),
66boundary
67conditions and forces such as windstress or pressure gradients if
68applicable.
69
70\anuga tracks the evolution of water depth and horizontal momentum
71within each cell over time by solving the shallow water wave equation
72governing equation using a finite-volume method.
73
74\anuga cannot model details of breaking waves, flow under ceilings such
75as pipes, turbulence and vortices, vertical convection or viscous
76flows.
77
78\anuga also incorporates a mesh generator, called \code{pmesh}, that
79allows the user to set up the geometry of the problem interactively as
80well as tools for interpolation and surface fitting, and a number of
81auxiliary tools for visualising and interrogating the model output.
82
83Most \anuga components are written in the object-oriented programming
84language Python and most users will interact with Anuga by writing
85small Python programs based on the \anuga library
86functions. Computationally intensive components are written for
87efficiency in C routines working directly with the Numerical Python
88structures.
89
90
91\end{abstract}
92
93\tableofcontents
94
95
96\chapter{Introduction}
97
98
99\section{Purpose}
100
101The purpose of this user manual is to introduce the new user to
102the software, describe what it can do and give step-by-step
103instructions for setting up, configuring and running the software.
104
105\section{Scope}
106
107This manual covers only what is needed to operate the software
108after installation. It does not includes instructions for
109installing the software or detailed API documentation, both of
110which will be covered in separate publications.
111
112\section{Audience}
113
114Readers are assumed to be familiar with the operating environment
115and have a general understanding of the problem background, as
116well as enough programming experience to adapt the code to
117different requirements, as described in this manual,  and to
118understand the basic terminology of object-oriented programming.
119
120\section{Structure of This Manual}
121
122This manual is structured as follows:
123
124\begin{itemize}
125  \item Background (What \anuga does)
126  \item A \emph{Getting Started} section
127  \item Anuga's overall architecture, components and file formats
128  \item Detailed descriptions of the user interface
129\end{itemize}
130
131
132\pagebreak
133\chapter{Getting Started}
134
135This section is designed to assist the reader to get started with
136\anuga by working through a simple example. What follows
137is a discussion of the structure and operation of the file
138\code{bedslope.py}, with just enough detail to allow the reader
139to appreciate what's involved in setting up a scenario like the
140one it depicts.
141
142\section{Overview}
143
144This example carries out the solution of the shallow-water wave
145equation in the simple case of a configuration comprising a flat
146bed, sloping at a fixed angle in one direction and having a
147constant depth across each line in the perpendicular direction.
148
149The example demonstrates many of the basic ideas involved in
150setting up a more complex scenario. In the general case the user
151specifies the geometry (bathymetry and topography), the initial
152water level, boundary conditions such as tide, and any forcing
153terms that may drive the system such as wind stress or atmospheric
154pressure gradients. Frictional resistance from the different
155terrains in the model is represented by predefined forcing
156terms. The boundary is reflective on three sides and a time dependent wave on one side.
157
158The present example, as it represents a simple scenario, does not
159include any forcing term, nor is the data taken from a file as it
160would be in many typical cases. The quantities involved in the
161present problem are:
162\begin{itemize}
163   \item elevation\index{elevation}
164   \item friction\index{friction}
165   \item depth\index{depth}
166   \item stage\index{stage}
167\end{itemize}
168
169%\emph{[More details of the problem background]}
170
171\section{Outline of the Program}
172
173In outline, \code{bedslope.py} performs the following steps:
174
175\begin{enumerate}
176
177   \item Sets up a triangular mesh.
178
179   \item Sets certain parameters governing the mode of
180operation of the model-specifying, for instance, where to store the model output.
181
182
183   \item Inputs various quantities describing physical measurements, such
184as the elevation, to be specified at each mesh point (vertex).
185
186   \item Sets up the boundary conditions.
187
188   \item Carries out the evolution of the model through a series of time
189steps and outputs the results, providing a results file that can
190be visualised.
191
192\end{enumerate}
193
194\section{The Code}
195
196%FIXME: we are using the \code function here.
197%This should be used whereever possible
198For reference we include below the complete code listing for
199\code{bedslope.py}. Subsequent paragraphs provide a `commentary'
200that describes each step of the program and explains it significance.
201
202
203{\scriptsize \begin{verbatim}
204from pyvolution.mesh_factory import rectangular
205from pyvolution.shallow_water import Domain, Reflective_boundary,
206     Dirichlet_boundary, Time_boundary, Transmissive_boundary
207
208#Create basic mesh
209points, vertices, boundary = rectangular(10,10)
210
211#Create shallow water domain
212domain = Domain(points, vertices,boundary)
213domain.set_name('bedslope')
214
215
216#######################
217# Initial conditions
218def f(x,y):
219    return -x/2
220
221domain.set_quantity('elevation', f)
222domain.set_quantity('friction', 0.1)
223
224h = 0.05  # Constant depth
225domain.set_quantity('stage', expression = 'elevation + %f' %h)
226
227
228# Boundary conditions
229from math import sin, pi
230Br = Reflective_boundary(domain)
231Bt = Transmissive_boundary(domain)
232Bd = Dirichlet_boundary([0.2,0.,0.])
233
234Bw = Time_boundary(domain=domain,
235                   f=lambda t: [(0.1*sin(t*2*pi)), 0.0, 0.0])
236
237
238domain.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
239
240
241######################
242#Evolution
243
244domain.check_integrity()
245
246for t in domain.evolve(yieldstep = 0.1, finaltime = 4.0):
247    domain.write_time()
248
249
250\end{verbatim}}
251
252
253\section{Establishing the Mesh}
254
255The first task is to set up the triangular mesh to be used for the
256scenario. This is carried out through the statement:
257
258{\small \begin{verbatim}
259    points, vertices, boundary = rectangular(10, 10)
260\end{verbatim}}
261
262The function \code{rectangular} is imported from a module
263\code{mesh\_factory} defined elsewhere. \anuga also
264contains several other schemes that can be used for setting up
265meshes, but we shall not discuss these now.) The above assignment
266sets up a $10 \times 10$ rectangular mesh, triangulated in a
267specific way. In general, the assignment
268
269{\small \begin{verbatim}
270    points, vertices, boundary = rectangular(m, n)
271\end{verbatim}}
272
273returns:
274
275\begin{itemize}
276
277   \item a list \code{points} of length $N$, where $N = (m + 1)(n + 1)$,
278comprising the coordinates $(x, y)$ of each of the $N$ mesh
279points,
280
281   \item a list \code{vertices} of length $2mn$ (each entry specifies the three
282vertices of one of the triangles used in the triangulation) , and
283
284   \item a dictionary \code{boundary}, used to tag the triangle edges on
285the boundaries. Each key corresponds to a triangle edge on one of
286the four boundaries and its value is one of \code{`left'},
287\code{`right'}, \code{`top'} and \code{`bottom'}, indicating
288which boundary the edge in question belongs to.
289
290\end{itemize}
291
292
293\section{Initialising the domain}
294
295These variables are then used to set up a data structure
296\code{domain}, through the assignment:
297
298{\small \begin{verbatim}
299    domain = Domain(points, vertices, boundary)
300\end{verbatim}}
301
302This uses a Python class \code{Domain}, imported from
303\code{shallow\_water}, which is an extension of a more generic
304class of the same name in the module \code{domain}, and inherits
305some methods from the generic class but has others specific to the
306shallow-water scenarios in which it is used. Specific options for domain
307are set at this point. One of them are to set the basename for the output file
308
309{\scriptsize \begin{verbatim}
310    domain.set_name('bedslope')
311\end{verbatim}}
312
313
314\section{Specifying the Quantities}
315
316The next task is to specify a number of quantities that we wish to set
317for each mesh point. The class \code{Domain} has a method
318\code{set\_quantity}, used to specify these quantities. It is a
319particularly flexible method that allows the user to set quantities in
320a variety of ways---using constants, functions, numeric arrays or
321expressions involving other quantities, arbitrary data points with
322associated values, all of which can be passed as arguments. All
323quantities can be initialised using \code{set\_quantity}. For
324conserved quantities (\code{stage, xmomentum, ymomentum}) this is
325called the \emph{initial condition}, for other quantities that aren't
326updated by the equation, the same interface is used to assign their
327values. The code in the present example demonstrates a number of forms
328in which we can invoke \code{set\_quantity}.
329
330
331\subsection{Elevation}
332
333The elevation is set using a function, defined through the
334statements below, which is specific to this example and specifies
335a particularly simple initial configuration for demonstration
336purposes:
337
338{\small \begin{verbatim}
339    def f(x,y):
340        return -x/2
341\end{verbatim}}
342
343This simply associates an elevation with each point $(x, y)$ of
344the plane.  It specifies that the bed slopes linearly in the $x$
345direction, with slope $-\frac{1}{2}$,  and is constant in the $y$
346direction.\\ %[screen shot?]
347\\
348Once the function $f$ is specified, the quantity
349\code{elevation} is assigned through the simple statement:
350
351{\small \begin{verbatim}
352    domain.set_quantity('elevation', f)
353\end{verbatim}}
354
355
356\subsection{Friction}
357
358The assignment of the friction quantity demonstrates another way
359we can use \code{set\_quantity} to set quantities---namely,
360assign them to a constant numerical value:
361
362{\small \begin{verbatim}
363    domain.set_quantity('friction', 0.1)
364\end{verbatim}}
365
366This just specifies that the Manning friction coefficient is set
367to 0.1 at every mesh point.
368
369\subsection{Depth}
370
371Assigning depth illustrates a more complex way to use
372\code{set\_quantity}, introducing an expression involving other
373quantities:
374
375{\small \begin{verbatim}
376    h = 0.05 \# Constant depth
377    domain.set_quantity('stage', expression = 'elevation + %f' %h)
378\end{verbatim}}
379
380Here the quantity \code{stage} is defined by taking the quantity
381elevation already defined and adding a constant value $h = 0.05$
382to it everywhere. This expresses the fact that the water depth is
383everywhere constant, so the surface is a constant height above the
384elevation of the bed.
385
386\subsection{Boundary Conditions}
387
388The boundary conditions are specified as follows:
389
390{\small \begin{verbatim}
391    Br = Reflective_boundary(domain)
392
393    Bt = Transmissive_boundary(domain)
394
395    Bd = Dirichlet_boundary([0.2,0.,0.])
396
397    Bw = Time_boundary(domain=domain,
398                f=lambda t: [(0.1*sin(t*2*pi)), 0.0, 0.0])
399\end{verbatim}}
400
401The effect of these statements is to set up four alternative
402boundary conditions and store them in variables that can be
403assigned as needed. Each boundary condition specifies the
404behaviour at a boundary in terms of the behaviour in neighbouring
405elements. The boundary conditions may be briefly described as
406follows:
407
408\begin{description}
409    \item[Reflective boundary] Returns same \code{stage} as
410    as present in its neighbour volume but momentum vector reversed 180 degrees (reflected).
411    Specific to the shallow water equation as it works with the
412    momentum quantities assumed to be the second and third conserved
413    quantities.
414    \item[Transmissive boundary]Returns same conserved quantities as
415    those present in its neighbour volume.
416    \item[Dirichlet boundary]Specifies a fixed value at the
417boundary.
418    \item[Time boundary.]A Dirichlet boundary whose behaviour varies with time.
419\end{description}
420
421Once the four boundary types have been specified through the
422statements above, they can be applied through a statement of the
423form
424
425{\small \begin{verbatim}
426    domain.set_boundary({'left': Bd, 'right': Br, 'top': Br, 'bottom': Br})
427\end{verbatim}}
428
429This statement stipulates that, in the current example, the left
430boundary is fixed, with an elevation of 0.2, while the other
431boundaries are all reflective.
432
433
434\section{Evolution}
435
436The final statement \nopagebreak[3]
437{\small \begin{verbatim}
438    for t in domain.evolve(yieldstep = 0.1, finaltime = 4.0):
439        domain.write_time()
440\end{verbatim}}
441
442is the key step that causes the configuration of the domain to
443`evolve' in accordance with the model embodied in the code, over a
444series of steps indicated by the values of \code{yieldstep} and
445\code{finaltime}, which can be altered as required.
446The yieldstep control the time interval between model output. Behind the scenes more timesteps are generally taken.
447
448
449
450
451\section{Output}
452
453%Give details here of the form of the output and explain how it can
454%be used with swollen. Include screen shots.//
455
456The output is a NetCDF file with the extension \code{.sww}. It
457contains stage and momentum information and can be used with the
458\code{swollen} visualisation package to generate a visual display.
459
460
461\section{How to Run the Code}
462
463The code can be run in various ways:
464
465\begin{itemize}
466\item{from a Windows command line} as in \code{python bedslope.py}
467
468\item{within the Python IDLE environment}
469
470\item{within emacs}
471
472\item{from a Linux command line} as in \code{python bedslope.py}
473\end{itemize}
474
475
476\section{Example with real data}
477
478The following discussion builds on the \code{bedslope.py} example and
479shows how, using the same basic outline, we can incorporate many more
480complex features.
481
482The chief difference is in the method used to create the mesh. Instead of imposing a mesh
483structure on a rectangular grid, the technique used for this example involves building
484mesh structures inside polygons.
485
486In its simplest form, the mesh is created within a single polygon
487whose vertices are at geographical locations specified by the user.  A
488triangular mesh is created using points inside the polygon selected
489through a random process, the user specifying the
490\emph{resolution}---that is, the maximal area of a triangle used for
491triangulation.
492
493Figure XXX shows a simple example, in which the triangulation is
494carried out within a pentagon. Instead of using the four tags
495\code{`left'}, \code{`right'}, \code{`bottom'} and
496\code{`top'} to distinguish boundary elements, the user can define
497tags appropriate to the configuration being modelled.
498
499While this offers more flexibility than the rectangular grid, it
500doesn't provide a way to adapt to geographic or other features in the
501landscape, for which we may require to vary the resolution. We achieve
502more flexibility by extending this method, allowing the user to
503specify a number of interior polygons which are triangulated
504separately, possibly using different resolutions.  See Figure XXX.
505
506
507\chapter{ANUGA Public Interface}
508
509thoaedut
510
511
512
513\begin{itemize}
514
515  \item \indexedcode{create_mesh_from_region}: Create mesh based on a bounding polygon and a number of internal polygons. Each polygon has a maximal area of triangles associated with it - the resolution. The bounding polygon also has symbolic \code{tags} associated with it.
516  Arguments are:
517  \item \indexedcode{pmesh_to_domain_instance}: Convert generated mesh file to domain object. Arguments are: Mesh file name and class specifying which domain class to instantiate. (Simpler)
518
519  \item \indexedcode{file_function} %in util.py "High priority"
520  \item \indexedcode{Interpolation_function} %In least_squares.py ("High priority")
521
522  \item \indexedcode{set_region} ``Low priority. Will be merged into set\_quantity''
523  \item \indexedcode{set_quantity} ``Pretty mature''
524  \item \indexedcode{set_boundary} ``Pretty mature''
525
526\end{itemize}
527
528
529Diagnostics
530\begin{itemize}
531  \item \indexedcode{write_time}
532  \item \indexedcode{write_boundary_statistics}
533
534
535\end{itemize}
536
537
538\subsection{Boundary conditions}
539
540ANUGA provides a large number of predefined boundary conditions to be used with
541\code{set_boundary}
542
543What do they do
544How are they used
545
546\begin{itemize}
547  \item \indexedcode{Reflective_boundary}
548  function, arguments
549
550  \item \indexedcode{Transmissive_boundary}
551  function, arguments, CAVEATS
552
553  \item \indexedcode{Dirichlet_boundary}
554
555  \item \indexedcode{Time_boundary}
556
557  \item \indexedcode{File_boundary}
558  Based on File\_function
559
560  \item \indexedcode{}
561
562  \item \indexedcode{}
563
564
565  \item \indexedcode{User defined boundary conditions.}
566  How to roll your own
567
568
569
570\end{itemize}
571
572
573
574\subsection{Initial conditions}
575
576ANUGA provides a number of predefined initial conditions to be used with
577\code{set_quantity}.
578
579\begin{itemize}
580
581
582  \item \indexedcode{tsunami_slump}
583  function, arguments
584
585  \item \indexedcode{}
586
587\end{itemize}
588
589
590\subsection{Initial conditions}
591
592ANUGA provides a number of predefined forcing functions to be used with .....
593
594\begin{itemize}
595
596
597  \item \indexedcode{}
598  function, arguments
599
600  \item \indexedcode{}
601
602\end{itemize}
603
604
605
606
607\chapter{ANUGA system architecture}
608
609From pyvolution/documentation
610
611
612
613\chapter{Basic ANUGA assumptions}
614
615(From pyvolution/documentation)
616
617
618Physical model time cannot be earlier than 1 Jan 1970 00:00:00.
619If one wished to recreate scenarios prior to that date it must be done
620using some relative time (e.g. 0).
621
622
623All spatial data relates to the WGS84 datum (or GDA94) and has been
624projected into UTM with false easting of 500000 and false northing of
6251000000 on the southern hemisphere (0 on the northern).
626
627It is assumed that all computations take place within one UTM zone.
628
629DEMs, meshes and boundary conditions can have different origins within
630one UTM zone. However, the computation will use that of the mesh for
631numerical stability.
632
633
634%OLD
635%The dataflow is: (See data_manager.py and from scenarios)
636%
637%
638%Simulation scenarios
639%--------------------%
640%%
641%
642%Sub directories contain scrips and derived files for each simulation.
643%The directory ../source_data contains large source files such as
644%DEMs provided externally as well as MOST tsunami simulations to be used
645%as boundary conditions.
646%
647%Manual steps are:
648%  Creation of DEMs from argcview (.asc + .prj)
649%  Creation of mesh from pmesh (.tsh)
650%  Creation of tsunami simulations from MOST (.nc)
651%%
652%
653%Typical scripted steps are%
654%
655%  prepare_dem.py:  Convert asc and prj files supplied by arcview to
656%                   native dem and pts formats%
657%
658%  prepare_pts.py: Convert netcdf output from MOST to an sww file suitable
659%                  as boundary condition%
660%
661%  prepare_mesh.py: Merge DEM (pts) and mesh (tsh) using least squares
662%                   smoothing. The outputs are tsh files with elevation data.%
663%
664%  run_simulation.py: Use the above together with various parameters to
665%                     run inundation simluation.
666
667
668
669
670\appendix
671
672\chapter{Supporting tools}
673
674
675\section{caching} Could do now.
676
677
678
679\section{swollen} Could do now.
680
681
682\section{utilities/polygons} Could do now.
683
684\begin{itemize}
685  \item \indexedcode{polygon_function}
686  \item \indexedcode{read_polygon}
687  \item \indexedcode{populate_polygon}
688  \item \indexedcode{point_in_polygon}
689  \item \indexedcode{inside_polygon}
690  \item \indexedcode{outside_polygon}
691  \item \indexedcode{point_on_line}
692  \item \indexedcode{separate_points_by_polygon}
693\end{itemize}
694
695
696
697
698
699\section{coordinate_transforms}
700
701\section{geo_spatial_data}
702
703\section{pmesh GUI}
704
705\section{alpha_shape}
706
707
708\section{utilities/numerical_tools} Could do now.
709
710\begin{itemize}
711  \item \indexedcode{ensure_numeric}
712  \item \indexedcode{mean}
713  \item
714\end{itemize}
715
716\chapter{Glossary}
717
718\begin{itemize}
719    \item \indexedbold{ANUGA} name of software (joint development between ANU and GA)
720
721    \item \indexedbold{Conserved quantity}
722
723    \item \indexedbold{Default order} is this really needed?
724
725    \item \indexedbold{Domain}
726
727    \item \indexedbold{Dirichlet boundary}
728
729    \item \indexedbold{Elevation} - refers to bathymetry and topography
730
731    \item \indexedbold{bathymetry} offshore
732
733    \item \indexedbold{topography} onshore
734
735    \item \indexedbold{Evolution} integration of the shallow water wave equations over time
736
737    \item \indexedbold{Forcing term}
738
739    \item \indexedbold{IDLE} development environment shipped with Python
740
741    \item \indexedbold{Manning friction coefficient}
742
743    \item \indexedbold{Mesh}    triangulation of domain
744
745    \item \indexedbold{Grid} evenly spaced
746
747    \item \indexedbold{NetCDF}
748
749    \item \indexedbold{pmesh} does this really need to be here? it's a class/module?
750
751    \item \indexedbold{pyvolution} does this really need to be here? it's a class/module?
752
753    \item \indexedbold{Quantity} conserved (state, x and y momentum)
754
755    \item \indexedbold{Reflective boundary}
756
757    \item \indexedbold{Smoothing} is this really needed?
758
759    \item \indexedbold{Stage}
760
761    \item \indexedbold{Swollen} visualisation tool
762
763    \item \indexedbold{Time boundary} defined in the manual (flog from there)
764
765    \item \indexedbold{Transmissive boundary} defined in the manual (flog from there)
766
767    \item \indexedbold{xmomentum} conserved quantity (note, two-dimensional SWW equations say only x and y and NOT z)
768
769    \item \indexedbold{ymomentum}  conserved quantity
770
771    \item \indexedbold{resolution}   refers to the maximal area of each triangular cell in the mesh
772
773    \item \indexedbold{polygon} A sequence of points in the plane. (Arbitrary polygons can be created in this way )
774    ANUGA represents polygons as either a list of 2-tuples, where the latter are either Python tuples or Python lists of length 2. The unit square, for example, would be represented by the polygon [ [0,0], [1,0], [1,1], [0,1] ]. Alternatively, polygons can be represented as $N \times 2$ Numeric arrays, where $N$ is the number of points.
775
776    NOTE: More can be read in the module utilities/polygon.py ....
777
778    \item \indexedbold{easting}
779
780    \item \indexedbold{northing}
781
782    \item \indexedbold{latitude}
783
784    \item \indexedbold{longitude}
785
786    \item \indexedbold{edge}
787
788    \item \indexedbold{vertex}
789
790    \item \indexedbold{finite volume}
791
792    \item \indexedbold{flux}
793
794    \item \indexedbold{Digital Elevation Model (DEM)}
795
796
797\end{itemize}
798
799The \code{\e appendix} markup need not be repeated for additional
800appendices.
801
802
803%
804%  The ugly "%begin{latexonly}" pseudo-environments are really just to
805%  keep LaTeX2HTML quiet during the \renewcommand{} macros; they're
806%  not really valuable.
807%
808%  If you don't want the Module Index, you can remove all of this up
809%  until the second \input line.
810%
811
812%begin{latexonly}
813%\renewcommand{\indexname}{Module Index}
814%end{latexonly}
815%\input{mod\jobname.ind}        % Module Index
816
817%begin{latexonly}
818\renewcommand{\indexname}{Index}
819%end{latexonly}
820\input{\jobname.ind}            % Index
821
822
823
824\end{document}
Note: See TracBrowser for help on using the repository browser.