10 #include "EpetraExt_BlockMultiVector.h"
30 label(
"Stokhos KL Reduced Matrix Free Operator"),
33 epetraCijk(epetraCijk_),
34 domain_base_map(domain_base_map_),
35 range_base_map(range_base_map_),
36 domain_sg_map(domain_sg_map_),
37 range_sg_map(range_sg_map_),
38 Cijk(epetraCijk->getParallelCijk()),
42 expansion_size(sg_basis->size()),
64 num_blocks = block_ops->
size();
68 block_ops->getCoeffPtr(0));
71 domain_base_map->Comm()));
74 sg_basis, block_ops->map(), block_vec_map, sg_comm));
103 useTranspose = UseTheTranspose;
104 kl_mat_free_op->SetUseTranspose(useTranspose);
105 for (
int i=0; i<num_blocks; i++)
106 (*block_ops)[i].SetUseTranspose(useTranspose);
115 return kl_mat_free_op->Apply(Input, Result);
122 throw "KLReducedMatrixFreeOperator::ApplyInverse not defined!";
138 return const_cast<char*
>(label.c_str());
166 return *range_sg_map;
167 return *domain_sg_map;
175 return *domain_sg_map;
176 return *range_sg_map;
183 #ifdef HAVE_STOKHOS_ANASAZI
184 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
189 block_ops->getCoeffPtr(0));
192 for (
int coeff=0; coeff<num_blocks; coeff++) {
195 (block_ops->getCoeffPtr(coeff));
197 for (
int i=0; i<mean->NumMyRows(); i++) {
200 for (
int j=0;
j<num_col;
j++)
201 (*block_vec_poly)[coeff][row++] = (*block_coeff)[i][
j];
205 int myPID = sg_comm->MyPID();
208 Stokhos::PCEAnasaziKL pceKL(*block_vec_poly, num_KL);
210 bool result = pceKL.computeKL(anasazi_params);
211 if (!result && myPID == 0)
212 std::cout <<
"KL Eigensolver did not converge!" << std::endl;
217 std::cout <<
"num computed eigenvectors = "
218 << evecs->NumVectors() << std::endl;
219 double kl_tol = params->get(
"KL Tolerance", 1e-6);
221 while (num_KL_computed < evals.
size() &&
222 std::sqrt(evals[num_KL_computed]/evals[0]) > kl_tol)
224 if (num_KL_computed == evals.
size() && myPID == 0)
225 std::cout <<
"Can't achieve KL tolerance " << kl_tol
226 <<
". Smallest eigenvalue / largest eigenvalue = "
227 <<
std::sqrt(evals[num_KL_computed-1]/evals[0]) << std::endl;
229 std::cout <<
"num KL eigenvectors = " << num_KL_computed << std::endl;
232 dot_products.resize(num_KL_computed);
233 for (
int rv=0; rv < num_KL_computed; rv++) {
234 dot_products[rv].resize(num_blocks-1);
235 for (
int coeff=1; coeff < num_blocks; coeff++) {
237 (*block_vec_poly)[coeff].Dot(*((*evecs)(rv)), &dot);
238 dot_products[rv][coeff-1] =
dot;
247 i_it!=Cijk->i_end(); ++i_it) {
248 int i = epetraCijk->GRID(index(i_it));
249 sparse_kl_coeffs->sum_term(i, i, 0, norms[i]);
256 j_it != Cijk->j_end(l_it); ++j_it) {
257 int j = epetraCijk->GCID(index(j_it));
259 i_it != Cijk->i_end(j_it); ++i_it) {
260 int i = epetraCijk->GRID(index(i_it));
261 double c = value(i_it);
262 for (
int k=1; k<num_KL_computed+1; k++) {
263 double dp = dot_products[k-1][l-1];
266 sparse_kl_coeffs->sum_term(i,j,k,v);
271 sparse_kl_coeffs->fillComplete();
273 bool save_tensor = params->get(
"Save Sparse 3 Tensor To File",
false);
276 std::string basename = params->get(
"Sparse 3 Tensor Base Filename",
278 std::stringstream ss;
279 ss << basename <<
"_" << idx++ <<
".mm";
281 *(epetraCijk->getStochasticRowMap()), ss.str());
285 kl_blocks.resize(num_KL_computed);
288 sg_comm->TimeDomainComm()));
291 sg_basis, kl_map, domain_base_map, range_base_map,
292 range_sg_map, sg_comm));
293 kl_ops->setCoeffPtr(0, mean);
294 for (
int rv=0; rv<num_KL_computed; rv++) {
298 for (
int i=0; i<mean->NumMyRows(); i++) {
300 mean->NumMyRowEntries(i, num_col);
301 for (
int j=0;
j<num_col;
j++)
302 (*kl_blocks[rv])[i][
j] = (*evecs)[rv][row++];
304 kl_ops->setCoeffPtr(rv+1, kl_blocks[rv]);
309 sg_basis, sparse_kl_coeffs, sg_comm,
310 epetraCijk->getStochasticRowMap(), sparse_kl_coeffs,
316 sg_comm, sg_basis, reducedEpetraCijk,
317 domain_base_map, range_base_map,
318 domain_sg_map, range_sg_map, params));
319 kl_mat_free_op->setupOperator(kl_ops);
322 if (do_error_tests) {
324 for (
int i=0; i<sg_basis->dimension(); i++)
327 sg_basis->evaluateBases(point, basis_vals);
331 block_vec_poly->evaluate(basis_vals, val);
332 val_kl.Update(1.0, (*block_vec_poly)[0], 0.0);
335 for (
int rv=0; rv<num_KL_computed; rv++) {
336 rvs[rv].reset(sg_basis);
338 for (
int coeff=1; coeff<num_blocks; coeff++)
339 rvs[rv][coeff] = dot_products[rv][coeff-1];
340 val_rvs[rv] = rvs[rv].evaluate(point, basis_vals);
341 val_kl.Update(val_rvs[rv], *((*evecs)(rv)), 1.0);
345 val.Update(-1.0, val_kl, 1.0);
349 std::cout <<
"Infinity norm of random field difference = " << diff/nrm
353 Epetra_Vector op_input(*domain_sg_map), op_result(*range_sg_map), op_kl_result(*range_sg_map);
354 op_input.PutScalar(1.0);
356 domain_base_map, range_base_map,
357 domain_sg_map, range_sg_map, params);
359 op.
Apply(op_input, op_result);
360 this->Apply(op_input, op_kl_result);
361 op_result.NormInf(&nrm);
362 op_result.Update(-1.0, op_kl_result, 1.0);
363 op_result.NormInf(&diff);
365 std::cout <<
"Infinity norm of operator difference = " << diff/nrm
371 "Stokhos::KLReducedMatrixFreeOperator is available " <<
372 "only when configured with Anasazi support!")
int NumMyRowEntries(int MyRow, int &NumEntries) const
KOKKOS_INLINE_FUNCTION PCE< Storage > sqrt(const PCE< Storage > &a)
virtual const Epetra_Map & OperatorDomainMap() const
Returns the Epetra_Map object associated with the domain of this matrix operator. ...
virtual int ApplyInverse(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
Returns the result of the inverse of the operator applied to a Epetra_MultiVector Input in Result as ...
An Epetra operator representing the block stochastic Galerkin operator.
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
A container class storing an orthogonal polynomial whose coefficients are vectors, operators, or in general any type that would have an expensive copy constructor.
virtual bool HasNormInf() const
Returns true if the this object can provide an approximate Inf-norm, false otherwise.
void transformToLocal()
Transform Cijk to local i and j indices.
T & get(ParameterList &l, const std::string &name)
void sparse3Tensor2MatrixMarket(const Stokhos::OrthogPolyBasis< ordinal_type, value_type > &basis, const Stokhos::Sparse3Tensor< ordinal_type, value_type > &Cijk, const Epetra_Comm &comm, const std::string &file)
virtual const char * Label() const
Returns a character string describing the operator.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void setup()
Setup KL blocks.
virtual int Apply(const Epetra_MultiVector &Input, Epetra_MultiVector &Result) const
Returns the result of a Epetra_Operator applied to a Epetra_MultiVector Input in Result as described ...
virtual double NormInf() const
Returns an approximate infinity norm of the operator matrix.
std::enable_if< Kokkos::is_view_uq_pce< Kokkos::View< XD, XP...> >::value &&Kokkos::is_view_uq_pce< Kokkos::View< YD, YP...> >::value, typename Kokkos::Details::InnerProductSpaceTraits< typename Kokkos::View< XD, XP...>::non_const_value_type >::dot_type >::type dot(const Kokkos::View< XD, XP...> &x, const Kokkos::View< YD, YP...> &y)
virtual Teuchos::RCP< Stokhos::EpetraOperatorOrthogPoly > getSGPolynomial()
Get SG polynomial.
Bi-directional iterator for traversing a sparse array.
int num_KL
Number of KL terms.
bool do_error_tests
Whether to do KL error tests (can be expensive)
KLReducedMatrixFreeOperator(const Teuchos::RCP< const EpetraExt::MultiComm > &sg_comm, const Teuchos::RCP< const Stokhos::OrthogPolyBasis< int, double > > &sg_basis, const Teuchos::RCP< const Stokhos::EpetraSparse3Tensor > &epetraCijk, const Teuchos::RCP< const Epetra_Map > &domain_base_map, const Teuchos::RCP< const Epetra_Map > &range_base_map, const Teuchos::RCP< const Epetra_Map > &domain_sg_map, const Teuchos::RCP< const Epetra_Map > &range_sg_map, const Teuchos::RCP< Teuchos::ParameterList > ¶ms)
Constructor.
virtual void setupOperator(const Teuchos::RCP< Stokhos::EpetraOperatorOrthogPoly > &poly)
Setup operator.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
A container class storing an orthogonal polynomial whose coefficients are vectors, operators, or in general any type that would have an expensive copy constructor.
UnitTestSetup< int, double > setup
double drop_tolerance
Tolerance for dropping entries in sparse 3 tensor.
KOKKOS_INLINE_FUNCTION PCE< Storage > abs(const PCE< Storage > &a)
virtual int Apply(const Epetra_MultiVector &Input, Epetra_MultiVector &Result) const
Returns the result of a Epetra_Operator applied to a Epetra_MultiVector Input in Result as described ...
virtual const Epetra_Comm & Comm() const
Returns a reference to the Epetra_Comm communicator associated with this operator.
Teuchos::RCP< Teuchos::ParameterList > params
Algorithmic parameters.
virtual int SetUseTranspose(bool UseTranspose)
Set to true if the transpose of the operator is requested.
virtual void setupOperator(const Teuchos::RCP< Stokhos::EpetraOperatorOrthogPoly > &poly)
Setup operator.
ordinal_type size() const
Return size.
virtual ~KLReducedMatrixFreeOperator()
Destructor.
virtual bool UseTranspose() const
Returns the current UseTranspose setting.
virtual const Epetra_Map & OperatorRangeMap() const
Returns the Epetra_Map object associated with the range of this matrix operator.