{ "cells": [ { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true, "slideshow": { "slide_type": "slide" } }, "source": [ "# Xpetra - a short introduction" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true, "slideshow": { "slide_type": "slide" } }, "source": [ "## Philosophy" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true, "slideshow": { "slide_type": "slide" } }, "source": [ "- Goal: write algorithms independent from *{E,T}petra* which easily allow to work on underlying data\n", "- Xpetra provides an abstract interface-wrapper for both *Epetra* and *Tpetra*\n", "- Xpetra follows the *Tpetra* user interface standards\n", "- Xpetra extends the logic of {E,T}petra by blocked objects (e.g., for multiphysics problems)\n", "- Xpetra is Thyra compatible\n", " - in contrast to Thyra, easy-access to underlying data\n", " - Xpetra ideal to write algorithms that operate on the data\n", "- Xpetra has a Kokkos interface (including an Epetra compatibility layer)" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true, "slideshow": { "slide_type": "slide" } }, "source": [ "## Basic design concept" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true, "slideshow": { "slide_type": "slide" } }, "source": [ "- For standard linear algebra objects (e.g. ```Map```, ```MultiVector```, ```CrsMatrix```,...)\n", " - Define abstract class and implement specializations for both {E,T}petra\n", " - Provide a ```Factory``` class to create new instances of the linear algebra objects without writing {E,T}petra specific code\n", "- Further classes for blocked linear algebra objects (e.g., ```BlockedMap```, ```BlockedMultiVector```,...)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Instructions for writing algorithms using ```Xpetra```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " - write algorithms using Xpetra only\n", " - by all means avoid Epetra/Tpetra specific code\n", " - use Factory classes to generate new objects\n", " - The factory classes \"automatically\" choose the right linear algebra framework underneath\n" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "## Example: how to transform an ```Epetra_CrsMatrix``` to a ```Xpetra::Matrix```?" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Declare location of include headers " ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ ".I /opt/install/do-conf-ep-serial/include/" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ " Load Trilinos libraries" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ ".L libepetra" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "### 1. Create a tridiagonal matrix of size $20\\times 20$ and store it in an ```Epetra_CrsMatrix``` object " ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Create a serial communicator..." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#include \"Epetra_SerialComm.h\"" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "(Epetra_SerialComm &) @0x7f850ea31018\n" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Epetra_SerialComm Comm;" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "... and define the matrix size." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "(int) 20\n" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "int NumMyElements = 20;" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Create a new map and fill the matrix." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#include \"Epetra_Map.h\"\n", "#include \"Epetra_CrsMatrix.h\"" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "(int) 0\n" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Epetra_Map Map(-1, NumMyElements, 0, Comm);\n", "int NumGlobalElements = Map.NumGlobalElements();\n", "\n", "Epetra_CrsMatrix A(Copy, Map, 3);\n", "\n", "double negOne = -1.0;\n", "double posTwo = 2.0;\n", "for (int i=0; iMueLu. " ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Even though the example uses Epetra, the procedure for Tpetra is similar." ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ ".L libxpetra" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "#### Package-specific wrapper class: ```{E,T}petraCrsMatrix```" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "First, we have to include some header files:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#include \n" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Next, we declare some typedefs:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "typedef double Scalar;\n", "typedef int LocalOrdinal;\n", "typedef int GlobalOrdinal;\n", "typedef Kokkos::Compat::KokkosSerialWrapperNode EpetraNode;\n", "typedef EpetraNode Node;" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "If you know *Tpetra* you are certainly familiar with most of the template parameters. *Xpetra* is templated on the exact same template parameters. Therefore, we have to provide compatible template parameters for the *Epetra* branch in *Xpetra*. \n", "\n", "Please note the *EpetraNode* typedef which can be either the *SerialNode* or *OpenMPNode* depending on the configuration of *Epetra* on your machine. This notebook only contains a standard *Epetra* installation using ```GO=int``` on the *SerialNode*." ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "To improve the readability of the source code, you should include the ```Xpetra_UseShortNames.hpp``` file after the typedefs. It contains typedefs of all *Xpetra* classes with the corresponding template parameters defined above. This allows us to write, e.g., ```Map``` instead of ```Xpetra::Map``` later in the code. However, this only works if your code lives in the ```Xpetra``` namespace. This is not the case in this notebook. So, we have to write the long version. At least, we can shorten the template parameters using ``SC, LO, GO, NO``. The corresponding typedefs come with the inclusion of ```Xpetra_UseShortNames.hpp```" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#include \"Xpetra_UseShortNames.hpp\"" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "```Xpetra_EpetraCrsMatrix.hpp``` defines the class which encapsulates an ```Epetra_CrsMatrix``` object in ```Xpetra```." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#include \"Xpetra_EpetraCrsMatrix.hpp\"" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "The constructor of ```Xpetra::EpetraCrsMatrix``` only accepts an ```RCP``` pointer to an ```Epetra_CrsMatrix``` object. So, let's wrap ```A``` into an rcp pointer:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#include \"Teuchos_RCP.hpp\"" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Teuchos::RCP{ptr=0x7f850ea31060,node=0x861d510,strong_count=1,weak_count=0}\n" ] }, { "data": { "text/plain": [ "(std::basic_ostream >::__ostream_type &) @0x7f8506776700\n" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Teuchos::RCP rcpA = Teuchos::rcpFromRef(A);\n", "std::cout << rcpA << std::endl;" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Then call the constructor" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "(Xpetra::EpetraCrsMatrixT &) @0x7f850ea311c0\n" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Xpetra::EpetraCrsMatrixT xA(rcpA);" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epetra::CrsMatrix\n", "Number of Global Rows = 20\n", "Number of Global Cols = 20\n", "Number of Global Diagonals = 20\n", "Number of Global Nonzeros = 58\n", "Global Maximum Num Entries = 3\n", "\n", "\n", "\n", "\n", "\n", "Number of My Rows = 20\n", "Number of My Cols = 20\n", "Number of My Diagonals = 20\n", "Number of My Nonzeros = 58\n", "My Maximum Num Entries = 3\n", "\n", " Processor Row Index Col Index Value \n", " 0 0 0 2 \n", " 0 0 1 -1 \n", " 0 1 0 -1 \n", " 0 1 1 2 \n", " 0 1 2 -1 \n", " 0 2 1 -1 \n", " 0 2 2 2 \n", " 0 2 3 -1 \n", " 0 3 2 -1 \n", " 0 3 3 2 \n", " 0 3 4 -1 \n", " 0 4 3 -1 \n", " 0 4 4 2 \n", " 0 4 5 -1 \n", " 0 5 4 -1 \n", " 0 5 5 2 \n", " 0 5 6 -1 \n", " 0 6 5 -1 \n", " 0 6 6 2 \n", " 0 6 7 -1 \n", " 0 7 6 -1 \n", " 0 7 7 2 \n", " 0 7 8 -1 \n", " 0 8 7 -1 \n", " 0 8 8 2 \n", " 0 8 9 -1 \n", " 0 9 8 -1 \n", " 0 9 9 2 \n", " 0 9 10 -1 \n", " 0 10 9 -1 \n", " 0 10 10 2 \n", " 0 10 11 -1 \n", " 0 11 10 -1 \n", " 0 11 11 2 \n", " 0 11 12 -1 \n", " 0 12 11 -1 \n", " 0 12 12 2 \n", " 0 12 13 -1 \n", " 0 13 12 -1 \n", " 0 13 13 2 \n", " 0 13 14 -1 \n", " 0 14 13 -1 \n", " 0 14 14 2 \n", " 0 14 15 -1 \n", " 0 15 14 -1 \n", " 0 15 15 2 \n", " 0 15 16 -1 \n", " 0 16 15 -1 \n", " 0 16 16 2 \n", " 0 16 17 -1 \n", " 0 17 16 -1 \n", " 0 17 17 2 \n", " 0 17 18 -1 \n", " 0 18 17 -1 \n", " 0 18 18 2 \n", " 0 18 19 -1 \n", " 0 19 18 -1 \n", " 0 19 19 2 \n", "\n" ] }, { "data": { "text/plain": [ "(std::basic_ostream >::__ostream_type &) @0x7f8506776700\n" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "std::cout << *rcpA << std::endl;" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "The ```{E,T}petraCrsMatrix``` class are package-specific wrappers for *Epetra* and *Tpetra* which encapsulate an *Epetra* ```Epetra_CrsMatrix``` or an *Tpetra* ```Tpetra::CrsMatrix``` object." ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "The ```EpetraCrsMatrix``` object is templated on the ```GlobalOrdinal``` and ```NodeType```. ```GlobalOrdinal``` can be either ```int``` (default) or ```long long``` depending on the *Epetra* configuration. In this container we only support ```GO=int```. The ```NodeType``` template parameter should be ```Xpetra::EpetraNode``` which translates to the serial or OpenMP node, depending on the configuration of *Epetra*. Note, that *Epetra* can only be compiled for one choice of ```GlobalOrdinal``` and ```NodeType```." ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "The ```TpetraCrsMatrix``` object is templated on the *Tpetra* template parameters, which include ```Scalar```, ```LocalOrdinal```, ```GlobalOrdinal``` and ```Node```." ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "*Xpetra* consequently follows the *Tpetra* style and naming conventions for functions." ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "#### Wrap the ```CrsMatrix``` class" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Next, one has to wrap the ```Xpetra::CrsMatrix``` object into an ```Xpetra::Matrix``` object. This can be done with the ```Xpetra::CrsMatrixWrap``` class." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#include \"Xpetra_CrsMatrixWrap.hpp\"\n", "#include \"Xpetra_CrsMatrix.hpp\"\n" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Again, we have to use RCP pointers from the *Teuchos* package." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "(Teuchos::RCP > &) @0x7f850ea31200\n" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Teuchos::RCP > xCrsMat = Teuchos::rcpFromRef(xA);" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The matrix has 20 rows and 58 nonzeros.\n" ] }, { "data": { "text/plain": [ "(std::basic_ostream >::__ostream_type &) @0x7f8506776700\n" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Teuchos::RCP > xMat = Teuchos::rcp(new Xpetra::CrsMatrixWrap(xCrsMat));\n", "GO numRows = xMat->getGlobalNumRows();\n", "auto numEntries = xMat->getNodeNumEntries();\n", "std::cout << \"The matrix has \" << numRows << \" rows and \" << numEntries << \" nonzeros.\" << std::endl;" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "The object ```xMat``` is an RCP pointer to a ```Xpetra::Matrix``` object that can be used as (abstract) input to *MueLu*." ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "It supports the *Tpetra* style interface, i.e., you can basically use it like an *Tpetra* object." ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "### 3. How can i access the underlying {E,T}petra CrsMatrix object?" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "**First of all: you never should need that!**\n", "\n", "*Xpetra* is meant to provide a common wrapper for {E,T}petra which allows you to write algorithms independent from the concrete implementation of {E,T}petra, but providing a Petra like API! This is a big advantage compared to, e.g., *Thyra*, which has a similar intention, but is too abstract for writing algorithms which operate on the low-level data (like matrix entries)." ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Nevertheless, here is how you can access the underlying ```Epetra_CrsMatrix``` object given an ```Xpetra::Matrix``` object:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The Epetra matrix has 20 rows.\n" ] }, { "data": { "text/plain": [ "(std::basic_ostream >::__ostream_type &) @0x7f8506776700\n" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Teuchos::RCP > xCrsMatWrap = Teuchos::rcp_dynamic_cast >(xMat);\n", "Teuchos::RCP > xCrsMatTmp = xCrsMatWrap->getCrsMatrix();\n", "Teuchos::RCP > xEpCrsMatTmp = Teuchos::rcp_dynamic_cast>(xCrsMatTmp);\n", "Teuchos::RCP epMat = xEpCrsMatTmp->getEpetra_CrsMatrix();\n", "std::cout << \"The Epetra matrix has \" << epMat->NumGlobalRows()<< \" rows.\" << std::endl;" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Again: you should not need this. As you can see from the last code snippet, it introduces {E,T}petra specific code which is against the *Xpetra* philosophy. You use *Xpetra* to write code independent from {E,T}petra!" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "## Example: how to wrap a (Multi)Vector?" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Again, let's assume we have an ```Epetra_Vector```:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "(int) 0\n" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Epetra_Vector x(Map);\n", "x.Random();" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "We can wrap it into a ```Xpetra::EpetraVectorT``` class using" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#include \"Xpetra_EpetraVector.hpp\"" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "(Xpetra::EpetraVectorT &) @0x7f850ea31360\n" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Xpetra::EpetraVectorT xx(Teuchos::rcpFromRef(x));" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Let's print the content of the vector. It contains the random values of the underlying *Epetra* vector." ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " MyPID GID Value \n", " 0 0 -0.630518\n", " 0 1 0.879819\n", " 0 2 -0.877245\n", " 0 3 0.150899\n", " 0 4 0.165755\n", " 0 5 -0.151011\n", " 0 6 -0.0357566\n", " 0 7 -0.961937\n", " 0 8 0.722493\n", " 0 9 0.934016\n", " 0 10 0.00486903\n", " 0 11 -0.16616\n", " 0 12 -0.657289\n", " 0 13 0.946171\n", " 0 14 0.291264\n", " 0 15 -0.727955\n", " 0 16 -0.743651\n", " 0 17 -0.542321\n", " 0 18 -0.792288\n", " 0 19 0.0205202\n", "\n" ] }, { "data": { "text/plain": [ "(std::basic_ostream >::__ostream_type &) @0x7f8506776700\n" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "std::cout << xx << std::endl;" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "The ```Xpetra::EpetraVectorT``` class is derived from the ```Xpetra::Vector``` class:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " MyPID GID Value \n", " 0 0 -0.630518\n", " 0 1 0.879819\n", " 0 2 -0.877245\n", " 0 3 0.150899\n", " 0 4 0.165755\n", " 0 5 -0.151011\n", " 0 6 -0.0357566\n", " 0 7 -0.961937\n", " 0 8 0.722493\n", " 0 9 0.934016\n", " 0 10 0.00486903\n", " 0 11 -0.16616\n", " 0 12 -0.657289\n", " 0 13 0.946171\n", " 0 14 0.291264\n", " 0 15 -0.727955\n", " 0 16 -0.743651\n", " 0 17 -0.542321\n", " 0 18 -0.792288\n", " 0 19 0.0205202\n", "\n" ] }, { "data": { "text/plain": [ "(std::basic_ostream >::__ostream_type &) @0x7f8506776700\n" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Teuchos::RCP > xv = Teuchos::rcpFromRef(xx);\n", "std::cout << *xv << std::endl;" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "To wrap multivectors for {E,T}petra requires a similar procedure." ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "## How to create new ```Xpetra::Vector``` objects in an algorithm independent from {E,T}petra?" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "If you write an algorithm in Xpetra (independent from the concrete {E,T}petra implementation), you may need to create objects such as (multi)vectors or matrices. You cannot use the {E,T}petra wrappers given by, e.g., ```Xpetra::EpetraMultiVector``` or ```Xpetra::TpetraCrsMatrix```, since this would make your code {E,T}petra specific.\n", "\n", "Instead, you use the *Xpetra* factory classes to create new instances of maps, vectors, multivectors, matrices, etc..." ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "### Create a new Map" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#include \"Xpetra_MapFactory.hpp\"\n", "#include \"Xpetra_Map.hpp\"\n", "#include \"Teuchos_DefaultSerialComm.hpp\"" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "*Xpetra* uses the communicator object from *Teuchos*:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "(Teuchos::RCP > &) @0x7f850ea313c8\n" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Teuchos::RCP > comm = Xpetra::toXpetra(Comm);" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "The factory classes have ```Build``` routines which accept a flag ```Xpetra::Use{E,T}petra``` and user parameters for the constructor of the Map object. The code, e.g., could look like:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "(Xpetra::UnderlyingLib) (Xpetra::UnderlyingLib::UseEpetra) : (unsigned int) 0\n" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Xpetra::UnderlyingLib lib = Xpetra::UseEpetra;" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "(Teuchos::RCP > &) @0x7f850ea313e8\n" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Teuchos::RCP > xm = Xpetra::MapFactory::Build(lib,10,0,comm);" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "By consequently using ```lib``` when creating map objects through *Xpetra* factories one can quickly switch from an *Epetra* to a *Tpetra* implementation by setting ```lib = Xpetra::UseTpetra```. No further code changes necessary." ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " \n", " Number of Global Entries = 10\n", " Maximum of all GIDs = 9\n", " Minimum of all GIDs = 0\n", " Index Base = 0\n", " \n", "\n" ] }, { "data": { "text/plain": [ "(std::basic_ostream >::__ostream_type &) @0x7f8506776700\n" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "std::cout << *xm < >::__ostream_type &) @0x7f8506776700\n" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Teuchos::RCP > xmv = Xpetra::MultiVectorFactory::Build(xm, 3);\n", "xmv->putScalar(42.0);\n", "std::cout << *xmv << std::endl;" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "C++11", "language": "", "name": "cling-cpp11" }, "language_info": { "codemirror_mode": "text/x-c++src", "file_extension": ".c++", "mimetype": " text/x-c++src", "name": "c++" } }, "nbformat": 4, "nbformat_minor": 0 }