Teuchos::RCP< Stokhos::Sparse3Tensor<ordinal_type, value_type> >
Stokhos::TotalOrderBasis<ordinal_type, value_type, ordering_type>::
computeTripleProductTensor() const
{
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos: Total Triple-Product Tensor Fill Time");
#endif

  TotalOrderPredicate<ordinal_type> predicate(p, max_orders);
  
  return ProductBasisUtils::computeTripleProductTensor(
    bases, basis_set, basis_map, predicate, predicate, sparse_tol);
}
void
Stokhos::ApproxSchurComplementPreconditioner::
divide_diagonal_block(int row_begin, int row_end, 
		      const EpetraExt::BlockMultiVector& Input, 
		      EpetraExt::BlockMultiVector& Result) const
{
  for (int i=row_begin; i<row_end; i++) {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
      TEUCHOS_FUNC_TIME_MONITOR(
	"Stokhos: ASC Deterministic Preconditioner Time");
#endif
      mean_prec->ApplyInverse(*(Input.GetBlock(i)), *(Result.GetBlock(i)));
  }
}
示例#3
0
void
Stokhos::StieltjesPCEBasis<ordinal_type, value_type>::
stieltjes(ordinal_type nstart,
	  ordinal_type nfinish,
	  const Teuchos::Array<value_type>& weights,
	  const Teuchos::Array<value_type>& points,
	  Teuchos::Array<value_type>& a,
	  Teuchos::Array<value_type>& b,
	  Teuchos::Array<value_type>& nrm,
	  Teuchos::Array< Teuchos::Array<value_type> >& phi_vals) const
{
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::StieltjesPCEBasis -- Discretized Stieltjes Procedure");
#endif

  value_type val1, val2;   
  ordinal_type start = nstart;
  if (nstart == 0) {
    if (project_integrals)
      integrateBasisSquaredProj(0, a, b, weights, points, phi_vals, val1, val2);
    else
      integrateBasisSquared(0, a, b, weights, points, phi_vals, val1, val2);
    nrm[0] = val1;
    a[0] = val2/val1;
    b[0] = value_type(1);
    start = 1;
  }
  for (ordinal_type i=start; i<nfinish; i++) {
    if (project_integrals)
      integrateBasisSquaredProj(i, a, b, weights, points, phi_vals, val1, val2);
    else
      integrateBasisSquared(i, a, b, weights, points, phi_vals, val1, val2);
    // std::cout << "i = " << i << " val1 = " << val1 << " val2 = " << val2
    // 	      << std::endl;
    TEUCHOS_TEST_FOR_EXCEPTION(val1 < 0.0, std::logic_error,
		     "Stokhos::StieltjesPCEBasis::stieltjes():  "
		       << " Polynomial " << i << " out of " << nfinish 
		       << " has norm " << val1 
		       << "!  Try increasing number of quadrature points");
    nrm[i] = val1;
    a[i] = val2/val1;
    b[i] = nrm[i]/nrm[i-1];

    // std::cout << "i = " << i << " alpha = " << a[i] << " beta = " << b[i]
    // 	      << " nrm = " << nrm[i] << std::endl;
  }
}
示例#4
0
void 
Stokhos::FullyAssembledOperator::
setupOperator(
   const Teuchos::RCP<Stokhos::EpetraOperatorOrthogPoly >& ops)
{
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos: SG Fully Assembled Operator Assembly");
#endif

  block_ops = ops;

  // Zero out matrix
  this->PutScalar(0.0);

  // Compute loop bounds
  Cijk_type::k_iterator k_begin = Cijk->k_begin();
  Cijk_type::k_iterator k_end = Cijk->k_end();
  if (!include_mean && index(k_begin) == 0)
    ++k_begin;
  if (only_use_linear) {
    int dim = sg_basis->dimension();
    k_end = Cijk->find_k(dim+1);
  }

  // Assemble matrix
  const Teuchos::Array<double>& norms = sg_basis->norm_squared();
  for (Cijk_type::k_iterator k_it=k_begin; k_it!=k_end; ++k_it) {
    int k = index(k_it);
    Teuchos::RCP<Epetra_RowMatrix> block = 
      Teuchos::rcp_dynamic_cast<Epetra_RowMatrix>(block_ops->getCoeffPtr(k), 
						  true);
    for (Cijk_type::kj_iterator j_it = Cijk->j_begin(k_it); 
	 j_it != Cijk->j_end(k_it); ++j_it) {
      int j = epetraCijk->GCID(index(j_it));
      for (Cijk_type::kji_iterator i_it = Cijk->i_begin(j_it);
	   i_it != Cijk->i_end(j_it); ++i_it) {
	int i = epetraCijk->GRID(index(i_it));
	double c = value(i_it);
	if (scale_op)
	  c /= norms[i];
	this->SumIntoGlobalBlock(c, *block, i, j);
      }
    }
  }

  this->FillComplete(*domain_sg_map, *range_sg_map);
}
示例#5
0
void
Stokhos::StieltjesPCEBasis<ordinal_type, value_type>::
getQuadPoints(ordinal_type quad_order,
	      Teuchos::Array<value_type>& quad_points,
	      Teuchos::Array<value_type>& quad_weights,
	      Teuchos::Array< Teuchos::Array<value_type> >& quad_values) const
{
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::StieltjesPCEBasis -- compute Gauss points");
#endif

  // Use underlying pce's quad points, weights, values
  if (use_pce_quad_points) {
    quad_points = pce_vals;
    quad_weights = pce_weights;
    quad_values = phi_vals;
    return;
  }

  // Call base class
  ordinal_type num_points = 
    static_cast<ordinal_type>(std::ceil((quad_order+1)/2.0));

  // We can't reliably generate quadrature points of order > 2*p
  //if (!project_integrals && quad_order > 2*this->p)
  if (quad_order > 2*this->p)
    quad_order = 2*this->p;
  Stokhos::RecurrenceBasis<ordinal_type,value_type>::getQuadPoints(quad_order, 
								   quad_points, 
								   quad_weights,
								   quad_values);

  // Fill in the rest of the points with zero weight
  if (quad_weights.size() < num_points) {
    ordinal_type old_size = quad_weights.size();
    quad_weights.resize(num_points);
    quad_points.resize(num_points);
    quad_values.resize(num_points);
    for (ordinal_type i=old_size; i<num_points; i++) {
      quad_weights[i] = value_type(0);
      quad_points[i] = quad_points[0];
      quad_values[i].resize(this->p+1);
      this->evaluateBases(quad_points[i], quad_values[i]);
    }
  }
}
示例#6
0
bool NOX::Epetra::LinearSystemMPBD::
applyJacobianInverse(Teuchos::ParameterList &params, 
		     const NOX::Epetra::Vector &input, 
		     NOX::Epetra::Vector &result)
{
  TEUCHOS_FUNC_TIME_MONITOR("Total deterministic solve Time");

  // Extract blocks
  EpetraExt::BlockVector input_block(View, *base_map, 
				     input.getEpetraVector());
  EpetraExt::BlockVector result_block(View, *base_map, 
				      result.getEpetraVector());
  result_block.PutScalar(0.0);
   
  
  Teuchos::ParameterList& block_solver_params = 
    params.sublist("Deterministic Solver Parameters");
  
  // Solve block linear systems
  bool final_status = true;
  bool status;
  for (int i=0; i<num_mp_blocks; i++) {
    NOX::Epetra::Vector nox_input(input_block.GetBlock(i), 
				  NOX::Epetra::Vector::CreateView);
    NOX::Epetra::Vector nox_result(result_block.GetBlock(i), 
				   NOX::Epetra::Vector::CreateView);
    
    block_solver->setJacobianOperatorForSolve(block_ops->getCoeffPtr(i));

    if (precStrategy == STANDARD)
      block_solver->setPrecOperatorForSolve(precs[i]);
    else if (precStrategy == ON_THE_FLY) {
      block_solver->createPreconditioner(*(prec_x->GetBlock(i)), 
					 block_solver_params, false);
    }

    status = block_solver->applyJacobianInverse(block_solver_params, nox_input, 
						nox_result);
    final_status = final_status && status;
  }

  return final_status;
}
void
Stokhos::MonoProjPCEBasis<ordinal_type, value_type>::
getQuadPoints(ordinal_type quad_order,
	      Teuchos::Array<value_type>& quad_points,
	      Teuchos::Array<value_type>& quad_weights,
	      Teuchos::Array< Teuchos::Array<value_type> >& quad_values) const
{
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::MonoProjPCEBasis -- compute Gauss points");
#endif

  // Call base class
  ordinal_type num_points = 
    static_cast<ordinal_type>(std::ceil((quad_order+1)/2.0));

  // We can't always reliably generate quadrature points of order > 2*p
  // when using sparse grids for the underlying quadrature
  if (limit_integration_order && quad_order > 2*this->p)
    quad_order = 2*this->p;
  Stokhos::RecurrenceBasis<ordinal_type,value_type>::getQuadPoints(quad_order, 
								   quad_points, 
								   quad_weights,
								   quad_values);

  // Fill in the rest of the points with zero weight
  if (quad_weights.size() < num_points) {
    ordinal_type old_size = quad_weights.size();
    quad_weights.resize(num_points);
    quad_points.resize(num_points);
    quad_values.resize(num_points);
    for (ordinal_type i=old_size; i<num_points; i++) {
      quad_weights[i] = value_type(0);
      quad_points[i] = quad_points[0];
      quad_values[i].resize(this->p+1);
      evaluateBases(quad_points[i], quad_values[i]);
    }
  }
}
示例#8
0
void
Stokhos::PseudoSpectralOrthogPolyExpansion<ordinal_type, value_type, point_compare_type, node_type>::
divideEqual(
  Stokhos::OrthogPolyApprox<ordinal_type, value_type, node_type>& c, 
  const Stokhos::OrthogPolyApprox<ordinal_type, value_type, node_type>& x)
{
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::OrthogPolyExpansionBase::divideEqual(OPA)");
#endif
  if (x.size() == 1) {
    ordinal_type p = c.size();
    value_type* cc = c.coeff();
    const value_type* xc = x.coeff();
    for (ordinal_type i=0; i<p; i++)
      cc[i] /= xc[0];
  }
  else {
    if (use_quad_for_division)
      binary_op(div_quad_func(), c, c, x);
    else
      OrthogPolyExpansionBase<ordinal_type, value_type, node_type>::divideEqual(c, x);
  }
}
void
Stokhos::StieltjesPCEBasis<ordinal_type, value_type>::
getQuadPoints(ordinal_type quad_order,
	      Teuchos::Array<value_type>& quad_points,
	      Teuchos::Array<value_type>& quad_weights,
	      Teuchos::Array< Teuchos::Array<value_type> >& quad_values) const
{
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::StieltjesPCEBasis -- compute Gauss points");

  // Use underlying pce's quad points, weights, values
  if (use_pce_quad_points) {
    quad_points = pce_vals;
    quad_weights = pce_weights;
    quad_values = phi_vals;
    return;
  }

  // Call base class
  ordinal_type num_points = 
    static_cast<ordinal_type>(std::ceil((quad_order+1)/2.0));
  if (quad_order > 2*this->p)
    quad_order = 2*this->p;
  Stokhos::RecurrenceBasis<ordinal_type,value_type>::getQuadPoints(quad_order, 
								   quad_points, 
								   quad_weights,
								   quad_values);
  if (quad_weights.size() < num_points) {
    ordinal_type old_size = quad_weights.size();
    quad_weights.resize(num_points);
    quad_points.resize(num_points);
    quad_values.resize(num_points);
    for (ordinal_type i=old_size; i<num_points; i++) {
      quad_values[i].resize(this->p+1);
      evaluateBases(quad_points[i], quad_values[i]);
    }
  }
}
示例#10
0
void
Stokhos::PseudoSpectralOrthogPolyExpansion<ordinal_type, value_type, point_compare_type, node_type>::
nary_op(const FuncT& func,
	OrthogPolyApprox<ordinal_type, value_type, node_type>& c, 
	const OrthogPolyApprox<ordinal_type, value_type, node_type>** na)
{
  const int N = FuncT::N;
  bool is_constant = true;
  for (int i=0; i<N; i++) {
    if (na[i]->size() > 1) {
      is_constant = false;
      break;
    }
  }
  ordinal_type pc;
  if (is_constant)
    pc = 1;
  else
    pc = sz;
  if (c.size() != pc)
    c.resize(pc);

  if (pc == 1) {
    value_type val[N];
    for (int i=0; i<N; i++)
      val[i] = (*na[i])[0];
    c[0] = func(val);
    return;
  }

  if (N >= navals.size())
    navals.resize(N+1);
  if (navals[N].size() != N) {
    navals[N].resize(N);
    for (int i=0; i<N; i++)
      navals[N][i].resize(nqp);
  }
  
  {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::PSExp -- N(" << N << ")-ary Polynomial Evaluation");
#endif

  // Evaluate input
  for (int i=0; i<N; i++) {
    SDV sdv(Teuchos::View, const_cast<value_type*>(na[i]->coeff()), 
	    na[i]->size());
    ps_op->transformPCE2QP(1.0, sdv, navals[N][i], 0.0, false);
  }

  }

  {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::PSExp -- N(" << N << ")-ary Function Evaluation");
#endif

  // Evaluate function
  value_type val[N];
  for (ordinal_type qp=0; qp<nqp; qp++) {
    for (int i=0; i<N; i++)
      val[i] = navals[N][i][qp];
    fvals[qp] = func(val);
  }

  }

  {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::PSExp -- N(" << N << ")-ary Polynomial Integration");
#endif

  // Integrate
  SDV c_sdv(Teuchos::View, c.coeff(), pc);
  ps_op->transformQP2PCE(1.0, fvals, c_sdv, 0.0, false);

  }
}
示例#11
0
void
Stokhos::KLReducedMatrixFreeOperator::
setup()
{
#ifdef HAVE_STOKHOS_ANASAZI
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
    TEUCHOS_FUNC_TIME_MONITOR("Stokhos::KLReducedMatrixFreeOperator -- Calculation/setup of KL opeator");
#endif

    mean = Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>(
               block_ops->getCoeffPtr(0));

    // Copy matrix coefficients into vectors
    for (int coeff=0; coeff<num_blocks; coeff++) {
        Teuchos::RCP<const Epetra_CrsMatrix> block_coeff =
            Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>
            (block_ops->getCoeffPtr(coeff));
        int row = 0;
        for (int i=0; i<mean->NumMyRows(); i++) {
            int num_col;
            mean->NumMyRowEntries(i, num_col);
            for (int j=0; j<num_col; j++)
                (*block_vec_poly)[coeff][row++] = (*block_coeff)[i][j];
        }
    }

    int myPID = sg_comm->MyPID();

    // Compute KL expansion of solution sg_J_vec_poly
    Stokhos::PCEAnasaziKL pceKL(*block_vec_poly, num_KL);
    Teuchos::ParameterList anasazi_params = pceKL.getDefaultParams();
    bool result = pceKL.computeKL(anasazi_params);
    if (!result && myPID == 0)
        std::cout << "KL Eigensolver did not converge!" << std::endl;
    Teuchos::RCP<Epetra_MultiVector> evecs = pceKL.getEigenvectors();
    Teuchos::Array<double> evals = pceKL.getEigenvalues();
    //num_KL_computed = evecs->NumVectors();
    if (myPID == 0)
        std::cout << "num computed eigenvectors  = "
                  << evecs->NumVectors() << std::endl;
    double kl_tol = params->get("KL Tolerance", 1e-6);
    num_KL_computed = 0;
    while (num_KL_computed < evals.size() &&
            std::sqrt(evals[num_KL_computed]/evals[0]) > kl_tol)
        num_KL_computed++;
    if (num_KL_computed == evals.size() && myPID == 0)
        std::cout << "Can't achieve KL tolerance " << kl_tol
                  << ".  Smallest eigenvalue / largest eigenvalue = "
                  << std::sqrt(evals[num_KL_computed-1]/evals[0]) << std::endl;
    if (myPID == 0)
        std::cout << "num KL eigenvectors = " << num_KL_computed << std::endl;

    // Compute dot products of Jacobian blocks and KL eigenvectors
    dot_products.resize(num_KL_computed);
    for (int rv=0; rv < num_KL_computed; rv++) {
        dot_products[rv].resize(num_blocks-1);
        for (int coeff=1; coeff < num_blocks; coeff++) {
            double dot;
            (*block_vec_poly)[coeff].Dot(*((*evecs)(rv)), &dot);
            dot_products[rv][coeff-1] = dot;
        }
    }

    // Compute KL coefficients
    const Teuchos::Array<double>& norms = sg_basis->norm_squared();
    sparse_kl_coeffs =
        Teuchos::rcp(new Stokhos::Sparse3Tensor<int,double>);
    for (Cijk_type::i_iterator i_it=Cijk->i_begin();
            i_it!=Cijk->i_end(); ++i_it) {
        int i = epetraCijk->GRID(index(i_it));
        sparse_kl_coeffs->sum_term(i, i, 0, norms[i]);
    }
    Cijk_type::k_iterator l_begin = ++(Cijk->k_begin());
    Cijk_type::k_iterator l_end = Cijk->k_end();
    for (Cijk_type::k_iterator l_it=l_begin; l_it!=l_end; ++l_it) {
        int l = index(l_it);
        for (Cijk_type::kj_iterator j_it = Cijk->j_begin(l_it);
                j_it != Cijk->j_end(l_it); ++j_it) {
            int j = epetraCijk->GCID(index(j_it));
            for (Cijk_type::kji_iterator i_it = Cijk->i_begin(j_it);
                    i_it != Cijk->i_end(j_it); ++i_it) {
                int i = epetraCijk->GRID(index(i_it));
                double c = value(i_it);
                for (int k=1; k<num_KL_computed+1; k++) {
                    double dp = dot_products[k-1][l-1];
                    double v = dp*c;
                    if (std::abs(v) > drop_tolerance)
                        sparse_kl_coeffs->sum_term(i,j,k,v);
                }
            }
        }
    }
    sparse_kl_coeffs->fillComplete();

    bool save_tensor = params->get("Save Sparse 3 Tensor To File", false);
    if (save_tensor) {
        static int idx = 0;
        std::string basename = params->get("Sparse 3 Tensor Base Filename",
                                           "sparse_KL_coeffs");
        std::stringstream ss;
        ss << basename << "_" << idx++ << ".mm";
        sparse3Tensor2MatrixMarket(*sparse_kl_coeffs,
                                   *(epetraCijk->getStochasticRowMap()), ss.str());
    }

    // Transform eigenvectors back to matrices
    kl_blocks.resize(num_KL_computed);
    Teuchos::RCP<Epetra_BlockMap> kl_map =
        Teuchos::rcp(new Epetra_LocalMap(num_KL_computed+1, 0,
                                         sg_comm->TimeDomainComm()));
    kl_ops =
        Teuchos::rcp(new Stokhos::EpetraOperatorOrthogPoly(
                         sg_basis, kl_map, domain_base_map, range_base_map,
                         range_sg_map, sg_comm));
    kl_ops->setCoeffPtr(0, mean);
    for (int rv=0; rv<num_KL_computed; rv++) {
        if (kl_blocks[rv] == Teuchos::null)
            kl_blocks[rv] = Teuchos::rcp(new Epetra_CrsMatrix(*mean));
        int row = 0;
        for (int i=0; i<mean->NumMyRows(); i++) {
            int num_col;
            mean->NumMyRowEntries(i, num_col);
            for (int j=0; j<num_col; j++)
                (*kl_blocks[rv])[i][j] = (*evecs)[rv][row++];
        }
        kl_ops->setCoeffPtr(rv+1, kl_blocks[rv]);
    }

    Teuchos::RCP<Stokhos::EpetraSparse3Tensor> reducedEpetraCijk =
        Teuchos::rcp(new Stokhos::EpetraSparse3Tensor(
                         sg_basis, sparse_kl_coeffs, sg_comm,
                         epetraCijk->getStochasticRowMap(), sparse_kl_coeffs,
                         0, -1));
    reducedEpetraCijk->transformToLocal();

    // Create matrix-free op
    kl_mat_free_op = Teuchos::rcp(new Stokhos::MatrixFreeOperator(
                                      sg_comm, sg_basis, reducedEpetraCijk,
                                      domain_base_map, range_base_map,
                                      domain_sg_map, range_sg_map, params));
    kl_mat_free_op->setupOperator(kl_ops);

    // Check accuracy of KL expansion
    if (do_error_tests) {
        Teuchos::Array<double> point(sg_basis->dimension());
        for (int i=0; i<sg_basis->dimension(); i++)
            point[i] = 0.5;
        Teuchos::Array<double> basis_vals(sg_basis->size());
        sg_basis->evaluateBases(point, basis_vals);

        Epetra_Vector val(*block_vec_map);
        Epetra_Vector val_kl(*block_vec_map);
        block_vec_poly->evaluate(basis_vals, val);
        val_kl.Update(1.0, (*block_vec_poly)[0], 0.0);
        Teuchos::Array< Stokhos::OrthogPolyApprox<int,double> > rvs(num_KL_computed);
        Teuchos::Array<double> val_rvs(num_KL_computed);
        for (int rv=0; rv<num_KL_computed; rv++) {
            rvs[rv].reset(sg_basis);
            rvs[rv][0] = 0.0;
            for (int coeff=1; coeff<num_blocks; coeff++)
                rvs[rv][coeff] = dot_products[rv][coeff-1];
            val_rvs[rv] = rvs[rv].evaluate(point, basis_vals);
            val_kl.Update(val_rvs[rv], *((*evecs)(rv)), 1.0);
        }
        double nrm;
        val.NormInf(&nrm);
        val.Update(-1.0, val_kl, 1.0);
        double diff;
        val.NormInf(&diff);
        if (myPID == 0)
            std::cout << "Infinity norm of random field difference = " << diff/nrm
                      << std::endl;

        // Check accuracy of operator
        Epetra_Vector op_input(*domain_sg_map), op_result(*range_sg_map), op_kl_result(*range_sg_map);
        op_input.PutScalar(1.0);
        Stokhos::MatrixFreeOperator op(sg_comm, sg_basis, epetraCijk,
                                       domain_base_map, range_base_map,
                                       domain_sg_map, range_sg_map, params);
        op.setupOperator(block_ops);
        op.Apply(op_input, op_result);
        this->Apply(op_input, op_kl_result);
        op_result.NormInf(&nrm);
        op_result.Update(-1.0, op_kl_result, 1.0);
        op_result.NormInf(&diff);
        if (myPID == 0)
            std::cout << "Infinity norm of operator difference = " << diff/nrm
                      << std::endl;
    }

#else
    TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
                               "Stokhos::KLReducedMatrixFreeOperator is available " <<
                               "only when configured with Anasazi support!")
