2
// ***********************************************************************
4
// Thyra: Interfaces and Support for Abstract Numerical Algorithms
5
// Copyright (2004) Sandia Corporation
7
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8
// license for use of this work by or on behalf of the U.S. Government.
10
// This library is free software; you can redistribute it and/or modify
11
// it under the terms of the GNU Lesser General Public License as
12
// published by the Free Software Foundation; either version 2.1 of the
13
// License, or (at your option) any later version.
15
// This library is distributed in the hope that it will be useful, but
16
// WITHOUT ANY WARRANTY; without even the implied warranty of
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
// Lesser General Public License for more details.
20
// You should have received a copy of the GNU Lesser General Public
21
// License along with this library; if not, write to the Free Software
22
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24
// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
26
// ***********************************************************************
29
#ifndef THYRA_SCALAR_PROD_BASE_DECL_HPP
30
#define THYRA_SCALAR_PROD_BASE_DECL_HPP
32
#include "Thyra_OperatorVectorTypes.hpp"
33
#include "Thyra_EuclideanLinearOpBaseDecl.hpp"
39
/** \brief Abstract interface for scalar products.
41
* This interface is not considered a user-level interface. Instead, this
42
* interface is designed to be sub-classed off of and used with
43
* <tt>ScalarProdVectorSpaceBase</tt> objects to define their scalar products.
44
* Applications should create subclasses of this interface to define
45
* application-specific scalar products (i.e. such as PDE finite-element codes
48
* This interface requires subclasses to override a multi-vector version of
49
* the scalar product function <tt>scalarProds()</tt>. This version yields
50
* the most efficient implementation in a distributed memory environment by
51
* requiring only a single global reduction operation and a single
54
* Note that one of the preconditions on the vector and multi-vector arguments
55
* in <tt>scalarProds()</tt> is a little vague in stating that the vector or
56
* multi-vector objects must be "compatible" with the underlying
57
* implementation of <tt>*this</tt>. The reason that this precondition must
58
* be vague is that we can not expose a method to return a
59
* <tt>VectorSpaceBase</tt> object that could be checked for compatibility
60
* since <tt>%ScalarProdBase</tt> is used to define a <tt>VectorSpaceBase</tt>
61
* object (through the <tt>ScalarProdVectorSpaceBase</tt> node subclass).
62
* Also, some definitions of <tt>%ScalarProdBase</tt>
63
* (i.e. <tt>EuclideanScalarProd</tt>) will work for any vector space
64
* implementation since they only rely on <tt>RTOp</tt> operators. In other
65
* cases, however, an application-specific scalar product may a have
66
* dependency on the data-structure of vector and multi-vector objects in
67
* which case one can not just use this with any vector or multi-vector
70
* This interface class also defines functions to modify the application of a
71
* Euclidean linear operator to insert the definition of the application
72
* specific scalar product.
74
* \ingroup Thyra_Op_Vec_basic_adapter_support_grp
76
template<class Scalar>
77
class ScalarProdBase {
80
/** @name Destructor */
84
virtual ~ScalarProdBase() {}
88
/** @name Non-virtual public interface */
91
/** \brief Return if this is a Euclidean (identity) scalar product is the
92
* same as the dot product.
94
* The default implementation returns <tt>false</tt> (evenn though on average
95
* the truth is most likely <tt>true</tt>).
97
bool isEuclidean() const
98
{ return isEuclideanImpl(); }
100
/** \brief Return the scalar product of two vectors in the vector space.
102
* <b>Preconditions:</b><ul>
104
* <li>The vectors <tt>x</tt> and <tt>y</tt> are <em>compatible</em> with
105
* <tt>*this</tt> implementation or an exception will be thrown.
107
* <li><tt>x.space()->isCompatible(*y.space())</tt> (throw
108
* <tt>Exceptions::IncompatibleVectorSpaces</tt>)
112
* <b>Postconditions:</b><ul>
114
* <li>The scalar product is returned.
118
* The default implementation calls on the multi-vector version
119
* <tt>scalarProds()</tt>.
122
const VectorBase<Scalar>& x, const VectorBase<Scalar>& y
124
{ return scalarProdImpl(x, y); }
126
/** \brief Return the scalar product of each column in two multi-vectors in
129
* \param X [in] Multi-vector.
131
* \param Y [in] Multi-vector.
133
* \param scalar_prod [out] Array (length <tt>X.domain()->dim()</tt>)
134
* containing the scalar products <tt>scalar_prod[j] =
135
* this->scalarProd(*X.col(j),*Y.col(j))</tt>, for <tt>j = 0
136
* ... X.domain()->dim()-1</tt>.
138
* <b>Preconditions:</b><ul>
140
* <li><tt>X.domain()->isCompatible(*Y.domain())</tt> (throw
141
* <tt>Exceptions::IncompatibleVectorSpaces</tt>)
143
* <li><tt>X.range()->isCompatible(*Y.range())</tt> (throw
144
* <tt>Exceptions::IncompatibleVectorSpaces</tt>)
146
* <li>The MultiVectorBase objects <tt>X</tt> and <tt>Y</tt> are
147
* <em>compatible</em> with this implementation or an exception will be
152
* <b>Postconditions:</b><ul>
154
* <li><tt>scalar_prod[j] = this->scalarProd(*X.col(j),*Y.col(j))</tt>, for
155
* <tt>j = 0 ... X.domain()->dim()-1</tt>
160
const MultiVectorBase<Scalar>& X, const MultiVectorBase<Scalar>& Y,
161
const ArrayView<Scalar> &scalarProds_out
163
{ scalarProdsImpl(X, Y, scalarProds_out); }
165
/** \brief Modify the application of a Euclidean linear operator by
166
* inserting the vector space's scalar product.
168
* Note that one responsibility of an implementation of this function is to
169
* provide the block scalar product implementation of
170
* <tt>MultiVectorBase</tt> objects that derive from
171
* <tt>EuclideanLinearOpBase</tt>. For example, let <tt>M</tt> be a
172
* <tt>%MultiVectorBase</tt> object and consider the operation
174
<tt>Y = adjoint(M)*X</tt>
176
* where <tt>M_trans==CONJTRANS</tt>. This function may, or many not, call
177
* the <tt>EuclideanLinearOpBase::euclideanApplyTranspose()</tt> function in
178
* order to implement this block Scalar product.
180
* Note that the special case of <tt>M==X</tt> should also be supported
181
* which provides the symmetric operation
183
<tt>Y = adjoint(X)*X</tt>
185
* that can be performed in half the flops as the general case.
187
* ToDo: Finish documentation!
190
const EuclideanLinearOpBase<Scalar> &M,
191
const EOpTransp M_trans,
192
const MultiVectorBase<Scalar> &X,
193
const Ptr<MultiVectorBase<Scalar> > &Y,
197
{ euclideanApplyImpl(M, M_trans, X, Y, alpha, beta); }
203
/** \brief Protected virtual functions. */
207
virtual bool isEuclideanImpl() const = 0;
209
/** \brief Default implementation calls scalarProdsImpl(). */
210
virtual Scalar scalarProdImpl(
211
const VectorBase<Scalar>& x, const VectorBase<Scalar>& y ) const;
214
virtual void scalarProdsImpl(
215
const MultiVectorBase<Scalar>& X, const MultiVectorBase<Scalar>& Y,
216
const ArrayView<Scalar> &scalarProds_out
220
virtual void euclideanApplyImpl(
221
const EuclideanLinearOpBase<Scalar> &M,
222
const EOpTransp M_trans,
223
const MultiVectorBase<Scalar> &X,
224
const Ptr<MultiVectorBase<Scalar> > &Y,
234
} // end namespace Thyra
237
#endif // THYRA_SCALAR_PROD_BASE_DECL_HPP