File: Blackboard.cpp

package info (click to toggle)
trilinos 13.2.0-6
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 837,964 kB
  • sloc: cpp: 3,466,826; ansic: 433,701; fortran: 168,838; python: 102,712; xml: 66,353; sh: 38,380; makefile: 25,246; perl: 7,516; f90: 6,358; csh: 4,161; objc: 2,620; lex: 1,484; lisp: 810; javascript: 552; yacc: 515; awk: 364; ml: 281; php: 145
file content (227 lines) | stat: -rw-r--r-- 6,798 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/* ******************************************************************** */
/* See the file COPYRIGHT for a complete copyright notice, contact      */
/* person and disclaimer.                                               */
/* ******************************************************************** */

#include "ml_config.h"
#include "ml_common.h"
#ifdef HAVE_ML_MLAPI

// This is the easiest way, since all MLAPI include files will
// automatically be included. However, this also makes the compilation
// longer, so you might want to specify the exact list of include files
// as long as you code gets finalized.
#include "MLAPI.h"

using namespace Teuchos;
using namespace MLAPI;

// ============== //
// example driver //
// ============== //

int main(int argc, char *argv[])
{

#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
#endif

  try {

    // Initialize the MLAPI workspace
    Init();

    // all MLAPI objects are based on Space's. A Space defines the number of
    // local and global distribution of elements. Space's can be constructed
    // in several ways. The simplest is to specify the number of global
    // elements:

    Space MySpace(4 * GetNumProcs());

    // Class MLAPI::DistributedMatrix is a simple way to define
    // matrices. This class can be used to define distributed matrices. Each
    // processor can set on-processor and off-processor elements. Before any
    // use, the matrix need to be "freezed", so that the communication pattern
    // can be established. This is done by method FillComplete(). After having
    // called this method, elements can no longer be added; however, already
    // inserted elements can be modified using method ReplaceElement().
    //
    // This class is based on the Epetra_FECrsMatrix class. The insertion of
    // elements is somehow slower, but the matrix-vector product is as
    // efficient as those of the Epetra_FECrsmatrix class (with the only
    // overhead of an additional function call).

    DistributedMatrix A(MySpace, MySpace);

    // As any processor can set any element, here we fill the entire
    // matrix on processor 0 only. It is of course possible (and preferable)
    // to let each processor fill local rows only.

    if (GetMyPID() == 0) {

      for (int i = 0 ; i < MySpace.GetNumGlobalElements() ; ++i) {

        if (i)
          A(i, i - 1) = -1.0;
        if (i + 1 != A.NumGlobalCols())
          A(i, i + 1) = -1.0;
        A(i, i) = 2.0;
      }
    }

    A.FillComplete();

    // To get the (row, col) value of the matrix, use method
    // value = GetElement(row, col). Note that both `row' and `col'
    // refer to global indices; however row must be a locally hosted row.
    // If (row, col) is not found, value is set to 0.0.

    std::cout << A;

    // Here we define 3 vectors. The last, z, is empty.

    MultiVector x(MySpace);
    MultiVector y(MySpace);
    MultiVector z;

    // It is easy to assign all the elements of x to a constant value,
    // or to populate with random numbers.

    x = 1.0;
    y.Random();

    // Work on vector's elements requires the () operator

    for (int i = 0 ; i < y.GetMyLength() ; ++i)
      y(i) = 1.0 * i + x(i);

    // vectors can be manipulated in an intuitive way:

    z = x + y;                        // addition
    double norm = sqrt(z * z);        // dot product
    double Anorm = sqrt(z * (A * z)); // dot product with a matrix (not the parenthesis)
    x = x / (x * y);                  // scale x by the dot product between x and y

    if (GetMyPID() == 0) {
      std::cout << "2-norm of z = " << norm << std::endl;
      std::cout << "A-norm of z = " << Anorm << std::endl;
    }

    // some basic operations on matrices are also supported. For example,
    // one can extract the diagonal of a matrix as a vector, then create a new
    // matrix, containing this vector on the diagonal
    // (that is, B will be a diagonal matrix so that B_{i,i} = A_{i,i})

    Operator B = GetDiagonal(GetDiagonal(A));

    // verify that the diagonal of A - B is zero

    z = GetDiagonal(B - A);

    // Also operators can be composed intuitively (for compatible
    // operators):

    Operator C = A * B;    // multiplication, A
    C = A + B;             // addition
    C = 1.0 * A - B * 2.0;             // subtraction

    // use Amesos to apply the inverse of A using LU factorization
    InverseOperator invA(A,"Amesos-KLU");

    // verify that x == inv(A) * A * x
    x = invA * (A * x) - x;
    double NormX = sqrt(x * x);

    if (GetMyPID() == 0)
      std::cout << "Norm of inv(A) * A * x - x = " << NormX << std::endl;

    // All MLAPI objects have a Label, which can be set using
    // SetLabel(Label). Also, all objects overload the << operator:

    std::cout << MySpace;
    std::cout << x;
    std::cout << A;

    // Function Eig() can be used to compute the eigenvalues of an Operator.
    // This function calls LAPACK, therefore the Operator should be "small".
    // ER will contain the real part of the eigenvalues;
    // EI will contain the imaginary part of the eigenvalues;

    MultiVector ER, EI;
    Eig(A, ER, EI);

    for (int i = 0 ; i < ER.GetMyLength() ; ++i)
      std::cout << "ER(" << MySpace(i) << ") = " << ER(i) << std::endl;

    // Another nice feature is that objects can be printed in a MATLAB format.
    // To that aim, simply do the following:
    // - set the label of the objects you want to port to MATLAB;
    // - create a MATLABStream object;
    // - use the << operator on MATLABStream
    // - File `Blackboard.m' has been created in your directory. This file
    //   (only one, for serial and parallel runs) can be executed in
    //   MATLAB to reproduce your MLAPI variables.

    MATLABStream matlab("Blackboard.m", false);

    matlab << "% you can add any MATLAB command this way\n";

    x.SetLabel("x");
    matlab << x;

    A.SetLabel("A");
    matlab << A;

    ER.SetLabel("ER");
    EI.SetLabel("EI");

    matlab << ER;
    matlab << EI;
    matlab << "plot(ER, EI, 'o')\n";

    // Finalize the MLAPI work space before leaving the application

    Finalize();

  }
  catch (const int e) {
    std::cout << "Integer exception, code = " << e << std::endl;
  }
  catch (...) {
    std::cout << "problems here..." << std::endl;
  }

#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  return(0);

}

#else

#include "ml_include.h"

int main(int argc, char *argv[])
{
#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
#endif

  puts("This MLAPI example requires the following configuration options:");
  puts("\t--enable-epetra");
  puts("\t--enable-teuchos");
  puts("\t--enable-ifpack");
  puts("\t--enable-amesos");
  puts("Please check your configure line.");

#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  return(0);
}

#endif // #if defined(HAVE_ML_MLAPI)