MFEM  v3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
blockoperator.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.googlecode.com.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 
13 #include "../general/array.hpp"
14 #include "operator.hpp"
15 #include "blockvector.hpp"
16 #include "blockoperator.hpp"
17 
18 namespace mfem
19 {
20 
22  : Operator(offsets.Last()),
23  owns_blocks(0),
24  nRowBlocks(offsets.Size() - 1),
25  nColBlocks(offsets.Size() - 1),
26  row_offsets(0),
27  col_offsets(0),
28  op(nRowBlocks, nRowBlocks)
29 {
30  op = static_cast<Operator *>(NULL);
31  row_offsets.MakeRef(offsets);
32  col_offsets.MakeRef(offsets);
33 }
34 
36  const Array<int> & col_offsets_)
37  : Operator(row_offsets_.Last(), col_offsets_.Last()),
38  owns_blocks(0),
39  nRowBlocks(row_offsets_.Size()-1),
40  nColBlocks(col_offsets_.Size()-1),
41  row_offsets(0),
42  col_offsets(0),
43  op(nRowBlocks, nColBlocks)
44 {
45  op = static_cast<Operator *>(NULL);
46  row_offsets.MakeRef(row_offsets_);
47  col_offsets.MakeRef(col_offsets_);
48 }
49 
51 {
52  SetBlock(iblock, iblock, op);
53 }
54 
55 void BlockOperator::SetBlock(int iRow, int iCol, Operator *opt)
56 {
57  op(iRow, iCol) = opt;
58 
59  MFEM_VERIFY(row_offsets[iRow+1] - row_offsets[iRow] == opt->NumRows() &&
60  col_offsets[iCol+1] - col_offsets[iCol] == opt->NumCols(),
61  "incompatible Operator dimensions");
62 }
63 
64 // Operator application
65 void BlockOperator::Mult (const Vector & x, Vector & y) const
66 {
67  MFEM_ASSERT(x.Size() == width, "incorrect input Vector size");
68  MFEM_ASSERT(y.Size() == height, "incorrect output Vector size");
69 
70  yblock.Update(y.GetData(),row_offsets);
71  xblock.Update(x.GetData(),col_offsets);
72 
73  y = 0.0;
74  for (int iRow=0; iRow < nRowBlocks; ++iRow)
75  {
76  tmp.SetSize(row_offsets[iRow+1] - row_offsets[iRow]);
77  for (int jCol=0; jCol < nColBlocks; ++jCol)
78  {
79  if (op(iRow,jCol))
80  {
81  op(iRow,jCol)->Mult(xblock.GetBlock(jCol), tmp);
82  yblock.GetBlock(iRow) += tmp;
83  }
84  }
85  }
86 }
87 
88 // Action of the transpose operator
89 void BlockOperator::MultTranspose (const Vector & x, Vector & y) const
90 {
91  MFEM_ASSERT(x.Size() == height, "incorrect input Vector size");
92  MFEM_ASSERT(y.Size() == width, "incorrect output Vector size");
93 
94  y = 0.0;
95 
96  xblock.Update(x.GetData(),row_offsets);
97  yblock.Update(y.GetData(),col_offsets);
98 
99  for (int iRow=0; iRow < nColBlocks; ++iRow)
100  {
101  tmp.SetSize(col_offsets[iRow+1] - col_offsets[iRow]);
102  for (int jCol=0; jCol < nRowBlocks; ++jCol)
103  {
104  if (op(jCol,iRow))
105  {
106  op(jCol,iRow)->MultTranspose(xblock.GetBlock(jCol), tmp);
107  yblock.GetBlock(iRow) += tmp;
108  }
109  }
110  }
111 
112 }
113 
115 {
116  if (owns_blocks)
117  for (int iRow=0; iRow < nRowBlocks; ++iRow)
118  for (int jCol=0; jCol < nColBlocks; ++jCol)
119  delete op(jCol,iRow);
120 }
121 
122 //-----------------------------------------------------------------------
124  Solver(offsets_.Last()),
125  owns_blocks(0),
126  nBlocks(offsets_.Size() - 1),
127  offsets(0),
128  op(nBlocks)
129 
130 {
131  op = static_cast<Operator *>(NULL);
132  offsets.MakeRef(offsets_);
133 }
134 
136 {
137  MFEM_VERIFY(offsets[iblock+1] - offsets[iblock] == opt->Height() &&
138  offsets[iblock+1] - offsets[iblock] == opt->Width(),
139  "incompatible Operator dimensions");
140 
141  op[iblock] = opt;
142 }
143 
144 // Operator application
146 {
147  MFEM_ASSERT(x.Size() == width, "incorrect input Vector size");
148  MFEM_ASSERT(y.Size() == height, "incorrect output Vector size");
149 
150  yblock.Update(y.GetData(), offsets);
151  xblock.Update(x.GetData(), offsets);
152 
153  for (int i=0; i<nBlocks; ++i)
154  if (op[i])
155  op[i]->Mult(xblock.GetBlock(i), yblock.GetBlock(i));
156  else
157  yblock.GetBlock(i) = xblock.GetBlock(i);
158 }
159 
160 // Action of the transpose operator
162 {
163  MFEM_ASSERT(x.Size() == height, "incorrect input Vector size");
164  MFEM_ASSERT(y.Size() == width, "incorrect output Vector size");
165 
166  yblock.Update(y.GetData(), offsets);
167  xblock.Update(x.GetData(), offsets);
168 
169  for (int i=0; i<nBlocks; ++i)
170  if (op[i])
171  (op[i])->MultTranspose(xblock.GetBlock(i), yblock.GetBlock(i));
172  else
173  yblock.GetBlock(i) = xblock.GetBlock(i);
174 }
175 
177 {
178  if (owns_blocks)
179  for (int i=0; i<nBlocks; ++i)
180  delete op[i];
181 }
182 
183 }
void SetSize(int s)
Resizes the vector if the new size is different.
Definition: vector.hpp:248
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols.
Definition: operator.hpp:41
int Size() const
Returns the size of the vector.
Definition: vector.hpp:76
void Update(double *data, const Array< int > &bOffsets)
Update method.
Definition: blockvector.cpp:61
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator.
void SetBlock(int iRow, int iCol, Operator *op)
Add a block op in the block-entry (iblock, jblock).
double * GetData() const
Definition: vector.hpp:80
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows.
Definition: operator.hpp:35
void SetDiagonalBlock(int iblock, Operator *op)
Add block op in the block-entry (iblock, iblock).
BlockDiagonalPreconditioner(const Array< int > &offsets)
Constructor that specifies the block structure.
BlockOperator(const Array< int > &offsets)
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
int NumRows() const
Definition: operator.hpp:38
int NumCols() const
Definition: operator.hpp:44
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator.
virtual void Mult(const Vector &x, Vector &y) const
Operator application.
void MakeRef(T *, int)
Make this Array a reference to a poiter.
Definition: array.hpp:416
Vector data type.
Definition: vector.hpp:29
Base class for solvers.
Definition: operator.hpp:102
Abstract operator.
Definition: operator.hpp:21
Vector & GetBlock(int i)
Get the i-th vector in the block.
void SetDiagonalBlock(int iblock, Operator *op)
Add a square block op in the block-entry (iblock, iblock).