diff --git a/.gitmodules b/.gitmodules index cb86c78b46bdff327233025966aff72d29689346..cb766b513364c6baf7795156248b958c1f61669f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,3 +3,8 @@ path = docs/tutorial url = git@gitlab.nektar.info:nektar/tutorial ignore = all +[submodule "docs/developer-guide"] + branch = master + path = docs/developer-guide + url = git@gitlab.nektar.info:nektar/developer-guide + ignore = all diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ead3eeb88c6acbdca168a1e03b340d40fe4986b..bf565655d08b048112de1c14be4d58b773455a6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,21 @@ Changelog ========= +v4.5.0 +------ +**NekMesh**: +- Add periodic boundary condition meshing in 2D (!733) +- Adjust boundary layer thickness in corners in 2D (!739) +- Rework meshing control so that if possible viewable meshes will be dumped + when some part of the system fails (!756) +- Add manifold meshing option (!756) + +**Documentation**: +- Added the developer-guide repository as a submodule (!751) + +**Library** +- Remove the duplicate output of errorutil (!756) + v4.4.0 ------ **Library**: @@ -100,9 +115,9 @@ v4.4.0 - Change variable names in mcf file to make more sense (!736) - Fix issues in varopti module so that in can be compiled without meshgen on (!736) -- Replace LAPACK Eigenvalue calculation with handwritten function in +- Replace LAPACK Eigenvalue calculation with handwritten function in varopti (!738) -- Improved node-colouring algorithm for better load-balancing +- Improved node-colouring algorithm for better load-balancing in varopti (!738) - Simplified calculation of the energy functional in varopti for improved performance (!738) diff --git a/VERSION b/VERSION index fdc6698807a92654177d5679fe2de81be0c17dd4..a84947d6ffe7bdf361dfd679a8e931b44f0e9001 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.4.0 +4.5.0 diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 25a41388486594e1577e0874d288ba79194d769a..c13b168ce38baeee88368932ed79fa8245562204 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -1,5 +1,8 @@ ADD_SUBDIRECTORY(user-guide) -ADD_SUBDIRECTORY(developer-guide) + +IF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/developer-guide/CMakeLists.txt) + ADD_SUBDIRECTORY(developer-guide) +ENDIF () IF (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tutorial/CMakeLists.txt) ADD_SUBDIRECTORY(tutorial) diff --git a/docs/developer-guide b/docs/developer-guide new file mode 160000 index 0000000000000000000000000000000000000000..e128cfaffbbd37c734a667cdc2a07b6f06291615 --- /dev/null +++ b/docs/developer-guide @@ -0,0 +1 @@ +Subproject commit e128cfaffbbd37c734a667cdc2a07b6f06291615 diff --git a/docs/developer-guide/CMakeLists.txt b/docs/developer-guide/CMakeLists.txt deleted file mode 100644 index b679a6bc11fdcc67a82ccf4b668010711c0072a4..0000000000000000000000000000000000000000 --- a/docs/developer-guide/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -SET(DEVGUIDESRC ${CMAKE_CURRENT_SOURCE_DIR}) -SET(DEVGUIDE ${CMAKE_BINARY_DIR}/docs/developer-guide) - -FILE(MAKE_DIRECTORY ${DEVGUIDE}/html) - -FIND_PROGRAM(HTLATEX htlatex) -ADD_CUSTOM_TARGET(developer-guide-html - export TEXINPUTS=${CMAKE_SOURCE_DIR}//:${DEVGUIDESRC}//: && - ${HTLATEX} ${DEVGUIDESRC}/developer-guide.tex - "${DEVGUIDESRC}/styling.cfg,html,3,next,NoFonts" - WORKING_DIRECTORY ${DEVGUIDE}/html -) - -# If tex4ht successful, create img dir and copy images across -FILE(GLOB_RECURSE imgfiles "img/*.png" "img/*.jpg" "*/img/*.png" "*/img/*.jpg") -ADD_CUSTOM_COMMAND(TARGET developer-guide-html - POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${DEVGUIDE}/html/img) -FOREACH(img ${imgfiles}) - ADD_CUSTOM_COMMAND(TARGET developer-guide-html - POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${img} ${DEVGUIDE}/html/img) -ENDFOREACH() - -FILE(GLOB_RECURSE pdffiles "*/img/*.pdf") -FIND_PROGRAM(CONVERT convert) -FOREACH(pdf ${pdffiles}) - GET_FILENAME_COMPONENT(BASENAME ${pdf} NAME_WE) - ADD_CUSTOM_COMMAND(TARGET developer-guide-html - POST_BUILD COMMAND - ${CONVERT} ${pdf} ${DEVGUIDE}/html/img/${BASENAME}.png) -ENDFOREACH() - -FIND_PROGRAM(PDFLATEX pdflatex) -FIND_PROGRAM(BIBTEX bibtex) -FIND_PROGRAM(MAKEINDEX makeindex) -ADD_CUSTOM_TARGET(developer-guide-pdf - export TEXINPUTS=${CMAKE_SOURCE_DIR}//: && - ${PDFLATEX} --output-directory ${DEVGUIDE} ${DEVGUIDESRC}/developer-guide.tex - COMMAND TEXMFOUTPUT=${DEVGUIDE} ${BIBTEX} ${DEVGUIDE}/developer-guide.aux - COMMAND TEXMFOUTPUT=${DEVGUIDE} ${MAKEINDEX} ${DEVGUIDE}/developer-guide.idx - COMMAND export TEXINPUTS=${CMAKE_SOURCE_DIR}//: && - ${PDFLATEX} --output-directory ${DEVGUIDE} ${DEVGUIDESRC}/developer-guide.tex - WORKING_DIRECTORY ${DEVGUIDESRC} -) diff --git a/docs/developer-guide/coding-standard/coding-standard.tex b/docs/developer-guide/coding-standard/coding-standard.tex deleted file mode 100644 index 71d8d4c6785ed570735598ed974ed2cdb67274f6..0000000000000000000000000000000000000000 --- a/docs/developer-guide/coding-standard/coding-standard.tex +++ /dev/null @@ -1,145 +0,0 @@ -\chapter{Coding Standard} - -The purpose of this page is to detail the coding standards of the project which -all contributers are requested to follow. - -This page describes the coding style standard for C++. A coding style standard -defines the visual layout of source code. Presenting source code in a uniform -fashion facilitates the use of code by different developers. In addition, -following a standard prevents certain types of coding errors. - -All of the items below, unless otherwise noted, are guidelines. They are -recommendations about how to lay out a given block of code. Use common sense and -provide comments to describe any deviation from the standard. Sometimes, -violating a guideline may actually improve readability. - -If you are working with code that does not follow the standard, bring the code -up-to-date or follow the existing style. Don’t mix styles. - -\section{Code Layout} - -The aim here is to maximise readability on all platforms and editors. -\begin{itemize} -\item Code width of 80 characters maximum - hard-wrap longer lines. -\item Use sensible wrapping for long statements in a way which maximises -readability. -\item Do not put multiple statements on the same line. -\item Do not declare multiple variables on the same line. -\item Provide a default value on all variable declarations. -\item Enclose every program block (if, else, for, while, etc) in braces, even if -empty or just a single line. -\item Opening braces (\{) should be on their own line. -\item Braces at same indentation as preceeding statement. -\item One class per .cpp and .h file only, unless nested. -\item Define member functions in the .cpp file in the same order as defined in -the .h file. -\item Templated classes defined and implemented in a single .hpp file. -\item Do not put inline functions in the header file unless the function is -trivial (e.g. accessor, empty destructor), or profiling explicitly suggests to. -\item Inline functions should be declared within the class declaration but -defined outside the class declaration at the bottom of the header file. -\begin{notebox} -Virtual and inline are mutually exclusive. Virtual functions should therefore be -implemented in the .cpp file. -\end{notebox} -\end{itemize} - - -\section{Space} - -Adding an appropriate amount of white space enhances readability. Too much white -space, on the other hand, detracts from that readability. - -\begin{itemize} -\item Indent using a four-space tab. Consistent tab spacing is necessary to -maintain formatting. Note that this means when a tab is pressed, four physical spaces are -inserted into the source instead. -\item Put a blank line at the end of a public/protected/private block. -\item Put a blank line at the end of every file. -\item Put a space after every keyword (if, while, for, etc.). -\item Put a space after every comma, unless the comma is at the end of the line. -\item Do not put a space before the opening parenthesis of an argument list to a -function. -\item Declare pointers and references with the * or \& symbol next to the -declarator, not the type; e.g., Object *object. Do not put multiple variables in the same -declaration. -\item Place a space on both sides of a binary operator. -\item Do not use a space to separate a unary operator from its operand. -\item Place open and close braces on their own line. No executable statements -should appear on the line with the brace, but comments are allowed. Indent opening -braces at the same level as the statement above and indent the closing brace at -the same level as the corresponding opening brace. -\item Indent all statements following an open brace by one tab. Developer Studio -puts any specifier terminated with a colon at the same indentation level as the -enclosing brace. Examples of such specifiers include case statements, access -specifiers (public, private, protected), and goto labels. This is not acceptable -and should be manually corrected so that all statements appearing within a block -and delineated by braces are indented. -\item Break a line into multiple lines when it becomes too long to read. Use at -least two tabs to start the new line, so it does not look like the start of a -block. -\item Follow C++ style comments with one space. It is also preferable to -consider any text that follows C++ style comments as a sentence and to begin this text -with a capital letter. This helps to distinguish the line from a continuation of -a previous line; i.e., \inlsh{// This is my comment.} -\item As a general rule, don’t keep commented out source code in the final -baselined product. Such code leads the reader to believe there was uncertainty -in the code as it currently exists. -\item Place the \# of a preprocessor directive at column one. An exception is -the use of nested ifdefs where the bodies only contain other preprocessor directives. -Add tabs to enhance readability: -\begin{lstlisting}[style=C++Style] -void foo() { - for(int i = 0; i < 10; ++i) - { -#ifdef BAR - do_something(); -#endif - for_loop_code(); - } -} -\end{lstlisting} -\item Use tabular white space if it enhances -readability. -\item Use only one return statement. Structure the code so that only one return -statement is necessary. -\end{itemize} - -\section{Naming Conventions} - -Keep variable and function names meaningful but concise. -\begin{itemize} -\item Begin variable names with lower-case letter. -\item Begin function names and class names with upper-case letter. -\item All function, class and variable names should be written in CamelCase, -e.g. \inlsh{MyClass, DoFunction() or myVariableName}. -\item All preprocessor definitions written in UPPER\_CASE with words separated -by underscores, e.g. USE\_SPECIFIC\_FEATURE. -\item All member variables prefixed with m\_. -\item All constants prefixed with a k. -\item All function parameters prefixed with a p. -\item All enumerations prefixed with an e. -\item Do not use leading underscores. -\end{itemize} - -\section{Namespaces} - -The top-level namespace is "Nektar". All code should reside in this namespace or -a sub-space of this. - -\begin{itemize} -\item Namespaces correspond to code structure. -\item Namespaces should be kept to a minimum to simplify the interface to their -contents. -\end{itemize} - -\section{Documentation} -\begin{itemize} -\item Briefs for classes, functions and types in header files using -\inlsh{///} notation. -\item Full documentation with implementation using \inlsh{/** ... *\/} -notation. -\item Use @ symbol for @class, @param, @returns, etc for ease of identification. -\item Any separate documentation pages not directly associated with a portion of -the code should be in a separate file in /docs/html/doxygen. -\end{itemize} diff --git a/docs/developer-guide/core-concepts/core-concepts.tex b/docs/developer-guide/core-concepts/core-concepts.tex deleted file mode 100644 index fd876236d1c4837be5de6d924241806596a067a5..0000000000000000000000000000000000000000 --- a/docs/developer-guide/core-concepts/core-concepts.tex +++ /dev/null @@ -1,354 +0,0 @@ -\chapter{Core Concepts} - -This section describes some of the key concepts which are useful when developing -code within the Nektar++ framework. - -\section{Factory method pattern} -The factory method pattern is used extensively throughout Nektar++ as a -mechanism to instantiate objects. It provides the following benefits: -\begin{itemize} -\item Encourages modularisation of code such that conceptually related -algorithms are grouped together -\item Structuring of code such that different implementations of the same -concept are encapsulated and share a common interface -\item Users of a factory-instantiated modules need only be concerned with the - interface and not the details of underlying implementations -\item Simplifies debugging since code relating to a specific implementation - resides in a single class -\item The code is naturally decoupled to reduce header-file dependencies and - improves compile times -\item Enables implementations (e.g. relating to third-party libraries) to be - disabled through the build process (CMake) by not compiling a specific - implementation, rather than scattering preprocessing statements throughout the - code -\end{itemize} - -For conceptual details see the Wikipedia page. -%\url{http://en.wikipedia.org/wiki/Factory_pattern}. - -\subsection{Using NekFactory} -The templated NekFactory class implements the factory pattern in Nektar++. -There are two distinct aspects to creating a factory-instantiated collection of -classes: defining the public interface, and registering specific -implementations. Both of these involve adding standard boilerplate code. It is -assumed that we are writing a code which implements a particular concept or -functionality within the code, for which there are multiple implementations. The -reasons for multiple implementations may be very low level such as alternative -algorithms for solving a linear system, or high level, such as selecting from a -range of PDEs to solve. - -\subsubsection{Creating an interface (base class)} -A base class must be defined which prescribes an implementation-independent -interface. In Nektar++, the template method pattern is used, requiring public -interface functions to be defined which call private virtual implementation -methods. The latter will be overridden in the specific implementation classes. -In the base class these virtual methods should be defined as pure virtual, since -there is no implementation and we will not be instantiating this base class -explicitly. - -As an example we will create a factory for instantiating different -implementations of some concept \inlsh{MyConcept}, defined in -\inlsh{MyConcept.h} and \inlsh{MyConcept.cpp}. First in \inlsh{MyConcept.h}, -we need to include the NekFactory header - -\begin{lstlisting}[style=C++Style] -#include -\end{lstlisting} - -The following code should then be included just before the base class -declaration (in the same namespace as the class): - -\begin{lstlisting}[style=C++Style] -class MyConcept - -// Datatype for the MyConcept factory -typedef LibUtilities::NekFactory< std::string, MyConcept, - ParamType1, - ParamType2 > MyConceptFactory; -MyConceptFactory& GetMyConceptFactory(); -\end{lstlisting} - -The template parameters define the datatype of the key used to retrieve a -particular implementation (usually a string, enum or custom class such as -\inlsh{MyConceptKey}, the base class (in our case \inlsh{MyConcept} and a list -of zero or more parameters which are taken by the constructors of all -implementations of the type \inlsh{MyConcept} (in our case we have two). Note -that all implementations must take the same parameter list in their constructors. - -The normal definition of our base class then follows: - -\begin{lstlisting}[style=C++Style] -class MyConcept -{ - public: - MyConcept(ParamType1 p1, ParamType2 p2); - ... -}; -\end{lstlisting} - -We must also define a shared pointer for our base class for use later -\begin{lstlisting}[style=C++Style] -typedef boost::shared_ptr MyConceptShPtr; -\end{lstlisting} - -\subsubsection{Creating a specific implementation (derived class)} -A class is defined for each specific implementation of a concept. It is these -specific implementations which are instantiated by the factory. - -In our example we will have an implementations called \inlsh{MyConceptImpl1} -defined in \inlsh{MyConceptImpl1.h} and \inlsh{MyConceptImpl1.cpp}. In the -header file we include the base class header file - -\begin{lstlisting}[style=C++Style] -#include -\end{lstlisting} - -We then define the derived class as normal: - -\begin{lstlisting}[style=C++Style] -class MyConceptImpl1 : public MyConcept -{ -... -}; -\end{lstlisting} - -In order for the factory to work, it must know -\begin{itemize} -\item that {{{MyConceptImpl1}}} exists, and -\item how to create it. -\end{itemize} - -To allow the factory to create instances of our class we define a function in -our class: -\begin{lstlisting}[style=C++Style] -/// Creates an instance of this class -static MyConceptSharedPtr create( - ParamType1 p1, - ParamType2 p2) -{ - return MemoryManager::AllocateSharedPtr(p1, p2); -} -\end{lstlisting} -This function simply creates an instance of \inlsh{MyConceptImpl1} using the -supplied parameters. It must be \inlsh{static} because we are not operating on -an existing instance and it should return a base class shared pointer (rather -than a \inlsh{MyConceptImpl1} shared pointer), since the point of the factory -is that the calling code does not know about specific implementations. - -The last task is to register our implementation with the factory. This is done -using the \inlsh{RegisterCreatorFunction} member function of the factory. -However, we wish this to happen as early on as possible (so we can use the -factory straight away) and without needing to explicitly call the function for -every implementation at the beginning of our program (since this would again -defeat the point of a factory)! The solution is to use the function to -initialise a static variable: it will be executed prior to the start of the -\inlsh{main()} routine, and can be located within the very class it is -registering, satisfying our code decoupling requirements. - -In \inlsh{MyConceptImpl1.h} we define a static variable with the same datatype -as the key used in our factory (in our case \inlsh{std::string}) -\begin{lstlisting}[style=C++Style] -static std::string className; -\end{lstlisting} -The above variable can be \inlsh{private} since it is typically never actually -used within the code. We then initialise it in \inlsh{MyConceptImpl1.cpp} - -\begin{lstlisting}[style=C++Style] -string MyConceptImpl1::className - = GetMyConceptFactory().RegisterCreatorFunction( - "Impl1", - MyConceptImpl1::create, - "First implementation of my concept."); -\end{lstlisting} -The first parameter specifies the value of the key which should be used to -select this implementation. The second parameter is a function pointer to our -static function used to instantiate our class. The third parameter provides a -description which can be printed when listing the available MyConcept -implementations. - -\subsection{Instantiating classes} -To create instances of MyConcept implementations elsewhere in the code, we must -first include the ''base class'' header file -\begin{lstlisting}[style=C++Style] -#include -\end{lstlisting} -Note we do not include the header files for the specific MyConcept -implementations anywhere in the code (apart from \inlsh{MyConceptImpl1.cpp}). -If we modify the implementation, only the implementation itself requires -recompiling and the executable relinking. - -We create an instance by retrieving the \inlsh{MyConceptFactory} and call the -\inlsh{CreateInstance} member function of the factory: -\begin{lstlisting}[style=C++Style] -ParamType p1 = ...; -ParamType p2 = ...; -MyConceptShPtr p = GetMyConceptFactory().CreateInstance( "Impl1", p1, p2 ); -\end{lstlisting} - -Note that the class is used through the pointer \inlsh{p}, which is of type -\inlsh{MyConceptShPtr}, allowing the use of any of the public interface -functions in the base class (and therefore the specific implementations behind them) to be -called, but not directly any functions declared solely in a specific -implementation. - - -\section{NekArray} -An Array is a thin wrapper around native arrays. Arrays provide all the -functionality of native arrays, with the additional benefits of automatic use of -the Nektar++ memory pool, automatic memory allocation and deallocation, bounds -checking in debug mode, and easier to use multi-dimensional arrays. - -Arrays are templated to allow compile-time customization of its dimensionality -and data type. - -Parameters: -\begin{itemize} -\item \inltt{Dim} Must be a type with a static unsigned integer called -\inltt{Value} that specifies the array's dimensionality. For example -\begin{lstlisting}[style=C++Style] -struct TenD { - static unsigned int Value = 10; -}; -\end{lstlisting} -\item \inltt{DataType} The type of data to store in the array. -\end{itemize} - -It is often useful to create a class member Array that is shared with users of -the object without letting the users modify the array. To allow this behavior, -Array inherits from Array. The following -example shows what is possible using this approach: -\begin{lstlisting}[style=C++Style] - class Sample { - public: - Array& getData() const { return m_data; } - void getData(Array& out) const { out = m_data; } - - private: - Array m_data; - }; -\end{lstlisting} -In this example, each instance of Sample contains an array. The getData -method gives the user access to the array values, but does not allow -modification of those values. - -\subsection{Efficiency Considerations} - -Tracking memory so it is deallocated only when no more Arrays reference it does -introduce overhead when copying and assigning Arrays. In most cases this loss of -efficiency is not noticeable. There are some cases, however, where it can cause -a significant performance penalty (such as in tight inner loops). If needed, -Arrays allow access to the C-style array through the \texttt{Array::data} member -function. - - -\section{Threading} -\begin{notebox} -Threading is not currently included in the main code distribution. However, this -hybrid MPI/pthread functionality should be available within the next few months. -\end{notebox} - -We investigated adding threaded parallelism to the already MPI parallel -Nektar++. MPI parallelism has multiple processes that exchange data using -network or network-like communications. Each process retains its own memory -space and cannot affect any other process’s memory space except through the MPI -API. A thread, on the other hand, is a separately scheduled set of instructions -that still resides within a single process’s memory space. Therefore threads -can communicate with one another simply by directly altering the process’s -memory space. The project's goal was to attempt to utilise this difference to -speed up communications in parallel code. - -A design decision was made to add threading in an implementation independent -fashion. This was achieved by using the standard factory methods which -instantiate an abstract thread manager, which is then implemented by a concrete -class. For the reference implementation it was decided to use the Boost library -rather than native p-threads because Nektar++ already depends on the Boost -libraries, and Boost implements threading in terms of p-threads anyway. - -It was decided that the best approach would be to use a thread pool. This -resulted in the abstract classes ThreadManager and ThreadJob. ThreadManager is -a singleton class and provides an interface for the Nektar++ programmer to -start, control, and interact with threads. ThreadJob has only one method, the -virtual method run(). Subclasses of ThreadJob must override run() and provide a -suitable constructor. Instances of these subclasses are then handed to the -ThreadManager which dispatches them to the running threads. Many thousands of -ThreadJobs may be queued up with the ThreadManager and strategies may be -selected by which the running threads take jobs from the queue. Synchronisation -methods are also provided within the ThreadManager such as wait(), which waits -for the thread queue to become empty, and hold(), which pauses a thread that -calls it until all the threads have called hold(). The API was thoroughly -documented in Nektar++’s existing Javadoc style. - -Classes were then written for a concrete implementation of ThreadManager using -the Boost library. Boost has the advantage of being available on all Nektar++’s -supported platforms. It would not be difficult, however, to implement -ThreadManager using some other functionality, such as native p-threads. - -Two approaches to utilising these thread classes were then investigated. The -bottom-up approach identifies likely regions of the code for parallelisation, -usually loops around a simple and independent operation. The top-down approach -seeks to run as much of the code as is possible within a threaded environment. - -The former approach was investigated first due to its ease of implementation. -The operation chosen was the multiplication of a very large sparse block -diagonal matrix with a vector, where the matrix is stored as its many smaller -sub matrices. The original algorithm iterated over the sub matrices multiplying -each by the vector and accumulating the result. The new parallel algorithm -sends ThreadJobs consisting of batches of sub matrices to the thread pool. The -worker threads pick up the ThreadJobs and iterate over the sub matrices in the -job accumulating the result in a thread specific result vector. This latter -detail helps to avoid the problem of cache ping-pong which is where multiple -threads try to write to the same memory location, repeatedly invalidating one -another's caches. - -Clearly this approach will work best when the sub matrices are large and there -are many of them . However, even for test cases that would be considered large -it became clear that the code was still spending too much time in its scalar -regions. - -This led to the investigation of the top-down approach. Here the intent is to -run as much of the code as possible in multiple threads. This is a much more -complicated approach as it requires that the overall problem can be partitioned -suitably, that a mechanism be available to exchange data between the threads, -and that any code using shared resources be thread safe. As Nektar++ already -has MPI parallelism the first two requirements (data partitioning and exchange) -are already largely met. However since MPI parallelism is implemented by having -multiple independent processes that do not share memory space, global data in -the Nektar++ code, such as class static members or singleton instances, are now -vulnerable to change by all the threads running in a process. - -To Nektar++’s communication class, Comm, was added a new class, ThreadedComm. -This class encapsulates a Comm object and provides extra functionality without -altering the API of Comm (this is the Decorator pattern). To the rest of the -Nektar++ library this Comm object behaves the same whether it is a purely MPI -Comm object or a hybrid threading plus MPI object. The existing data -partitioning code can be used with very little modification and the parts of the -Nektar++ library that exchange data are unchanged. When a call is made to -exchange data with other workers ThreadedComm first has the master thread on -each process (i.e. the first thread) use the encapsulated Comm object (typically -an MPI object) to exchange the necessary data between the other processes, and -then exchanges data with the local threads using direct memory to memory copies. - -As an example: take the situation where there are two processes A and B, -possibly running on different computers, each with two threads 1 and 2. A -typical data exchange in Nektar++ uses the Comm method AllToAll(...) in which -each worker sends data to each of the other workers. Thread A1 will send data -from itself and thread A2 via the embedded MPI Comm to thread B1, receiving in -turn data from threads B1 and B2. Each thread will then pick up the data it -needs from the master thread on its process using direct memory to memory -copies. Compared to the situation where there are four MPI processes the number -of communications that actually pass over the network is reduced. Even MPI -implementations that are clever enough to recognise when processes are on the -same host must make a system call to transfer data between processes. - -The code was then audited for situations where threads would be attempting to -modify global data. Where possible such situations were refactored so that each -thread has a copy of the global data. Where the original design of Nektar++ did -not permit this access to global data was mediated through locking and -synchronisation. This latter approach is not favoured except for global data -that is used infrequently because locking reduces concurrency. - -The code has been tested and Imperial College cluster cx1 and has shown good -scaling. However it is not yet clear that the threading approach outperforms -the MPI approach; it is possible that the speedups gained through avoiding -network operations are lost due to locking and synchronisation issues. These -losses could be mitigated through more in-depth refactoring of Nektar++. \ No newline at end of file diff --git a/docs/developer-guide/data-structures-algorithms/connectivity.tex b/docs/developer-guide/data-structures-algorithms/connectivity.tex deleted file mode 100644 index fc7bf9ad755459a48db8fc45979ceb0106227d81..0000000000000000000000000000000000000000 --- a/docs/developer-guide/data-structures-algorithms/connectivity.tex +++ /dev/null @@ -1,289 +0,0 @@ -\section{Connectivity} -The typical elemental decomposition of the spectral/hp element method requires a -global assembly process when considering multi-elemental problems. This global -assembly will ensure some level of connectivity between adjacent elements sucht -that there is some form of continuity across element boundaries in the global -solution. In this section, we will merely focus on the classical Galerkin -method, where global continuity is typically imposed by making the approximation -$C^0$ continuous. - -\subsection{Connectivity in two dimensions} - -As explained in \cite{KaSh05}, the global assembly process involves the -transformation from local degrees of freedom to global degrees of freedom -(DOF). This transformation is typically done by a mapping array which relates -the numbering of the local (= elemental) DOF's to the numbering of the global -DOF's. To understand how this transformation is set up in Nektar++ one should -understand the following: -\begin{itemize} -\item \textbf{Starting point} - - The starting point is the initial numbering of the elemental expansion modes. - This corresponds to the order in which the different local expansion modes - are listed in the coefficient array \texttt{m\_coeffs} of the elemental - (local or standard) expansion. The specific order in which the different elemental - expansion modes appear is motivated by the compatability with the - sum-factorisation technique. This also implies that this ordering is fixed - and should not be changed by the user. Hence, this unchangeable initial local - numbering will serve as starting input for the connectivity. - -\item \textbf{end point} - - Obviously, we are working towards the numbering of the global DOF's. This - global ordering should: - \begin{itemize} - \item reflect the chosen continuity approach (standard $C^0$ Galerkin in our case) - \item (optionally) have some optimal ordering (where optimality can - be defined in different ways, e.g. minimal bandwith) - \end{itemize} -\end{itemize} - -All intermittent steps from starting point to end point can basically be chosen -freely but they should allow for an efficient construction of the global -numbering system starting from the elemental ordering of the local degrees of -freedom. Currently, Nektar++ provides a number of tools and routines in the -different sublibraries which can be employed to set up the mapping from local to -global DOF's. These tools will be listed below, but first the connectivity -strategies for both modal and nodal expansions will be explained. Note that all -explanations below are focussed on quadrilateral elements. However, the general -idea equally holds for triangles. - -\subsection{Connectivity strategies} - -For a better understanding of the described strategies, one should first -understand how Nektar++ deals with the basic geometric concepts such as edges -and (2D) elements. - -In Nektar++, a (2D) element is typically defined by a set of edges. In the input -.xml files, this should be done as (for a quadrilateral element): -\begin{lstlisting}[style=XMLStyle] - e0 e1 e2 e3 -\end{lstlisting} -where \inltt{e0} to \inltt{e3} correspond to the mesh ID's of the different -edges. -It is important to know that in Nektar++, the convention is that these edges -should be ordered counterclokwise (Note that this order also corresponds to the -order in which the edges are passed to the constructors of the 2D geometries). -In addition, note that we will refer to edge \inltt{e0} as the edge with local -(elemental) edge ID equal to 0, to edge \inltt{e1} as local edge with ID 1, to -edge \inltt{e2} as local edge with ID equal 2 and to edge \inltt{e3} as local -edge with ID 3. -Furthermore, one should note that the local coordinate system is orientated such -that the first coordinate axis is aligned with edge 0 and 2 (local edge ID), and -the second coordinate axis is aligned with edge 1 and 3. The direction of these -coordinate axis is such that it points in counterclockwise direction for edges 0 -and 1, and in clockwise direction for edge 2 and 3. - -Another important feature in the connectivity strategy is the concept of edge -orientation. For a better understanding, consider the input format of an edge as -used in the input .xml files which contain the information about the mesh. An -edge is defined as: -\begin{lstlisting}[style=XMLStyle] - v0 v1 -\end{lstlisting} -where \inltt{v0} and \inltt{v1} are the ID's of the two vertices that define -the edge (Note that these vertices are passed in the same order to the constructor -of the edge). Now, the orientation of an edge of a two-dimensional element (i.e. -quadrilateral or triangle) is defined as: -\begin{itemize} -\item Forward if the vertex with ID \inltt{v0} comes before the vertex with ID -\inltt{v1} when considering the vertices the vertices of the element in a -counterclockwise direction -\item Backward otherwise. -\end{itemize} - -This has the following implications: -\begin{itemize} -\item The common edge of two adjacent elements has always a forward orientation -for one of the elements it belongs to and a backward orientation for the other. -\item The orientation of an edge is only relevant when considering -two-dimensional elements. It is a property which is not only inherent to the edge itself, but - depends on the element it belongs to. (This also means that a segment does not - have an orientation) -\end{itemize} - -\subsubsection{Modal expansions} - -We will follow the basic principles of the connectivity strategy as explained in -Section 4.2.1.1 of \cite{KaSh05} (such as the hierarchic ordering of the edge -modes). However, we do not follow the strategy described to negate the odd modes -of an intersecting edge of two adjacent elements if the local coordinate systems -have an opposite direction. The explained strategy involves checking the -direction of the local coordinate systems of the neighbouring elements. However, -for a simpler automatic procedure to identify which edges need to have odd mode -negated, we would like to have an approach which can be applied to the elements -individually, without information being coupled between neighbouring elements. -This can be accomplished in the following way. Note that this approach is based -on the earlier observation that the intersecting edge of two elements always has -opposite orientation. Proper connectivity can now be guaranteed if: -\begin{itemize} -\item forward oriented edges always have a counterclockwise local coordinate -axis -\item backward oriented edges always have a clockwise local coordinate axis. -\end{itemize} - -Both the local coordinate axis along an intersecting edge will then point in the -same direction. Obviously, these conditions will not be fulfilled by default. -But in order to do so, the direction of the local coordinate axis should be -reversed in following situations: -\begin{lstlisting}[style=C++Style] - if ((LocalEdgeId == 0)||(LocalEdgeId == 1)) { - if( EdgeOrientation == Backward ) { - change orientation of local coordinate axis - } - } - - if ((LocalEdgeId == 2)||(LocalEdgeId == 3)) { - if( EdgeOrientation == Forward ) { - change orientation of local coordinate axis - } - } -\end{lstlisting} -This algorithm above is based on the earlier observation that the local -coordinate axis automatically point in counterclockwise direction for edges 0 -and 1 and in clockwise direction for the other edges. As explained in \cite{KaSh05} -the change in local coordinate axis can actually be done by reversing the sigqn -of the odd modes. This is implemented by means of an additional sign vector. - -\subsubsection{Nodal expansions} - -For the nodal expansions, we will use the connectivity strategy as explained in -Section 4.2.1.1 of \cite{KaSh05}. However, we will clarify this strategy from a -Nektar++ point of view. As pointed out in \cite{KaSh05}, the nodal edge modes -can be identified with the physical location of the nodal points. In order to ensure -proper connectivity between elements the egde modes with the same nodal location -should be matched. This will be accomplished if both the sets of local edge -modes along the intersection edge of two elements are numbered in the same -direction. And as the intersecting edge of two elements always has opposite -direction, this can be guaranteed if: -\begin{itemize} -\item the local numbering of the edge modes is counterclockwise for forward - oriented edges -\item the local numbering of the edge modes is clockwise for backward oriented -edges. -\end{itemize} - -This will ensure that the numbering of the global DOF's on an edge is in the -same direction as the tow subsets of local DOF's on the intersecting edge. - -\subsection{Implementation} -The main entity for the transformation from local DOF's to global DOF's (in 2D) -is the LocalToGlobalMap2D class. This class basically is the abstraction of the -mapping array map[e][i] as introduced in section 4.2.1 of \cite{KaSh05}. This -mapping array is contained in the class' main data member, -LocalToGlobalMap2D::m\_locToContMap. Let us recall what this mapping array -\begin{lstlisting} - map[e][i] = globalID -\end{lstlisting} -actually represents: -\begin{itemize} -\item e corresponds to the e th element -\item i corresponds to the i th expansion -mode within element e. This index i in this map array corresponds to the index of - the coefficient array m\_coeffs. -\item globalID represents the ID of the corresponding global degree of freedom. -\end{itemize} - -However, rather than this two-dimensional structure of the mapping array,\\ -\texttt{LocalToGlobalMap2D::m\_locToContMap} stores the mapping array as a -one-dimensional array which is the concatenation of the different elemental -mapping arrays map[e]. This mapping array can then be used to assemble the -global system out of the local entries, or to do any other transformation -between local and global degrees of freedom (Note that other mapping arrays such -as the boundary mapping bmap[e][i] or the sign vector sign[e][i] which might be -required are also contained in the LocalToGlobalMap2D class). - -For a better appreciation of the implementation of the connectivity in Nektar++, -it might be useful to consider how this mapping array is actually being -constructed (or filled). To understand this, first consider the following: -\begin{itemize} -\item The initial local elemental numbering (referred to as starting point in -the beginning of this document) is not suitable to set up the mapping. In no way - does it correspond to the local numbering required for a proper connectivity as - elaborated in Section 4.2.1 of \cite{KaSh05}. Hence, this initial ordering - asuch cannot be used to implement the connectivity strategies explained above. As a - result, additional routines (see here), which account for some kind of - reordering of the local numbering will be required in order to construct the - mapping array properly. -\item Although the different edge modes can be thought of as to include both -the vertex mode, we will make a clear distinction between them in the - implementation. In other words, the vertex modes will be treated separately - from the other modes on an edge as they are conceptually different from an - connectivity point of view. We will refer to these remaining modes as interior - edge modes. -\end{itemize} - -The fill-in of the mapping array can than be summarised by the following part of -(simplified) code: -\begin{lstlisting}[style=C++Style] - for(e = 0; e < Number_Of_2D_Elements; e++) { - for(i = 0; i < Number_Of_Vertices_Of_Element_e; i++) { - offsetValue = ... - map[e][GetVertexMap(i)] = offsetValue; - } - - for(i = 0; i < Number_Of_Edges_Of_Element_e; i++) { - localNumbering = GetEdgeInteriorMap(i); offsetValue = ... - for(j = 0; j < Number_Of_InteriorEdgeModes_Of_Edge_i; j++) { - map[e][localNumbering(j)] = offsetValue + j; - } - } - } -\end{lstlisting} - -In this document, we will not cover how the calculate the offsetValue which: -\begin{itemize} -\item for the vertices, corresponds to the global ID of the specific vertex -\item for the edges, corresponds to the starting value of the global numbering on the - concerned edge -\end{itemize} - -However, we would like to focus on the routines GetVertexMap() and -GetEdgeInteriorMap(), 2 functions which somehow reorder the initial local -numbering in order to be compatible with the connectivity strategy. - -\subsubsection{GetVertexMap()} - -Given the local vertex id (i.e. 0,1,2 or 3 for a quadrilateral element), it -returns the position of the corresponding vertex mode in the elemental -coefficient array StdRegions::StdExpansion::m\_coeffs. By using this function as -in the code above, it is ensured that the global ID of the vertex is entered in -the correct position in the mapping array. - -\subsubsection{GetEdgeInteriorMap()} - -Like the previous routine, this function is also defined for all two dimensional -expanions in the StdRegions::StdExpansion class tree. This is actually the most -important function to ensure proper connectivity between neigbouring elements. -It is a function which reorders the numbering of local DOF's according to the -connectivity strategy. As input this function takes: -\begin{itemize} -\item the local edge ID of the edge to be considered -\item the orientation of this edge. -\end{itemize} - -As output, it returns the local ordering of the requested (interior) edge modes. -This is contained - in an array of size N-2, where N is the number of expansion modes in the - relevant direction. The entries in this array represent the position of the - corresponding interior edge mode in the elemental coefficient array - StdRegions::StdExpansion::m\_coeffs. - -Rather than the actual values of the local numbering, it is the ordering of -local edge modes which is of importance for the connectivity. That is why it is -important how the different interior edge modes are sorted in the returned -array. This should be such that for both the elements which are connected by the -intersecting edge, the local (interior) edge modes are iterated in the same -order. This will guarantee a correct global numbering scheme when employing the -algorithm shown above. This proper connectivity can be ensured if the function -GetEdgeInteriorMap: - -\begin{itemize} -\item for modal expansions: returns the edge interior modes in hierarchical -order (i.e. the lowest polynomial order mode first), -\item for nodal expansions: returns the edge interior modes in: - \begin{itemize} - \item counterclockwise order for forward oriented edges - \item clockwise order for backward oriented edges. - \end{itemize} -\end{itemize} diff --git a/docs/developer-guide/data-structures-algorithms/data-structures-algorithms.tex b/docs/developer-guide/data-structures-algorithms/data-structures-algorithms.tex deleted file mode 100644 index ea1e4e22a640cb72d919e240d077896e0c16b1ed..0000000000000000000000000000000000000000 --- a/docs/developer-guide/data-structures-algorithms/data-structures-algorithms.tex +++ /dev/null @@ -1,8 +0,0 @@ -\chapter{Data Structures and Algorithms} -\label{ch:data} - -\input{connectivity} - -\input{time-integration} - -\input{preconditioners} \ No newline at end of file diff --git a/docs/developer-guide/data-structures-algorithms/preconditioners.tex b/docs/developer-guide/data-structures-algorithms/preconditioners.tex deleted file mode 100644 index 7834c599657ea23c8ac84836524bef8d860cd87a..0000000000000000000000000000000000000000 --- a/docs/developer-guide/data-structures-algorithms/preconditioners.tex +++ /dev/null @@ -1,385 +0,0 @@ -\section{Preconditioners} -\label{sec:precon} - -Most of the solvers in \nekpp, including the incompressible Navier-Stokes -equations, rely on the solution of a Helmholtz equation, -% -\begin{equation} - \nabla^{2}u(\mathbf{x})+\lambda u(\mathbf{x})=f(\mathbf{x}), - \label{eq:precon:helm} -\end{equation} -% -an elliptic boundary value problem, at every time-step, where $u$ is defined on -a domain $\Omega$ of $N_{\mathrm{el}}$ non-overlapping elements. In this -section, we outline the preconditioners which are implemented in \nekpp. Whilst -some of the preconditioners are generic, many are especially designed for the -\emph{modified} basis only. - -\subsection{Mathematical formulation} - -The standard spectral/$hp$ approach to discretise \eqref{eq:precon:helm} starts -with an expansion in terms of the elemental modes: -% -\begin{equation} - u^{\delta}(\mathbf{x})=\sum_{n=0}^{N_{\mathrm{dof}}-1}\hat{u}_n - \Phi_n(\mathbf{x})=\sum_{e=1}^{{N_{\mathrm{el}}}} - \sum_{n=0}^{N^{e}_m-1}\hat{u}_n^e\phi_n^e(\mathbf{x}) - \label{eq:precon:disc} -\end{equation} -% -where $N_{\mathrm{el}}$ is the number of elements, $N^{e}_m$ is the number of -local expansion modes within the element $\Omega^e$, $\phi_n^e(\mathbf{x})$ is -the $n^{\mathrm{th}}$ local expansion mode within the element $\Omega^e$, -$\hat{u}_n^e$ is the $n^{\mathrm{th}}$ local expansion coefficient within the -element $\Omega^e$. Approximating our solution by~\eqref{eq:precon:disc}, we -adopt a Galerkin discretisation of equation~\eqref{eq:precon:helm} where for an -appropriate test space $V^\delta$ we find an approximate solution -$\mathbf{u}^{\delta} \in V^{\delta}$ such that -% -\[ -\mathcal L \left({v, u}\right) = \int_{\Omega}\nabla v^{\delta} \cdot \nabla -u^{\delta} + \lambda v^{\delta} u^{\delta} d \mathbf{x} = \int_{\Omega} -v^{\delta} f d\mathbf{x} \quad \forall v^{\delta} \in V^{\delta} -\] -% -This can be formulated in matrix terms as -% -\[ -\mathbf{H}\hat{\mathbf{u}} = \mathbf{f} -\] -% -where $\mathbf{H}$ represents the Helmholtz matrix, $\hat{\mathbf{u}}$ are the -unknown global coefficients and $\mathbf{f}$ the inner product the expansion -basis with the forcing function. - -\subsubsection{$C^0$ formulation} - -We first consider the $C^0$ (i.e. continuous Galerkin) formulation. The -spectral/$hp$ expansion basis is obtained by considering interior modes, which -have support in the interior of the element, separately from boundary modes -which are non-zero on the boundary of the element. We align the boundary modes -across the interface of the elements to obtain a continuous global solution. The -boundary modes can be further decomposed into vertex, edge and face modes, -defined as follows: - -\begin{itemize} - \item vertex modes have support on a single vertex and the three adjacent - edges and faces as well as the interior of the element; - \item edge modes have support on a single edge and two adjacent faces as well - as the interior of the element; - \item face modes have support on a single face and the interior of the - element. -\end{itemize} - -When the discretisation is continuous, this strong coupling between vertices, -edges and faces leads to a matrix of high condition number $\kappa$. Our aim is -to reduce this condition number by applying specialised -preconditioners. Utilising the above mentioned decomposition, we can write the -matrix equation as: -% -\[ -\left[\begin{array}{cc} - \mathbf{H}_{bb} & \mathbf{H}_{bi}\\ - \mathbf{H}_{ib} & \mathbf{H}_{ii} - \end{array}\right] -\left[ \begin{array}{c} -\hat{\mathbf{u}}_{b}\\ -\hat{\mathbf{u}}_{i}\\ -\end{array}\right] = -\left[ \begin{array}{c} -\hat{\mathbf{f}}_{b}\\ -\hat{\mathbf{f}}_{i}\\ -\end{array}\right] -\] -% -where the subscripts $b$ and $i$ denote the boundary and interior degrees of -freedom respectively. This system then can be statically condensed allowing us -to solve for the boundary and interior degrees of freedom in a decoupled -manor. The statically condensed matrix is given by -% -\[ -\left[\begin{array}{cc} - \mathbf{H}_{bb}-\mathbf{H}_{bi} \mathbf{H}_{ii}^{-1} \mathbf{H}_{ib} & 0\\ - \mathbf{H}_{ib} & \mathbf{H}_{ii} - \end{array}\right] -\left[ \begin{array}{c} -\hat{\mathbf{u}}_{b}\\ -\hat{\mathbf{u}}_{i}\\ -\end{array}\right] = -\left[ \begin{array}{c} -\hat{\mathbf{f}}_{b}-\mathbf{H}_{bi} \mathbf{H}_{ii}^{-1}\hat{\mathbf{f}}_{i}\\ -\hat{\mathbf{f}}_{i}\\ -\end{array}\right] -\] -% -This is highly advantageous since by definition of our interior expansion this -vanishes on the boundary, and so $\mathbf{H}_{ii}$ is block diagonal and thus -can be easily inverted. The above sub-structuring has reduced our problem to -solving the boundary problem: -% -\[ -\mathbf{S}_{1}\hat{\mathbf{u}} = \hat{\mathbf{f}}_{1} -\] -% -where -$\mathbf{S_{1}}=\mathbf{H}_{bb}-\mathbf{H}_{bi} \mathbf{H}_{ii}^{-1} -\mathbf{H}_{ib}$ -and -$\hat{\mathbf{f}}_{1}=\hat{\mathbf{f}}_{b}-\mathbf{H}_{bi} -\mathbf{H}_{ii}^{-1}\hat{\mathbf{f}}_{i}$. -Although this new system typically has better convergence properties (i.e lower -$\kappa$), the system is still ill-conditioned, leading to a convergence rate of -the conjugate gradient (CG) routine that is prohibitively slow. For this reason -we need to precondition $\mathbf{S}_1$. To do this we solve an equivalent -system of the form: -% -\[ -\mathbf{M}^{-1}\left(\mathbf{S}_{1} \hat{\mathbf{u}} - \hat{\mathbf{f}}_{1} \right) = 0 -\] -% -where the preconditioning matrix $\mathbf{M}$ is such that -$\kappa\left(\mathbf{M}^{-1} \mathbf{S}_{1}\right)$ is less than -$\kappa\left(\mathbf{S}_{1}\right)$ and speeds up the convergence rate. Within -the conjugate gradient routine the same preconditioner $\mathbf{M}$ is applied -to the residual vector $\hat{\mathbf{r}}_{k+1}$ of the CG routine every -iteration: -% -\[ -\hat{\mathbf{z}}_{k+1}=\mathbf{M}^{-1}\hat{\mathbf{r}}_{k+1}. -\] -% - -\subsubsection{HDG formulation} - -When utilising a hybridizable discontinuous Galerkin formulation, we perform a -static condensation approach but in a discontinuous framework, which for brevity -we omit here. However, we still obtain a matrix equation of the form -% -\[ -\mathbf{\Lambda}\hat{\mathbf{u}} = \hat{\mathbf{f}}. -\] -% -where $\mathbf{\Lambda}$ represents an operator which projects the solution of -each face back onto the three-dimensional element or edge onto the -two-dimensional element. In this setting then, $\hat{\mathbf{f}}$ consists of -degrees of freedom for each egde (in 2D) or face (in 3D). The overall system -does not, therefore, results in a weaker coupling between degrees of freedom, -but at the expense of a larger matrix system. - -\subsection{Preconditioners} - -Within the \nekpp framework a number of preconditioners are available to speed -up the convergence rate of the conjugate gradient routine. The table below -summarises each method, the dimensions of elements which are supported, and also -the discretisation type support which can either be continuous (CG) or -discontinuous (hybridizable DG). - -\begin{center} - \begin{tabular}{lll} - \toprule - \textbf{Name} & \textbf{Dimensions} & \textbf{Discretisations} \\ - \midrule - \inltt{Null} & All & All \\ - \inltt{Diagonal} & All & All \\ - \inltt{FullLinearSpace} & 2/3D & CG \\ - \inltt{LowEnergyBlock} & 3D & CG \\ - \inltt{Block} & 2/3D & All \\ - \midrule - \inltt{FullLinearSpaceWithDiagonal} & All & CG \\ - \inltt{FullLinearSpaceWithLowEnergyBlock} & 2/3D & CG \\ - \inltt{FullLinearSpaceWithBlock} & 2/3D & CG \\ - \bottomrule - \end{tabular} -\end{center} - -The default is the \inltt{Diagonal} preconditioner. The above preconditioners -are specified through the \inltt{Preconditioner} option of the -\inltt{SOLVERINFO} section in the session file. For example, to enable -\inltt{FullLinearSpace} one can use: - -\begin{lstlisting}[style=XMLStyle] - -\end{lstlisting} - -Alternatively one can have more control over different preconditioners for each -solution field by using the \inltt{GlobalSysSoln} section. For more details, -consult the user guide. The following sections specify the details for each -method. - -\subsubsection{Diagonal} - -Diagonal (or Jacobi) preconditioning is amongst the simplest preconditioning -strategies. In this scheme one takes the global matrix $\mathbf{H} = (h_{ij})$ -and computes the diagonal terms $h_{ii}$. The preconditioner is then formed as a -diagonal matrix $\mathbf{M}^{-1} = (h_{ii}^{-1})$. - -\subsubsection{Linear space} - -The linear space (or coarse space) of the matrix system is that containing -degrees of freedom corresponding only to the vertex modes in the high-order -system. Preconditioning of this space is achieved by forming the matrix -corresponding to the coarse space and inverting it, so that -% -\[ -\mathbf{M}^{-1} = (\mathbf{S}^{-1}_{1})_{vv} -\] -% -Since the mesh associated with higher order methods is relatively coarse -compared with traditional finite element discretisations, the linear space can -usually be directly inverted without memory issues. However such a methodology -can be prohibitive on large parallel systems, due to a bottleneck in -communication. - -In \nekpp the inversion of the linear space present is handled using the -$XX^{T}$ library. $XX^{T}$ is a parallel direct solver for problems of the form -$\mathbf{A}\hat{\mathbf{x}} = \hat{\mathbf{b}}$ based around a sparse -factorisation of the inverse of $\mathbf{A}$. To precondition utilising this -methodology the linear sub-space is gathered from the expansion and the -preconditioned residual within the CG routine is determined by solving -% -\[ -(\mathbf{S}_{1})_{vv}\hat{\mathbf{z}}=\hat{\mathbf{r}} -\] -% -The preconditioned residual $\hat{\mathbf{z}}$ is then scattered back to the -respective location in the global degrees of freedom. - -\subsubsection{Block} - -Block preconditioning of the $C^0$ continuous system is defined by the -following: -% -\[ -\mathbf{M}^{-1}=\left[ \begin{array}{ccc} -(\mathbf{S}^{-1}_{1})_{vv} & 0 & 0 \\ -0 & (\mathbf{S}^{-1}_{1})_{eb} & 0\\ -0 & 0 & (\mathbf{S}^{-1}_{1})_{ef}\\ - \end{array} \right] -\] -% -where $\mathrm{diag}[(\mathbf{S}_{1})_{vv}]$ is the diagonal of the vertex -modes, $(\mathbf{S}_{1})_{eb}$ and $(\mathbf{S}_{1})_{fb}$ are block diagonal -matrices corresponding to coupling of an edge (or face) with itself i.e ignoring -the coupling to other edges and faces. This preconditioner is best suited for -two dimensional problems. - -In the HDG system, we take the block corresponding to each face and invert -it. Each of these inverse blocks then forms one of the diagonal components of -the block matrix $\mathbf{M}^{-1}$. - -\subsection{Low energy} - -Low energy basis preconditioning follows the methodology proposed by Sherwin \& -Casarin. In this method a new basis is numerically constructed from the original -basis which allows the Schur complement matrix to be preconditioned using a -block preconditioner. The method is outlined briefly in the following. - -Elementally the local approximation $\mathbf{u}^{\delta}$ can be expressed as -different expansions lying in the same discrete space $V^{\delta}$ -% -\[ -\mathbf{u}^{\delta}(\mathbf{x})=\sum_{i}^{\dim(V^{\delta})}\hat{u}_{1i}\phi_{1i}(x) -= \sum_{i}^{\dim(V^{\delta})}\hat{u}_{2i}\phi_{2j}(x) -\] -% -Since both expansions lie in the same space it's possible to express one basis -in terms of the other via a transformation, i.e. -% -\[ -\phi_{2}=\mathbf{C}\phi_{1} \implies \hat{\mathbf{u}}_{1}=C^{T}\hat{\mathbf{u}}_{2} -\] -% -Applying this to the Helmholtz operator it is possible to show that, -% -\[ -\mathbf{H}_{2}=\mathbf{C}\mathbf{H}_{1}\mathbf{C}^{T} -\] -% -For sub-structured matrices ($\mathbf{S}$) the transformation matrix -($\mathbf{C}$) becomes: -% -\[ -\mathbf{C}=\left[ \begin{array}{cc} -\mathbf{R} & 0\\ -0 & \mathbf{I} - \end{array} \right] -\] -% -Hence the transformation in terms of the Schur complement matrices is: -% -\[ -\mathbf{S}_{2}=\mathbf{R}\mathbf{S}_{1}\mathbf{R}^{T} -\] -% -Typically the choice of expansion basis $\phi_{1}$ can lead to a Helmholtz -matrix that has undesirable properties i.e poor condition number. By choosing a -suitable transformation matrix $\mathbf{C}$ it is possible to construct a new -basis, numerically, that is amenable to block diagonal preconditioning. -% -\[ -\mathbf{S}_{1}=\left[ \begin{array}{ccc} -\mathbf{S}_{vv} & \mathbf{S}_{ve} & \mathbf{S}_{vf}\\ -\mathbf{S}^{T}_{ve}& \mathbf{S}_{ee} & \mathbf{S}_{ef} \\ -\mathbf{S}^{T}_{vf} & \mathbf{S}^{T}_{ef} & \mathbf{S}_{ff} \end{array} \right] =\left[ \begin{array}{cc} -\mathbf{S}_{vv} & \mathbf{S}_{v,ef} \\ -\mathbf{S}^{T}_{v,ef} & \mathbf{S}_{ef,ef} \end{array} \right] -\] -% -Applying the transformation -$\mathbf{S}_{2}=\mathbf{R} \mathbf{S}_{1} \mathbf{R}^{T}$ leads to the following -matrix -% -\[ -\mathbf{S}_{2}=\left[ \begin{array}{cc} -\mathbf{S}_{vv}+\mathbf{R}_{v}\mathbf{S}^{T}_{v,ef}+\mathbf{S}_{v,ef}\mathbf{R}^{T}_{v}+\mathbf{R}_{v}\mathbf{S}_{ef,ef}\mathbf{R}^{T}_{v} & [\mathbf{S}_{v,ef}+\mathbf{R}_{v}\mathbf{S}_{ef,ef}]\mathbf{A}^{T} \\ -\mathbf{A}[\mathbf{S}^{T}_{v,ef}+\mathbf{S}_{ef,ef}\mathbf{R}^{T}_{v}] & \mathbf{A}\mathbf{S}_{ef,ef}\mathbf{A}^{T} \end{array} \right] -\] -% -where $\mathbf{A}\mathbf{S}_{ef,ef}\mathbf{A}^{T}$ is given by -% -\[ -\mathbf{A}\mathbf{S}_{ef,ef}\mathbf{A}^{T}=\left[ \begin{array}{cc} -\mathbf{S}_{ee}+\mathbf{R}_{ef}\mathbf{S}^{T}_{ef}+\mathbf{S}_{ef}\mathbf{R}^{T}_{ef}+\mathbf{R}_{ef}\mathbf{S}_{ff}\mathbf{R}^{T}_{ef} & \mathbf{S}_{ef}+\mathbf{R}_{ef}\mathbf{S}_{ff}\\ -\mathbf{S}^{T}_{ef}+\mathbf{S}_{ff}\mathbf{R}^{T}_{ef} & \mathbf{S}_{ff} - \end{array} \right] -\] -% -To orthogonalise the vertex-edge and vertex-face modes, it can be seen from the -above that -% -\[ -\mathbf{R}^{T}_{ef}=-\mathbf{S}^{-1}_{ff}\mathbf{S}^{T}_{ef} -\] -% -and for the edge-face modes: -% -\[ -\mathbf{R}^{T}_{v}=-\mathbf{S}^{-1}_{ef,ef}\mathbf{S}^{T}_{v,ef} -\] -% -Here it is important to consider the form of the expansion basis since the -presence of $\mathbf{S}^{-1}_{ff}$ will lead to a new basis which has support on -all other faces; this is problematic when creating a $C^{0}$ continuous global -basis. To circumvent this problem when forming the new basis, the decoupling is -only performed between a specific edge and the two adjacent faces in a symmetric -standard region. Since the decoupling is performed in a rotationally symmetric -standard region the basis does not take into account the Jacobian mapping -between the local element and global coordinates, hence the final expansion will -not be completely orthogonal. - -The low energy basis creates a Schur complement matrix that although it is not -completely orthogonal can be spectrally approximated by its block diagonal -contribution. The final form of the preconditioner is: -% -\[ -\mathbf{M}^{-1}=\left[ \begin{array}{ccc} -\mathrm{diag}[(\mathbf{S}_{2})_{vv}] & 0 & 0 \\ -0 & (\mathbf{S}_{2})_{eb} & 0\\ -0 & 0 & (\mathbf{S}_{2})_{fb}\\ - \end{array} \right]^{-1} -\] -% -where $\mathrm{diag}[(\mathbf{S}_{2})_{vv}]$ is the diagonal of the vertex -modes, $(\mathbf{S}_{2})_{eb}$ and $(\mathbf{S}_{2})_{fb}$ are block diagonal -matrices corresponding to coupling of an edge (or face) with itself i.e ignoring -the coupling to other edges and faces. diff --git a/docs/developer-guide/data-structures-algorithms/time-integration.tex b/docs/developer-guide/data-structures-algorithms/time-integration.tex deleted file mode 100644 index fc653ec7ca4664f8e96390c8dc04c1951cc531ee..0000000000000000000000000000000000000000 --- a/docs/developer-guide/data-structures-algorithms/time-integration.tex +++ /dev/null @@ -1,908 +0,0 @@ -\section{Time integration} -This page discusses the implementation of time-integration in Nektar++. - -\subsection{General Linear Methods} -General linear methods (GLMs) can be considered as the generalization of a broad -range of different numerical methods for ordinary differential equations. They -were introduced by Butcher and they provide a unified formulation for -traditional methods such as the Runge-Kutta methods and the linear multi-step -methods. From an implementation point of view, this means that all these -numerical methods can be abstracted in a similar way. As this allows a high -level of generality, it is chosen in Nektar++ to cast all time integration -schemes in the framework of general linear methods. - -For background information about general linear methods, please consult -\cite{Bu06} - -\subsection{Introduction} -The standard initial value problem can written in the form -\begin{align*} -\frac{d\boldsymbol{y}}{dt} = \boldsymbol{f}(t,\boldsymbol{y}),\quad -\boldsymbol{y}(t_0)=\boldsymbol{y}_0 -\end{align*} -where $\boldsymbol{y}$ is a vector containing the variable (or an -array of array contianing the variables). - -In the formulation of general linear methods, it is more convenient to consider -the ODE in autonomous form, i.e. -\begin{align*} -\frac{d\boldsymbol{\hat{y}}}{dt}=\boldsymbol{\hat{f}}(\boldsymbol{\hat{y}}),\quad -\boldsymbol{\hat{y}}(t_0)= \boldsymbol{\hat{y}}_0. -\end{align*} - -\subsection{Formulation} -Suppose the governing differential equation is given in autonomous form, the -$n^{th}$ step of the GLM comprising -\begin{itemize} -\item $r$ steps (as in a multi-step method) -\item $s$ stages (as in a Runge-Kutta method) -\end{itemize} -is formulated as: -\begin{align*} -\boldsymbol{Y}_i &= \Delta -t\sum_{j=0}^{s-1}a_{ij}\boldsymbol{F}_j+\sum_{j=0}^{r-1}u_{ij}\boldsymbol{\hat{y}}_{j}^{[n-1]}, -\qquad i=0,1,\ldots,s-1 \\ -\boldsymbol{\hat{y}}_{i}^{[n]}&=\Delta -t\sum_{j=0}^{s-1}b_{ij}\boldsymbol{F}_j+\sum_{j=0}^{r-1}v_{ij} -\boldsymbol{\hat{y}}_{j}^{[n-1]}, \qquad i=0,1,\ldots,r-1 -\end{align*} -where $\boldsymbol{Y}_i$ are referred to as the stage values and -$\boldsymbol{F}_j$ as the stage derivatives. Both quantities are -related by the differential equation: -\begin{align*} -\boldsymbol{F}_i = \boldsymbol{\hat{f}}(\boldsymbol{Y}_i). -\end{align*} - -The matrices $A=[a_{ij}]$, $U=[u_{ij}]$, -$B=[b_{ij}]$, $V=[v_{ij}]$ are characteristic of a -specific method. Each scheme can then be uniquely defined by a partioned -$(s+r)\times(s+r)$ matrix -\begin{align*} -\left[ -\begin{array}{cc} - A & U\\ - B & V \end{array}\right] -\end{align*} - - -\subsection{Matrix notation} -Adopting the notation: -\begin{align*} -\boldsymbol{\hat{y}}^{[n-1]}= \left[\begin{array}{c} -\boldsymbol{\hat{y}}^{[n-1]}_0\\ -\boldsymbol{\hat{y}}^{[n-1]}_1\\ -\vdots\\ -\boldsymbol{\hat{y}}^{[n-1]}_{r-1} -\end{array}\right],\quad \boldsymbol{\hat{y}}^{[n]}= \left[\begin{array}{c} -\boldsymbol{\hat{y}}^{[n]}_0\\ -\boldsymbol{\hat{y}}^{[n]}_1\\ -\vdots\\ -\boldsymbol{\hat{y}}^{[n]}_{r-1} -\end{array}\right],\quad \boldsymbol{Y}= \left[\begin{array}{c} -\boldsymbol{Y}_0\\ -\boldsymbol{Y}_1\\ -\vdots\\ -\boldsymbol{Y}_{s-1} -\end{array}\right],\quad \boldsymbol{F}= \left[\begin{array}{c} -\boldsymbol{F}_0\\ -\boldsymbol{F}_1\\ -\vdots\\ -\boldsymbol{F}_{s-1} -\end{array}\right]\quad -\end{align*} -the general linear method can be written more compactly in the following form: -\begin{align*} -\left[ \begin{array}{c} \boldsymbol{Y}\\ -\boldsymbol{\hat{y}}^{[n]} -\end{array}\right] = \left[ \begin{array}{cc} A\otimes I_N & U\otimes I_N \\ -B\otimes I_N & V\otimes I_N \end{array}\right] \left[ \begin{array}{c} \Delta -t\boldsymbol{F}\\ -\boldsymbol{\hat{y}}^{[n-1]} -\end{array}\right] -\end{align*} -where $I_N$ is the identity matrix of dimension $N\times N$. - - -\subsection{General Linear Methods in Nektar++} -Although the GLM is essentially presented for ODE's in its autonomous form, in -Nektar++ it will be used to solve ODE's formulated in non-autonomous form. -Given the ODE, -\begin{align*} -\frac{d\boldsymbol{y}}{dt}=\boldsymbol{f}(t,\boldsymbol{y}),\quad -\boldsymbol{y}(t_0)=\boldsymbol{y}_0 -\end{align*} -a single step of GLM can then be evaluated in the following way: -\begin{itemize} -\item \textbf{input} - -$\boldsymbol{y}^{[n-1]}$, \emph{i.e.} the $r$ - subvectors comprising $\boldsymbol{y}^{[n-1]}_i$ - - $t^{[n-1]}$, \emph{i.e.} the equivalent of - $\boldsymbol{y}^{[n-1]}$ for the time variable $t$. - -\item \textbf{step 1}: The stage values $\boldsymbol{Y}_i$, -$\boldsymbol{T}_i$ and the stage derivatives -$\boldsymbol{F}_i$ are calculated through the relations: -\begin{enumerate} -\item $\boldsymbol{Y}_i = \Delta - t\sum_{j=0}^{s-1}a_{ij}\boldsymbol{F}_j+\sum_{j=0}^{r-1}u_{ij}\boldsymbol{y}_{j}^{[n-1]}, - \qquad i=0,1,\ldots,s-1$ -\item $T_i\ =\ \Delta - t\sum_{j=0}^{s-1}a_{ij}+\sum_{j=0}^{r-1}u_{ij}t_{j}^{[n-1]}, \qquad - i=0,1,\ldots,s-1$ -\item $\boldsymbol{F}_i\ =\ - f(T_i,\boldsymbol{Y}_i), \qquad i=0,1,\ldots,s-1$ -\end{enumerate} - -\item \textbf{step 2}: The approximation at the new time level -$\boldsymbol{y}^{[n]}$ is calculated as a linear combination of the -stage derivatives $\boldsymbol{F}_i$ and the input vector -$\boldsymbol{y}^{[n-1]}$. In addition, the time vector -$t^{[n]}$ is also updated - -\begin{enumerate} -\item $\boldsymbol{y}_{i}^{[n]} = \Delta - t\sum_{j=0}^{s-1}b_{ij}\boldsymbol{F}_j+\sum_{j=0}^{r-1}v_{ij}\boldsymbol{y}_{j}^{[n-1]}, - \qquad i=0,1,\ldots,r-1$ -\item $t_{i}^{[n]}\ =\ \Delta - t\sum_{j=0}^{s-1}b_{ij}+\sum_{j=0}^{r-1}v_{ij}t_{j}^{[n-1]}, \qquad - i=0,1,\ldots,r-1$ -\end{enumerate} - -\item \textbf{output} -\begin{enumerate} -\item $\boldsymbol{y}^{[n]}$, i.e. the $r$ subvectors - comprising $\boldsymbol{y}^{[n]}_i$. - $\boldsymbol{y}^{[n]}_0$ corresponds to the actual approximation - at the new time level. -\item $t^{[n]}$ where $t^{[n]}_0$ is equal to the new time - level $t+\Delta t$. -\end{enumerate} -\end{itemize} - -For a detailed describtion of the formulation and a deeper insight of the -numerical method see \cite{VoEsBoChKi11}. - - -\subsection{Types of time Integration Schemes} -Nektar++ contains various classes and methods which implement the concept of -GLMs. This toolbox is capable of numerically solving the generalised ODE using a -broad range of different time-stepping methods. We distinguish the following -types of general linear methods: -\begin{itemize} -\item \textbf{Formally Explicit Methods}: These types of methods are -considered explicit from an ODE point of view. They are characterised by a lower - triangular coefficient matrix $A$, ''i.e.'' $a_{ij} = 0$ - for $j\geq i$. To avoid confusion, we make a further distinction: - \begin{itemize} - \item \textbf{direct explicit method}: Only forward operators are required. - \item \textbf{indirect explicit method}: The inverse operator is required. - \end{itemize} - \item \textbf{Diagonally Implicit Methods}: Compared to explicit methods, - the coefficient matrix $A$ has now non-zero entries on the diagonal. - This means that each stage value depend on the stage derivative at the same - stage, requiring an implicit step. However, the calculation of the different - stage values is still uncoupled. Best known are the DIRK schemes. - \item \textbf{IMEX schemes}: These schemes support the concept of being able - to split right hand forcing term into an explicit and implicit component. This is - useful in advection diffusion type problems where the advection is handled - explicity and the diffusion is handled implicit. - \item \textbf{Fully Implicit Methods Methods}: The coefficient matrix has a - non-zero upper triangular part. The calculation of all stages values is fully coupled. -\end{itemize} - -The aim in Nektar++ is to fully support the first three types of GLMs. -Fully implicit methods are currently not implemented. - -\subsection{Usage} -The goal of abstracting the concept of general linear methods is to provide -users with a single interface for time-stepping, independent of the chosen -method. The classes tree allows the user to numerically integrate ODE's using -high-order complex schemes, as if it was done using the Forward-Euler method. -Switching between time-stepping schemes is as easy as changing a parameter in an -input file. - -In the already implemented solvers the time-integration schemes have been set up -according to the nature of the equations. -For example the incompressible Navier-Stokes equations solver allows the use of -three different Implicit-Explicit time-schemes if solving the equations with a -splitting-scheme. -This is because this kind of scheme has an explicit and an implicit operator -that combined solve the ODE's system. - -Once aware of the problem's nature and implementation, the user can easily -switch between some (depending on the problem) of the following -time-integration schemes: - -\begin{center} -\footnotesize -\begin{tabular}{p{4cm}p{10cm}} -\toprule -AdamsBashforthOrder1 & Adams-Bashforth Forward multi-step scheme of order 1\\ -AdamsBashforthOrder2 & Adams-Bashforth Forward multi-step scheme of order 2\\ -AdamsBashforthOrder3 & Adams-Bashforth Forward multi-step scheme of order 3\\ -AdamsMoultonOrder1 & Adams-Moulton Forward multi-step scheme of order 1\\ -AdamsMoultonOrder2 & Adams-Moulton Forward multi-step scheme of order 2\\ -BDFImplicitOrder2 & BDF multi-step scheme of order 2 (implicit)\\ -ClassicalRungeKutta4 & Runge-Kutta multi-stage scheme 4th order explicit\\ -RungeKutta2\_ModifiedEuler & Runge-Kutta multi-stage scheme 2nd order explicit\\ -RungeKutta2\_ImprovedEuler & Runge-Kutta multi-stage scheme 2nd order explicit\\ -ForwardEuler & Forward-Euler scheme\\ -BackwardEuler & Backward Euler scheme\\ -IMEXOrder1 & IMEX 1st order scheme using Euler Backwards Euler - Forwards \\ -IMEXOrder2 & IMEX 2nd order scheme using Backward Different Formula \& - Extrapolation\\ -IMEXOrder3 & IMEX 3rd order scheme using Backward Different Formula \& - Extrapolation\\ -Midpoint & Midpoint method\\ -DIRKOrder2 & Diagonally Implicit Runge-Kutta scheme of order 2\\ -DIRKOrder3 & Diagonally Implicit Runge-Kutta scheme of order 3\\ -CNAB & Crank-Nicolson-Adams-Bashforth Order 2 (CNAB)\\ -IMEXGear & IMEX Gear Order 2\\ -MCNAB & Modified Crank-Nicolson-Adams-Bashforth Order 2 (MCNAB)\\ -IMEXdirk\_1\_1\_1 & Forward-Backward Euler IMEX DIRK(1,1,1)\\ -IMEXdirk\_1\_2\_1 & Forward-Backward Euler IMEX DIRK(1,2,1)\\ -IMEXdirk\_1\_2\_2 & Implicit-Explicit Midpoint IMEX DIRK(1,2,2)\\ -IMEXdirk\_2\_2\_2 & L-stable, two stage, second order IMEX DIRK(2,2,2)\\ -IMEXdirk\_2\_3\_2 & L-stable, three stage, third order IMEX DIRK(3,4,3)\\ -IMEXdirk\_2\_3\_3 & L-stable, two stage, third order IMEX DIRK(2,3,3)\\ -IMEXdirk\_3\_4\_3 & L-stable, three stage, third order IMEX DIRK(3,4,3)\\ -IMEXdirk\_4\_4\_3 & L-stable, four stage, third order IMEX DIRK(4,4,3)\\ -\bottomrule -\end{tabular} -\end{center} - -Nektar++ input file for your problem will ask you just the string corresponding -the time-stepping scheme you want to use (between quotation marks in the -previous list), and few parameters to define your integration in time (time-step -and number of steps or final time). For example:\\ -\begin{lstlisting}[style=XMLStyle] - - - - - - - - - -

TimeStep = 0.001

-

NumSteps = 1000

-

Kinvis = 1

-
-\end{lstlisting} - - -\subsection{Implementation of a time-dependent problem} -In order to implement a new solver which takes advantage of the time-integration -class in Nektar++, two main ingredients are required: -\begin{itemize} -\item A main files in which the time-integration of you ODE's system is -initialized and performed. -\item A class representing the spatial discretization of your problem, which -reduces your system of PDE's to a system of ODE's. -\end{itemize} - -Your pseudo-main file, where you actually loop over the time steps, will look -like -\begin{lstlisting}[style=C++Style] -NekDouble timestep = 0.1; -NekDouble time = 0.0; -int NumSteps = 1000; - -YourClass solver(Input); - -LibUtilities::TimeIntegrationMethod TIME_SCHEME; -LibUtilities::TimeIntegrationSchemeOperators ODE; - -ODE.DefineOdeRhs(&YourClass::YourExplicitOperatorFunction,solver); -ODE.DefineProjection(&YourClass::YourProjectionFunction,solver); -ODE.DefineImplicitSolve(&YourClass::YourImplicitOperatorFunction,solver); - -Array IntScheme; - -LibUtilities::TimeIntegrationSolutionSharedPtr ode_solution; - -Array > U; - -TIME_SCHEME = LibUtilities::eForwardEuler; -int numMultiSteps=1; -IntScheme = Array(numMultiSteps); -LibUtilities::TimeIntegrationSchemeKey IntKey(TIME_SCHEME); -IntScheme[0] = LibUtilities::TimeIntegrationSchemeManager()[IntKey]; -ode_solution = IntScheme[0]->InitializeScheme(timestep,U,time,ODE); - -for(int n = 0; n < NumSteps; ++n) { - U = IntScheme[0]->TimeIntegrate(timestep,ode_solution,ODE); -} -\end{lstlisting} - -We can distinguish three different sections in the code above - -\subsubsection{Definitions} -\begin{lstlisting}[style=C++Style] -NekDouble timestep = 0.1; -NekDouble time = 0.0; -int NumSteps = 1000; - -YourClass equation(Input); - -LibUtilities::TimeIntegrationMethod TIME_SCHEME; -LibUtilities::TimeIntegrationSchemeOperators ODE; - -ODE.DefineOdeRhs(&YourClass::YourExplicitOperatorFunction,equation); -ODE.DefineProjection(&YourClass::YourProjectionFunction, equation); -ODE.DefineImplicitSolve(&YourClass::YourImplicitOperatorFunction, equation); -\end{lstlisting} -In this section you define the basic parameters (like time-step, initial time, -etc.) and the time-integration objects. -The operators are not all required, it depends on the nature of your problem and -on the type of time integration schemes you want to use. In this case, the -problem has been set up to work just with Forward-Euler, then for sure you will -not need the implicit operator. -An object named \texttt{equation} has been initialized, is an object of type -\texttt{YourClass}, where your spatial discretization and the functions which -actually represent your operators are implemented. An example of this class will -be shown later in this page. - -\subsubsection{Initialisations} -\begin{lstlisting}[style=C++Style] -Array IntScheme; - -LibUtilities::TimeIntegrationSolutionSharedPtr ode_solution; - -Array > U; - -TIME_SCHEME = LibUtilities::eForwardEuler; -int numMultiSteps=1; -IntScheme = Array(numMultiSteps); -LibUtilities::TimeIntegrationSchemeKey IntKey(TIME_SCHEME); -IntScheme[0] = LibUtilities::TimeIntegrationSchemeManager()[IntKey]; -ode_solution = IntScheme[0]->InitializeScheme(timestep,U,time,ODE); -\end{lstlisting} -The second part consists in the scheme initialization. In this example we set up -just Forward-Euler, but we can set up more then one time-integration scheme and -quickly switch between them from the input file. -Forward-Euler does not require any other scheme for the start-up procedure. High -order multi-step schemes may need lower-order schemes for the start up. - -\subsubsection{Integration} -\begin{lstlisting}[style=C++Style] -for(int n = 0; n < NumSteps; ++n) { - U = IntScheme[0]->TimeIntegrate(timestep,ode_solution,ODE); -} -\end{lstlisting} -The last step is the typical time-loop, where you iterate in time to get -your new solution at each time-level. -The solution at time $t^{n+1}$ is stored into vector \texttt{U} (you need -to properly initialize this vector). -\texttt{U} is an Array of Arrays, where the first dimension corresponds to -the number of variables (eg. u,v,w) and the second dimension corresponds to the -variables size (e.g. the number of modes or the number of physical points). - -The variable \texttt{ODE} is an object which contains the methods. A class -representing a PDE equation (or a system of equations) must have a series of -functions representing the implicit/explicit part of the method, which -represents the reduction of the PDE's to a system of ODE's. -The spatial discretization and the definition of this method should be -implemented in \texttt{YourClass}. -\texttt{\&YourClass::YourExplicitOperatorFunction} is a functor, i.e. a pointer -to a function where the method is implemented. \texttt{equation} is a pointer -to the object, i.e. the class, where the function/method is implemented. -Here a pseudo-example of the .h file of your hypothetical class representing the -set of equations. -The implementation of the functions is meant to be in the related .cpp file. - -\begin{lstlisting}[style=C++Style] -class YourCalss -{ -public: - YourClass(INPUT); - - ~YourClass(void); - - void YourExplicitOperatorFunction( - const Array > & inarray, - Array > & outarray, - const NekDouble time); - - void YourProjectionFunction( - const Array > & inarray, - Array > & outarray, const - NekDouble time); - - void YourImplicitOperatorFunction( - const Array > & inarray, - Array > & outarray, const - NekDouble time, - const NekDouble lambda); - - void InternalMethod1(...); - - NekDouble internalvariale1; - -protected: - ... - -private: - ... -}; -\end{lstlisting} - - -\subsection{Strongly imposed essential boundary conditions} -Dirichlet boundary conditions can be strongly imposed by lifting the known -Dirichlet solution. -This is equivalent to decompose the approximate solution $y$ into an -known part, $y^{\mathcal{D}}$, which satisfies the Dirichlet boundary -conditions, and an unknown part, $y^{\mathcal{H}}$, which is zero on -the Dirichlet boundaries, i.e. -\begin{align*} -y = y^{\mathcal{D}} + y^{\mathcal{H}} -\end{align*} - -In a Finite Element discretisation, this corresponds to splitting the solution -vector of coefficients $\boldsymbol{y}$ into the known Dirichlet -degrees of freedom $\boldsymbol{y}^{\mathcal{D}}$ and the unknown -homogeneous degrees of freedom $\boldsymbol{y}^{\mathcal{H}}$. -Ordering the known coefficients first, this corresponds to: -\begin{align*} -\boldsymbol{y} = \left[ \begin{array}{c} -\boldsymbol{y}^{\mathcal{D}} \\ -\boldsymbol{y}^{\mathcal{H}} \end{array} \right] -\end{align*} - -The generalised formulation of the general linear method (i.e. the introduction -of a left hand side operator) allows for an easier treatment of these types of -boundary conditions. To better appreciate this, consider the equation for the -stage values for an explicit general linear method where both the left and right -hand side operator are linear operators, i.e. they can be represented by a -matrix. -\begin{align*} -\boldsymbol{M}\boldsymbol{Y}_i = \Delta -t\sum_{j=0}^{i-1}a_{ij}\boldsymbol{L}\boldsymbol{Y}_j+\sum_{j=0}^{r-1}u_{ij}\boldsymbol{y}_{j}^{[n-1]}, -\qquad i=0,1,\ldots,s-1 -\end{align*} - -In case of a lifted known solution, this can be written as: -\begin{align*} -\left[ \begin{array}{cc} -\boldsymbol{M}^{\mathcal{DD}} & \boldsymbol{M}^{\mathcal{DH}} \\ -\boldsymbol{M}^{\mathcal{HD}} & \boldsymbol{M}^{\mathcal{HH}} \end{array} \right] -\left[ \begin{array}{c} -\boldsymbol{Y}^{\mathcal{D}}_i \\ -\boldsymbol{Y}^{\mathcal{H}}_i \end{array} \right] -= \Delta t\sum_{j=0}^{i-1}a_{ij} -\left[ \begin{array}{cc} -\boldsymbol{L}^{\mathcal{DD}} & \boldsymbol{L}^{\mathcal{DH}} \\ -\boldsymbol{L}^{\mathcal{HD}} & \boldsymbol{L}^{\mathcal{HH}} \end{array} \right] -\left[ \begin{array}{c} -\boldsymbol{Y}^{\mathcal{D}}_j \\ -\boldsymbol{Y}^{\mathcal{H}}_j \end{array} \right] -+\sum_{j=0}^{r-1}u_{ij} -\left[ \begin{array}{c} -\boldsymbol{y}^{\mathcal{D}[n-1]}_j \\ -\boldsymbol{y}^{\mathcal{H}[n-1]}_j \end{array} \right],\\ -\qquad i=0,1,\ldots,s-1 -\end{align*} - -In order to calculate the stage values correctly, the explicit operator -should now be implemented to do the following: -\begin{align*} -\left[ \begin{array}{c} -\boldsymbol{b}^{\mathcal{D}} \\ -\boldsymbol{b}^{\mathcal{H}} \end{array} \right] -= -\left[ \begin{array}{cc} -\boldsymbol{L}^{\mathcal{DD}} & \boldsymbol{L}^{\mathcal{DH}} \\ -\boldsymbol{L}^{\mathcal{HD}} & \boldsymbol{L}^{\mathcal{HH}} \end{array} \right] -\left[ \begin{array}{c} -\boldsymbol{y}^{\mathcal{D}} \\ -\boldsymbol{y}^{\mathcal{H}} \end{array} \right] -\end{align*} - -Note that only the homogeneous part $\boldsymbol{b}^{\mathcal{H}}$ will be used -to calculate the stage values. This means essentially that only the bottom part -of the operation above, i.e. -$\boldsymbol{L}^{\mathcal{HD}}\boldsymbol{y}^{\mathcal{D}} + -\boldsymbol{L}^{\mathcal{HH}}\boldsymbol{y}^{\mathcal{H}}$ is required. However, -sometimes it might be more convenient to use/implement routines for the explicit -operator that also calculate $\boldsymbol{b}^{\mathcal{D}}$.\\ - -An implicit method should solve the system: -\begin{align*} -\left(\left[ \begin{array}{cc} -\boldsymbol{M}^{\mathcal{DD}} & \boldsymbol{M}^{\mathcal{DH}} \\ -\boldsymbol{M}^{\mathcal{HD}} & \boldsymbol{M}^{\mathcal{HH}} \end{array} \right] -- \lambda \left[ \begin{array}{cc} -\boldsymbol{L}^{\mathcal{DD}} & \boldsymbol{L}^{\mathcal{DH}} \\ -\boldsymbol{L}^{\mathcal{HD}} & \boldsymbol{L}^{\mathcal{HH}} \end{array} \right]\right) -\left[ \begin{array}{c} -\boldsymbol{y}^{\mathcal{D}} \\ -\boldsymbol{y}^{\mathcal{H}} \end{array} \right] -= -\left[ \begin{array}{cc} -\boldsymbol{H}^{\mathcal{DD}} & \boldsymbol{H}^{\mathcal{DH}} \\ -\boldsymbol{H}^{\mathcal{HD}} & \boldsymbol{H}^{\mathcal{HH}} \end{array} \right] -\left[ \begin{array}{c} -\boldsymbol{y}^{\mathcal{D}} \\ -\boldsymbol{y}^{\mathcal{H}} \end{array} \right] -= -\left[ \begin{array}{c} -\boldsymbol{b}^{\mathcal{D}} \\ -\boldsymbol{b}^{\mathcal{H}} \end{array} \right] -\end{align*} - -for the unknown vector $\boldsymbol{y}$. This can be done in three steps: -\begin{itemize} -\item Set the known solution $\boldsymbol{y}^{\mathcal{D}}$ -\item Calculate the modified right hand side term - $\boldsymbol{b}^{\mathcal{H}} - - \boldsymbol{H}^{\mathcal{HD}}\boldsymbol{y}^{\mathcal{D}}$ -\item Solve the system below for the unknown - $\boldsymbol{y}^{\mathcal{H}}$, i.e. - $\boldsymbol{H}^{\mathcal{HH}}\boldsymbol{y}^{\mathcal{H}} = - \boldsymbol{b}^{\mathcal{H}} - - \boldsymbol{H}^{\mathcal{HD}}\boldsymbol{y}^{\mathcal{D}}$ -\end{itemize} - -\subsection{How to add a new time-stepping method} - -To add a new time integration scheme, follow the steps below: -\begin{itemize} -\item Choose a name for the method and add it to the -\texttt{TimeIntegrationMethod} enum list. -\item Populate the switch statement in the \texttt{TimeIntegrationScheme} -constructor with the coefficients of the new method. -\item Use ( or modify) the function \texttt{InitializeScheme} to select (or -implement) a proper initialisation strategy for the method. -\item Add documentation for the method (especially indicating what the auxiliary - parameters of the input and output vectors of the multi-step method represent) -\end{itemize} - -\subsection{Examples of already implemented time stepping schemes} - -Here we show some examples time-stepping shemes implemented in Nektar++, to give an idea of what is required -to add one of them. - -\subsubsection{Forward Euler} -\begin{align*} -\left[\begin{array}{c|c} -A & U \\ -\hline -B & V -\end{array}\right] = -\left[\begin{array}{c|c} -0 & 1 \\ -\hline -1 & 1 -\end{array}\right],\qquad -\boldsymbol{y}^{[n]}= -\left[\begin{array}{c} -\boldsymbol{y}^{[n]}_0 -\end{array}\right]= -\left[\begin{array}{c} -\boldsymbol{m}\left(t^n,\boldsymbol{y}^{n}\right) -\end{array}\right] -\end{align*} - -\subsubsection{Backward Euler} -\begin{align*} -\left[\begin{array}{c|c} -A & U \\ -\hline - B & V -\end{array}\right] = -\left[\begin{array}{c|c} -1 & 1 \\ -\hline -1 & 1 -\end{array}\right],\qquad -\boldsymbol{y}^{[n]}= -\left[\begin{array}{c} -\boldsymbol{y}^{[n]}_0 -\end{array}\right]= -\left[\begin{array}{c} -\boldsymbol{m}\left(t^n,\boldsymbol{y}^{n}\right) -\end{array}\right] -\end{align*} - -\subsubsection{2nd order Adams Bashforth} -\begin{align*} -\left[\begin{array}{c|c} -A & U \\ -\hline -B & V -\end{array}\right] = -\left[\begin{array}{c|cc} -0 & 1 & 0 \\ -\hline -\frac{3}{2} & 1 & \frac{-1}{2} \\ -1 & 0 & 0 -\end{array}\right],\qquad -\boldsymbol{y}^{[n]}= -\left[\begin{array}{c} -\boldsymbol{y}^{[n]}_0\\ -\boldsymbol{y}^{[n]}_1\\ -\end{array}\right]= -\left[\begin{array}{c} -\boldsymbol{m}\left(t^n,\boldsymbol{y}^{n}\right)\\ -\Delta t \boldsymbol{l}(t^{n-1},\boldsymbol{y}^{n-1}) -\end{array}\right] -\end{align*} - -\subsubsection{1st order IMEX Euler backwards/ Euler Forwards} -\begin{align*} -\left[ \begin{array}{cc|c} -A^{\mathrm{IM}} & A^{\mathrm{EM}} & U \\ -\hline -B^{\mathrm{IM}} & B^{\mathrm{EM}} & V -\end{array} \right ] = -\left[\begin{array}{cc|c} -\left [ \begin{array}{c} 1 \end{array} \right ] & \left [ \begin{array}{c} 0 \end{array} \right ] & -\left [ \begin{array}{cc} 1 & 1 \end{array} \right ] \\ -\hline -\left [ \begin{array}{c} 1 \\ 0 \end{array} \right ] & \left [ \begin{array}{c} 0 \\ 1 \end{array} \right ]& -\left [ \begin{array}{cc} 1 & 1 \\ 0 & 0 \end{array} \right ] -\end{array}\right] \quad \mathrm{with}\quad -\boldsymbol{y}^{[n]}= -\left[\begin{array}{c} -\boldsymbol{y}^{[n]}_0\\ -\boldsymbol{y}^{[n]}_1 -\end{array}\right]= -\left[\begin{array}{c} -\boldsymbol{m}\left(t^n,\boldsymbol{y}^{n}\right)\\ -\Delta t \boldsymbol{l}\left ( t^n, \boldsymbol{y}^{n}\right) -\end{array}\right] -\end{align*} - -\subsubsection{2nd order IMEX Backward Different Formula \& Extrapolation} -\begin{align*} -\left[ \begin{array}{cc|c} -A^{\mathrm{IM}} & A^{\mathrm{EM}} & U \\ -\hline -B^{\mathrm{IM}} & B^{\mathrm{EM}} & V -\end{array} \right ] = -\left[\begin{array}{cc|c} -\left [ \begin{array}{c} \frac{2}{3} \end{array} \right ] & \left [ \begin{array}{c} 0 \end{array} \right ] & -\left [ \begin{array}{cccc} \frac{4}{3} & -\frac{1}{3} & \frac{4}{3} & -\frac{2}{3} \end{array} \right ] \\ -\hline -\left [ \begin{array}{c} \frac{2}{3} \\ 0 \\ 0 \\ 0 \end{array} \right ] & \left [ \begin{array}{c} 0 \\0 \\ 1 \\ 0 \end{array} \right ]& -\left [ \begin{array}{cccc} \frac{4}{3} & -\frac{1}{3} & \frac{4}{3} & -\frac{2}{3} \\ 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0\\ 0 & 0 & 1 & 0 \end{array} \right ] -\end{array}\right] -\end{align*} -with -\begin{align*} -\boldsymbol{y}^{[n]}= -\left[\begin{array}{c} -\boldsymbol{y}^{[n]}_0\\ -\boldsymbol{y}^{[n]}_1 \\ -\boldsymbol{y}^{[n]}_2 \\ -\boldsymbol{y}^{[n]}_3 -\end{array}\right]= -\left[\begin{array}{l} -\boldsymbol{m}\left(t^n,\boldsymbol{y}^{n}\right)\\ -\boldsymbol{m}\left(t^{n-1},\boldsymbol{y}^{n-1}\right)\\ -\Delta t \boldsymbol{l}\left ( t^n, \boldsymbol{y}^{n}\right)\\ -\Delta t \boldsymbol{l}\left ( t^{n-1}, \boldsymbol{y}^{n-1}\right) -\end{array}\right] -\end{align*} - -\begin{notebox} -The first two rows are normalised so the coefficient on -$\boldsymbol{y}_n^{[n+1]}$ is one. In the standard formulation it is $3/2$. -\end{notebox} - -\subsubsection{3rdorder IMEX Backward Different Formula \& Extrapolation} -\begin{align*} - \left[ \begin{array}{cc|c} - A^{\mathrm{IM}} & A^{\mathrm{EM}} & U \\ - \hline - B^{\mathrm{IM}} & B^{\mathrm{EM}} & V - \end{array} \right ] = - \left[\begin{array}{cc|c} - \left [ \begin{array}{c} \frac{6}{11} \end{array} \right ] & \left [ \begin{array}{c} 0 \end{array} \right ] & - \left [ \begin{array}{cccccc} \frac{18}{11} & -\frac{9}{11} & \frac{2}{11} & \frac{18}{11} & -\frac{18}{11} & \frac{6}{11} \end{array} \right ] \\ - \hline - \left [ \begin{array}{c} \frac{6}{11}\\ 0 \\ 0 \\ 0 \\0 \\0 \end{array} \right ] & \left [ \begin{array}{c} 0 \\0 \\ 0 \\ 1 \\ 0 \\ 0 \end{array} \right ]& - \left [ \begin{array}{cccccc} \frac{18}{11} & -\frac{9}{11} & \frac{2}{11} & \frac{18}{11} & -\frac{18}{11} & \frac{6}{11} \\ 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 \end{array} \right ] - \end{array}\right] -\end{align*} -with -\begin{align*} - \boldsymbol{y}^{[n]}= - \left[\begin{array}{l} - \boldsymbol{y}^{[n]}_0 \\ - \boldsymbol{y}^{[n]}_1 \\ - \boldsymbol{y}^{[n]}_2 \\ - \boldsymbol{y}^{[n]}_3 \\ - \boldsymbol{y}^{[n]}_4 \\ - \boldsymbol{y}^{[n]}_5 - \end{array}\right]= - \left[\begin{array}{l} - \boldsymbol{m}\left(t^n,\boldsymbol{y}^{n}\right)\\ - \boldsymbol{m}\left(t^{n-1},\boldsymbol{y}^{n-1}\right)\\ - \boldsymbol{m}\left(t^{n-2},\boldsymbol{y}^{n-2}\right)\\ - \Delta t \boldsymbol{l}\left ( t^n, \boldsymbol{y}^{n}\right)\\ - \Delta t \boldsymbol{l}\left ( t^{n-1}, \boldsymbol{y}^{n-1}\right)\\ - \Delta t \boldsymbol{l}\left ( t^{n-2}, \boldsymbol{y}^{n-2}\right) - \end{array}\right] -\end{align*} - -\begin{notebox} -The first two rows are normalised so the coefficient on -$\boldsymbol{y}_n^{[n+1]}$ is one. In the standard formulation it is $11/6$. -\end{notebox} - -\subsubsection{2nd order Adams Moulton} -\begin{align*} - \left[\begin{array}{c|c} - A & U \\ - \hline - B & V - \end{array}\right] = - \left[\begin{array}{c|cc} - \frac{1}{2} & 1 & \frac{1}{2} \\ - \hline - \frac{1}{2} & 1 & \frac{1}{2} \\ - 1 & 0 & 0 - \end{array}\right],\qquad - \boldsymbol{y}^{[n]}= - \left[\begin{array}{c} - \boldsymbol{y}^{[n]}_0\\ - \boldsymbol{y}^{[n]}_1\\ - \end{array}\right]= - \left[\begin{array}{c} - \boldsymbol{m}\left(t^n,\boldsymbol{y}^{n}\right)\\ - \Delta t \boldsymbol{l}(t^{n},\boldsymbol{y}^{n}) - \end{array}\right] -\end{align*} - -\subsubsection{Midpoint method} -\begin{align*} - \left[\begin{array}{c|c} - A & U \\ - \hline - B & V - \end{array}\right] = - \left[\begin{array}{cc|c} - 0 & 0 & 1 \\ - \frac{1}{2} & 0 & 1 \\ - \hline - 0 & 1 & 1 - \end{array}\right],\qquad - \boldsymbol{y}^{[n]}= - \left[\begin{array}{c} - \boldsymbol{y}^{[n]}_0 - \end{array}\right]= - \left[\begin{array}{c} - \boldsymbol{m}\left(t^n,\boldsymbol{y}^{n}\right) - \end{array}\right] -\end{align*} - -\subsubsection{RK4: the standard fourth order Runge-Kutta scheme} -\begin{align*} - \left[\begin{array}{c|c} - A & U \\ - \hline - B & V - \end{array}\right] = - \left[\begin{array}{cccc|c} - 0 & 0 & 0 & 0 & 1 \\ - \frac{1}{2} & 0 & 0 & 0 & 1 \\ - 0 & \frac{1}{2} & 0 & 0 & 1 \\ - 0 & 0 & 1 & 0 & 1 \\ - \hline - \frac{1}{6} & \frac{1}{3} & \frac{1}{3} & \frac{1}{6} & 1 - \end{array}\right],\qquad - \boldsymbol{y}^{[n]}= - \left[\begin{array}{c} - \boldsymbol{y}^{[n]}_0 - \end{array}\right]= - \left[\begin{array}{c} - \boldsymbol{m}\left(t^n,\boldsymbol{y}^{n}\right) - \end{array}\right] -\end{align*} - -\subsubsection{2nd order Diagonally Implicit Runge Kutta (DIRK)} -\begin{align*} - \left[\begin{array}{c|c} - A & U \\ - \hline - B & V - \end{array}\right] = - \left[\begin{array}{cc|c} - \lambda & 0 & 1 \\ - \left(1-\lambda\right) & \lambda & 1 \\ - \hline - \left(1-\lambda\right) & \lambda & 1 - \end{array}\right]\quad \mathrm{with}\quad \lambda=\frac{2-\sqrt{2}}{2},\qquad - \boldsymbol{y}^{[n]}= - \left[\begin{array}{c} - \boldsymbol{y}^{[n]}_0 - \end{array}\right]= - \left[\begin{array}{c} - \boldsymbol{m}\left(t^n,\boldsymbol{y}^{n}\right) - \end{array}\right] -\end{align*} - -\subsubsection{3rd order Diagonally Implicit Runge Kutta (DIRK)} -\begin{align*} - \left[\begin{array}{c|c} - A & U \\ - \hline - B & V - \end{array}\right] = - \left[\begin{array}{ccc|c} - \lambda & 0 & 0 & 1 \\ - \frac{1}{2}\left(1-\lambda\right) & \lambda & 0 & 1 \\ - \frac{1}{4}\left(-6\lambda^2+16\lambda-1\right) & \frac{1}{4}\left(6\lambda^2-20\lambda+5\right) & \lambda & 1 \\ - \hline - \frac{1}{4}\left(-6\lambda^2+16\lambda-1\right) & \frac{1}{4}\left(6\lambda^2-20\lambda+5\right) & \lambda & 1 - \end{array}\right] -\end{align*} -with -\begin{align*} - \lambda=0.4358665215,\qquad - \boldsymbol{y}^{[n]}= - \left[\begin{array}{c} - \boldsymbol{y}^{[n]}_0 - \end{array}\right]= - \left[\begin{array}{c} - \boldsymbol{m}\left(t^n,\boldsymbol{y}^{n}\right) - \end{array}\right] -\end{align*} - -\subsubsection{3rd order L-stable, three stage IMEX DIRK(3,4,3)} -\tiny -\begin{align*} - &\left[\begin{array}{cc|c} - A^{\mathrm{IM}} & A^{\mathrm{EM}} & U \\ - \hline - B^{\mathrm{IM}} & B^{\mathrm{EM}} & V - \end{array}\right] =\\ - &\left[\begin{array}{cc|c} - \left[\begin{array}{cccc} - 0 & 0 & 0 & 0 \\ - 0 & \lambda & 0 & 0 \\ - 0 & \frac{1}{2}\left(1-\lambda\right) & \lambda & 0 \\ - 0 & \frac{1}{4}\left(-6\lambda^2+16\lambda-1\right) & \frac{1}{4}\left(6\lambda^2-20\lambda+5\right) & \lambda - \end{array}\right] & - \left[\begin{array}{cccc} - 0 & 0 & 0 & 0 \\ - \lambda & 0 & 0 & 0 \\ - 0.3212788860 & 0.3966543747 & 0 & 0 \\ - -0.105858296 & 0.5529291479 & 0.5529291479 & 0 - \end{array}\right] & - \left[\begin{array}{c} - 1\\ - 1\\ - 1\\ - 1 - \end{array}\right] \\ - \hline - \left[\begin{array}{cccc} - 0 & \frac{1}{4}\left(-6\lambda^2+16\lambda-1\right) & \frac{1}{4}\left(6\lambda^2-20\lambda+5\right) & \lambda - \end{array}\right] & - \left[\begin{array}{cccc} - 0 & \frac{1}{4}\left(-6\lambda^2+16\lambda-1\right) & \frac{1}{4}\left(6\lambda^2-20\lambda+5\right) & \lambda - \end{array}\right] & - \left[\begin{array}{c} - 1 - \end{array}\right] - \end{array}\right] -\end{align*} -\normalsize -with -\begin{align*} - \lambda=0.4358665215,\qquad - \boldsymbol{y}^{[n]}= - \left[\begin{array}{c} - \boldsymbol{y}^{[n]}_0 - \end{array}\right]= - \left[\begin{array}{c} - \boldsymbol{m}\left(t^n,\boldsymbol{y}^{n}\right) - \end{array}\right] -\end{align*} - diff --git a/docs/developer-guide/developer-guide.tex b/docs/developer-guide/developer-guide.tex deleted file mode 100644 index 3122068c73d9fb79b5903a3655f9c5c7efc5974c..0000000000000000000000000000000000000000 --- a/docs/developer-guide/developer-guide.tex +++ /dev/null @@ -1,467 +0,0 @@ -%%% DOCUMENTCLASS -%%%------------------------------------------------------------------------------- - -\documentclass[ -a4paper, % Stock and paper size. -11pt, % Type size. -% article, -% oneside, -onecolumn, % Only one column of text on a page. -% openright, % Each chapter will start on a recto page. -% openleft, % Each chapter will start on a verso page. -openany, % A chapter may start on either a recto or verso page. -]{memoir} - -%%% PACKAGES -%%%------------------------------------------------------------------------------ - -\usepackage[utf8]{inputenc} % If utf8 encoding -% \usepackage[lantin1]{inputenc} % If not utf8 encoding, then this is probably the way to go -\usepackage[T1]{fontenc} % -\usepackage{lmodern} -\usepackage[english]{babel} % English please -\usepackage[final]{microtype} % Less badboxes - -% \usepackage{kpfonts} %Font - -\usepackage{amsmath,amssymb,mathtools} % Math -\usepackage{pifont}% http://ctan.org/pkg/pifont -\newcommand{\cmark}{\ding{51}}% -\newcommand{\xmark}{\ding{55}}% - -\usepackage{graphicx} % Include figures -\usepackage{makeidx} -\usepackage{import} - - -%%% PAGE LAYOUT -%%%----------------------------------------------------------------------------- -\setlrmarginsandblock{0.15\paperwidth}{*}{1} % Left and right margin -\setulmarginsandblock{0.2\paperwidth}{*}{1} % Upper and lower margin -\checkandfixthelayout - -\newlength\forceindent -\setlength{\forceindent}{\parindent} -\setlength{\parindent}{0cm} -\renewcommand{\indent}{\hspace*{\forceindent}} -\setlength{\parskip}{1em} - - -%%% SECTIONAL DIVISIONS -%%%------------------------------------------------------------------------------ - -\maxsecnumdepth{paragraph} % Subsections (and higher) are numbered -\setsecnumdepth{paragraph} - -\makeatletter % -\makechapterstyle{standard}{ - \setlength{\beforechapskip}{0\baselineskip} - \setlength{\midchapskip}{1\baselineskip} - \setlength{\afterchapskip}{8\baselineskip} - \renewcommand{\chapterheadstart}{\vspace*{\beforechapskip}} - \renewcommand{\chapnamefont}{\centering\normalfont\Large} - \renewcommand{\printchaptername}{\chapnamefont \@chapapp} - \renewcommand{\chapternamenum}{\space} - \renewcommand{\chapnumfont}{\normalfont\Large} - \renewcommand{\printchapternum}{\chapnumfont \thechapter} - \renewcommand{\afterchapternum}{\par\nobreak\vskip \midchapskip} - \renewcommand{\printchapternonum}{\vspace*{\midchapskip}\vspace*{5mm}} - \renewcommand{\chaptitlefont}{\centering\bfseries\LARGE} -% \renewcommand{\printchaptertitle}[1]{\chaptitlefont ##1} - \renewcommand{\afterchaptertitle}{\par\nobreak\vskip \afterchapskip} -} -\makeatother - -%\chapterstyle{standard} -\chapterstyle{madsen} - -\setsecheadstyle{\normalfont\large\bfseries} -\setsubsecheadstyle{\normalfont\normalsize\bfseries} -\setparaheadstyle{\normalfont\normalsize\bfseries} -\setparaindent{0pt}\setafterparaskip{0pt} - -%%% FLOATS AND CAPTIONS -%%%------------------------------------------------------------------------------ - -\makeatletter % You do not need to write [htpb] all the time -\renewcommand\fps@figure{htbp} % -\renewcommand\fps@table{htbp} % -\makeatother % - -\captiondelim{\space } % A space between caption name and text -\captionnamefont{\small\bfseries} % Font of the caption name -\captiontitlefont{\small\normalfont} % Font of the caption text - -\changecaptionwidth % Change the width of the caption -\captionwidth{1\textwidth} % -\usepackage{tabularx} - -%%% ABSTRACT -%%%------------------------------------------------------------------------------ - -\renewcommand{\abstractnamefont}{\normalfont\small\bfseries} % Font of abstract title -\setlength{\absleftindent}{0.1\textwidth} % Width of abstract -\setlength{\absrightindent}{\absleftindent} - -%%% HEADER AND FOOTER -%%%------------------------------------------------------------------------------ - -\makepagestyle{standard} % Make standard pagestyle - -\makeatletter % Define standard pagestyle -\makeevenfoot{standard}{}{}{} % -\makeoddfoot{standard}{}{}{} % -\makeevenhead{standard}{\bfseries\thepage\normalfont\qquad\small\leftmark}{}{} -\makeoddhead{standard}{}{}{\small\rightmark\qquad\bfseries\thepage} -% \makeheadrule{standard}{\textwidth}{\normalrulethickness} -\makeatother % - -\makeatletter -\makepsmarks{standard}{ -\createmark{chapter}{both}{shownumber}{\@chapapp\ }{ \quad } -\createmark{section}{right}{shownumber}{}{ \quad } -\createplainmark{toc}{both}{\contentsname} -\createplainmark{lof}{both}{\listfigurename} -\createplainmark{lot}{both}{\listtablename} -\createplainmark{bib}{both}{\bibname} -\createplainmark{index}{both}{\indexname} -\createplainmark{glossary}{both}{\glossaryname} -} -\makeatother % - -\makepagestyle{chap} % Make new chapter pagestyle - -\makeatletter -\makeevenfoot{chap}{}{\small\bfseries\thepage}{} % Define new chapter pagestyle -\makeoddfoot{chap}{}{\small\bfseries\thepage}{} % -\makeevenhead{chap}{}{}{} % -\makeoddhead{chap}{}{}{} % -% \makeheadrule{chap}{\textwidth}{\normalrulethickness} -\makeatother - -\nouppercaseheads -\pagestyle{standard} % Choosing pagestyle and chapter pagestyle -\aliaspagestyle{chapter}{chap} % - - -%%% NEW COMMANDS -%%%----------------------------------------------------------------------------- - -% Nektar++ version -\usepackage{xspace} -\newcommand{\nekver} {\input{VERSION}\unskip} - -\newcommand{\p}{\partial} %Partial -% Or what ever you want - - -%%% CODE SNIPPETS, COMMANDS, ETC -%%%----------------------------------------------------------------------------- -\usepackage{xcolor} -\usepackage{listings} % Display code / shell commands -\usepackage{lstautogobble} -%\newcommand{\shellcommand}[1]{\begin{lstlisting} \#1 \end{lstlisting} -\lstdefinestyle{BashInputStyle}{ - language=bash, - basicstyle=\small\sffamily, -% numbers=left, -% numberstyle=\tiny, -% numbersep=3pt, - frame=, - columns=fullflexible, - backgroundcolor=\color{black!05}, - linewidth=0.9\linewidth, - xleftmargin=0.1\linewidth -} -\definecolor{gray}{rgb}{0.4,0.4,0.4} -\definecolor{darkblue}{rgb}{0.0,0.0,0.6} -\definecolor{cyan}{rgb}{0.0,0.6,0.6} -\definecolor{maroon}{rgb}{0.5,0.0,0.0} -\lstdefinelanguage{XML} -{ - basicstyle=\ttfamily\footnotesize, - morestring=[b]", - moredelim=[s][\bfseries\color{maroon}]{<}{\ }, - moredelim=[s][\bfseries\color{maroon}]{}, - moredelim=[l][\bfseries\color{maroon}]{/>}, - moredelim=[l][\bfseries\color{maroon}]{>}, - morecomment=[s]{}, - morecomment=[s]{}, - commentstyle=\color{gray}, - stringstyle=\color{orange}, - identifierstyle=\color{darkblue} -} -\lstdefinestyle{XMLStyle}{ - language=XML, - basicstyle=\sffamily\footnotesize, - numbers=left, - numberstyle=\tiny, - numbersep=3pt, - frame=, - columns=fullflexible, - backgroundcolor=\color{black!05}, - linewidth=0.9\linewidth, - xleftmargin=0.1\linewidth -} -\lstdefinestyle{C++Style}{ - language=C++, - basicstyle=\sffamily\footnotesize, - numbers=left, - numberstyle=\tiny, - numbersep=3pt, - frame=, - columns=fullflexible, - backgroundcolor=\color{black!05}, - linewidth=0.9\linewidth, - xleftmargin=0.1\linewidth, - showspaces=false, - showstringspaces=false -} - -\usepackage{tikz} -\ifdefined\HCode -\newcommand{\inltt}[1]{\texttt{#1}} -\newcommand{\inlsh}[1]{\texttt{#1}} -\else -\newcommand{\inltt}[1]{\tikz[anchor=base,baseline]\node[inner sep=3pt, -rounded corners,outer sep=0,draw=black!30,fill=black!05]{\small\texttt{#1}};} -\newcommand{\inlsh}[1]{\tikz[anchor=base,baseline]\node[inner sep=2pt, -outer sep=0,fill=black!05]{\texttt{#1}};} -\fi -\newcommand{\nekpp}{{\em Nektar++}\xspace} - - -% Highlight box -\usepackage{environ} -\usepackage[tikz]{bclogo} -\usetikzlibrary{calc} - -% Only use fancy boxes for PDF -\ifdefined\HCode -\NewEnviron{notebox}{\textbf{Note:} \BODY} -\NewEnviron{warningbox}{\textbf{Warning:} \BODY} -\NewEnviron{tipbox}{\textbf{Tip:} \BODY} -\NewEnviron{custombox}[3]{\textbf{#1} \BODY} -\else -\NewEnviron{notebox} - {\par\medskip\noindent - \begin{tikzpicture} - \node[inner sep=5pt,fill=black!10,draw=black!30] (box) - {\parbox[t]{.99\linewidth}{% - \begin{minipage}{.1\linewidth} - \centering\tikz[scale=1]\node[scale=1.5]{\bcinfo}; - \end{minipage}% - \begin{minipage}{.9\linewidth} - \textbf{Note}\par\smallskip - \BODY - \end{minipage}\hfill}% - }; - \end{tikzpicture}\par\medskip% -} -\NewEnviron{warningbox} - {\par\medskip\noindent - \begin{tikzpicture} - \node[inner sep=5pt,fill=red!10,draw=black!30] (box) - {\parbox[t]{.99\linewidth}{% - \begin{minipage}{.1\linewidth} - \centering\tikz[scale=1]\node[scale=1.5]{\bcdanger}; - \end{minipage}% - \begin{minipage}{.9\linewidth} - \textbf{Warning}\par\smallskip - \BODY - \end{minipage}\hfill}% - }; - \end{tikzpicture}\par\medskip% -} -\NewEnviron{tipbox} - {\par\medskip\noindent - \begin{tikzpicture} - \node[inner sep=5pt,fill=green!10,draw=black!30] (box) - {\parbox[t]{.99\linewidth}{% - \begin{minipage}{.1\linewidth} - \centering\tikz[scale=1]\node[scale=1.5]{\bclampe}; - \end{minipage}% - \begin{minipage}{.9\linewidth} - \textbf{Tip}\par\smallskip - \BODY - \end{minipage}\hfill}% - }; - \end{tikzpicture}\par\medskip% -} -\NewEnviron{custombox}[3] - {\par\medskip\noindent - \begin{tikzpicture} - \node[inner sep=5pt,fill=#3!10,draw=black!30] (box) - {\parbox[t]{.99\linewidth}{% - \begin{minipage}{.1\linewidth} - \centering\tikz[scale=1]\node[scale=1.5]{#2}; - \end{minipage}% - \begin{minipage}{.9\linewidth} - \textbf{#1}\par\smallskip - \BODY - \end{minipage}\hfill}% - }; - \end{tikzpicture}\par\medskip% -} -\fi - -%%% TABLE OF CONTENTS AND INDEX -%%%----------------------------------------------------------------------------- - -\maxtocdepth{subsection} % Only parts, chapters and sections in the table of contents -\settocdepth{subsection} - -\makeindex - -%\AtEndDocument{\addtocontents{toc}{\par}} % Add a \par to the end of the TOC - -%%% INTERNAL HYPERLINKS -%%%----------------------------------------------------------------------------- -\usepackage[linktoc=all,hyperfootnotes=false]{hyperref} % Internal hyperlinks -\hypersetup{ -colorlinks, -citecolor=darkblue, -filecolor=darkblue, -linkcolor=darkblue, -urlcolor=darkblue, -pdfborder={0 0 0}, % No borders around internal hyperlinks -pdfauthor={I am the Author} % author -} -\usepackage{memhfixc} % - - -%%% PRETTY TITLE PAGE FOR PDF DOC -%%%----------------------------------------------------------------------------- -\makeatletter -\newlength\drop -\newcommand{\br}{\hfill\break} -\newcommand*{\titlepage}{% - \thispagestyle{empty} - \begingroup% Gentle Madness - \drop = 0.1\textheight - \vspace*{\baselineskip} - \vfill - \hbox{% - \hspace*{0.1\textwidth}% - \rule{1pt}{\dimexpr\textheight-28pt\relax}% - \hspace*{0.05\textwidth}% - \parbox[b]{0.85\textwidth}{% - \vbox{% - {\includegraphics[width=0.2\textwidth]{icon-blue.png}\par} - \vskip1.00\baselineskip - {\Huge\bfseries\raggedright\@title\par} - \vskip2.37\baselineskip - {\huge\bfseries Version \nekver\par} - \vskip4\baselineskip - {\huge\bfseries \textcolor{darkblue}{Developer Guide}\par} - \vskip1.0\baselineskip - {\large\bfseries\@date\par} - \vspace{0.3\textheight} - {\small\noindent\@author}\\[\baselineskip] - }% end of vbox - }% end of parbox - }% end of hbox - \vfill - \null -\endgroup} -\makeatother - -%%% THE DOCUMENT -%%% Where all the important stuff is included! -%%%------------------------------------------------------------------------------- - -\author{Department of Aeronautics, Imperial College London, UK\newline -Scientific Computing and Imaging Institute, University of Utah, USA} -\title{Nektar++: Spectral/hp Element Framework} -\date{\today} - -\begin{document} - -\frontmatter - -% Render pretty title page if not building HTML -\ifdefined\HCode -\begin{center} - \includegraphics[width=0.1\textwidth]{img/icon-blue.png} -\end{center} -\maketitle -\begin{center} - \huge{Developers Guide - Version \nekver} -\end{center} -\else -\titlepage -\fi - -\clearpage - -\ifx\HCode\undefined -\tableofcontents* -\fi - -\clearpage - -\chapter{Introduction} -Nektar++ \cite{CaMoCoBoRo15} is a tensor product based finite element package -designed to allow one to construct efficient classical low polynomial order -$h$-type solvers (where $h$ is the size of the finite element) as well as higher -$p$-order piecewise polynomial order solvers. The framework currently has the -following capabilities: - -\begin{itemize} -\item Representation of one, two and three-dimensional fields as a collection of - piecewise continuous or discontinuous polynomial domains. -\item Segment, plane and volume domains are permissible, as well as domains - representing curves and surfaces (dimensionally-embedded domains). -\item Hybrid shaped elements, i.e triangles and quadrilaterals or tetrahedra, -prisms and hexahedra. -\item Both hierarchical and nodal expansion bases. -\item Continuous or discontinuous Galerkin operators. -\item Cross platform support for Linux, Mac OS X and Windows. -\end{itemize} - -The framework comes with a number of solvers and also allows one to construct a -variety of new solvers. - -Our current goals are to develop: -\begin{itemize} -\item Automatic auto-tuning of optimal operator implementations based upon not -only $h$ and $p$ but also hardware considerations and mesh connectivity. -\item Temporal and spatial adaption. -\item Features enabling evaluation of high-order meshing techniques. -\end{itemize} - -This document provides implementation details for the design of the libraries, -Nektar++-specific data structures and algorithms and other development -information. - -\begin{warningbox} -This document is still under development and may be incomplete in parts. -\end{warningbox} - -For further information and to download the software, visit the Nektar++ website -at \url{http://www.nektar.info}. - -\mainmatter - -\import{core-concepts/}{core-concepts.tex} - -\import{library-design/}{library-design.tex} - -\import{data-structures-algorithms/}{data-structures-algorithms.tex} - -\import{coding-standard/}{coding-standard.tex} - -%\appendix - - -\backmatter - -%%% BIBLIOGRAPHY -%%% ------------------------------------------------------------- - -\bibliographystyle{plain} -\bibliography{../refs} - -\printindex - -\end{document} diff --git a/docs/developer-guide/img/icon-blue.png b/docs/developer-guide/img/icon-blue.png deleted file mode 100644 index 03b0d5ebd09de36e0879d0ce183e6d4ef0c7e551..0000000000000000000000000000000000000000 Binary files a/docs/developer-guide/img/icon-blue.png and /dev/null differ diff --git a/docs/developer-guide/library-design/img/LocalRegions.png b/docs/developer-guide/library-design/img/LocalRegions.png deleted file mode 100644 index f294dbfed3da621d9eb3228fbf920e7d16532632..0000000000000000000000000000000000000000 Binary files a/docs/developer-guide/library-design/img/LocalRegions.png and /dev/null differ diff --git a/docs/developer-guide/library-design/img/MultiRegions.png b/docs/developer-guide/library-design/img/MultiRegions.png deleted file mode 100644 index 4eacaeded1d448ab6b351f3c631722f095fb7e73..0000000000000000000000000000000000000000 Binary files a/docs/developer-guide/library-design/img/MultiRegions.png and /dev/null differ diff --git a/docs/developer-guide/library-design/img/Quasi3d.png b/docs/developer-guide/library-design/img/Quasi3d.png deleted file mode 100644 index 026e6b520a5a8edbb850fee961ec6a6bf6c969c4..0000000000000000000000000000000000000000 Binary files a/docs/developer-guide/library-design/img/Quasi3d.png and /dev/null differ diff --git a/docs/developer-guide/library-design/img/SpatialDomains.png b/docs/developer-guide/library-design/img/SpatialDomains.png deleted file mode 100644 index de6be159afc12854924cb505335a65b9e2373c4a..0000000000000000000000000000000000000000 Binary files a/docs/developer-guide/library-design/img/SpatialDomains.png and /dev/null differ diff --git a/docs/developer-guide/library-design/img/StdRegions.png b/docs/developer-guide/library-design/img/StdRegions.png deleted file mode 100644 index 96c6553c2779f17d2c25f610c0eb22662f5379b7..0000000000000000000000000000000000000000 Binary files a/docs/developer-guide/library-design/img/StdRegions.png and /dev/null differ diff --git a/docs/developer-guide/library-design/img/architecture.eps b/docs/developer-guide/library-design/img/architecture.eps deleted file mode 100644 index 40a2c3fbd7a637e8f47541aa64c56f41ad0d4eff..0000000000000000000000000000000000000000 --- a/docs/developer-guide/library-design/img/architecture.eps +++ /dev/null @@ -1,2895 +0,0 @@ -%!PS-Adobe-3.0 EPSF-3.0 -%%Creator: cairo 1.12.16 (http://cairographics.org) -%%CreationDate: Mon Sep 15 21:14:06 2014 -%%Pages: 1 -%%DocumentData: Clean7Bit -%%LanguageLevel: 3 -%%BoundingBox: 0 -1 579 646 -%%EndComments -%%BeginProlog -save -50 dict begin -/q { gsave } bind def -/Q { grestore } bind def -/cm { 6 array astore concat } bind def -/w { setlinewidth } bind def -/J { setlinecap } bind def -/j { setlinejoin } bind def -/M { setmiterlimit } bind def -/d { setdash } bind def -/m { moveto } bind def -/l { lineto } bind def -/c { curveto } bind def -/h { closepath } bind def -/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto - 0 exch rlineto 0 rlineto closepath } bind def -/S { stroke } bind def -/f { fill } bind def -/f* { eofill } bind def -/n { newpath } bind def -/W { clip } bind def -/W* { eoclip } bind def -/BT { } bind def -/ET { } bind def -/pdfmark where { pop globaldict /?pdfmark /exec load put } - { globaldict begin /?pdfmark /pop load def /pdfmark - /cleartomark load def end } ifelse -/BDC { mark 3 1 roll /BDC pdfmark } bind def -/EMC { mark /EMC pdfmark } bind def -/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def -/Tj { show currentpoint cairo_store_point } bind def -/TJ { - { - dup - type /stringtype eq - { show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse - } forall - currentpoint cairo_store_point -} bind def -/cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore - cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def -/Tf { pop /cairo_font exch def /cairo_font_matrix where - { pop cairo_selectfont } if } bind def -/Td { matrix translate cairo_font_matrix matrix concatmatrix dup - /cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point - /cairo_font where { pop cairo_selectfont } if } bind def -/Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def - cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def -/g { setgray } bind def -/rg { setrgbcolor } bind def -/d1 { setcachedevice } bind def -%%EndProlog -%!FontType1-1.1 f-0-0 1.0 -11 dict begin -/FontName /f-0-0 def -/PaintType 0 def -/FontType 1 def -/FontMatrix [0.001 0 0 0.001 0 0] readonly def -/FontBBox {-19 -200 623 673 } readonly def -/Encoding 256 array -0 1 255 {1 index exch /.notdef put} for -dup 68 /D put -dup 76 /L put -dup 77 /M put -dup 82 /R put -dup 83 /S put -dup 85 /U put -dup 97 /a put -dup 98 /b put -dup 99 /c put -dup 100 /d put -dup 101 /e put -dup 103 /g put -dup 105 /i put -dup 108 /l put -dup 109 /m put -dup 110 /n put -dup 111 /o put -dup 112 /p put -dup 114 /r put -dup 115 /s put -dup 116 /t put -dup 117 /u put -dup 118 /v put -readonly def -currentdict end -currentfile eexec -f983ef0097ece636fb4a96c74d26ab84185f6dfa4a16a7a1c27bbe3f1156aea698df336d20b467 -b10e7f33846656653c5ac6962759d3056cbdb3190bac614b984bf5a132dc418192443014ba63de -800d392b6fea026574bb2535fd7bb5338f35bf15a88ea328fdaa49670c7852e3d060f3c5d6b07f -2ef6d0f22646c5d18e19a2ae3ee120390f6dd96f76dcf1e127de5e9299077a00c17c0d71e36e5b -9d5ec58fceda57739a6a4214d4b79d6c48d2784b60c320323c7acddddf34db833cac0cf109f799 -69d114a330d372e5c978a66acc84e3fe5557f6240856a013ffaa0199444e5c5036f775eba4a5c5 -8cde66cf604b9aca2178431127b8a1ff7ed633a65c04600af5f573483112251caf347b8ce51112 -d5fff4f7751f4ca1a9c6975afcd0442cd4a8c57cee08043dedb0cc9ae42871d9992ca6be403299 -392c226babc258d751f61b8735945de632016144c924d5cf79748facb74934512687422088c093 -3648a1072b72f869c459c4bf63241e24618c110bdd454015c50bd490cdc8d0558921771c3cd302 -de1659076744c31b1de7efc199af9ee4a417c579f9e31626450f33ac0eb1145b0d6d30ad754c4c -57ebaa9120597aad0b0eef2fb2f77c23669fc4764671c5f742f5feed78cc2c97b8e09330cb8f2b -e1749a3826b92dad29de70a5001999282622fa6c76f04422b53c35bc41c68f440cb15593b5485a -0cfd3a5c87e230a383c6df8f92e0387f1d2af86fae9019b07126d457e75747e50045b073b150bd -0c7a21e3c5f6aae15a02f92a5d419af7b561c0fd6589b33df53a1dcc2177951488ee485b9964ae -a79708f283ae694f5dbae5664afdcc32e0e78a53fb86345a52fccdb4a86036fde9d4b4874ec1d9 -81fa874aef78eca627175f4014c2aca343e7067d71dd0eb88ebd7456f3faaab59e517d97ab42ba -fb1097b271f10a324597bbd64de5c7486bd29d63f70738eb8907019613bb2a15c1589e4c3aa5ab -848bdfd84eb36b313f17d94ef1be6daf485d540763c14f289fb8dd6735b401b002526694860a36 -ffb55504905cee09f39a371928eb5290fc1bbad3899e2d453b90ab37d557ac0128dbb32faa9a55 -12660133f5610065cc5644db75dee3ae661f1241c6e2b89d5a54da8563ca26537818a7131a6c2c -1638085ca857ec309655e4187d055fe71eb8639ea8767d34e0cc91aecf2a7a2c766f454e506270 -84008378862bdfd3c739cdc93605879052d569a2b109c740e0123d8cd1793a0a79402835cbd2bf -18a2dd5fd92c742257ae2f0f07da6c69054951f363fec473e18610834ac2c6d058b2b1a1146751 -f07b34ac12a0ea3a7d356ad230ad645858bb9cc86b4f3e5195c2d91af3be607b3a772f9d528f1b -1333ba120eb9b69128b4224d19e131463ec1ef51cdf0a9ebbc245ae4b5f914b7f9262a6d3e22f3 -40cd4173e60b8c93f49838fd0b2d2d216ef054b845a98650a97238f88827e79cb7fe9eae81580a -bb4349e121f3fc36dca8a6895af7082b6369da9c317758be0cf2dd771511faaef86d31427b0fd0 -448d2c7e67c0e893f33efabaaf461734bf939d71096a7608b1889d99d8dfe249d8da9ed013cff0 -1d99be4187b130b9b8877a08c493725e292d8badb9784b63f8e9ba65bf43430b2782968d2d3e90 -07c737cb7c02b9e9cd0ff54a6d6391a84d01f20d61d6dc73a64b03dd2b42e365e1288c890b9c1d -9c57a0de96e6a2f6f850fc363b46fcb223913676301992f55f2d8f973f906fdd64d4d69db09a8d -cf276a3327c7f6a9c183051217e03a9cce54910614585b8c2539fe62e53457627d33eda42b0810 -8f29a0cae41de3a78381ecd0d77b63ac2f362f957f5fbdc69d8f9dfc62550fd75fb0a64575aacf -bd9575cb19e98c72b8b06e2c699d6a10c7e482a2d6f1bf92aafe50f7764bb82443d7e7ff4ecbf3 -0bbf36b9316dc48ed25698fe121e06ef6dbedefff2215c52127244e4e37a7caee4cd09db19a8ec -856cd3383d9cf1f3e1db59152881aa6acd2cf244f37a4f2eeecc47b28cb3bd4bed8f314e23ddf8 -1d85f6a8789a6d7aa32ec49ea3164176635241b6c436ef3409a305f4ed986ad6134f6834ca487c -415bc909326988fbeaa50fe58460e8ddc5bc7b03694b1237da9fb3463077a22ca50cdaf01a76c4 -34249073723c107c8abc7d1674d4062d5f1e478d0ea179e9713fe785bf2c8bbba6ae4d49a543b0 -a8c45b1be979a586a393a0bac52c55ae68201834dccb3abc51ab38c4fe9887652ef4cad100220c -590b84161ad30d99ebd4d9f6ad02f458e1abf68e25229084fdfead9fdf1e992a6b5661a7dc53e3 -b38445aae1aaba54e7d4f14c1b87e147df13f4e96514bc074fa7b6ad83af1282f1db47e76f0451 -033f1bffee37b4e802d328ecfbc31280b28f07897c886d77001332f94a085211976df253dba952 -bcb6f7facdeffeb144e4516f1ba6a5820739fd99d29114c70c41ae4427e07b0b101961cb55689c -0e4a03ea628054277a869574d60774abad54ee142f2209049e14b53a14b6f9e0c2ce3578d4fcd1 -755749e3f288f520be133e755057dca21ad10700b0906cc512d72ee1104983bc311e32a6468200 -5d01f4a38ac317fa9b834092a879ffd90a6c5db30b5de46d36069c356849af498d4d6cc6ac7a0a -22564dfdbcd1b4dd05ae8401548bbf1283d4dee05ac493771de40375f0c4f76c54e3c54fdbfd15 -54a6e6c181606fe6bb5cb6a3960303d9282b71f23d9b12a69b68429e3f5d77efa27cbb24cab01e -bcda3f7dfc05d4a5bc51cc512254e2348895d987f7eb6333e006c6401122287d7553759cefb56f -6d5df6501a891ef2a36a9d42cc69c9ce1c72113c50980af207ececbe4c1d6c736a3c9fa64a9d7d -312509a5ad31f418a9de197cc3df8454544cc23ebeb6fe22420dcdcab8715bb00e97b36fbeaca9 -c0d15caeb3d3e9481d84719e3476994f8e49dffb699efde7989210c80343196652fc7d24c4bab8 -f616b16704a9b4eba5f272f65ab7fe208f97bbd6db0ddfb0be2705fd62031dd434eda29e46749a -94d6e6dc3c06292b46cf153b8128df54f2ee9691b9ee56f889015017e865e5be848dab6d40d70c -8fe861c3b9182e5818deec47d4e6c8833bd24c9d52abb5c2412f58a87f1f67ce8d061f4ca29596 -57276fff09486005210264c902ab45f0a6750f17a29244bce473aaedc14d3dcf43b7004a1975c1 -c21648f7d8661691970e741001c0e3922ff97c654d897867c146683329f3cd88532c900951ba0a -34db6bc52b168d515530ee88bca5d7b2ec412e383395f9079b6d6416badf44fef4307bb8e08a68 -51442794c4a85e29ba67110e2f9647148efe5d2595b25f4e53b7ed361d0fcd55adfbe1d3aa3f2d -08cef55b7d0a07e6a1d7ff62030106baef26179b0d76e4a8bc194f7db049a9f99a6e36a005a094 -4920ee21c96f54cc01b678f7c3b51b307e9ffebbd1c6c2a55c75e438193ff07c887d3adddd9df3 -8fb008165815c81a95ad68831fc8a789c253f3ccc0e1330ba3a7cadc529a2b37845c6fa89f656e -daf7366866f53162fdab9d17c2711c1c8d396ecdd76e6440ad9e1beaf8231784ac68df7326f54a -2f26d1d8a1e8b4d0ff1ffca952f3901b46973cf45f663f2bc2791e6d375ced4880b0bc3a86ec5e -6a57715967ab2e2f2ed4947c836a37a4505fdc2a782190126e5a5993e0c4c152e79b2d62c2d012 -48ba928fb5e355753f1943041d64c8b3553d0f14aea9d84a50499f114918c2f14368f18d7f4aab -acf99132f3c089ff9c02d216c4d9896f2bfd0d101f83332e633fa85ff61a7393e19dc34e7b1600 -7df66407d90dba9e2e653048bf35cedea72f13f880ce5f17e0224cb17574374e48dc457f94ff85 -46e34a754221a3a47724b00a1544a278dba785c6985382d52e80db70f5e2dc47c5fb8686378445 -c05af430bc49d1f60d35a54f05e7d4e447f3a07f02c1bdfdd7522a56e1b977f67fd3fba944c6eb -d94f5fe9c11a940aa73e693ab66d1317a68beddec4dccf745b54cfca5bbe96b39efa4c46e9dd1a -ba058736ff90c463e47d09328e535492a9df64ffbe6da921dcbb6262f1ecd9492885537d9d792e -85158e5dca29b9ad2748668524f2f99018571cd96bc6a95af6799dea1b4cc13f7bf4381e01cf9c -679b852bc18c452cebe29fe3997b8b33cb576775d3c09a33dc47316a347ce05442f44c74cefa0c -aeaf0a927d5c0e14dbaebc3e7291225ec36b093c29331640788d8302537816306d67e05849a36d -ed333bc39f28b75e486a0a35aee63ce0991e1dee86041c3a329971ffecfd7ee82f6209fc674096 -2448b9278eb27ebc0fa49d9ccdb12a0e9e2408b3c5b7e326b9a5861c11eeece6f973706f45f59c -591ad54a57e4ccd1c0f2320d83d4da19387a6d79abf61f7571fd1587a646d6a74f105cc69b4b98 -2fb7f2974762cc878a8de2d5ca2b12613a68ab4cd05001ff1b1e82ec3ec5870e7b6e60af890b30 -cc1fefa6199b941ceef7a14fcdc04f10ddbf520d80a5f33075e7629fce35573cbcdc8cc7ae577a -9d2cc2a2740068d68682d46bfe103bcdbb2b6a606d69a292b65dfae5edf08e7c584b86963fb241 -ad5bb65b71f1ec0ad35fec73164c4854b8c65cbaa7ae8be4ebea66cd34cfdfa13e55bfaf900c07 -3dd1127aec50195b0cbbdf0ba47be73208c613e8d7bcae1a3ada80831e03bcc25ecada33e3f6d6 -e6cddc1ae26f43dce30caf200cd743b8563cf8b6604c13950359246a2523952f0d70d7ddd0bfa5 -8901bd448c5fe5a4e443570b83aede36ef62a261c474c62bdfa09c742d95367a1f5f7736c89a6b -6432bf1a7a73f601b6c2863844de7392f84d2dfd4dc62e4552578d599d2d99e56e10091276801d -6db1adafd9a6d570a013f8f48531cf6a586277238e604c2869ee6c761aa2e1a524edc8e16f2aff -571e6fbb2f0cf5db412e900d39d45975f0b5d30927094c8e6747772e76c493442557edd190cb20 -b0a4bfb22a83222dd1b12b537c38f70d961ee89d1ec428418427a147d0029c9f89f9a71dd9f909 -666cf119c0868c18dbae45c16b6c7c1cab07f38ac8da9b6fa14b8a0fac6875dc7639813e77c4bb -a3526dbf6cc91cb053827960b0f548885f5a42181ab7aca96bfe8621269220d0a39cea51002e18 -25940e5b9c9b6a1f71f80bcb7ad630c262844495e73e8abf85749352435d11c33754b14f108ac8 -7b4d8ed7dcc22094986011e9a5223ccecdd79c041709ff1689b6ebeffcd301cabdc95cb6209375 -92be909e4663ee7611ab466582ec3608da65daf867dd9dc5a5d6fa41d20b31c697bb7da2bad995 -5f90616f04a6ab4182865c6cc9ade7145d42a5e5db1cfcbba0560a12027c6b7a79b1e59fcbf82f -02aed7154482b3b0c825cac898327439102cb372ddacd62fadf3145a8e37de7886d59ee284ac3c -ce8d644a9825a7eb8900546cdbc384b9128d452ccbd5fce16903aec46dc970f95c44010d684165 -73e17dd1816b8a2c6c4ab33baa6d71d42aa34659796483366949b866f38b9abeb00eba227f1d11 -86869bd51b8fb3f8fa1e91b3cf5a0bb4ebb755bfce7425804b056300069a901a7c6ae406b9a8e3 -dce294872f798e23267fec8bf26a6e3b7327de7c132d2c37ea7c4d666f63e80000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -11 dict begin -/FontType 42 def -/FontName /DejaVuSans def -/PaintType 0 def -/FontMatrix [ 1 0 0 1 0 0 ] def -/FontBBox [ 0 0 0 0 ] def -/Encoding 256 array def -0 1 255 { Encoding exch /.notdef put } for -Encoding 45 /hyphen put -Encoding 49 /one put -/CharStrings 3 dict dup begin -/.notdef 0 def -/hyphen 1 def -/one 2 def -end readonly def -/sfnts [ -<0001000000090080000300106376742000691d390000017c000001fe6670676d7134766a0000 -037c000000ab676c7966b9130c6c0000009c000000e068656164012c8c210000042800000036 -686865610cb806540000046000000024686d74780cc701ab000004840000000c6c6f63610000 -019400000490000000106d61787004700671000004a000000020707265703b07f100000004c0 -0000056800020066fe96046605a400030007001a400c04fb0006fb0108057f0204002fc4d4ec -310010d4ecd4ec301311211125211121660400fc73031bfce5fe96070ef8f272062900010064 -01df027f028300030011b6009c020401000410dccc310010d4ec301321152164021bfde50283 -a400000100e10000045a05d5000a004040154203a00402a005810700a009081f061c03001f01 -0b10d44bb00f5458b9000100403859ecc4fcec31002fec32f4ecd4ec304b5358592201b40f03 -0f04025d3721110535253311211521fe014afe990165ca014afca4aa047348b848fad5aa0000 -013500b800cb00cb00c100aa009c01a600b800660000007100cb00a002b20085007500b800c3 -01cb0189022d00cb00a600f000d300aa008700cb03aa0400014a003300cb000000d9050200f4 -015400b4009c01390114013907060400044e04b4045204b804e704cd0037047304cd04600473 -013303a2055605a60556053903c5021200c9001f00b801df007300ba03e9033303bc0444040e -00df03cd03aa00e503aa0404000000cb008f00a4007b00b80014016f007f027b0252008f00c7 -05cd009a009a006f00cb00cd019e01d300f000ba018300d5009803040248009e01d500c100cb -00f600830354027f00000333026600d300c700a400cd008f009a0073040005d5010a00fe022b -00a400b4009c00000062009c0000001d032d05d505d505d505f0007f007b005400a406b80614 -072301d300b800cb00a601c301ec069300a000d3035c037103db0185042304a80448008f0139 -011401390360008f05d5019a0614072306660179046004600460047b009c00000277046001aa -00e904600762007b00c5007f027b000000b4025205cd006600bc00660077061000cd013b0185 -0389008f007b0000001d00cd074a042f009c009c0000077d006f0000006f0335006a006f007b -00ae00b2002d0396008f027b00f600830354063705f6008f009c04e10266008f018d02f600cd -03440029006604ee00730000140000960000b707060504030201002c2010b002254964b04051 -5820c859212d2cb002254964b040515820c859212d2c20100720b00050b00d7920b8ffff5058 -041b0559b0051cb0032508b0042523e120b00050b00d7920b8ffff5058041b0559b0051cb003 -2508e12d2c4b505820b0fd454459212d2cb002254560442d2c4b5358b00225b0022545445921 -212d2c45442d2cb00225b0022549b00525b005254960b0206368208a108a233a8a10653a2d00 -000100000002570af329593a5f0f3cf5001f080000000000ce58f50b00000000ce58f50bf7d6 -fcae0d72095500000008000000010000000000010000076dfe1d00000de2f7d6fa510d720001 -0000000000000000000000000000000304cd006602e30064051700e100000000000000440000 -0070000000e00001000000030354002b0068000c000200100099000800000415021600080004 -b8028040fffbfe03fa1403f92503f83203f79603f60e03f5fe03f4fe03f32503f20e03f19603 -f02503ef8a4105effe03ee9603ed9603ecfa03ebfa03eafe03e93a03e84203e7fe03e63203e5 -e45305e59603e48a4105e45303e3e22f05e3fa03e22f03e1fe03e0fe03df3203de1403dd9603 -dcfe03db1203da7d03d9bb03d8fe03d68a4105d67d03d5d44705d57d03d44703d3d21b05d3fe -03d21b03d1fe03d0fe03cffe03cefe03cd9603cccb1e05ccfe03cb1e03ca3203c9fe03c68511 -05c61c03c51603c4fe03c3fe03c2fe03c1fe03c0fe03bffe03befe03bdfe03bcfe03bbfe03ba -1103b9862505b9fe03b8b7bb05b8fe03b7b65d05b7bb03b78004b6b52505b65d40ff03b64004 -b52503b4fe03b39603b2fe03b1fe03b0fe03affe03ae6403ad0e03acab2505ac6403abaa1205 -ab2503aa1203a98a4105a9fa03a8fe03a7fe03a6fe03a51203a4fe03a3a20e05a33203a20e03 -a16403a08a4105a096039ffe039e9d0c059efe039d0c039c9b19059c64039b9a10059b19039a -1003990a0398fe0397960d0597fe03960d03958a410595960394930e05942803930e0392fa03 -9190bb0591fe03908f5d0590bb039080048f8e25058f5d038f40048e25038dfe038c8b2e058c -fe038b2e038a8625058a410389880b05891403880b0387862505876403868511058625038511 -0384fe038382110583fe0382110381fe0380fe037ffe0340ff7e7d7d057efe037d7d037c6403 -7b5415057b25037afe0379fe03780e03770c03760a0375fe0374fa0373fa0372fa0371fa0370 -fe036ffe036efe036c21036bfe036a1142056a530369fe03687d036711420566fe0365fe0364 -fe0363fe0362fe03613a0360fa035e0c035dfe035bfe035afe0359580a0559fa03580a035716 -190557320356fe035554150555420354150353011005531803521403514a130551fe03500b03 -4ffe034e4d10054efe034d10034cfe034b4a13054bfe034a4910054a1303491d0d0549100348 -0d0347fe0346960345960344fe0343022d0543fa0342bb03414b0340fe033ffe033e3d12053e -14033d3c0f053d12033c3b0d053c40ff0f033b0d033afe0339fe033837140538fa0337361005 -37140336350b05361003350b03341e03330d0332310b0532fe03310b03302f0b05300d032f0b -032e2d09052e10032d09032c32032b2a25052b64032a2912052a250329120328272505284103 -27250326250b05260f03250b0324fe0323fe03220f03210110052112032064031ffa031e1d0d -051e64031d0d031c1142051cfe031bfa031a42031911420519fe031864031716190517fe0316 -01100516190315fe0314fe0313fe031211420512fe0311022d05114203107d030f64030efe03 -0d0c16050dfe030c0110050c16030bfe030a100309fe0308022d0508fe030714030664030401 -100504fe03401503022d0503fe0302011005022d0301100300fe0301b80164858d012b2b2b2b -2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b -2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b -2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b -2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b -2b2b2b2b2b2b2b2b2b002b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b -2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b -2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b -2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b -2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b1d00> -] def -/f-1-0 currentdict end definefont pop -%!FontType1-1.1 f-2-0 1.0 -11 dict begin -/FontName /f-2-0 def -/PaintType 0 def -/FontType 1 def -/FontMatrix [0.001 0 0 0.001 0 0] readonly def -/FontBBox {0 -139 766 800 } readonly def -/Encoding 256 array -0 1 255 {1 index exch /.notdef put} for -dup 32 /space put -dup 65 /A put -dup 67 /C put -dup 68 /D put -dup 69 /E put -dup 72 /H put -dup 73 /I put -dup 76 /L put -dup 77 /M put -dup 78 /N put -dup 79 /O put -dup 80 /P put -dup 82 /R put -dup 83 /S put -dup 84 /T put -dup 85 /U put -dup 88 /X put -dup 89 /Y put -readonly def -currentdict end -currentfile eexec -f983ef0097ece636fb4a96c74d26ab84185f6dfa4a16a7a1c27bbe3f1156aea698df336d20b467 -b10e7f33846656653c5ac6962759d3056cbdb3190bac614b984bf5a132dc418192443014ba63de -800d392b6fea026574bb2535fd7bb5338f35bf15a88ea328fdaa49670c7852e3d060f3c5d6b07f -2ef6d0f22646c5d18e19a2ae3ee120390f6dd96f76dcf1e127de5e9299077a00c17c0d71e36e5b -9d5ec58fceda57739a6a4214d4b79d6c48d2784b60c320323c7acddddf34db833cac0cf109f799 -69d114a330d372e5c978a66acc84e3fe5557f6240856a013ffaa0199444e5c5036f775eba4a5c5 -8cde66cf604b9aca2178431127b8a1ff7ed633a65c04600af5f573483112251caf31d0c7c7e1a8 -decc942f4bccae86153efd43475966e5202fd074454ef561dfefa485386c30b27067c7bdccbca3 -028b4c8bfa7e0bc262bc637a3648d3bddeed0b3156794339aa4d73abdabc9e1f3b206001e9d695 -b661933748e28c205197b3b81ae15d1d00eade5d50a45439e37269ee30a8497a12b99ed5d57ef5 -452a7ea954198776424fe98730e1e17e112b86ef87ad0fd3dd500934c2a1fe2c75dc11f16fc4a0 -d02e3137c4f4fab97429937f0b88f24b224695de81fd134bf11b8f552f6d0211ba8d7614fd0b5d -bdfa7bebcbdf39ff7aa7835f75298d480ec2f7fc65366976ee97705392941d4ceb71e51d5e1865 -0f6388dba23a731cf7fffc07186212eb020e7226796f95f3838dacf097c817adc1a129e481e185 -2063a24f07c905490f9708dfccabc666a8d06cfe0721494a3678e977b758200f8b20609d38cd1a -0f339270049138602a3bce9cad50b28e4e79614c88775c201761bd363538045b86058de819a3be -7257e4f96bba71e253b33a9d52f9c03b85031dc3bb914cbb8a0fd3833537d73fa0dc993bbc9e0b -187e43c218517f18216305d5f163cb763355557844f40fd2cff0cf7982a15d4fa1d3004e548af0 -a08b3fa9a80b4967303e29b2af2b4f3556f20ebe93248d5391d98ccd2e26316742a32ab13e0bc0 -d352c51e2cecc5100cbcb08d9a4b1acfea93279cca20c6489dea7f323f43a0747b2576c7791c5c -2b74e117fde5c974ed3a950e32b24bbd34915873b17caadee66db3bbdc0b58ad34740f98072b15 -b74e7803c1bbc82095d327b2a3dee4e7ef6506a69cc2c16f2ab79919a053aa59df3b7ee39bc8d6 -ab22591513fdd4cedd99545675e7e1d565b1a40e70b33d49cdc5edf30524d1caa2c5385afbdcc4 -115e1436522c46ae108110d5d07f15a13b8ff06d8849cc3d87f24f9d209d78e0720df9b1cd4aa4 -0a523d25a41a4ec7940c00c8c9de1e8434c6e0c739aa871c00020b67ae778c7ceef3f4de1047ac -e13352346b46ac99db167f07181aee4c9e865eabbb181039278009c5cffbcad6aedc0f8e7fa926 -a6680df8f1e8abffa96cff207f7f60fd582f9ab41549d276bf41a763939da45820d27f8fc15078 -62d2805f78d80a43e84de7160373cad07aae9490a92fc925722af940bb2596021353ea61c43d6d -0c45a6a64e04363cc126ab87ff0b9b39d9384735d4fa3b22a3ebe7ce3e3f7d8c78e25d319b0ae9 -3f8fdf3a3f2cf30358b76f04c610f80e1077e5e0ab4b2619fd17cc40e6a188da34b50252ee608f -f2767cb055077d60bb1f865788f2d93ac5aeebe4dd2e4aca345b3451ed521e2a8de3637936cea7 -c7a3f2ab6fc7f5529206548a1799b7181aea9004b2dc7a5972433f212f51920f0f2018ab647a05 -a9a5986481fdf90451be00d9fc781d3787dde14c37664c7c915c7af23ff8a2e90cff25963e4c9f -9cf973178890d7896893276e071ec0050c7729a4d88ec273bc895e42839aa01600614bef1536d1 -dc7d648d7f14c693a3a072306f99b7689ae48465ce39ab7853768fe6f52787b28a47d0c7803c54 -4a01b14c98af6df52658f04f52bad1f1c514f9bf46220391540fd02bc1e3c686aa7b7fbf5d2c0c -5181ff731dd450f46d8040a2081254763a302af4b778486d3a2fd705d78bcd6ef091bd5d301ce8 -b9f81beb244d203275d57cecb8aa0fb6eda5f1aedda203f407f6ea8413a6644c22815d7f880a24 -3c185921e609e59d2a71f26c003a4c25bf13d92afafa02b89f6027bddf77c2aa39c15916521379 -5468a9d33323a746352c5ba2eb332fa1eee7d62a10a6264c1b938ba6b7c832b5718352e4ce4556 -432f3e44697071575c4e4ab21b231c5b30da8a0974ab91b4d3e9242a1b5a3cdefcbafc54943e81 -54aebae51ae7cb07d0b72513062b228825c570891683e0e42a4e6a21f7600d3e896029f9d8fe67 -82ec0e0954392af6e9f4035cd7b32e19772b6d27195816118ccac1db18e5ea646ca621ee61e8ed -38d30338a0efe61fe8c7908cf9a58b46183e95ea1b823ae3dbac853fbd723cd1669b0ac9c21ab0 -5aa022e52a5e3a9456219f4081bca683ffec7f0aaef774e4564e4a8bc2b526129af3dbf3fb00c4 -74b3f58720691da5b23431a35f092457ace1fdcce8a6179cf491f5a8571629423b4036e5e126ea -945d2e8973e362978bb490578cd4cc7d75e360338f29d9d59cfc73813e38856d761664c64a6f95 -e6ca9d9199116b3b49152c03f74a7bf4d7213857122d75492e488f207a884ebd7bdcc570a3e0ce -e57cbd0df241bb5161002243fa313f283e6200a6c43df5d5c0729c9c081c0902d81d9e086be1c2 -4c818a0431fb109921018df30ee34dd26f8341d2362034f0b1e5763930f6ed922640e5faf3ab5c -a70c78793f5af3db4700e9797ed3505d465c925a46590b9690bc2bbc853c5d2385c8fbbe4fbbcb -24b2455b52d61db08effdf2502f010af4dcf910000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000 -cleartomark -%%Page: 1 1 -%%BeginPageSetup -%%PageBoundingBox: 0 -1 579 646 -%%EndPageSetup -q 0 -1 579 647 rectclip q -0.698039 0.937255 0.360784 rg -47.566 480.34 m 338.133 480.34 l 353.836 480.34 366.477 467.695 366.477 - 451.992 c 366.477 430.902 l 366.477 415.199 353.836 402.555 338.133 402.555 - c 47.566 402.555 l 31.863 402.555 19.219 415.199 19.219 430.902 c 19.219 - 451.992 l 19.219 467.695 31.863 480.34 47.566 480.34 c h -f -0 g -2.216693 w -1 J -0 j -[] 0.0 d -4 M q 1 0 0 -1 0 645.5 cm -47.566 165.16 m 338.133 165.16 l 353.836 165.16 366.477 177.805 366.477 - 193.508 c 366.477 214.598 l 366.477 230.301 353.836 242.945 338.133 242.945 - c 47.566 242.945 l 31.863 242.945 19.219 230.301 19.219 214.598 c 19.219 - 193.508 l 19.219 177.805 31.863 165.16 47.566 165.16 c h -S Q -BT -28.8 0 0 28.8 40.27063 454.305359 Tm -/f-0-0 1 Tf -[(MultiReg)3(ions)]TJ -ET -48.738 422.078 m 49 421.105 49.863 420.469 50.875 420.469 c 51.699 420.469 - 52.262 421.031 52.637 421.781 c 53.051 422.641 53.348 424.105 53.348 424.141 - c 53.348 424.406 53.16 424.406 53.086 424.406 c 52.824 424.406 52.824 424.293 - 52.75 423.953 c 52.41 422.605 51.961 420.992 50.949 420.992 c 50.461 420.992 - 50.199 421.293 50.199 422.078 c 50.199 422.605 50.5 423.73 50.688 424.594 - c 51.363 427.18 l 51.438 427.516 51.66 428.418 51.773 428.793 c 51.887 -429.355 52.113 430.254 52.113 430.406 c 52.113 430.816 51.773 431.043 51.438 - 431.043 c 51.324 431.043 50.688 431.004 50.5 430.219 c 50.051 428.453 49 - 424.254 48.699 423.016 c 48.66 422.906 47.723 420.992 45.961 420.992 c -44.723 420.992 44.5 422.078 44.5 422.941 c 44.5 424.293 45.176 426.168 45.773 - 427.816 c 46.074 428.566 46.188 428.906 46.188 429.355 c 46.188 430.406 - 45.438 431.305 44.238 431.305 c 41.949 431.305 41.086 427.816 41.086 427.629 - c 41.086 427.367 41.312 427.367 41.348 427.367 c 41.613 427.367 41.613 -427.441 41.723 427.816 c 42.324 429.879 43.262 430.781 44.16 430.781 c 44.387 - 430.781 44.762 430.742 44.762 429.992 c 44.762 429.43 44.5 428.719 44.348 - 428.379 c 43.449 425.98 42.961 424.516 42.961 423.355 c 42.961 421.066 -44.613 420.469 45.887 420.469 c 47.461 420.469 48.324 421.555 48.738 422.078 - c h -f -59.012 436.68 m 56.5 436.043 55.074 433.906 55.074 432.145 c 55.074 430.344 - 56.426 429.219 58.074 429.219 c 60.098 429.219 61.676 431.582 61.676 434.02 - c 61.676 435.629 60.812 436.605 60.285 437.168 c 59.688 437.879 58.41 439.23 - 58.41 440.02 c 58.41 440.242 58.676 440.691 59.348 440.691 c 59.91 440.691 - 60.398 440.43 60.738 440.242 c 60.887 440.168 61.488 439.793 61.75 439.793 - c 62.16 439.793 62.461 440.168 62.461 440.504 c 62.461 440.918 62.238 440.957 - 61.336 441.145 c 61.148 441.18 60.363 441.332 59.836 441.332 c 58.562 441.332 - 57.887 440.617 57.887 439.605 c 57.887 438.707 58.41 437.691 59.012 436.68 - c h -59.273 436.23 m 59.762 435.48 60.363 434.504 60.363 433.305 c 60.363 431.918 - 59.535 429.668 58.113 429.668 c 57.211 429.668 56.312 430.27 56.312 431.656 - c 56.312 432.781 56.949 435.668 59.273 436.23 c h -f -72.469 414.992 m 72.469 415.066 72.469 415.105 72.055 415.516 c 69.094 -418.516 68.305 423.055 68.305 426.73 c 68.305 430.891 69.203 435.055 72.168 - 438.016 c 72.469 438.316 72.469 438.355 72.469 438.43 c 72.469 438.617 -72.391 438.691 72.242 438.691 c 71.98 438.691 69.844 437.043 68.418 434.004 - c 67.219 431.379 66.918 428.719 66.918 426.73 c 66.918 424.855 67.18 421.969 - 68.492 419.23 c 69.953 416.305 71.98 414.73 72.242 414.73 c 72.391 414.73 - 72.469 414.805 72.469 414.992 c h -f -81.844 427.969 m 81.992 428.566 82.555 430.781 84.203 430.781 c 84.316 -430.781 84.918 430.781 85.406 430.48 c 84.73 430.328 84.281 429.766 84.281 - 429.168 c 84.281 428.793 84.543 428.344 85.18 428.344 c 85.703 428.344 -86.453 428.754 86.453 429.73 c 86.453 430.969 85.066 431.305 84.242 431.305 - c 82.855 431.305 82.031 430.031 81.73 429.504 c 81.129 431.078 79.855 431.305 - 79.141 431.305 c 76.668 431.305 75.281 428.23 75.281 427.629 c 75.281 427.367 - 75.543 427.367 75.578 427.367 c 75.766 427.367 75.844 427.441 75.879 427.629 - c 76.703 430.18 78.281 430.781 79.105 430.781 c 79.555 430.781 80.379 430.555 - 80.379 429.168 c 80.379 428.418 79.969 426.844 79.105 423.469 c 78.73 422.004 - 77.867 420.992 76.816 420.992 c 76.668 420.992 76.141 420.992 75.617 421.293 - c 76.219 421.441 76.742 421.93 76.742 422.605 c 76.742 423.242 76.219 423.43 - 75.879 423.43 c 75.129 423.43 74.566 422.828 74.566 422.043 c 74.566 420.953 - 75.73 420.469 76.781 420.469 c 78.391 420.469 79.254 422.156 79.293 422.266 - c 79.594 421.406 80.453 420.469 81.879 420.469 c 84.355 420.469 85.703 -423.543 85.703 424.141 c 85.703 424.406 85.516 424.406 85.441 424.406 c -85.219 424.406 85.18 424.293 85.105 424.141 c 84.316 421.555 82.703 420.992 - 81.953 420.992 c 81.016 420.992 80.641 421.742 80.641 422.566 c 80.641 -423.094 80.754 423.617 81.016 424.668 c h -f -94.422 426.73 m 94.422 428.566 94.156 431.453 92.844 434.191 c 91.422 437.117 - 89.359 438.691 89.133 438.691 c 88.984 438.691 88.871 438.578 88.871 438.43 - c 88.871 438.355 88.871 438.316 89.32 437.867 c 91.684 435.504 93.031 431.719 - 93.031 426.73 c 93.031 422.605 92.172 418.406 89.207 415.406 c 88.871 415.105 - 88.871 415.066 88.871 414.992 c 88.871 414.844 88.984 414.73 89.133 414.73 - c 89.359 414.73 91.531 416.379 92.922 419.418 c 94.156 422.043 94.422 424.703 - 94.422 426.73 c h -f -119.891 428.566 m 120.266 428.566 120.715 428.566 120.715 429.016 c 120.715 - 429.504 120.266 429.504 119.93 429.504 c 105.602 429.504 l 105.266 429.504 - 104.816 429.504 104.816 429.016 c 104.816 428.566 105.266 428.566 105.602 - 428.566 c h -119.93 423.918 m 120.266 423.918 120.715 423.918 120.715 424.406 c 120.715 - 424.855 120.266 424.855 119.891 424.855 c 105.602 424.855 l 105.266 424.855 - 104.816 424.855 104.816 424.406 c 104.816 423.918 105.266 423.918 105.602 - 423.918 c h -f -138.785 425.875 m 130.273 415.375 l 130.086 415.148 130.051 415.113 130.051 - 415 c 130.051 414.738 130.273 414.738 130.723 414.738 c 150.523 414.738 - l 152.586 420.699 l 151.988 420.699 l 151.387 418.898 149.812 417.438 147.75 - 416.762 c 147.375 416.613 145.723 416.051 142.199 416.051 c 132.035 416.051 - l 140.363 426.324 l 140.512 426.551 140.551 426.586 140.551 426.699 c 140.551 - 426.812 140.551 426.812 140.398 427.039 c 132.637 437.688 l 142.086 437.688 - l 144.824 437.688 150.336 437.539 151.988 433.074 c 152.586 433.074 l 150.523 - 438.664 l 130.723 438.664 l 130.051 438.664 130.051 438.625 130.051 437.914 - c h -f -167.887 442.352 m 168.039 442.988 168.336 443.551 169.648 443.59 c 169.727 - 443.59 169.988 443.59 169.988 443.926 c 169.988 444.039 169.914 444.188 - 169.727 444.188 c 169.199 444.188 168.562 444.113 168 444.113 c 167.586 - 444.113 166.648 444.188 166.238 444.188 c 166.164 444.188 165.898 444.188 - 165.898 443.812 c 165.898 443.59 166.125 443.59 166.273 443.59 c 167.062 - 443.551 167.324 443.289 167.324 442.875 c 167.324 442.762 167.324 442.652 - 167.25 442.5 c 165.449 435.188 l 161.211 443.887 l 161.062 444.188 161.023 - 444.188 160.613 444.188 c 158.324 444.188 l 158.023 444.188 157.801 444.188 - 157.801 443.812 c 157.801 443.59 157.988 443.59 158.363 443.59 c 158.699 - 443.59 159.074 443.551 159.414 443.477 c 157.199 434.551 l 157.051 433.914 - 156.75 433.387 155.438 433.352 c 155.324 433.352 155.102 433.352 155.102 - 433.012 c 155.102 432.824 155.211 432.75 155.324 432.75 c 155.887 432.75 - 156.523 432.824 157.086 432.824 c 157.5 432.824 158.438 432.75 158.852 -432.75 c 159.039 432.75 159.188 432.824 159.188 433.09 c 159.188 433.352 - 159 433.352 158.812 433.352 c 157.762 433.387 157.762 433.84 157.762 434.062 - c 157.762 434.137 157.762 434.215 157.801 434.477 c 159.977 443.027 l 164.852 - 433.051 l 164.961 432.75 165.039 432.75 165.227 432.75 c 165.488 432.75 - 165.488 432.789 165.562 433.09 c h -f -174.145 438.391 m 174.145 437.863 l 175.008 437.863 175.121 437.789 175.121 - 437.188 c 175.121 434.863 l 174.855 435.09 174.219 435.5 173.207 435.5 -c 171.445 435.5 169.945 434.301 169.945 432.801 c 169.945 431.34 171.293 - 430.062 173.094 430.062 c 174.07 430.062 174.746 430.516 175.082 430.812 - c 175.082 430.062 l 177.145 430.215 l 177.145 430.738 l 176.246 430.738 - 176.133 430.812 176.133 431.414 c 176.133 438.5 l h -175.082 431.527 m 174.52 430.625 173.621 430.477 173.133 430.477 c 172.57 - 430.477 171.969 430.703 171.559 431.227 c 171.184 431.75 171.145 432.426 - 171.145 432.801 c 171.145 433.102 171.184 433.891 171.668 434.453 c 172.082 - 434.863 172.719 435.09 173.32 435.09 c 173.656 435.09 174.52 435.051 175.082 - 434.227 c h -f -185.398 432.766 m 185.398 434.266 184.012 435.578 182.098 435.578 c 180.223 - 435.578 178.836 434.266 178.836 432.766 c 178.836 431.34 180.262 430.062 - 182.098 430.062 c 184.012 430.062 185.398 431.34 185.398 432.766 c h -182.098 430.516 m 180.035 430.516 180.035 432.312 180.035 432.875 c 180.035 - 433.402 180.035 435.164 182.098 435.164 c 184.199 435.164 184.199 433.402 - 184.199 432.875 c 184.199 432.312 184.199 430.516 182.098 430.516 c h -f -189.184 434.828 m 190.91 434.828 l 190.91 435.352 l 189.148 435.352 l 189.148 - 436.664 l 189.148 437.789 189.898 438.238 190.461 438.238 c 190.535 438.238 - 190.758 438.238 190.758 438.203 c 190.758 438.164 l 190.684 438.09 190.535 - 437.938 190.535 437.715 c 190.535 437.375 190.797 437.078 191.172 437.078 - c 191.547 437.078 191.773 437.375 191.773 437.715 c 191.773 438.238 191.285 - 438.652 190.461 438.652 c 189.41 438.652 188.172 437.977 188.172 436.664 - c 188.172 435.352 l 187.008 435.352 l 187.008 434.828 l 188.172 434.828 - l 188.172 431.227 l 188.172 430.852 188.172 430.738 187.422 430.738 c 187.195 - 430.738 l 187.195 430.215 l 187.684 430.25 188.246 430.25 188.734 430.25 - c 189.371 430.25 189.934 430.25 190.461 430.215 c 190.461 430.738 l 190.121 - 430.738 l 189.184 430.738 189.184 430.852 189.184 431.227 c h -f -155.961 414.605 m 155.926 414.383 155.812 413.969 155.812 413.93 c 155.812 - 413.555 156.113 413.406 156.375 413.406 c 156.676 413.406 156.938 413.594 - 157.051 413.742 c 157.125 413.895 157.238 414.457 157.352 414.793 c 157.426 - 415.094 157.613 415.883 157.688 416.293 c 157.801 416.668 157.914 417.043 - 157.988 417.418 c 158.176 418.094 158.211 418.242 158.699 418.918 c 159.148 - 419.594 159.938 420.457 161.211 420.457 c 162.148 420.457 162.188 419.594 - 162.188 419.293 c 162.188 418.281 161.477 416.445 161.211 415.73 c 161.023 - 415.242 160.949 415.094 160.949 414.832 c 160.949 413.93 161.664 413.406 - 162.523 413.406 c 164.211 413.406 164.926 415.695 164.926 415.957 c 164.926 - 416.18 164.738 416.18 164.664 416.18 c 164.438 416.18 164.438 416.07 164.363 - 415.883 c 163.988 414.531 163.238 413.855 162.602 413.855 c 162.227 413.855 - 162.148 414.082 162.148 414.457 c 162.148 414.832 162.262 415.055 162.562 - 415.805 c 162.75 416.332 163.426 418.094 163.426 419.031 c 163.426 420.645 - 162.148 420.945 161.25 420.945 c 159.863 420.945 158.926 420.082 158.438 - 419.406 c 158.324 420.57 157.352 420.945 156.637 420.945 c 155.926 420.945 - 155.551 420.418 155.324 420.043 c 154.949 419.406 154.727 418.469 154.727 - 418.355 c 154.727 418.168 154.949 418.168 155.023 418.168 c 155.25 418.168 - 155.25 418.207 155.363 418.656 c 155.625 419.633 155.961 420.457 156.602 - 420.457 c 157.051 420.457 157.164 420.082 157.164 419.633 c 157.164 419.332 - 157.012 418.695 156.863 418.242 c 156.75 417.793 156.602 417.117 156.523 - 416.742 c h -f -208.41 423.953 m 212.082 424.254 214.746 426.469 214.746 428.906 c 214.746 - 431.379 212.047 433.555 208.41 433.855 c 208.41 435.168 l 208.41 435.992 - 208.41 436.328 210.66 436.328 c 211.445 436.328 l 211.445 437.078 l 210.582 - 437.004 208.41 437.004 207.395 437.004 c 206.422 437.004 204.207 437.004 - 203.348 437.078 c 203.348 436.328 l 204.133 436.328 l 206.422 436.328 206.422 - 436.031 206.422 435.168 c 206.422 433.855 l 202.746 433.48 200.195 431.266 - 200.195 428.906 c 200.195 426.43 202.859 424.328 206.422 423.953 c 206.422 - 422.605 l 206.422 421.816 206.422 421.48 204.133 421.48 c 203.348 421.48 - l 203.348 420.73 l 204.207 420.805 206.422 420.805 207.395 420.805 c 208.371 - 420.805 210.582 420.805 211.445 420.73 c 211.445 421.48 l 210.66 421.48 - l 208.41 421.48 208.41 421.781 208.41 422.605 c h -206.422 424.516 m 203.008 424.969 202.598 427.406 202.598 428.906 c 202.598 - 430.141 202.82 432.805 206.422 433.293 c h -208.41 433.328 m 211.707 432.918 212.348 430.742 212.348 428.906 c 212.348 - 427.48 212.008 424.93 208.41 424.48 c h -f -218.141 418.195 m 218.102 417.969 217.988 417.555 217.988 417.52 c 217.988 - 417.145 218.289 416.992 218.551 416.992 c 218.852 416.992 219.113 417.18 - 219.227 417.332 c 219.301 417.48 219.414 418.043 219.527 418.383 c 219.602 - 418.68 219.789 419.469 219.863 419.883 c 219.977 420.258 220.09 420.633 - 220.164 421.008 c 220.352 421.68 220.391 421.832 220.879 422.508 c 221.328 - 423.18 222.113 424.043 223.391 424.043 c 224.328 424.043 224.363 423.18 - 224.363 422.883 c 224.363 421.867 223.652 420.031 223.391 419.32 c 223.203 - 418.832 223.129 418.68 223.129 418.418 c 223.129 417.52 223.84 416.992 -224.703 416.992 c 226.391 416.992 227.102 419.281 227.102 419.543 c 227.102 - 419.77 226.914 419.77 226.84 419.77 c 226.613 419.77 226.613 419.656 226.539 - 419.469 c 226.164 418.117 225.414 417.445 224.777 417.445 c 224.402 417.445 - 224.328 417.668 224.328 418.043 c 224.328 418.418 224.441 418.645 224.738 - 419.395 c 224.926 419.918 225.602 421.68 225.602 422.617 c 225.602 424.23 - 224.328 424.531 223.426 424.531 c 222.039 424.531 221.102 423.668 220.613 - 422.992 c 220.504 424.156 219.527 424.531 218.816 424.531 c 218.102 424.531 - 217.727 424.008 217.504 423.633 c 217.129 422.992 216.902 422.055 216.902 - 421.945 c 216.902 421.758 217.129 421.758 217.203 421.758 c 217.426 421.758 - 217.426 421.793 217.539 422.242 c 217.801 423.219 218.141 424.043 218.777 - 424.043 c 219.227 424.043 219.34 423.668 219.34 423.219 c 219.34 422.918 - 219.191 422.281 219.039 421.832 c 218.926 421.383 218.777 420.707 218.703 - 420.332 c h -f -237.043 414.992 m 237.043 415.066 237.043 415.105 236.629 415.516 c 233.668 - 418.516 232.879 423.055 232.879 426.73 c 232.879 430.891 233.781 435.055 - 236.742 438.016 c 237.043 438.316 237.043 438.355 237.043 438.43 c 237.043 - 438.617 236.969 438.691 236.816 438.691 c 236.555 438.691 234.418 437.043 - 232.992 434.004 c 231.793 431.379 231.492 428.719 231.492 426.73 c 231.492 - 424.855 231.754 421.969 233.066 419.23 c 234.531 416.305 236.555 414.73 - 236.816 414.73 c 236.969 414.73 237.043 414.805 237.043 414.992 c h -f -246.414 427.969 m 246.566 428.566 247.129 430.781 248.777 430.781 c 248.891 - 430.781 249.488 430.781 249.977 430.48 c 249.301 430.328 248.852 429.766 - 248.852 429.168 c 248.852 428.793 249.113 428.344 249.754 428.344 c 250.277 - 428.344 251.027 428.754 251.027 429.73 c 251.027 430.969 249.641 431.305 - 248.816 431.305 c 247.426 431.305 246.602 430.031 246.301 429.504 c 245.703 - 431.078 244.426 431.305 243.715 431.305 c 241.238 431.305 239.852 428.23 - 239.852 427.629 c 239.852 427.367 240.113 427.367 240.152 427.367 c 240.34 - 427.367 240.414 427.441 240.453 427.629 c 241.277 430.18 242.852 430.781 - 243.676 430.781 c 244.129 430.781 244.953 430.555 244.953 429.168 c 244.953 - 428.418 244.539 426.844 243.676 423.469 c 243.301 422.004 242.441 420.992 - 241.391 420.992 c 241.238 420.992 240.715 420.992 240.191 421.293 c 240.789 - 421.441 241.316 421.93 241.316 422.605 c 241.316 423.242 240.789 423.43 - 240.453 423.43 c 239.703 423.43 239.141 422.828 239.141 422.043 c 239.141 - 420.953 240.301 420.469 241.352 420.469 c 242.965 420.469 243.828 422.156 - 243.863 422.266 c 244.164 421.406 245.027 420.469 246.453 420.469 c 248.926 - 420.469 250.277 423.543 250.277 424.141 c 250.277 424.406 250.09 424.406 - 250.016 424.406 c 249.789 424.406 249.754 424.293 249.676 424.141 c 248.891 - 421.555 247.277 420.992 246.527 420.992 c 245.59 420.992 245.215 421.742 - 245.215 422.566 c 245.215 423.094 245.328 423.617 245.59 424.668 c h -f -258.992 426.73 m 258.992 428.566 258.73 431.453 257.418 434.191 c 255.992 - 437.117 253.93 438.691 253.707 438.691 c 253.555 438.691 253.441 438.578 - 253.441 438.43 c 253.441 438.355 253.441 438.316 253.895 437.867 c 256.254 - 435.504 257.605 431.719 257.605 426.73 c 257.605 422.605 256.742 418.406 - 253.781 415.406 c 253.441 415.105 253.441 415.066 253.441 414.992 c 253.441 - 414.844 253.555 414.73 253.707 414.73 c 253.93 414.73 256.105 416.379 257.492 - 419.418 c 258.73 422.043 258.992 424.703 258.992 426.73 c h -f -268.922 437.344 m 265.695 434.078 l 266.109 433.668 l 268.922 436.105 l - 271.66 433.668 l 272.07 434.078 l h -f -269.754 422.078 m 270.016 421.105 270.879 420.469 271.891 420.469 c 272.715 - 420.469 273.277 421.031 273.652 421.781 c 274.066 422.641 274.367 424.105 - 274.367 424.141 c 274.367 424.406 274.18 424.406 274.102 424.406 c 273.84 - 424.406 273.84 424.293 273.766 423.953 c 273.43 422.605 272.977 420.992 - 271.965 420.992 c 271.477 420.992 271.215 421.293 271.215 422.078 c 271.215 - 422.605 271.516 423.73 271.703 424.594 c 272.379 427.18 l 272.453 427.516 - 272.68 428.418 272.789 428.793 c 272.902 429.355 273.129 430.254 273.129 - 430.406 c 273.129 430.816 272.789 431.043 272.453 431.043 c 272.34 431.043 - 271.703 431.004 271.516 430.219 c 271.066 428.453 270.016 424.254 269.715 - 423.016 c 269.68 422.906 268.742 420.992 266.977 420.992 c 265.742 420.992 - 265.516 422.078 265.516 422.941 c 265.516 424.293 266.191 426.168 266.789 - 427.816 c 267.09 428.566 267.203 428.906 267.203 429.355 c 267.203 430.406 - 266.453 431.305 265.254 431.305 c 262.965 431.305 262.102 427.816 262.102 - 427.629 c 262.102 427.367 262.328 427.367 262.367 427.367 c 262.629 427.367 - 262.629 427.441 262.742 427.816 c 263.34 429.879 264.277 430.781 265.18 - 430.781 c 265.402 430.781 265.777 430.742 265.777 429.992 c 265.777 429.43 - 265.516 428.719 265.367 428.379 c 264.465 425.98 263.977 424.516 263.977 - 423.355 c 263.977 421.066 265.629 420.469 266.902 420.469 c 268.477 420.469 - 269.34 421.555 269.754 422.078 c h -f -277.105 418.195 m 277.066 417.969 276.957 417.555 276.957 417.52 c 276.957 - 417.145 277.254 416.992 277.52 416.992 c 277.816 416.992 278.082 417.18 - 278.191 417.332 c 278.27 417.48 278.379 418.043 278.492 418.383 c 278.566 - 418.68 278.754 419.469 278.832 419.883 c 278.941 420.258 279.055 420.633 - 279.129 421.008 c 279.316 421.68 279.355 421.832 279.844 422.508 c 280.293 - 423.18 281.082 424.043 282.355 424.043 c 283.293 424.043 283.332 423.18 - 283.332 422.883 c 283.332 421.867 282.617 420.031 282.355 419.32 c 282.168 - 418.832 282.094 418.68 282.094 418.418 c 282.094 417.52 282.805 416.992 - 283.668 416.992 c 285.355 416.992 286.066 419.281 286.066 419.543 c 286.066 - 419.77 285.879 419.77 285.805 419.77 c 285.582 419.77 285.582 419.656 285.504 - 419.469 c 285.129 418.117 284.379 417.445 283.742 417.445 c 283.367 417.445 - 283.293 417.668 283.293 418.043 c 283.293 418.418 283.406 418.645 283.707 - 419.395 c 283.895 419.918 284.566 421.68 284.566 422.617 c 284.566 424.23 - 283.293 424.531 282.395 424.531 c 281.004 424.531 280.066 423.668 279.582 - 422.992 c 279.469 424.156 278.492 424.531 277.781 424.531 c 277.066 424.531 - 276.691 424.008 276.469 423.633 c 276.094 422.992 275.867 422.055 275.867 - 421.945 c 275.867 421.758 276.094 421.758 276.168 421.758 c 276.395 421.758 - 276.395 421.793 276.504 422.242 c 276.77 423.219 277.105 424.043 277.742 - 424.043 c 278.191 424.043 278.305 423.668 278.305 423.219 c 278.305 422.918 - 278.156 422.281 278.004 421.832 c 277.895 421.383 277.742 420.707 277.668 - 420.332 c h -f -Q q -425.75 399.406 72.949 -86.445 re W n -q -425 399.5 74 -87 re W n -[ 0.240758 0 0 0.240125 425.748853 312.959678 ] concat -/DeviceRGB setcolorspace -8 dict dup begin - /ImageType 1 def - /Width 303 def - /Height 360 def - /Interpolate true def - /BitsPerComponent 8 def - /Decode [ 0 1 0 1 0 1 ] def - /DataSource currentfile /ASCII85Decode filter /FlateDecode filter def - /Interpolate true def - /ImageMatrix [ 1 0 0 -1 0 360 ] def -end -image -Gb"/LGC1,!orV83e[r3B'`oY\k[9kC9f,]MVOD*j2ZciEYn5Fe)+6t;KEN,j6a6[>7IOV<#) - qe<*%.Pr,VLgcOr#KpfD>K6pXPhfg"A,bn+iJ+:ne]!eETZ&-rC?JNt=h#Qt3[5TgUD"9O->+:ne]!eETZ&-rC?JNt=h#Qt3 - [5TgUD"9O->+:ne]!eETZ&-rC?JNt=h#R&o?h]i!iTE"iJLEGH(3;Q]$&DS77oc`,(HhW_" - 4q[g=8,qQOJt'QO"pM)7]iqJe5'lkBfH5))7j/FK(!:+/OHG[ajlP$g8X"Z%iu^%+bg@Mj5 - ]AHFX2KMdlX/&ed9[R/c-8-Ak8jNs#Qtro=TT9;maUPSI!g9(LY!gZtrknqk1Vtmb!e0q'LLJ)TGu_kkC"(`796qipb^sjQrZHoJKENPiNCJ!J_?J - n:OWFf3Ks3gss*Tafc_#PUTj"j=J,.8ppn'f\,S9$F;MgPT"T7-aPa%D'M@hOclra$5UdkJ - P+VZDg(EgU[.PQ2@BObKS*'8>&rH4(q"WbFmWYHs - !^Rmi.Zr?@IoYG"ldmmaA/IFR0RJ`u8Wq"_+:+'1U8/3c#649HG4+.BUmIOE($fkcSirl>! - ^R$R@['idcj`9ks&"?^=((t$nORkj5LFUg'S-0m<)h@khgNOo-L$XX5VUk,GpOXPrgsPqm; - IKT;l:*Y3aJQ-lg5"ff#C2_HQt]Im+E&$RTPUr7KPli/P7LTaUg<(^FSg=eLRH*^9%H&N5, - mdU;UZOW2POE80E^sd\)J_aCP(t^]*mZ("fp0(Qr"ZkQiM)@![_ro`'Z#L;%p&K%HbPZg-a - a6Qk"l`nI.A,mk(nPkaE+s7q.E@+(iB88`)3FFk@uDpZOZqk-1#^3tA'YtU5LiR-%CLd80X - j:/,b&m7R)-3!.)J,81Is7h@6r1RQ:L6\piKR+"uA1X,i/N0X5"U4De`Hif99(5NACl=HKK - PnkAq"rtK*XnsUGGV>s4dlNu0`hTh$US;2#RG\Mn=^IX3r0s2#kie3[OC3)?ATfBhu2teDr - /.[]mD\9ftu_,@PL(#Ce0B%B(_^=hLV+C;@+X - )^>CLFM:'Yqn+Q/'A6'!X%O=O);2)I"$nAku_j'r^?iTt(^\ZJ6J,.88:S.@XqXWY2e0r," - &qNi9%*A%R8<ZG8TKPOpI"/O"?+[_ - ,'0;c'gL_\C3`UQ/I4T&L2%Kbb26l2W.>u&mrA#3HaUd,cefj@cbQ7SD#>)r@Mr+mu%u8P$ - ')U/<"jRagNT7<60n\s7su,M9hbVCXJj[YGjd:c1>cVP@B20PEP-boN7kX%?N]?W7;GeXN2Mu]q>'#CX-4l)Jq"\f!A^\YO+J"*b-sgUTY>aFlM:& - 7hgYI)3&&YA+/Vkn^cCk3e_6-M`CI.+cCkfPBkUO^92%ZJ%j("+:AMiSoB\p*UL:f+"/:#Dr7DjD"R(QXCA'&hcbK4 - J!h*Wl/QLcd0!Ll0pGB:jU,'_Gg[W!-XXUJHW51Qjqkf-L!U - V(hnPeKQ%]pZF(Vc_@K^!jL^ss5cN3\(f8n-*_%WIe0_-:X]C3I\rVH3YkKd:8r:8#a4*9] - %CWFKMld9>9![H$CEKO_:\paI!191PeLU"Y9DJGj1W.INfqXj%4a,e"3lDr[KDhj$H\hVU: - \g;oiB=Fa_P[&HX3.(gi=XCR4PQXHt*EDU-%j+!JGOOC[4aW90`cVfs;N,hNkp&R"=maeB) - a+BjE+::&N9l6IYt'63i5+6]GA#0hKiD!@BjkE1\bSUL;0!U6C`p&VE*#Sf;=^Rgnu1p'%= - $AT?+TNOd:g2\Dq%uE7UZ8IGWJ?6E%lBE-"`G788p0MV/%h?$6Jm%bEmfN]liXA<)f\0<]e - .D-;"Di[7RQ[`7$_E;cDWk'C1e!88r:1'c>i@H,K(Co,dS?JHJFoUUgT_8rUQV1F5N4X]Vi - [bUUHRTJ/'oRi9VE4_*)@n(bH0Dr*UPP`:m%Ca_d2n;b?KT?q>\n?8#s$17q[JPcuR&/`6Y - ZG=ODCjg2Y"a+$#jq`:!oo1T0:k:O_X@*S\8am6e+"?UY - 4K''&fD5(MtIjFP0:thTi#h5pOJN[&No?@,=dh\L9qIh6]AhN4n'j[?XM^Vf<:B@-+Eu?"@ - `rtA7/q,20*bZO[)s.Mc<9,hek=$1gmXn[r,LH%EY[a>TFRb7Wq_jk09BDqXd)=\?aQ&JW] - -#7<.$V5W\LASFJhg3AieI!e'/C!n6B[:"Dj4FR(5VXd3c?Hjd^U8l8WTBLm6fW5Q#1.:\e8% - R/8E*??W(tktgq>'hW#`IRrZ/`jdbSr,g8oF+S^!n#.Xo`A?U[Uh>Y[PG2$;N.7?Aba44#F - b%3MN7Bi2_M&88nm&'c95qr&]j(?qa-`i?]$V,e"If4l0Ea&-"K7@sWG^1TU.M%`-8\0JJ( - qg!C].4,i:_jZYknhYHQm=DfRfWa%VO@[(,;EA9=@K(Hm]_"d':)f]7j]65bUrqSqJ*>j(q - Hm]L(5%.l.d)nq@"=Juq^rW\8L]c\9;56tXJ"CG%.B7^,[m;)VL$V+[0Qr$jiMg9 - .$qV5UD7?lM4#/hesjX>QDGJoefa_"as;r<`_J_SSW=or - :ZlEDYT\+9191Q@J]Y\U4\@`?eVk005\AsM::O:e8)^c6W1A - 5qX%AiiXnj>jb0T$H4Ya;l5XZ,rcme"/G?P1#'SoXOY - t6F!n!T#sG@qMQ/.=%1#>9YXYBJFm9[/us3cp1H,JbO","B\iprtbTYe[b]cQ6'3UUrR0?kiC91ndni/ - c+Shio7b2P9(&(L\63Q4$+D3F5[fP01Am%='*?G#@Ol!@))c2c9\Zj,Qf9;5$TEgZB<+?Bk - aN5n#UU(^rS>3I>R2.T76Vc2+N6]@=;OrET78u3kgQ:j&K6>W[^(h_P?07"iD]64VI)c$Nd - *m688k,LCP=kAN[%]Yf"Fk/oRqQNsNQ4X`j0iS]iS"DQkZG5(!!^"if<+Ds-3BTGh,m?EL' - &WcI-q.'Zo,/1dU]*!A>g8RRcfMTQ1Do^m6)^t/om>`,O2dp(g/EZlSLnBF=4Q(U%r4fZW# - W%9VL,UDm0>9uc3V5W\Lr^M<@31eFCY$F+K'P(5NWkt4?aEH>Y4aIg-mXR3q01Am+V-+G+j - ArEg8S46\.V&T*5Cn\&N+a[*OsNath<)K@P(AbYOS3p`>X1OS2ute8"I3A7@-!ZKAn5GF]" - P>b:.nI7j.jj'0\bf42/CbO%LAJ&Jf52YdB(.)7M[?t-1M]h)t(RoOlsHh&u4N.F*$T"7tM - Y`4trQjGnM\t9lFIlV5UD7Cg%)WUT^liX]r9UX:f=ZKn3*A.4P^a.or`:jgntjKYp5h.m>C - ;eBm5QE[`Fdi"jD8&o7is![E%U>R69UL($AUH?tt]QD1D"cZ:C%aj$2-K?Pg]L9O6WXBiFr - ?_n@NhQIp('NJ..m=RpNH$amF\8[#C.`#/i4trQiG7McYYL7;_*OZY^4[.b8W)j^pP"SD>J - g3X/,hN7N"@b;T\=fJpQ"\H>7kR51O/J;`q>'#CWtQgR@*apu=X@/V8MM\$N5AKBOX!AjqE - 2@9O\8POjkN.HPT8WVn`/+=$!'A>0T&@9$\=F'+"d]9"q;L?Po1S"pnaqSnRZE$Z^Q-'SAA - T`D^s0[_&=^1N5EYF'H$;q]mJ_T"^g.ZQi0!&E5TK4o4#Ed:c(d^fW\d@8rd9gbR0;IhRjF - *`f1orU9^:Pcmb9TWlcV4,.p<'E8U^R7tS]6.kptb2noq0`j'$oU7+4>OkU(0JZhZZg=F0: - jC2S-^rDQZ#o5cG(esG.&I6IB05-O<:tK[SN\M;S(0,s]"kcmR8ni*=;)O**B1*)\)rUqf15 - F,O[fODSm/'aN07DSDB2I7+=Mo^JWX;s)B9a@=('Kfk?WtF.PjumFH3#e+?32. - g\D[PMp?gU3"]"FG)EVhQc3Kj2\k"rS")J(!Os;B+N#396`luY#<.fXL,dU)s"sm`C>`-Z*j./8UG44:IWp]h'*Z>l@rbR%b[q - M#]r;#s+X:gK.qS5(;p2!]K>Gf!U;H-XVTa)VbkMtS)7Y8i65n(lNB^SdJY$JZ6P5B:57gD - M7:Q#[i%!Xg'mFnu,G`l2U+BT^&Dqqi7',/8">>;fs/O`[#`tu^O8',=SAs-:C+BT0ld8JH - r#7dD!)rB!8QD1D%XT!H*LIS%!HhK"Y<<<]S!i)t6'a!Fnq=@I[Xe/.8YnCE.,W)T_VfPh> - =r#6cl&icS4>=o/7IAd7-RuHlX'KisWd6dsVpkM$9<7Nrs#uF*,;@2c6IEo,ue1=[WUu6W9WnaBgU"sGWLUTVh5(EH6gQ77cB&1ahT=k\6 - 61P&ZW"!@pOO4Wd;=j1-S6ec0CrfK4m<$LI4X@P['*g#KHcAqkMTNPje09;,u`Kd1W58G44 - 9^c-_^u(8D%aZ!+PMPtY84Rk.!.PoUe$ko>hJOmke0HLtfBC5s>@b5rnlME5Ft - +B2*K5Gl5pPeELjU8&MC)@FK:o]U"n1,-"r`O0I2WYBhIgi+^BHG$^Q*tsCRC539>BU#$b_ - >:rlk0+^&VUAK@m`d.6R`FE%'%8iJ$4:I2S4>kR@$FoRao^V'[ - Uq^"9C9Y*Wg*YUTicjq!d7@MN0?IF*MQ6*$5q7$rM86>k@+&iVS_\W[GSm?rXEG[9gOmI/S - ^$C0jeG["u?#@l0qE*/bUdVAC::!S.LqoB4GpV5PCR](o6'lZKUZC^lY7E"4bc6"W;N,3>73+0r%'#i83UXWrbK.;G%n:&(.`o[c4_k&EJ#CsFKC6]i5!]tH()\jU/\?(ir+U)c0Z@(^j\/ - sM.+J#+;$W@8mq'NI:[.lPnZJk*r5W)3ZB"mODd@9-c`oB)#l0Q,RL"Vj^3IgV.CiJAk#I_ - PU*lK$'NafN'"PQs[$ogTo<-VTnXWb(W=cWZ4+.VB9V(aXCsj@O*HD?b)g1qDX9]G.bBM\^ - ]>^c2'&cWc:,*ab-W1eG]^jJl1Y!oK!57sBQJ^h@a;C/@a'-b,Vqo['G5lLFcZ?%>-tX!:) - mOF6#L`9aU'fR6drUkM - WlJ2;$*EOQ;0&qHYn.mGO)=q*!i'uhC>616q==%Fp3Kh3JPd.g>nnFoLs9]7rr$OlLE"&*^ - j,8#[F!8m2l7NnoCSlXWq)@Y'%8jam+=VKdFDY\0Uc7(\nfnM<#?^!Vkp?WZ:e[i8hN4g*5 - 3[iO"Ln-"67Un1JqRsc(r.R/oRqQNsNQ4XeqqkO]cg48-VQF92Si"m+f--?P49:fDQ/c'NK - 9nRM$o)WuF!8V!/jO$KZh9An5m\<2HUnAY?hP-h_828'(o>#K-9]R8m=A&huu_7Ua?^rr)^ - k4cJ`$92Y)pq]#3JiHRCRRl5-!dZ@US3ER@?kKTKOS^JceMJ>@nc]T+kQ_0mGc]GaSX:1&( - A9!YO4]!H[>"_LcmE2+Cn8o/Bfs>)MS^IaC4\SI8e3?a).nUZA:JT2'"Ka^InOA0["n*BT#$HiMY2(`giE^(R4%b0.uMX?&/ - u"/D$UW6:JY6g&mnBNg;Y?p-J\u3B)M&** - En?c/::Thn4l\?8kuSA_tPYFdFk0H0Zkq8c-O^+kBbNp>)MT5]TfT-dUKODFQcPIiR+W4=^ - XWBMh_`\L/)jD@TnZS>[0T]smFt.UdQ\`i - 6j#T]^2-\:rAZ+Ra)a/@@La^#h6;H.;iNRdRg4c/fuSt8\heOa.C?t:L?fh>" - 2Fslo;<%A6,9#U/lh+,KfW98]e-V'FR8jJY@:0d=(8J[dQD46OJ`1BFGW34&NSae*gIt)tCRO,:TB:'VT`Cj(;D;0e?jjZK$'\/KDG`/8 - 1*1kI'Y[KmYojh+j$$-3DG\$@*ack+t"R"h7![F/QK-/'YMakh5SNE1^Wnh&K?ki(>8PMq@ - c_-?.(OX[m]Xip]E^EPa9$YJt#;QRQkb-a?M]"\+j>dpbZr".me8X&^hA7 - :]Hd!0_t2ElX.N)"67jZZG;)FSa#OTV\Tib2\E>I!r5'rU@]8afO1s11F3"(pgNRd((Zu7S - ?TaQo"SoTbFHRBMP0`9kIC*-k)(*92Rcolra)%H%!)WQD1rE?^)fmXH'3",UOji2'P2`#N^ - NafZ<(A - -;0%F&+/\2!'!)V&g"G'BHu5<=92XMr01us^f#H0!io8tU4.5_SF%?L)F-iVuV59mWF_;]u - 7Q9;fQ1BM,9'd5o]T.oFp=bj;H1-er=/Uj0PjeE[;-$)gLO?eKM5cQ\.j)-OsT>AX;F;t;;IY - pVFQQhlH5ABafJYJMZY3='K%*[".beM.qgB3Rr_Cf4A%4K+95jYR8o.g(8D%+;3R0+plc=0 - :4^gkq684RLr,qJRPejbhqhmE/VE_In`7fUBIPD6I#"$qd14rq*MX3@k?,65+hdAY)&*9ER - AHi4&/^02)1kW(WMQs9ePl7=aH348UZ - >)MT:4M2ff#N+b7RQ5F9R8pS$I:,0]m[Ub1V)-N$#q\ - U=3.@59MSod#EUi$W198Q+9jhKVM[Kk!crp-W#VAL<3'JiNUa4qsEllGF:cY=AKod"D=\DU - ^NZ=eSET0C[$os_UH,p+Xn]5/_0VYDB%2q(]%mDR6ojh[LMatki - b0%l*3LYW<^aQN'otlCj^:ol8Up[C%92Rj=n3,P`)39qR84W_b7=(2R=b0Fj.I+p4)pse?2 - 1V!eH8NsOcis8UZT4jAOL4A&k=]rj2D7(d4FJhiem'GMp7;C6$:V%ZD`Ygk - Z&BZY%JW"0V=G4>!EN2kJ;rV$X+MGa)H,9[*7gIntBTKTa,!\`6-bN0c2)enQ]Uo2]u^0G8 - lp[=\185\sKup?bN%3@&$N?kb7_/Li5:7m"%1/O^ub%p+dN'V!Y$dSah?@OMbG`^U_>RPY< - klHa(k;H2ZUB@k.JP[%5Y@%#tZYFnr]Q)t$9M>kE4DX.p.4S1,^YNY' - WQ1dplI;d8Z,d$lWWdqc/O_gAhuGg*ONeepQAMc]UC/A;a^o'rHD"EK/2.E(;'@WFa[\jAh - *bG(8i21LqVb:l)NEn7\T8g'EJMFo^XcaOeW=2UfoW`?)(aiJPq.. - :"J/k+=Vp&$OGJPk'>ZY7`1FS%a797`4=$"&uF1p;U'ai2<@6Pj]g4XpbsP"S[J^t?DOIrt< - 8k0m4-U4p7EY7&cfZT<@#@(2cR+VpgVJItdTFn%KV&A1h - 7L/.RT7N4,?fscB[@lD`6Na(92UO(i0s0KUZAk$hl]mBAH6PL/(92UPSkLYFapddN4Z@ - /6T8HaU=/iQC;Mi',]EDicXS/a?!<+XK5Hl,HWUWK@2 - 5s^bWMJ-1GQD,#Z`tp$.NKWdQN[e&/J<=oT/$$epUTpYo,paki,kRtL8@0nnjls.$fW:)Q3 - RY=ZWf.c0m^SZGFXfEX4(ci;<2.'o4%s+JgqeUJ?,`mK&/`AZ;;8NrbC=m]Dm+qM'Gu]#k, - Zp`QeY$J - ZdB-3U492UNUj,,Q(UZ?Udh!+`Keb['@F660g_2G2=;H0A8fr7gKWl^'Q#]On2CfVhaU[k7 - [/2288gmS2l)NE@^%C?h7kXaQ6)]oZNVfSZ1V)e,TbfJeBW$qWif/1iP<2/E`@8`>V - #b*_hEnY/,Q&&9m0FBmZp@$n"54=^6'Ca( - 5PB:r=/VUE'0\dD;2KqgWgQUXUL/)A9!YO4j\tt\V?EE&tO_&dj7K*jlbegRou$NW![b(k] - Alb@oeSa^drQ"%W7%la_A0:#7hk8Po_L_N+a[*iPUGu`uNThQD,"_M[p1)$.7D,2Jq.^N1] - ^/)Gpo3prO`0hQ?"Jd"niVaF$`1q==.:S0i7"((t[QD," - _O^ku]ko@FO^/2_m?rh+W(_[Prq+heK8P;p;:jFVPU4ZVrlJmTr;Y<]tMaa5OUkDC - 2mYBQ_Fs03"UM@Z[!6%M,)=YgC,NfGa)H2;A.KiUE7SjMp[-QW6*0'r$R@/olg,(-5'&DeC - $<@?[QR1r:ofB198t2`m^h]USXnPRKYbM3"q-2?^1K\Y4:@/1&:9.JjJeY.^3WmIuJ'm.`: - f:`uSVi'a@-q*B3fiq<5.9*)9.(M%8RZ%Jh_u@lI/?Re(FLYR\KdlY.#BIDqOgA>%Q?_$&K - f0`]Au,8s]ICtLH6=iqN/;H0CUHr=K7S#7d]MI&Chie-YBBh\]p;7X6JV5:")/mNor"+:C]*dSA35<)"AK&)ljU_qA1E4O3Ykh - .4Qf.H1L%pqtHe=TopR?61XmOqsU615`nFkJV&Z_LZ/OF5YJCYF#5C$)I&*QW)4f=ZNp>BS - o:Bd`Lb/S$h\(hj0hX@RQi'FAEVk\%0D^QIJrQs0S=t/&ebqpA:j5=NZ:&peuVlPo6\.UlkjOC$06)cZD:&$hhFo_%m2AllTfmFJC - Dp[6iV]\/5]1R9\$^2Dc<%3%2>()B7*gU:tRp?gUYmFnsln(s]8lt8hK*'&3/fVqfIb0.s] - ?bUpdqXlpomQf&abn5gQ8fa?F3)uY4g;g0B%ueMOgqX.b#AQa.0S`^;d3]!OH#%9p_2i'WN - /sKs&b^+sTN63BqC!HUWc"(%%PoXeXBN#H9q!p'gq!$gn%Ll4r:mgDkN:mfJb3!E=HT5Js2 - cX\5l3&[-s3ff%27d!9q/S-fhu'[$o.8#:I![KHh[OYALX91s^He-:nqQ94:)-)53*"HJeTRrJ@T5=?==kQ(%?91r,fO,l1<:+V7VRMhY - P1jjD3i(f75C?g3Lr9`Z$!s/PrH@jfCF:rC>l\m5MSi_/a - d\TUp<$>n*_1U#7rC(\*m$as4<'cJeWN(8=pScgd*A##3&WqI7(o"YM8".bdL1MJ;<>'s21E-Z$mT'VgZ@j9 - i(YA^JW-HZ877UA,P"5kl.U7uDPVubQs/M1i'd%QXN:]BRQO3A6-Z$qIM-^GfP*s9t7010] - V]FpniJk+Y2I65&k__S!_(r\En,\*TgK1"dt.dNApD_$"dUo("i3a(U<$R!YHmR+S?7UQ-?V%N$nXK+C-GLUhNk;Amkbf'IY/):KVDR - ^ZC'!N&.hLLS*`A`#DEWU(u29c[T]3)YE/XN?#Xb%@U - `faL(1t-An5G2*BSH6A#7U6:6Er\9IDurVQ - jf#+tB]eL - TofXJZ(kRQoA'dn"1Cp0J7BL^X*"\61<=qf1"?\V#t\(E2^T]2J^kP*9Q1qK-sEa3.LpT=* - 0i#c&V7:]^E40?q1BD(_EYW`5tGTL"2?*BNi]h]Ej - #XBDmrkqK5RFrT>U@aX_W'1Bl_pK7ZC=+EjQW=JuW&2\Xma:ZcAl\8t^A^CuaSN6p7Z+R`> - =!H-J]6"-lOkoOtJPl".<-sL"H!nkAc:3MpEO*b=7=A?U357ehF(Y'MOV&7QL@fj@Y^SIE0 - K[!ji908>)]K.pZZYTbi%X&8mlb<,QjPLE.+B7MSRf&?qOQ"("Pkfs*NT6VInY8aJ?07g)M - DuVaRIWS9389$!I$"A&I^/=1V7bHg*5u_q7qf(qV+i*r*Pd$N&!J4daHQ?J_aYuFA#J\HED - >7:G3`i*ZmD;J(VOp5qQkfj!3scdK+EV8P)KJRl9Zf[HjJOK>:p@RlAZu%[4Y;Y-u4^P+>b - #:>G:@h$K)0BEb(-$0hUGaoltObSebMR*tThcX4>0Oi\.Q,%Rb/[r4'H.OYl;.b$?n5Bc8q - g7mM&q7rrWj)AH^=qDP2io9a5X0-O5;UgJUL9ed<78osF)A3O7\RWO-)L>bmT3WIL6:(`5b - kCGYK>W*:rV'sMS@N1P&eB)OkbJ3&&2]6_uc<]q'?%4Psb\R'57%4!nlf`2$_5]pf6bXR7 - /BCtI9B_-tot?+X+;<]tg'*'ScFe>ZAfF*$aB8=7XBVJRua(iu'"c&NU2d-UOVa1"0;GJ*Q - #IE_OKjnPC;-8\_T.VK=#F4N< - EOK53$GQ7R:@-[@5J;.mW817Q[2SE/>&/A-GkL@P_-qNOdKLWQKF&=ScCHKcdXc8)SWXq8Y - 37RYc0dt'R-8dqanIl,\c[HdjjaT1&-N8e:s^>P;FjoA%&'')ks8<*GKQ-u>dk<0B^@d[%: - Aff)&Q(#786QR8#:QTQ0!SenJ9$AV/aJBdCI037s>F,dQ!ns_:P83*$$WqXc3 - i6RZbiI=aNqPUIAJ@r9Uo@[%C^$C@JR39#i6)O;#`rUeOS-bA-e1!@U*9^*SOVe'8r,laf> - HOilNa\W+?38t@H]/D?b^2.'H3^)'#eS44s!`"NZ0t?W5pbmEF?Gk:4He?m.uQ9ZNl4NS4lZ)=0>7HfJX$mC - Nph\"WmY=.6?WpN[&JPgm:%9n\srXBT,"M.%>_r'nud]H)+m0(&8F`dE+4,eF+Z*a.t)]Nu - +HkK0hM]PbF$Kn^FDMZH#W)@"[q*HeM]Xab(%b#m-,4jDV0f8*Ub]XgBSKR9[rD3d@"f - oo"#K-O/WWrOD0gFL66 - \Rn\ZfVNK!UVR(1.b*TN?+n2Wf\+DU8mY@,2`ho)RADuTdc8lu$W'o<-#_F-3_]?>_A# - %)aW#Dh3D:`c;f(=WOQ_eoOS"Y2`#:I*L/od$7Z9+'(thie`l&/%#o*hZ%->`C,:Gn*,=m[ - 5C:t53i>O%XG%Na.PHVCJp8%ir3_\KM'o+bBa^g/pBjlsr$,W^3D;;:3q - +,E.?j+7U-!YbR3b*;C/@fe`bmPh`Q2E%JMMlKKF-srg$+&S"40op()U6QF\l2gfk)'aV^_,uj6L@')6D6a=69R\u6d:5d"?h?a5Y%I - oVFnXI%QiOab0bU>jY4r-l+g>\KK6fb<28,LUH;K+B;HHuXUTI&T07`-eHf.^FUQ.sjUK`M - &cb?S4b@jE,[!3=''&*94G-T!i%WE%l+hQaV?N;be8UfKd@K*hB2"-h`@0MSKL1:UJs'V^D - *ZK8)+/8Ib;c-uO9Wc/,QmT<*J()T\Ftb%o,OVG%b'K3#L;QfD>m(n8^XMc3Q:i,k:6F*+c - M8?^R?Y-oOgtX#]CJG]g35sAMU.j<=MA,Pn-1]?%>C01/*k49*,Sp61);FmclKc2*:PRQo8 - Z%c6b\/jM`P&o]Mi@AT)DkYn7"fIMr_3C6_5OY].P-pSoJ(XNX?#h0!G@cBFM)^4GRY@2,)0tVl9>nX4'6Fk#;i>m6tXr-H.BVWdJl@8qu%8oE_/kJM9ZIJj;pN-mhVB"FF - kG_'tCmXd'kQM,"7a0r!;KDN68.$@67]&``rW!2VA@JquZaTIE^g>nI4Y\Y$c=qkXC8Qu3< - M0a^[@DiRYRbcJ*#3Df"bYC\Al,G5iL%4I%3P'+,:Q1=NOLde4P%]u9BVN\c:?k\;ec-Anr - +%]s;'fAKnM+<[+$!"-SP)=JN5h<]0g,jq&l\u(! - ?H`[=?Cj^_MblGLIhu>^dEqq=`Y;$Wh;kJ+$gBg,XFD_+OC]6V?"?Na\45U1l(&q - 35]6sbpNW4X0SIKW(FOp(S7.5>6L"5i?ZkV27`0G9pL6XG_koZ6q['L.a+'+ko-)rm$*pt7 - Y4Vi\eAfEYk?U?3lg=/"t`M\IGYN%5Pg_s^#ZMK@1].F+eP7op8f'o!e/aC+?p,dS.&0;;,ag," - r[&#p:.GeX5[Y->$.@iEQ*9B?P2oUli9sS=%hZlk&dVs6V+3h78 -Q -Q q -0.952941 0.827451 0.505882 rg -47.566 395.422 m 338.133 395.422 l 353.836 395.422 366.477 382.781 366.477 - 367.078 c 366.477 345.988 l 366.477 330.281 353.836 317.641 338.133 317.641 - c 47.566 317.641 l 31.863 317.641 19.219 330.281 19.219 345.988 c 19.219 - 367.078 l 19.219 382.781 31.863 395.422 47.566 395.422 c h -f -0 g -2.216693 w -1 J -0 j -[] 0.0 d -4 M q 1 0 0 -1 0 645.5 cm -47.566 250.078 m 338.133 250.078 l 353.836 250.078 366.477 262.719 366.477 - 278.422 c 366.477 299.512 l 366.477 315.219 353.836 327.859 338.133 327.859 - c 47.566 327.859 l 31.863 327.859 19.219 315.219 19.219 299.512 c 19.219 - 278.422 l 19.219 262.719 31.863 250.078 47.566 250.078 c h -S Q -BT -28.8 0 0 28.8 40.333826 371.021021 Tm -/f-0-0 1 Tf -[(LocalReg)3(ions)]TJ -ET -0.427451 0.607843 0.760784 rg -421.508 227.535 m 421.508 157.184 l 505.02 157.184 l h -f -0 g -2.316277 w -0 J -[ 4.632554 4.632554] 0 d -q 1 0 0 -0.84244 0 645.5 cm -421.508 496.136 m 421.508 579.645 l 505.02 579.645 l h -S Q -0.871606 w -[] 0.0 d -q 1 0 0 -0.84244 0 645.5 cm -404.805 587.996 m 521.719 587.996 l S Q -512.402 153.406 m 522.879 150.16 l 512.402 146.914 l 514.074 148.832 514.066 - 151.453 512.402 153.406 c h -f* -0.843125 w -q 1 0 0 -0.84244 0 645.5 cm -413.156 596.347 m 413.156 479.434 l S Q -409.414 234.012 m 413.141 242.551 l 416.867 234.012 l 414.668 235.379 411.656 - 235.371 409.414 234.012 c h -f* -BT -16.498199 0 0 13.898747 413.635566 134.090573 Tm -/f-1-0 1 Tf -(-1)Tj --1.298091 1.296916 Td -(-1)Tj -0.296439 5.061866 Td -(1)Tj -5.996626 -6.288526 Td -(1)Tj -ET -528.43 143.871 m 528.191 143.73 l 527.957 143.594 l 527.746 143.453 l 527.555 - 143.316 l 527.367 143.176 l 527.18 143.039 l 527.016 142.898 l 526.848 -142.738 l 526.707 142.602 l 526.566 142.461 l 526.449 142.324 l 526.332 -142.164 l 526.211 142.023 l 526.117 141.887 l 526 141.746 l 525.93 141.609 - l 525.836 141.469 l 525.766 141.328 l 525.695 141.211 l 525.648 141.07 -l 525.602 140.953 l 525.551 140.832 l 525.504 140.715 l 525.457 140.594 -l 525.41 140.398 l 525.387 140.297 l 525.363 140.199 l 525.363 140.098 l - 525.34 140.02 l 525.34 139.879 l 525.34 138.926 525.977 138.371 526.023 - 138.312 c 526.777 137.656 526.988 137.578 528.758 137.02 c 531.586 136.109 - l 531.941 135.969 532.41 135.828 532.41 135.254 c 532.41 134.797 531.988 - 134.203 531.258 134.203 c 530.219 134.203 529.441 134.68 529.207 134.836 - c 529.062 134.918 529.039 134.938 528.945 134.938 c 528.758 134.938 528.711 - 134.797 528.711 134.719 c 528.711 134.48 529.938 133.766 531.258 133.766 - c 532.719 133.766 533.707 134.918 533.707 135.891 c 533.707 136.824 532.836 - 137.18 532.574 137.277 c 532.246 137.379 531.445 137.637 531.137 137.734 - c 530.668 137.895 530.195 138.055 529.699 138.191 c 528.309 138.668 l 527.25 - 139.027 526.543 139.602 526.543 140.438 c 526.543 141.25 527.461 142.957 - 529.441 143.793 c 530.289 143.535 530.996 143.535 531.492 143.535 c 532.199 - 143.535 533.684 143.535 533.684 144.148 c 533.684 144.645 532.672 144.684 - 531.75 144.684 c 531.727 144.25 l 532.551 144.25 532.648 144.23 533.07 -144.129 c 532.883 144.051 532.648 143.969 531.562 143.969 c 531.02 143.969 - 530.809 143.969 530.383 144.129 c 530.926 144.25 531.445 144.25 531.727 - 144.25 c 531.75 144.684 l 531.328 144.684 530.645 144.684 529.77 144.445 - c 529.184 144.965 529.086 145.617 529.086 145.996 c 529.086 147.086 529.914 - 148.617 531.68 149.352 c 532.105 148.914 532.648 148.914 533.188 148.914 - c 533.777 148.914 535.285 148.914 535.285 149.531 c 535.285 150.047 534.25 - 150.066 533.332 150.066 c 533.355 149.629 l 534.156 149.629 534.25 149.609 - 534.672 149.512 c 534.484 149.449 534.25 149.352 533.211 149.352 c 532.766 - 149.352 532.48 149.352 532.223 149.531 c 532.598 149.629 533.094 149.629 - 533.355 149.629 c 533.332 150.066 l 533.023 150.066 532.457 150.066 531.844 - 149.965 c 531.773 150.145 531.727 150.285 531.727 150.621 c 531.727 150.898 - 531.844 151.316 531.844 151.355 c 531.844 151.516 531.727 151.613 531.562 - 151.613 c 531.137 151.613 531.137 150.703 531.137 150.641 c 531.137 150.246 - 531.281 149.945 531.305 149.867 c 528.805 149.273 527.203 147.684 527.203 - 146.176 c 527.203 145.441 527.625 144.605 528.734 144.07 c h -f -540.59 143.672 m 540.59 143.793 l 540.566 143.793 l 540.566 143.91 l 540.543 - 143.93 l 540.543 143.969 l 540.52 143.969 l 540.52 143.992 l 540.496 143.992 - l 540.496 144.012 l 540.473 144.012 l 540.473 144.031 l 540.402 144.031 - l 540.379 144.051 l 540.094 144.051 l 539.035 143.176 537.551 143.156 536.867 - 143.156 c 536.867 142.66 l 537.266 142.66 538.352 142.66 539.246 143.059 - c 539.246 135.988 l 539.246 135.531 539.246 135.352 537.598 135.352 c 536.984 - 135.352 l 536.984 134.855 l 537.266 134.875 539.293 134.918 539.906 134.918 - c 540.426 134.918 542.477 134.875 542.852 134.855 c 542.852 135.352 l 542.215 - 135.352 l 540.59 135.352 540.59 135.531 540.59 135.988 c h -f -394.82 254 m 394.586 253.859 l 394.348 253.723 l 394.137 253.582 l 393.949 - 253.445 l 393.762 253.305 l 393.57 253.164 l 393.406 253.027 l 393.242 -252.867 l 393.102 252.73 l 392.957 252.59 l 392.84 252.449 l 392.723 252.293 - l 392.605 252.152 l 392.512 252.016 l 392.395 251.875 l 392.324 251.734 - l 392.227 251.598 l 392.156 251.457 l 392.086 251.34 l 392.039 251.199 -l 391.992 251.082 l 391.945 250.961 l 391.898 250.844 l 391.852 250.723 -l 391.828 250.625 l 391.805 250.523 l 391.758 250.328 l 391.758 250.227 -l 391.734 250.148 l 391.734 250.008 l 391.734 249.055 392.371 248.5 392.418 - 248.441 c 393.172 247.785 393.383 247.707 395.152 247.148 c 397.98 246.234 - l 398.332 246.098 398.805 245.957 398.805 245.383 c 398.805 244.926 398.379 - 244.328 397.648 244.328 c 396.613 244.328 395.836 244.805 395.598 244.965 - c 395.457 245.043 395.434 245.066 395.34 245.066 c 395.152 245.066 395.102 - 244.926 395.102 244.848 c 395.102 244.609 396.328 243.895 397.648 243.895 - c 399.109 243.895 400.102 245.043 400.102 246.02 c 400.102 246.949 399.227 - 247.309 398.969 247.406 c 398.641 247.508 397.836 247.766 397.531 247.863 - c 397.059 248.023 396.59 248.184 396.094 248.32 c 394.703 248.797 l 393.641 - 249.156 392.934 249.73 392.934 250.566 c 392.934 251.379 393.855 253.086 - 395.836 253.922 c 396.684 253.66 397.391 253.66 397.883 253.66 c 398.59 - 253.66 400.078 253.66 400.078 254.277 c 400.078 254.773 399.062 254.812 - 398.145 254.812 c 398.121 254.375 l 398.945 254.375 399.039 254.355 399.465 - 254.258 c 399.273 254.18 399.039 254.098 397.957 254.098 c 397.414 254.098 - 397.199 254.098 396.777 254.258 c 397.32 254.375 397.836 254.375 398.121 - 254.375 c 398.145 254.812 l 397.719 254.812 397.035 254.812 396.164 254.574 - c 395.574 255.09 395.48 255.746 395.48 256.125 c 395.48 257.215 396.305 - 258.746 398.074 259.48 c 398.496 259.043 399.039 259.043 399.582 259.043 - c 400.172 259.043 401.68 259.043 401.68 259.66 c 401.68 260.176 400.641 - 260.195 399.723 260.195 c 399.746 259.758 l 400.547 259.758 400.641 259.738 - 401.066 259.637 c 400.879 259.578 400.641 259.48 399.605 259.48 c 399.156 - 259.48 398.875 259.48 398.613 259.66 c 398.992 259.758 399.488 259.758 -399.746 259.758 c 399.723 260.195 l 399.418 260.195 398.852 260.195 398.238 - 260.094 c 398.168 260.273 398.121 260.414 398.121 260.75 c 398.121 261.027 - 398.238 261.445 398.238 261.484 c 398.238 261.645 398.121 261.742 397.957 - 261.742 c 397.531 261.742 397.531 260.828 397.531 260.77 c 397.531 260.375 - 397.672 260.074 397.695 259.996 c 395.199 259.398 393.594 257.812 393.594 - 256.305 c 393.594 255.566 394.02 254.734 395.129 254.199 c h -f -409.762 247.508 m 409.199 247.508 l 409.152 247.211 408.984 246.375 408.773 - 246.258 c 408.656 246.156 407.383 246.156 407.148 246.156 c 404.129 246.156 - l 405.852 247.449 406.441 247.844 407.43 248.48 c 408.633 249.312 409.762 - 250.168 409.762 251.477 c 409.762 253.145 408.02 254.18 405.922 254.18 -c 403.895 254.18 402.504 252.969 402.504 251.695 c 402.504 251 403.211 250.922 - 403.375 250.922 c 403.777 250.922 404.25 251.16 404.25 251.656 c 404.25 - 251.914 404.129 252.391 403.281 252.391 c 403.777 253.383 404.906 253.684 - 405.664 253.684 c 407.312 253.684 408.16 252.609 408.16 251.477 c 408.16 - 250.266 407.148 249.312 406.629 248.816 c 402.668 245.52 l 402.504 245.402 - 402.504 245.383 402.504 244.984 c 409.27 244.984 l h -f -2.4 w -q 1 0 0 -1 0 645.5 cm -498.109 337.012 m 522.797 388.02 524.172 394.441 495.438 448.398 c S Q -499.699 280.754 m 496.68 311.34 l 518.793 289.996 l 511.148 291.418 503.449 - 287.66 499.699 280.754 c h -f* -516.898 214.742 m 493.977 194.266 l 498.172 224.711 l 501.535 217.703 509.109 - 213.699 516.898 214.742 c h -f* -0.976471 0.760784 0.760784 rg -47.566 310.508 m 338.133 310.508 l 353.836 310.508 366.477 297.867 366.477 - 282.16 c 366.477 261.07 l 366.477 245.367 353.836 232.727 338.133 232.727 - c 47.566 232.727 l 31.863 232.727 19.219 245.367 19.219 261.07 c 19.219 - 282.16 l 19.219 297.867 31.863 310.508 47.566 310.508 c h -f -0 g -2.216693 w -1 J -q 1 0 0 -1 0 645.5 cm -47.566 334.992 m 338.133 334.992 l 353.836 334.992 366.477 347.633 366.477 - 363.34 c 366.477 384.43 l 366.477 400.133 353.836 412.773 338.133 412.773 - c 47.566 412.773 l 31.863 412.773 19.219 400.133 19.219 384.43 c 19.219 - 363.34 l 19.219 347.633 31.863 334.992 47.566 334.992 c h -S Q -BT -28.8 0 0 28.8 39.498627 286.537744 Tm -/f-0-0 1 Tf -[(SpatialD)3(omains)]TJ -ET -0.760784 0.905882 0.976471 rg -47.566 225.594 m 338.133 225.594 l 353.836 225.594 366.477 212.949 366.477 - 197.246 c 366.477 176.156 l 366.477 160.453 353.836 147.809 338.133 147.809 - c 47.566 147.809 l 31.863 147.809 19.219 160.453 19.219 176.156 c 19.219 - 197.246 l 19.219 212.949 31.863 225.594 47.566 225.594 c h -f -0 g -2.216693 w -q 1 0 0 -1 0 645.5 cm -47.566 419.906 m 338.133 419.906 l 353.836 419.906 366.477 432.551 366.477 - 448.254 c 366.477 469.344 l 366.477 485.047 353.836 497.691 338.133 497.691 - c 47.566 497.691 l 31.863 497.691 19.219 485.047 19.219 469.344 c 19.219 - 448.254 l 19.219 432.551 31.863 419.906 47.566 419.906 c h -S Q -BT -28.8 0 0 28.8 36.800128 201.767236 Tm -/f-0-0 1 Tf -[(StdRegio)3(ns)]TJ -ET -46.188 169.297 m 46.449 168.324 47.312 167.688 48.324 167.688 c 49.148 -167.688 49.711 168.25 50.086 169 c 50.5 169.859 50.801 171.324 50.801 171.359 - c 50.801 171.625 50.613 171.625 50.535 171.625 c 50.273 171.625 50.273 -171.512 50.199 171.172 c 49.863 169.824 49.41 168.211 48.398 168.211 c 47.91 - 168.211 47.648 168.512 47.648 169.297 c 47.648 169.824 47.949 170.949 48.137 - 171.812 c 48.812 174.398 l 48.887 174.734 49.113 175.637 49.223 176.012 - c 49.336 176.574 49.562 177.473 49.562 177.625 c 49.562 178.035 49.223 -178.262 48.887 178.262 c 48.773 178.262 48.137 178.223 47.949 177.438 c -47.5 175.672 46.449 171.473 46.148 170.234 c 46.113 170.125 45.176 168.211 - 43.41 168.211 c 42.176 168.211 41.949 169.297 41.949 170.16 c 41.949 171.512 - 42.625 173.387 43.223 175.035 c 43.523 175.785 43.637 176.125 43.637 176.574 - c 43.637 177.625 42.887 178.523 41.688 178.523 c 39.398 178.523 38.535 -175.035 38.535 174.848 c 38.535 174.586 38.762 174.586 38.801 174.586 c -39.062 174.586 39.062 174.66 39.176 175.035 c 39.773 177.098 40.711 178 -41.613 178 c 41.836 178 42.211 177.961 42.211 177.211 c 42.211 176.648 41.949 - 175.938 41.801 175.598 c 40.898 173.199 40.41 171.734 40.41 170.574 c 40.41 - 168.285 42.062 167.688 43.336 167.688 c 44.91 167.688 45.773 168.773 46.188 - 169.297 c h -f -56.461 183.898 m 53.949 183.262 52.523 181.125 52.523 179.363 c 52.523 -177.562 53.875 176.438 55.523 176.438 c 57.551 176.438 59.125 178.801 59.125 - 181.238 c 59.125 182.852 58.262 183.824 57.738 184.387 c 57.137 185.102 - 55.863 186.449 55.863 187.238 c 55.863 187.461 56.125 187.914 56.801 187.914 - c 57.363 187.914 57.848 187.648 58.188 187.461 c 58.336 187.387 58.938 -187.012 59.199 187.012 c 59.613 187.012 59.91 187.387 59.91 187.727 c 59.91 - 188.137 59.688 188.176 58.785 188.363 c 58.598 188.398 57.812 188.551 57.285 - 188.551 c 56.012 188.551 55.336 187.836 55.336 186.824 c 55.336 185.926 - 55.863 184.914 56.461 183.898 c h -56.723 183.449 m 57.211 182.699 57.812 181.727 57.812 180.523 c 57.812 -179.137 56.988 176.887 55.562 176.887 c 54.66 176.887 53.762 177.488 53.762 - 178.875 c 53.762 180 54.398 182.887 56.723 183.449 c h -f -69.918 162.211 m 69.918 162.285 69.918 162.324 69.504 162.734 c 66.543 -165.734 65.754 170.273 65.754 173.949 c 65.754 178.109 66.652 182.273 69.617 - 185.234 c 69.918 185.535 69.918 185.574 69.918 185.648 c 69.918 185.836 - 69.84 185.91 69.691 185.91 c 69.43 185.91 67.293 184.262 65.867 181.223 - c 64.668 178.598 64.367 175.938 64.367 173.949 c 64.367 172.074 64.629 -169.188 65.941 166.449 c 67.402 163.523 69.43 161.949 69.691 161.949 c 69.84 - 161.949 69.918 162.023 69.918 162.211 c h -f -74.98 175.262 m 72.391 173.535 71.867 171.285 71.867 170.422 c 71.867 169.297 - 72.504 168.625 72.543 168.547 c 73.328 167.762 73.516 167.648 75.316 166.973 - c 78.203 165.848 l 78.578 165.699 79.066 165.547 79.066 164.836 c 79.066 - 164.273 78.617 163.562 77.867 163.562 c 76.816 163.562 76.027 164.16 75.766 - 164.348 c 75.617 164.422 75.617 164.461 75.504 164.461 c 75.316 164.461 - 75.277 164.273 75.277 164.199 c 75.277 163.898 76.555 163.035 77.867 163.035 - c 79.367 163.035 80.379 164.422 80.379 165.586 c 80.379 166.75 79.48 167.199 - 79.215 167.312 c 78.879 167.422 78.09 167.723 77.754 167.836 c 77.305 168.062 - 76.816 168.25 76.293 168.398 c 74.867 168.961 l 73.777 169.41 73.066 170.086 - 73.066 171.098 c 73.066 172.074 74.004 174.172 76.027 175.188 c 76.891 -174.848 77.605 174.848 78.129 174.848 c 78.84 174.848 80.34 174.848 80.34 - 175.598 c 80.34 176.199 79.328 176.234 78.391 176.234 c 77.941 176.234 -77.266 176.234 76.367 175.973 c 75.766 176.574 75.652 177.359 75.652 177.812 - c 75.652 179.16 76.516 181 78.316 181.898 c 78.73 181.375 79.293 181.375 - 79.855 181.375 c 80.453 181.375 81.992 181.375 81.992 182.125 c 81.992 -182.723 80.902 182.762 80.004 182.762 c 79.668 182.762 79.105 182.762 78.465 - 182.648 c 78.391 182.836 78.355 183.023 78.355 183.438 c 78.355 183.773 - 78.465 184.262 78.465 184.297 c 78.465 184.484 78.355 184.637 78.203 184.637 - c 77.754 184.637 77.754 183.512 77.754 183.438 c 77.754 182.984 77.902 -182.609 77.941 182.535 c 75.355 181.785 73.742 179.875 73.742 178.035 c -73.742 177.172 74.191 176.16 75.316 175.523 c h -78.879 182.125 m 79.254 182.234 79.742 182.234 80.004 182.234 c 80.828 -182.234 80.902 182.199 81.355 182.086 c 81.168 182.012 80.902 181.898 79.855 - 181.898 c 79.402 181.898 79.141 181.898 78.879 182.125 c h -77.004 175.598 m 77.566 175.711 78.09 175.711 78.355 175.711 c 79.215 175.711 - 79.293 175.711 79.742 175.598 c 79.516 175.484 79.293 175.375 78.203 175.375 - c 77.641 175.375 77.418 175.375 77.004 175.598 c h -f -89.766 173.949 m 89.766 175.785 89.504 178.672 88.191 181.41 c 86.766 184.336 - 84.703 185.91 84.477 185.91 c 84.328 185.91 84.215 185.797 84.215 185.648 - c 84.215 185.574 84.215 185.535 84.664 185.086 c 87.027 182.723 88.379 -178.938 88.379 173.949 c 88.379 169.824 87.516 165.625 84.551 162.625 c -84.215 162.324 84.215 162.285 84.215 162.211 c 84.215 162.062 84.328 161.949 - 84.477 161.949 c 84.703 161.949 86.879 163.598 88.266 166.637 c 89.504 -169.262 89.766 171.922 89.766 173.949 c h -f -115.234 175.785 m 115.609 175.785 116.062 175.785 116.062 176.234 c 116.062 - 176.723 115.609 176.723 115.273 176.723 c 100.949 176.723 l 100.609 176.723 - 100.16 176.723 100.16 176.234 c 100.16 175.785 100.609 175.785 100.949 -175.785 c h -115.273 171.137 m 115.609 171.137 116.062 171.137 116.062 171.625 c 116.062 - 172.074 115.609 172.074 115.234 172.074 c 100.949 172.074 l 100.609 172.074 - 100.16 172.074 100.16 171.625 c 100.16 171.137 100.609 171.137 100.949 -171.137 c h -f -134.133 173.094 m 125.617 162.594 l 125.43 162.367 125.395 162.332 125.395 - 162.219 c 125.395 161.957 125.617 161.957 126.07 161.957 c 145.867 161.957 - l 147.93 167.918 l 147.332 167.918 l 146.73 166.117 145.156 164.656 143.094 - 163.98 c 142.719 163.832 141.07 163.27 137.543 163.27 c 127.383 163.27 -l 135.707 173.543 l 135.855 173.77 135.895 173.805 135.895 173.918 c 135.895 - 174.031 135.895 174.031 135.742 174.258 c 127.98 184.906 l 137.43 184.906 - l 140.168 184.906 145.68 184.758 147.332 180.293 c 147.93 180.293 l 145.867 - 185.883 l 126.07 185.883 l 125.395 185.883 125.395 185.844 125.395 185.133 - c h -f -154.984 185.145 m 158.02 185.145 l 160.832 185.145 163.234 186.945 163.234 - 188.781 c 163.234 190.207 161.844 191.406 159.559 191.406 c 153.707 191.406 - l 153.371 191.406 153.184 191.406 153.184 191.031 c 153.184 190.809 153.371 - 190.809 153.746 190.809 c 154.008 190.809 154.082 190.809 154.383 190.77 - c 154.719 190.734 154.719 190.695 154.719 190.508 c 154.719 190.508 154.719 - 190.395 154.684 190.172 c 152.469 181.359 l 152.281 180.684 152.281 180.57 - 150.969 180.57 c 150.672 180.57 150.484 180.57 150.484 180.195 c 150.484 - 180.195 150.484 179.969 150.746 179.969 c 151.234 179.969 152.434 180.047 - 152.922 180.047 c 153.184 180.047 153.781 180.047 154.082 180.008 c 154.383 - 180.008 154.832 179.969 155.133 179.969 c 155.246 179.969 155.469 179.969 - 155.469 180.344 c 155.469 180.57 155.281 180.57 154.945 180.57 c 154.945 - 180.57 154.609 180.57 154.309 180.609 c 153.934 180.645 153.934 180.684 - 153.934 180.871 c 153.934 180.871 153.934 180.984 154.008 181.207 c h -156.184 190.207 m 156.332 190.734 156.332 190.809 157.047 190.809 c 158.996 - 190.809 l 160.57 190.809 161.508 190.32 161.508 189.121 c 161.508 188.633 - 161.32 187.281 160.496 186.531 c 159.895 186.008 158.922 185.707 157.719 - 185.707 c 155.059 185.707 l h -f -150.52 158.75 m 150.406 158.262 150.371 158.148 149.734 158.148 c 149.508 - 158.148 149.281 158.148 149.281 157.773 c 149.281 157.586 149.434 157.512 - 149.508 157.512 c 149.922 157.512 150.484 157.586 150.934 157.586 c 151.496 - 157.586 152.133 157.512 152.695 157.512 c 152.844 157.512 153.031 157.586 - 153.031 157.887 c 153.031 158.148 152.809 158.148 152.582 158.148 c 152.207 - 158.148 151.758 158.148 151.758 158.336 c 151.758 158.414 151.906 158.863 - 151.945 159.086 c 152.172 159.988 152.395 160.887 152.582 161.602 c 152.77 - 161.262 153.297 160.625 154.309 160.625 c 156.332 160.625 158.582 162.875 - 158.582 165.352 c 158.582 167.301 157.234 168.164 156.109 168.164 c 155.059 - 168.164 154.156 167.449 153.707 166.961 c 153.445 167.938 152.508 168.164 - 151.984 168.164 c 151.344 168.164 150.934 167.711 150.672 167.262 c 150.332 - 166.699 150.07 165.688 150.07 165.574 c 150.07 165.387 150.297 165.387 -150.371 165.387 c 150.594 165.387 150.594 165.426 150.707 165.875 c 150.969 - 166.852 151.309 167.676 151.945 167.676 c 152.395 167.676 152.508 167.301 - 152.508 166.852 c 152.508 166.664 152.469 166.477 152.434 166.363 c h -153.707 166.137 m 154.684 167.449 155.508 167.676 156.031 167.676 c 156.707 - 167.676 157.27 167.188 157.27 166.062 c 157.27 165.387 156.895 163.664 -156.406 162.688 c 155.957 161.863 155.172 161.074 154.309 161.074 c 153.109 - 161.074 152.809 162.352 152.809 162.539 c 152.809 162.613 152.844 162.727 - 152.844 162.801 c h -f -179.672 183.961 m 179.672 184.035 179.746 184.297 179.746 184.297 c 179.746 - 184.336 179.746 184.562 179.445 184.562 c 179.223 184.562 179.184 184.484 - 179.07 184.074 c 177.684 178.562 l 173.898 178.41 170.371 175.262 170.371 - 172 c 170.371 169.711 172.059 167.836 174.984 167.648 c 174.797 166.938 - 174.609 166.148 174.422 165.398 c 174.121 164.273 173.898 163.375 173.898 - 163.297 c 173.898 163.074 174.086 163.035 174.195 163.035 c 174.309 163.035 - 174.348 163.074 174.422 163.148 c 174.461 163.188 174.609 163.75 174.684 - 164.086 c 175.586 167.648 l 179.445 167.797 182.934 171.023 182.934 174.211 - c 182.934 176.125 181.66 178.297 178.32 178.562 c h -175.098 168.172 m 173.672 168.25 171.945 169.109 171.945 171.473 c 171.945 - 174.359 174.008 177.699 177.57 178.035 c h -178.172 178.035 m 180.008 177.922 181.359 176.836 181.359 174.734 c 181.359 - 171.887 179.297 168.473 175.734 168.172 c h -f -184.695 162.34 m 184.582 161.852 184.543 161.738 183.906 161.738 c 183.68 - 161.738 183.457 161.738 183.457 161.363 c 183.457 161.176 183.605 161.102 - 183.68 161.102 c 184.094 161.102 184.656 161.176 185.105 161.176 c 185.668 - 161.176 186.305 161.102 186.867 161.102 c 187.02 161.102 187.207 161.176 - 187.207 161.477 c 187.207 161.738 186.98 161.738 186.758 161.738 c 186.383 - 161.738 185.93 161.738 185.93 161.926 c 185.93 162 186.082 162.449 186.117 - 162.676 c 186.344 163.574 186.57 164.477 186.758 165.188 c 186.945 164.852 - 187.469 164.215 188.48 164.215 c 190.508 164.215 192.758 166.465 192.758 - 168.938 c 192.758 170.887 191.406 171.75 190.281 171.75 c 189.23 171.75 - 188.332 171.039 187.883 170.551 c 187.617 171.527 186.68 171.75 186.156 - 171.75 c 185.52 171.75 185.105 171.301 184.844 170.852 c 184.508 170.289 - 184.242 169.277 184.242 169.164 c 184.242 168.977 184.469 168.977 184.543 - 168.977 c 184.77 168.977 184.77 169.012 184.883 169.465 c 185.145 170.438 - 185.48 171.262 186.117 171.262 c 186.57 171.262 186.68 170.887 186.68 170.438 - c 186.68 170.25 186.645 170.062 186.605 169.949 c h -187.883 169.727 m 188.855 171.039 189.68 171.262 190.207 171.262 c 190.883 - 171.262 191.445 170.777 191.445 169.652 c 191.445 168.977 191.07 167.25 - 190.582 166.277 c 190.133 165.449 189.344 164.664 188.48 164.664 c 187.281 - 164.664 186.98 165.938 186.98 166.125 c 186.98 166.199 187.02 166.312 187.02 - 166.387 c h -f -202.422 162.211 m 202.422 162.285 202.422 162.324 202.008 162.734 c 199.047 - 165.734 198.258 170.273 198.258 173.949 c 198.258 178.109 199.156 182.273 - 202.121 185.234 c 202.422 185.535 202.422 185.574 202.422 185.648 c 202.422 - 185.836 202.344 185.91 202.195 185.91 c 201.934 185.91 199.797 184.262 -198.371 181.223 c 197.172 178.598 196.871 175.938 196.871 173.949 c 196.871 - 172.074 197.133 169.188 198.445 166.449 c 199.906 163.523 201.934 161.949 - 202.195 161.949 c 202.344 161.949 202.422 162.023 202.422 162.211 c h -f -207.484 175.262 m 204.895 173.535 204.371 171.285 204.371 170.422 c 204.371 - 169.297 205.008 168.625 205.047 168.547 c 205.832 167.762 206.02 167.648 - 207.82 166.973 c 210.707 165.848 l 211.082 165.699 211.57 165.547 211.57 - 164.836 c 211.57 164.273 211.121 163.562 210.371 163.562 c 209.32 163.562 - 208.531 164.16 208.27 164.348 c 208.121 164.422 208.121 164.461 208.008 - 164.461 c 207.82 164.461 207.781 164.273 207.781 164.199 c 207.781 163.898 - 209.059 163.035 210.371 163.035 c 211.871 163.035 212.883 164.422 212.883 - 165.586 c 212.883 166.75 211.984 167.199 211.719 167.312 c 211.383 167.422 - 210.594 167.723 210.258 167.836 c 209.809 168.062 209.32 168.25 208.797 - 168.398 c 207.371 168.961 l 206.281 169.41 205.57 170.086 205.57 171.098 - c 205.57 172.074 206.508 174.172 208.531 175.188 c 209.395 174.848 210.109 - 174.848 210.633 174.848 c 211.344 174.848 212.844 174.848 212.844 175.598 - c 212.844 176.199 211.832 176.234 210.895 176.234 c 210.445 176.234 209.77 - 176.234 208.871 175.973 c 208.27 176.574 208.156 177.359 208.156 177.812 - c 208.156 179.16 209.02 181 210.82 181.898 c 211.234 181.375 211.797 181.375 - 212.359 181.375 c 212.957 181.375 214.496 181.375 214.496 182.125 c 214.496 - 182.723 213.406 182.762 212.508 182.762 c 212.172 182.762 211.609 182.762 - 210.969 182.648 c 210.895 182.836 210.859 183.023 210.859 183.438 c 210.859 - 183.773 210.969 184.262 210.969 184.297 c 210.969 184.484 210.859 184.637 - 210.707 184.637 c 210.258 184.637 210.258 183.512 210.258 183.438 c 210.258 - 182.984 210.406 182.609 210.445 182.535 c 207.859 181.785 206.246 179.875 - 206.246 178.035 c 206.246 177.172 206.695 176.16 207.82 175.523 c h -211.383 182.125 m 211.758 182.234 212.246 182.234 212.508 182.234 c 213.332 - 182.234 213.406 182.199 213.859 182.086 c 213.672 182.012 213.406 181.898 - 212.359 181.898 c 211.906 181.898 211.645 181.898 211.383 182.125 c h -209.508 175.598 m 210.07 175.711 210.594 175.711 210.859 175.711 c 211.719 - 175.711 211.797 175.711 212.246 175.598 c 212.02 175.484 211.797 175.375 - 210.707 175.375 c 210.145 175.375 209.922 175.375 209.508 175.598 c h -f -222.27 173.949 m 222.27 175.785 222.008 178.672 220.695 181.41 c 219.27 - 184.336 217.207 185.91 216.98 185.91 c 216.832 185.91 216.719 185.797 216.719 - 185.648 c 216.719 185.574 216.719 185.535 217.168 185.086 c 219.531 182.723 - 220.883 178.938 220.883 173.949 c 220.883 169.824 220.02 165.625 217.055 - 162.625 c 216.719 162.324 216.719 162.285 216.719 162.211 c 216.719 162.062 - 216.832 161.949 216.98 161.949 c 217.207 161.949 219.383 163.598 220.77 - 166.637 c 222.008 169.262 222.27 171.922 222.27 173.949 c h -f -232.199 184.562 m 228.973 181.297 l 229.387 180.887 l 232.199 183.324 l - 234.934 180.887 l 235.348 181.297 l h -f -233.027 169.297 m 233.293 168.324 234.152 167.688 235.168 167.688 c 235.992 - 167.688 236.555 168.25 236.93 169 c 237.34 169.859 237.641 171.324 237.641 - 171.359 c 237.641 171.625 237.453 171.625 237.379 171.625 c 237.117 171.625 - 237.117 171.512 237.043 171.172 c 236.703 169.824 236.254 168.211 235.242 - 168.211 c 234.754 168.211 234.492 168.512 234.492 169.297 c 234.492 169.824 - 234.793 170.949 234.98 171.812 c 235.652 174.398 l 235.73 174.734 235.953 - 175.637 236.066 176.012 c 236.18 176.574 236.402 177.473 236.402 177.625 - c 236.402 178.035 236.066 178.262 235.73 178.262 c 235.617 178.262 234.98 - 178.223 234.793 177.438 c 234.34 175.672 233.293 171.473 232.992 170.234 - c 232.953 170.125 232.016 168.211 230.254 168.211 c 229.016 168.211 228.793 - 169.297 228.793 170.16 c 228.793 171.512 229.465 173.387 230.066 175.035 - c 230.367 175.785 230.48 176.125 230.48 176.574 c 230.48 177.625 229.73 - 178.523 228.527 178.523 c 226.242 178.523 225.379 175.035 225.379 174.848 - c 225.379 174.586 225.605 174.586 225.641 174.586 c 225.902 174.586 225.902 - 174.66 226.016 175.035 c 226.617 177.098 227.555 178 228.453 178 c 228.68 - 178 229.055 177.961 229.055 177.211 c 229.055 176.648 228.793 175.938 228.641 - 175.598 c 227.742 173.199 227.254 171.734 227.254 170.574 c 227.254 168.285 - 228.902 167.688 230.18 167.688 c 231.754 167.688 232.617 168.773 233.027 - 169.297 c h -f -239.59 162.34 m 239.48 161.852 239.441 161.738 238.805 161.738 c 238.578 - 161.738 238.355 161.738 238.355 161.363 c 238.355 161.176 238.504 161.102 - 238.578 161.102 c 238.992 161.102 239.555 161.176 240.004 161.176 c 240.566 - 161.176 241.203 161.102 241.766 161.102 c 241.918 161.102 242.105 161.176 - 242.105 161.477 c 242.105 161.738 241.879 161.738 241.652 161.738 c 241.277 - 161.738 240.828 161.738 240.828 161.926 c 240.828 162 240.98 162.449 241.016 - 162.676 c 241.242 163.574 241.465 164.477 241.652 165.188 c 241.84 164.852 - 242.367 164.215 243.379 164.215 c 245.402 164.215 247.652 166.465 247.652 - 168.938 c 247.652 170.887 246.305 171.75 245.18 171.75 c 244.129 171.75 - 243.23 171.039 242.777 170.551 c 242.516 171.527 241.578 171.75 241.055 - 171.75 c 240.418 171.75 240.004 171.301 239.742 170.852 c 239.402 170.289 - 239.141 169.277 239.141 169.164 c 239.141 168.977 239.367 168.977 239.441 - 168.977 c 239.668 168.977 239.668 169.012 239.777 169.465 c 240.043 170.438 - 240.379 171.262 241.016 171.262 c 241.465 171.262 241.578 170.887 241.578 - 170.438 c 241.578 170.25 241.543 170.062 241.504 169.949 c h -242.777 169.727 m 243.754 171.039 244.578 171.262 245.105 171.262 c 245.777 - 171.262 246.34 170.777 246.34 169.652 c 246.34 168.977 245.965 167.25 245.48 - 166.277 c 245.027 165.449 244.242 164.664 243.379 164.664 c 242.18 164.664 - 241.879 165.938 241.879 166.125 c 241.879 166.199 241.918 166.312 241.918 - 166.387 c h -f -0.8185 w -0 J -q 1 0 0 -0.955306 0 645.5 cm -406.195 277.631 m 406.195 373.069 l S Q -402.566 371.918 m 406.184 381.316 l 409.801 371.918 l 407.664 373.422 404.742 - 373.414 402.566 371.918 c h -f* -q 1 0 0 -0.955306 0 645.5 cm -483.859 357.162 m 393.098 357.162 l S Q -475.109 307.77 m 484.945 304.312 l 475.109 300.859 l 476.68 302.898 476.672 - 305.691 475.109 307.77 c h -f* -389.789 364.227 m 389.789 364.312 l 389.82 364.402 l 389.852 364.488 l -389.883 364.605 l 389.91 364.691 l 389.941 364.836 l 389.973 364.953 l 390.031 - 365.066 l 390.062 365.211 l 390.125 365.355 l 390.184 365.5 l 390.246 365.648 - l 390.305 365.793 l 390.398 365.938 l 390.457 366.082 l 390.547 366.227 - l 390.641 366.344 l 390.82 366.633 l 390.941 366.746 l 391.062 366.891 -l 391.184 367.008 l 391.309 367.094 l 391.43 367.211 l 391.578 367.297 l - 391.73 367.383 l 391.793 367.414 l 391.883 367.473 l 391.945 367.5 l 392.035 - 367.531 l 392.125 367.559 l 392.215 367.559 l 392.309 367.586 l 392.398 - 367.617 l 392.582 367.617 l 392.672 367.645 l 392.762 367.645 l 392.914 - 367.645 393.641 367.645 394.277 367.27 c 393.43 367.125 392.824 366.398 - 392.824 365.703 c 392.824 365.242 393.156 364.691 393.977 364.691 c 394.641 - 364.691 395.613 365.211 395.613 366.371 c 395.613 367.879 393.824 368.281 - 392.793 368.281 c 391.035 368.281 389.973 366.746 389.609 366.082 c 388.879 - 367.992 387.242 368.281 386.363 368.281 c 383.211 368.281 381.512 364.547 - 381.512 363.82 c 381.512 363.531 381.816 363.531 381.844 363.531 c 382.09 - 363.531 382.18 363.59 382.238 363.852 c 383.27 366.922 385.273 367.645 -386.305 367.645 c 386.879 367.645 387.941 367.383 387.941 365.703 c 387.941 - 364.805 387.426 362.867 386.305 358.84 c 385.816 357.043 384.758 355.824 - 383.422 355.824 c 383.242 355.824 382.543 355.824 381.906 356.203 c 382.664 - 356.348 383.332 356.957 383.332 357.766 c 383.332 358.551 382.664 358.781 - 382.211 358.781 c 381.328 358.781 380.57 358.027 380.57 357.102 c 380.57 - 355.77 382.09 355.188 383.391 355.188 c 385.395 355.188 386.484 357.215 - 386.574 357.391 c 386.941 356.32 388.031 355.188 389.852 355.188 c 392.945 - 355.188 394.672 358.926 394.672 359.648 c 394.672 359.941 394.398 359.941 - 394.309 359.941 c 394.035 359.941 393.977 359.824 393.914 359.621 c 392.914 - 356.52 390.852 355.824 389.883 355.824 c 388.73 355.824 388.242 356.754 - 388.242 357.738 c 388.242 358.375 388.426 359.012 388.758 360.289 c h -f -471.184 299.246 m 471.215 299.277 l 471.215 299.336 l 471.246 299.395 l - 471.246 299.449 l 471.273 299.48 l 471.273 299.625 l 471.305 299.625 l -471.305 299.914 l 471.305 300.434 470.879 300.695 470.426 300.695 c 470.121 - 300.695 469.637 300.523 469.363 300.09 c 469.305 299.941 469.062 299.047 - 468.941 298.523 c 468.727 297.77 468.547 296.988 468.363 296.207 c 467 -291.02 l 466.879 290.586 465.574 288.559 463.57 288.559 c 462.027 288.559 - 461.691 289.832 461.691 290.906 c 461.691 292.238 462.207 294.004 463.238 - 296.555 c 463.723 297.742 463.844 298.059 463.844 298.641 c 463.844 299.941 - 462.875 301.016 461.359 301.016 c 458.508 301.016 457.387 296.812 457.387 - 296.555 c 457.387 296.266 457.688 296.266 457.75 296.266 c 458.055 296.266 - 458.082 296.32 458.234 296.785 c 459.055 299.508 460.238 300.379 461.266 - 300.379 c 461.512 300.379 462.027 300.379 462.027 299.449 c 462.027 298.727 - 461.723 297.973 461.512 297.422 c 460.297 294.352 459.781 292.73 459.781 - 291.367 c 459.781 288.789 461.66 287.922 463.449 287.922 c 464.633 287.922 - 465.664 288.414 466.512 289.223 c 466.121 287.719 465.754 286.328 464.543 - 284.793 c 463.754 283.809 462.602 282.969 461.207 282.969 c 460.781 282.969 - 459.449 283.055 458.934 284.184 c 459.418 284.184 459.812 284.184 460.207 - 284.531 c 460.508 284.793 460.844 285.168 460.844 285.719 c 460.844 286.59 - 460.023 286.703 459.723 286.703 c 459.023 286.703 458.023 286.242 458.023 - 284.852 c 458.023 283.402 459.355 282.328 461.207 282.328 c 464.332 282.328 - 467.453 284.965 468.273 288.211 c h -f -0.941176 0.898039 0.396078 rg -49.18 85.465 m 339.746 85.465 l 355.449 85.465 368.09 72.824 368.09 57.121 - c 368.09 36.031 l 368.09 20.324 355.449 7.684 339.746 7.684 c 49.18 7.684 - l 33.477 7.684 20.832 20.324 20.832 36.031 c 20.832 57.121 l 20.832 72.824 - 33.477 85.465 49.18 85.465 c h -f -0 g -2.216693 w -1 J -q 1 0 0 -1 0 645.5 cm -49.18 560.035 m 339.746 560.035 l 355.449 560.035 368.09 572.676 368.09 - 588.379 c 368.09 609.469 l 368.09 625.176 355.449 637.816 339.746 637.816 - c 49.18 637.816 l 33.477 637.816 20.832 625.176 20.832 609.469 c 20.832 - 588.379 l 20.832 572.676 33.477 560.035 49.18 560.035 c h -S Q -BT -28.8 0 0 28.8 40.564413 54.567187 Tm -/f-0-0 1 Tf -[(LibUtili)3(ties)]TJ -ET -78.277 40.734 m 78.277 40.809 78.352 41.074 78.352 41.074 c 78.352 41.109 - 78.352 41.336 78.051 41.336 c 77.828 41.336 77.789 41.262 77.676 40.848 - c 76.289 35.336 l 72.504 35.184 68.977 32.035 68.977 28.773 c 68.977 26.484 - 70.664 24.609 73.59 24.422 c 73.402 23.711 73.215 22.922 73.027 22.172 -c 72.727 21.047 72.504 20.148 72.504 20.074 c 72.504 19.848 72.691 19.809 - 72.801 19.809 c 72.914 19.809 72.953 19.848 73.027 19.922 c 73.066 19.961 - 73.215 20.523 73.289 20.859 c 74.191 24.422 l 78.051 24.574 81.539 27.797 - 81.539 30.984 c 81.539 32.898 80.266 35.074 76.926 35.336 c h -73.703 24.949 m 72.277 25.023 70.551 25.887 70.551 28.246 c 70.551 31.137 - 72.613 34.473 76.176 34.809 c h -76.777 34.809 m 78.613 34.699 79.965 33.609 79.965 31.512 c 79.965 28.66 - 77.902 25.246 74.34 24.949 c h -f -83.297 19.113 m 83.188 18.625 83.148 18.512 82.512 18.512 c 82.285 18.512 - 82.062 18.512 82.062 18.137 c 82.062 17.949 82.211 17.875 82.285 17.875 - c 82.699 17.875 83.262 17.949 83.711 17.949 c 84.273 17.949 84.91 17.875 - 85.473 17.875 c 85.625 17.875 85.812 17.949 85.812 18.25 c 85.812 18.512 - 85.586 18.512 85.359 18.512 c 84.984 18.512 84.535 18.512 84.535 18.699 - c 84.535 18.773 84.688 19.227 84.723 19.449 c 84.949 20.352 85.172 21.25 - 85.359 21.961 c 85.547 21.625 86.074 20.988 87.086 20.988 c 89.109 20.988 - 91.359 23.238 91.359 25.711 c 91.359 27.664 90.012 28.523 88.887 28.523 - c 87.836 28.523 86.938 27.812 86.484 27.324 c 86.223 28.301 85.285 28.523 - 84.762 28.523 c 84.125 28.523 83.711 28.074 83.449 27.625 c 83.109 27.062 - 82.848 26.051 82.848 25.938 c 82.848 25.75 83.074 25.75 83.148 25.75 c -83.375 25.75 83.375 25.789 83.484 26.238 c 83.75 27.211 84.086 28.039 84.723 - 28.039 c 85.172 28.039 85.285 27.664 85.285 27.211 c 85.285 27.023 85.25 - 26.836 85.211 26.727 c h -86.484 26.5 m 87.461 27.812 88.285 28.039 88.812 28.039 c 89.484 28.039 - 90.047 27.551 90.047 26.426 c 90.047 25.75 89.672 24.023 89.188 23.051 -c 88.734 22.227 87.949 21.438 87.086 21.438 c 85.887 21.438 85.586 22.711 - 85.586 22.898 c 85.586 22.977 85.625 23.086 85.625 23.164 c h -f -101.027 18.984 m 101.027 19.059 101.027 19.098 100.613 19.512 c 97.652 -22.512 96.863 27.047 96.863 30.723 c 96.863 34.887 97.762 39.047 100.727 - 42.012 c 101.027 42.309 101.027 42.348 101.027 42.422 c 101.027 42.609 -100.949 42.684 100.801 42.684 c 100.539 42.684 98.402 41.035 96.977 37.996 - c 95.777 35.371 95.477 32.711 95.477 30.723 c 95.477 28.848 95.738 25.961 - 97.051 23.223 c 98.512 20.297 100.539 18.723 100.801 18.723 c 100.949 18.723 - 101.027 18.797 101.027 18.984 c h -f -110.398 31.961 m 110.547 32.559 111.109 34.773 112.762 34.773 c 112.875 - 34.773 113.473 34.773 113.961 34.473 c 113.285 34.324 112.836 33.762 112.836 - 33.16 c 112.836 32.785 113.098 32.336 113.734 32.336 c 114.262 32.336 115.012 - 32.746 115.012 33.723 c 115.012 34.961 113.625 35.297 112.797 35.297 c -111.41 35.297 110.586 34.023 110.285 33.496 c 109.688 35.074 108.41 35.297 - 107.699 35.297 c 105.223 35.297 103.836 32.223 103.836 31.621 c 103.836 - 31.359 104.098 31.359 104.137 31.359 c 104.324 31.359 104.398 31.434 104.438 - 31.621 c 105.262 34.172 106.836 34.773 107.66 34.773 c 108.109 34.773 108.938 - 34.547 108.938 33.16 c 108.938 32.41 108.523 30.836 107.66 27.461 c 107.285 - 25.996 106.422 24.984 105.375 24.984 c 105.223 24.984 104.699 24.984 104.172 - 25.285 c 104.773 25.434 105.297 25.922 105.297 26.598 c 105.297 27.234 -104.773 27.422 104.438 27.422 c 103.688 27.422 103.125 26.824 103.125 26.035 - c 103.125 24.949 104.285 24.461 105.336 24.461 c 106.949 24.461 107.812 - 26.148 107.848 26.262 c 108.148 25.398 109.012 24.461 110.438 24.461 c -112.91 24.461 114.262 27.535 114.262 28.137 c 114.262 28.398 114.074 28.398 - 114 28.398 c 113.773 28.398 113.734 28.285 113.66 28.137 c 112.875 25.547 - 111.262 24.984 110.512 24.984 c 109.574 24.984 109.199 25.734 109.199 26.559 - c 109.199 27.086 109.312 27.609 109.574 28.66 c h -f -122.977 30.723 m 122.977 32.559 122.715 35.449 121.402 38.184 c 119.977 - 41.109 117.914 42.684 117.688 42.684 c 117.539 42.684 117.426 42.574 117.426 - 42.422 c 117.426 42.348 117.426 42.309 117.875 41.859 c 120.238 39.496 -121.59 35.711 121.59 30.723 c 121.59 26.598 120.727 22.398 117.766 19.398 - c 117.426 19.098 117.426 19.059 117.426 18.984 c 117.426 18.836 117.539 - 18.723 117.688 18.723 c 117.914 18.723 120.09 20.371 121.477 23.41 c 122.715 - 26.035 122.977 28.699 122.977 30.723 c h -f -2.964922 w -0 J -q 0.558965 0 0 -1 0 645.5 cm -708.515 564.629 m 708.515 630.813 l S Q -q 0.558965 0 0 -1 0 645.5 cm -972.606 564.629 m 972.606 630.813 l S Q -3.416663 w -q 0.558965 0 0 -1 0 645.5 cm -708.725 597.723 m 972.396 597.723 l S Q -0 0 1 rg -1.070034 w -q 0.558965 0 0 -1 0 645.5 cm -708.515 597.723 m 708.515 597.723 734.987 564.629 774.702 564.629 c 834.264 - 564.629 893.833 690.379 973.256 597.723 c 973.256 597.723 955.764 630.813 - 940.159 630.813 c 908.963 630.813 905.175 564.629 873.979 564.629 c 842.776 - 564.629 838.988 630.813 807.792 630.813 c 776.589 630.813 772.808 564.629 - 741.605 564.629 c 726.007 564.629 708.515 597.723 708.515 597.723 c h -S Q -0.803922 0 0 rg -1.89573 w -q 0.558965 0 0 -1 0 645.5 cm -708.515 598.047 m 708.515 598.047 719.208 631.137 725.553 631.301 c 741.605 - 631.715 741.92 564.406 758.154 564.465 c 775.254 564.527 774.059 631.348 - 791.167 631.301 c 810.65 631.25 805.095 564.793 824.585 564.871 c 843.601 - 564.949 838.981 630.902 857.591 631.301 c 876.614 631.707 871.994 565.281 - 890.604 564.871 c 909.214 564.465 904.595 631.301 923.617 631.301 c 942.633 - 631.301 938.013 564.93 956.623 564.871 c 965.736 564.844 973.256 598.047 - 973.256 598.047 c S Q -0 g -1.6 w -[ 4.8 4.8] 0 d -q 1 0 0 -1 0 645.5 cm -446.555 218.176 m 432.012 324.848 l S Q -[ 4.8 4.8] 0 d -q 1 0 0 -1 0 645.5 cm -491.004 315.148 m 494.234 213.324 l S Q -[ 4.8 4.8] 0 d -q 1 0 0 -1 0 645.5 cm -448.172 254.539 m 460.293 165.648 l S Q -[ 4.8 4.8] 0 d -q 1 0 0 -1 0 645.5 cm -412.617 495.359 m 394.836 564.859 l S Q -[ 4.8 4.8] 0 d -q 1 0 0 -1 0 645.5 cm -510.398 497.785 m 542.723 563.242 l S Q -0.729412 0.619608 0.964706 rg -48.375 616.094 m 338.941 616.094 l 354.645 616.094 367.285 603.453 367.285 - 587.75 c 367.285 566.656 l 367.285 550.953 354.645 538.312 338.941 538.312 - c 48.375 538.312 l 32.672 538.312 20.027 550.953 20.027 566.656 c 20.027 - 587.75 l 20.027 603.453 32.672 616.094 48.375 616.094 c h -f -0 g -2.216693 w -1 J -[] 0.0 d -q 1 0 0 -1 0 645.5 cm -48.375 29.406 m 338.941 29.406 l 354.645 29.406 367.285 42.047 367.285 -57.75 c 367.285 78.844 l 367.285 94.547 354.645 107.188 338.941 107.188 -c 48.375 107.188 l 32.672 107.188 20.027 94.547 20.027 78.844 c 20.027 57.75 - l 20.027 42.047 32.672 29.406 48.375 29.406 c h -S Q -BT -28.8 0 0 28.8 39.759128 585.195728 Tm -/f-0-0 1 Tf -[(SolverUt)3(ils)]TJ -ET -2.4 w -0 J -[ 7.2 7.2] 0 d -q 1 0 0 -1 0 645.5 cm -19.355 526.582 m 561.332 526.582 l 570.121 526.582 577.199 531.621 577.199 - 537.879 c 577.199 633 l 577.199 639.258 570.121 644.297 561.332 644.297 - c 19.355 644.297 l 10.562 644.297 3.484 639.258 3.484 633 c 3.484 537.879 - l 3.484 531.621 10.562 526.582 19.355 526.582 c h -S Q -[ 7.2 7.2] 0 d -q 1 0 0 -1 0 645.5 cm -17.07 134.012 m 559.047 134.012 l 567.836 134.012 574.914 139.051 574.914 - 145.309 c 574.914 506.715 l 574.914 512.973 567.836 518.012 559.047 518.012 - c 17.07 518.012 l 8.277 518.012 1.199 512.973 1.199 506.715 c 1.199 145.309 - l 1.199 139.051 8.277 134.012 17.07 134.012 c h -S Q -[ 7.2 7.2] 0 d -q 1 0 0 -1 0 645.5 cm -17.07 1.211 m 559.047 1.211 l 567.836 1.211 574.914 6.25 574.914 12.508 - c 574.914 109.914 l 574.914 116.172 567.836 121.211 559.047 121.211 c 17.07 - 121.211 l 8.277 121.211 1.199 116.172 1.199 109.914 c 1.199 12.508 l 1.199 - 6.25 8.277 1.211 17.07 1.211 c h -S Q -BT -19.2 0 0 19.2 8.05715 490.345947 Tm -/f-2-0 1 Tf -[(SPECTRAL ELEMENT METHOD)]TJ -0.0767334 -20.418523 Td -[(AUXILIARY)]TJ --0.119047 27.357143 Td -[(APPLICATION DOMAI)3(N)]TJ -ET -52.566 257.066 m 56.27 261.215 l 56.719 261.668 56.918 261.867 59.52 261.867 - c 59.52 263.367 l 58.418 263.316 56.77 263.266 56.617 263.266 c 55.816 -263.266 54.219 263.367 53.316 263.367 c 53.316 261.867 l 53.77 261.867 54.168 - 261.816 54.52 261.617 c 54.418 261.418 54.418 261.316 54.27 261.215 c 51.617 - 258.215 l 48.469 261.867 l 49.77 261.867 l 49.77 263.367 l 48.918 263.367 - 46.918 263.266 45.867 263.266 c 44.867 263.266 43.418 263.367 42.367 263.367 - c 42.367 261.867 l 44.668 261.867 l 49.617 256.016 l 45.418 251.316 l 44.918 - 250.715 43.77 250.715 42.219 250.715 c 42.219 249.215 l 43.316 249.266 -45.02 249.316 45.168 249.316 c 45.969 249.316 47.816 249.266 48.418 249.215 - c 48.418 250.715 l 47.867 250.715 47.27 250.867 47.27 251.066 c 47.27 251.117 - 47.27 251.117 47.469 251.367 c 50.566 254.867 l 54.066 250.715 l 52.816 - 250.715 l 52.816 249.215 l 53.668 249.266 55.617 249.316 56.668 249.316 - c 57.668 249.316 59.117 249.266 60.168 249.215 c 60.168 250.715 l 57.918 - 250.715 l h -f -91.621 259.668 m 92.121 259.668 92.723 259.668 92.723 260.266 c 92.723 -260.918 92.121 260.918 91.672 260.918 c 72.574 260.918 l 72.121 260.918 -71.523 260.918 71.523 260.266 c 71.523 259.668 72.121 259.668 72.574 259.668 - c h -91.672 253.465 m 92.121 253.465 92.723 253.465 92.723 254.117 c 92.723 -254.715 92.121 254.715 91.621 254.715 c 72.574 254.715 l 72.121 254.715 -71.523 254.715 71.523 254.117 c 71.523 253.465 72.121 253.465 72.574 253.465 - c h -f -121.973 262.066 m 122.324 262.418 122.324 262.465 122.324 262.566 c 122.324 - 262.766 122.172 262.965 121.922 262.965 c 121.723 262.965 121.625 262.816 - 121.422 262.566 c 114.125 254.465 l 112.824 258.516 112.574 259.316 111.875 - 260.965 c 111.523 261.715 110.824 263.316 108.023 263.316 c 106.172 263.316 - 105.324 261.668 105.324 261.215 c 105.324 261.168 105.324 260.918 105.723 - 260.918 c 105.973 260.918 106.074 261.066 106.125 261.266 c 106.574 262.465 - 107.625 262.617 107.824 262.617 c 108.773 262.617 109.723 260.168 110.273 - 258.766 c 111.273 256.266 112.324 252.566 112.324 252.465 c 112.324 252.418 - 112.324 252.367 112.074 252.117 c 104.723 243.918 l 104.375 243.566 104.375 - 243.516 104.375 243.418 c 104.375 243.215 104.574 243.016 104.723 243.016 - c 104.973 243.016 105.125 243.266 105.273 243.367 c 112.574 251.566 l 113.574 - 248.266 113.973 247.016 114.723 245.215 c 115.125 244.266 115.824 242.668 - 118.672 242.668 c 120.523 242.668 121.375 244.316 121.375 244.766 c 121.375 - 244.918 121.324 245.117 121.023 245.117 c 120.672 245.117 120.672 244.965 - 120.574 244.668 c 120.273 243.867 119.473 243.367 118.875 243.367 c 117.273 - 243.367 115.074 251.117 114.375 253.566 c h -f -128.324 249.535 m 128.922 249.535 130.723 249.586 131.922 249.984 c 133.574 - 250.586 133.871 251.637 133.871 252.285 c 133.871 253.535 132.621 254.285 - 131.121 254.285 c 128.422 254.285 124.824 252.234 124.824 248.387 c 124.824 - 246.137 126.223 244.234 128.824 244.234 c 132.621 244.234 134.371 246.434 - 134.371 246.734 c 134.371 246.887 134.172 247.137 133.973 247.137 c 133.871 - 247.137 133.824 247.086 133.621 246.887 c 131.871 244.836 129.273 244.836 - 128.871 244.836 c 127.523 244.836 126.621 245.734 126.621 247.535 c 126.621 - 247.836 126.621 248.285 126.922 249.535 c h -127.074 250.137 m 128.023 253.387 130.473 253.637 131.121 253.637 c 132.074 - 253.637 132.922 253.137 132.922 252.285 c 132.922 250.137 129.121 250.137 - 128.172 250.137 c h -f -147.562 241.566 m 147.562 241.668 147.562 241.715 147.012 242.266 c 143.062 - 246.266 142.012 252.316 142.012 257.215 c 142.012 262.766 143.211 268.316 - 147.164 272.266 c 147.562 272.668 147.562 272.715 147.562 272.816 c 147.562 - 273.066 147.461 273.168 147.262 273.168 c 146.914 273.168 144.062 270.965 - 142.164 266.918 c 140.562 263.418 140.164 259.867 140.164 257.215 c 140.164 - 254.715 140.512 250.867 142.262 247.215 c 144.211 243.316 146.914 241.215 - 147.262 241.215 c 147.461 241.215 147.562 241.316 147.562 241.566 c h -f -154.309 258.965 m 150.859 256.668 150.16 253.668 150.16 252.516 c 150.16 - 251.016 151.008 250.117 151.059 250.016 c 152.109 248.965 152.359 248.816 - 154.758 247.918 c 158.609 246.418 l 159.109 246.215 159.758 246.016 159.758 - 245.066 c 159.758 244.316 159.16 243.367 158.16 243.367 c 156.758 243.367 - 155.707 244.168 155.359 244.418 c 155.16 244.516 155.16 244.566 155.008 - 244.566 c 154.758 244.566 154.707 244.316 154.707 244.215 c 154.707 243.816 - 156.41 242.668 158.16 242.668 c 160.16 242.668 161.508 244.516 161.508 -246.066 c 161.508 247.617 160.309 248.215 159.957 248.367 c 159.508 248.516 - 158.457 248.918 158.008 249.066 c 157.41 249.367 156.758 249.617 156.059 - 249.816 c 154.16 250.566 l 152.707 251.168 151.758 252.066 151.758 253.418 - c 151.758 254.715 153.008 257.516 155.707 258.867 c 156.859 258.418 157.809 - 258.418 158.508 258.418 c 159.457 258.418 161.457 258.418 161.457 259.418 - c 161.457 260.215 160.109 260.266 158.859 260.266 c 158.258 260.266 157.359 - 260.266 156.16 259.918 c 155.359 260.715 155.207 261.766 155.207 262.367 - c 155.207 264.168 156.359 266.617 158.758 267.816 c 159.309 267.117 160.059 - 267.117 160.809 267.117 c 161.609 267.117 163.66 267.117 163.66 268.117 - c 163.66 268.918 162.207 268.965 161.008 268.965 c 160.559 268.965 159.809 - 268.965 158.957 268.816 c 158.859 269.066 158.809 269.316 158.809 269.867 - c 158.809 270.316 158.957 270.965 158.957 271.016 c 158.957 271.266 158.809 - 271.465 158.609 271.465 c 158.008 271.465 158.008 269.965 158.008 269.867 - c 158.008 269.266 158.207 268.766 158.258 268.668 c 154.809 267.668 152.66 - 265.117 152.66 262.668 c 152.66 261.516 153.258 260.168 154.758 259.316 - c h -159.508 268.117 m 160.008 268.266 160.66 268.266 161.008 268.266 c 162.109 - 268.266 162.207 268.215 162.809 268.066 c 162.559 267.965 162.207 267.816 - 160.809 267.816 c 160.207 267.816 159.859 267.816 159.508 268.117 c h -157.008 259.418 m 157.758 259.566 158.457 259.566 158.809 259.566 c 159.957 - 259.566 160.059 259.566 160.66 259.418 c 160.359 259.266 160.059 259.117 - 158.609 259.117 c 157.859 259.117 157.559 259.117 157.008 259.418 c h -f -174.023 257.215 m 174.023 259.668 173.672 263.516 171.922 267.168 c 170.023 - 271.066 167.273 273.168 166.973 273.168 c 166.773 273.168 166.625 273.016 - 166.625 272.816 c 166.625 272.715 166.625 272.668 167.223 272.066 c 170.375 - 268.918 172.172 263.867 172.172 257.215 c 172.172 251.715 171.023 246.117 - 167.074 242.117 c 166.625 241.715 166.625 241.668 166.625 241.566 c 166.625 - 241.367 166.773 241.215 166.973 241.215 c 167.273 241.215 170.172 243.418 - 172.023 247.465 c 173.672 250.965 174.023 254.516 174.023 257.215 c h -f -61.254 569.996 m 61.293 570.07 61.367 570.223 61.367 570.332 c 61.367 570.484 - 61.328 570.52 60.805 570.52 c 44.266 570.52 l 43.742 570.52 43.703 570.484 - 43.703 570.332 c 43.703 570.223 43.781 570.07 43.816 569.996 c 51.879 553.832 - l 52.066 553.535 52.141 553.383 52.516 553.383 c 52.93 553.383 53.004 553.535 - 53.191 553.832 c h -46.668 568.797 m 59.793 568.797 l 53.266 555.633 l h -f -70.941 565.883 m 70.379 565.883 l 70.344 565.508 70.156 564.535 69.93 564.383 - c 69.816 564.273 68.543 564.273 68.281 564.273 c 65.203 564.273 l 66.969 - 565.809 67.566 566.297 68.543 567.086 c 69.781 568.059 70.941 569.109 70.941 - 570.684 c 70.941 572.711 69.18 573.945 67.043 573.945 c 64.98 573.945 63.555 - 572.484 63.555 570.945 c 63.555 570.121 64.266 570.008 64.453 570.008 c - 64.828 570.008 65.316 570.309 65.316 570.91 c 65.316 571.211 65.203 571.809 - 64.344 571.809 c 64.867 572.973 65.992 573.348 66.781 573.348 c 68.469 -573.348 69.328 572.035 69.328 570.684 c 69.328 569.223 68.281 568.098 67.754 - 567.496 c 63.742 563.484 l 63.555 563.336 63.555 563.297 63.555 562.848 - c 70.453 562.848 l h -f -81.594 555.52 m 81.859 554.547 82.719 553.91 83.734 553.91 c 84.559 553.91 - 85.121 554.473 85.496 555.223 c 85.906 556.082 86.207 557.547 86.207 557.582 - c 86.207 557.848 86.02 557.848 85.945 557.848 c 85.684 557.848 85.684 557.734 - 85.609 557.395 c 85.27 556.047 84.82 554.434 83.809 554.434 c 83.32 554.434 - 83.059 554.734 83.059 555.52 c 83.059 556.047 83.359 557.172 83.547 558.035 - c 84.219 560.621 l 84.297 560.957 84.52 561.859 84.633 562.234 c 84.746 - 562.797 84.969 563.695 84.969 563.848 c 84.969 564.258 84.633 564.484 84.297 - 564.484 c 84.184 564.484 83.547 564.445 83.359 563.66 c 82.906 561.895 -81.859 557.695 81.559 556.457 c 81.52 556.348 80.582 554.434 78.82 554.434 - c 77.582 554.434 77.359 555.52 77.359 556.383 c 77.359 557.734 78.031 559.609 - 78.633 561.258 c 78.934 562.008 79.047 562.348 79.047 562.797 c 79.047 -563.848 78.297 564.746 77.094 564.746 c 74.809 564.746 73.945 561.258 73.945 - 561.07 c 73.945 560.809 74.172 560.809 74.207 560.809 c 74.469 560.809 -74.469 560.883 74.582 561.258 c 75.184 563.32 76.121 564.223 77.02 564.223 - c 77.246 564.223 77.621 564.184 77.621 563.434 c 77.621 562.871 77.359 -562.16 77.207 561.82 c 76.309 559.422 75.82 557.957 75.82 556.797 c 75.82 - 554.508 77.469 553.91 78.746 553.91 c 80.32 553.91 81.184 554.996 81.594 - 555.52 c h -f -107.984 559.684 m 108.395 559.684 108.848 559.684 108.848 560.172 c 108.848 - 560.621 108.395 560.621 107.984 560.621 c 95.047 560.621 l 94.633 560.621 - 94.223 560.621 94.223 560.172 c 94.223 559.684 94.633 559.684 95.047 559.684 - c h -f -124.691 561.145 m 125.668 558.633 126.828 554.996 127.203 554.434 c 127.578 - 553.91 127.805 553.91 128.48 553.91 c 129.004 553.91 l 129.23 553.945 129.266 - 554.059 129.266 554.133 c 129.266 554.207 129.191 554.285 129.117 554.359 - c 128.891 554.621 128.742 554.996 128.594 555.445 c 123.719 569.059 l 123.191 - 570.445 121.918 570.785 120.793 570.785 c 120.68 570.785 120.344 570.785 - 120.344 570.52 c 120.344 570.332 120.531 570.258 120.566 570.258 c 121.355 - 570.145 121.543 569.996 122.141 568.348 c 124.43 561.859 l 117.828 555.297 - l 117.566 554.996 117.418 554.883 117.418 554.547 c 117.418 554.133 117.754 - 553.871 118.129 553.871 c 118.504 553.871 118.73 554.133 118.918 554.359 - c h -f -138.453 555.52 m 138.715 554.547 139.578 553.91 140.59 553.91 c 141.414 - 553.91 141.977 554.473 142.352 555.223 c 142.766 556.082 143.062 557.547 - 143.062 557.582 c 143.062 557.848 142.875 557.848 142.801 557.848 c 142.539 - 557.848 142.539 557.734 142.465 557.395 c 142.125 556.047 141.676 554.434 - 140.664 554.434 c 140.176 554.434 139.914 554.734 139.914 555.52 c 139.914 - 556.047 140.215 557.172 140.402 558.035 c 141.078 560.621 l 141.152 560.957 - 141.375 561.859 141.488 562.234 c 141.602 562.797 141.828 563.695 141.828 - 563.848 c 141.828 564.258 141.488 564.484 141.152 564.484 c 141.039 564.484 - 140.402 564.445 140.215 563.66 c 139.766 561.895 138.715 557.695 138.414 - 556.457 c 138.375 556.348 137.438 554.434 135.676 554.434 c 134.438 554.434 - 134.215 555.52 134.215 556.383 c 134.215 557.734 134.891 559.609 135.488 - 561.258 c 135.789 562.008 135.902 562.348 135.902 562.797 c 135.902 563.848 - 135.152 564.746 133.953 564.746 c 131.664 564.746 130.801 561.258 130.801 - 561.07 c 130.801 560.809 131.027 560.809 131.062 560.809 c 131.328 560.809 - 131.328 560.883 131.438 561.258 c 132.039 563.32 132.977 564.223 133.875 - 564.223 c 134.102 564.223 134.477 564.184 134.477 563.434 c 134.477 562.871 - 134.215 562.16 134.062 561.82 c 133.164 559.422 132.676 557.957 132.676 - 556.797 c 132.676 554.508 134.328 553.91 135.602 553.91 c 137.176 553.91 - 138.039 554.996 138.453 555.52 c h -f -166.844 562.008 m 167.219 562.008 167.668 562.008 167.668 562.457 c 167.668 - 562.945 167.219 562.945 166.883 562.945 c 152.555 562.945 l 152.219 562.945 - 151.77 562.945 151.77 562.457 c 151.77 562.008 152.219 562.008 152.555 -562.008 c h -166.883 557.359 m 167.219 557.359 167.668 557.359 167.668 557.848 c 167.668 - 558.297 167.219 558.297 166.844 558.297 c 152.555 558.297 l 152.219 558.297 - 151.77 558.297 151.77 557.848 c 151.77 557.359 152.219 557.359 152.555 -557.359 c h -f -184.434 563.734 m 186.496 563.734 l 186.984 563.734 187.211 563.734 187.211 - 564.223 c 187.211 564.484 186.984 564.484 186.57 564.484 c 184.586 564.484 - l 185.07 567.223 l 185.184 567.707 185.523 569.395 185.672 569.695 c 185.859 - 570.145 186.273 570.52 186.797 570.52 c 186.871 570.52 187.508 570.52 187.961 - 570.07 c 186.91 569.996 186.648 569.133 186.648 568.797 c 186.648 568.234 - 187.098 567.934 187.547 567.934 c 188.184 567.934 188.859 568.496 188.859 - 569.395 c 188.859 570.484 187.773 571.047 186.797 571.047 c 185.973 571.047 - 184.473 570.598 183.758 568.234 c 183.609 567.746 183.535 567.484 182.973 - 564.484 c 181.32 564.484 l 180.836 564.484 180.57 564.484 180.57 564.035 - c 180.57 563.734 180.797 563.734 181.246 563.734 c 182.82 563.734 l 181.059 - 554.285 l 180.609 551.957 180.195 549.785 178.961 549.785 c 178.848 549.785 - 178.285 549.785 177.797 550.234 c 178.922 550.309 179.148 551.172 179.148 - 551.508 c 179.148 552.07 178.695 552.371 178.246 552.371 c 177.609 552.371 - 176.934 551.809 176.934 550.91 c 176.934 549.859 177.984 549.258 178.961 - 549.258 c 180.273 549.258 181.246 550.684 181.66 551.582 c 182.445 553.082 - 182.973 555.973 183.008 556.16 c h -f -49.867 339.547 m 50.129 338.57 50.992 337.934 52.004 337.934 c 52.832 337.934 - 53.395 338.496 53.77 339.246 c 54.18 340.109 54.48 341.57 54.48 341.609 - c 54.48 341.871 54.293 341.871 54.219 341.871 c 53.957 341.871 53.957 341.758 - 53.879 341.422 c 53.543 340.07 53.094 338.457 52.082 338.457 c 51.594 338.457 - 51.332 338.758 51.332 339.547 c 51.332 340.07 51.629 341.195 51.816 342.059 - c 52.492 344.645 l 52.566 344.984 52.793 345.883 52.906 346.258 c 53.02 - 346.82 53.242 347.719 53.242 347.871 c 53.242 348.281 52.906 348.508 52.566 - 348.508 c 52.457 348.508 51.816 348.469 51.629 347.684 c 51.18 345.922 -50.129 341.719 49.832 340.484 c 49.793 340.371 48.855 338.457 47.094 338.457 - c 45.855 338.457 45.629 339.547 45.629 340.406 c 45.629 341.758 46.305 -343.633 46.906 345.281 c 47.207 346.031 47.316 346.371 47.316 346.82 c 47.316 - 347.871 46.566 348.77 45.367 348.77 c 43.082 348.77 42.219 345.281 42.219 - 345.094 c 42.219 344.832 42.441 344.832 42.48 344.832 c 42.742 344.832 -42.742 344.906 42.855 345.281 c 43.457 347.344 44.395 348.246 45.293 348.246 - c 45.52 348.246 45.895 348.207 45.895 347.457 c 45.895 346.895 45.629 346.184 - 45.48 345.844 c 44.582 343.445 44.094 341.984 44.094 340.82 c 44.094 338.531 - 45.742 337.934 47.02 337.934 c 48.594 337.934 49.457 339.02 49.867 339.547 - c h -f -60.141 354.145 m 57.629 353.508 56.203 351.371 56.203 349.609 c 56.203 -347.809 57.555 346.684 59.203 346.684 c 61.23 346.684 62.805 349.047 62.805 - 351.484 c 62.805 353.098 61.941 354.07 61.418 354.633 c 60.816 355.348 -59.543 356.695 59.543 357.484 c 59.543 357.707 59.805 358.16 60.48 358.16 - c 61.043 358.16 61.531 357.895 61.867 357.707 c 62.016 357.633 62.617 357.258 - 62.879 357.258 c 63.293 357.258 63.594 357.633 63.594 357.973 c 63.594 -358.383 63.367 358.422 62.469 358.609 c 62.281 358.645 61.492 358.797 60.969 - 358.797 c 59.691 358.797 59.016 358.082 59.016 357.07 c 59.016 356.172 -59.543 355.16 60.141 354.145 c h -60.406 353.695 m 60.891 352.945 61.492 351.973 61.492 350.77 c 61.492 349.383 - 60.668 347.133 59.242 347.133 c 58.344 347.133 57.441 347.734 57.441 349.121 - c 57.441 350.246 58.078 353.133 60.406 353.695 c h -f -73.598 332.457 m 73.598 332.531 73.598 332.57 73.184 332.984 c 70.223 335.984 - 69.434 340.52 69.434 344.195 c 69.434 348.359 70.336 352.52 73.297 355.484 - c 73.598 355.781 73.598 355.82 73.598 355.895 c 73.598 356.082 73.523 356.156 - 73.371 356.156 c 73.109 356.156 70.973 354.508 69.547 351.469 c 68.348 -348.844 68.047 346.184 68.047 344.195 c 68.047 342.32 68.309 339.434 69.621 - 336.695 c 71.086 333.77 73.109 332.195 73.371 332.195 c 73.523 332.195 -73.598 332.27 73.598 332.457 c h -f -82.973 345.434 m 83.121 346.031 83.684 348.246 85.336 348.246 c 85.449 -348.246 86.047 348.246 86.535 347.945 c 85.859 347.797 85.41 347.234 85.41 - 346.633 c 85.41 346.258 85.672 345.809 86.309 345.809 c 86.836 345.809 -87.586 346.219 87.586 347.195 c 87.586 348.434 86.199 348.77 85.371 348.77 - c 83.984 348.77 83.16 347.496 82.859 346.969 c 82.262 348.547 80.984 348.77 - 80.273 348.77 c 77.797 348.77 76.41 345.695 76.41 345.094 c 76.41 344.832 - 76.672 344.832 76.711 344.832 c 76.898 344.832 76.973 344.906 77.012 345.094 - c 77.836 347.645 79.41 348.246 80.234 348.246 c 80.684 348.246 81.512 348.02 - 81.512 346.633 c 81.512 345.883 81.098 344.309 80.234 340.934 c 79.859 -339.469 78.996 338.457 77.949 338.457 c 77.797 338.457 77.273 338.457 76.746 - 338.758 c 77.348 338.906 77.871 339.395 77.871 340.07 c 77.871 340.707 -77.348 340.895 77.012 340.895 c 76.262 340.895 75.699 340.297 75.699 339.508 - c 75.699 338.422 76.859 337.934 77.91 337.934 c 79.523 337.934 80.387 339.621 - 80.422 339.734 c 80.723 338.871 81.586 337.934 83.012 337.934 c 85.484 -337.934 86.836 341.008 86.836 341.609 c 86.836 341.871 86.648 341.871 86.574 - 341.871 c 86.348 341.871 86.309 341.758 86.234 341.609 c 85.449 339.02 -83.836 338.457 83.086 338.457 c 82.148 338.457 81.773 339.207 81.773 340.031 - c 81.773 340.559 81.887 341.082 82.148 342.133 c h -f -95.551 344.195 m 95.551 346.031 95.289 348.922 93.977 351.656 c 92.551 -354.582 90.488 356.156 90.262 356.156 c 90.113 356.156 90 356.047 90 355.895 - c 90 355.82 90 355.781 90.449 355.332 c 92.812 352.969 94.164 349.184 94.164 - 344.195 c 94.164 340.07 93.301 335.871 90.34 332.871 c 90 332.57 90 332.531 - 90 332.457 c 90 332.309 90.113 332.195 90.262 332.195 c 90.488 332.195 -92.664 333.844 94.051 336.883 c 95.289 339.508 95.551 342.172 95.551 344.195 - c h -f -121.023 346.031 m 121.398 346.031 121.848 346.031 121.848 346.484 c 121.848 - 346.969 121.398 346.969 121.059 346.969 c 106.734 346.969 l 106.398 346.969 - 105.945 346.969 105.945 346.484 c 105.945 346.031 106.398 346.031 106.734 - 346.031 c h -121.059 341.383 m 121.398 341.383 121.848 341.383 121.848 341.871 c 121.848 - 342.32 121.398 342.32 121.023 342.32 c 106.734 342.32 l 106.398 342.32 -105.945 342.32 105.945 341.871 c 105.945 341.383 106.398 341.383 106.734 - 341.383 c h -f -139.918 343.34 m 131.406 332.84 l 131.219 332.617 131.18 332.578 131.18 - 332.465 c 131.18 332.203 131.406 332.203 131.855 332.203 c 151.656 332.203 - l 153.719 338.164 l 153.117 338.164 l 152.52 336.367 150.941 334.902 148.879 - 334.227 c 148.504 334.078 146.855 333.516 143.332 333.516 c 133.168 333.516 - l 141.492 343.789 l 141.645 344.016 141.68 344.055 141.68 344.164 c 141.68 - 344.277 141.68 344.277 141.531 344.504 c 133.77 355.152 l 143.219 355.152 - l 145.957 355.152 151.469 355.004 153.117 350.539 c 153.719 350.539 l 151.656 - 356.129 l 131.855 356.129 l 131.18 356.129 131.18 356.09 131.18 355.379 - c h -f -160.77 355.391 m 163.805 355.391 l 166.617 355.391 169.02 357.191 169.02 - 359.031 c 169.02 360.453 167.633 361.656 165.344 361.656 c 159.492 361.656 - l 159.156 361.656 158.969 361.656 158.969 361.281 c 158.969 361.055 159.156 - 361.055 159.531 361.055 c 159.793 361.055 159.867 361.055 160.168 361.016 - c 160.508 360.98 160.508 360.941 160.508 360.754 c 160.508 360.754 160.508 - 360.641 160.469 360.418 c 158.258 351.605 l 158.07 350.93 158.07 350.816 - 156.758 350.816 c 156.457 350.816 156.27 350.816 156.27 350.441 c 156.27 - 350.441 156.27 350.219 156.531 350.219 c 157.02 350.219 158.219 350.293 - 158.707 350.293 c 158.969 350.293 159.57 350.293 159.867 350.254 c 160.168 - 350.254 160.617 350.219 160.918 350.219 c 161.031 350.219 161.258 350.219 - 161.258 350.594 c 161.258 350.816 161.07 350.816 160.73 350.816 c 160.73 - 350.816 160.395 350.816 160.094 350.855 c 159.719 350.891 159.719 350.93 - 159.719 351.117 c 159.719 351.117 159.719 351.23 159.793 351.453 c h -161.969 360.453 m 162.117 360.98 162.117 361.055 162.832 361.055 c 164.781 - 361.055 l 166.355 361.055 167.293 360.566 167.293 359.367 c 167.293 358.879 - 167.105 357.531 166.281 356.781 c 165.68 356.254 164.707 355.953 163.508 - 355.953 c 160.844 355.953 l h -f -156.305 328.996 m 156.195 328.508 156.156 328.398 155.52 328.398 c 155.293 - 328.398 155.07 328.398 155.07 328.023 c 155.07 327.836 155.219 327.758 -155.293 327.758 c 155.707 327.758 156.27 327.836 156.719 327.836 c 157.281 - 327.836 157.918 327.758 158.48 327.758 c 158.633 327.758 158.82 327.836 - 158.82 328.133 c 158.82 328.398 158.594 328.398 158.367 328.398 c 157.992 - 328.398 157.543 328.398 157.543 328.586 c 157.543 328.66 157.695 329.109 - 157.73 329.336 c 157.957 330.234 158.18 331.133 158.367 331.848 c 158.555 - 331.508 159.082 330.871 160.094 330.871 c 162.117 330.871 164.367 333.121 - 164.367 335.598 c 164.367 337.547 163.02 338.41 161.895 338.41 c 160.844 - 338.41 159.945 337.695 159.492 337.211 c 159.23 338.184 158.293 338.41 -157.77 338.41 c 157.133 338.41 156.719 337.961 156.457 337.508 c 156.117 - 336.945 155.855 335.934 155.855 335.82 c 155.855 335.633 156.082 335.633 - 156.156 335.633 c 156.383 335.633 156.383 335.672 156.492 336.121 c 156.758 - 337.098 157.094 337.922 157.73 337.922 c 158.18 337.922 158.293 337.547 - 158.293 337.098 c 158.293 336.91 158.258 336.723 158.219 336.609 c h -159.492 336.383 m 160.469 337.695 161.293 337.922 161.82 337.922 c 162.492 - 337.922 163.055 337.434 163.055 336.309 c 163.055 335.633 162.68 333.91 - 162.195 332.934 c 161.742 332.109 160.957 331.32 160.094 331.32 c 158.895 - 331.32 158.594 332.598 158.594 332.785 c 158.594 332.859 158.633 332.973 - 158.633 333.047 c h -f -185.457 354.207 m 185.457 354.281 185.531 354.547 185.531 354.547 c 185.531 - 354.582 185.531 354.809 185.234 354.809 c 185.008 354.809 184.969 354.734 - 184.859 354.32 c 183.469 348.809 l 179.684 348.656 176.156 345.508 176.156 - 342.246 c 176.156 339.957 177.844 338.082 180.77 337.895 c 180.582 337.184 - 180.395 336.395 180.207 335.645 c 179.906 334.52 179.684 333.621 179.684 - 333.547 c 179.684 333.32 179.871 333.281 179.984 333.281 c 180.094 333.281 - 180.133 333.32 180.207 333.395 c 180.246 333.434 180.395 333.996 180.469 - 334.332 c 181.371 337.895 l 185.234 338.047 188.719 341.27 188.719 344.457 - c 188.719 346.371 187.445 348.547 184.109 348.809 c h -180.883 338.422 m 179.457 338.496 177.734 339.359 177.734 341.719 c 177.734 - 344.609 179.797 347.945 183.359 348.281 c h -183.957 348.281 m 185.797 348.172 187.145 347.082 187.145 344.984 c 187.145 - 342.133 185.082 338.719 181.52 338.422 c h -f -190.48 332.586 m 190.367 332.098 190.328 331.984 189.691 331.984 c 189.469 - 331.984 189.242 331.984 189.242 331.609 c 189.242 331.422 189.391 331.348 - 189.469 331.348 c 189.879 331.348 190.441 331.422 190.891 331.422 c 191.453 - 331.422 192.094 331.348 192.656 331.348 c 192.805 331.348 192.992 331.422 - 192.992 331.723 c 192.992 331.984 192.766 331.984 192.543 331.984 c 192.168 - 331.984 191.719 331.984 191.719 332.172 c 191.719 332.246 191.867 332.699 - 191.906 332.922 c 192.129 333.824 192.355 334.723 192.543 335.434 c 192.73 - 335.098 193.254 334.461 194.266 334.461 c 196.293 334.461 198.543 336.711 - 198.543 339.184 c 198.543 341.137 197.191 341.996 196.066 341.996 c 195.016 - 341.996 194.117 341.285 193.668 340.797 c 193.406 341.773 192.469 341.996 - 191.941 341.996 c 191.305 341.996 190.891 341.547 190.629 341.098 c 190.293 - 340.535 190.031 339.523 190.031 339.41 c 190.031 339.223 190.254 339.223 - 190.328 339.223 c 190.555 339.223 190.555 339.262 190.668 339.711 c 190.93 - 340.684 191.266 341.512 191.906 341.512 c 192.355 341.512 192.469 341.137 - 192.469 340.684 c 192.469 340.496 192.43 340.309 192.391 340.199 c h -193.668 339.973 m 194.641 341.285 195.469 341.512 195.992 341.512 c 196.668 - 341.512 197.23 341.023 197.23 339.898 c 197.23 339.223 196.855 337.496 -196.367 336.523 c 195.918 335.699 195.129 334.91 194.266 334.91 c 193.066 - 334.91 192.766 336.184 192.766 336.371 c 192.766 336.449 192.805 336.559 - 192.805 336.637 c h -f -208.207 332.457 m 208.207 332.531 208.207 332.57 207.793 332.984 c 204.832 - 335.984 204.043 340.52 204.043 344.195 c 204.043 348.359 204.945 352.52 - 207.906 355.484 c 208.207 355.781 208.207 355.82 208.207 355.895 c 208.207 - 356.082 208.133 356.156 207.98 356.156 c 207.719 356.156 205.582 354.508 - 204.156 351.469 c 202.957 348.844 202.656 346.184 202.656 344.195 c 202.656 - 342.32 202.918 339.434 204.23 336.695 c 205.695 333.77 207.719 332.195 -207.98 332.195 c 208.133 332.195 208.207 332.27 208.207 332.457 c h -f -215.707 332.195 m 215.707 333.172 l 213.379 333.172 l 213.379 355.184 l - 215.707 355.184 l 215.707 356.156 l 212.406 356.156 l 212.406 332.195 l - h -f -230.184 347.832 m 230.449 348.094 230.449 348.133 230.449 348.207 c 230.449 - 348.359 230.336 348.508 230.148 348.508 c 229.996 348.508 229.922 348.395 - 229.773 348.207 c 224.297 342.133 l 223.324 345.172 223.137 345.77 222.609 - 347.008 c 222.348 347.57 221.824 348.77 219.723 348.77 c 218.336 348.77 - 217.699 347.531 217.699 347.195 c 217.699 347.156 217.699 346.969 217.996 - 346.969 c 218.184 346.969 218.262 347.082 218.297 347.234 c 218.637 348.133 - 219.422 348.246 219.574 348.246 c 220.285 348.246 220.996 346.406 221.41 - 345.359 c 222.16 343.484 222.949 340.707 222.949 340.633 c 222.949 340.594 - 222.949 340.559 222.762 340.371 c 217.246 334.219 l 216.984 333.957 216.984 - 333.922 216.984 333.844 c 216.984 333.695 217.137 333.547 217.246 333.547 - c 217.434 333.547 217.547 333.734 217.66 333.809 c 223.137 339.957 l 223.887 - 337.484 224.184 336.547 224.746 335.195 c 225.047 334.484 225.574 333.281 - 227.711 333.281 c 229.098 333.281 229.734 334.52 229.734 334.859 c 229.734 - 334.969 229.699 335.121 229.473 335.121 c 229.211 335.121 229.211 335.008 - 229.137 334.781 c 228.91 334.184 228.309 333.809 227.859 333.809 c 226.66 - 333.809 225.012 339.621 224.484 341.457 c h -f -234.945 338.434 m 235.395 338.434 236.742 338.473 237.645 338.773 c 238.883 - 339.223 239.105 340.012 239.105 340.496 c 239.105 341.434 238.168 341.996 - 237.043 341.996 c 235.02 341.996 232.32 340.461 232.32 337.574 c 232.32 - 335.887 233.367 334.461 235.32 334.461 c 238.168 334.461 239.48 336.109 - 239.48 336.336 c 239.48 336.449 239.332 336.637 239.18 336.637 c 239.105 - 336.637 239.07 336.598 238.918 336.449 c 237.605 334.91 235.656 334.91 -235.355 334.91 c 234.344 334.91 233.668 335.586 233.668 336.934 c 233.668 - 337.16 233.668 337.496 233.895 338.434 c h -234.008 338.887 m 234.719 341.324 236.555 341.512 237.043 341.512 c 237.758 - 341.512 238.395 341.137 238.395 340.496 c 238.395 338.887 235.543 338.887 - 234.832 338.887 c h -f -245.25 356.156 m 241.984 356.156 l 241.984 355.184 l 244.312 355.184 l -244.312 333.172 l 241.984 333.172 l 241.984 332.195 l 245.25 332.195 l h -f -260.555 350.66 m 260.816 350.66 261.23 350.66 261.23 351.035 c 261.23 351.484 - 260.816 351.484 260.555 351.484 c 250.578 351.484 l 250.316 351.484 249.906 - 351.484 249.906 351.07 c 249.906 350.66 250.281 350.66 250.578 350.66 c - h -f -268.637 357.52 m 268.637 357.973 268.637 357.973 268.148 357.973 c 267.062 - 356.922 265.562 356.922 264.887 356.922 c 264.887 356.32 l 265.262 356.32 - 266.387 356.32 267.285 356.77 c 267.285 348.258 l 267.285 347.695 267.285 - 347.473 265.637 347.473 c 265 347.473 l 265 346.871 l 265.301 346.871 267.363 - 346.945 267.961 346.945 c 268.488 346.945 270.586 346.871 270.961 346.871 - c 270.961 347.473 l 270.324 347.473 l 268.637 347.473 268.637 347.695 268.637 - 348.258 c h -f -281.688 332.457 m 281.688 332.531 281.688 332.57 281.273 332.984 c 278.312 - 335.984 277.523 340.52 277.523 344.195 c 277.523 348.359 278.426 352.52 - 281.387 355.484 c 281.688 355.781 281.688 355.82 281.688 355.895 c 281.688 - 356.082 281.613 356.156 281.461 356.156 c 281.199 356.156 279.062 354.508 - 277.637 351.469 c 276.438 348.844 276.137 346.184 276.137 344.195 c 276.137 - 342.32 276.398 339.434 277.711 336.695 c 279.176 333.77 281.199 332.195 - 281.461 332.195 c 281.613 332.195 281.688 332.27 281.688 332.457 c h -f -291.059 345.434 m 291.211 346.031 291.773 348.246 293.422 348.246 c 293.535 - 348.246 294.137 348.246 294.621 347.945 c 293.949 347.797 293.496 347.234 - 293.496 346.633 c 293.496 346.258 293.762 345.809 294.398 345.809 c 294.922 - 345.809 295.672 346.219 295.672 347.195 c 295.672 348.434 294.285 348.77 - 293.461 348.77 c 292.074 348.77 291.246 347.496 290.949 346.969 c 290.348 - 348.547 289.074 348.77 288.359 348.77 c 285.887 348.77 284.496 345.695 -284.496 345.094 c 284.496 344.832 284.762 344.832 284.797 344.832 c 284.984 - 344.832 285.059 344.906 285.098 345.094 c 285.922 347.645 287.496 348.246 - 288.324 348.246 c 288.773 348.246 289.598 348.02 289.598 346.633 c 289.598 - 345.883 289.184 344.309 288.324 340.934 c 287.949 339.469 287.086 338.457 - 286.035 338.457 c 285.887 338.457 285.359 338.457 284.836 338.758 c 285.434 - 338.906 285.961 339.395 285.961 340.07 c 285.961 340.707 285.434 340.895 - 285.098 340.895 c 284.348 340.895 283.785 340.297 283.785 339.508 c 283.785 - 338.422 284.949 337.934 285.996 337.934 c 287.609 337.934 288.473 339.621 - 288.512 339.734 c 288.809 338.871 289.672 337.934 291.098 337.934 c 293.574 - 337.934 294.922 341.008 294.922 341.609 c 294.922 341.871 294.734 341.871 - 294.66 341.871 c 294.434 341.871 294.398 341.758 294.324 341.609 c 293.535 - 339.02 291.922 338.457 291.172 338.457 c 290.234 338.457 289.859 339.207 - 289.859 340.031 c 289.859 340.559 289.973 341.082 290.234 342.133 c h -f -303.637 344.195 m 303.637 346.031 303.375 348.922 302.062 351.656 c 300.637 - 354.582 298.574 356.156 298.352 356.156 c 298.199 356.156 298.09 356.047 - 298.09 355.895 c 298.09 355.82 298.09 355.781 298.539 355.332 c 300.902 - 352.969 302.25 349.184 302.25 344.195 c 302.25 340.07 301.387 335.871 298.426 - 332.871 c 298.09 332.57 298.09 332.531 298.09 332.457 c 298.09 332.309 -298.199 332.195 298.352 332.195 c 298.574 332.195 300.75 333.844 302.137 - 336.883 c 303.375 339.508 303.637 342.172 303.637 344.195 c h -f -312.938 344.195 m 312.938 346.031 312.676 348.922 311.363 351.656 c 309.938 - 354.582 307.875 356.156 307.648 356.156 c 307.5 356.156 307.387 356.047 - 307.387 355.895 c 307.387 355.82 307.387 355.781 307.836 355.332 c 310.199 - 352.969 311.551 349.184 311.551 344.195 c 311.551 340.07 310.688 335.871 - 307.723 332.871 c 307.387 332.57 307.387 332.531 307.387 332.457 c 307.387 - 332.309 307.5 332.195 307.648 332.195 c 307.875 332.195 310.051 333.844 - 311.438 336.883 c 312.676 339.508 312.938 342.172 312.938 344.195 c h -f -322.867 354.809 m 319.641 351.547 l 320.055 351.133 l 322.867 353.57 l -325.602 351.133 l 326.016 351.547 l h -f -323.699 339.547 m 323.961 338.57 324.824 337.934 325.836 337.934 c 326.66 - 337.934 327.223 338.496 327.598 339.246 c 328.012 340.109 328.312 341.57 - 328.312 341.609 c 328.312 341.871 328.125 341.871 328.047 341.871 c 327.785 - 341.871 327.785 341.758 327.711 341.422 c 327.375 340.07 326.922 338.457 - 325.91 338.457 c 325.422 338.457 325.16 338.758 325.16 339.547 c 325.16 - 340.07 325.461 341.195 325.648 342.059 c 326.324 344.645 l 326.398 344.984 - 326.625 345.883 326.734 346.258 c 326.848 346.82 327.074 347.719 327.074 - 347.871 c 327.074 348.281 326.734 348.508 326.398 348.508 c 326.285 348.508 - 325.648 348.469 325.461 347.684 c 325.012 345.922 323.961 341.719 323.66 - 340.484 c 323.625 340.371 322.688 338.457 320.922 338.457 c 319.688 338.457 - 319.461 339.547 319.461 340.406 c 319.461 341.758 320.137 343.633 320.734 - 345.281 c 321.035 346.031 321.148 346.371 321.148 346.82 c 321.148 347.871 - 320.398 348.77 319.199 348.77 c 316.91 348.77 316.047 345.281 316.047 345.094 - c 316.047 344.832 316.273 344.832 316.312 344.832 c 316.574 344.832 316.574 - 344.906 316.688 345.281 c 317.285 347.344 318.223 348.246 319.125 348.246 - c 319.348 348.246 319.723 348.207 319.723 347.457 c 319.723 346.895 319.461 - 346.184 319.312 345.844 c 318.41 343.445 317.922 341.984 317.922 340.82 - c 317.922 338.531 319.574 337.934 320.848 337.934 c 322.422 337.934 323.285 - 339.02 323.699 339.547 c h -f -330.262 332.586 m 330.148 332.098 330.109 331.984 329.473 331.984 c 329.246 - 331.984 329.023 331.984 329.023 331.609 c 329.023 331.422 329.172 331.348 - 329.246 331.348 c 329.66 331.348 330.223 331.422 330.672 331.422 c 331.234 - 331.422 331.871 331.348 332.434 331.348 c 332.586 331.348 332.773 331.422 - 332.773 331.723 c 332.773 331.984 332.547 331.984 332.324 331.984 c 331.949 - 331.984 331.496 331.984 331.496 332.172 c 331.496 332.246 331.648 332.699 - 331.684 332.922 c 331.91 333.824 332.137 334.723 332.324 335.434 c 332.512 - 335.098 333.035 334.461 334.047 334.461 c 336.074 334.461 338.324 336.711 - 338.324 339.184 c 338.324 341.137 336.973 341.996 335.848 341.996 c 334.797 - 341.996 333.898 341.285 333.449 340.797 c 333.184 341.773 332.246 341.996 - 331.723 341.996 c 331.086 341.996 330.672 341.547 330.41 341.098 c 330.074 - 340.535 329.809 339.523 329.809 339.41 c 329.809 339.223 330.035 339.223 - 330.109 339.223 c 330.336 339.223 330.336 339.262 330.449 339.711 c 330.711 - 340.684 331.047 341.512 331.684 341.512 c 332.137 341.512 332.246 341.137 - 332.246 340.684 c 332.246 340.496 332.211 340.309 332.172 340.199 c h -333.449 339.973 m 334.422 341.285 335.246 341.512 335.773 341.512 c 336.449 - 341.512 337.012 341.023 337.012 339.898 c 337.012 339.223 336.637 337.496 - 336.148 336.523 c 335.699 335.699 334.91 334.91 334.047 334.91 c 332.848 - 334.91 332.547 336.184 332.547 336.371 c 332.547 336.449 332.586 336.559 - 332.586 336.637 c h -f -Q q -398 493.5 127 -110 re W n -q -398 493.5 127 -110 re W n -% Fallback Image: x=398 y=152 w=127 h=110 res=300ppi size=729810 -[ 0.24 0 0 0.24 398 383.34 ] concat -/DeviceRGB setcolorspace -8 dict dup begin - /ImageType 1 def - /Width 530 def - /Height 459 def - /Interpolate false def - /BitsPerComponent 8 def - /Decode [ 0 1 0 1 0 1 ] def - /DataSource currentfile /ASCII85Decode filter /FlateDecode filter def - /Interpolate false def - /ImageMatrix [ 1 0 0 -1 0 459 ] def -end -image -Gb"-6#C%6M[6Cb\74YK`=2"@bV,d!/[U`U.-!@OReSJKpEPj^&%2U_.i*LElZ>b=Z+JC(t\0 - MUk,ln(@,S1$NhrNYOrSRWXNEOSV1V9)]m:qR)qj]$0>``TBB"n"$hg+:ne]!eETZ&-rC?JNt=h#Qt3[5TgUD"9O->+:ne]!eETZ&-rC?JNt=h#Qt3[5TgU - D"9O->+:ne]!eETZ&-rC?JNt=h#Qt3[5TgUD"9O->+:ne]!eETZ&-rC?JNt=h#Qt3[5TgUD - "9O->+:ne]!eETZ&-rC?JNt=h#Qt3[5TgUD"9O->+:ne]!eETZ&-rC?JNt=h#Qt3[5TgUD" - 9O->+:ne]!eETZ&-rC?JNt=h#Qt3[5TgUD"9O->+:ne]!eETZ&-rC?JNt=h#Qt3[5TgUD"9 - O->+:ne]!eETZ&-rC?JNt=h#Qt3[5TgUD"9O->+:ne]!eETZ&-rC?@0Z]qoC9d9?SHuYhOa - n$5TgWHJd"iA`t(E4:fg`mh07aR^O5L`pPp:XqEP#O5KG&T"9ROSYa?d:qnN1.`>;nZn])` - N?U"5>F7/JaX&lJ/qUi8q?VF/;NZC2`=T]NEJNt?J&JjsAL&_,/s4stl972-bN#=EpmFjFE - p2#:Fi9BKoQ^=UNX8./B07WdjpcI8\TY8)N"9O->Y[E]+61G,4cT_4W4[!'tPGqM2KgNW9n - _DpTKL-j[+/"[u^A>u'ej'F*+:ng6_WY]c!mnbnO$341gMd,]_[k'WqlGR.#K7L$!-bfY[d - MhTLH>bn!4cA&`W5K6Q%K2D"stT@[(!O5h7NFCQXB - aD^]%e!K@p&O6m*%sE<3,%`W)^lTna[udY%o,\H%8\eS8KRUnjfHNXkgjYIsGK^]47NrQdt - <5p-^E8&/g5ir9n4il-i#@L[oT+?.\]1r7#EWMul'B$EA]nDL@N^8bfWF6NcE"G&f\X9'o8 - `W+4[$K^YOCu>_lpcI)DVR"JO#/K/>*Cb9EFqW@6F54;^E_9!eJ-:X - ?eOr]=Y\a[s(A684H(g^qdajA&mGNiskcRO[0Na"N%#Q%::fWK#1mpqU^E/(Bt'JMF8Y0)8 - Xct`YX_*<[IgJUh>djXK4F'k+"DNilsF>KM+W95p-^E/&Ec`TkB74&*%$sqU`9!kL.f,==\ - 3u^r&t%YUd2!;0([7?qmF%cVatpC:/-Gc96=8eD"oVN=:D(+:t<$/bn>-\)(k:D>!SpL"2Y - a)*GW;7"MP2iGT+#jS9P;6tT*QX:#bKB?T"(PVhgQ03O[,!"9LC0UG'>$AFP%:M=ETDJnn? - q=@CS55iMdrXg"NJNt@%"aA*C_&%F'!.=\2\%?hNMMd:Sa^hJ%L,rQo@;SJ[Es2#gC"'uui - k5UI&\AFKh4HcJUO)VY2=S@DQRcu/aI`Dg$T_jdi/@X3YQ&q-Kbl3h/(JAlD]$EM/WpGr>9dc%/*a`I'p,L@rj6QYG/F - Em;GU3in-X@-\QgjCUa$@tcl$BjK6bH-'B?(oi_o%+9OQ,9Z`JYO>]Qit!%mHX'_ufd## - !j@CXo[s<_5%K?^A-ZB+0Jn]QCXT6l06<9,UHBG$g5O=T.0k>TMgO"Jog_(Z8)9/l - b:Tq%5h\.,e729^$ALRfs3,0Y'f - lh8&ueY"CbVE`0H3-Tna,rti"YH - PB-&Yqn<4GKa'BqS3)rS@;fQ6-c836Y`RF8$/Y!Ir>o'(APab\!"UkHK#Tk`_4M8>>I/3?p - 5`m.nV\g+TI/E[@-VcP"dfgrdJ12m@h0Yu]4)5ZeaIk/DTbsU)^79e+31r&9\Z1iTBjn,6ML)I,Z=X=SKgB/lOpcUh)C- - Qs+!sbm,Dr8k6=*toCu9B1!f+;p1@nUfr=3]D5[79n^Fm,QLI&jf0uY7I&J8#CKfFSr>.Zm8(QW(YDYK:"T]$K83]pXe%qhYq`e4A3` - !uD@`r&%U,I:>b[6T=FKo0>9[U5p-`!"1'D. - U[!9ujN3XN'SSli\i_HiV<*W!4&;1uo**\V)i>PCL8[BKTV4'A%p=]='hm>C`MF-t3Xg&B$ - 8)EE+>Cmt/_N/?0gLkAQ.RVlO[pb5+@*QS+E_gLRl5,0ie]%sr:3Kk&-N&C0:9]p*)hgRs8 - Mc;c-;KD'QZ!^/0JqAn;II'glIEJNYdnR7L"dL6'(.1L$meqih,r6PBEEH2ldMAM@@r'E," - X#U=tT0g5bC$*$:UE$por`NK&q"YHQipFmDt%4n[?,?Qk%E&;[TB[J5?F@_amHkK]XGdEs] - effDDb'Bq5kD+<.11:*9aD&4X9A9Y>8)?pTBNU$)2.=;`T3lOJ&8>q"XW=L5'R"[f,c`^\m7Zs+q/95TjkGZRCH!n)!frJ,cQVr - Mllt9!).#(=n@RJukA;1QN8T+>3F:1.7*B3@"))YXOA - j%*Z9C(V/LiU#>O#oGK-V]f1c@5nCVu/,qWk>aH\W#]5TiN&ZhT,FMXeRp5CE%D-d.f-1LV - XGSDdbgo9Pr3"Uck1C:K`G2<`G:Z:#_9+;SCRQal-RdFb'iNQ<6u_[Ot6\8]Fp=X)nq;rW,&-N&C)9ef`/h+eahgK_1aq_$ZCWoOGY*KdH9kZak - Wjhs]2qj:SU.0+a#bm&;J/[^]A;fMZ+g,1BZKJMVc`'TF1W:L+V6q9mS?O=bZR%@d6R,Hq_ - '"j-a^d/7&>8TiUnlSmem5n2^$rlHhgYGS1'dr4hu^7[Jn'].c9(K:GB`r]qm5!JnbBcLME - m`'e>898CJBJj1Rd[[kScb:TEhR6=`%#`Tj]+IJ=#+4C$S)jX"h\@@#u"/OIF_a))EH"Ji!7EgBU9'+?(ObCMrG6:0,KdQ0HO@4 - 1R8b:b)m+;!QHB(6&F,H9!Rs*XeAojM9;lul8h[t#`(h3P-[lh*ZQ*[O77O=[Q/#!MefX,@ - c>''E55_9linp+=4j$A8!M`$!>%$R!Cjf(Mo1'$8@0&D.9hK;>ECGB\6Q3,mf@='gHINXUM - )N!G_=)&uZFRl>7$()@gpPEL6Lnp4eSiNd>uCN]q3C?0KW=E^dqF/^@\1k9P`'o;Z#92eMg - ?o_*>@ZYZK%.[4\e_R4(e&)"r]nB9>(doJX\@]@O%$I$Hg!eDkkg6$\rU+korqI]n#Qit20 - T.SDVASd:s8LfaF,ejE!Ja&Wpi3[)1,o+DPf,e!Y,FXIRE(2Q'Dgd)$2hLnSl9W;OKN!rBm - Q_NEd:8LI@+BSQV_,tK7nu6AnPcNp%9=cEoaX[?@rIb)$GM0!LQ:n>ZC01^A6p0M%_6&Uce - QdjbooIc*]gKXD]AURT%uodC3]*'Ej%dWV@\BjUn:=34B.IH-P - YM&B7?.0f>4nGrjAC:+-G"36EBHi7/5,a"N1MqFt+`P4M[@P^*?\iJT#.XdD;Pmrc^%pb_;N`D_qSXl.bs>_^! - =TSV(7(/J1M=uQfNnF6%t?hK5p.-hf&@(KS^\H_I'J+sG,'4Y4?&lLji$h[k1WCp)qjUU`+ - `-;/.4lUHGF+h-$U$]N'nh*GTb=iPFJ'di:H4NjK+A-)Y`;[g6bhUiY1].&=\f7#_bT.KB2 - .Uc(-rje>ZAb^%E.':<4O`KVQ@7b2B4E5Q16''bqHu[@2N"P.M8@o9mWNZ'-q%I,dapA(pm - lUZX*$$1N"XG#*ihLFZuIoJtG-?]-([PhhUp=<$6?AI3uSIL6K]:f&iqrqt6C:VZMH3u!;i - I39)EKNW]=;>'qPUQ:]n?#%SYMT9oKc.:Q>c*Ghob1n,05U7Bp=OsSE:\S5"b3tB)M"nmn9 - UH[`m"MrMM;&GZ]O^kkH)1n4i1&+^HC2ku*ZcB<+Q;;<77BXhhKe;;ZY/0DpK_;@"Cg_+(1 - ik.1%_L?KaS^&Za5YE8\+^hMruI0kj5+bkR=B^:a'g%Tiu@bC@8D\H?STsp%4&2'N - ?6QIO@[KG23m["ZgeQUh>nqtBDM84[-tPN'-P_A#$mWRFnPP;5(E@i;#\/h;_roRP/^Ed9.@q@o)2f.P"Lf! - fj]6&l`4hj77u2^,UZ:_i850nWG)<%MCjr5t9T++Eu.1'dq98rSKXN2b[Krq3HB:S-q5j'u - n];HdRTb@.I)8XUNNW$1i@R]&L_pmHuH+iH\p&Fg.j`/g*K>cU9m?o@F)ln3AgZ88EJNeH& - B5d+S+\I>2SP$V-g[:7+4CY,_;o[-1ukZYbEp3pQb#eRo(^>Pr9s7NRF?+4]WG^-_t8l!r\ - )]",0;cImDZL'DVRu/(7U5"_g)@8K#Q$>fG'*"J$.;jU5@([66=s\W,OA]JJWB5-NIq-V'P - X/n8#`m">Mo?B_6q9c!eC:R'[;'Z"n<6X35mBUt9Z&F(i0%Pso?B4T4Ru$O@A-;i@TC*Q?K - /W3\@*&O[Z`I*ZBls&WrN?lFfD+qFD36ZaEDF:5[8 - DFJ20C8(RWGiJUrBf+;6(q=M9%Rd*U.;T7.,C3&1a@Tnccu_,9lSpYC&VcCG>]+01qH]Z?4 - (ILQh?`(nJ1n;SS[NJ:_a[S)#EY#T0tUD\cq][UY(=GUapkT?nS1!%8/X[e8GCs1,mO,GLX - p[FN;b91+t?LSBD`5G?<1hl@2[5W$\K\Y69#!ikf\.$TU$nc^$s8;%ENugHQR[WO#iPG4Gl - 6]5i01iF>SWpZ.P)Y0o6'(FAjhVfQU(CBO(Y!]:.cqs-Vq1QSWpZ>j'X$-%3( - UK.oCp?NI16P]h+nf)(=r9;i6:=[Yt.NL()KL)d2C&n<*:cA.Y"u'bh>r+!3^Yb*7l)2a76 - 9j.Ci#3P69mdK_N5_HC7u^*&.Yh0\V(`pBLGHoKqBjhu:"\!&R+10[:H,N!+-L;EF<=B2p\ - M/7\(\\U1K4?JO]A^DISL(pYq)a^+bI2m(GM(&-ahH00#gG++3 - Roil-gC6:0>lU]e?7*2!(u3SbLoc(1Uj2F5R%O=>$!C=$JQZ!qjcJhaf-giBn1$ZYPI6T'; - -+;`0^:6i7-0!*lrWU5WSbOq!u,s9JM-5;*J-7Uu73%6:jqXj%,[V^Bfl)2;onk4ueLqT,^ - "@<@"."dGKeCS&WIK'.iUNTNt2heH:G^a,6c;)MJGKquS0LUo5Yn/eb!RrfCI3pZX$4r<#J - q_D9hp47mfK;t=dQYktP;Zrd4/-."A/9e_p.]1]VP^424*EaXbVNUSp!nj,@dc/V0n*R('] - Zgo^3fhOf/l&UNS-l07/ZiFTVd/54dR2cLd#;Q6e(=X)rjYAn(#SQjp7[mQS79.c&?\5RK3 - g;K3YJBVASAjiP]jVg$MY1=s'0!R&q+F."fTO111[7bu7M8f[/8pqSlt.SsBJc04L5+;dHOZ/KKHjk]I)2h/J,AWBcT_5B?!X#1[ - l:AQ/X?cPgY@+nDK\q?L6)s(]Yn;/C=$%UL0_?1'e'Qj_A(hh*)mHcT]-`>S1eeFWFM"rCG - R_M,D.d0;Pf0oK.LBDr0'o?)=_ROpMtk)EL=]]**)Hg5Q5p#lIBIpBV!mA.scoVMoRUD+,q[AZBP=ViT_ - MYr8s>bP+nFa"`>i]:Al)5MP-6-VQ,OG8*igOb1uKH+q7>Fn'8C\U==4f:`1N+p8&*BVij@EHX)QTDCj;_JLmLEeUASr%]P3a - K0(b@=!WiK3u&\_@tO=UhVi];FnSL=e:f?gu0Ocbbjs7t""eY?G?,S%b[_-/8l?1i[2V3dX - >Rf**]=RDnl^Q^iHq:Xr:of#^A.ui5pQrYfYB&\i2Crh^0FfDWR5B]$Y - s$ZV^lEdM9W)@?@[/ml?jK+C/==MloRYkL23E#Mh5`LuRn^A@,qZY.U![9BD) - a]_g4)'CS8OP##f`*r&/b`0V*q8B1i..D9tb+JgaMGUDciS#lH$RW%&E39O\N*-rI_Xi0>[ - o0>/?b(4=]C3Id(Q_8_9bRc/)[OVpob7KLg/hX0[A0KA+3: - TQJB?*(PCWt@$pA#cD185?31I0N7ZGZdI(;j6Jg5r:T2Q!1V[eAgL?iK#>++F.Xa3bHR^"4 - N_j'kEj0V)[W(=ms6q<&8Nn:5L?.@taJVp8'&ZkM(`R2_S#"n?l-pGn,06')#]lE\CN7"mj - e89f\m2\tC6:S]n%M\W^FAWY;XhnK'<:I"gWqsR$#%QpXU=FefgKs;dncTLem?!X"^Nt8;V - /b'Bab_Tpmlnil`jouuDa;mt(TL[>iMYIKD6m8]ubV,Q[kc/jI`F@u7ih/+c4^j;,MRn*)k - 15^%U/q^`'G,@jMWMc,F`RKXn - =5MXf4u?X:?k[BQl3V,FRuhX3SUK%][2c=SG8DPT.C&Ke]*N['E"qLE@NZnY555ruUP-[Gg - (g\p[s9LSng!T3h"3k']=3I'IT<\9R&3fsSUD4LYC:0LYLltr)diHp"&p@18L7 - 0Q+m!!PKK-%?O8cC"&qq,7=?jG#IL/`(nJ1+@HZ_NRTCF%=5B - $.TD*OG`9a=XbVh=&D(oroghqFMMdduET+cg5QCQ*++[)q?h?Ue;D4/R37L" - q,Dk-V>.$H2&6s%aUY*o9j6_!S7&8_[dpHq"3$2l0/CXh6>h!b22G%_R?[pM?-qGhu<>Y-L - @Nr;F0<$eiQ4gnM(3h"Nna'aVJ5efp('4G-ZZ&NG$hCJN$nSTA7fF[ - \T6f&GM[W>h01$uprd%D_GiHf+&X7tN'g^e(FBK)i>I"-WM`GB8P)'6RB9==CaWdp!,E-`: - @?ua-YhH93()4p[qgh,!.ZE="*Orn^V"P-gEWd)6VMAl-N5$oA&kK=Y[:2Z4$C@4Y8LLo!G - &eii,W'UoQM^p;.Y@#'DqWk?"q<"1=6RngnMU!-E1ITe2LTi>K@.FJLL_;gp!s8Wk5s_Sq; - F63_[PDflfL_JG_kI@7qm7>`<`+JjbmtO;KA=Sj:&a^Oa)Q-`I3NrWW(;BL.#$"1Y?8'hq< - +CMrU579LHk]f3i(2*;GkjHX!!G(1#=UQ'SFq2$8s/kj;PFi'(@^i*Yll=Oe%_>_%\a@519 - Grc73SUUOTMZ@VI=*RuBs"_fL72&9mIC[NYao#&P7j&J9d/+9'Udr6Nu$HgQeOhOmL\F?pm - L@m"6X.E6l;"Cd28$ST0>f\#ENkJqY$*/E7+!Ac2EQk - Z.)dr8fT$2Jn>.M.*lW'(Q*&e`5"Ob,g,3-@%@6e6%fGpC"<:ZlLgiM,b1B\2'>ZEDJd\Sm - rOaf;bQ'U;l.9]3gp_5N>R_mA;G/g(WB\n'u]\bjLfV:1ELK*:IQn2N@A - $oFiTIr5X]_p!A1G?E1_M^(]8?i@t%;/_u>/2' - M?4.>i@mn$J0u_N2Kq:&-bHZ-Oc@giRFuq,rcS*,8Ap$0$B?%KQPdpg%QWK!$M]25<%('P2 - ,-qh>Wl,teEGZO[22RM`kQA0dI/]9T9-/T\EJcXG2,pZB[fgK*kX1&\L3$dfI).q.Jk+qE- - _IKBXnDD]B!mhcH&8l]cq_a#?kG9o>YrqCa/k16Z'Bl.+g+YY03sfqKt'$u)$^NI'>92[NI - C]t4nHlR^]*o0.Frb2[FaVJIRJ*6e%O+]k:NuoZbS-+i2Ct:qsM'H=0=Ap-RIo1jnPL>Pf9 - =020P(U7Z<7_)Y@]+>bm5Ki#1rKgqBPq_1e8Wg)u:8-7F6M?K$WnL5Qj$55X]Q^`"l>o[7Z - -qcg'ZS8]19I&Q8#[jDH\:t0G:=?XWRh8P'U(Q@$=_>EX<+>95uhf^",Ub%R8;'UbhDG+88 - e=_<\)q>U&Vb90EgR4]k2&>1T4o2<^7MbgiKssWW-BkQ=^])>&T7$(;kC3#lhn8mXbJ3r1m - sm8D+"FsN+l2`*$`I;:QDGEF]KmYBKj;%#^YbELPXm-WWsYBr!8:#(2HWD-efudtC=&aM8n - E3U+$P)I=24U^o?TWs'i4pHkR4?QXC4Bq'ls\epDS - lBJCRR,fNLE0cpR;!Z._e>"[)6e:S"'+.C>;E63(fja-iklO,eug"&i/]J`5Z::D'[KrKtB - (0/?`VM6sF`Vs!pLld%]b%/0fQk"$h6[u$i6'>_7/#!<+Z<':'EZdYgJ2eFE@%piFLpl,/b - -Y8hc(oi>POnb)Lb$AB(TRR&BGA>sI)3^O64CDB&pWIW;kWE,dS70dAiU-$GIJ`_Fr8JN=; - 1gKT1MtQ#MAjPS%LrmA_M%1`Nra&K2Jh"W)]Qt8-RB>oK@2Vj-Y;+a6mH[a6e#5*AG6HNbN - QQEQ/V?N9QX.LoK4 - H72&mLb4d(EPF(f6cZEhoGSWpu]RbJK;o-i%!WhR+$XY[:.cP(-s`'rG#C4*=: - ?S7Rn\:tYnc:ie=[&B?'TW38j(1H]hkgA(?1?$$>.>jHQ0>+9V4NIr;#q2Ni2*3)U+XSm*o - tuR%%QP:qbfgJ@*gZSWlMc8tH[L[''JsUhghL2l[N<1.7*jj%Imp#eY+3\tB$#k9c4ekV]iE1_N+*YSTcm@PI2F+S"6l@n1!;,.jD1 - L_l/KR]nido/,/mff!rHL7q*$`cmnt[+Od_B#eRH;qrKhD9\u5?M - (km#ccjTqFQh*#:HqQR:Z:i.94F,7#+[F*mQ^^Gj0c;&5!D03G#IaC8TmT\g.@8ukX5lR_- - KkAb/a>33&"<;[j>7]+U`:VV,Mrl@nSNo99 - Z&=/PeaX<)M0i+.38*^9jp1ulQ`s^:^;t86PIkeN\dY\=jrTf2;EP$iN^,*F.o2]sV*CP,d - G/BYZ&jDsL!>#U"Uc`2eP6J>25HjmI=9-%UgQ]Z0Hk];K4lVif$Q]aXUJ`r)TTn+W,XnRC) - Zj-l+S7W4cV;=IHJp$b_c(kg;UsU4VOik)1$/;EFT/"#VJI* - 5/6i*1!E<`/ta1#&G.-Y?r@f(FPQ5srYgX/!K - \.0eR.fJ>'\YTPJJ9HkWqh;*gFi1eBrcq__,Jkaba$?ep:K/ItY<+a@1KEp.[@thRSQ:TiL - D"#PgbXcLX-bNSoc^kSM8otYbG&ZCJ/h%"[jeG>,k2bU-g.=SrWep3n6TZ`PM1MAc=qij/-RJEsV::8XmE8!=+3+[nVabe?EMpsGTVu;s)]Pf31tg>b7MOj^_\I%/8hbH9U3p[4B7R - gSSEfD)LECu4hPL=1L08@3W.Wh@QLTYm`R([BE0n%NgLeZ)8g**uVPkiC8V_^4g.=;(%#Z# - .0/\g:CVrmVP6![4iLG.LJt1U1Lu0QS2^KT;Fo]BqPt(i%Q\# - 0Mtp[p[lj'+#Rd\`H-+pQ>4fBat[D)VZ.Ql)O69?WO%%X?%JJ - :!$CJ`O='Jg45W$=ELL)VEL5?[UW!_fPlaR+hLWt"?&>$>)^?+Qi`_)\rJ.3O&Kf=el27dZuc_LtKo-fkKY5?LW. - PsG*2-aE>pC\1l79UuqgT7ZGgXQ&>`a3;+KhB2aN%@O4-"-kZ$2tuO`USar':l,C!4@RlGOOCZSt9iD:P`3_sR??07I?H:.hZ%B=:4&SWp - J!^l@VNlSAuf+jV`K,)R:NIZ6_F;sqp(n0N3?mqC%U'B;#eCHGi2A4eLM%L:)@cfVpqh^L%6"ZgGI9[d-_aqOVI* - mV1T!`C:.5TG#Ig/PV5dL5D=8Y:)O-mW[Fso0[(Kl&grCcrPG'`q?O(E(+2a4U?+t\(gGBlW<_P5uhr2kh[^HAC"L-TOactf7L9RP'"[/3mHYoJJL@,JD, - /@T3j1//B:UU(R3Hat!W^rWo/0kRB-2bV?n`-MSIFa,CO=Y;kXf0ImdrXj+Xk9N033[:X!V - c$=Hga[$8n,8n'(^`ReS$>l!mu5*b(C6_KICS;+^0pBq8Fe.L5!/*)G.iLgi66?4E5eHQXQ - @Q?=)KnA&jsR)O(a2Va(,OT4fq51oNeEO/K(8d81%0@_eO\jH2rICMS?HIG'B(q9$'M0eJ1 - -:InpU0fphH9Ft?cG#GIV\s[YU:t2^LoNnN@RMeO.i^,,]eeem8OPMS9VU9^s) - #05"&eG`kZtn8GCt!>7==(q:gN<;al(XmrFuq,R:DK`TStFAQ*:9P,-Zl(P3SCB/GrLU!6ZV)eu2_a7UbLM5+j9\1mn03st+iG3E'=^,*Wp?Ypudr5FlKehT#^]koG5G-J$MT9r4M=m - CM6T]aM]Q"QF;8\Ge/glNO*Fe*bQ09k,Ot2h`\m*[u9_13M5O7[Nm[RtbFi@`k>Oha$1 - ?;]mTdReW8,#.6NbQl+V!W6"B;,_i^9=Oa8ljB>92#DsGN%9PrTk9U[n\F>[#PQu<#G0NA/ - C%pe:7iBt.,pjr[3,jC]e"D`!\@6211l]mm1mF[U]gkp(g_\mj\63c<(G8sk<#WtV)1K`a6 - ul^DWk*LV)QkQm&HatlCK?Xn7T(7a)V0sP(WqS+G&G2bB1`sd\Ra6:G"8p`bFhS)Za1>"1` - QN@Z3HjTLf$bY?dL5(BH?Y0\6j1sp[@"3R[VCC3;>h3=0R$`94XrYmZGLhoFFtkQ][gW<@^ - nqYY!%u<9P@i8PX0oPrA#P[E2/!kKAK61d(d)*#<^kgU:sGo#W72CX^)Z.;QaNarmtuHAV` - &:/M3L45;9p?]]7-n)(d'ZaI2@+sH7V@:=^l4$;DEau6BXT21En7,RYeKqUf55fi89(e"n' - "AhJY4_\pOq*Mn!lXGRX'@p\BKB2[N=BJ[Miku/7%SjNiQtXr6(D/0Lj4TY#PQ;XGgcM2.( - LD>p_hJVoTqT]+6QkN,U-.uOid*5f@"(6[676MQ@1bA%Cu=PTd;uiRD0i]oDHM]Fib,_j_u - AHZQY3EkWXBE\D`>Z,GeA_<(I%E2,KAFohL5-(S>J"FYW?@2D:2>egq/V3rYVRU2?9s'3-k - (*77@B]Yks'1@;b9sNI0(^n#0Gg?)ZR4bdF5E<,#0`L@C(bH&3neeb6O - A6$qp[,/476HGN]S8B?Do5%q#lj,\]f,IVMl;p&kmS$8HF(9_Ri->OJ;l - >>[f^Z%YLJH@g@>Gh(j=geqr3`Q;^0$5I@3I8\/R`+-k@s+Ng]S]NZH-F^Lfc37]6&P1MDAQe!-]4H0K+USLM72N@.mDHJXW3]OQ^N'0YJ)V!FSSMK+]5uu&hR*npQX0960;$ - Nh^^]*o0iRYmKE:`5:qsM)"['WdT0Gkls-/(+-EHI';oEXsRrX<9RMn\LWYh(bBEBL_q<@D - U@?1\Y.="I&h>2b"D_fC0qoVAt^CfsTGRa-O8Q"p3imF\:EGDn`5J=AmI)&-XI@L,@42bl# - U;d'AgbCJ=Vfd0H!gjM^OT6T?%+H@[:Nke,9>p>X)I:JNg$PN?>U."F*diAt+O(RKdao29IfdA.<%Q@\TP\Rf^`_H - O"a+&k8N&fET"Y`Z'$BTX"thAN]tej$3FocYhOJEVf=lPq,o_-RU^,K.#T&prX4b6X#PDFd - 6IU^ej^*Mkm<1NM;.j@cjq)s!083iOt=g,ZApL38$FUTpink_/onBoD*UdFVhK#fGu27L;% - cPQj?G4)MFU]3?ps1E+e//69=r%M_EL-"-QB915:O<"pYC:?G1[Ym+H71[aipYalN`]$nC' - KbCr5rlC-8f\0f]*,VM - .%X.oU[_K"JM.R:gqrrV?'JYt`.(i5-C#Ns8HB749)N6j%>$51(M6%(PP`A&=hrk9Jc_Xm^bC>nb"@qnL]ZJ544(R]rm>qlMKlr@@QoY - fG)X^&V;Z^6!lj:J8CF&,kTiVC38dHsUp.[@/@[gq.L*!%$^_o2)00h$^c1mhoS:H\0c - @uicroB+::2f8V,>e+n:il-g@)/%6b!QmBAil&*3`ss+NZt7FHk2p987`.n\?to1lngp.Kn - 'i*:c5sG_%DKYE\kf[\*[083VDLDsWsVi>55p>[Gm5aGc"oZTmdaAUI5"nZ!^c - %1WLNSZUW7!,C[B8[]K.1G<\o\8,ca.9155aof-Vp_ - Vp/>!0Zh"^0-k5At!AY82$;-eH+.;G[.LY;XC`d.2`Y:<\:82NEDXbeOtGPojGR4XQ>bc0I - U??=jXW'gaB1ouV_Z\F=s.=JTU;peu")OE*aV@j@'C^Lf7UIUB^f&GW(KDYE3hm[O]!tRMu - @`=32'.16$]/,W\O\?=JUoI[ciac%5/eL-AUPKUAC0%7erPC7#>ptc;#o6,B$?>$k`Ua]_H - 1H"=RBjV-K/O0u7^I1!:2JBu"B`Y^`^C99H4#g'ruX<.eJ^!&k11T+)/ - Wqh#9SE4f>;`Om3fl:]ja!@'^QeoB#do`(D4jfp_Vaa?:n9E)bE - +'1h"]Y+h%:`9qSMfW];gM=$qXs0=%Sj9`?3dAM:Jn1o\H]:XrV,3aIJ`_/Z;cCI%@m+AR_j2QY$JWuB5[cpP)Eg7o]e:7=4['$] - OoNeYX..fCpnp(o"TW$gOd=/)P,hne:`0Df@[2Uq!XuVd^=>2gCXt_p*S3DAtKaS])h4V5k - (t6=+9uGPdOfkDPShcFD0QdiU'.RB!ie0qM)N\rTfs522OsLbh:A"$0n5?-VZ`]0aQJ@nh) - AC@81JlS?MAR21T"6.:2gX5_#gk`^U\1hnq=F5bXUNPKU!G$L8u3IbCnS7O^g_n4)KpdFXC - 8\pMJbXi9FYWG%23J9Yf<7tHh=CZhgP7`Mmp3839h.]DA7QsL3-<_OI^5c\&D%b6k%M - R\CA>du;:KR#!.K]?4QI;H\H(nsJe - \D8eHK/L6dQcG:tVgD+1e`YcU&ehGYo: - @IbK9,g9c+5MK?05ZYM7Ra-m5TE2'5nV/'/R)8W=OGXJjQC1&4$_bjFk+^7Y&ei4@^XR>)? - gOH@r6tV0+>a#1d+gr*T]jfDXs,Om`De^L=l<@=^[,EIVmruhXID[=ohi%$edF6#Ib;(&I6 - eSQ?sJaAR.hH;DB1\W'`%\\j89K+r^EIl3h[(u9gr.nDlIi2ePq2]VrC#_Rl>7lZ=HODD69.k(Gk:m[]]0L7-gjMa0;L>:5Ts0-u(_fo - N\CeW=L3\ET+UPl&+^hDn!h_n2SBe"k)-^@,n_Dq/TRZ@$?Fa)@cpT*)\M^dZ"^fTW9#"$1 - ;J_A':/iCY#TOmd?*pNFfH!Ec^u@`)R&e3)F;_=4hens$h/,;M3q2n4ffT7o@/1U@!2F:n! - hZWW\Ea,ZF-]p=lS)Y\@IY:Q-\"HD7..i-hN4BgAD$\kRfL2"5b4eejN,7dSh_2r.l1V)+Z - \7nF[7GAQ'En]j5b/1W67aiFcGDNo9DZDqY.C-V-G/W.:.WVq7 - nOe-Cio^!U&a*cNc-qn/2hI5ke1/fdiCgNb/,*[4?9cYbQjp8>cnLc)RO5"j`5Tk@: - d54%EF-)XMIRhL_?0*5]-[,'HCqI - I':)#pL)EdjT#s2-$24Q)+cBLa5q?b)pPFE9'Wg.:.XSUIaamocnn?U?^auX_4(o;jpRt_# - sq#srfD@ku1`i="&,n?e3:3baGbsmY_OhBR56f^Li"%?$ZfI'[?sR9:.6"Yc - ijn3`'K4>qPl#n3A/"+K9/)eT2og^Z=WFW[Cs8eM2@)Uel?HV9NaX@Sp^FMc41rGJ55*CA) - ]N`24Q5oY?-uA8s66nL+e/ujG>)H#\d5brXZP-kZ6o/)`Xs=!`^07.6C - 56IZRg:t0I,R!#)HEDhT`/g+JR_V&q8/rW4BDY_]p%mL/%*a[/KB?kI1dkIYOA"1ITJ4mI^ - U3D6gV_XSuo]!Bp*1%KPX7mPf+`ljCX,PS0d?BT;m^]6tXXuXtS4O\_^H#dTQECZXaB - s/?jWpVoP7Z&)j?79PJBs\j4K&&V_SD5BhhjJ!?a\D^mWaj0RKp(3$^H`oDZ!t\IO$61CBi - $iMdAF`W#KPjR>C_tr9Uo$aKfFmg.X`Co^&a>$2e:&NVGF6P9&ppLCm[/"?9pl.=DX@r&$L - OnG@>I%7X*oKAH/"Md/m@3Z:0M=)LPk;;hWs[%)]@N\q`f3_j;pm%89g1*jKQ*DW@=9mjNf - HNL6(MGaDk5aJDU`Y(LdXT#*n5MD39n>QbPM1-Qn%d&X1F4q;uCTY>K;/p!CDXYQ2aN-JO6 - H1U11n%QE=Z-eq]Pq(9H].M0c%C;'4IFkL9Ed\A1.fjS:qFnM.(l$#WH_iK5Aea2D#d45E# - !1)_nDH%1-WXiXWjK.?^hZ^0i$5[E:c^SEC"O$Qc`*95#C#1S=&i+G*)m"_eN$CG*6ck]]f - RjQ.$mOeR%8c/2S&IUA)4_=!s8X>Bk]+23R:Es'Lrl4::hUMWsi#G6IZRi"Pr6Gdn - GG"6AMi:XR+g)1>S';Ma(K\M>GbRsm-Tmd@f#b8/Ye%5)gXfVUCsi-8#9'KET6#JFuEDJr' - gNpC6dI1IJ!ZqZEP7F.+e-$d"U?0 - "7BRqc5bYb$c>;99nYjr]jl\ig=f8(?GQh7.9`hh2M'MXiES)2S;KCJd/,fdS`?e,#Q;#e= - ^._haJmW*oB]N,E8l5C,t??K?rlsrI`Xs$^2"6*#(88,l - 4ZD(!TI7H&7B55IMc?m=b.j6^T3XF6Cif2@ZS%M!5+fimG_)8V'Z - 22QH2ePjVj?(.I4"^dSd&Db2a&GFk(^h(=J$X3=Jbp",\!L'&D`oj/N/L;K?eVnUa0pp:p_ - =6&J9Qe+!,+LGtI'.qH)&ck?k)dr7-GQT4Vc*;[s#VTba+1Ch_8]dT4R>K'#TLSP$._fQ^j - Ln9BdFk)Eg1P141R)G])XpWZ]=*:)UVoSSG="4OP;CiW-O%EbE`n3]NrW:tZV84=NS"#2JC - tc$s/+/bHmRgOT)XP]q9UK4^9nS@0+h^T[6ld7M_n*(>3*=@DNToK#:TN]e - r]<(E5Kdk.f^79d07("K/^00@RY@@:CE*`%bM\.aXSEa6J%K]?d3^:&ofb!GJ!A4kp9ri4C>;g'8'X_,hP&uNTl='"YT$-08\dI#PP(e_sCC-W"0dG-7(PZASkdaZThFMr[ - #t4^Xp*cucC7P92SgM=,rkmdVj5CGYD::2@K4CC*j1lLIN(=r\#!g@,X/MhH3j%BcO`Tb2\ - (J9,c'gMSFVW)A-_AVp._7a8C#=0?Y3NW"'rppb?r%rLG#O^_0+>b`d<;6037F?M1ap;-WP - ibfi@u22&(btn':O8P>8t5f-JC:aEPOIAa2dD#KB$Y\CXPM>omk2"Wgg[V7];XI+)`:TO-elD>kJI2=miOgB?TNe'U4I/3>fL'A_AK:W5R_q%hFm.Mi - o4LAN52)`#s94I*oW+Pno4RX[/StXu#=-+DNhh!\km9$W#]TV-#*Z,_"Y9)5k!W,+qD&TW6 - @%2mlJKo.G7CgXrWmOAu6l.ki/p@^LElttn^V;uj23hl]"g:T - LurjNK5sAmMPoM;5I\(&-rf'QHt#<>-`To^FO_+J^+ko6m>rMruD[>oV8gbI.f2_E.$:pl(CePN-19#;oFpA7l4C^[ - B9Sj@'.U0/Whie4"XR=TVSAO+u)dMWNF[SF]J+W1hY^0pKlC<>15\S/0K))Yu>/F`5%At8K - 0EJ"3ASYr^j+*c@rd^NbG.2X.uEl?:iU_)YAJtCt!?H=>B%o-BSsIjH+I#PK8a6jYA-&f', - pV7`ob6aB,HF0k833It)qpETjL)K&jA3DI`"r\]cOa/Ze!kOUH/ - A>pp4U2e^\0o^mf<$+>#SgGJ-mi7Opc)R+A46.G"bON:.#=0YBYAm&3'QH7[]?U&o2m**[I - J\]&SFSI]5:#[T/c1.4-9l'KIhh$AHWVmM[C':901&_7,+elc=/kc9'fri%:*B;%1IlhXUL - 8SIL7R9<@m+M"l\?Rq$r!_bLK8Hgo!5RPfUC/GG7akCY#TOl04% - cO(Yr)dcdd5ReMlcP@9D;-Yd1+%*g.eHk\HXBCoK5.\<7tMu\Sp1qGMOjtWWb\?/8ZI,bXh - 1kL@4iLSE+Bu$cA[;!G5O5?`7>=@'&.;[IP-.qFgat2j.@hLeC]$lJdkOEcS_4/3%uM5'lpH2N>'HK*j@>kh0@8&?f%rB&!i'8 - _a1.9!+Z)[C^MAt+O(CnJF9K2i/s2@W`>_p7f>1VE1q;c-GWb'hYYihW?&R+(m - brt;V'?!6YS??Qd6oHIDhj:AN2/(H08kO\ZML1hI$+iN?dr7I/a;oGja@EV?U+78\\m4O-b - &l&t&Vo5S8u'eD1%:BLYN!S^%Zdhk:dA^Y"jktZP]S2mBtBjETj6r$ldV50n(Z`]0:oUGhfT&# - _7[`+r'kfeVn^gT55@k=DR6qO?.Rssu4J;8F0\kN(`VXANeJLP@1'QU$J$#^0uVP1IL`&8& - -"WO"5fk%`.Qb(rm_dM'WhK@FU2)R5uKgE.rCQg+-qo!`F/4^cZTJS1=^ef1.M%YGE0V,/9 - 5u@_op@.)sj^,&=`1;.?IA/lopD6YUVe1(_Vn^&6<`)`A_[euUV+nkG1_"9M(an7e*KEA?8 - Y:*lCL))/4nj&AG"+qj15SA2?0*S2Ql'XjQ)K[/-YhF&MAk/b-u*/FMS?,k"oWGZKL^8Xi[ - 4l:%1an?k?0&dB[^(rGVSR0@(/%'Rg)kUV,&qHj!iKo`uAiZF;U4_3DOeX.$7`W\n^9FN=- - LQJ/oHiaob%0K0ihJ]U>$&Q:*1#nh^GEo:97]jf36i'mdS\N0+JXFjWa]*<0lDiJ/Z - 8>b5]XPH_Zn3Dof>'-dm.l-=i=`kM;7`F-dr^=0r;csl`)7(QIOI8.@!M;d\4"MMY&;6M!r - #l#Ocb@5qZ=\lb(U/PMlM1*:!h;H$NQ9clMX+74%dadu*d>8e9U8WXZ - *j%qjJho7%jbgV$RC4o?R)>YR5TkTT*SWC^D%NZ=E4m8cSIhP;U9%YcKJbGW-TdXe:=)8MAd>f(WrZ3QW& - '/En8I5p^'7Fq7].oC;0m)mq>K-5FJc],:kAS?4)+M#40U52@W26R+!kt]0^>_5VQVu3*<` - /15XeDe"'T2atb8`bH.c,cCLGoRk#2Y*"bgX_Ve,V0lST1^Ksno5`-K6%MUe?;9ZURdBG.) - HuVbZ>?&Imi!<_G1pqh-QVWR<=,=K*7gcf)81">*@*Aa]5taiY]I^.$)O(_,*)E76,_eC]=+oH0.A?,ALGN>PGuK_7=L5CnnkasY_X2i0o?lE*O$2jg7)GpGH/)--F#HSUmaNg-[%G1j>7ba4OW_B^rlcc4(23HdkhWe!dEWXSTM) - .jL1ZJ6mWjc8`W9F/g6?Uel@EXKe1]DL97KX;H+=\Ug%UplFC.;QtdaY^re?R4,OsMM1HVr - /Vf62XNAQLMbTc])HGc=P3!^GUscM8\AH-j`suS"*Q0jJ#8,kL>Numf)4'Rj)jTcX;8r,?- - `kR[\g(kam_%]\"g(:Pg/""7E=f3K>?ab2Lp0Y'@-ZYiVeKP5JRF26P7HlbC;d\gZQsR;d_ - Sd)k;_:3`JPC)9hi@9^(9eqG0Ld%WWQR.l,3N'p - bAk+WSi`n8::"TZ:/=YuRI9-*=]bDo].\@bCDSN'YUm9rU.2T#,C&^h9XGlpT!TZIE-?Woo - ^J6RJC&+i*P=5E%KS>q8ogCACrR!5!DfkaGXm+8C45)WJhpUUMrlA9gli4>jXkX8>h"4sV" - 7:5XG[gAf;c?Z>1G.P4T#WCW(K]UiQ9+u%E'+$1i[J.3im4)`C1uKqrM#5\dG`l:JXdK;K0 - gjC3G!^2%*=b=`Q$/FQNGBcD6W2XS\+3E4LO]VP/+)=5-[6T+Da6$1:l - f\7ra^)Rc)qXKeV#A62k_J'noCV_L=6(CuD2;O,>\r)ZlWMIG!7*_mW[E)Q!QojHK&W/tS]&hAd,/'c<86'0AU/.YHgM)M - uC"A92qPo420:aAtV_26g.IE$_`6W*5Recb@R8G&_9t;V`QJ8\?N'9N.&:dY]Wsrh5TN - h%ST_eNhXNhd<2U>l?7$dSOo5$On$tQiH_eRl!S^ZDlJa;Uq1_`)mTRl9r\o,_\L!*)TZ8. - M^]L!LDp]02/QE4j50\O#:XgESTUX=n*2SgN61J8PJtuod7`pip*\B< - p4PIG."]DiX.bWJq]EOlje[eFM_gcISUe3NR;Rc?aoTb7]dn9hN:e"Cf%CstY.-+FW/s4Z# - 7MNZ&KFh(PFmW?JiGA+BfQK_.*lRGb&QM4p-@p@pJcg*;>CtFL^h(C3moN\DL'tAX2Ect[Z - /ZU2?9I!S`gM4j]m,7"1*2EpA"Jog_*E&ejkOlep/5)ts1<^5TIU\(f9=rL\Zbm6!Z@fELZ - :t^S9)h`%^:pfr,,T(AB[ab2)@0Qb.S7\EXfM(,\TP$Tba$7.Dr/-Cfs:JNHBh+A>a/XD;h - lf0nK7:o$3!7V$:E=Ih`O2?7IQMakmuiU/5=7;=Y8l!d=O1(rkg;uW_eQn`4(^#CtUEmtPjgT8UMRG<% - Yr;BCRDph%\8AXl\$;?UfNkEaQ3X:ci!W>[&'O?s/ROZ=].'f[^78EoE7A%DJMfL7PS.gOJ - ;Fpe_L@?b1^uR=6B!X8STKg(>rCV`-S"?tYqFXq6uKlQMCFZdelC8NeT/3j\XEgMI%M6el, - '7q6'c)>?.@4^U8ZI`]rGdR6.Lil8>)+m%pLVsCAb&c36Fo^WAi;1,s02%arkspZ7;m,5@n - SCcE*D=`Q8fU9])CbM]GRK@Y]EqB*VpDH$:_l1@aJ5[^K'p3;n)Z[8"Q+M[6b*+D_:`-QQf - %.!))7/-Ha=`7g=H'.)^;bU.)ccEa@H!W-h-MC#5sYOPFV - S_U"&m\_f4WH;J"f - H28WuM_\me8J,u**T=hg/4[A7Gj_/[I)7KQ*omLceRGfc*pYZ##BM!3SMN4FaPRg*=Q@?mX - @MaYj=Ub!gSF8*kcU3.1r*I$ChG@P-X\$n;;KcIP(EmJQ]S9A`)$TtY3if+*T?K,)DOG4[k[k_kK2BDiG(>'!U-Qa/gbNP<9kQlU14 - Gs872\5Hq`/nI_LT@e1Y,GOmec=)kq210"EcPijt(pL(Re=jbj%'laKO!I.UaE%*?r%c3dp - nIQc.KK\iSW_d3obKeZ4]R!#sXO:DZ`E^sVF`B)ghoB+;^Fd7`;#KtOVCgE=`(T6YVVZ/h2 - "aN89,I0]6WKPt0=bV&FUc!nIr0TH(6PZ-I*@Dc8G$^.:KJ@G&N14fW&/:F=qE, - I'1L-)NVTl\tU\<_FpWT<+ - @>R^"R+"!Rhjn;1"sjn^;t$I7(ZGY"2UCuX:?^hoQAA;;mte:qpORYDlfR:14MdHf^MlkSK - HY]\A[eE%=o5B - BQ));!M-QZp(mE%?Ugn5BX5J-/,sCI(`SMO':`62NnM!4fGVCi2)`I5pabU1\0oP1B"hHT$ - )Id/b?k3A81(JY"\.Yl0*#;XX0o'i^,A!jM_ZK-RF!^D>k%,6T="u+ - s=QR4F_lnik(7I\@/&1[@gmtBVW$t2%XS - gZOQ!`-eu"!N+pb*$eWUKl')@?4\]3oT9okOH5U+Oub[g92;cAlJ,4Y6p@\(jh&G%\i7,54 - b7l>j!WOb\XE&YoDSZ#\sK3HO?, - SNFFAm;BJB8Be3Aj!-2LmS - pKbNY*RXdri4@r,Pq1b&WWckt-[0ZtdXA*DALb8kL9SFNg@A5;b<`q)>.AUA,&2?0A^m+ie - QD-sr/(Xtd-mQo&Lilruq>9`p0a,+K.O:-.SO3O:?iKO6@4FVT+WSDH]K@`8[$(R1/K0^V@ - G04(0@T?f>V'Zl&kKmmkdMXA-$@Fuk1DH'+@q[:?O*t4i>\9@7CGT'__Bs?m\fVX4=)-B&d - YY68(BO,2#7,HhYcX`#iL'H56JBO94YH4gY21bQ"68:\a;q&+W_!W]i`n3fAhL&=j_'*Gr> - T@QToK'LmdkpQ=$K2'E:)p-p%Z]#/7]acj@9mI4F=/1:->Uhs4klA&aJr7@VG*C%Q'/9^Hm - -fp?9)T/f'\G5`Y_56X;Iqb^lbLhUB>ZjXDJkt*SaiI1lsR+NeoJ]3f*#q(.dLc>qTD,f3; - <2-#t+<830@88sl]bqYtL&bbM2LcG.\ri,Y5r\0)n:+q>_T,D%$pMde>S9+H!4SsEfbX[a%u6[c(\hf>f` - '4M=H=8[R+inm"8"m!oqKcF&]@A)$.d`Pii]Hl294\Ga?hK - j5Z=D&UK7_p^o,_U_^Zq=E(`dNTn\8`Qd1F64$$#M1M.1C@-d*'V!rn)A1&99q,[#Ef+'=,Z$k)S*Dh`23Po(kf. - %(+^jb/1`G-YGeDPY[Kn/@jAprfWGcO,ged=OAD"^]?"R7,+"h%U/!sd?.S,d*-lgT19(?X - 70ZFi4f83@=uh?2QF8ch&pUVT_-et`fs:qO+u2:b%j'`,hmmeUk.qWt#3E_\TbP&MTgQ-a# - Wl6Zqc:h:3B5tg:J[e)`9O<[:tR<2%$'T@afkJ&dVIUlb - 7T3?>N]!+S+_/FJqrs]/4VcZW30:X-BD?W,R\83Kb=3//F/Rrj]_fS2,$D]'&4$I/q2[`AV - pe\h1e8VQjsj1'gaV9`ses;)LBr40`'7K"+2biG]QSBJFUb[8k]_-s;cb.3'VX61a-0)Ihf - FI!g<-6%O]S,J][#,AL5.Y1L]Zgt^U%/f#e[N](#[C`5H"4`L#>4?*J>U1ugci.IC%7hCB! - 3p:P9BUr?C:hI.nm9@OFjg&S1BDM)cmV[$GQo]A)>?fk1V+Uml!k>^uAj]8GLseYs]KQtfV - L0n@ACcQ6%Q9==oQ5>P?u6g$5DXLbg`[pRmV]X'$oF()M7u92P"+aEB<+EJTM1eA5!Qc0qf - Zt\=Kl064CiVWFKA`X;I#mmS*'!G65F`u>^fg@3a5%DJ@'50r:\6KQ"6>9?%lP-O%Yp!Hmj]6GKIdEkLets#p('[&-B@Ahbn=Y#k+WeH^3.e(o0B(8ek`DmJ - iehb&di@rSna>i5WiE'fM\aR-3AVs-A]0B:#(p@MeudF+f[Jg5t$-& - Zm%*H@r.M,hcZEa1T&IGa;al'uG#_B4n,eM'6-CG(g3r%_%+DX36cPOXi/.E3iPLh^W8Q%b - AlJP98rpX2rHDXFIml[s-T8D5jM6ii$;opWkB0?$?dJWt4'(ikeQ_9r#80).HKeH3s`+[^J - *aqEiPd2@Tf:Jk(G'8OJ8+-QlWX/",O]b`Bp`<_7J9g9k_JPUTPLJL)Gk1;5Gkr=?0DqI&+ - 05!:8C-%r[?,U=Z-p\.UU#&RGoeC5aMgfIj2Q(+A^G(g4]0"M=DOqbHSD3\4fbGI:%2i$u% - 388[GZ==V3UX#8`7pH_M@Ps.jNir9\2HLuB>MceFL^2Uk$HT^i$Yu+ - +i^.$LMfp,+"_"@\&%ldi>HYK/ThEoA_HWKBlW.KVPr_[CEa!@^0mib;[\r-V(7c1<8_@,] - 7^>\55/2Q@hoLhqu2PYE-)*5cdRYe(Dtii50o+;)ect2Jr+( - cDFHG?dIC^k\;$!2:rJd@NHLTF@Tif+ZWaQRH@VWA4_&lq49`r*e4*-)#llHjP:eT3,!c2q - T%DDX:g5^]=Y\PVC">b=r_9Dj(reF9\allW:@1f8'YPTeXW'm12V]\GV9XM*Zbe-'V6N,Y$ - b>[J4C*ZIjuot`(LCI-YUso&5Srr3+QX%BUT$4%C=a3rMU)2$7+(?P50)/%[nIU$`d547o) - oV@q0"H;Na#n"@ZIk=/IfZ.)_dr>?c+EP[M+U9k3%mH(7S2!Y$nJ"VL(+A]r$X#iRAh1_@T - HBGV.kZW6M)N@51K-Q2Md26uH#fjoB(WDM^s - 8Mt5RR8hp:03UD.BLrqOaHTU_;2_Ic^6FSU:GT33H]deearB/3!OV3F)4T^Z@bjR6:/2ZU. - s\(GMe+0%CgKAc_&PL^=B6r>p63PJnRGsclr+bJjEU?%2e%q;6I8'39MB-<`l33,.FDF,sO - V$Wk#\i0e7#3d9IBGJ_]C(R2@p#_5=JH`]D2`I)8G2_E=fWGcO"q4djK+0k - bm+Jm-jDh"W^(=+a-b.fd#/u*!8!&9i`GCfu'8@.rXP5lKY - CLWeuUgi6rYM^C^c55X\&GiXDPLT[M - *2@TfZ,$KYPBF"HIi;oNKNNB34GoNDY=9ZRX'ioUY,.G;#4t\H_b`@O<%*Yjrhf'/XE]ph4 - s5EmC#nAj&:iNpNc>4D+D0f]m@*=m83G94 - "ICqYK0`#,?Ic&H@("JDV^bEOs16g/L"TFb2h7u00nLc`)bAG3@N%dVD3T"I(5EdC`;+$Pi - T,uB[]3XDkU>oi:ek(`WH`6^tJc7],e22<163J0*\18Oe4(-DN<b:/2:X?(?(?D!!Ht0pOtjMo)1J[eaZT`9:U[VNIC= - %+gDQ=30)PBV7YhVb!J32@Td,4K&gONfFTH2;WT<%C&X11Z8l]k"o0B/&1khP)A&Gf%.^T6 - F5@h$&?X[3,32=`ShdN%_]<@`X.3)%Q9<(M@*hAJ7eu3VSVE2SP;nR9`mZc#n"(mr'D_,Oh - r?;9Uf:qYY&/fj4(&,EH-!)B$FMa@`=?J4(+Q`;#n]LHfXJB>^b;2AV#D`]TpBFLm^5sj?# - 04Bm&Y,+a9l'p#c\rVFRmL%BJ"dkPlnoq$CicJ3\apC!\t%4D%tB*'jchb(G`-ZY+?B&KDe - 7q8\cm=/Wn9UUhj@0Xc%fgPf`JRpBjZYs6\;FO2nSp-]Npc?'p$:5am - <13K*YrD3]0EFV+ps,%D=WS3r]q#PN@eAC^pR*Ye"D6rg,'@O0]Q%j5Q\k9^9k7HVV@e;iE - 3gA\Tl?M?@.[CWj?_^gpf'n0i8XF@(URDqUGB5B]W'sXZr3q4[.**XQU]?(%pXO:TC - j;?lg:R"uGhe!P`_rK\sIi[sXZMR>P5\NbQt>EX^7N#?R%g`6.&?\b`aOgEoU - ]+CX@;pWk6\g47Guh;8QD1Mr6Tm)^e0/3J@W1tjbt`.r?0)X#G=(KCRWB-mN,SJ>0o7RhD' - 9MJ6(eg&c[c..%*g',W11`Eoc&J/b"?PJRGe_St4(T6E9RKMuK9U!T*J,auZ2@UsXE1ELdO - ?n\uC;>o]WlAhX^#lE2\kD#WnA>dU""m][5jXV+KS-DJeZlZ2F)uD/?65&D]Tj_g1cd^Ec* - 98W*"'/T7rlK\*GcWC.4K3r31C+7'qe8'6$s2?2;fhj5PCFMH3jf7SND%]Pa#]hAAGOGbeb - @j'tKt=U2&3.eVR<:Y",X*F*2V+%\b!@p?c(oE+)!s!,pu'(ulu6PWtInKiLaRfaZuD@2AP - >Y$&(8/s'bq&G+gndm+Hd^tD[%6)O1.jGH^,E(E%7%idRE2HT'fj=5)Nc3f?Dk3?MhA\l4! - Hpt3[&3W3n8aga8%f*6pgk&C%,?^Ljc";TlN&D+J)-1De%[i40md=si2.4Y+4`UeA\bb$fC - W"'-`THFt8\kd<1)hh]H@9`RZs1X>1I=PlfJI3aQiSCk2@Td,DR_2:c5,ORKk&#T%AIUQ#U - A#-?0m\(DrjesOUI:HD/HCcF7mm^>L')P%He*<07/2)*e[a0=d$PE_5;5PrV'[5Hs+mp61W - rIdm+IO77e^\Nm]!])Z)>;,8.0LNGa - @@4oKNHGp=%l03:(L-\D2HTqI%F - 2lD\KaiJ%Q9<,NXeXM#0DKrRg,2aLQh0S!!g@).0LO"\3!pV9K6D[&]]ZqRMu"alB50XXs- - q;/'$M[HOC/f//AU@*9I6"iln?$:ZYtm'l5B2kCb3BX:(PeRX3u3#phJ=Op@mC%ES[.Rl>9 - FoFulcBljrIQX4u0*$5Y13$@*`S[3?m'tNUuX&Isg.rl_Vi.7^tQV')92]H3RKpR6IX'sWg - a/n!7ekcU@7V-/mq=Ec`*aH^^61Ws@HE+*L9tVuADU>83+@@1:_?&!YiqRK`j@P]_eX]_$' - &d4KEh->nBQJliOtoABo6)lOD[U)bO+-0"\ - ":S(0Zj^9TZAZQlY,*uIn1cAERBP9q19G@l86=L"/eW-[l59)1o-^>r\!Ze9Zi-@Sq9r#G: - ?Lk875Qa<"#1^Rf=BNX-[mrkU8N'WTiF&.UF&idZ,1gCIF]LK_S#]0h7pfW\eu`/sNup"^L - Fj]Xb)56hB80K/or@3;7AY[AQSBg6##;%1Rtfu:_seGA#(lU_WeCPH/R^b%GO?FZb8WBXKE - 55]7kV8##A<.k'tHr*X%QVVSppNMcH7;;OUKL`;l#T03 - L=(GCM!/7[-OJVLM]1fgba.B:BPs7oH\SjEu16XDb?\7t&D\LNB1Ps_jf3X>spO\;er=t4P - Y31?;)k005<(X>uk2*%H!f4-%FB@;QopZam][)e>E"_%kZ\BY2-X9:'[^!@J`e - %0Z3$g^Q;D1fp$KEXZ&kF^jHGD/CjW0"+rcHujF[j/?[S.it>Mo>7d'M:j+C3S61.O!"DG1 - XE#(C!\IVKnY5NC4q7nTP>U*&%a>?t2XW6iOb$$f=F*/$(al_liQ,@0SFXe@dc.1S'gI - k14`THGTP9D8i`6nm'1gKZaiQ/#j%1$sXBiJ/86St^XVErrOk2k]EWaWBkdADI;^5[*3$9[NI1I_SFe\5Wp8IHibCT]9C* - (l[#K5g&2>eR&5Vm3K]3B:4VNo4U:N2j.jB78%IOhN)lZYAd_]c2P_Y$Ia5X(dM32i]tN)& - X;/BHYCC!f#9E*h1'aVG*CU?=)LJZ;f7!c - Tl72U6H/Z7h+;MF:R]Ebq%_%n-_t,dFEb;YG4'_m'k&Cdg.\HBrk3DcS-3]EKY\>Xo\eNG] - Qj;ej)A$RQg,+V#^pUW*mG+\14*N;L#(d78[VXV@WlE($J#r.cPm`A)MHjf2iPjsE/M/RMq - >($hrk+N6C)WW`^$8/V:p7rW\5\\T45+5U2]$,3=F,:>A8E/>m0[PKS1ND2)B-cSBgkHZW# - >psZm[OZk'kB*9#.Cnej2DG*3>D-Smu&03@$+q74X/ak3B$e&FF.HCKnGrZ-?n@XW/*d>\: - qFn')d!'tNFebmoZ@Z/7&`/I`C0_Da(Xma@uKk.umhJD,$&>=hDCGf+di<_!]h(K+./\0(: - /0k40&7i1-GZ#XgZECh[9lK7B5E(F$jEl,)2s8E``<_,&K2]:uB_A78i)nJ1QB3(!$#^3Fd - eCN3V2@TpKgpLi-aajDK;/J`j"\JuN$mB#s(2)k>$ObK*9tPB.CZY&!F7l]=Y''']g$NssY - fbl?OVD'IPVEk&Ebg/(0JY5M[:t.H55t?;`2:AZ.s/t35ue$H5.D0"WX[r(385"]TP>Uj&- - @=OioApn9q,*(cs>VWV'9!JEXYW_o`GF/eCE(q,UA0\\Y6::fa[!-I_;?DZM1alq$'\o:m? - T,,<%Ot:6B)!6KL*7\=dePal@sMZ@/Yi#VsK3Eoi1W)DF'a3Mttm6YrpnQBd*)aHa,QW+`? - jgY9>ObEgZ-<3[V`L>Q^Ga4-V#8enlM(QL7TmsPe#_9gum%&ZbBK=b^DJ."tKK3W)+4G=nF - Qi?u5;)R8l>iT6U+WTd9X2?>5fj%gVQ%KiQa]LP5*^$rBa,\9*-VH9t&+`S$1ogD+GsanX. - Xs-2+uu$uBuJ'4+$4Y)[;!uM31ZWbJVLg3K2i@=cp6,HOp4e.?-: - =47+Hg[]O&X&2sBaEF*/$(R>P8#arsoMldEr'g=f_0<$XA'2[:05B1/kL@WoX3((U+U8[G. - NN]%>C6T@_\HA]t"]4KI,kpZc*)8pE5G.V&;ImOt1+PPdJ3,!c2$AXN$lH64K1)7>14RbU- - 8VoiVFgE67;L$;N1C%bcDY^'\Ts5(cNV)l8kF[6qfJJhoVVs':mVI2A]G^@TnIPiN*Vc2Bp - r9:&G':<[A!5Lg(b<+G8>C..5mJ,7QPI&135jtE+<4WT0"#_]MHjoX3-!r2]Tn*W3]];_;cqPEm^b8do-P31Vf&WS=WonDOm)'QC! - r%j2ApUjlY]+=''TgF\+c!apSI%%Y[pnI@I9Q[rQS7GJb5`Cp#rG+_^<;oX])O]Ijla[c'o - raGD-,fBDB+$ObG,VLa#3"S!@IgpeN-7V?A3Q=GeN?84/hj=PMkTl5!pB3#MN,$,R27o)q, - `f1p-NufkgZ!I[1fmafj`&dUII#IdBk_:Uqq`)#0Y)T'i+]>XTf - AXMC$aZfpZ7`K"&Yg@_)@6]VTT>U;K<1q9o&+315`jqr=17IZ[.Sr)!^mn+dh.dif4bY"B7W!!Z>$;i'&p2&_:J - ]S_5fkH.(m()'SI7L4gY:[)4tJ7D[rRiE0b[&.m[7DM%4fKin';=Y)9@ - 8ubficUNc[,fRKn&gVEq'm0b99e^'FRt@1[s_'#m0R&%*BLElnb27qMZf]5S1Pk3AM.SX#J - *@WQ[Ed4Z\(A3ik#rI@u1:0Tl9ZY;6S2KC\b#W,f?1gII>`9A]R5t&X?YE4hWQ[e,"E4F,Q - X1!$sCp$Nd6ZmHm#k:BD)C8QI_W#FCRjZ^W*B<#V3B]TQI$fK\+Q;;^JoBB][Uh>b.q:'nrEZV.IJp"bD5U]TpBL8 - t'28?:`H"!\eKc.+g)LY,k&XiPY<>hrOk'e:8@D/CtgMTs[G(1UT]`3P0)4Ah - 6qE1nso3cEII7>#L`hc-f01q5e\ac[tJFBi4Hme7lV+@?9(k3C!J*s^b$=HU4Fs*f4gqmb#M3i;3!>^cFAXH48(S&U[A;bioHWN][% - 3h$=AH,%L`7!Y((1NkWXl%634)dJghO";tii;?lEl@,gI7IJZ_A:L(9+s'/Po&\'HY?tpZ)TpeL3h)^M1E*g7\_J2<(Dj"0*J - biZcsk4d1#/.XP*2R0Qu8`\<*/.lZuWZmXtEc9Wj?`qe^[5Ll@AK<%kk1' - =mE=Ol9#]lS`l7(;]6/*.>B[`>4I6.,9i1A?XhEqiba8lBs=@?=t>cdnF.YP^qMHjoXODM) - F=ZKG_j=4lHhV6esA]pBr'.8Yb1FUC,Fk)lP5LcAN\*/Al[VuJ@7R9<@Hua?f%2*>&Z"^#3 - VfQ2p/M0]o*J,ET:^!B9r<-L.eE,V[&.Z,m=5M)n9655g'tKK.NZC3)9Udrb@^0n8di.A@[ - V4/Lc.03.7qt=@CXXsUNU?-#Ou`9-@a60=EB,?GmchctU&YrO$A*,HP8aiX - #Y8\7;\Rg']J7TB2Yg$5$,k;5p>#]YZ0r^>6jAOr5?BM;%\U$b9a-nl$Ume>'U/F=8p._]2Vn)Z0LU - 2U"<\C]Y+-3gDgq%W$SP@"5]0`dIDg?W=\*kXH6&#O]Ku9\1e_,gbL!A00L#]t""#VqnnaZ - -Y7IGtbTY,,U[:]j]W^^UrBM5#96+1Xb#/QElD&NQ0a%rA6ZI7L:&qV7D"l4l"M3Z!7MHkk - [e`EnQ5]:RZ@q4QOZ"(b1glRo=RFPe_::Y8F^Ac+LW3IMI9d;,;WkZ:jPYST"cut*u2@[.L - 'uGeBo*j=>7:3+ta`7On^_nDM.MgUCg+A;Cu2[YTIXj[h(oW - u&3V#*/1cs0/H#kj7!/,S0=eV?,RXUJ6@@VbpD&Lig:X#9aB4Ra\01P:'$@"5sLQm>n"Wh1 - \4_k3?2?Y.U#eE`ETQ=N,"[D6D.n^B#LDnO;t`:ZONQY(!p+m(AH-Ig;H4B4iS_RkpOgMEJ - DmC)V%>;)Of2R_4(G+:-tqS=CSqZ\@p^_Lr41'c#U):mt3E>K$r)P)$Kn(tb+c.)njaZ2(+%nei_?e(bf(2m]")C[*an,YqH#0DM(2@YfSf=77RLodNnmHs;t - ^3:+kEK.J'CIUdJ[m-)e\/TP"CZV4'%^*@R9LZ+Ak3CI=_<&_j\,uriV+[/0KS8j>ebtK&V - F6`!=/*8%m/$5Q_%'CJQ'IUG!@b9fO?C$fRg&nR/?208:QN!R)?`?2+Lt85o&\'.rOMPd]5 - VFtY0L)/_Dj)IjJoG)E'X`ZNioOfTe2o7_1P&b$Rl%71dhm-C - ji:@d?62@\4($<\L;&T9f,3o7S^&-R!(j>sEW1qftf3':9)X2<#qbuPGDT^pLbgKRTT',ql - @d9M*AE5A-)]!MDg*$l-?%#T)0C!;r!j4(&,OuS)Ctn9jQhc_W!mKL8CRFifMG.ND\^XqE5i9ln[SK?=GX45]kZVG3PCPEWtCgorbBcGoAnc - ?s-`a=L'FC`5BZmY$Weo&)!6)K+ZQn(_1j*(3`>"J1nl9:T;Wl'@h - Vc^qY-Ub*B;W+Z"/3:u8ob&-R!(j>sCbIIrZ25F;B5/fZ>jEg8I_QaCdPBatbt;!fCr!Bg3 - 1Xf\^.=]o3&DIBu(r7"9DeKN:A\8WVhUGNK6g,/G:=3.BGJfmDpELg.:faPWDDgsC#+>4^Y - 4P!c.<9/XMYSF^oR]B@;LL`h+RB<2L#E:en6quV4NfK.qoB2#H\H\7-SX%<=i4oBgf=?'Y> - &5*0!t>B!L+Xo(.@b,u-RX9<6[97)_P+Ob=.tmHXN6[3EcCho#WbMRK>\d+3!-;!l_#eWI= - 9;)/JBXT=]/0siS\MnS@*(@eZM_H2)*BB&77bES^tZp6>q?+O/#u?PZQp<=uk5m>\@(I[N_ - (#a4[,(f797BR7R#?R$\oAar$M?Fqf4,A9g^anmili=YKd - (oZ>2)Q[--ZdP_B?ckKP/R45`HHrWH:h\Z6<"BsnH%R)<)a;DVGnWK#*#(?R\$)l(uep/Je - :Jm:[8b)-*=-:\fa6@CTBE?KjLc^E?YeVdY3fshI)58u/*?C=j9k# - Vn5tW9&iV_Uj%h9LJ!Y*PSTqYg98d9nB!%fcSU2%KRU&'LnH/Z9nZ&2fJc.-NWSBP#rTS$ta` - "CHjid=fneua0$AW.\Y%fHlfBNpeH!6F?5mPdILc_P_Yai63]ZWkNW"0jT%X@sKF - YV8$$>uEB.n#j2Jdb$)#u_i&4$,O3*&Afa6f0=GYFn>d^!oTb3@BQLPLZ&+TL5Qh62F?%Gmf%S6\UeX(07\S%Q[f_Jdt\F$ebWU5idQMkQU;q8d=N@7=,ct5_CnbEbj> - lS=W'/@E[R.rc]1j<<"reK=Xj(GnG7S6Xb%Y);u,WEk000WLJME*CMtS'Sq-U^l.[tli=YK - cu>-K@K]2u*XsjN^cXT.+NB263KSrjS@u2(KCQDo_.IrKY27pC59ui>ij5\BmuSAXWg'O[;4BMG( - :bJq0:GPfBr_/_EP1O-Q/_0#aq/[*b\q&*'k.LJ?V@>%A]kDg$^WMR?;XQs?!Z:=f_F*/Nt'a<6kEl_&02e9WCB?HL:9C3c=de"'ikg5+"+Bp2! - ?'MNjmkkMeL/URlK - "k,&gs)Ce\gFr'P4`9Y3@,`VtRp?[A#_:p'V,:M%O\#^R4q/L%5#HJl<"[kQ2 - ]$%:lL&7=urh^?->WRM.S)OJY>mbK.T+g[Z*BSEQbZ."AA:Td^+ZF8l,`Vsq77@u - MAb"d!0[>K(ipH3.%k<6"iMmm!J"-m-3:-\hT^kDDrE\Xe_HTD]8;P)R#,i0"$sGU/c:thX - 1u+OkqN'-pO20VcHO&JT+UBiba:++`pft@MjiEQ/9he?YV5VqFs))sAu-VdE@)RoF&TY0q`r4jeJQ`ZB+ - P1XOWPN&?spNjo;9oKK[BdQA)t^nDnl7Zbl6JuEa$j=*&;4<3a5%*%TY[4S/#_X-[5C]/g! - )??A*N22qT#/LAEYr0#O)fcpi_,"WC"9k,hjs7+HPO_$<,QTb%>E#aC5N*CaG,H2R3Qa_1[ - S@5aVHoCHAr6K+"?%[l!">*MZ9*Ko+WOQ_=Q#RbqJo=Mf`n0^&T6.=_SP2W*""1W@2L8Z"% - OF$[7+UBh7-s$`k(joAf?;1Y-&.Y2Sf%o0Lnn?nZ\m"WcE6q8`SZnjB!TQD,&#(1G6s.Or< - %hp@6&KJMqHI8]F::!VCY,_GWc@+@&PlaS"@5/0$G@Rt5a7Y'aGpQL*-Ssm(VfaaE#+HqMQ - Ilhg-I'erc/fU5)=e]6H"Jo(IToILdqHNo6oZA7,-G7cl;BTh5W]Yea1l37*&Ql@M*$N@:^&!d_EqQSqbXs;6O^FL6]5]L3, - q9t2dUq*K'?>;=3:.&#p`d.MDrj%i8TW+biY3O:O14?a%A&%uWBdp$:3mGps:-;9?qD-cI1oZd1h - YmNXO%M)-XRfpI_=0_2mTp=ihMK*sU>!WofHg#DS=eMi0A5Ah6;8Hp3pKGDlE<^*I6:hWNg - ,7>\2S6jPRK1g]@82>_aIIDOBN<.?]T">+2JuGQY]3G3L^A6o\F9e.q+mK7.8.;9BdA'4bK - :@gK;c50:E.iq!?+P,Lhm$iKUKTWfZpR_T=:ntQJeJMm0=VS2V.=8S;LNtAi_9[h)kK.k#_ - K!E1?7lS='s>q'M=*>pJ-IK^]*o0F`hin_1Mdtk8oH%)Xl"dBJ^VT9UGh[/dfW>k;u*h>dF*<%l0$_kW@qm,,Qb]F!JFs*YEKGm$F?OHYmGrE=%r)uH\&*7.*qi!Mm:_"Hf - U?`'Zrh$Yb2r/sR=D]anLe7fF"1pGqn`F>gHW_u`_K>Je,*E55dKoglR8]APLLuFY1\9idq - S!ujsq!>?54EK'c"OTV29FUZ29i"Q_mlDE17*1OlmJ4derc.8T/[O,(%rO<$Q/r-tHm8!lU - N%;i_q9GTKHiH9pr+%Vr-u"&2>E>Lr(#:8J6^I;Ba6.1XFc84]S'oqnDV:G?-.Xj7P_oZX<2l_dH&E5mtlXghl%sP# - KPk\C-]hJ;E11\#NqFnVBb(alk*e#![Rq7L,4Sp*>2B4[F - \_0mn-1VWu@^CE6FOGqU`LUpV0c[AN'?9R2JO@K*oY;T8[&<_o`9UCi&Hbn%C(ULMm]%/qq - 3>G5P#&k"CSfUf*"piDtcnH^=h#&VQ#N=V&i4g?H+$TG.f. - tg7h=/U1jL(F]G_jP[=b(k#el%SS3"U%+:8P)M4<+GRadI^^A2:t0HbY,cP:m5DkA - Ta5m@B-NEIV4@DRO!jBZb1Opj1'.>-\:W+:;Ojd2ThrqVNm2]uG:Qdd_c'i2/bI"I[n.NC\ - MDG5Z<`2\R>B["ZCK7?4H3/5>LV-H!EaG4!0p$[5(4^ES>RR0ed`1L)StD"Z[s=@5h"WJ0<3%&F6CWVge^@<6Sd"2F&RSdiuc - &2iX:j,O$uEO"-'LuqW\T@p]F(,`ufeYqtBELrq**S62.)XPL2$J,61-JV.tDQ - FPP"#82IRl#AJ#,daBmekG^EF<[*:SksZ0%)3pJPU2#2iOE\ep+Yu:#"r_T$$7+Ya%mG7$S - Tg)84mJEanCt93<*h>YE4gBODUY=fDOr=;3;DdhX/+4cn=6Bh6+oMpA:T4cs-LLujbke+f\ - P@hM:fFk/O22H4aoiQ$6U4l - SV+?_k.r]/],$AF*9`<&=:0-[A6P1*@*FG^8@[r:1'rU579Z_.24p?^J6C.*^lJ+o1cU^!S - 4h\aAZ[RC?ZXSDOL"*)MM/Ke7W:ZW4R#m<4'/Ul%1NbX - P8ZFprEUa-\8^L,UN*oh6N%n/fkd!.?cI@@"@8,8Keq6jVl*)M'H:`@\ok'g^Rn/6gg:\g> - VasOL==3>F2BYTlr_U`S>S[b";rIU:/A,d% -Q -Q Q -showpage -%%Trailer -end restore -%%EOF diff --git a/docs/developer-guide/library-design/img/overview.png b/docs/developer-guide/library-design/img/overview.png deleted file mode 100644 index bc9d5ae1da95e648953d9a6e21b79a2b99527a00..0000000000000000000000000000000000000000 Binary files a/docs/developer-guide/library-design/img/overview.png and /dev/null differ diff --git a/docs/developer-guide/library-design/library-design.tex b/docs/developer-guide/library-design/library-design.tex deleted file mode 100644 index 2c3bd76969a2543241f046de8494db8abd2d1717..0000000000000000000000000000000000000000 --- a/docs/developer-guide/library-design/library-design.tex +++ /dev/null @@ -1,628 +0,0 @@ -\chapter{Library Design} - -A major challenge which arises when one aims to develop a software package that -implements the spectral/hp element method is to implement the mathematical -structure of the method in a digestible and coherent matter. Obviously, there -are many ways to encapsulate the fundamental concepts related to the -spectral/$hp$ element method, depending on e.g. the intended goal of the -developer or the chosen programming language. We will (without going in too much -detail) give a an overview of how we have chosen to abstract and implement -spectral/hp elements in the \nekpp library. However, we want to emphasise that -this is not the only possible choice. - -Five different sublibraries, employing this characteristic pattern, are provided -in the full \nekpp library: - -\begin{itemize} -\item the supporting utilities sublibrary (LibUtilities library) -\item the standard elemental region sublibrary (StdRegions library) -\item the parametric mapping sublibrary (SpatialDomains library) -\item the local elemental region sublibrary (LocalRegions library) -\item the global region sublibrary (MultiRegions library) -\item the solver support sublibrary (SolverUtils library) -\end{itemize} - -This structure can also be related to the formulation of a global spectral/hp -element expansion, i.e. - -\begin{align*} - u(\boldsymbol{x})=\overbrace{\sum_{e\in\mathcal{E}}\underbrace{\sum_{n\in\mathcal{N}}\phi^e_n(\boldsymbol{x})\hat{u}^e_n}_{\mbox{\scriptsize{LocalRegions - library}}}}^{\mbox{\scriptsize{MultiRegions - library}}}=\sum_{e\in\mathcal{E}}\underbrace{\sum_{n\in\mathcal{N}}\phi^{std}_n\overbrace{(\left[\chi^e\right]^{-1}(\boldsymbol{x}))}^{\mbox{\scriptsize{SpatialDomains - library}}}\hat{u}^e_n}_{\mbox{\scriptsize{StdRegions library}}} -\end{align*} - -A more detailed overview of the \nekpp structure is given in -Figure~\ref{f:library:structure}. A diagram showing the most important classes -in the core sub-libraries, is depicted in the Figure~\ref{f:library:overview}. - -\begin{figure} -\centering -\includegraphics[width=0.6\textwidth]{library-design/img/architecture} -\caption{Structural overview of the Nektar++ libraries} -\label{f:library:structure} -\end{figure} - -\begin{figure} -\centering -\includegraphics[width=\textwidth]{img/overview.png} -\caption{Diagram of the important classes in each library.} -\label{f:library:overview} -\end{figure} - -\section{LibUtilities} - -This contains the underlying building blocks for constructing a spectral element -formulation including linear algebra, polynomial routines and memory management -\cite{Ga39,AbSt64,CaHuYoQu88,GhOs70,KaSh05}. This includes: -\begin{itemize} -\setlength{\itemsep}{0em} -\item Basic Constants -\item Basic Utilities ( Nektar++ Arrays) -\item Expression Templates -\item Foundations -\item Interpreter -\item Kernel -\item Linear Algebra -\item Memory Management -\item Nodal Data -\item Polynomial Subroutines -\item Time Integration -\end{itemize} - -\subsection{The Polylib library} -These are routines for orthogonal polynomial calculus and interpolation based on -codes by Einar Ronquist and Ron Henderson. - -\subsubsection{Abbreviations} -\begin{tabular}{ll} -\toprule -Character(s) & Description \\ -\midrule -z & Set of collocation/quadrature points \\ -w & Set of quadrature weights \\ -D & Derivative matrix \\ -h & Lagrange Interpolant \\ -I & Interpolation matrix \\ -g & Gauss \\ -k & Kronrod \\ -gr & Gauss-Radau \\ -gl & Gauss-Lobatto \\ -j & Jacobi \\ -m & point at minus 1 in Radau rules \\ -p & point at plus 1 in Radau rules \\ -\bottomrule -\end{tabular} - - -\subsubsection{Main routines} -\begin{tabular}{ll} -\toprule -\multicolumn{2}{l}{\textbf{Points and Weights}} \\ -Routine & Description \\ -\midrule -zwgj & Compute Gauss-Jacobi points and weights \\ -zwgrjm & Compute Gauss-Radau-Jacobi points and weights (z=-1) \\ -zwgrjp & Compute Gauss-Radau-Jacobi points and weights (z= 1) \\ -zwglj & Compute Gauss-Lobatto-Jacobi points and weights \\ -zwgk & Compute Gauss-Kronrod-Jacobi points and weights \\ -zwrk & Compute Radau-Kronrod points and weights \\ -zwlk & Compute Lobatto-Kronrod points and weights \\ -JacZeros & Compute Gauss-Jacobi points and weights \\ -\bottomrule -\end{tabular} - -\begin{tabular}{ll} -\toprule -\multicolumn{2}{l}{\textbf{Derivative Matrices}} \\ -Routine & Description \\ -\midrule -Dgj & Compute Gauss-Jacobi derivative matrix \\ -Dgrjm & Compute Gauss-Radau-Jacobi derivative matrix (z=-1) \\ -Dgrjp & Compute Gauss-Radau-Jacobi derivative matrix (z= 1) \\ -Dglj & Compute Gauss-Lobatto-Jacobi derivative matrix \\ -\bottomrule -\end{tabular} - -\begin{tabular}{ll} -\toprule -\multicolumn{2}{l}{\textbf{Lagrange Interpolants}} \\ -Routine & Description \\ -\midrule -hgj & Compute Gauss-Jacobi Lagrange interpolants \\ -hgrjm & Compute Gauss-Radau-Jacobi Lagrange interpolants (z=-1) \\ -hgrjp & Compute Gauss-Radau-Jacobi Lagrange interpolants (z= 1) \\ -hglj & Compute Gauss-Lobatto-Jacobi Lagrange interpolants \\ -\bottomrule -\end{tabular} - -\begin{tabular}{ll} -\toprule -\multicolumn{2}{l}{\textbf{Interpolation Operators}} \\ -Routine & Description \\ -\midrule -Imgj & Compute interpolation operator gj->m \\ -Imgrjm & Compute interpolation operator grj->m (z=-1) \\ -Imgrjp & Compute interpolation operator grj->m (z= 1) \\ -Imglj & Compute interpolation operator glj->m \\ -\bottomrule -\end{tabular} - -\begin{tabular}{ll} -\toprule -\multicolumn{2}{l}{\textbf{Polynomial Evaluation}} \\ -Routine & Description \\ -\midrule -jacobfd & Returns value and derivative of Jacobi poly. at point z \\ -jacobd & Returns derivative of Jacobi poly. at point z (valid at z=-1,1) \\ -\bottomrule -\end{tabular} - -\subsubsection{Local routines} -\begin{tabular}{ll} -\toprule -Routine & Description \\ -\midrule -jacobz & Returns Jacobi polynomial zeros \\ -gammaf & Gamma function for integer values and halves \\ -RecCoeff & Calculates the recurrence coefficients for orthogonal poly \\ -TriQL & QL algorithm for symmetrix tridiagonal matrix \\ -JKMatrix & Generates the Jacobi-Kronrod matrix \\ -\bottomrule -\end{tabular} - -\subsubsection{Notes} -\begin{itemize} -\setlength{\itemsep}{0em} -\item Legendre polynomial $\alpha = \beta = 0$ -\item Chebychev polynomial $\alpha = \beta = -0.5$ -\item All routines are double precision. -\item All array subscripts start from zero, i.e. vector $0..N-1$ -\end{itemize} - - - -\section{StdRegions} -The StdRegions library, a summary of which is shown in -Figure~\ref{f:library:stdregions}, bundles all classes that mimic a -spectral/$hp$ element expansion on a standard region. Such an expansion, i.e. -\begin{align*} -u(\boldsymbol{\xi}_i) = - \sum_{n\in\mathcal{N}}\phi_n(\boldsymbol{\xi}_i)\hat{u}_n, -\end{align*} -can be encapsulated in a class that essentially should only contain three data -structures, respectively representing: - -\begin{itemize} -\item the coefficient vector $\hat{\boldsymbol{u}}$, -\item the discrete basis matrix $\boldsymbol{B}$, and -\item the vector $\boldsymbol{u}$ which represents the value of the expansion -at the quadrature points $\boldsymbol{\xi}_i$. -\end{itemize} - -All standard expansions, independent of the dimensionality or shape of the -standard region, can be abstracted in a similar way. Therefore, it is possible -to define these data structures in an \emph{abstract} base class, i.e. the class -!StdExpansion. This base class can also contain the implementation of methods -that are identical across all shapes. Derived from this base class is another -level of abstraction, i.e. the abstract classes StdExpansion1D, StdExpansion2D -and StdExpansion3D. All other shape-specific classes (such as e.g. StdSegExp or -StdQuadExp) are inherited from these abstract base classes. These shape-specific -classes are the classes from which objects will be instantiated. -They also contain the shape-specific implementation for operations such as -integration or differentiation. - -\begin{figure} -\centering -\includegraphics[width=\textwidth]{img/StdRegions.png} -\caption{Main classes in the StdRegions library.} -\label{f:library:stdregions} -\end{figure} - -\section{SpatialDomains} -The most important family of classes in the SpatialDomains library is the -Geometry family, as can also be seen in Figure~\ref{f:library:spatialdomains}. -These classes are the representation of a (geometric) element in \emph{physical -space}. It has been indicated before that every local element can be considered -as an image of the standard element where the corresponding one-to-one mapping -can be represented as an elemental standard spectral/hp expansion. As such, a -proper encapsulation should at least contain data structures that represent such -an expansion in order to completely define the geometry of the element. -Therefore, we have equipped the classes in the Geometry family with the -following data structures: - -\begin{itemize} -\item an object of !StdExpansion class, and -\item a data structure that contains the metric terms (Jacobian, derivative - metrics) of the transformation. -\end{itemize} - -Note that although the latter data structure is not necessary to define the -geometry, it contains information inherent to the iso-parametric representation -of the element that can later be used in e.g. the LocalRegions library. Again, -the StdExpansion object can be defined in the abstract base class Geometry. -However, for every shape-specific geometry class, it needs to be initialised -according to the corresponding StdRegions class (e.g. for the QuadGeom class, -it needs to be initialised as an StdQuadExp object). - -\begin{figure} -\centering -\includegraphics{img/SpatialDomains.png} -\caption{Main classes in the SpatialDomains library.} -\label{f:library:spatialdomains} -\end{figure} - - -\section{LocalRegions} -The LocalRegions library is designed to encompass all classes that encapsulate -the elemental spectral/hp expansions in physical space, see also the figure -below. It can be appreciated that such a local expansion essentially is a -standard expansion that has a (in C++ parlance) additional coordinate -transformation that maps the standard element to the local element. In an -object-oriented context, these is-a and has-a relationships can be applied as -follows: the classes in the !LocalRegions library are derived from the -{!StdExpansion} class tree but they are supplied with an additional data member -representing the geometry of the local element. Depending on the shape-specific -class in the !LocalRegions library, this additional data member is an object of -the corresponding class in the Geometry class structure. This inheritance -between the !LocalRegions and !StdRegions library also allows for a localised -implementation that prevents code duplication. In order to e.g. evaluate the -integral over a local element, the integrand can be multiplied by the Jacobian -of the coordinate transformation, where after the evaluation is redirected to -the !StdRegions implementation. - -This provides extensions of the spectral element formulation into the world. It -provides spatially local forms of the reference space expansions through a -one-to-one linear mapping from a standard straight-sided region to the physical -space, based on the vertices. - -\subsection{Local Mappings} - -\subsubsection{Linear Mappings} -In one dimension this has the form -\begin{align*} -x = \chi(\xi) = \frac{1-\xi}{2}x_{e-1} + \frac{1+\xi}{2}x_e \quad \xi -\Omega^e -\end{align*} - -In two dimensions, for a quadrilateral, each coordinate is given by -\begin{align*} -x_i = \chi(\xi_1,\xi_2) &= x_i^A\frac{1-\xi_1}{2}\frac{1-\xi_2}{2} + -x_i^B\frac{1+\xi_1}{2}\frac{1-\xi_2}{2} \\ &\qquad+ -x_i^D\frac{1-\xi_1}{2}\frac{1+\xi_2}{2} + -x_i^C\frac{1+\xi_1}{2}\frac{1+\xi_2}{2}, \quad i=1,2 -\end{align*} - -\subsubsection{Curvilinear mappings} - -The mapping can be extended to curved-sided regions through the use of an -iso-parametric representation. In contrast to the linear mapping, where only -information about the vertices of the element were required, a curvilinear -mapping requires information about the shape of each side. This is provided by -shape functions, $f^A(\xi_1), f^B(\xi_2), f^C(\xi_1)$ and -$f^D(\xi_2)$, in the local coordinate system. For example, the linear -blending function is given by -\begin{align*} - x_i = \chi_i(\xi_1,\xi_2) &= f^A(\xi_1)\frac{1-\xi_2}{2} + - f^C(\xi_1)\frac{1+\xi_2}{2} + f^B(\xi_2)\frac{1-\xi_1}{2} + - f^D(\xi_2)\frac{1+\xi_1}{2}\\ &\qquad- - \frac{1-\xi_1}{2}\frac{1-\xi_2}{2}f^A(-1) - - \frac{1+\xi_1}{2}\frac{1-\xi_2}{2}f^A(1)\\ &\qquad- - \frac{1-\xi_1}{2}\frac{1+\xi_2}{2}f^C(-1) - - \frac{1+\xi_1}{2}\frac{1+\xi_2}{2}f^C(1) -\end{align*} - -\subsection{Classes} -All local expansions are derived from the top level Expansion base class. Three -classes, Expansion1D, Expansion2D and Expansion3D, are derived from this and -provided base classes for expansions in one-, two- and three- dimensions, -respectively. The various local expansions are derived from these. The class -hierarchy is shown in Figure~\ref{f:library:localregions}. - -One dimension: -\begin{itemize} -\item SegExp - Line expansion, local version of StdRegions::StdSegExp. -\end{itemize} - -Two dimensions: -\begin{itemize} -\item TriExp - Triangular expansion. -\item QuadExp - Quadrilateral expansion. -\end{itemize} - -Three dimensions: -\begin{itemize} -\item TetExp - Tetrehedral expansion. (All triangular faces) -\item HexExp - Hexahedral expansion. (All rectangular faces) -\item PrismExp - Prism expansion. (Two triangular, three rectangular faces) -\item PyrExp - Pyramid expansion. (One rectangular, four triangular faces) -\end{itemize} - -Other classes: -\begin{itemize} -\item PointExp -\item LinSys -\item MatrixKey -\end{itemize} - -\begin{figure} -\centering -\includegraphics[width=\textwidth]{img/LocalRegions.png} -\caption{Main classes in the LocalRegions library.} -\label{f:library:localregions} -\end{figure} - -\section{Collections} -The Collections library contains optimised approaches to performing finite -element operations on multiple elements. Typically, the geometric information is -handled separately to the core reference operator, allowing the reference -operator to be applied to elements stored in contiguous blocks of memory. While -this does not necessarily reduce the operation count, data transfer from -memory to CPU is often substantially reduced and the contiguous storage -structures enable more efficient access, thereby reducing runtime. - -\subsection{Structure} -The top-level container is the \texttt{Collection} class, which manages one or -more LocalRegions objects of the same type (shape and basis). The -\texttt{Operator} class generically describes an operation of these elements. -Derived classes from \texttt{Operator} are created for each specific operation -(e.g. BwdTrans, IProductWRTBase) on each element type. A factory pattern is used -to instantiate the correct class using the key triple (shape, operator, impl). -All classes relating to a particular operator are collated in a single .cpp -file. - -An example template for a specific \texttt{Operator} class is as follows: -\begin{lstlisting}[style=C++Style] -class [[NAME]] : public Operator -{ - public: - OPERATOR_CREATE([[NAME]]) - - virtual ~[[NAME]]() - { - } - - virtual void operator()( - const Array &input, - Array &output, - Array &output1, - Array &output2, - Array &wsp) - { - [[IMPLEMENTATION]] - } - - protected: - [[MEMBERS]] - - private: - [[NAME]]( - vector pCollExp, - CoalescedGeomDataSharedPtr pGeomData) - : Operator(pCollExp, pGeomData) - { - [[INITIALISATION]] - } -}; -\end{lstlisting} -The placeholders in double square brackets should be replaced as follows: -\begin{itemize} - \item \texttt{[[NAME]]}: The name of the class in the form - \begin{lstlisting} - _{_} - \end{lstlisting} - where the shape need only be included if the operator is shape-specific. - \item \texttt{[[MEMBERS]]}: Any member variables necessary to store precomputed - quantities and ensure computational efficiency. - \item \texttt{[[IMPLEMENTATION]]}: The code which actually computes the action - of the operator on the elements in the collection. - \item \texttt{[[INITIALIZATION]]}: Code to initialize member variables and - precomputed quantities. -\end{itemize} - -\subsection{Instantiation} -Operators are instantiated through the OperatorFactory. Therefore the operator -classes must be registered with the factory during start-up. This is achieved -using static initialisation with either the \texttt{m\_type} or -\texttt{m\_typeArr}. The latter is shown in the following example: -\begin{lstlisting}[style=C++Style] -OperatorKey BwdTrans_StdMat::m_typeArr[] = { - GetOperatorFactory().RegisterCreatorFunction( - OperatorKey(eSegment, eBwdTrans, eStdMat,false), - BwdTrans_StdMat::create, "BwdTrans_StdMat_Seg"), - GetOperatorFactory().RegisterCreatorFunction( - OperatorKey(eTriangle, eBwdTrans, eStdMat,false), - BwdTrans_StdMat::create, "BwdTrans_StdMat_Tri"), - ... -}; -\end{lstlisting} -This instructs the factory to use the \texttt{BwdTrans\_StdMat} class for all -shapes when performing a backward transform using the \texttt{StdMat} approach. -In contrast, if the class is shape specific, the non-array member variable would -be initialised, for example: -\begin{lstlisting}[style=C++Style] -OperatorKey BwdTrans_SumFac_Seg::m_type = GetOperatorFactory(). - RegisterCreatorFunction( - OperatorKey(eSegment, eBwdTrans, eSumFac, false), - BwdTrans_SumFac_Seg::create, "BwdTrans_SumFac_Seg"); -\end{lstlisting} - -\section{MultiRegions} -In the MultiRegions library, all classes and routines are related to the -process of assembling a global spectral/hp expansion out of local elemental -contributions are bundled together. The most important entities of this library -are the base class ExpList and its daughter classes. These classes all are the -abstraction of a multi-elemental spectral/hp element expansion. Three different -types of multi-elemental expansions can be distinguished: - -\subsection{A collection of local expansions} -This collection is just a list of local expansions, without any coupling between -the expansions on the different elements, and can be formulated as: -\begin{align*} -u^{\delta}(\boldsymbol{x})=\sum_{e=1}^{{N_{\mathrm{el}}}}\sum_{n=0}^{N^{e}_m-1}\hat{u}_n^e\phi_n^e(\boldsymbol{x}) -\end{align*} -where -\begin{itemize} -\item ${N_{\mathrm{el}}}$ is the number of elements, -\item $N^{e}_m$ is the number of local expansion modes within the -element $e$, -\item $\phi_n^e(\boldsymbol{x})$ is the $n^{th}$ local expansion mode within -the element $e$, -\item $\hat{u}_n^e$ is the $n^{th}$ local expansion coefficient -\item within the element $e$. -\end{itemize} - -These types of expansion are represented by the classes ExpList0D, ExpList1D, -ExpList2D and ExpList3D, depending on the dimension of the problem (ExpList0D is -used just to deal with boundary conditions for 1D expansions). - -\subsection{A multi-elemental discontinuous global expansion} -The expansions are represented by the classes DisContField1D, DisContField2D and -DisContField3D. Objects of these classes should be used when solving partial -differential equations using a discontinuous Galerkin approach. These classes -enforce a coupling between elements and augment the domain with boundary -conditions. - -All local elemental expansions are now connected to form a global spectral/hp -representation. This type of global expansion can be defined as: -\begin{align*} -u^{\delta}(\boldsymbol{x})=\sum_{n=0}^{N_{\mathrm{dof}}-1}\hat{u}_n - \Phi_n(\boldsymbol{x})=\sum_{e=1}^{{N_{\mathrm{el}}}} - \sum_{n=0}^{N^{e}_m-1}\hat{u}_n^e\phi_n^e(\boldsymbol{x}) -\end{align*} -where -\begin{itemize} -\item $N_{\mathrm{dof}}$ refers to the number of global modes, -\item $\Phi_n(\boldsymbol{x})$ is the $n^{th}$ global -expansion mode, -\item $\hat{u}_n$ is the $n^{th}$ global expansion coefficient. -\end{itemize} - -Typically, a mapping array to relate the global degrees of freedom -$\hat{u}_n$ and local degrees of freedom $\hat{u}_n^e$ is -required to assemble the global expansion out of the local contributions. - -In order to solve (second-order) partial differential equations, information - about the boundary conditions should be incorporated in the expansion. In case - of a standard Galerkin implementation, the Dirichlet boundary conditions can be - enforced by lifting a known solution satisfying these conditions, leaving a - homogeneous Dirichlet problem to be solved. If we denote the unknown solution - by $u^{\mathcal{H}}(\boldsymbol{x})$ and the known Dirichlet - boundary conditions by $u^{\mathcal{D}}(\boldsymbol{x})$ then we can - decompose the solution $u^{\delta}(\boldsymbol{x})$ into the form -\begin{align*} - u^{\delta}(\boldsymbol{x}_i)=u^{\mathcal{D}}(\boldsymbol{x}_i)+ - u^{\mathcal{H}}(\boldsymbol{x}_i)=\sum_{n=0}^{N^{\mathcal{D}}-1} - \hat{u}_n^{\mathcal{D}}\Phi_n(\boldsymbol{x}_i)+ - \sum_{n={N^{\mathcal{D}}}}^{N_{\mathrm{dof}}-1} - \hat{u}_n^{\mathcal{H}}\Phi_n(\boldsymbol{x}_i). -\end{align*} -Implementation-wise, the known solution can be lifted by ordering the known -degrees of freedom $\hat{u}_n^{\mathcal{H}}$ first in the global -solution array $\boldsymbol{\hat{u}}$. - - -\subsection{A multi-elemental continuous global expansion} -The discontinuous case is supplimented with a global continuity condition. In -this case a $C^0$ continuity condition is imposed across the element -interfaces and the expansion is therefore globally continuous. - -This type of global continuous expansion which incorporates the boundary - conditions are represented by the classes ContField1D, ContField2D and - ContField3D. Objects of these classes should be used when solving partial - differential equations using a standard Galerkin approach. - - -\subsection{Additional classes} -Furthermore, we have two more sets of classes: -\begin{itemize} -\item The class LocalToGlobalBaseMap and its daughter classes: - LocalToGlobalC0ContMap and LocalToGlobalDGMap. - - These classes are an abstraction of the mapping from local to global degrees - of freedom and contain one or both of the following mapping arrays: - \begin{itemize} - \item map $[e][n]$ - - This array contains the index of the global degree of freedom corresponding - to the $n^{th}$ local expansion mode within the $e^{th}$ element. - \item bmap $[e][n]$ - - This array contains the index of the global degree of freedom corresponding - to the $n^{th}$ local boundary mode within the - $e^{th}$ element. - \end{itemize} - Next to the mapping array, these classes also contain routines to assemble the - global system from the local contributions, and other routines to transform - between local and global level. -\item The classes GlobalLinSys and GlobalLinSysKey. - - The class GlobalLinSys is an abstraction of the global system matrix - resulting from the global assembly procedure. Depending of the choice to - statically condense the global matrix or not, the relevant blocks are stored - as a member of this class. Given a proper right hand side vector, this class - also contains a routine to solve the resulting matrix system. - - The class GlobalLinSysKey represents a key which uniquely defines a global - matrix. This key can be used to construct or retrieve the global matrix - associated to a certain key. -\end{itemize} - -More information about the implementation of connectivity between elements in -Nektar++ can be found [wiki:Connectivity here]. - -\begin{center} -\includegraphics{img/MultiRegions.png} -\end{center} - -\subsection{Quasi-3D approach} - -The Quasi-3D approach is an extension of the 1D and the 2D spectral/hp element -method. This technique permits to study 3D problems combining the spectral/hp -element method with a spectral method. In the Quasi-3D approach with 1 -homogenous direction, the third dimension (z-axis) is expandend with an harmonic -expansion (a Fourier series). In each quadrature point of the Fourier -discretisation we can find a 2D plane discretised with a 2D spectral/hp elements -expasions. In the case with 2 homogeneous directions a plane is discretised with -a 2D Fourier expansion (y-z palne). In each one of the quadrature point of this -harmonic expansion there is a 1D spectral/hp element discretisation. The -homogenous classes derive directly form ExpList, and they are -ExpListHomogeneous1D and ExpListHomogeneous2D. This classes are used to -represent the collections of 2D (or 1D) spectral/hp element problems which are -located in the Fourier expansions quatradure points to create a 3D problem. As -describer above, we can find the find the continuos or discontinuos case, -depending on the spectral/hp element approach. ExpList2DHomogeneous1D and -ExpList1DHomogeneous2D are used to manage boundary conditions. A description of -the Quasi-3D approach usage can be found in Chapter 3 in the User Guide. - -\begin{center} -\includegraphics[width=\textwidth]{img/Quasi3d.png} -\end{center} - - -\section{SolverUtils} - -\subsection{Drivers} -Drivers govern the high-level execution of a solver. - -\subsubsection{Implementing a new Driver} -To take advantage of the Nektar++ architecture and implement an algorithm -which will wrap around an existing solver, new drivers can be created. This can -be done in a few steps by using DriverStandard.cpp (and .h) as a template: -\begin{itemize} -\item Create the new files called DriverMyAlgorithm.cpp (and .h) -\item Implement constructor and destructor -\item Provide implementation for \texttt{v\_InitObject} and \texttt{v\_Execute} -as necessary. -\item Register the new driver with the driver factory. -\begin{lstlisting}[style=C++Style] -string DriverMyAlgorithm::className = - GetDriverFactory().RegisterCreatorFunction("MyAlgorithm", - DriverMyAlgorithm::create); -string DriverMyAlgorithm::driverLookupId = - LibUtilities::SessionReader::RegisterEnumValue("Driver","MyAlgorithm",0); -\end{lstlisting} -\item Add the new driver to the library. In \inlsh{CMakeLists.txt}, -DriverMyAlgorithm.cpp must be added in the \inlsh{SOLVER\_UTILS\_SOURCES} -section and DriverMyAlgorithm.h in the \inlsh{SOLVER\_UTILS\_HEADERS} section. -\end{itemize} diff --git a/docs/developer-guide/memoir.4ht b/docs/developer-guide/memoir.4ht deleted file mode 100644 index ebe2d9aab92a3d53f78a69f4e815edbedfed5758..0000000000000000000000000000000000000000 --- a/docs/developer-guide/memoir.4ht +++ /dev/null @@ -1,68 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% memoir.4ht 2009-05-21-09:32 % -% Copyright (C) 2003--2009 Eitan M. Gurari % -% % -% This work may be distributed and/or modified under the % -% conditions of the LaTeX Project Public License, either % -% version 1.3c of this license or (at your option) any % -% later version. The latest version of this license is % -% in % -% http://www.latex-project.org/lppl.txt % -% and version 1.3c or later is part of all distributions % -% of LaTeX version 2005/12/01 or later. % -% % -% This work has the LPPL maintenance status "maintained".% -% % -% This Current Maintainer of this work % -% is Eitan M. Gurari. % -% % -% If you modify this program your changing its signature % -% with a directive of the following form will be % -% appreciated. % -% \message{signature} % -% % -% gurari@cse.ohio-state.edu % -% http://www.cse.ohio-state.edu/~gurari % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\immediate\write-1{version 2009-05-21-09:32} - -\input book.4ht -\input verse.4ht -% Tables Handling -\input array.4ht -\input dcolumn.4ht -\input tabularx.4ht -\input booktabs.4ht -\let\rm\empty -\let\sf\empty -\let\tt\empty -\let\bf\empty -\let\it\empty - -\def\@chapter[#1]#2{% - \gHAdvance\:mpNum by 1 -\HAssign\minipageNum=\:mpNum \relax -% - {\SkipRefstepAnchor \let\addcontentsline\:gobbleIII\no@chapter[#1]{}% - \global\let\f@rtoc\f@rtoc - \global\let\f@rhdr\f@rhdr }% - \HtmlEnv \Toc:Title{#1}\:chapter{#2}} -\NewConfigure{poemline}{2} - -\ifx \memgobble\:UnDef - \pend:defI\getthelinenumber{% - \let\sv:thepoemline\thepoemline - \pend:def\thepoemline{\a:poemline}% - \append:def\thepoemline{\b:poemline}} -\append:defI\getthelinenumber{\let\thepoemline\sv:thepoemline} - -\else - \pend:defII\getthelinenumber{% - \let\sv:thepoemline\thepoemline - \pend:def\thepoemline{\a:poemline}% - \append:def\thepoemline{\b:poemline}} -\append:defII\getthelinenumber{\let\thepoemline\sv:thepoemline} - -\fi -\Hinput{memoir} -\endinput diff --git a/docs/developer-guide/styling.cfg b/docs/developer-guide/styling.cfg deleted file mode 100644 index 70720feff507e753de4711069e89510e12e7a837..0000000000000000000000000000000000000000 --- a/docs/developer-guide/styling.cfg +++ /dev/null @@ -1,88 +0,0 @@ -\Preamble{html} - \Configure{graphics*} - {pdf} - {\Picture[pict]{\csname Gin@base\endcsname.png}} - - %% Use HTML for italics and bold - \Configure{emph}{\ifvmode\ShowPar\fi\HCode{}}{\HCode{}} - \Configure{textbf}{\ifvmode\ShowPar\fi\HCode{}}{\HCode{}} - \Configure{texttt}{\ifvmode\ShowPar\fi\HCode{}}{\HCode{}} - \ConfigureEnv{notebox}{\ifvmode\ShowPar\fi\HCode{
}}{\HCode{
}} {} {} - \ConfigureEnv{warningbox}{\ifvmode\ShowPar\fi\HCode{
}}{\HCode{
}} {} {} - \ConfigureEnv{tipbox}{\ifvmode\ShowPar\fi\HCode{
}}{\HCode{
}} {} {} - - %% Remove div indents - \Configure{HtmlPar} - {\EndP\Tg

} - {\EndP\Tg

} - {\HCode{

\Hnewline}} - {\HCode{

\Hnewline}} - - \begin{document} - \DeclareGraphicsExtensions{.pdf,.eps,.png,.jpg,.mp,.mps} - - \Css{ - body { - margin: 0 auto; - max-width: 800px; - background: \#ffffff; - font-family: "Helvetica Neue", Arial, Freesans, clean, sans-serif; - } - h2 {color: \#000000; text-align: right; font-size: 32pt;} - .chapterHead .titlemark { - font-size: 20pt; - } - a { - color: \#000066; - text-decoration: none; - } - a:hover { - color: \#0000ff; - } - img { - max-width: 800px; - } - .figure { - text-align: center; - } - div .caption { - text-align: center; - } - .author { - font-size: 14pt; - } - .lstlisting { - background: \#eeeeee; - margin-left: 20px; - margin-right: 20px; - padding: 5px; - font-family: "Lucida Console", Monaco, monospace; - } - .lstinline { - padding: 2px; - font-family: "Lucida Console", Monaco, monospace; - } - .notebox { - border: 1px solid \#999999; - border-radius: 10px; - background: \#bbbbbb; - padding: 10px; - margin: 10px; - } - .warningbox { - border: 1px solid \#999999; - border-radius: 10px; - background: \#ffbbbb; - padding: 10px; - margin: 10px; - } - .tipbox { - border: 1px solid \#999999; - border-radius: 10px; - background: \#bbffbb; - padding: 10px; - margin: 10px; - } -} - -\EndPreamble diff --git a/docs/user-guide/CMakeLists.txt b/docs/user-guide/CMakeLists.txt index 3ba4e6769b6e1d405f16230f04813d45dd6ec90d..4e73e573f90bd4c0436185ca7aac9110638df04c 100644 --- a/docs/user-guide/CMakeLists.txt +++ b/docs/user-guide/CMakeLists.txt @@ -44,7 +44,9 @@ ADD_CUSTOM_TARGET(user-guide-pdf ${PDFLATEX} --output-directory ${USERGUIDE} ${USERGUIDESRC}/user-guide.tex COMMAND TEXMFOUTPUT=${USERGUIDE} ${BIBTEX} ${USERGUIDE}/user-guide.aux COMMAND TEXMFOUTPUT=${USERGUIDE} ${MAKEINDEX} ${USERGUIDE}/user-guide.idx - COMMAND export TEXINPUTS=${CMAKE_SOURCE_DIR}//: && + COMMAND TEXINPUTS=${CMAKE_SOURCE_DIR}//: + ${PDFLATEX} --output-directory ${USERGUIDE} ${USERGUIDESRC}/user-guide.tex + COMMAND TEXINPUTS=${CMAKE_SOURCE_DIR}//: ${PDFLATEX} --output-directory ${USERGUIDE} ${USERGUIDESRC}/user-guide.tex WORKING_DIRECTORY ${USERGUIDESRC} ) diff --git a/library/MultiRegions/ExpList.h b/library/MultiRegions/ExpList.h index 9821ddde8998f563f1e0d3cc5e75545257b4f228..efbb880287c886e5f74125760afd750f72c6bbbd 100644 --- a/library/MultiRegions/ExpList.h +++ b/library/MultiRegions/ExpList.h @@ -475,11 +475,11 @@ namespace Nektar /** * This operation is evaluated as: * \f{tabbing} - * \hspace{1cm} \= Do \= $e=$ $1, N_{\mathrm{el}}$ \ \ - * \> \> Do \= $i=$ $0,N_m^e-1$ \ \ + * \hspace{1cm} \= Do \= $e=$ $1, N_{\mathrm{el}}$ \\ + * \> \> Do \= $i=$ $0,N_m^e-1$ \\ * \> \> \> $\boldsymbol{\hat{u}}^{e}[i] = \mbox{sign}[e][i] \cdot - * \boldsymbol{\hat{u}}_g[\mbox{map}[e][i]]$ \ \ - * \> \> continue \ \ + * \boldsymbol{\hat{u}}_g[\mbox{map}[e][i]]$ \\ + * \> \> continue \\ * \> continue * \f} * where \a map\f$[e][i]\f$ is the mapping array and \a diff --git a/library/NekMeshUtils/2DGenerator/2DGenerator.cpp b/library/NekMeshUtils/2DGenerator/2DGenerator.cpp index c79f4f237d0b6d7ad217eced7ac64b93c9fa5047..12e1e91677ed232cddd3e5441fb604ec17b03eb3 100644 --- a/library/NekMeshUtils/2DGenerator/2DGenerator.cpp +++ b/library/NekMeshUtils/2DGenerator/2DGenerator.cpp @@ -33,12 +33,15 @@ // //////////////////////////////////////////////////////////////////////////////// #include +#include #include #include #include +#include + using namespace std; namespace Nektar { @@ -55,6 +58,12 @@ Generator2D::Generator2D(MeshSharedPtr m) : ProcessModule(m) ConfigOption(false, "", "Generate parallelograms on these curves"); m_config["blthick"] = ConfigOption(false, "0.0", "Parallelogram layer thickness"); + m_config["periodic"] = + ConfigOption(false, "", "Set of pairs of periodic curves"); + m_config["bltadjust"] = + ConfigOption(false, "2.0", "Boundary layer thickness adjustment"); + m_config["adjustblteverywhere"] = + ConfigOption(true, "0", "Adjust thickness everywhere"); } Generator2D::~Generator2D() @@ -68,12 +77,9 @@ void Generator2D::Process() cout << endl << "2D meshing" << endl; cout << endl << "\tCurve meshing:" << endl << endl; } - m_mesh->m_numNodes = m_mesh->m_cad->GetNumVerts(); - m_thickness_ID = m_thickness.DefineFunction("x y z", m_config["blthick"].as()); - ParseUtils::GenerateSeqVector(m_config["blcurves"].as().c_str(), m_blCurves); @@ -85,10 +91,8 @@ void Generator2D::Process() LibUtilities::PrintProgressbar(i, m_mesh->m_cad->GetNumCurve(), "Curve progress"); } - vector::iterator f = find(m_blCurves.begin(), m_blCurves.end(), i); - if (f == m_blCurves.end()) { m_curvemeshes[i] = @@ -99,17 +103,24 @@ void Generator2D::Process() m_curvemeshes[i] = MemoryManager::AllocateSharedPtr( i, m_mesh, m_config["blthick"].as()); } - m_curvemeshes[i]->Mesh(); } + //////// + // consider periodic curves + + if (m_config["periodic"].beenSet) + { + PeriodicPrep(); + MakePeriodic(); + } + //////////////////////////////////////// if (m_config["blcurves"].beenSet) { // we need to do the boundary layer generation in a face by face basis MakeBLPrep(); - for (int i = 1; i <= m_mesh->m_cad->GetNumSurf(); i++) { MakeBL(i); @@ -120,7 +131,6 @@ void Generator2D::Process() { cout << endl << "\tFace meshing:" << endl << endl; } - // linear mesh all surfaces for (int i = 1; i <= m_mesh->m_cad->GetNumSurf(); i++) { @@ -130,9 +140,8 @@ void Generator2D::Process() "Face progress"); } - m_facemeshes[i] = - MemoryManager::AllocateSharedPtr(i,m_mesh, - m_curvemeshes, 99+i); + m_facemeshes[i] = MemoryManager::AllocateSharedPtr( + i, m_mesh, m_curvemeshes, 99 + i); m_facemeshes[i]->Mesh(); } @@ -144,28 +153,25 @@ void Generator2D::Process() vector ns; ns.push_back((*it)->m_n1); ns.push_back((*it)->m_n2); - // for each iterator create a LibUtilities::eSegement // push segment into m_mesh->m_element[1] // tag for the elements shoudl be the CAD number of the curves - ElmtConfig conf(LibUtilities::eSegment, 1, false, false); - vector tags; tags.push_back((*it)->m_parentCAD->GetId()); - ElementSharedPtr E2 = GetElementFactory().CreateInstance( LibUtilities::eSegment, conf, ns, tags); - m_mesh->m_element[1].push_back(E2); } + // m_mesh->m_expDim = 1; + // m_mesh->m_element[2].clear(); + ProcessVertices(); ProcessEdges(); ProcessFaces(); ProcessElements(); ProcessComposites(); - Report(); } @@ -193,17 +199,13 @@ void Generator2D::MakeBLPrep() void Generator2D::MakeBL(int faceid) { map > edgeNormals; - int eid = 0; - for (vector::iterator it = m_blCurves.begin(); it != m_blCurves.end(); ++it) { CADOrientation::Orientation edgeo = m_mesh->m_cad->GetCurve(*it)->GetOrienationWRT(faceid); - vector es = m_curvemeshes[*it]->GetMeshEdges(); - // on each !!!EDGE!!! calculate a normal // always to the left unless edgeo is 1 // normal must be done in the parametric space (and then projected back) @@ -214,57 +216,70 @@ void Generator2D::MakeBL(int faceid) Array p1, p2; p1 = es[j]->m_n1->GetCADSurfInfo(faceid); p2 = es[j]->m_n2->GetCADSurfInfo(faceid); + Array n(2); + n[0] = p1[1] - p2[1]; + n[1] = p2[0] - p1[0]; if (edgeo == CADOrientation::eBackwards) { - swap(p1, p2); + n[0] *= -1.0; + n[1] *= -1.0; } - Array n(2); - n[0] = p1[1] - p2[1]; - n[1] = p2[0] - p1[0]; NekDouble mag = sqrt(n[0] * n[0] + n[1] * n[1]); n[0] /= mag; n[1] /= mag; - - Array np = es[j]->m_n1->GetCADSurfInfo(faceid); - np[0] += n[0]; - np[1] += n[1]; - + Array np(2); + np[0] = p1[0] + n[0]; + np[1] = p1[1] + n[1]; Array loc = es[j]->m_n1->GetLoc(); Array locp = m_mesh->m_cad->GetSurf(faceid)->P(np); - n[0] = locp[0] - loc[0]; n[1] = locp[1] - loc[1]; mag = sqrt(n[0] * n[0] + n[1] * n[1]); n[0] /= mag; n[1] /= mag; - edgeNormals[es[j]->m_id] = n; } } + bool adjust = m_config["bltadjust"].beenSet; + NekDouble divider = m_config["bltadjust"].as(); + bool adjustEverywhere = m_config["adjustblteverywhere"].beenSet; + + if (divider < 2.0) + { + WARNINGL1(false, "BndLayerAdjustment too low, corrected to 2.0"); + divider = 2.0; + } + map nodeNormals; map >::iterator it; for (it = m_nodesToEdge.begin(); it != m_nodesToEdge.end(); it++) { - Array n(3); + Array n(3, 0.0); ASSERTL0(it->second.size() == 2, "wierdness, most likely bl_surfs are incorrect"); Array n1 = edgeNormals[it->second[0]->m_id]; Array n2 = edgeNormals[it->second[1]->m_id]; - n[0] = (n1[0] + n2[0]) / 2.0; n[1] = (n1[1] + n2[1]) / 2.0; NekDouble mag = sqrt(n[0] * n[0] + n[1] * n[1]); n[0] /= mag; n[1] /= mag; - NekDouble t = m_thickness.Evaluate(m_thickness_ID, it->first->m_x, it->first->m_y, 0.0, 0.0); + // Adjust thickness according to angle between normals + if (adjust) + { + if (adjustEverywhere || it->first->GetNumCadCurve() > 1) + { + NekDouble angle = acos(n1[0] * n2[0] + n1[1] * n2[1]); + angle = (angle > M_PI) ? 2 * M_PI - angle : angle; + t /= cos(angle / divider); + } + } - n[0] = n[0] * t + it->first->m_x; - n[1] = n[1] * t + it->first->m_y; - n[2] = 0.0; - + n[0] = n[0] * t + it->first->m_x; + n[1] = n[1] * t + it->first->m_y; NodeSharedPtr nn = boost::shared_ptr( new Node(m_mesh->m_numNodes++, n[0], n[1], 0.0)); CADSurfSharedPtr s = m_mesh->m_cad->GetSurf(faceid); @@ -278,7 +293,6 @@ void Generator2D::MakeBL(int faceid) { CADOrientation::Orientation edgeo = m_mesh->m_cad->GetCurve(*it)->GetOrienationWRT(faceid); - vector ns = m_curvemeshes[*it]->GetMeshPoints(); vector newNs; for (int i = 0; i < ns.size(); i++) @@ -287,7 +301,6 @@ void Generator2D::MakeBL(int faceid) } m_curvemeshes[*it] = MemoryManager::AllocateSharedPtr(*it, m_mesh, newNs); - if (edgeo == CADOrientation::eBackwards) { reverse(ns.begin(), ns.end()); @@ -295,22 +308,16 @@ void Generator2D::MakeBL(int faceid) for (int i = 0; i < ns.size() - 1; ++i) { vector qns; - qns.push_back(ns[i]); qns.push_back(ns[i + 1]); qns.push_back(nodeNormals[ns[i + 1]]); qns.push_back(nodeNormals[ns[i]]); - ElmtConfig conf(LibUtilities::eQuadrilateral, 1, false, false); - vector tags; tags.push_back(101); - ElementSharedPtr E = GetElementFactory().CreateInstance( LibUtilities::eQuadrilateral, conf, qns, tags); - E->m_parentCAD = m_mesh->m_cad->GetSurf(faceid); - for (int j = 0; j < E->GetEdgeCount(); ++j) { pair testIns; @@ -328,6 +335,60 @@ void Generator2D::MakeBL(int faceid) } } +void Generator2D::PeriodicPrep() +{ + m_periodicPairs.clear(); + set periodic; + + // Build periodic curve pairs + string s = m_config["periodic"].as(); + vector lines; + + boost::split(lines, s, boost::is_any_of(":")); + + for (vector::iterator il = lines.begin(); il != lines.end(); ++il) + { + vector tmp; + boost::split(tmp, *il, boost::is_any_of(",")); + + ASSERTL0(tmp.size() == 2, "periodic pairs ill-defined"); + + vector data(2); + data[0] = boost::lexical_cast(tmp[0]); + data[1] = boost::lexical_cast(tmp[1]); + + ASSERTL0(!periodic.count(data[0]), "curve already periodic"); + ASSERTL0(!periodic.count(data[1]), "curve already periodic"); + + m_periodicPairs[data[0]] = data[1]; + periodic.insert(data[0]); + periodic.insert(data[1]); + } +} + +void Generator2D::MakePeriodic() +{ + // Override slave curves + + for (map::iterator ip = m_periodicPairs.begin(); + ip != m_periodicPairs.end(); ++ip) + { + m_curvemeshes[ip->second]->PeriodicOverwrite(m_curvemeshes[ip->first]); + } + + if (m_mesh->m_verbose) + { + cout << "\t\tPeriodic boundary conditions" << endl; + for (map::iterator it = m_periodicPairs.begin(); + it != m_periodicPairs.end(); ++it) + { + cout << "\t\t\tCurves " << it->first << " => " << it->second + << endl; + } + cout << endl; + } +} + void Generator2D::Report() { if (m_mesh->m_verbose) diff --git a/library/NekMeshUtils/2DGenerator/2DGenerator.h b/library/NekMeshUtils/2DGenerator/2DGenerator.h index 29d64e08ead96a04c6b470d9e541fcf7bbc50f5d..15100475eb84b5023713be4c76398ee9785efec0 100644 --- a/library/NekMeshUtils/2DGenerator/2DGenerator.h +++ b/library/NekMeshUtils/2DGenerator/2DGenerator.h @@ -61,14 +61,18 @@ public: static ModuleKey className; Generator2D(MeshSharedPtr m); + virtual ~Generator2D(); virtual void Process(); private: - void MakeBLPrep(); + void PeriodicPrep(); + + void MakePeriodic(); + void MakeBL(int faceid); void Report(); @@ -76,6 +80,8 @@ private: std::map m_facemeshes; /// map of individual curve meshes of the curves in the domain std::map m_curvemeshes; + /// map of periodic curve pairs + std::map m_periodicPairs; std::vector m_blCurves; LibUtilities::AnalyticExpressionEvaluator m_thickness; diff --git a/library/NekMeshUtils/CADSystem/CADSystem.cpp b/library/NekMeshUtils/CADSystem/CADSystem.cpp index e914ef9142d8e9a3e02c74daf6b2c45edfe63d1e..3b2d1a1751218deb97a44817fbf97be6b7b85c19 100644 --- a/library/NekMeshUtils/CADSystem/CADSystem.cpp +++ b/library/NekMeshUtils/CADSystem/CADSystem.cpp @@ -33,10 +33,10 @@ // //////////////////////////////////////////////////////////////////////////////// -#include -#include #include #include +#include +#include using namespace std; @@ -45,7 +45,7 @@ namespace Nektar namespace NekMeshUtils { -EngineFactory& GetEngineFactory() +EngineFactory &GetEngineFactory() { typedef Loki::SingletonHolder @@ -53,7 +53,7 @@ EngineFactory& GetEngineFactory() return Type::Instance(); } -CADVertFactory& GetCADVertFactory() +CADVertFactory &GetCADVertFactory() { typedef Loki::SingletonHolder @@ -61,7 +61,7 @@ CADVertFactory& GetCADVertFactory() return Type::Instance(); } -CADCurveFactory& GetCADCurveFactory() +CADCurveFactory &GetCADCurveFactory() { typedef Loki::SingletonHolder @@ -69,7 +69,7 @@ CADCurveFactory& GetCADCurveFactory() return Type::Instance(); } -CADSurfFactory& GetCADSurfFactory() +CADSurfFactory &GetCADSurfFactory() { typedef Loki::SingletonHolder @@ -77,5 +77,37 @@ CADSurfFactory& GetCADSurfFactory() return Type::Instance(); } +Array CADSystem::GetPeriodicTranslationVector(int first, + int second) +{ + ASSERTL0(GetNumSurf() == 1, "wont work for multi surfaces yet"); + + CADCurveSharedPtr c1 = GetCurve(first); + CADCurveSharedPtr c2 = GetCurve(second); + + NekDouble tst = c1->GetTotLength() - c2->GetTotLength(); + ASSERTL0(fabs(tst) < 1e-6, "periodic curves not same length"); + + vector v1 = c1->GetVertex(); + Array p1 = v1[0]->GetLoc(); + + Array p2; + vector v2 = c2->GetVertex(); + if (c1->GetOrienationWRT(1) == c2->GetOrienationWRT(1)) + { + p2 = v2[1]->GetLoc(); + } + else + { + p2 = v2[0]->GetLoc(); + } + + Array ret(3); + ret[0] = p2[0] - p1[0]; + ret[1] = p2[1] - p1[1]; + ret[2] = p2[2] - p1[2]; + + return ret; +} } } diff --git a/library/NekMeshUtils/CADSystem/CADSystem.h b/library/NekMeshUtils/CADSystem/CADSystem.h index bed9bda644084d588c5c9d3db7f3631f544ca0f9..b86df6c18a8e0e7ed05b232a44cf0dfe010c61ad 100644 --- a/library/NekMeshUtils/CADSystem/CADSystem.h +++ b/library/NekMeshUtils/CADSystem/CADSystem.h @@ -43,6 +43,8 @@ #include +#include + #include "CADObject.h" namespace Nektar @@ -201,6 +203,9 @@ public: return m_verts.size(); } + NEKMESHUTILS_EXPORT Array GetPeriodicTranslationVector( + int first, int second); + protected: /// Name of cad file std::string m_name; diff --git a/library/NekMeshUtils/CADSystem/OCE/CADSurfOCE.cpp b/library/NekMeshUtils/CADSystem/OCE/CADSurfOCE.cpp index 9a72cdf6d7280451a0f031a27c8ca6b690b0c781..e0d9b838e7359d115b154b05abbe64819336e981 100644 --- a/library/NekMeshUtils/CADSystem/OCE/CADSurfOCE.cpp +++ b/library/NekMeshUtils/CADSystem/OCE/CADSurfOCE.cpp @@ -61,8 +61,8 @@ void CADSurfOCE::Initialise(int i, TopoDS_Shape in) gp_Pnt ori(0.0, 0.0, 0.0); transform.SetScale(ori, 1.0 / 1000.0); TopLoc_Location mv(transform); - in.Move(mv); + m_occSurface = BRepAdaptor_Surface(TopoDS::Face(in)); m_id = i; @@ -85,14 +85,14 @@ Array CADSurfOCE::locuv(Array p) Array uvr(2); - gp_Pnt2d p2 = m_sas->ValueOfUV(loc, 1e-3); + gp_Pnt2d p2 = m_sas->ValueOfUV(loc, Precision::Confusion()); uvr[0] = p2.X(); uvr[1] = p2.Y(); gp_Pnt p3 = m_sas->Value(p2); - if (p3.Distance(loc) > 1.0) + if (p3.Distance(loc) > 1e-6) { - cout << "large locuv distance " << p3.Distance(loc) << " " << m_id + cout << "large locuv distance " << p3.Distance(loc)/1000.0 << " " << m_id << endl; } @@ -173,13 +173,9 @@ NekDouble CADSurfOCE::DistanceTo(Array p) { gp_Pnt loc(p[0] * 1000.0, p[1] * 1000.0, p[2] * 1000.0); - // alternative locuv methods - ShapeAnalysis_Surface sas(m_s); - sas.SetDomain(m_bounds[0], m_bounds[1], m_bounds[2], m_bounds[3]); - - gp_Pnt2d p2 = sas.ValueOfUV(loc, 1e-7); + gp_Pnt2d p2 = m_sas->ValueOfUV(loc, Precision::Confusion()); - gp_Pnt p3 = sas.Value(p2); + gp_Pnt p3 = m_sas->Value(p2); return p3.Distance(loc); } @@ -189,13 +185,9 @@ void CADSurfOCE::ProjectTo(Array &tp, { gp_Pnt loc(tp[0] * 1000.0, tp[1] * 1000.0, tp[2] * 1000.0); - // alternative locuv methods - ShapeAnalysis_Surface sas(m_s); - sas.SetDomain(m_bounds[0], m_bounds[1], m_bounds[2], m_bounds[3]); - - gp_Pnt2d p2 = sas.ValueOfUV(loc, 1e-7); + gp_Pnt2d p2 = m_sas->ValueOfUV(loc, Precision::Confusion()); - gp_Pnt p3 = sas.Value(p2); + gp_Pnt p3 = m_sas->Value(p2); tp[0] = p3.X() / 1000.0; tp[1] = p3.Y() / 1000.0; @@ -226,7 +218,7 @@ Array CADSurfOCE::N(Array uv) Test(uv); #endif - BRepLProp_SLProps slp(m_occSurface, 2, 1e-6); + BRepLProp_SLProps slp(m_occSurface, 2, 1e-8); slp.SetParameters(uv[0], uv[1]); if (!slp.IsNormalDefined()) diff --git a/library/NekMeshUtils/CADSystem/OCE/OpenCascade.h b/library/NekMeshUtils/CADSystem/OCE/OpenCascade.h index 5f8ea570e3d7d38ef8a4970fe7495c37058fc8e1..abbde7f0c8fc48084b6ddb71f96ecb8996407205 100644 --- a/library/NekMeshUtils/CADSystem/OCE/OpenCascade.h +++ b/library/NekMeshUtils/CADSystem/OCE/OpenCascade.h @@ -71,6 +71,7 @@ #include #include #include +#include #include #include diff --git a/library/NekMeshUtils/MeshElements/Quadrilateral.cpp b/library/NekMeshUtils/MeshElements/Quadrilateral.cpp index b7bf0c919bab612a42d24e30d336e792a1ec21c6..d144f75dfa77479d95c27e3c3e002350a21b9cee 100644 --- a/library/NekMeshUtils/MeshElements/Quadrilateral.cpp +++ b/library/NekMeshUtils/MeshElements/Quadrilateral.cpp @@ -105,6 +105,7 @@ Quadrilateral::Quadrilateral(ElmtConfig pConf, if (sum > 0.0) { reverse(m_edge.begin(), m_edge.end()); + swap(m_vertex[1], m_vertex[3]); } } diff --git a/library/NekMeshUtils/SurfaceMeshing/CurveMesh.cpp b/library/NekMeshUtils/SurfaceMeshing/CurveMesh.cpp index 7b43ffd4f9d425f2fb4cf0874b57e8131d7a60b5..33481fd6e6eab09b97f31138bc17bf8543c035be 100644 --- a/library/NekMeshUtils/SurfaceMeshing/CurveMesh.cpp +++ b/library/NekMeshUtils/SurfaceMeshing/CurveMesh.cpp @@ -353,5 +353,71 @@ void CurveMesh::GetSampleFunction() m_dst[i] = dsti; } } + +void CurveMesh::PeriodicOverwrite(CurveMeshSharedPtr from) +{ + //clear current mesh points and remove edges from edgeset + m_meshpoints.clear(); + for (int i = 0; i < m_meshedges.size(); i++) + { + m_mesh->m_edgeSet.erase(m_meshedges[i]); + } + m_meshedges.clear(); + + /////// + + int tid = from->GetId(); + Array T = + m_mesh->m_cad->GetPeriodicTranslationVector(tid, m_id); + + CADCurveSharedPtr c1 = m_mesh->m_cad->GetCurve(tid); + + bool reversed = c1->GetOrienationWRT(1) == m_cadcurve->GetOrienationWRT(1); + + vector nodes = from->GetMeshPoints(); + + vector > surfs = + m_cadcurve->GetAdjSurf(); + + for (int i = 1; i < nodes.size() - 1; i++) + { + Array loc = nodes[i]->GetLoc(); + NodeSharedPtr nn = NodeSharedPtr(new Node( + m_mesh->m_numNodes++, loc[0] + T[0], loc[1] + T[1], 0.0)); + + for (int j = 0; j < surfs.size(); j++) + { + nn->SetCADSurf(surfs[j].first->GetId(), surfs[j].first, + surfs[j].first->locuv(nn->GetLoc())); + } + + nn->SetCADCurve(m_id, m_cadcurve, m_cadcurve->loct(nn->GetLoc())); + + m_meshpoints.push_back(nn); + } + + // Reverse internal nodes of the vector if necessary + if (reversed) + { + reverse(m_meshpoints.begin(), m_meshpoints.end()); + } + + vector verts = m_cadcurve->GetVertex(); + + m_meshpoints.insert(m_meshpoints.begin(), verts[0]->GetNode()); + m_meshpoints.push_back(verts[1]->GetNode()); + //dont need to realign cad for vertices + + // make edges and add them to the edgeset for the face mesher to use + for (int i = 0; i < m_meshpoints.size() - 1; i++) + { + EdgeSharedPtr e = boost::shared_ptr( + new Edge(m_meshpoints[i], m_meshpoints[i + 1])); + e->m_parentCAD = m_cadcurve; + m_mesh->m_edgeSet.insert(e); + m_meshedges.push_back(e); + } +} + } } diff --git a/library/NekMeshUtils/SurfaceMeshing/CurveMesh.h b/library/NekMeshUtils/SurfaceMeshing/CurveMesh.h index accf248c8ef224aba59318ffc7183d01f6da557b..1075a6b311f2a7872ff5f2b119538ae4bb68ee3f 100644 --- a/library/NekMeshUtils/SurfaceMeshing/CurveMesh.h +++ b/library/NekMeshUtils/SurfaceMeshing/CurveMesh.h @@ -54,6 +54,10 @@ namespace Nektar namespace NekMeshUtils { +//forward +class CurveMesh; +typedef boost::shared_ptr CurveMeshSharedPtr; + class CurveMesh { public: @@ -125,6 +129,13 @@ public: return m_curvelength; } + void PeriodicOverwrite(CurveMeshSharedPtr from); + + int GetId() + { + return m_id; + } + private: /** * @brief get node spacing sampling function @@ -179,7 +190,6 @@ private: int m_blID; }; -typedef boost::shared_ptr CurveMeshSharedPtr; } } diff --git a/utilities/NekMesh/InputModules/InputMCF.cpp b/utilities/NekMesh/InputModules/InputMCF.cpp index 79e4a68f76a6ceec23a52483d34409a40b6cb8d7..a768bd6ffbadc69e2e76a918a1b818d9e5256a41 100644 --- a/utilities/NekMesh/InputModules/InputMCF.cpp +++ b/utilities/NekMesh/InputModules/InputMCF.cpp @@ -33,8 +33,12 @@ // //////////////////////////////////////////////////////////////////////////////// +#include #include + +#include + #include #include @@ -151,7 +155,22 @@ void InputMCF::ParseFile(string nm) } } - map::iterator it; + set periodic; + if (pSession->DefinesElement("NEKTAR/MESHING/PERIODIC")) + { + TiXmlElement *per = mcf->FirstChildElement("PERIODIC"); + TiXmlElement *pair = per->FirstChildElement("P"); + + while (pair) + { + string tmp; + pair->QueryStringAttribute("PAIR", &tmp); + periodic.insert(tmp); + pair = pair->NextSiblingElement("P"); + } + } + + map::iterator it; it = information.find("CADFile"); ASSERTL0(it != information.end(), "no cadfile defined"); @@ -161,12 +180,13 @@ void InputMCF::ParseFile(string nm) ASSERTL0(it != information.end(), "no meshtype defined"); m_makeBL = it->second == "3DBndLayer"; m_2D = it->second == "2D"; + m_manifold = it->second == "Manifold"; if (it->second == "2DBndLayer") { m_makeBL = true; m_2D = true; } - if (!m_makeBL && !m_2D) + if (!m_makeBL && !m_2D && !m_manifold) { ASSERTL0(it->second == "3D", "unsure on MeshType") } @@ -205,6 +225,17 @@ void InputMCF::ParseFile(string nm) it = parameters.find("BndLayerProgression"); m_blprog = it != parameters.end() ? it->second : "2.0"; } + + it = parameters.find("BndLayerAdjustment"); + if (it != parameters.end()) + { + m_adjust = true; + m_adjustment = it->second; + } + else + { + m_adjust = false; + } } m_naca = false; @@ -233,12 +264,14 @@ void InputMCF::ParseFile(string nm) } set::iterator sit; - sit = boolparameters.find("SurfaceOptimiser"); - m_surfopti = sit != boolparameters.end(); - sit = boolparameters.find("WriteOctree"); - m_woct = sit != boolparameters.end(); - sit = boolparameters.find("VariationalOptimiser"); - m_varopti = sit != boolparameters.end(); + sit = boolparameters.find("SurfaceOptimiser"); + m_surfopti = sit != boolparameters.end(); + sit = boolparameters.find("WriteOctree"); + m_woct = sit != boolparameters.end(); + sit = boolparameters.find("VariationalOptimiser"); + m_varopti = sit != boolparameters.end(); + sit = boolparameters.find("BndLayerAdjustEverywhere"); + m_adjustall = sit != boolparameters.end(); m_refine = refinement.size() > 0; if (m_refine) @@ -252,6 +285,18 @@ void InputMCF::ParseFile(string nm) m_refinement = ss.str(); m_refinement.erase(m_refinement.end() - 1); } + + if (periodic.size() > 0) + { + stringstream ss; + for (sit = periodic.begin(); sit != periodic.end(); ++sit) + { + ss << *sit; + ss << ":"; + } + m_periodic = ss.str(); + m_periodic.erase(m_periodic.end() - 1); + } } void InputMCF::Process() @@ -302,7 +347,8 @@ void InputMCF::Process() ////**** LINEAR MESHING ****//// if (m_2D) { - m_mesh->m_expDim = 2; + ////**** 2DGenerator ****//// + m_mesh->m_expDim = 2; m_mesh->m_spaceDim = 2; module = GetModuleFactory().CreateInstance( ModuleKey(eProcessModule, "2dgenerator"), m_mesh); @@ -352,36 +398,44 @@ void InputMCF::Process() return; } - ////**** VolumeMesh ****//// - module = GetModuleFactory().CreateInstance( - ModuleKey(eProcessModule, "volumemesh"), m_mesh); - if (m_makeBL) - { - module->RegisterConfig("blsurfs", m_blsurfs); - module->RegisterConfig("blthick", m_blthick); - module->RegisterConfig("bllayers", m_bllayers); - module->RegisterConfig("blprog", m_blprog); - } - - try + if(m_manifold) { - module->SetDefaults(); - module->Process(); + //dont want to volume mesh + m_mesh->m_expDim = 2; } - catch (runtime_error &e) + else { - cout << "Volume meshing has failed with message:" << endl; - cout << e.what() << endl; - cout << "The linear surface mesh be dumped as a manifold mesh" - << endl; - m_mesh->m_expDim = 2; - m_mesh->m_element[3].clear(); - ProcessVertices(); - ProcessEdges(); - ProcessFaces(); - ProcessElements(); - ProcessComposites(); - return; + ////**** VolumeMesh ****//// + module = GetModuleFactory().CreateInstance( + ModuleKey(eProcessModule, "volumemesh"), m_mesh); + if (m_makeBL) + { + module->RegisterConfig("blsurfs", m_blsurfs); + module->RegisterConfig("blthick", m_blthick); + module->RegisterConfig("bllayers", m_bllayers); + module->RegisterConfig("blprog", m_blprog); + } + + try + { + module->SetDefaults(); + module->Process(); + } + catch (runtime_error &e) + { + cout << "Volume meshing has failed with message:" << endl; + cout << e.what() << endl; + cout << "The linear surface mesh be dumped as a manifold mesh" + << endl; + m_mesh->m_expDim = 2; + m_mesh->m_element[3].clear(); + ProcessVertices(); + ProcessEdges(); + ProcessFaces(); + ProcessElements(); + ProcessComposites(); + return; + } } } @@ -463,7 +517,26 @@ void InputMCF::Process() } } + ////**** Peralign ****//// + if (m_2D && m_periodic.size()) + { + vector lines; + boost::split(lines, m_periodic, boost::is_any_of(":")); + + for (vector::iterator il = lines.begin(); il != lines.end(); + ++il) + { + module = GetModuleFactory().CreateInstance( + ModuleKey(eProcessModule, "peralign"), m_mesh); + + vector tmp(2); + boost::split(tmp, *il, boost::is_any_of(",")); + module->RegisterConfig("surf1", tmp[0]); + } + module->SetDefaults(); + module->Process(); + } } } } diff --git a/utilities/NekMesh/InputModules/InputMCF.h b/utilities/NekMesh/InputModules/InputMCF.h index 31b31f2e4874f653c2b0ea662bf7393cf0a34a01..1073e3a9b951f6d901d6948c5f60f0847846ce25 100644 --- a/utilities/NekMesh/InputModules/InputMCF.h +++ b/utilities/NekMesh/InputModules/InputMCF.h @@ -63,9 +63,10 @@ public: private: std::string m_minDelta, m_maxDelta, m_eps, m_cadfile, m_order, m_blsurfs, m_blthick, m_blprog, m_bllayers, m_refinement, - m_nacadomain; + m_nacadomain, m_periodic, m_adjustment; + bool m_makeBL, m_surfopti, m_varopti, m_refine, m_woct, m_2D, m_splitBL, - m_naca; + m_naca, m_adjust, m_adjustall, m_manifold; }; } diff --git a/utilities/NekMesh/ProcessModules/ProcessPerAlign.cpp b/utilities/NekMesh/ProcessModules/ProcessPerAlign.cpp index fea1e4e43da84a4541a5fd42a5f2e52d3ee4de1d..14053d35048dd1e5886f8fa33944c4cdbe8fee31 100644 --- a/utilities/NekMesh/ProcessModules/ProcessPerAlign.cpp +++ b/utilities/NekMesh/ProcessModules/ProcessPerAlign.cpp @@ -44,6 +44,8 @@ #include "ProcessPerAlign.h" +#include + using namespace std; using namespace Nektar::NekMeshUtils; @@ -70,7 +72,8 @@ ProcessPerAlign::ProcessPerAlign(MeshSharedPtr m) : ProcessModule(m) m_config["surf2"] = ConfigOption(false, "-1", "Tag identifying first surface."); m_config["dir"] = ConfigOption( - false, "", "Direction in which to align (either x, y, or z)"); + false, "", "Direction in which to align (either x, y, or z; " + "or vector with components separated by a comma)"); m_config["orient"] = ConfigOption(true, "0", "Attempt to reorient tets and prisms"); } @@ -103,17 +106,49 @@ void ProcessPerAlign::Process() return; } - if (dir != "x" && dir != "y" && dir != "z") - { - cerr << "WARNING: dir must be set to either x, y or z. " - << "Skipping periodic alignment." << endl; - return; - } + vector tmp1; + boost::split(tmp1, dir, boost::is_any_of(",")); NekDouble vec[3]; - vec[0] = dir == "x" ? 1.0 : 0.0; - vec[1] = dir == "y" ? 1.0 : 0.0; - vec[2] = dir == "z" ? 1.0 : 0.0; + + if (tmp1.size() == 1) + { + //if the direction is not specified and its a 2D mesh and there is CAD + //it can figure out the dir on its own + if (!dir.size() && m_mesh->m_spaceDim == 2 && m_mesh->m_cad) + { + Array T = + m_mesh->m_cad->GetPeriodicTranslationVector(surf1, surf2); + NekDouble mag = sqrt(T[0] * T[0] + T[1] * T[1]); + + vec[0] = T[0] / mag; + vec[1] = T[1] / mag; + vec[2] = T[2] / mag; + } + else + { + if (dir != "x" && dir != "y" && dir != "z") + { + cerr << "WARNING: dir must be set to either x, y or z. " + << "Skipping periodic alignment." << endl; + return; + } + + vec[0] = dir == "x" ? 1.0 : 0.0; + vec[1] = dir == "y" ? 1.0 : 0.0; + vec[2] = dir == "z" ? 1.0 : 0.0; + } + } + else if (tmp1.size() == 3) + { + vec[0] = boost::lexical_cast(tmp1[0]); + vec[1] = boost::lexical_cast(tmp1[1]); + vec[2] = boost::lexical_cast(tmp1[2]); + } + else + { + ASSERTL0(false,"expected three components or letter for direction"); + } CompositeMap::iterator it1 = m_mesh->m_composite.find(surf1); CompositeMap::iterator it2 = m_mesh->m_composite.find(surf2); diff --git a/utilities/NekMesh/Tests/MeshGen/2d-naca.mcf b/utilities/NekMesh/Tests/MeshGen/2d-naca.mcf index 6e6ca06f88edb13f0127cf051cb26c8bff6dac79..5ac8b86b05f8f3b3f88e443aa54a4d7fe1421555 100644 --- a/utilities/NekMesh/Tests/MeshGen/2d-naca.mcf +++ b/utilities/NekMesh/Tests/MeshGen/2d-naca.mcf @@ -16,6 +16,8 @@

+

+

@@ -24,6 +26,7 @@ +