#endif
}
int 
Stokhos::ApproxSchurComplementPreconditioner::
ApplyInverse(const Epetra_MultiVector& Input, Epetra_MultiVector& Result) const
{
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos: Total Approximate Schur Complement Time");
#endif

  // We have to be careful if Input and Result are the same vector.
  // If this is the case, the only possible solution is to make a copy
  const Epetra_MultiVector *input = &Input;
  bool made_copy = false;
  if (Input.Values() == Result.Values()) {
    input = new Epetra_MultiVector(Input);
    made_copy = true;
  } 

  // Allocate temporary storage
  int m = input->NumVectors();
  if (rhs_block == Teuchos::null || rhs_block->NumVectors() != m)
    rhs_block = 
      Teuchos::rcp(new EpetraExt::BlockMultiVector(*base_map, *sg_map, m));
  if (tmp == Teuchos::null || tmp->NumVectors() != m*max_num_mat_vec)
    tmp = Teuchos::rcp(new Epetra_MultiVector(*base_map, 
					      m*max_num_mat_vec));
  j_ptr.resize(m*max_num_mat_vec);
  mj_indices.resize(m*max_num_mat_vec);
  
  // Extract blocks
  EpetraExt::BlockMultiVector input_block(View, *base_map, *input);
  EpetraExt::BlockMultiVector result_block(View, *base_map, Result);

  result_block.PutScalar(0.0);

  // Set right-hand-side to input_block
  rhs_block->Update(1.0, input_block, 0.0);

  // At level l, linear system has the structure
  // [ A_{l-1} B_l ][ u_l^{l-1} ] = [ r_l^{l-1} ]
  // [ C_l     D_l ][ u_l^l     ]   [ r_l^l     ]

  for (int l=P; l>=1; l--) {
    // Compute D_l^{-1} r_l^l
    divide_diagonal_block(block_indices[l], block_indices[l+1], 
			  *rhs_block, result_block);

    // Compute r_l^{l-1} = r_l^{l-1} - B_l D_l^{-1} r_l^l
    multiply_block(upper_block_Cijk[l], -1.0, result_block, *rhs_block);
  }

  // Solve A_0 u_0 = r_0
  divide_diagonal_block(0, 1, *rhs_block, result_block);

  for (int l=1; l<=P; l++) {
    // Compute r_l^l - C_l*u_l^{l-1}
    multiply_block(lower_block_Cijk[l], -1.0, result_block, *rhs_block);

    // Compute D_l^{-1} (r_l^l - C_l*u_l^{l-1})
    divide_diagonal_block(block_indices[l], block_indices[l+1], 
			  *rhs_block, result_block);
  }

  if (made_copy)
    delete input;

  return 0; 
}
示例#13
0
int main(int argc, char *argv[]) {
  int n = 32;                        // spatial discretization (per dimension)
  int num_KL = 2;                    // number of KL terms
  int p = 3;                         // polynomial order
  double mu = 0.1;                   // mean of exponential random field
  double s = 0.2;                    // std. dev. of exponential r.f.
  bool nonlinear_expansion = false;  // nonlinear expansion of diffusion coeff
                                     // (e.g., log-normal)
  bool symmetric = false;            // use symmetric formulation

  double g_mean_exp = 0.172988;      // expected response mean
  double g_std_dev_exp = 0.0380007;  // expected response std. dev.
  double g_tol = 1e-6;               // tolerance on determining success

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

  int MyPID;

  try {

    {
    TEUCHOS_FUNC_TIME_MONITOR("Total PCE Calculation Time");

    // Create a communicator for Epetra objects
    Teuchos::RCP<const Epetra_Comm> globalComm;
#ifdef HAVE_MPI
    globalComm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
#else
    globalComm = Teuchos::rcp(new Epetra_SerialComm);
#endif
    MyPID = globalComm->MyPID();

    // Create Stochastic Galerkin basis and expansion
    Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double> > > bases(num_KL); 
    for (int i=0; i<num_KL; i++)
      bases[i] = Teuchos::rcp(new Stokhos::LegendreBasis<int,double>(p,true));
    Teuchos::RCP<const Stokhos::CompletePolynomialBasis<int,double> > basis = 
      Teuchos::rcp(new Stokhos::CompletePolynomialBasis<int,double>(bases,
		     1e-12));
    int sz = basis->size();
    Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > Cijk;
    if (nonlinear_expansion)
      Cijk = basis->computeTripleProductTensor(sz);
    else
      Cijk = basis->computeTripleProductTensor(num_KL+1);
    Teuchos::RCP<Stokhos::OrthogPolyExpansion<int,double> > expansion = 
      Teuchos::rcp(new Stokhos::AlgebraicOrthogPolyExpansion<int,double>(basis,
									 Cijk));
    if (MyPID == 0)
      std::cout << "Stochastic Galerkin expansion size = " << sz << std::endl;

    // Create stochastic parallel distribution
    int num_spatial_procs = -1;
    Teuchos::ParameterList parallelParams;
    parallelParams.set("Number of Spatial Processors", num_spatial_procs);
    // parallelParams.set("Rebalance Stochastic Graph", true);
    // Teuchos::ParameterList& isorropia_params = 
    //   parallelParams.sublist("Isorropia");
    // isorropia_params.set("Balance objective", "nonzeros");
    Teuchos::RCP<Stokhos::ParallelData> sg_parallel_data =
      Teuchos::rcp(new Stokhos::ParallelData(basis, Cijk, globalComm,
					     parallelParams));
    Teuchos::RCP<const EpetraExt::MultiComm> sg_comm = 
      sg_parallel_data->getMultiComm();
    Teuchos::RCP<const Epetra_Comm> app_comm = 
      sg_parallel_data->getSpatialComm();

    // Create application
    Teuchos::RCP<twoD_diffusion_ME> model = 
      Teuchos::rcp(new twoD_diffusion_ME(app_comm, n, num_KL, mu, s, basis, 
					 nonlinear_expansion, symmetric));
    
    // Setup stochastic Galerkin algorithmic parameters
    Teuchos::RCP<Teuchos::ParameterList> sgParams = 
      Teuchos::rcp(new Teuchos::ParameterList);
    if (!nonlinear_expansion) {
      sgParams->set("Parameter Expansion Type", "Linear");
      sgParams->set("Jacobian Expansion Type", "Linear");
    }
    
    Teuchos::ParameterList precParams;
    precParams.set("default values", "SA");
    precParams.set("ML output", 0);
    precParams.set("max levels",5);
    precParams.set("increasing or decreasing","increasing");
    precParams.set("aggregation: type", "Uncoupled");
    precParams.set("smoother: type","ML symmetric Gauss-Seidel");
    precParams.set("smoother: sweeps",2);
    precParams.set("smoother: pre or post", "both");
    precParams.set("coarse: max size", 200);
    //precParams.set("PDE equations",sz);
#ifdef HAVE_ML_AMESOS
    precParams.set("coarse: type","Amesos-KLU");
#else
    precParams.set("coarse: type","Jacobi");
#endif

    // Create stochastic Galerkin model evaluator
    Teuchos::RCP<Stokhos::SGModelEvaluator_Interlaced> sg_model =
      Teuchos::rcp(new Stokhos::SGModelEvaluator_Interlaced(
		     model, basis, Teuchos::null,
		     expansion, sg_parallel_data, 
		     sgParams));

    // Set up stochastic parameters
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_p_poly =
      sg_model->create_p_sg(0);
    for (int i=0; i<num_KL; i++) {
      sg_p_poly->term(i,0)[i] = 0.0;
      sg_p_poly->term(i,1)[i] = 1.0;
    }

    // Create vectors and operators
    Teuchos::RCP<const Epetra_Vector> sg_p = sg_p_poly->getBlockVector();
    Teuchos::RCP<Epetra_Vector> sg_x =
      Teuchos::rcp(new Epetra_Vector(*(sg_model->get_x_map())));
    sg_x->PutScalar(0.0);
    Teuchos::RCP<Epetra_Vector> sg_f = 
      Teuchos::rcp(new Epetra_Vector(*(sg_model->get_f_map())));
    Teuchos::RCP<Epetra_Vector> sg_dx = 
      Teuchos::rcp(new Epetra_Vector(*(sg_model->get_x_map())));
    Teuchos::RCP<Epetra_CrsMatrix> sg_J = 
      Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>(sg_model->create_W());
    Teuchos::RCP<ML_Epetra::MultiLevelPreconditioner> sg_M =
      Teuchos::rcp(new ML_Epetra::MultiLevelPreconditioner(*sg_J, precParams,
							   false));
    
    // Setup InArgs and OutArgs
    EpetraExt::ModelEvaluator::InArgs sg_inArgs = sg_model->createInArgs();
    EpetraExt::ModelEvaluator::OutArgs sg_outArgs = sg_model->createOutArgs();
    sg_inArgs.set_p(1, sg_p);
    sg_inArgs.set_x(sg_x);
    sg_outArgs.set_f(sg_f);
    sg_outArgs.set_W(sg_J);

    // Evaluate model
    sg_model->evalModel(sg_inArgs, sg_outArgs);
    sg_M->ComputePreconditioner();

    // Print initial residual norm
    double norm_f;
    sg_f->Norm2(&norm_f);
    if (MyPID == 0)
      std::cout << "\nInitial residual norm = " << norm_f << std::endl;

    // Setup AztecOO solver
    AztecOO aztec;
    if (symmetric)
      aztec.SetAztecOption(AZ_solver, AZ_cg);
    else
      aztec.SetAztecOption(AZ_solver, AZ_gmres);
    aztec.SetAztecOption(AZ_precond, AZ_none);
    aztec.SetAztecOption(AZ_kspace, 20);
    aztec.SetAztecOption(AZ_conv, AZ_r0);
    aztec.SetAztecOption(AZ_output, 1);
    aztec.SetUserOperator(sg_J.get());
    aztec.SetPrecOperator(sg_M.get());
    aztec.SetLHS(sg_dx.get());
    aztec.SetRHS(sg_f.get());

    // Solve linear system
    aztec.Iterate(1000, 1e-12);

    // Update x
    sg_x->Update(-1.0, *sg_dx, 1.0);

    // Save solution to file
    EpetraExt::VectorToMatrixMarketFile("stochastic_solution_interlaced.mm", 
					*sg_x);

    // Save RHS to file
    EpetraExt::VectorToMatrixMarketFile("stochastic_RHS_interlaced.mm", 
					*sg_f);

    // Save operator to file
    EpetraExt::RowMatrixToMatrixMarketFile("stochastic_operator_interlaced.mm", 
					   *sg_J);

    // Save mean and variance to file
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_x_poly = 
      sg_model->create_x_sg(View, sg_x.get());
    Epetra_Vector mean(*(model->get_x_map()));
    Epetra_Vector std_dev(*(model->get_x_map()));
    sg_x_poly->computeMean(mean);
    sg_x_poly->computeStandardDeviation(std_dev);
    EpetraExt::VectorToMatrixMarketFile("mean_gal_interlaced.mm", mean);
    EpetraExt::VectorToMatrixMarketFile("std_dev_gal_interlaced.mm", std_dev);

    // Compute new residual & response function
    EpetraExt::ModelEvaluator::OutArgs sg_outArgs2 = sg_model->createOutArgs();
    Teuchos::RCP<Epetra_Vector> sg_g = 
      Teuchos::rcp(new Epetra_Vector(*(sg_model->get_g_map(0))));
    sg_f->PutScalar(0.0);
    sg_outArgs2.set_f(sg_f);
    sg_outArgs2.set_g(0, sg_g);
    sg_model->evalModel(sg_inArgs, sg_outArgs2);

    // Print initial residual norm
    sg_f->Norm2(&norm_f);
    if (MyPID == 0)
      std::cout << "\nFinal residual norm = " << norm_f << std::endl;

    // Print mean and standard deviation of responses
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_g_poly =
      sg_model->create_g_sg(0, View, sg_g.get());
    Epetra_Vector g_mean(*(model->get_g_map(0)));
    Epetra_Vector g_std_dev(*(model->get_g_map(0)));
    sg_g_poly->computeMean(g_mean);
    sg_g_poly->computeStandardDeviation(g_std_dev);
    std::cout.precision(16);
    // std::cout << "\nResponse Expansion = " << std::endl;
    // std::cout.precision(12);
    // sg_g_poly->print(std::cout);
    std::cout << "\nResponse Mean =      " << std::endl << g_mean << std::endl;
    std::cout << "Response Std. Dev. = " << std::endl << g_std_dev << std::endl;

    // Determine if example passed
    bool passed = false;
    if (norm_f < 1.0e-10 &&
	std::abs(g_mean[0]-g_mean_exp) < g_tol &&
	std::abs(g_std_dev[0]-g_std_dev_exp) < g_tol)
      passed = true;
    if (MyPID == 0) {
      if (passed)
	std::cout << "Example Passed!" << std::endl;
      else
	std::cout << "Example Failed!" << std::endl;
    }

    }

    Teuchos::TimeMonitor::summarize(std::cout);
    Teuchos::TimeMonitor::zeroOutTimers();

  }
  
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
  }
  catch (string& s) {
    std::cout << s << std::endl;
  }
  catch (char *s) {
    std::cout << s << std::endl;
  }
  catch (...) {
    std::cout << "Caught unknown exception!" <<std:: endl;
  }

#ifdef HAVE_MPI
  MPI_Finalize() ;
#endif

}
示例#14
0
Stokhos::SparseGridQuadrature<ordinal_type, value_type>::
SparseGridQuadrature(
  const Teuchos::RCP<const ProductBasis<ordinal_type,value_type> >& product_basis,
  ordinal_type sparse_grid_level,
  value_type duplicate_tol,
  ordinal_type growth_rate) :
  coordinate_bases(product_basis->getCoordinateBases())
{
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos: Sparse Grid Generation");
#endif

  ordinal_type d = product_basis->dimension();
  ordinal_type p = product_basis->order();
  ordinal_type sz = product_basis->size();
  ordinal_type level = sparse_grid_level;

  // Make level = order the default, which is correct for Gaussian abscissas
  // slow, linear growth, and total-order basis
  if (level == 0) {
    level = p;
  }

  //std::cout << "Sparse grid level = " << level << std::endl;

  // Compute quad points, weights, values
  Teuchos::Array<typename OneDOrthogPolyBasis<ordinal_type,value_type>::LevelToOrderFnPtr> growth_rules(d);
  
  Teuchos::Array< void (*) ( int order, int dim, double x[] ) > compute1DPoints(d);
  Teuchos::Array< void (*) ( int order, int dim, double w[] ) > compute1DWeights(d);
  for (ordinal_type i=0; i<d; i++) {
    compute1DPoints[i] = &(getMyPoints);
    compute1DWeights[i] = &(getMyWeights);
    growth_rules[i] = coordinate_bases[i]->getSparseGridGrowthRule();
  }

  // Set the static sparse grid quadrature pointer to this
  // (this will cause a conflict if another sparse grid quadrature object
  // is trying to access the VPISparseGrid library, but that's all we can
  // do at this point).
  sgq = this;

  int num_total_pts  =
    webbur::sgmg_size_total(d, level, growth_rate, &growth_rules[0]);
  ordinal_type ntot =
    webbur::sgmg_size(d, level, &compute1DPoints[0], duplicate_tol, 
                      growth_rate, &growth_rules[0]);
  Teuchos::Array<int> sparse_order(ntot*d);
  Teuchos::Array<int> sparse_index(ntot*d);
  Teuchos::Array<int> sparse_unique_index(num_total_pts);
  quad_points.resize(ntot);
  quad_weights.resize(ntot);
  quad_values.resize(ntot);
  Teuchos::Array<value_type> gp(ntot*d);

  webbur::sgmg_unique_index(d, level, &compute1DPoints[0],
			    duplicate_tol, ntot, num_total_pts, 
			    growth_rate, &growth_rules[0],
			    &sparse_unique_index[0]);
  webbur::sgmg_index(d, level, ntot, num_total_pts, 
		     &sparse_unique_index[0], growth_rate, 
		     &growth_rules[0], 
		     &sparse_order[0], &sparse_index[0]);
  webbur::sgmg_weight(d, level, &compute1DWeights[0],
		      ntot, num_total_pts, 
		      &sparse_unique_index[0], growth_rate,
		      &growth_rules[0],
		      &quad_weights[0]);
  webbur::sgmg_point(d, level, &compute1DPoints[0],
		     ntot, &sparse_order[0], 
		     &sparse_index[0], growth_rate,
		     &growth_rules[0], 
		     &gp[0]);
  
  for (ordinal_type i=0; i<ntot; i++) {
    quad_values[i].resize(sz);
    quad_points[i].resize(d);
    for (ordinal_type j=0; j<d; j++)
      quad_points[i][j] = gp[i*d+j];
    product_basis->evaluateBases(quad_points[i], quad_values[i]);
  }

  //std::cout << "Number of quadrature points = " << ntot << std::endl;
}
示例#15
0
  static bool 
  run_impl(int n, int sz, int nblocks, int nthreads, bool reset, bool print) {

    // Allocate memory inputs and outpus
    int len = nblocks*nthreads*sz*n;
    std::cout << "total size = " << len << std::endl;

    int stride = 1;
    
    double *x = new double[len];
    double *y = new double[len];
    double *y_mp = new double[len];
    
    // Initialize x
    for (int i=0; i<len; i++)
      x[i] = static_cast<double>(i+1)/static_cast<double>(len);
    
    // Invoke kernel
    {
      TEUCHOS_FUNC_TIME_MONITOR("Host calculation");
      for (int offset=0; offset<len; offset += sz*n)
	kernel(offset, stride, n, sz, x, y);
    }
    
    // Invoke kernel
    {
      TEUCHOS_FUNC_TIME_MONITOR("Host calculation (MP)");
      for (int offset=0; offset<len; offset += sz*n)
	mpkernel<vector_type>(offset, stride, n, sz, x, y_mp, reset, print);
    }
    
    // Check results agree
    double rtol = 1e-15;
    double atol = 1e-15;
    bool agree = true;
    for (int i=0; i<len; i++) {
      if (std::abs(y[i]-y_mp[i]) > std::abs(y[i])*rtol + atol) {
	agree = false;
	break;
      }
    }
    
    if (print) {
      std::cout << "x    = [ ";
      for (int i=0; i<len; i++)
	std::cout << x[i] << " ";
      std::cout << "]" << std::endl;
      
      std::cout << "y      [ ";
      for (int i=0; i<len; i++)
	std::cout << y[i] << " ";
      std::cout << "]" << std::endl;
      
      std::cout << "y_mp = [ ";
      for (int i=0; i<len; i++)
	std::cout << y_mp[i] << " ";
      std::cout << "]" << std::endl;
    }
    
    // Clean up memory
    delete [] x;
    delete [] y;
    delete [] y_mp;
  
    return agree;
  }
示例#16
0
int main(int argc, char *argv[]) {
  int n = 32;                        // spatial discretization (per dimension)
  int num_KL = 2;                    // number of KL terms
  int p = 3;                         // polynomial order
  double mu = 0.1;                   // mean of exponential random field
  double s = 0.2;                    // std. dev. of exponential r.f.
  bool nonlinear_expansion = false;  // nonlinear expansion of diffusion coeff
                                     // (e.g., log-normal)
  bool matrix_free = true;           // use matrix-free stochastic operator
  bool symmetric = false;            // use symmetric formulation

  double g_mean_exp = 0.172988;      // expected response mean
  double g_std_dev_exp = 0.0380007;  // expected response std. dev.
  double g_tol = 1e-6;               // tolerance on determining success

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

  int MyPID;

  try {

    {
    TEUCHOS_FUNC_TIME_MONITOR("Total PCE Calculation Time");

    // Create a communicator for Epetra objects
    Teuchos::RCP<const Epetra_Comm> globalComm;
#ifdef HAVE_MPI
    globalComm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
#else
    globalComm = Teuchos::rcp(new Epetra_SerialComm);
#endif
    MyPID = globalComm->MyPID();
    
    // Create Stochastic Galerkin basis and expansion
    Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double> > > bases(num_KL); 
    for (int i=0; i<num_KL; i++)
      bases[i] = Teuchos::rcp(new Stokhos::LegendreBasis<int,double>(p, true));
    Teuchos::RCP<const Stokhos::CompletePolynomialBasis<int,double> > basis = 
      Teuchos::rcp(new Stokhos::CompletePolynomialBasis<int,double>(bases));
    int sz = basis->size();
    Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > Cijk;
    if (nonlinear_expansion)
      Cijk = basis->computeTripleProductTensor();
    else
      Cijk = basis->computeLinearTripleProductTensor();
    Teuchos::RCP<Stokhos::OrthogPolyExpansion<int,double> > expansion = 
      Teuchos::rcp(new Stokhos::AlgebraicOrthogPolyExpansion<int,double>(basis,
									 Cijk));
    if (MyPID == 0)
      std::cout << "Stochastic Galerkin expansion size = " << sz << std::endl;

    // Create stochastic parallel distribution
    int num_spatial_procs = -1;
    if (argc > 1)
      num_spatial_procs = std::atoi(argv[1]);
    Teuchos::ParameterList parallelParams;
    parallelParams.set("Number of Spatial Processors", num_spatial_procs);
    Teuchos::RCP<Stokhos::ParallelData> sg_parallel_data =
      Teuchos::rcp(new Stokhos::ParallelData(basis, Cijk, globalComm,
					     parallelParams));
    Teuchos::RCP<const EpetraExt::MultiComm> sg_comm = 
      sg_parallel_data->getMultiComm();
    Teuchos::RCP<const Epetra_Comm> app_comm = 
      sg_parallel_data->getSpatialComm();

    // Create application
    Teuchos::RCP<twoD_diffusion_ME> model =
      Teuchos::rcp(new twoD_diffusion_ME(app_comm, n, num_KL, mu, s, basis, 
					 nonlinear_expansion, symmetric));
    
    // Setup stochastic Galerkin algorithmic parameters
    Teuchos::RCP<Teuchos::ParameterList> sgParams = 
      Teuchos::rcp(new Teuchos::ParameterList);
    Teuchos::ParameterList& sgOpParams = 
      sgParams->sublist("SG Operator");
    Teuchos::ParameterList& sgPrecParams = 
      sgParams->sublist("SG Preconditioner");
    if (!nonlinear_expansion) {
      sgParams->set("Parameter Expansion Type", "Linear");
      sgParams->set("Jacobian Expansion Type", "Linear");
    }
    if (matrix_free) {
      sgOpParams.set("Operator Method", "Matrix Free");
      sgPrecParams.set("Preconditioner Method", "Approximate Gauss-Seidel");
      sgPrecParams.set("Symmetric Gauss-Seidel", symmetric);
      sgPrecParams.set("Mean Preconditioner Type", "ML");
      Teuchos::ParameterList& precParams = 
      	sgPrecParams.sublist("Mean Preconditioner Parameters");
      precParams.set("default values", "SA");
      precParams.set("ML output", 0);
      precParams.set("max levels",5);
      precParams.set("increasing or decreasing","increasing");
      precParams.set("aggregation: type", "Uncoupled");
      precParams.set("smoother: type","ML symmetric Gauss-Seidel");
      precParams.set("smoother: sweeps",2);
      precParams.set("smoother: pre or post", "both");
      precParams.set("coarse: max size", 200);
#ifdef HAVE_ML_AMESOS
      precParams.set("coarse: type","Amesos-KLU");
#else
      precParams.set("coarse: type","Jacobi");
#endif
    }
    else {
      sgOpParams.set("Operator Method", "Fully Assembled");
      sgPrecParams.set("Preconditioner Method", "None");
    }

   // Create stochastic Galerkin model evaluator
    Teuchos::RCP<Stokhos::SGModelEvaluator> sg_model =
      Teuchos::rcp(new Stokhos::SGModelEvaluator(model, basis, Teuchos::null,
                                                 expansion, sg_parallel_data, 
						 sgParams));

    // Set up stochastic parameters
    // The current implementation of the model doesn't actually use these 
    // values, but is hard-coded to certain uncertainty models
    Teuchos::Array<double> point(num_KL, 1.0);
    Teuchos::Array<double> basis_vals(sz);
    basis->evaluateBases(point, basis_vals);
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_p_init =
      sg_model->create_p_sg(0);
    for (int i=0; i<num_KL; i++) {
      sg_p_init->term(i,0)[i] = 0.0;
      sg_p_init->term(i,1)[i] = 1.0 / basis_vals[i+1];
    }
    sg_model->set_p_sg_init(0, *sg_p_init);

    // Setup stochastic initial guess
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_x_init = 
      sg_model->create_x_sg();
    sg_x_init->init(0.0);
    sg_model->set_x_sg_init(*sg_x_init);

    // Set up NOX parameters
    Teuchos::RCP<Teuchos::ParameterList> noxParams = 
      Teuchos::rcp(new Teuchos::ParameterList);

    // Set the nonlinear solver method
    noxParams->set("Nonlinear Solver", "Line Search Based");

    // Set the printing parameters in the "Printing" sublist
    Teuchos::ParameterList& printParams = noxParams->sublist("Printing");
    printParams.set("MyPID", MyPID); 
    printParams.set("Output Precision", 3);
    printParams.set("Output Processor", 0);
    printParams.set("Output Information", 
                    NOX::Utils::OuterIteration + 
                    NOX::Utils::OuterIterationStatusTest + 
                    NOX::Utils::InnerIteration +
                    NOX::Utils::LinearSolverDetails +
                    NOX::Utils::Warning + 
                    NOX::Utils::Error);

    // Create printing utilities
    NOX::Utils utils(printParams);

    // Sublist for line search 
    Teuchos::ParameterList& searchParams = noxParams->sublist("Line Search");
    searchParams.set("Method", "Full Step");

    // Sublist for direction
    Teuchos::ParameterList& dirParams = noxParams->sublist("Direction");
    dirParams.set("Method", "Newton");
    Teuchos::ParameterList& newtonParams = dirParams.sublist("Newton");
    newtonParams.set("Forcing Term Method", "Constant");

    // Sublist for linear solver for the Newton method
    Teuchos::ParameterList& lsParams = newtonParams.sublist("Linear Solver");
    if (symmetric)
      lsParams.set("Aztec Solver", "CG");
    else
      lsParams.set("Aztec Solver", "GMRES");
    lsParams.set("Max Iterations", 1000);
    lsParams.set("Size of Krylov Subspace", 100);
    lsParams.set("Tolerance", 1e-12); 
    lsParams.set("Output Frequency", 1);
    if (matrix_free)
      lsParams.set("Preconditioner", "User Defined");
    else {
      lsParams.set("Preconditioner", "ML");
      Teuchos::ParameterList& precParams = 
	lsParams.sublist("ML");
      ML_Epetra::SetDefaults("DD", precParams);
      lsParams.set("Write Linear System", false);
    }

    // Sublist for convergence tests
    Teuchos::ParameterList& statusParams = noxParams->sublist("Status Tests");
    statusParams.set("Test Type", "Combo");
    statusParams.set("Number of Tests", 2);
    statusParams.set("Combo Type", "OR");
    Teuchos::ParameterList& normF = statusParams.sublist("Test 0");
    normF.set("Test Type", "NormF");
    normF.set("Tolerance", 1e-10);
    normF.set("Scale Type", "Scaled");
    Teuchos::ParameterList& maxIters = statusParams.sublist("Test 1");
    maxIters.set("Test Type", "MaxIters");
    maxIters.set("Maximum Iterations", 1);

    // Create NOX interface
    Teuchos::RCP<NOX::Epetra::ModelEvaluatorInterface> nox_interface = 
       Teuchos::rcp(new NOX::Epetra::ModelEvaluatorInterface(sg_model));

    // Create NOX linear system object
    Teuchos::RCP<const Epetra_Vector> u = sg_model->get_x_init();
    Teuchos::RCP<Epetra_Operator> A = sg_model->create_W();
    Teuchos::RCP<NOX::Epetra::Interface::Required> iReq = nox_interface;
    Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac = nox_interface;
    Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linsys;
    if (matrix_free) {
      Teuchos::RCP<Epetra_Operator> M = sg_model->create_WPrec()->PrecOp;
      Teuchos::RCP<NOX::Epetra::Interface::Preconditioner> iPrec = nox_interface;
      linsys = 
	Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
							  iJac, A, iPrec, M,
							  *u));
    }
    else {
      linsys = 
	Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
							  iReq, iJac, A, 
							  *u));
    }

    // Build NOX group
    Teuchos::RCP<NOX::Epetra::Group> grp = 
      Teuchos::rcp(new NOX::Epetra::Group(printParams, iReq, *u, linsys));

    // Create the Solver convergence test
    Teuchos::RCP<NOX::StatusTest::Generic> statusTests =
      NOX::StatusTest::buildStatusTests(statusParams, utils);

    // Create the solver
    Teuchos::RCP<NOX::Solver::Generic> solver = 
      NOX::Solver::buildSolver(grp, statusTests, noxParams);

    // Solve the system
    NOX::StatusTest::StatusType status = solver->solve();

    // Get final solution
    const NOX::Epetra::Group& finalGroup = 
      dynamic_cast<const NOX::Epetra::Group&>(solver->getSolutionGroup());
    const Epetra_Vector& finalSolution = 
      (dynamic_cast<const NOX::Epetra::Vector&>(finalGroup.getX())).getEpetraVector();

    // Save final solution to file
    EpetraExt::VectorToMatrixMarketFile("nox_stochastic_solution.mm", 
					finalSolution);

    // Save mean and variance to file
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_x_poly = 
      sg_model->create_x_sg(View, &finalSolution);
    Epetra_Vector mean(*(model->get_x_map()));
    Epetra_Vector std_dev(*(model->get_x_map()));
    sg_x_poly->computeMean(mean);
    sg_x_poly->computeStandardDeviation(std_dev);
    EpetraExt::VectorToMatrixMarketFile("mean_gal.mm", mean);
    EpetraExt::VectorToMatrixMarketFile("std_dev_gal.mm", std_dev);
      
    // Evaluate SG responses at SG parameters
    EpetraExt::ModelEvaluator::InArgs sg_inArgs = sg_model->createInArgs();
    EpetraExt::ModelEvaluator::OutArgs sg_outArgs = 
      sg_model->createOutArgs();
    Teuchos::RCP<const Epetra_Vector> sg_p = sg_model->get_p_init(1);
    Teuchos::RCP<Epetra_Vector> sg_g = 
      Teuchos::rcp(new Epetra_Vector(*(sg_model->get_g_map(0))));
    sg_inArgs.set_p(1, sg_p);
    sg_inArgs.set_x(Teuchos::rcp(&finalSolution,false));
    sg_outArgs.set_g(0, sg_g);
    sg_model->evalModel(sg_inArgs, sg_outArgs);

    // Print mean and standard deviation of response
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_g_poly =
      sg_model->create_g_sg(0, View, sg_g.get());
    Epetra_Vector g_mean(*(model->get_g_map(0)));
    Epetra_Vector g_std_dev(*(model->get_g_map(0)));
    sg_g_poly->computeMean(g_mean);
    sg_g_poly->computeStandardDeviation(g_std_dev);
    std::cout.precision(16);
    // std::cout << "\nResponse Expansion = " << std::endl;
    // std::cout.precision(12);
    // sg_g_poly->print(std::cout);
    std::cout << std::endl;
    std::cout << "Response Mean =      " << std::endl << g_mean << std::endl;
    std::cout << "Response Std. Dev. = " << std::endl << g_std_dev << std::endl;

    // Determine if example passed
    bool passed = false;
    if (status == NOX::StatusTest::Converged &&
	std::abs(g_mean[0]-g_mean_exp) < g_tol &&
	std::abs(g_std_dev[0]-g_std_dev_exp) < g_tol)
      passed = true;
    if (MyPID == 0) {
      if (passed)
	std::cout << "Example Passed!" << std::endl;
      else
	std::cout << "Example Failed!" << std::endl;
    }

    }

    Teuchos::TimeMonitor::summarize(std::cout);
    Teuchos::TimeMonitor::zeroOutTimers();

  }
  
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
  }
  catch (string& s) {
    std::cout << s << std::endl;
  }
  catch (char *s) {
    std::cout << s << std::endl;
  }
  catch (...) {
    std::cout << "Caught unknown exception!" <<std:: endl;
  }

#ifdef HAVE_MPI
  MPI_Finalize() ;
#endif

}
示例#17
0
bool run_kernels(Kokkos::ParallelWorkRequest config,
                 int num_elements, int num_samples, bool reset, bool print,
                 const std::string& device_name) {
  typedef vector_kernel<Scalar,ArrayVector,ScalarVector,Device> vec_kernel;
  typedef scalar_kernel<Scalar,Device> sca_kernel;
  typedef typename vec_kernel::view_type view_type;
  typedef typename view_type::HostMirror host_view_type;

  view_type x     = view_type("x", num_elements, num_samples);
  view_type y_vec = view_type("y", num_elements, num_samples);
  view_type y_sca = view_type("y", num_elements, num_samples);

  host_view_type hx = Kokkos::create_mirror(x);

  // Initialize x
  for (int element=0; element<num_elements; element++) {
    for (int sample=0; sample<num_samples; sample++) {
      hx(element,sample) =
        static_cast<Scalar>(element+sample+1) /
        static_cast<Scalar>(num_elements*num_samples);
    }
  }

  // Copy x to device
  Kokkos::deep_copy(x, hx);

  // Run vector and scalar kernels
  {
    TEUCHOS_FUNC_TIME_MONITOR(device_name + " calculation");
    sca_kernel::run(config, x, y_sca, reset, print);
  }
  {
    TEUCHOS_FUNC_TIME_MONITOR(device_name + " calculation (MP)");
    vec_kernel::run(config, x, y_vec, reset, print);
  }

  // Copy results back to host
  host_view_type hy_vec = Kokkos::create_mirror(y_vec);
  host_view_type hy_sca = Kokkos::create_mirror(y_sca);
  Kokkos::deep_copy(hy_vec, y_vec);
  Kokkos::deep_copy(hy_sca, y_sca);

  // Check results agree
  double rtol = 1e-15;
  double atol = 1e-15;
  bool agree = true;
  for (int e=0; e<num_elements; e++) {
    for (int s=0; s<num_samples; s++) {
      if (std::abs(hy_vec(e,s)-hy_sca(e,s)) > std::abs(hy_sca(e,s))*rtol+atol) {
        agree = false;
        break;
      }
    }
  }

  // Print results if requested
  if (print) {
    std::cout << "x    = [ ";
    for (int e=0; e<num_elements; e++) {
      for (int s=0; s<num_samples; s++)
        std::cout << hx(e,s) << " ";
      std::cout << ";" << std::endl;
    }
    std::cout << "]" << std::endl;

    std::cout << "y      [ ";
    for (int e=0; e<num_elements; e++) {
      for (int s=0; s<num_samples; s++)
        std::cout << hy_sca(e,s) << " ";
      std::cout << ";" << std::endl;
    }
    std::cout << "]" << std::endl;

    std::cout << "y_mp = [ ";
    for (int e=0; e<num_elements; e++) {
      for (int s=0; s<num_samples; s++)
        std::cout << hy_vec(e,s) << " ";
      std::cout << ";" << std::endl;
    }
    std::cout << "]" << std::endl;
  }

  return agree;
}
示例#18
0
bool run_view_kernel( Kokkos::ParallelWorkRequest config,
                      int num_elements ,
                      int num_samples ,
                      bool reset, bool print,
                      const std::string& device_name )
{
  typedef typename
    Kokkos::Impl::if_c< SamplesPerThread ,
                        Stokhos::StaticFixedStorage< int , Scalar , SamplesPerThread , Device > ,
                        Stokhos::DynamicStorage<     int , Scalar , Device > >::type
      storage_type ;

  typedef Kokkos::View< Sacado::MP::Vector< storage_type > * , Device > view_type ;

  typedef view_kernel< view_type > kernel;
  typedef typename view_type::HostMirror host_view_type;

  const bool input_error = SamplesPerThread && ( num_samples != int(config.team_size * SamplesPerThread) );

  if ( print || input_error ) {
    std::cout << "run_view_kernel" ;
    if ( input_error ) {
      std::cout << " : ERROR num_samples != static(SamplesPerThread) * team_size : " ;
    }
    std::cout << " num_elements(" << num_elements << ")"
              << " num_samples(" << num_samples << ")"
              << " league_size(" << config.league_size << ")"
              << " team_size(" << config.team_size << ")" ;
    if ( SamplesPerThread ) { std::cout << " static(" << SamplesPerThread << ")" ; }
    else { std::cout << " dynamic" ; }
    std::cout << std::endl ;

    if ( input_error ) { return false ; }
  }

  view_type x( "x", num_elements, num_samples);
  view_type y( "y", num_elements, num_samples);

  host_view_type hy_ans("y_ans", num_elements, num_samples);

  host_view_type hx = Kokkos::create_mirror(x);

  // Initialize x
  for (int element=0; element<num_elements; element++) {
    for (int sample=0; sample<num_samples; sample++) {
      hx(element,sample) =
        static_cast<Scalar>(element+sample+1) /
        static_cast<Scalar>(num_elements*num_samples);
      simple_function<Scalar>( hx(element,sample) , hy_ans(element,sample) );
    }
  }

  // Copy x to device
  Kokkos::deep_copy(x, hx);

  // Run vector and scalar kernels
  {
    TEUCHOS_FUNC_TIME_MONITOR(device_name + " calculation");
    kernel::run(config, x, y, reset, print);
  }

  // Copy results back to host
  host_view_type hy = Kokkos::create_mirror(y);

  Kokkos::deep_copy(hy, y);

  // Check results agree
  double rtol = 1e-15;
  double atol = 1e-15;
  bool agree = true;
  for (int e=0; e<num_elements; e++) {
    for (int s=0; s<num_samples; s++) {
      if (std::abs(hy(e,s)-hy_ans(e,s)) > std::abs(hy_ans(e,s))*rtol+atol) {
        agree = false;
        break;
      }
    }
  }

  // Print results if requested
  if (print) {
    std::cout << "x = [ ";
    for (int e=0; e<num_elements; e++) {
      for (int s=0; s<num_samples; s++)
        std::cout << hx(e,s) << " ";
      std::cout << ";" << std::endl;
    }
    std::cout << "]" << std::endl;

    std::cout << "y = [ ";
    for (int e=0; e<num_elements; e++) {
      for (int s=0; s<num_samples; s++)
        std::cout << hy(e,s) << " ";
      std::cout << ";" << std::endl;
    }
    std::cout << "]" << std::endl;

    std::cout << "hy_ans = [ ";
    for (int e=0; e<num_elements; e++) {
      for (int s=0; s<num_samples; s++)
        std::cout << hy_ans(e,s) << " ";
      std::cout << ";" << std::endl;
    }
    std::cout << "]" << std::endl;
  }

  return agree;
}
int
Stokhos::MatrixFreeOperator::
Apply(const Epetra_MultiVector& Input, Epetra_MultiVector& Result) const
{
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos: SG Operator Apply()");
#endif

  // Note for transpose:
  // The stochastic matrix is symmetric, however the matrix blocks may not
  // be.  So the algorithm here is the same whether we are using the transpose
  // or not.  We just apply the transpose of the blocks in the case of
  // applying the global transpose, and make sure the imported Input
  // vectors use the right map.

  // We have to be careful if Input and Result are the same vector.
  // If this is the case, the only possible solution is to make a copy
  const Epetra_MultiVector *input = &Input;
  bool made_copy = false;
  if (Input.Values() == Result.Values() && !is_stoch_parallel) {
    input = new Epetra_MultiVector(Input);
    made_copy = true;
  }

  // Initialize
  Result.PutScalar(0.0);

  const Epetra_Map* input_base_map = domain_base_map.get();
  const Epetra_Map* result_base_map = range_base_map.get();
  if (useTranspose == true) {
    input_base_map = range_base_map.get();
    result_base_map = domain_base_map.get();
  }

  // Allocate temporary storage
  int m = Input.NumVectors();
  if (useTranspose == false &&
      (tmp == Teuchos::null || tmp->NumVectors() != m*max_num_mat_vec))
    tmp = Teuchos::rcp(new Epetra_MultiVector(*result_base_map,
                                              m*max_num_mat_vec));
  else if (useTranspose == true &&
           (tmp_trans == Teuchos::null ||
            tmp_trans->NumVectors() != m*max_num_mat_vec))
    tmp_trans = Teuchos::rcp(new Epetra_MultiVector(*result_base_map,
                                                    m*max_num_mat_vec));
  Epetra_MultiVector *tmp_result;
  if (useTranspose == false)
    tmp_result = tmp.get();
  else
    tmp_result = tmp_trans.get();

  // Map input into column map
  const Epetra_MultiVector *tmp_col;
  if (!is_stoch_parallel)
    tmp_col = input;
  else {
    if (useTranspose == false) {
      if (input_col == Teuchos::null || input_col->NumVectors() != m)
        input_col = Teuchos::rcp(new Epetra_MultiVector(*global_col_map, m));
      input_col->Import(*input, *col_importer, Insert);
      tmp_col = input_col.get();
    }
    else {
      if (input_col_trans == Teuchos::null ||
          input_col_trans->NumVectors() != m)
        input_col_trans =
          Teuchos::rcp(new Epetra_MultiVector(*global_col_map_trans, m));
      input_col_trans->Import(*input, *col_importer_trans, Insert);
      tmp_col = input_col_trans.get();
    }
  }

  // Extract blocks
  EpetraExt::BlockMultiVector sg_input(View, *input_base_map, *tmp_col);
  EpetraExt::BlockMultiVector sg_result(View, *result_base_map, Result);
  for (int i=0; i<input_block.size(); i++)
    input_block[i] = sg_input.GetBlock(i);
  for (int i=0; i<result_block.size(); i++)
    result_block[i] = sg_result.GetBlock(i);

  // Apply block SG operator via
  // w_i =
  //    \sum_{j=0}^P \sum_{k=0}^L J_k v_j < \psi_i \psi_j \psi_k > / <\psi_i^2>
  // for i=0,...,P where P = expansion_size, L = num_blocks, w_j is the jth
  // input block, w_i is the ith result block, and J_k is the kth block operator

  // k_begin and k_end are initialized in the constructor
  const Teuchos::Array<double>& norms = sg_basis->norm_squared();
  for (Cijk_type::k_iterator k_it=k_begin; k_it!=k_end; ++k_it) {
    int k = index(k_it);
    Cijk_type::kj_iterator j_begin = Cijk->j_begin(k_it);
    Cijk_type::kj_iterator j_end = Cijk->j_end(k_it);
    int nj = Cijk->num_j(k_it);
    if (nj > 0) {
      Teuchos::Array<double*> j_ptr(nj*m);
      Teuchos::Array<int> mj_indices(nj*m);
      int l = 0;
      for (Cijk_type::kj_iterator j_it = j_begin; j_it != j_end; ++j_it) {
        int j = index(j_it);
        for (int mm=0; mm<m; mm++) {
          j_ptr[l*m+mm] = (*input_block[j])[mm];
          mj_indices[l*m+mm] = l*m+mm;
        }
        l++;
      }
      Epetra_MultiVector input_tmp(View, *input_base_map, &j_ptr[0], nj*m);
      Epetra_MultiVector result_tmp(View, *tmp_result, &mj_indices[0], nj*m);
      if (use_block_apply) {
        (*block_ops)[k].Apply(input_tmp, result_tmp);
      }
      else {
        for (int jj=0; jj<nj*m; jj++)
          (*block_ops)[k].Apply(*(input_tmp(jj)), *(result_tmp(jj)));
      }
      l = 0;
      for (Cijk_type::kj_iterator j_it = j_begin; j_it != j_end; ++j_it) {
        int j = index(j_it);
        for (Cijk_type::kji_iterator i_it = Cijk->i_begin(j_it);
             i_it != Cijk->i_end(j_it); ++i_it) {
          int i = index(i_it);
          double c = value(i_it);
          if (scale_op) {
            int i_gid;
            if (useTranspose)
              i_gid = epetraCijk->GCID(j);
            else
              i_gid = epetraCijk->GRID(i);
            c /= norms[i_gid];
          }
          for (int mm=0; mm<m; mm++)
            (*result_block[i])(mm)->Update(c, *result_tmp(l*m+mm), 1.0);
        }
        l++;
      }
    }
  }

  // Destroy blocks
  for (int i=0; i<input_block.size(); i++)
    input_block[i] = Teuchos::null;
  for (int i=0; i<result_block.size(); i++)
    result_block[i] = Teuchos::null;

  if (made_copy)
    delete input;

  return 0;
}
void
Stokhos::CGDivisionExpansionStrategy<ordinal_type,value_type,node_type>::
divide(Stokhos::OrthogPolyApprox<ordinal_type, value_type, node_type>& c,
       const value_type& alpha,
       const Stokhos::OrthogPolyApprox<ordinal_type, value_type, node_type>& a, 
       const Stokhos::OrthogPolyApprox<ordinal_type, value_type, node_type>& b,
       const value_type& beta)
{
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::CGDivisionStrategy::divide()");
#endif

  
  ordinal_type sz = basis->size();
  ordinal_type pa = a.size();
  ordinal_type pb = b.size();
  
  ordinal_type pc;
  if (pb > 1)
    pc = sz;
  else
    pc = pa;
  if (c.size() != pc)
    c.resize(pc);
 
  const value_type* ca = a.coeff();
  const value_type* cb = b.coeff();


  value_type* cc = c.coeff();

  if (pb > 1) {
    // Compute A
    A->putScalar(0.0);
    typename Cijk_type::k_iterator k_begin = Cijk->k_begin();
    typename Cijk_type::k_iterator k_end = Cijk->k_end();
    
    if (pb < Cijk->num_k())
      k_end = Cijk->find_k(pb);
    value_type cijk;
    ordinal_type i,j,k;
    for (typename Cijk_type::k_iterator k_it=k_begin; k_it!=k_end; ++k_it) {
      k = index(k_it);
      for (typename Cijk_type::kj_iterator j_it = Cijk->j_begin(k_it); 
	   j_it != Cijk->j_end(k_it); ++j_it) {
	j = index(j_it);
	for (typename Cijk_type::kji_iterator i_it = Cijk->i_begin(j_it);
	     i_it  != Cijk->i_end(j_it); ++i_it) {       
	  i = index(i_it);
	  cijk = value(i_it);
	  (*A)(i,j) += cijk*cb[k];
	}
      }
    }

    // Compute B
    B->putScalar(0.0);
    for (ordinal_type i=0; i<pa; i++)
      (*B)(i,0) = ca[i]*basis->norm_squared(i);

    Teuchos::SerialDenseMatrix<ordinal_type,value_type> D(sz, 1);
    //Equilibrate the linear system
    if (equil == 1){
      //Create diag mtx of max row entries
      for (ordinal_type i=0; i<sz; i++){
	Teuchos::SerialDenseMatrix<ordinal_type, value_type> r(Teuchos::View, *A, 1, sz, i, 0);
	D(i,0)=sqrt(r.normOne());
      }


      //Compute inv(D)*A*inv(D)
      for (ordinal_type i=0; i<sz; i++){
	for (ordinal_type j=0; j<sz; j++){
	  (*A)(i,j)=(*A)(i,j)/(D(i,0)*D(j,0));
	}
      }

      //Scale b by inv(D)
      for (ordinal_type i=0; i<sz; i++){
	(*B)(i,0)=(*B)(i,0)/D(i,0);
      }

    }

    if (linear == 1){
      //Compute M, the linear matrix to be used in the preconditioner

      pb = basis->dimension()+1;

      M->putScalar(0.0);
      if (pb < Cijk->num_k())
	k_end = Cijk->find_k(pb);
      for (typename Cijk_type::k_iterator k_it=k_begin; k_it!=k_end; ++k_it) {
	k = index(k_it);
	for ( typename Cijk_type::kj_iterator j_it = Cijk->j_begin(k_it);
	      j_it != Cijk->j_end(k_it); ++j_it) {
	  j = index(j_it);
	  for ( typename Cijk_type::kji_iterator i_it = Cijk->i_begin(j_it);
		i_it  != Cijk->i_end(j_it); ++i_it) {
	    i = index(i_it);
	    cijk = value(i_it);
	    (*M)(i,j) += cijk*cb[k];
	  }
	}
      }
      
      //Scale M
      if (equil == 1){
	//Compute inv(D)*M*inv(D)
	for (ordinal_type i=0; i<sz; i++){
	  for (ordinal_type j=0; j<sz; j++){
	    (*M)(i,j)=(*M)(i,j)/(D(i,0)*D(j,0));
	  }
 	}
      }
      CG(*A,*X,*B, max_it, tol, prec_iter, basis->order(), basis->dimension(), PrecNum, *M, diag);
    }
    
    else{
      
      CG(*A,*X,*B, max_it, tol, prec_iter, basis->order(), basis->dimension(), PrecNum, *A, diag);
    }
    
    if (equil == 1 ) {
      //Rescale X 
      for (ordinal_type i=0; i<sz; i++){
	(*X)(i,0)=(*X)(i,0)/D(i,0);
      }
    }
   
    // Compute c
    for (ordinal_type i=0; i<pc; i++)
      cc[i] = alpha*(*X)(i,0) + beta*cc[i];
  }
  else {
    for (ordinal_type i=0; i<pc; i++)
      cc[i] = alpha*ca[i]/cb[0] + beta*cc[i];
  }
}
示例#21
0
int main(int argc, char *argv[]) {   

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

  // Create a communicator for Epetra objects
  Teuchos::RCP<const Epetra_Comm> globalComm;
#ifdef HAVE_MPI
  globalComm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
#else
  globalComm = Teuchos::rcp(new Epetra_SerialComm);
#endif
  int MyPID = globalComm->MyPID();

  try {

    // Setup command line options
    Teuchos::CommandLineProcessor CLP;
    CLP.setDocString(
      "This example runs a variety of stochastic Galerkin solvers.\n");

    int n = 32;
    CLP.setOption("num_mesh", &n, "Number of mesh points in each direction");

    bool symmetric = false;
    CLP.setOption("symmetric", "unsymmetric", &symmetric, 
		  "Symmetric discretization");

    int num_spatial_procs = -1;
    CLP.setOption("num_spatial_procs", &num_spatial_procs, "Number of spatial processors (set -1 for all available procs)");

    bool rebalance_stochastic_graph = false;
    CLP.setOption("rebalance", "no-rebalance", &rebalance_stochastic_graph, 
		  "Rebalance parallel stochastic graph (requires Isorropia)");

    SG_RF randField = UNIFORM;
    CLP.setOption("rand_field", &randField, 
		   num_sg_rf, sg_rf_values, sg_rf_names,
		  "Random field type");

    double mean = 0.2;
    CLP.setOption("mean", &mean, "Mean");

    double sigma = 0.1;
    CLP.setOption("std_dev", &sigma, "Standard deviation");

    double weightCut = 1.0;
    CLP.setOption("weight_cut", &weightCut, "Weight cut");

    int num_KL = 2;
    CLP.setOption("num_kl", &num_KL, "Number of KL terms");

    int p = 3;
    CLP.setOption("order", &p, "Polynomial order");

    bool normalize_basis = true;
    CLP.setOption("normalize", "unnormalize", &normalize_basis, 
		  "Normalize PC basis");
    
    SG_Solver solve_method = SG_KRYLOV;
    CLP.setOption("sg_solver", &solve_method, 
		  num_sg_solver, sg_solver_values, sg_solver_names, 
		  "SG solver method");

    Krylov_Method outer_krylov_method = GMRES;
    CLP.setOption("outer_krylov_method", &outer_krylov_method, 
		  num_krylov_method, krylov_method_values, krylov_method_names, 
		  "Outer Krylov method (for Krylov-based SG solver)");

    Krylov_Solver outer_krylov_solver = AZTECOO;
    CLP.setOption("outer_krylov_solver", &outer_krylov_solver, 
		  num_krylov_solver, krylov_solver_values, krylov_solver_names, 
		  "Outer linear solver");

    double outer_tol = 1e-12;
    CLP.setOption("outer_tol", &outer_tol, "Outer solver tolerance");

    int outer_its = 1000;
    CLP.setOption("outer_its", &outer_its, "Maximum outer iterations");

    Krylov_Method inner_krylov_method = GMRES;
    CLP.setOption("inner_krylov_method", &inner_krylov_method, 
		  num_krylov_method, krylov_method_values, krylov_method_names, 
		  "Inner Krylov method (for G-S, Jacobi, etc...)");

    Krylov_Solver inner_krylov_solver = AZTECOO;
    CLP.setOption("inner_krylov_solver", &inner_krylov_solver, 
		  num_krylov_solver, krylov_solver_values, krylov_solver_names, 
		  "Inner linear solver");

    double inner_tol = 3e-13;
    CLP.setOption("inner_tol", &inner_tol, "Inner solver tolerance");

    int inner_its = 1000;
    CLP.setOption("inner_its", &inner_its, "Maximum inner iterations");

    SG_Op opMethod = MATRIX_FREE;
    CLP.setOption("sg_operator_method", &opMethod, 
		  num_sg_op, sg_op_values, sg_op_names,
		  "Operator method");

    SG_Prec precMethod = AGS;
    CLP.setOption("sg_prec_method", &precMethod, 
		  num_sg_prec, sg_prec_values, sg_prec_names,
		  "Preconditioner method");

    double gs_prec_tol = 1e-1;
    CLP.setOption("gs_prec_tol", &gs_prec_tol, "Gauss-Seidel preconditioner tolerance");

    int gs_prec_its = 1;
    CLP.setOption("gs_prec_its", &gs_prec_its, "Maximum Gauss-Seidel preconditioner iterations");

    CLP.parse( argc, argv );

    if (MyPID == 0) {
      std::cout << "Summary of command line options:" << std::endl
		<< "\tnum_mesh            = " << n << std::endl
		<< "\tsymmetric           = " << symmetric << std::endl
		<< "\tnum_spatial_procs   = " << num_spatial_procs << std::endl
		<< "\trebalance           = " << rebalance_stochastic_graph
		<< std::endl
		<< "\trand_field          = " << sg_rf_names[randField] 
		<< std::endl
		<< "\tmean                = " << mean << std::endl
		<< "\tstd_dev             = " << sigma << std::endl
		<< "\tweight_cut          = " << weightCut << std::endl
		<< "\tnum_kl              = " << num_KL << std::endl
		<< "\torder               = " << p << std::endl
		<< "\tnormalize_basis     = " << normalize_basis << std::endl
		<< "\tsg_solver           = " << sg_solver_names[solve_method] 
		<< std::endl
		<< "\touter_krylov_method = " 
		<< krylov_method_names[outer_krylov_method] << std::endl
		<< "\touter_krylov_solver = " 
		<< krylov_solver_names[outer_krylov_solver] << std::endl
		<< "\touter_tol           = " << outer_tol << std::endl
		<< "\touter_its           = " << outer_its << std::endl
		<< "\tinner_krylov_method = " 
		<< krylov_method_names[inner_krylov_method] << std::endl
		<< "\tinner_krylov_solver = " 
		<< krylov_solver_names[inner_krylov_solver] << std::endl
		<< "\tinner_tol           = " << inner_tol << std::endl
		<< "\tinner_its           = " << inner_its << std::endl
		<< "\tsg_operator_method  = " << sg_op_names[opMethod] 
		<< std::endl
		<< "\tsg_prec_method      = " << sg_prec_names[precMethod] 
		<< std::endl
		<< "\tgs_prec_tol         = " << gs_prec_tol << std::endl
		<< "\tgs_prec_its         = " << gs_prec_its << std::endl;
    }

    bool nonlinear_expansion = false;
    if (randField == UNIFORM || randField == RYS)
      nonlinear_expansion = false;
    else if (randField == LOGNORMAL)
      nonlinear_expansion = true;
    bool scaleOP = true; 

    {
    TEUCHOS_FUNC_TIME_MONITOR("Total PCE Calculation Time");

    // Create Stochastic Galerkin basis and expansion
    Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double> > > bases(num_KL); 
    for (int i=0; i<num_KL; i++)
      if (randField == UNIFORM)
        bases[i] = Teuchos::rcp(new Stokhos::LegendreBasis<int,double>(p,normalize_basis));
      else if (randField == RYS)
        bases[i] = Teuchos::rcp(new Stokhos::RysBasis<int,double>(p,weightCut,normalize_basis));
      else if (randField == LOGNORMAL)      
        bases[i] = Teuchos::rcp(new Stokhos::HermiteBasis<int,double>(p,normalize_basis));

    //  bases[i] = Teuchos::rcp(new Stokhos::DiscretizedStieltjesBasis<int,double>("beta",p,&uniform_weight,-weightCut,weightCut,true));
    Teuchos::RCP<const Stokhos::CompletePolynomialBasis<int,double> > basis = 
      Teuchos::rcp(new Stokhos::CompletePolynomialBasis<int,double>(bases));
    int sz = basis->size();
    Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > Cijk;
    if (nonlinear_expansion)
      Cijk = basis->computeTripleProductTensor(sz);
    else
      Cijk = basis->computeTripleProductTensor(num_KL+1);
    Teuchos::RCP<Stokhos::OrthogPolyExpansion<int,double> > expansion = 
      Teuchos::rcp(new Stokhos::AlgebraicOrthogPolyExpansion<int,double>(basis,
									 Cijk));
    if (MyPID == 0)
      std::cout << "Stochastic Galerkin expansion size = " << sz << std::endl;

    // Create stochastic parallel distribution
    Teuchos::ParameterList parallelParams;
    parallelParams.set("Number of Spatial Processors", num_spatial_procs);
    parallelParams.set("Rebalance Stochastic Graph", 
		       rebalance_stochastic_graph);
    Teuchos::RCP<Stokhos::ParallelData> sg_parallel_data =
      Teuchos::rcp(new Stokhos::ParallelData(basis, Cijk, globalComm,
					     parallelParams));
    Teuchos::RCP<const EpetraExt::MultiComm> sg_comm = 
      sg_parallel_data->getMultiComm();
    Teuchos::RCP<const Epetra_Comm> app_comm = 
      sg_parallel_data->getSpatialComm();
    
    // Create application
    Teuchos::RCP<twoD_diffusion_ME> model =
      Teuchos::rcp(new twoD_diffusion_ME(app_comm, n, num_KL, sigma, 
					 mean, basis, nonlinear_expansion,
					 symmetric));

    // Set up NOX parameters
    Teuchos::RCP<Teuchos::ParameterList> noxParams = 
      Teuchos::rcp(new Teuchos::ParameterList);

    // Set the nonlinear solver method
    noxParams->set("Nonlinear Solver", "Line Search Based");

    // Set the printing parameters in the "Printing" sublist
    Teuchos::ParameterList& printParams = noxParams->sublist("Printing");
    printParams.set("MyPID", MyPID); 
    printParams.set("Output Precision", 3);
    printParams.set("Output Processor", 0);
    printParams.set("Output Information", 
                    NOX::Utils::OuterIteration + 
                    NOX::Utils::OuterIterationStatusTest + 
                    NOX::Utils::InnerIteration +
		    //NOX::Utils::Parameters + 
		    NOX::Utils::Details + 
		    NOX::Utils::LinearSolverDetails +
                    NOX::Utils::Warning + 
                    NOX::Utils::Error);

    // Create printing utilities
    NOX::Utils utils(printParams);

    // Sublist for line search 
    Teuchos::ParameterList& searchParams = noxParams->sublist("Line Search");
    searchParams.set("Method", "Full Step");

    // Sublist for direction
    Teuchos::ParameterList& dirParams = noxParams->sublist("Direction");
    dirParams.set("Method", "Newton");
    Teuchos::ParameterList& newtonParams = dirParams.sublist("Newton");
    newtonParams.set("Forcing Term Method", "Constant");

    // Sublist for linear solver for the Newton method
    Teuchos::ParameterList& lsParams = newtonParams.sublist("Linear Solver");

    // Alternative linear solver list for Stratimikos
    Teuchos::ParameterList& stratLinSolParams = 
      newtonParams.sublist("Stratimikos Linear Solver");
    // Teuchos::ParameterList& noxStratParams = 
    //   stratLinSolParams.sublist("NOX Stratimikos Options");
    Teuchos::ParameterList& stratParams = 
      stratLinSolParams.sublist("Stratimikos");

    // Sublist for convergence tests
    Teuchos::ParameterList& statusParams = noxParams->sublist("Status Tests");
    statusParams.set("Test Type", "Combo");
    statusParams.set("Number of Tests", 2);
    statusParams.set("Combo Type", "OR");
    Teuchos::ParameterList& normF = statusParams.sublist("Test 0");
    normF.set("Test Type", "NormF");
    normF.set("Tolerance", outer_tol);
    normF.set("Scale Type", "Scaled");
    Teuchos::ParameterList& maxIters = statusParams.sublist("Test 1");
    maxIters.set("Test Type", "MaxIters");
    maxIters.set("Maximum Iterations", 1);

    // Create NOX interface
    Teuchos::RCP<NOX::Epetra::ModelEvaluatorInterface> det_nox_interface = 
       Teuchos::rcp(new NOX::Epetra::ModelEvaluatorInterface(model));

     // Create NOX linear system object
    Teuchos::RCP<const Epetra_Vector> det_u = model->get_x_init();
    Teuchos::RCP<Epetra_Operator> det_A = model->create_W();
    Teuchos::RCP<NOX::Epetra::Interface::Required> det_iReq = det_nox_interface;
    Teuchos::RCP<NOX::Epetra::Interface::Jacobian> det_iJac = det_nox_interface;
    Teuchos::ParameterList det_printParams;
    det_printParams.set("MyPID", MyPID); 
    det_printParams.set("Output Precision", 3);
    det_printParams.set("Output Processor", 0);
    det_printParams.set("Output Information", NOX::Utils::Error);
    
    Teuchos::ParameterList det_lsParams;
    Teuchos::ParameterList& det_stratParams = 
      det_lsParams.sublist("Stratimikos");
    if (inner_krylov_solver == AZTECOO) {
      det_stratParams.set("Linear Solver Type", "AztecOO");
      Teuchos::ParameterList& aztecOOParams = 
	det_stratParams.sublist("Linear Solver Types").sublist("AztecOO").sublist("Forward Solve");
      Teuchos::ParameterList& aztecOOSettings =
	aztecOOParams.sublist("AztecOO Settings");
      if (inner_krylov_method == GMRES) {
	aztecOOSettings.set("Aztec Solver","GMRES");
      }
      else if (inner_krylov_method == CG) {
	aztecOOSettings.set("Aztec Solver","CG");
      }
      aztecOOSettings.set("Output Frequency", 0);
      aztecOOSettings.set("Size of Krylov Subspace", 100);
      aztecOOParams.set("Max Iterations", inner_its);
      aztecOOParams.set("Tolerance", inner_tol);
      Teuchos::ParameterList& verbParams = 
	det_stratParams.sublist("Linear Solver Types").sublist("AztecOO").sublist("VerboseObject");
      verbParams.set("Verbosity Level", "none");
    }
    else if (inner_krylov_solver == BELOS) {
      det_stratParams.set("Linear Solver Type", "Belos");
      Teuchos::ParameterList& belosParams = 
	det_stratParams.sublist("Linear Solver Types").sublist("Belos");
      Teuchos::ParameterList* belosSolverParams = NULL;
      if (inner_krylov_method == GMRES || inner_krylov_method == FGMRES) {
	belosParams.set("Solver Type","Block GMRES");
	belosSolverParams = 
	  &(belosParams.sublist("Solver Types").sublist("Block GMRES"));
	if (inner_krylov_method == FGMRES)
	  belosSolverParams->set("Flexible Gmres", true);
      }
      else if (inner_krylov_method == CG) {
	belosParams.set("Solver Type","Block CG");
	belosSolverParams = 
	  &(belosParams.sublist("Solver Types").sublist("Block CG"));
      }
      else if (inner_krylov_method == RGMRES) {
      	belosParams.set("Solver Type","GCRODR");
      	belosSolverParams = 
      	  &(belosParams.sublist("Solver Types").sublist("GCRODR"));
      }
      belosSolverParams->set("Convergence Tolerance", inner_tol);
      belosSolverParams->set("Maximum Iterations", inner_its);
      belosSolverParams->set("Output Frequency",0);
      belosSolverParams->set("Output Style",1);
      belosSolverParams->set("Verbosity",0);
      Teuchos::ParameterList& verbParams = belosParams.sublist("VerboseObject");
      verbParams.set("Verbosity Level", "none");
    }
    det_stratParams.set("Preconditioner Type", "ML");
    Teuchos::ParameterList& det_ML = 
      det_stratParams.sublist("Preconditioner Types").sublist("ML").sublist("ML Settings");
    ML_Epetra::SetDefaults("SA", det_ML);
    det_ML.set("ML output", 0);
    det_ML.set("max levels",5);
    det_ML.set("increasing or decreasing","increasing");
    det_ML.set("aggregation: type", "Uncoupled");
    det_ML.set("smoother: type","ML symmetric Gauss-Seidel");
    det_ML.set("smoother: sweeps",2);
    det_ML.set("smoother: pre or post", "both");
    det_ML.set("coarse: max size", 200);
#ifdef HAVE_ML_AMESOS
    det_ML.set("coarse: type","Amesos-KLU");
#else
    det_ML.set("coarse: type","Jacobi");
#endif
    Teuchos::RCP<NOX::Epetra::LinearSystem> det_linsys = 
      Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
		     det_printParams, det_lsParams, det_iJac, 
		     det_A, *det_u));
    
    // Setup stochastic Galerkin algorithmic parameters
    Teuchos::RCP<Teuchos::ParameterList> sgParams = 
      Teuchos::rcp(new Teuchos::ParameterList);
    Teuchos::ParameterList& sgOpParams = 
      sgParams->sublist("SG Operator");
    Teuchos::ParameterList& sgPrecParams = 
      sgParams->sublist("SG Preconditioner");

    if (!nonlinear_expansion) {
      sgParams->set("Parameter Expansion Type", "Linear");
      sgParams->set("Jacobian Expansion Type", "Linear");
    }
    if (opMethod == MATRIX_FREE)
      sgOpParams.set("Operator Method", "Matrix Free");
    else if (opMethod == KL_MATRIX_FREE)
      sgOpParams.set("Operator Method", "KL Matrix Free");
    else if (opMethod == KL_REDUCED_MATRIX_FREE) {
      sgOpParams.set("Operator Method", "KL Reduced Matrix Free");
      if (randField == UNIFORM || randField == RYS)
	sgOpParams.set("Number of KL Terms", num_KL);
      else
	sgOpParams.set("Number of KL Terms", basis->size());
      sgOpParams.set("KL Tolerance", outer_tol);
      sgOpParams.set("Sparse 3 Tensor Drop Tolerance", outer_tol);
      sgOpParams.set("Do Error Tests", true);
    }
    else if (opMethod == FULLY_ASSEMBLED)
      sgOpParams.set("Operator Method", "Fully Assembled");
    else
      TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
		       "Error!  Unknown operator method " << opMethod
			 << "." << std::endl);
    if (precMethod == MEAN)  {
      sgPrecParams.set("Preconditioner Method", "Mean-based");
      sgPrecParams.set("Mean Preconditioner Type", "ML");
      Teuchos::ParameterList& precParams =
	sgPrecParams.sublist("Mean Preconditioner Parameters");
      precParams = det_ML;
    }
    else if(precMethod == GS) {
      sgPrecParams.set("Preconditioner Method", "Gauss-Seidel");
      sgPrecParams.sublist("Deterministic Solver Parameters") = det_lsParams;
      sgPrecParams.set("Deterministic Solver", det_linsys);
      sgPrecParams.set("Max Iterations", gs_prec_its);
      sgPrecParams.set("Tolerance", gs_prec_tol);
    }
    else if (precMethod == AGS)  {
      sgPrecParams.set("Preconditioner Method", "Approximate Gauss-Seidel");
      if (outer_krylov_method == CG)
	sgPrecParams.set("Symmetric Gauss-Seidel", true);
      sgPrecParams.set("Mean Preconditioner Type", "ML");
      Teuchos::ParameterList& precParams =
	sgPrecParams.sublist("Mean Preconditioner Parameters");
      precParams = det_ML;
    }
    else if (precMethod == AJ)  {
      sgPrecParams.set("Preconditioner Method", "Approximate Jacobi");
      sgPrecParams.set("Mean Preconditioner Type", "ML");
      Teuchos::ParameterList& precParams =
        sgPrecParams.sublist("Mean Preconditioner Parameters");
      precParams = det_ML;
      Teuchos::ParameterList& jacobiOpParams =
	sgPrecParams.sublist("Jacobi SG Operator");
      jacobiOpParams.set("Only Use Linear Terms", true);
    }
    else if (precMethod == ASC)  {
      sgPrecParams.set("Preconditioner Method", "Approximate Schur Complement");
      sgPrecParams.set("Mean Preconditioner Type", "ML");
      Teuchos::ParameterList& precParams =
	sgPrecParams.sublist("Mean Preconditioner Parameters");
      precParams = det_ML;
    }
    else if (precMethod == KP)  {
      sgPrecParams.set("Preconditioner Method", "Kronecker Product");
      sgPrecParams.set("Only Use Linear Terms", true);
      sgPrecParams.set("Mean Preconditioner Type", "ML");
      Teuchos::ParameterList& meanPrecParams =
        sgPrecParams.sublist("Mean Preconditioner Parameters");
      meanPrecParams = det_ML;
      sgPrecParams.set("G Preconditioner Type", "Ifpack");
      Teuchos::ParameterList& GPrecParams =
        sgPrecParams.sublist("G Preconditioner Parameters");
      if (outer_krylov_method == GMRES || outer_krylov_method == FGMRES)
	GPrecParams.set("Ifpack Preconditioner", "ILUT");
      if (outer_krylov_method == CG)
	GPrecParams.set("Ifpack Preconditioner", "ICT");
      GPrecParams.set("Overlap", 1);
      GPrecParams.set("fact: drop tolerance", 1e-4);
      GPrecParams.set("fact: ilut level-of-fill", 1.0);
      GPrecParams.set("schwarz: combine mode", "Add");
    }
    else if (precMethod == NONE)  {
      sgPrecParams.set("Preconditioner Method", "None");
    }
    else
      TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
		       "Error!  Unknown preconditioner method " << precMethod
			 << "." << std::endl);

    // Create stochastic Galerkin model evaluator
    Teuchos::RCP<Stokhos::SGModelEvaluator> sg_model =
      Teuchos::rcp(new Stokhos::SGModelEvaluator(model, basis, Teuchos::null,
                                                 expansion, sg_parallel_data, 
						 sgParams, scaleOP));
    EpetraExt::ModelEvaluator::InArgs sg_inArgs = sg_model->createInArgs();
    EpetraExt::ModelEvaluator::OutArgs sg_outArgs = 
      sg_model->createOutArgs();

    // Set up stochastic parameters
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_p_init =
      sg_model->create_p_sg(0);
    for (int i=0; i<num_KL; i++) {
      sg_p_init->term(i,0)[i] = 0.0;
      sg_p_init->term(i,1)[i] = 1.0;
    }
    sg_model->set_p_sg_init(0, *sg_p_init);

    // Setup stochastic initial guess
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_x_init = 
      sg_model->create_x_sg();
    sg_x_init->init(0.0);
    sg_model->set_x_sg_init(*sg_x_init);

     // Create NOX interface
    Teuchos::RCP<NOX::Epetra::ModelEvaluatorInterface> nox_interface =
       Teuchos::rcp(new NOX::Epetra::ModelEvaluatorInterface(sg_model));

    // Create NOX stochastic linear system object
    Teuchos::RCP<const Epetra_Vector> u = sg_model->get_x_init();
    Teuchos::RCP<const Epetra_Map> base_map = model->get_x_map();
    Teuchos::RCP<const Epetra_Map> sg_map = sg_model->get_x_map();
    Teuchos::RCP<Epetra_Operator> A = sg_model->create_W();
    Teuchos::RCP<NOX::Epetra::Interface::Required> iReq = nox_interface;
    Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac = nox_interface;

    // Build linear solver
    Teuchos::RCP<NOX::Epetra::LinearSystem> linsys;
    if (solve_method==SG_KRYLOV) {
      bool has_M = 
	sg_outArgs.supports(EpetraExt::ModelEvaluator::OUT_ARG_WPrec);
      Teuchos::RCP<Epetra_Operator> M;
      Teuchos::RCP<NOX::Epetra::Interface::Preconditioner> iPrec;
      if (has_M) {
	M = sg_model->create_WPrec()->PrecOp;
	iPrec = nox_interface;
      }
      stratParams.set("Preconditioner Type", "None");
      if (outer_krylov_solver == AZTECOO) {
	stratParams.set("Linear Solver Type", "AztecOO");
	Teuchos::ParameterList& aztecOOParams = 
	  stratParams.sublist("Linear Solver Types").sublist("AztecOO").sublist("Forward Solve");
	Teuchos::ParameterList& aztecOOSettings =
	  aztecOOParams.sublist("AztecOO Settings");
	if (outer_krylov_method == GMRES) {
	  aztecOOSettings.set("Aztec Solver","GMRES");
	}
	else if (outer_krylov_method == CG) {
	  aztecOOSettings.set("Aztec Solver","CG");
	}
	aztecOOSettings.set("Output Frequency", 1);
	aztecOOSettings.set("Size of Krylov Subspace", 100);
	aztecOOParams.set("Max Iterations", outer_its);
	aztecOOParams.set("Tolerance", outer_tol);
	stratLinSolParams.set("Preconditioner", "User Defined");
	if (has_M)
	  linsys = 
	    Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
			   printParams, stratLinSolParams, iJac, A, iPrec, M, 
			   *u, true));
	else
	  linsys = 
	    Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
			   printParams, stratLinSolParams, iJac, A, *u));
      }
      else if (outer_krylov_solver == BELOS){
	stratParams.set("Linear Solver Type", "Belos");
	Teuchos::ParameterList& belosParams = 
	  stratParams.sublist("Linear Solver Types").sublist("Belos");
	Teuchos::ParameterList* belosSolverParams = NULL;
	if (outer_krylov_method == GMRES || outer_krylov_method == FGMRES) {
	  belosParams.set("Solver Type","Block GMRES");
	  belosSolverParams = 
	    &(belosParams.sublist("Solver Types").sublist("Block GMRES"));
	  if (outer_krylov_method == FGMRES)
	    belosSolverParams->set("Flexible Gmres", true);
	}
	else if (outer_krylov_method == CG) {
	  belosParams.set("Solver Type","Block CG");
	  belosSolverParams = 
	    &(belosParams.sublist("Solver Types").sublist("Block CG"));
	}
	else if (inner_krylov_method == RGMRES) {
	  belosParams.set("Solver Type","GCRODR");
	  belosSolverParams = 
	    &(belosParams.sublist("Solver Types").sublist("GCRODR"));
	}
	belosSolverParams->set("Convergence Tolerance", outer_tol);
	belosSolverParams->set("Maximum Iterations", outer_its);
	belosSolverParams->set("Output Frequency",1);
	belosSolverParams->set("Output Style",1);
	belosSolverParams->set("Verbosity",33);
	stratLinSolParams.set("Preconditioner", "User Defined");
	if (has_M)
	  linsys = 
	    Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
			   printParams, stratLinSolParams, iJac, A, iPrec, M, 
			   *u, true));
	else
	  linsys = 
	    Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
			   printParams, stratLinSolParams, iJac, A, *u));
	  
      }
    }
    else if (solve_method==SG_GS) {
      lsParams.sublist("Deterministic Solver Parameters") = det_lsParams;
      lsParams.set("Max Iterations", outer_its);
      lsParams.set("Tolerance", outer_tol);
      linsys =
	Teuchos::rcp(new NOX::Epetra::LinearSystemSGGS(
		       printParams, lsParams, det_linsys, iReq, iJac, 
		       basis, sg_parallel_data, A, base_map, sg_map));
    }
    else {
      lsParams.sublist("Deterministic Solver Parameters") = det_lsParams;
      lsParams.set("Max Iterations", outer_its);
      lsParams.set("Tolerance", outer_tol);
      Teuchos::ParameterList& jacobiOpParams =
	lsParams.sublist("Jacobi SG Operator");
      jacobiOpParams.set("Only Use Linear Terms", true);
      linsys =
	Teuchos::rcp(new NOX::Epetra::LinearSystemSGJacobi(
		       printParams, lsParams, det_linsys, iReq, iJac, 
		       basis, sg_parallel_data, A, base_map, sg_map));
    }

    // Build NOX group
    Teuchos::RCP<NOX::Epetra::Group> grp = 
      Teuchos::rcp(new NOX::Epetra::Group(printParams, iReq, *u, linsys));
    
    // Create the Solver convergence test
    Teuchos::RCP<NOX::StatusTest::Generic> statusTests =
      NOX::StatusTest::buildStatusTests(statusParams, utils);

    // Create the solver
    Teuchos::RCP<NOX::Solver::Generic> solver = 
      NOX::Solver::buildSolver(grp, statusTests, noxParams);

    // Solve the system
    NOX::StatusTest::StatusType status;
    {
      TEUCHOS_FUNC_TIME_MONITOR("Total Solve Time");
      status = solver->solve();
    }

    // Get final solution
    const NOX::Epetra::Group& finalGroup = 
      dynamic_cast<const NOX::Epetra::Group&>(solver->getSolutionGroup());
    const Epetra_Vector& finalSolution = 
      (dynamic_cast<const NOX::Epetra::Vector&>(finalGroup.getX())).getEpetraVector();

    // Save final solution to file
    EpetraExt::VectorToMatrixMarketFile("nox_solver_stochastic_solution.mm", 
					finalSolution);

    // Save mean and variance to file
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_x_poly = 
      sg_model->create_x_sg(View, &finalSolution);
    Epetra_Vector mean(*(model->get_x_map()));
    Epetra_Vector std_dev(*(model->get_x_map()));
    sg_x_poly->computeMean(mean);
    sg_x_poly->computeStandardDeviation(std_dev);
    EpetraExt::VectorToMatrixMarketFile("mean_gal.mm", mean);
    EpetraExt::VectorToMatrixMarketFile("std_dev_gal.mm", std_dev);
      
    // Evaluate SG responses at SG parameters
    Teuchos::RCP<const Epetra_Vector> sg_p = sg_model->get_p_init(1);
    Teuchos::RCP<Epetra_Vector> sg_g = 
      Teuchos::rcp(new Epetra_Vector(*(sg_model->get_g_map(0))));
    sg_inArgs.set_p(1, sg_p);
    sg_inArgs.set_x(Teuchos::rcp(&finalSolution,false));
    sg_outArgs.set_g(0, sg_g);
    sg_model->evalModel(sg_inArgs, sg_outArgs);

    // Print mean and standard deviation of response
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_g_poly =
      sg_model->create_g_sg(0, View, sg_g.get());
    Epetra_Vector g_mean(*(model->get_g_map(0)));
    Epetra_Vector g_std_dev(*(model->get_g_map(0)));
    sg_g_poly->computeMean(g_mean);
    sg_g_poly->computeStandardDeviation(g_std_dev);
    std::cout.precision(16);
    // std::cout << "\nResponse Expansion = " << std::endl;
    // std::cout.precision(12);
    // sg_g_poly->print(std::cout);
    std::cout << "\nResponse Mean =      " << std::endl << g_mean << std::endl;
    std::cout << "Response Std. Dev. = " << std::endl << g_std_dev << std::endl;

    if (status == NOX::StatusTest::Converged && MyPID == 0) 
      utils.out() << "Example Passed!" << std::endl;

    }

    Teuchos::TimeMonitor::summarize(std::cout);
    Teuchos::TimeMonitor::zeroOutTimers();

  }
  
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
  }
  catch (string& s) {
    std::cout << s << std::endl;
  }
  catch (char *s) {
    std::cout << s << std::endl;
  }
  catch (...) {
    std::cout << "Caught unknown exception!" <<std:: endl;
  }

#ifdef HAVE_MPI
  MPI_Finalize() ;
#endif

}
void 
Stokhos::SGQuadModelEvaluator::
evalModel(const InArgs& inArgs, const OutArgs& outArgs) const
{
  // Create underlying inargs
  InArgs me_inargs = me->createInArgs();
  if (me_inargs.supports(IN_ARG_x))
    me_inargs.set_x(inArgs.get_x());
  if (me_inargs.supports(IN_ARG_x_dot))
    me_inargs.set_x_dot(inArgs.get_x_dot());
  if (me_inargs.supports(IN_ARG_alpha))
    me_inargs.set_alpha(inArgs.get_alpha());
  if (me_inargs.supports(IN_ARG_beta))
    me_inargs.set_beta(inArgs.get_beta());
  if (me_inargs.supports(IN_ARG_t))
    me_inargs.set_t(inArgs.get_t());
  for (int i=0; i<num_p; i++)
    me_inargs.set_p(i, inArgs.get_p(i));

  // Create underlying outargs
  OutArgs me_outargs = me->createOutArgs();
  if (me_outargs.supports(OUT_ARG_f))
    me_outargs.set_f(outArgs.get_f());
  if (me_outargs.supports(OUT_ARG_W))
    me_outargs.set_W(outArgs.get_W());
  for (int j=0; j<num_p; j++)
    if (!outArgs.supports(OUT_ARG_DfDp, j).none())
      me_outargs.set_DfDp(j, outArgs.get_DfDp(j));
  for (int i=0; i<num_g; i++) {
    me_outargs.set_g(i, outArgs.get_g(i));
    if (!outArgs.supports(OUT_ARG_DgDx, i).none())
	me_outargs.set_DgDx(i, outArgs.get_DgDx(i));
    if (!outArgs.supports(OUT_ARG_DgDx_dot, i).none())
	me_outargs.set_DgDx(i, outArgs.get_DgDx_dot(i));
    for (int j=0; j<num_p; j++)
      if (!outArgs.supports(OUT_ARG_DgDp, i, j).none())
	me_outargs.set_DgDp(i, j, outArgs.get_DgDp(i,j));
  }

  bool do_quad = false;
  InArgs::sg_const_vector_t x_sg;
  InArgs::sg_const_vector_t x_dot_sg;
  Teuchos::Array<InArgs::sg_const_vector_t> p_sg(num_p);
  OutArgs::sg_vector_t f_sg;
  OutArgs::sg_operator_t W_sg;
  Teuchos::Array<SGDerivative> dfdp_sg(num_p);
  Teuchos::Array<OutArgs::sg_vector_t> g_sg(num_g);
  Teuchos::Array<SGDerivative> dgdx_sg(num_g);
  Teuchos::Array<SGDerivative> dgdx_dot_sg(num_g);
  Teuchos::Array< Teuchos::Array<SGDerivative> > dgdp_sg(num_g);
  TEUCHOS_TEST_FOR_EXCEPTION(inArgs.get_sg_basis() == Teuchos::null, 
		     std::logic_error,
		     "Error!  Stokhos::SGQuadModelEvaluator::evalModel():  " <<
		     "SG basis inArg cannot be null!");
  TEUCHOS_TEST_FOR_EXCEPTION(inArgs.get_sg_quadrature() == Teuchos::null, 
		     std::logic_error,
		     "Error!  Stokhos::SGQuadModelEvaluator::evalModel():  " <<
		     "SG quadrature inArg cannot be null!");
  Teuchos::RCP<const Stokhos::OrthogPolyBasis<int,double> > basis = 
    inArgs.get_sg_basis();
  Teuchos::RCP< const Stokhos::Quadrature<int,double> > quad = 
    inArgs.get_sg_quadrature();
  if (inArgs.supports(IN_ARG_x_sg)) {
    x_sg = inArgs.get_x_sg();
    if (x_sg != Teuchos::null) {
      do_quad = true;
    }
  }
  if (inArgs.supports(IN_ARG_x_dot_sg)) {
    x_dot_sg = inArgs.get_x_dot_sg();
    if (x_dot_sg != Teuchos::null) {
      do_quad = true;
    }
  }
  for (int i=0; i<num_p; i++) {
    p_sg[i] = inArgs.get_p_sg(i);
    if (p_sg[i] != Teuchos::null) {
      do_quad = true;
    }
  }
  if (outArgs.supports(OUT_ARG_f_sg)) {
    f_sg = outArgs.get_f_sg();
    if (f_sg != Teuchos::null)
      f_sg->init(0.0);
  }
  if (outArgs.supports(OUT_ARG_W_sg)) {
    W_sg = outArgs.get_W_sg();
    if (W_sg != Teuchos::null)
      W_sg->init(0.0);
  }
  for (int i=0; i<num_p; i++) {
    if (!outArgs.supports(OUT_ARG_DfDp_sg, i).none()) {
      dfdp_sg[i] = outArgs.get_DfDp_sg(i);
      if (dfdp_sg[i].getMultiVector() != Teuchos::null)
	dfdp_sg[i].getMultiVector()->init(0.0);
      else if (dfdp_sg[i].getLinearOp() != Teuchos::null)
	dfdp_sg[i].getLinearOp()->init(0.0);
    }
  }
      
  for (int i=0; i<num_g; i++) {
    g_sg[i] = outArgs.get_g_sg(i);
    if (g_sg[i] != Teuchos::null)
      g_sg[i]->init(0.0);
    
    if (!outArgs.supports(OUT_ARG_DgDx_sg, i).none()) {
      dgdx_sg[i] = outArgs.get_DgDx_sg(i);
      if (dgdx_sg[i].getMultiVector() != Teuchos::null)
	dgdx_sg[i].getMultiVector()->init(0.0);
      else if (dgdx_sg[i].getLinearOp() != Teuchos::null)
	dgdx_sg[i].getLinearOp()->init(0.0);
    }

    if (!outArgs.supports(OUT_ARG_DgDx_dot_sg, i).none()) {
      dgdx_dot_sg[i] = outArgs.get_DgDx_dot_sg(i);
      if (dgdx_dot_sg[i].getMultiVector() != Teuchos::null)
	dgdx_dot_sg[i].getMultiVector()->init(0.0);
      else if (dgdx_dot_sg[i].getLinearOp() != Teuchos::null)
	dgdx_dot_sg[i].getLinearOp()->init(0.0);
    }

    dgdp_sg[i].resize(num_p);
    for (int j=0; j<num_p; j++) {
      if (!outArgs.supports(OUT_ARG_DgDp_sg, i, j).none()) {
	dgdp_sg[i][j] = outArgs.get_DgDp_sg(i,j);
	if (dgdp_sg[i][j].getMultiVector() != Teuchos::null)
	  dgdp_sg[i][j].getMultiVector()->init(0.0);
	else if (dgdp_sg[i][j].getLinearOp() != Teuchos::null)
	  dgdp_sg[i][j].getLinearOp()->init(0.0);
      }
    }
  }

  if (do_quad) {
    // Get quadrature data
    const Teuchos::Array< Teuchos::Array<double> >& quad_points = 
      quad->getQuadPoints();
    const Teuchos::Array<double>& quad_weights = 
      quad->getQuadWeights();
    const Teuchos::Array< Teuchos::Array<double> > & quad_values = 
      quad->getBasisAtQuadPoints();
    const Teuchos::Array<double>& basis_norms = basis->norm_squared();

    // Perform integrations
    for (int qp=0; qp<quad_points.size(); qp++) {

      // StieltjesPCEBasis can introduce quadrature points with zero weight
      // Don't do those evaluations, since the model might not like the
      // quadrature points (i.e., zero)
      if (quad_weights[qp] == 0.0)
	continue;

      {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
        TEUCHOS_FUNC_TIME_MONITOR_DIFF("Stokhos: SGQuadModelEvaluator -- Polynomial Evaluation",
          PolyEvaluation);
#endif

        // Evaluate inputs at quadrature points
        if (x_sg != Teuchos::null) {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
          TEUCHOS_FUNC_TIME_MONITOR("Stokhos: SGQuadModelEvaluator -- X Evaluation");
#endif
          x_sg->evaluate(quad_values[qp], *x_qp);
          me_inargs.set_x(x_qp);
        }
        if (x_dot_sg != Teuchos::null) {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
          TEUCHOS_FUNC_TIME_MONITOR("Stokhos: SGQuadModelEvaluator -- X_dot Evaluation");
#endif
          x_dot_sg->evaluate(quad_values[qp], *x_dot_qp);
          me_inargs.set_x_dot(x_qp);
        }
        for (int i=0; i<num_p; i++) {
          if (p_sg[i] != Teuchos::null) {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
            TEUCHOS_FUNC_TIME_MONITOR("Stokhos: SGQuadModelEvaluator -- P Evaluation");
#endif
            p_sg[i]->evaluate(quad_values[qp], *(p_qp[i]));
            me_inargs.set_p(i, p_qp[i]);
          }
        }
        if (f_sg != Teuchos::null)
          me_outargs.set_f(f_qp);
        if (W_sg != Teuchos::null)
          me_outargs.set_W(W_qp);
	for (int i=0; i<num_p; i++) {
	  if (!dfdp_sg[i].isEmpty())
	    me_outargs.set_DfDp(i, dfdp_qp[i]);
	}
        for (int i=0; i<num_g; i++) {
	  if (g_sg[i] != Teuchos::null)
	    me_outargs.set_g(i, g_qp[i]);
	  if (!dgdx_dot_sg[i].isEmpty())
	    me_outargs.set_DgDx_dot(i, dgdx_dot_qp[i]);
	  if (!dgdx_sg[i].isEmpty())
	    me_outargs.set_DgDx(i, dgdx_qp[i]);
          for (int j=0; j<num_p; j++)
            if (!dgdp_sg[i][j].isEmpty())
              me_outargs.set_DgDp(i, j, dgdp_qp[i][j]);
        }

      }

      {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
        TEUCHOS_FUNC_TIME_MONITOR("Stokhos: SGQuadModelEvaluator -- Model Evaluation");
#endif

        // Evaluate model at quadrature points
        me->evalModel(me_inargs, me_outargs);

      }

      {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
        TEUCHOS_FUNC_TIME_MONITOR_DIFF(
	  "Stokhos: SGQuadModelEvaluator -- Polynomial Integration", Integration);
#endif

        // Sum in results
        if (f_sg != Teuchos::null) {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
          TEUCHOS_FUNC_TIME_MONITOR("Stokhos: SGQuadModelEvaluator -- F Integration");
#endif
          f_sg->sumIntoAllTerms(quad_weights[qp], quad_values[qp], basis_norms,
				*f_qp);
        }
        if (W_sg != Teuchos::null) {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
          TEUCHOS_FUNC_TIME_MONITOR("Stokhos: SGQuadModelEvaluator -- W Integration");
#endif
          W_sg->sumIntoAllTerms(quad_weights[qp], quad_values[qp], basis_norms,
				*W_qp);
        }
	for (int j=0; j<num_p; j++) {
	  if (!dfdp_sg[j].isEmpty()) {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
	    TEUCHOS_FUNC_TIME_MONITOR(
	      "Stokhos: SGQuadModelEvaluator -- df/dp Integration");
#endif
	    if (dfdp_sg[j].getMultiVector() != Teuchos::null) {
	      dfdp_sg[j].getMultiVector()->sumIntoAllTerms(
		quad_weights[qp], quad_values[qp], basis_norms, 
		*(dfdp_qp[j].getMultiVector()));
	    }
	    else if (dfdp_sg[j].getLinearOp() != Teuchos::null) {
	      dfdp_sg[j].getLinearOp()->sumIntoAllTerms(
		quad_weights[qp], quad_values[qp], basis_norms, 
		*(dfdp_qp[j].getLinearOp()));
	    }
	  }
	}
        for (int i=0; i<num_g; i++) {
          if (g_sg[i] != Teuchos::null) {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
            TEUCHOS_FUNC_TIME_MONITOR("Stokhos: SGQuadModelEvaluator -- G Integration");
#endif
            g_sg[i]->sumIntoAllTerms(quad_weights[qp], quad_values[qp], 
				     basis_norms, *g_qp[i]);
          }
	  if (!dgdx_dot_sg[i].isEmpty()) {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
	    TEUCHOS_FUNC_TIME_MONITOR(
	      "Stokhos: SGQuadModelEvaluator -- dg/dx_dot Integration");
#endif
	    if (dgdx_dot_sg[i].getMultiVector() != Teuchos::null) {
	      dgdx_dot_sg[i].getMultiVector()->sumIntoAllTerms(
		quad_weights[qp], quad_values[qp], basis_norms, 
		*(dgdx_dot_qp[i].getMultiVector()));
	    }
	    else if (dgdx_dot_sg[i].getLinearOp() != Teuchos::null) {
	      dgdx_dot_sg[i].getLinearOp()->sumIntoAllTerms(
		quad_weights[qp], quad_values[qp], basis_norms, 
		*(dgdx_dot_qp[i].getLinearOp()));
	    }
	  }
	  if (!dgdx_sg[i].isEmpty()) {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
	    TEUCHOS_FUNC_TIME_MONITOR(
	      "Stokhos: SGQuadModelEvaluator -- dg/dx Integration");
#endif
	    if (dgdx_sg[i].getMultiVector() != Teuchos::null) {
	      dgdx_sg[i].getMultiVector()->sumIntoAllTerms(
		quad_weights[qp], quad_values[qp], basis_norms, 
		*(dgdx_qp[i].getMultiVector()));
	    }
	    else if (dgdx_sg[i].getLinearOp() != Teuchos::null) {
	      dgdx_sg[i].getLinearOp()->sumIntoAllTerms(
		quad_weights[qp], quad_values[qp], basis_norms, 
		*(dgdx_qp[i].getLinearOp()));
	    }
	  }
          for (int j=0; j<num_p; j++) {
	    if (!dgdp_sg[i][j].isEmpty()) {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
	      TEUCHOS_FUNC_TIME_MONITOR(
		"Stokhos: SGQuadModelEvaluator -- dg/dp Integration");
#endif
	      if (dgdp_sg[i][j].getMultiVector() != Teuchos::null) {
		dgdp_sg[i][j].getMultiVector()->sumIntoAllTerms(
		  quad_weights[qp], quad_values[qp], basis_norms, 
		  *(dgdp_qp[i][j].getMultiVector()));
	      }
	      else if (dgdp_sg[i][j].getLinearOp() != Teuchos::null) {
		dgdp_sg[i][j].getLinearOp()->sumIntoAllTerms(
		  quad_weights[qp], quad_values[qp], basis_norms, 
		  *(dgdp_qp[i][j].getLinearOp()));
	      }
	    }
          }
        }

      }
    }
  }
  else {
    // Compute the non-SG functions
    me->evalModel(me_inargs, me_outargs);
  }
}
示例#23
0
void
Stokhos::QuadOrthogPolyExpansion<int, float, Stokhos::CUDAStorage<int, float> >::
binary_op(const FuncT& func,
          OrthogPolyApprox<int, float, CUDAStorage<int,float> >& c, 
          const OrthogPolyApprox<int, float, CUDAStorage<int,float> >& a, 
          const OrthogPolyApprox<int, float, CUDAStorage<int,float> >& b)
{
  int pa = a.size();
  int pb = b.size();
  int pc;
  if (pa == 1 && pb == 1)
    pc = 1;
  else
    pc = sz;
  if (c.size() != pc)
    c.resize(pc);

  if (pc == 1) {
    c[0] = func(a[0], b[0]);
    return;
  }

  float *qv_ptr = thrust::raw_pointer_cast(qv.data());
  float *sqv_ptr = thrust::raw_pointer_cast(sqv.data());
  const float *a_ptr = thrust::raw_pointer_cast(a.coeff());
  const float *b_ptr = thrust::raw_pointer_cast(b.coeff());
  float *c_ptr = thrust::raw_pointer_cast(c.coeff());
  float *avals_ptr = thrust::raw_pointer_cast(avals.data());
  float *bvals_ptr = thrust::raw_pointer_cast(bvals.data());
  float *fvals_ptr = thrust::raw_pointer_cast(fvals.data());

  {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::QuadExp --Binary Polynomial Evaluation");
#endif

  // Evaluate input
  cublasSgemv('T', pa, nqp, 1.0, qv_ptr, sz, a_ptr, 1, 0.0, avals_ptr, 1);
  cublasSgemv('T', pb, nqp, 1.0, qv_ptr, sz, b_ptr, 1, 0.0, bvals_ptr, 1);

  }

  {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::QuadExp -- Binary Function Evaluation");
#endif

  // Evaluate function
  thrust::transform(avals.begin(), avals.end(), bvals.begin(), fvals.begin(), 
		    func);

  }

  {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::QuadExp -- Binary Polynomial Integration");
#endif

  // Integrate
  cublasSgemv('N', pc, nqp, 1.0, sqv_ptr, sz, fvals_ptr, 1, 0.0, c_ptr, 1);

  }
}
示例#24
0
void
Stokhos::QuadOrthogPolyExpansion<int, float, Stokhos::CUDAStorage<int,float> >::
nary_op(const FuncT& func,
	OrthogPolyApprox<int, float, Stokhos::CUDAStorage<int,float> >& c, 
	const OrthogPolyApprox<int, float, Stokhos::CUDAStorage<int,float> >** na)
{
  const int N = FuncT::N;
  bool is_constant = true;
  for (int i=0; i<N; i++) {
    if (na[i]->size() > 1) {
      is_constant = false;
      break;
    }
  }
  int pc;
  if (is_constant)
    pc = 1;
  else
    pc = sz;
  if (c.size() != pc)
    c.resize(pc);

  if (pc == 1) {
    float val[N];
    for (int i=0; i<N; i++)
      val[i] = (*na[i])[0];
    c[0] = func(val);
    return;
  }

  if (N >= navals.size())
    navals.resize(N+1);
  if (navals[N].size() != N) {
    navals[N].resize(N);
    for (int i=0; i<N; i++)
      navals[N][i].resize(nqp);
  }

  float *qv_ptr = thrust::raw_pointer_cast(qv.data());
  float *sqv_ptr = thrust::raw_pointer_cast(sqv.data());
  float *c_ptr = thrust::raw_pointer_cast(c.coeff());
  float *fvals_ptr = thrust::raw_pointer_cast(fvals.data());

  {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::QuadExp -- N(" << N << ")-ary Polynomial Evaluation");
#endif

  // Evaluate input
  for (int i=0; i<N; i++) {
    int pa = na[i]->size();
    const float *na_ptr = thrust::raw_pointer_cast(na[i]->coeff());
    float *navals_ptr = thrust::raw_pointer_cast(navals[N][i].data());
    cublasSgemv('T', pa, nqp, 1.0, qv_ptr, sz, na_ptr, 1, 0.0, navals_ptr, 1);
  }

  }

  {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::QuadExp -- N(" << N << ")-ary Function Evaluation");
#endif

  // Evaluate function
  thrust::transform(
    thrust::make_zip_iterator(make_tuple_N<N,navals_type>::begin(navals[N])), 
    thrust::make_zip_iterator(make_tuple_N<N,navals_type>::end(navals[N])), 
    fvals.begin(), 
    func);

  }

  {
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::QuadExp -- N(" << N << ")-ary Polynomial Integration");
#endif

  // Integrate
  cublasSgemv('N', pc, nqp, 1.0, sqv_ptr, sz, fvals_ptr, 1, 0.0, c_ptr, 1);

  }
}
Stokhos::AnisoSparseGridQuadrature<ordinal_type, value_type>::
AnisoSparseGridQuadrature(
  const Teuchos::RCP<const ProductBasis<ordinal_type,value_type> >& product_basis,
  ordinal_type sparse_grid_level, value_type dim_weights[]) :
  coordinate_bases(product_basis->getCoordinateBases())
{
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::AnisoSparseGridQuadrature -- Quad Grid Generation");
  ordinal_type d = product_basis->dimension();
  ordinal_type p = product_basis->order();
  ordinal_type sz = product_basis->size();
  ordinal_type level = sparse_grid_level;

  // Mike's heuristic formula for computing the level
  if (level == 0) {
    level = static_cast<ordinal_type>(std::ceil(0.5*(p+d-1)));
    if (level < d)
      level = p;
  }

  std::cout << "Sparse grid level = " << level << std::endl;

  // Compute quad points, weights, values
  Teuchos::Array<int> rules(d), growthRules(d);

  Teuchos::Array< void (*) ( int order, int dim, double x[] ) > compute1DPoints(d);
  Teuchos::Array< void (*) ( int order, int dim, double w[] ) > compute1DWeights(d);
  for (ordinal_type i=0; i<d; i++) {
    compute1DPoints[i] = &(getMyPoints);
    compute1DWeights[i] = &(getMyWeights);
    rules[i] = coordinate_bases[i]->getSparseGridRule();
    growthRules[i] = coordinate_bases[i]->getSparseGridGrowthRule();
  }

  // Set the static sparse grid quadrature pointer to this
  // (this will cause a conflict if another sparse grid quadrature object
  // is trying to access the VPISparseGrid library, but that's all we can
  // do at this point).
  sgq = this;

  int num_total_pts =
    webbur::sandia_sgmga_size_total(d,&dim_weights[0],level,&rules[0],
				    &growthRules[0]);

  ordinal_type ntot =
    webbur::sandia_sgmga_size(d,&dim_weights[0],level,&rules[0],
			      &compute1DPoints[0], 1e-15,&growthRules[0]);

  Teuchos::Array<int> sparse_order(ntot*d);
  Teuchos::Array<int> sparse_index(ntot*d);
  Teuchos::Array<int> sparse_unique_index(num_total_pts);
  quad_points.resize(ntot);
  quad_weights.resize(ntot);
  quad_values.resize(ntot);
  Teuchos::Array<value_type> gp(ntot*d);

  webbur::sandia_sgmga_unique_index(d, &dim_weights[0], level, &rules[0],
				    &compute1DPoints[0],
				    1e-15, ntot, num_total_pts,
				    &growthRules[0],
				    &sparse_unique_index[0] );


  webbur::sandia_sgmga_index(d, &dim_weights[0], level,
			     &rules[0], ntot, num_total_pts, 
			     &sparse_unique_index[0],
			     &growthRules[0],
			     &sparse_order[0], &sparse_index[0]);

  webbur::sandia_sgmga_weight(d,&dim_weights[0],level,
			      &rules[0], &compute1DWeights[0],
			      ntot, num_total_pts, &sparse_unique_index[0],
			      &growthRules[0],
			      &quad_weights[0]);

  webbur::sandia_sgmga_point(d, &dim_weights[0], level,
			     &rules[0], &compute1DPoints[0],
			     ntot, &sparse_order[0], &sparse_index[0],
			     &growthRules[0],
			     &gp[0]);

  for (ordinal_type i=0; i<ntot; i++) {
    quad_values[i].resize(sz);
    quad_points[i].resize(d);
    for (ordinal_type j=0; j<d; j++)
      quad_points[i][j] = gp[i*d+j];
    product_basis->evaluateBases(quad_points[i], quad_values[i]);
  }

  std::cout << "Number of quadrature points = " << ntot << std::endl;
}
int
Stokhos::ApproxGaussSeidelPreconditioner::
ApplyInverse(const Epetra_MultiVector& Input, Epetra_MultiVector& Result) const
{
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
  TEUCHOS_FUNC_TIME_MONITOR("Stokhos: Total Approximate Gauss-Seidel Time");
#endif

  // We have to be careful if Input and Result are the same vector.
  // If this is the case, the only possible solution is to make a copy
  const Epetra_MultiVector *input = &Input;
  bool made_copy = false;
  if (Input.Values() == Result.Values()) {
    input = new Epetra_MultiVector(Input);
    made_copy = true;
  }

  int m = input->NumVectors();
  if (mat_vec_tmp == Teuchos::null || mat_vec_tmp->NumVectors() != m)
    mat_vec_tmp = Teuchos::rcp(new Epetra_MultiVector(*base_map, m));
  if (rhs_block == Teuchos::null || rhs_block->NumVectors() != m)
    rhs_block =
      Teuchos::rcp(new EpetraExt::BlockMultiVector(*base_map, *sg_map, m));

  // Extract blocks
  EpetraExt::BlockMultiVector input_block(View, *base_map, *input);
  EpetraExt::BlockMultiVector result_block(View, *base_map, Result);

  result_block.PutScalar(0.0);

  int k_limit = sg_poly->size();
  if (only_use_linear)
    k_limit = sg_poly->basis()->dimension() + 1;
  const Teuchos::Array<double>& norms = sg_basis->norm_squared();

  rhs_block->Update(1.0, input_block, 0.0);

  for (Cijk_type::i_iterator i_it=Cijk->i_begin();
       i_it!=Cijk->i_end(); ++i_it) {
    int i = index(i_it);

    Teuchos::RCP<Epetra_MultiVector> res_i = result_block.GetBlock(i);
    {
      // Apply deterministic preconditioner
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
      TEUCHOS_FUNC_TIME_MONITOR("Stokhos: Total AGS Deterministic Preconditioner Time");
#endif
      mean_prec->ApplyInverse(*(rhs_block->GetBlock(i)), *res_i);
    }

    int i_gid = epetraCijk->GRID(i);
    for (Cijk_type::ik_iterator k_it = Cijk->k_begin(i_it);
         k_it != Cijk->k_end(i_it); ++k_it) {
      int k = index(k_it);
      if (k!=0 && k<k_limit) {
        bool do_mat_vec = false;
        for (Cijk_type::ikj_iterator j_it = Cijk->j_begin(k_it);
             j_it != Cijk->j_end(k_it); ++j_it) {
          int j = index(j_it);
          int j_gid = epetraCijk->GCID(j);
          if (j_gid > i_gid) {
            bool on_proc = epetraCijk->myGRID(j_gid);
            if (on_proc) {
              do_mat_vec = true;
              break;
            }
          }
        }
        if (do_mat_vec) {
          (*sg_poly)[k].Apply(*res_i, *mat_vec_tmp);
          for (Cijk_type::ikj_iterator j_it = Cijk->j_begin(k_it);
               j_it != Cijk->j_end(k_it); ++j_it) {
            int j = index(j_it);
            int j_gid = epetraCijk->GCID(j);
            double c = value(j_it);
            if (scale_op) {
              if (useTranspose)
                c /= norms[i_gid];
              else
                c /= norms[j_gid];
            }
            if (j_gid > i_gid) {
              bool on_proc = epetraCijk->myGRID(j_gid);
              if (on_proc) {
                rhs_block->GetBlock(j)->Update(-c, *mat_vec_tmp, 1.0);
              }
            }
          }
        }
      }
    }
  }

  // For symmetric Gauss-Seidel
  if (symmetric) {

    for (Cijk_type::i_reverse_iterator i_it= Cijk->i_rbegin();
       i_it!=Cijk->i_rend(); ++i_it) {
      int i = index(i_it);

      Teuchos::RCP<Epetra_MultiVector> res_i = result_block.GetBlock(i);
      {
        // Apply deterministic preconditioner
#ifdef STOKHOS_TEUCHOS_TIME_MONITOR
        TEUCHOS_FUNC_TIME_MONITOR("Stokhos: Total AGS Deterministic Preconditioner Time");
#endif
        mean_prec->ApplyInverse(*(rhs_block->GetBlock(i)), *res_i);
      }

      int i_gid = epetraCijk->GRID(i);
      for (Cijk_type::ik_iterator k_it = Cijk->k_begin(i_it);
           k_it != Cijk->k_end(i_it); ++k_it) {
        int k = index(k_it);
        if (k!=0 && k<k_limit) {
          bool do_mat_vec = false;
          for (Cijk_type::ikj_iterator j_it = Cijk->j_begin(k_it);
               j_it != Cijk->j_end(k_it); ++j_it) {
            int j = index(j_it);
            int j_gid = epetraCijk->GCID(j);
            if (j_gid < i_gid) {
              bool on_proc = epetraCijk->myGRID(j_gid);
              if (on_proc) {
                do_mat_vec = true;
                break;
              }
            }
          }
          if (do_mat_vec) {
            (*sg_poly)[k].Apply(*res_i, *mat_vec_tmp);
            for (Cijk_type::ikj_iterator j_it = Cijk->j_begin(k_it);
                 j_it != Cijk->j_end(k_it); ++j_it) {
              int j = index(j_it);
              int j_gid = epetraCijk->GCID(j);
              double c = value(j_it);
              if (scale_op)
                c /= norms[j_gid];
              if (j_gid < i_gid) {
                bool on_proc = epetraCijk->myGRID(j_gid);
                if (on_proc) {
                  rhs_block->GetBlock(j)->Update(-c, *mat_vec_tmp, 1.0);
                }
              }
            }
          }
        }
      }
    }
  }

  if (made_copy)
    delete input;

  return 0;
}