13 #include "EpetraExt_MatrixMatrix.h"
20 struct KL_Diffusion_Func {
25 KL_Diffusion_Func(
double xyLeft,
double xyRight,
26 double mean_,
double std_dev,
27 double L,
int num_KL) : mean(mean_), point(2)
30 rfParams.
set(
"Number of KL Terms", num_KL);
31 rfParams.
set(
"Mean", mean);
32 rfParams.
set(
"Standard Deviation", std_dev);
35 correlation_length(ndim);
36 for (
int i=0; i<ndim; i++) {
37 domain_upper[i] = xyRight;
38 domain_lower[i] = xyLeft;
39 correlation_length[i] = L;
41 rfParams.
set(
"Domain Upper Bounds", domain_upper);
42 rfParams.
set(
"Domain Lower Bounds", domain_lower);
43 rfParams.
set(
"Correlation Lengths", correlation_length);
49 ~KL_Diffusion_Func() {
52 double operator() (
double x,
double y,
int k)
const {
57 return rf->evaluate_eigenfunction(point, k-1);
63 template <
typename DiffusionFunc>
64 struct Normalized_KL_Diffusion_Func {
65 const DiffusionFunc& func;
69 Normalized_KL_Diffusion_Func(
70 const DiffusionFunc& func_,
78 for(
int k=0; k<d; k++) {
86 double operator() (
double x,
double y,
int k)
const {
88 double val = func(x, y, 0);
89 for (
int i=1; i<=d; i++)
90 val -= psi_0[i]/(psi_1[i]-psi_0[i])*func(x, y, i);
95 return 1.0/(psi_1[k]-psi_0[k])*func(x, y, k);
100 template <
typename DiffusionFunc>
101 struct LogNormal_Diffusion_Func {
103 const DiffusionFunc& func;
106 LogNormal_Diffusion_Func(
108 const DiffusionFunc& func_,
110 : mean(mean_), func(func_), prodbasis(prodbasis_) {}
112 double operator() (
double x,
double y,
int k)
const {
113 int d = prodbasis->dimension();
116 double sum_g = 0.0, efval;
117 for (
int l=0; l<d; l++) {
120 efval =
std::exp(mean + 0.5*sum_g)/norms[k];
121 for (
int l=0; l<d; l++) {
122 efval *=
std::pow(func(x,y,l+1),multiIndex[l]);
140 log_normal(log_normal_),
141 eliminate_bcs(eliminate_bcs_),
142 precParams(precParams_)
144 Kokkos::initialize();
157 h = (xyRight - xyLeft)/((
double)(n-1));
159 for (
int j=0;
j<n;
j++) {
160 double y = xyLeft +
j*
h;
161 for (
int i=0; i<n; i++) {
162 double x = xyLeft + i*
h;
166 if (i == 0 || i == n-1 ||
j == 0 ||
j == n-1)
167 mesh[idx].boundary =
true;
169 mesh[idx].left = idx-1;
171 mesh[idx].right = idx+1;
173 mesh[idx].down = idx-n;
175 mesh[idx].up = idx+n;
182 int n_global_dof = global_dof_indices.
size();
184 int proc_id = comm->
MyPID();
185 int n_my_dof = n_global_dof / n_proc;
186 if (proc_id == n_proc-1)
187 n_my_dof += n_global_dof % n_proc;
188 int *my_dof = global_dof_indices.
getRawPtr() + proc_id*(n_global_dof / n_proc);
208 for (
int i=0;i<d;i++) {
209 std::stringstream ss;
210 ss <<
"KL Random Variable " << i+1;
211 (*p_names)[i] = ss.str();
215 int NumMyElements = x_map->NumMyElements();
216 int *MyGlobalElements = x_map->MyGlobalElements();
218 for (
int i=0; i<NumMyElements; ++i ) {
221 int global_idx = MyGlobalElements[i];
224 if (!
mesh[global_idx].boundary) {
245 KL_Diffusion_Func klFunc(xyLeft, xyRight, mu, s, 1.0, d);
252 Normalized_KL_Diffusion_Func<KL_Diffusion_Func> nklFunc(klFunc, *basis);
258 int sz = basis->
size();
262 LogNormal_Diffusion_Func<KL_Diffusion_Func> lnFunc(mu, klFunc, prodbasis);
271 for(
int i=0 ; i<NumMyElements; ++i ) {
272 int global_idx = MyGlobalElements[i];
273 if (
mesh[global_idx].boundary)
285 std::string name =
precParams->
get(
"Preconditioner Type",
"Ifpack");
322 "Error! twoD_diffusion_ME::get_p_map(): " <<
323 "Invalid parameter index l = " << l << std::endl);
335 "Error! twoD_diffusion_ME::get_g_map(): " <<
336 "Invalid parameter index l = " << l << std::endl);
348 "Error! twoD_diffusion_ME::get_p_names(): " <<
349 "Invalid parameter index l = " << l << std::endl);
368 "Error! twoD_diffusion_ME::get_p_init(): " <<
369 "Invalid parameter index l = " << l << std::endl);
392 return Teuchos::rcp(
new EpetraExt::ModelEvaluator::Preconditioner(precOp,
398 EpetraExt::ModelEvaluator::InArgs
403 inArgs.setModelEvalDescription(
"TwoD Diffusion Model Evaluator");
406 inArgs.setSupports(IN_ARG_x,
true);
410 inArgs.setSupports(IN_ARG_x_sg,
true);
411 inArgs.setSupports(IN_ARG_p_sg, 0,
true);
412 inArgs.setSupports(IN_ARG_sg_basis,
true);
413 inArgs.setSupports(IN_ARG_sg_quadrature,
true);
414 inArgs.setSupports(IN_ARG_sg_expansion,
true);
417 inArgs.setSupports(IN_ARG_x_mp,
true);
418 inArgs.setSupports(IN_ARG_p_mp, 0,
true);
423 EpetraExt::ModelEvaluator::OutArgs
427 OutArgsSetup outArgs;
428 outArgs.setModelEvalDescription(
"TwoD Diffusion Model Evaluator");
431 outArgs.set_Np_Ng(1, 1);
432 outArgs.setSupports(OUT_ARG_f,
true);
433 outArgs.setSupports(OUT_ARG_W,
true);
435 outArgs.setSupports(OUT_ARG_WPrec,
true);
438 outArgs.setSupports(OUT_ARG_f_sg,
true);
439 outArgs.setSupports(OUT_ARG_W_sg,
true);
440 outArgs.setSupports(OUT_ARG_g_sg, 0,
true);
443 outArgs.setSupports(OUT_ARG_f_mp,
true);
444 outArgs.setSupports(OUT_ARG_W_mp,
true);
445 outArgs.setSupports(OUT_ARG_g_mp, 0,
true);
452 evalModel(
const InArgs& inArgs,
const OutArgs& outArgs)
const
477 EpetraExt::MatrixMatrix::Add((*
A_k[k]),
false,
basis_vals[k], *
A, 1.0);
482 EpetraExt::MatrixMatrix::Add((*
A_k[k]),
false, (*p)[k-1], *
A, 1.0);
485 A->OptimizeStorage();
491 A->Apply(*det_x,*kx);
492 f->Update(1.0,*kx,-1.0, *
b, 0.0);
501 jac->OptimizeStorage();
511 (det_x->MeanValue(&(*g)[0]));
512 (*g)[0] *=
double(det_x->GlobalLength()) /
double(
mesh.size());
520 InArgs::sg_const_vector_t x_sg = inArgs.get_x_sg();
523 InArgs::sg_const_vector_t p_sg = inArgs.get_p_sg(0);
526 OutArgs::sg_vector_t f_sg = outArgs.get_f_sg();
531 inArgs.get_sg_expansion();
538 for (
int i=0;i<basis->
size();i++) {
544 Cijk_type::k_iterator k_begin = Cijk->k_begin();
545 Cijk_type::k_iterator k_end = Cijk->k_end();
546 for (Cijk_type::k_iterator k_it=k_begin; k_it!=k_end; ++k_it) {
547 int k = Stokhos::index(k_it);
548 for (Cijk_type::kj_iterator j_it = Cijk->j_begin(k_it);
549 j_it != Cijk->j_end(k_it); ++j_it) {
550 int j = Stokhos::index(j_it);
553 for (Cijk_type::kj_iterator j_it = Cijk->j_begin(k_it);
554 j_it != Cijk->j_end(k_it); ++j_it) {
555 int j = Stokhos::index(j_it);
556 for (Cijk_type::kji_iterator i_it = Cijk->i_begin(j_it);
557 i_it != Cijk->i_end(j_it); ++i_it) {
558 int i = Stokhos::index(i_it);
559 double c = Stokhos::value(i_it);
564 (*f_sg)[0].Update(-1.0,*
b,1.0);
568 OutArgs::sg_operator_t W_sg = outArgs.get_W_sg();
570 for (
int i=0; i<W_sg->size(); i++) {
575 jac->OptimizeStorage();
583 int sz = x_sg->
size();
584 for (
int i=0; i<sz; i++) {
585 (*x_sg)[i].MeanValue(&(*g_sg)[i][0]);
595 mp_const_vector_t x_mp = inArgs.get_x_mp();
598 mp_const_vector_t p_mp = inArgs.get_p_mp(0);
601 mp_vector_t f_mp = outArgs.get_f_mp();
602 mp_operator_t W_mp = outArgs.get_W_mp();
604 int num_mp = x_mp->size();
605 for (
int i=0; i<num_mp; i++) {
609 point[k] = (*p_mp)[i][k];
619 EpetraExt::MatrixMatrix::Add((*
A_k[k]),
false, (*p_mp)[i][k-1], *
A,
624 A->OptimizeStorage();
628 A->Apply((*x_mp)[i], (*f_mp)[i]);
629 (*f_mp)[i].Update(-1.0, *
b, 1.0);
639 jac->OptimizeStorage();
645 mp_vector_t g_mp = outArgs.get_g_mp(0);
647 int sz = x_mp->size();
648 for (
int i=0; i<sz; i++) {
649 (*x_mp)[i].MeanValue(&(*g_mp)[i][0]);
Teuchos::RCP< const Epetra_Vector > get_x_init() const
Return initial solution.
void evalModel(const InArgs &inArgs, const OutArgs &outArgs) const
Evaluate model on InArgs.
KOKKOS_INLINE_FUNCTION PCE< Storage > pow(const PCE< Storage > &a, const PCE< Storage > &b)
T & get(ParameterList &l, const std::string &name)
Teuchos::Array< Teuchos::RCP< Epetra_CrsMatrix > > A_k
KL coefficients of operator.
Teuchos::RCP< Epetra_Vector > x_init
Initial guess.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Teuchos::RCP< Epetra_Map > p_map
Parameter vector map.
RCP< ParameterList > sublist(const RCP< ParameterList > ¶mList, const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
virtual void evaluateBases(const Teuchos::ArrayView< const value_type > &point, Teuchos::Array< value_type > &basis_vals) const =0
Evaluate basis polynomials at given point point.
int InsertGlobalIndices(int_type GlobalRow, int NumIndices, int_type *Indices)
virtual void recompute(const Teuchos::RCP< Epetra_Operator > &mat, const Teuchos::RCP< Epetra_Operator > &prec)=0
Recompute preconditioner operator for a new matrix.
virtual int MyPID() const =0
int FillComplete(bool OptimizeDataStorage=true)
Teuchos::RCP< const Epetra_Vector > get_p_init(int l) const
Return initial parameters.
A multidimensional index.
Teuchos::RCP< Stokhos::AbstractPreconditionerFactory > precFactory
Teuchos::RCP< Epetra_CrsGraph > graph
Jacobian graph.
Teuchos::Array< MeshPoint > mesh
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< Teuchos::ParameterList > precParams
virtual Teuchos::RCP< Epetra_Operator > compute(const Teuchos::RCP< Epetra_Operator > &mat, bool compute_prec=true)=0
Compute preconditioner operator.
Teuchos::Array< double > basis_vals
Array to store values of basis at a point.
void resize(size_type new_size, const value_type &x=value_type())
~twoD_diffusion_ME()
Destructor.
virtual const Teuchos::Array< value_type > & norm_squared() const =0
Return array storing norm-squared of each basis polynomial.
Teuchos::RCP< const Epetra_Map > get_p_map(int l) const
Return parameter vector map.
KOKKOS_INLINE_FUNCTION PCE< Storage > exp(const PCE< Storage > &a)
Teuchos::RCP< const Epetra_Map > get_g_map(int j) const
Return response function map.
Teuchos::RCP< Epetra_Map > x_map
Solution vector map.
Stokhos::Sparse3Tensor< int, double > Cijk_type
Teuchos::RCP< Epetra_CrsMatrix > A
Matrix to store deterministic operator.
twoD_diffusion_ME(const Teuchos::RCP< const Epetra_Comm > &comm, int n, int d, double s=0.1, double mu=0.2, const Teuchos::RCP< const Stokhos::OrthogPolyBasis< int, double > > &basis=Teuchos::null, bool log_normal=false, bool eliminate_bcs=false, const Teuchos::RCP< Teuchos::ParameterList > &precParams=Teuchos::null)
Constructor.
Teuchos::RCP< Epetra_Operator > create_W() const
Create W = alpha*M + beta*J matrix.
An class for building preconditioners.
void push_back(const value_type &x)
InArgs createInArgs() const
Create InArgs.
OutArgs createOutArgs() const
Create OutArgs.
virtual int NumProc() const =0
Teuchos::RCP< Epetra_Vector > p_init
Initial parameters.
ScalarType f(const Teuchos::Array< ScalarType > &x, double a, double b)
Teuchos::RCP< EpetraExt::ModelEvaluator::Preconditioner > create_WPrec() const
Create preconditioner for W.
Class representing a KL expansion of an exponential random field.
Teuchos::RCP< const Epetra_Map > get_x_map() const
Return solution vector map.
Teuchos::RCP< Epetra_Vector > b
Deterministic RHS.
Teuchos::RCP< Teuchos::Array< std::string > > p_names
Parameter names.
Teuchos::Array< double > point
Array to store a point for basis evaluation.
void fillMatrices(const FuncT &func, int sz)
Fill coefficient matrix given function to evaluate diffusion coefficient.
ordinal_type size() const
Return size.
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int l) const
Return array of parameter names.
Teuchos::RCP< Epetra_Map > g_map
Response vector map.
virtual ordinal_type size() const =0
Return total size of basis.
Teuchos::RCP< const Stokhos::OrthogPolyBasis< int, double > > basis
Teuchos::Array< Teuchos::RCP< Epetra_Vector > > sg_kx_vec_all
Vectors to store matrix-vector products in SG residual calculation.
ScalarType g(const Teuchos::Array< ScalarType > &x, const ScalarType &y)
Teuchos::RCP< const Epetra_Map > get_f_map() const
Return residual vector map.