diff --git a/doc/manual/manual-gettingstarted.tex b/doc/manual/manual-gettingstarted.tex index 4ee2b1473..496e52494 100644 --- a/doc/manual/manual-gettingstarted.tex +++ b/doc/manual/manual-gettingstarted.tex @@ -1,196 +1,199 @@ \chapter{Getting started} \section{Downloading the code} The \akantu source code can be requested using the form accessible at the URL \url{http://lsms.epfl.ch/akantu}. There, you will be asked to accept the LGPL license terms. \section{Compiling Akantu} Akantu is a \code{cmake} project, so to configure it you can either follow the usual way: \begin{command} > cd akantu > mkdir build > cd build > ccmake .. [ Set the options that you need ] > make > make install \end{command} Or, you can use a tool we added to help you. You can just use the given \code{Makefile} that handles the \code{cmake} configuration \begin{command} > cd akantu > make config > make > make install \end{command} \section{Writing a \code{main} function\label{sect:common:main}} First of all, \akantu needs to be initialized. There is a memory management included in the core library which allows a correct allocation and de-allocation of vectors, structures and objects. Moreover, in parallel computations the initialization procedure can perform the communication setup. This is achieved by a pair of functions (\code{initialize} and \code{finalize}) that are used as follows: \begin{cpp} int main(int argc, char *argv[]) { akantu::initialize(argc, argv); // your code ... akantu::finalize(); } \end{cpp} The \code{initialize} function takes the program parameters which can be interpreted by \akantu and given to the underlying libraries (\eg MPI). \section{Creating and loading a mesh\label{sect:common:mesh}} \akantu supports meshes generated with Gmsh~\cite{gmsh2009}, a free software available at \url{http://geuz.org/gmsh/}. A detailed documentation can be found at this URL, so this manual will not provide Gmsh usage directions. Gmsh outputs meshes in \code{.msh} format that can be read by \akantu. In order to import a mesh, it is necessary to create a \code{Mesh} object through the following function calls: \begin{cpp} UInt spatial_dimension = 2; Mesh mesh(spatial_dimension); \end{cpp} The only parameter that has to be specified by the user is the spatial dimension of the problem. Now it is possible to read a \code{.msh} file with -a \code{MeshIOMSH} object that takes care of loading a mesh to memory. -This step is carried out by: +a \code{read()} function of the mesh. \begin{cpp} - MeshIOMSH mesh_io; - mesh_io.read("square.msh", mesh); + mesh.read("square.msh", mesh); \end{cpp} -where the \code{MeshIOMSH} object is first created before being -used to read the \code{.msh} file. The mesh file name as well as the \code{Mesh} -object must be specified by the user. +This function tries to guess the reader to use based on the extension of the file. -The \code{MeshIOMSH} object can also write mesh files. This feature -is useful to save a mesh that has been modified during a -simulation. The \code{write} method takes care of it: +The mesh can also be wrote to a file with the \code{write()} method. \begin{cpp} - mesh_io.write("square_modified.msh", mesh); + mesh.write("square_modified.msh", mesh); \end{cpp} -which works exactly like the \code{read} method. - -\akantu supports also meshes generated by -DIANA (\url{http://tnodiana.com}), but only in reading mode. A similar -procedure applies where the only -difference is that the \code{MeshIODiana} object should be used -instead of the \code{MeshIOMSH} one. Additional mesh readers can be -introduced into \akantu by coding new \code{MeshIO} classes. + +For now, \akantu supports only meshes generated Gmsh or by +DIANA (\url{http://tnodiana.com}). If the \code{read()} or \code{write()} +functions cannot guess the file type, an optional parameter can be specified +to force the use of a particular reader/writer. + +\begin{center} + \begin{tabular}{lll} + \toprule + Mesh Type & \multicolumn{1}{c}{Key} & Capabilities\\ + \midrule + Gmsh & \code{\_miot\_gmsh} & read/write\\ + Diana & \code{\_miot\_diana} & read\\ + \bottomrule + \end{tabular} +\end{center} + \section{Using \code{Vectors}} Data in \akantu can be stored in the data structures implemented by the \code{Vector} class. In its most basic usage the \code{Vector} class implemented in \akantu is similar to the \code{vector} class of the Standard Template Library (STL) for C++. A simple \code{Vector} containing a sequence of \code{nb\_element} values can be generated with: \begin{cpp} Vector example_vector(nb_element); \end{cpp} where \code{type} usually is \code{Real}, \code{UInt} or \code{bool}. Each value is associated to an index, so that data can be accessed by typing: \begin{cpp} type & val = example_vector(index) \end{cpp} \code{Vectors} can also contain a sequence of values for each index. In that case the number of components of each sequence must be specified during \code{Vector} creation. For example, if we want to create a \code{Vector} to store the coordinates (sequence of three values) of ten nodes, the appropriate code is the following: \begin{cpp} UInt nb_nodes = 10; UInt spatial_dimension = 3; Vector position(nb_nodes, spatial_dimension); \end{cpp} In this case the $x$ position of node number 8 will be given by \code{position(7, 0)} (in C++, numbering starts from 0). If the number of components for the sequence is not specified, the default value of 1 is used. It is very common in \akantu to loop over vectors to perform a specific operation. This ranges from geometric calculation on nodal quantities to tensor algebra (in constitutive laws for example). The \code{Vector} object provides iterators in order to make the writing of loops easier and enhance readability. For instance, a loop over the nodal coordinates can be performed as: \begin{cpp} //accessing the nodal coordinates Vector Vector & nodes = mesh.getNodes(); //creating the iterators Vector::iterator it = nodes.begin(spatial_dimension); Vector::iterator end = nodes.end(spatial_dimension); for (; it != end; ++it){ RVector & coords = (*it); //do what you need .... } \end{cpp} In this example, each \code{RVector} is a geometrical vector of size \code{spatial\_dimension} and the iteration is conveniently performed by the \code{Vector} iterator \code{it}. The \code{Vector} object is intensively used to store tensor values. In that case it should be specified that the returned object type is a matrix when constructing the iterator. This is done when calling the \code{begin} function. For instance, assuming that we have a \code{Vector} storing stresses, we can loop over the stored tensors by: \begin{cpp} //creating the iterators Vector::iterator it = stresses.begin(spatial_dimension,spatial_dimension); Vector::iterator end = stresses.end(spatial_dimension,spatial_dimension); for (; it != end; ++it){ Matrix & stress = (*it); //do what you need .... } \end{cpp} In this last example, the \code{Matrix} objects have dimension \code{spatial\_dimension} $\times$ \code{spatial\_dimension}. The light objects \code{Matrix} and \code{RVector} can be used and combined to do most common linear algebra. In general, a mesh consists of several kinds of elements. Consequently, the amount of data to be stored can differ for each element type. The straightforward example is the connectivity array, \ie the sequences of nodes belonging to each element. In order to easily manage this kind of data, a particular data structure called \code{ByElementTypeVector} is available. This structure is just a group of \code{Vector}, each associated to an element type. The following code can retrieve the \code{ByElementTypeVector} which stores the connectivity arrays for a mesh: \begin{cpp} ByElementTypeVector & connectivities = mesh.getConnectivities(); \end{cpp} Then the specific vector associated to a given element type can be obtained by \begin{cpp} Vector & connectivity_triangle = connectivities(_triangle_3); \end{cpp} where the first order 3-node triangular element was used in the presented piece of code. %%% Local Variables: %%% mode: latex %%% TeX-master: "manual" %%% End: diff --git a/doc/manual/manual-io.tex b/doc/manual/manual-io.tex index 0a474b411..d2a7cb412 100644 --- a/doc/manual/manual-io.tex +++ b/doc/manual/manual-io.tex @@ -1,88 +1,88 @@ \chapter{Input/Output}\index{I\/O} In this chapter, the problem of getting the internal data in a human readable way will be addressed. The models in \akantu handle data associated to a mesh, but this data can be split in many \code{Vectors}. For example, the data stored per element type in a \code{ByElementTypeVector} is composed by as many vectors as element types in the mesh. To help you get this data into a visualization software, the models contain a object that is used to dump \code{VTK} files. These files can be visualized in softwares such as \code{ParaView}\cite{paraview}, \code{ViSit}\cite{visit} or \code{Mayavi}\cite{mayavi}. The internal dumper of the model can be configured to specify which data fields are to be output. This is done with the \code{addDumpField}\index{I\/O!addDumpField} method. By default all the files are generated in a folder called \code{paraview/} \begin{cpp} model.setBaseName("output"); // prefix for all generated files model.addDumpField("displacement"); model.addDumpField("stress"); ... model.dump() \end{cpp} The fields are dumped with the number of component they have in memory. In 2D, for example, vectors have 2 components and $2^{nd}$ order tensors have $2\times2$ components. This can be changed by using \code{addDumpFieldVector}\index{I\/O!addDumpFieldVector} which always dumps vectors with 3 components or \code{addDumpFieldTensor}\index{I\/O!addDumpFieldTensor} which dumps $2^{nd}$ order tensors with $3\times3$ components. The fields that are stored by quadrature points are modified to be seen in the \code{VTK} file as elemental data. To do this, the default behavior averages the values at the quadrature points. The list of fields that can be dumped to file are model dependents. The user can choose to add or remove any of this fields from a dump file, by calling \code{addDumpField*} or \code{removeDumpField} before the \code{dump}. \paragraph{\code{SolidMechanicsModel}:\index{I\/O!SolidMechanicsModel}}\hfill \vspace*{0.2cm} \begin{tabular}{llll} \toprule key & type & support \\ \midrule displacement & Vector & nodes \\ velocity & Vector & nodes \\ acceleration & Vector & nodes \\ force & Vector & nodes \\ residual & Vector & nodes \\ boundary & Vector & nodes \\ mass & Vector & nodes \\ partitions & Real & elements \\ stress & Matrix & quadrature points \\ strain & Matrix & quadrature points \\ \textit{material internals} & variable & quadrature points \\ -\bottomrule + \bottomrule\\ \end{tabular} -The user can also register external fields which have the same mesh as the mesh from the model as support. To do this an object of type \code{Field} as to be created.\index{I\/O!addDumpFieldExternal} +The user can also register external fields that are associated to the same +nodes, elements or quadrature points than the one in the model. To do this +vectors can be registered to the model. \begin{itemize} \item For nodal fields : \begin{cpp} - Vector vect(nb_nodes, nb_component); - Field field = new DumperIOHelper::NodalField(vect)); + Vector field(nb_nodes, nb_component); model.addDumpFieldExternal("my_field", field); \end{cpp} \item For elemental fields : \begin{cpp} - ByElementTypeVector vect; - Field field = new DumperIOHelper::ElementalField(vect, spatial_displacement)); + ByElementTypeVector field; model.addDumpFieldExternal("my_field", field); \end{cpp} \end{itemize} -%%% Local Variables: +%%% Local Variables: %%% mode: latex %%% TeX-master: "manual" -%%% End: +%%% End: diff --git a/doc/manual/manual-parallel.tex b/doc/manual/manual-parallel.tex index d5ef71003..06a411f05 100644 --- a/doc/manual/manual-parallel.tex +++ b/doc/manual/manual-parallel.tex @@ -1,113 +1,112 @@ \chapter{Parallel Computation} -This section explains how to launch a parallel computation. -The strategy adopted by \akantu uses a mesh partitioning -where elements are mapped to processors. Mesh partitions are -then distributed to available processors by adequate routines -as will be described below. -The sequence of additional operations to be performed by the user are: +This section explains how to launch a parallel computation. The strategy +adopted by \akantu uses a mesh partitioning where elements are mapped to a +partition. Mesh partitions are then distributed to available processors by +adequate routines as will be described below. The sequence of additional +operations to be performed by the user are: \begin{itemize} \item Initializing the parallel context \item Partitioning the mesh \item Distributing mesh partitions \end{itemize} After these steps, the \code{Model} object will proceed to the inter processes communications automatically without the user having to explicitly take care of them. In what follows we show how it works on a \code{SolidMechanics} model. \section{Initializing the parallel context} The user must initialize \akantu by forwarding the arguments passed to the program by using the function \code{initialize}, and close \akantu instances at the end of the program by calling the \code{finalize} function.\\ \note{This step does not change from the sequential case as it was stated in Section \ref{sect:common:main}. It only gives a stronger motivation in the parallel/MPI context.}\\ The \code{initialize} function builds a \code{StaticCommunicator} object responsible of handling the interprocesse communications lateron. The \code{StaticCommunicator} can, for instance, be used to ask the total number of declared processors available for computations as well as the process rank -through the functions \code{getNbProc} and \code{whoAmI} respectively. +through the functions \code{getNbProc()} and \code{whoAmI()} respectively. An example of the initializing sequence and basic usage of the \code{StaticCommunicator} is: \begin{cpp} int main(int argc, char *argv[]) { akantu::initialize(argc, argv); akantu::StaticCommunicator & comm = akantu::StaticCommunicator::getStaticCommunicator(); akantu::Int psize = comm.getNbProc(); akantu::Int prank = comm.whoAmI(); ... akantu::finalize(); } \end{cpp} \section{Partitioning the mesh} -After a correct initialization of the processes playing a role in the -computation the mesh shall be partitioned. We assume that a \code{Mesh} object -is constructed as presented in section \ref{sect:common:mesh}. Then a partition -must be computed by using an appropriate mesh partitioner. At present time, the -only partitioner available is \code{MeshPartitionScotch} which implements the +After a correct initialization of the processes that participate in the +computation, the mesh is partitioned. We assume that a \code{Mesh} object +is constructed as presented in section \ref{sect:common:mesh}. Then, a partition +must be computed by using an appropriate mesh partitioner. Currently, the +only partitioner available is \code{MeshPartitionScotch}, which implements the function \code{partitionate} using the \textbf{Scotch}\cite{scotch} program. This is achieved by the following code \begin{cpp} akantu::Mesh mesh(spatial_dimension); akantu::MeshPartition * partition = NULL; if(prank == 0) { akantu::MeshIOMSH mesh_io; mesh_io.read("my_mesh.msh", mesh); partition = new akantu::MeshPartitionScotch(mesh, spatial_dimension); partition->partitionate(psize); } \end{cpp} -\note{Only the processor of rank $0$ should load the mesh file +\note{Only the processor of rank $0$ should load the mesh file to partition it. Nevertheless, the \code{Mesh} object must by declared for all processors since the mesh distribution will store mesh pieces to that object.} \section{Distributing mesh partitions} The distribution of the mesh is automatically done by the \code{SolidMechanicsModel} through the \code{initParallel} function. Thus, after creating a \code{SolidMechanicsModel} with our mesh as the initial -parameter, the \code{initParallel} method must be called receiving the partition +parameter, the \code{initParallel()} method must be called with the partition as a parameter. \begin{cpp} akantu::SolidMechanicsModel model(mesh); model.initParallel(partition); \end{cpp} After that point, everything remains as in the sequential case from the user point of view. This allows the user to care only about his simulation without concern for the parallelism. -An example of an explicit dynamic 2D bar in compression in a parallel -context can be found in \code{\examplesdir/parallel\_2d}. +An example of an explicit dynamic 2D bar in compression, within a parallel +context, can be found in \code{\examplesdir/parallel\_2d}. \section{Launching a parallel program} Using \textbf{MPI} a parallel run can be launched from a shell using the command \begin{cpp} mpirun -np #procs program_name parameter1 paramter2 ... \end{cpp} %%% Local Variables: %%% mode: latex %%% TeX-master: "manual" %%% End: