Ejemplo n.º 1
0
void UNIFAQ::UNIFAQMixture::set_temperature(const double T){
//    // Check whether you are using exactly the same temperature as last time
//    if (static_cast<bool>(_T) && std::abs(static_cast<double>(_T) - T) < 1e-15 {
//        // 
//        return;
//    }
    this->m_T = T;
    
    if (this->mole_fractions.empty()){
        throw CoolProp::ValueError("mole fractions must be set before calling set_temperature");
    }
    
    for (std::size_t i = 0; i < this->mole_fractions.size(); ++i) {
        const UNIFAQLibrary::Component &c = components[i];
        for (std::size_t k = 0; k < c.groups.size(); ++k) {
            double Q = c.groups[k].group.Q_k;
            int sgik = c.groups[k].group.sgi;
            double sum1 = 0;
            for (std::size_t m = 0; m < c.groups.size(); ++m) {
                int sgim = c.groups[m].group.sgi;
                sum1 += theta_pure(i, sgim)*Psi(sgim, sgik);
            }
            double s = 1 - log(sum1);
            for (std::size_t m = 0; m < c.groups.size(); ++m) {
                int sgim = c.groups[m].group.sgi;
                double sum2 = 0;
                for (std::size_t n = 0; n < c.groups.size(); ++n) {
                    int sgin = c.groups[n].group.sgi;
                    sum2 += theta_pure(i, sgin)*Psi(sgin, sgim);
                }
                s -= theta_pure(i, sgim)*Psi(sgik, sgim)/sum2;
            }
            ComponentData &cd = pure_data[i];
            cd.lnGamma.insert(std::pair<int, double>(sgik, Q*s));
            //printf("ln(Gamma)^(%d)_{%d}: %g\n", static_cast<int>(i + 1), sgik, Q*s);
        }
    }
    
    std::map<std::size_t, double> &thetag = m_thetag, &lnGammag = m_lnGammag;
    lnGammag.clear();

    for (std::vector<UNIFAQLibrary::Group>::iterator itk = unique_groups.begin(); itk != unique_groups.end(); ++itk) {
        double sum1 = 0;
        for (std::vector<UNIFAQLibrary::Group>::iterator itm = unique_groups.begin(); itm != unique_groups.end(); ++itm) {
            sum1 += thetag.find(itm->sgi)->second*this->Psi(itm->sgi, itk->sgi);
        }
        double s = 1-log(sum1);
        for (std::vector<UNIFAQLibrary::Group>::iterator itm = unique_groups.begin(); itm != unique_groups.end(); ++itm) {
            double sum3 = 0;
            for (std::vector<UNIFAQLibrary::Group>::iterator itn = unique_groups.begin(); itn != unique_groups.end(); ++itn) {
                sum3 += thetag.find(itn->sgi)->second*this->Psi(itn->sgi, itm->sgi);
            }
            s -= thetag.find(itm->sgi)->second*Psi(itk->sgi, itm->sgi)/sum3;
        }
        lnGammag.insert(std::pair<std::size_t, double>(itk->sgi, itk->Q_k*s));
        //printf("log(Gamma)_{%d}: %g\n", itk->sgi, itk->Q_k*s);
    }
    _T = m_T;
}
Ejemplo n.º 2
0
/**
   @overload void SQDFrame::showEvent(QShowEvent *event)
   @brief Fill the frame with the results from Hartree-Fock calculations
   *
   *The summary is given in the log frame and potential and the solution of the orbitals
   \f$u_{nl} = r R_{nl}\f$ are plotted with respect to the radius.
*/
void SQDFrame::showEvent( QShowEvent *event) {  

  int max_rad_all = HFSolver->report();

  QString msg 
    = QString("Potential type: %1\nGrid type: %2\nEffective mass: %3").arg(potType).arg(gridType).arg(Pot.getMass());
  d_log->append(msg);
  d_log->append("Eigen energies of a spherical quantum dot");
  for(int i=0; i<Psi.size(); i++) {
    msg 
      = QString("\tOrbital n=%1.l=%2.m=%3.s=%4  %5").arg(Psi.N[i]).arg(Psi.L[i]).arg(Psi.M[i]).arg(Psi.S[i]).arg(HFSolver->getE(i));
    d_log->append(msg);
  }

  long y1 = potFrame->insertCurve("Potential Energy");
  potFrame->appendCurveData(y1,
	                    Psi.m_grid->data(),
			    Pot.Vext->data(),
			    max_rad_all);
  potFrame->replot();

  int orbindex = 0;
  wfsFrame->setAxisTitle(QwtPlot::xBottom, "Radius in AU");
  for(int orb=0; orb<Psi.NumUniqueOrb; orb++){
    int n = Psi.N[orbindex];
    int l = Psi.L[orbindex];
    QString cname= QString("n=%1.l=%2").arg(n,l);
    y1 = wfsFrame->insertCurve(cname);
    wfsFrame->appendCurveData(y1,Psi.m_grid->data(),Psi(orbindex).data(),max_rad_all);
    orbindex += Psi.IDcount[orb];  
  }
   wfsFrame->replot();

//   double e = HFSolver->getE(0);
//   int orb = 0;
//   int ng = Psi.m_grid->size();
//   int n = Psi.N[orb];
//   int l = Psi.L[orb];
//   QString cname= QString("n=%1.l=%2").arg(n,l);
//   y1 = wfsFrame->insertCurve(cname);
//   wfsFrame->appendCurveData(y1,Psi.m_grid->data()+1,Psi(orb).data()+1,ng-1);
//   for(orb=1; orb<Psi.NumUniqueOrb; orb++){
//     int n_cur = Psi.N[orb];
//     int l_cur = Psi.L[orb];
//     //if(fabs(e-HFSolver->getE(orb))>1e-6 || n_cur != n || l_cur != l ) { 
//     if(n_cur != n || l_cur != l) { 
//       n=n_cur; l=l_cur;
//       cname= QString("n=%1.l=%2").arg(n,l);
//       y1 = wfsFrame->insertCurve(cname);
//       wfsFrame->appendCurveData(y1,Psi.m_grid->data()+1,Psi(orb).data()+1,ng-1);
//       e = HFSolver->getE(orb);
//     }
//   }
//   wfsFrame->replot();
}
Ejemplo n.º 3
0
DataMesh ConstructConformalFactor(const DataMesh& theta,
                                  const DataMesh& phi,
                                  const int& axisym)
{
    DataMesh Psi(theta); //copy constructor to get the right size

    Psi = 1.28 ;

    switch(axisym) {
    case 0: //complete symmetry, constant
        //do nothing to Psi
        //Psi = 1.0; //delete this later
        std::cout << "COMPLETELY SYMMETRIC" << std::endl;
        break;
    case 1: //z axisymmetry
        Psi += 0.001*cos(theta)*cos(theta);
        std::cout << "Z AXISYMMETRY" << std::endl;
        break;
    case 2: //x axisymmetry
        Psi += 0.001*(1.0-3.0*cos(theta)*cos(theta)+3.0*sin(theta)*sin(theta)*cos(2.0*phi));
        std::cout << "X AXISYMMETRY" << std::endl;
        break;
    case 3: //y axisymmetry
        Psi += 0.001*(1.0-3.0*cos(theta)*cos(theta)-3.0*sin(theta)*sin(theta)*cos(2.0*phi));
        std::cout << "Y AXISYMMETRY" << std::endl;
        break;
    case 4: //no symmetry
        //Psi += 0.001*(phi+theta); //too difficult to analize with small l,m
        //Psi += 0.001*(sin(theta)*(cos(phi)+sin(theta)) + cos(theta)*sin(2.*phi));
        Psi += 0.001*(0.//-1.0+3.0*cos(theta)*cos(theta)
                      +3.0*sqrt(2.0)*sin(2.0*theta)*(cos(phi)+sin(phi))
                      +3.0*sin(theta)*sin(theta)*sin(2.0*phi));
        std::cout << "NO AXISYMMETRY" << std::endl;
        break;
    case 5: //off-axis symmetry
        //based on Merzbacher Eq. 16.60
        //Y(L,0)(thetap,phip) = sqrt(4*PI/(2L+1))\Sum(M=-L..L) Y(L,M)(theta,phi) Y(L,M)*(beta,alpha)
        //assume z-symmetry in the new coordinate system (thetap, phip), where the new z-axis had
        //coordinates (beta, alpha) in the old system

        Psi+= 0.001//*(5./(32.*M_PI))
              *(-1.0+3.0*cos(theta)*cos(theta)
                +3.0*sqrt(2.0)*sin(2.0*theta)*(cos(phi)+sin(phi))
                +3.0*sin(theta)*sin(theta)*sin(2.0*phi));
        std::cout << "OFF-AXIS AXISYMMETRY" << std::endl;
        break;
    } //end switch

    return Psi;
}
Ejemplo n.º 4
0
Archivo: A1.cpp Proyecto: nMerlin/CP
//Initialisierung
Eigen::VectorXcd init(double xiMax, double xiMin, double dXi) {
	int n_max = floor((xiMax - xiMin + 3/2*dXi)/dXi);
	double summe = 0;
	double skal = 0;
	Eigen::VectorXcd xi(n_max);
	std::complex<double> c;
	
	for (int i = 0; i < n_max; i++) {
		c = Psi((i-floor(n_max/2))*dXi,1,1);
		xi(i) = c;
	}
	
	//Numerische Normierung des Anfangszustandes auf 1
	summe = Norm(xi);
	skal = sqrt(1./summe);
	xi = skal * xi;
	
	//Anfangszustand in Datei schreiben
	SchreibeZustand(xi, "A1c");
	
	return xi;
}
Stokhos::ProductLanczosPCEBasis<ordinal_type, value_type>::
ProductLanczosPCEBasis(
  ordinal_type p,
  const Teuchos::Array< Stokhos::OrthogPolyApprox<ordinal_type, value_type> >& pce,
  const Teuchos::RCP<const Stokhos::Quadrature<ordinal_type, value_type> >& quad,
  const Teuchos::RCP< const Stokhos::Sparse3Tensor<ordinal_type, value_type> >& Cijk,
  const Teuchos::ParameterList& params_) :
  name("Product Lanczos PCE Basis"),
  params(params_)
{
  Teuchos::RCP<const Stokhos::OrthogPolyBasis<ordinal_type,value_type> > pce_basis = pce[0].basis();
  ordinal_type pce_sz = pce_basis->size();

  // Check if basis is a product basis
  Teuchos::RCP<const Stokhos::ProductBasis<ordinal_type,value_type> > prod_basis = Teuchos::rcp_dynamic_cast<const Stokhos::ProductBasis<ordinal_type,value_type> >(pce_basis);
  Teuchos::Array< Teuchos::RCP<const OneDOrthogPolyBasis<ordinal_type,value_type> > > coord_bases;
  if (prod_basis != Teuchos::null)
    coord_bases = prod_basis->getCoordinateBases();

  // Build Lanczos basis for each pce
  bool project = params.get("Project", true);
  bool normalize = params.get("Normalize", true);
  bool limit_integration_order = params.get("Limit Integration Order", false);
  bool use_stieltjes = params.get("Use Old Stieltjes Method", false);
  Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double > > > coordinate_bases;
  Teuchos::Array<int> is_invariant(pce.size(),-2);
  for (ordinal_type i=0; i<pce.size(); i++) {

    // Check for pce's lying in invariant subspaces, which are pce's that
    // depend on only a single dimension.  In this case use the corresponding
    // original coordinate basis.  Convention is:  -2 -- not invariant, -1 --
    // constant, i >= 0 pce depends only on dimension i
    if (prod_basis != Teuchos::null)
      is_invariant[i] = isInvariant(pce[i]);
    if (is_invariant[i] >= 0) {
      coordinate_bases.push_back(coord_bases[is_invariant[i]]);
    }

    // Exclude constant pce's from the basis since they don't represent
    // stochastic dimensions
    else if (is_invariant[i] != -1) {
      if (use_stieltjes) {
	coordinate_bases.push_back(
	  Teuchos::rcp(
	    new Stokhos::StieltjesPCEBasis<ordinal_type,value_type>(
	      p, Teuchos::rcp(&(pce[i]),false), quad, false,
	      normalize, project, Cijk)));
      }
      else {
	if (project) 
	  coordinate_bases.push_back(
	    Teuchos::rcp(
	      new Stokhos::LanczosProjPCEBasis<ordinal_type,value_type>(
		p, Teuchos::rcp(&(pce[i]),false), Cijk,
		normalize, limit_integration_order)));
	else
	  coordinate_bases.push_back(
	    Teuchos::rcp(
	      new Stokhos::LanczosPCEBasis<ordinal_type,value_type>(
		p, Teuchos::rcp(&(pce[i]),false), quad,
		normalize, limit_integration_order)));
      }
    }
  }
  ordinal_type d = coordinate_bases.size();

  // Build tensor product basis
  tensor_lanczos_basis = 
    Teuchos::rcp(
      new Stokhos::CompletePolynomialBasis<ordinal_type,value_type>(
	coordinate_bases,
	params.get("Cijk Drop Tolerance", 1.0e-15),
	params.get("Use Old Cijk Algorithm", false)));

  // Build reduced quadrature
  Teuchos::ParameterList sg_params;
  sg_params.sublist("Basis").set< Teuchos::RCP< const Stokhos::OrthogPolyBasis<ordinal_type,value_type> > >("Stochastic Galerkin Basis", tensor_lanczos_basis);
  sg_params.sublist("Quadrature") = params.sublist("Reduced Quadrature");
  reduced_quad = 
    Stokhos::QuadratureFactory<ordinal_type,value_type>::create(sg_params);

  // Build Psi matrix -- Psi_ij = Psi_i(x^j)*w_j/<Psi_i^2>
  const Teuchos::Array<value_type>& weights = quad->getQuadWeights();
  const Teuchos::Array< Teuchos::Array<value_type> >& points = 
    quad->getQuadPoints(); 
  const Teuchos::Array< Teuchos::Array<value_type> >& basis_vals = 
    quad->getBasisAtQuadPoints();
  ordinal_type nqp = weights.size();
  SDM Psi(pce_sz, nqp);
  for (ordinal_type i=0; i<pce_sz; i++)
    for (ordinal_type k=0; k<nqp; k++)
      Psi(i,k) = basis_vals[k][i]*weights[k]/pce_basis->norm_squared(i);

  // Build Phi matrix -- Phi_ij = Phi_i(y(x^j))
  ordinal_type sz = tensor_lanczos_basis->size();
  Teuchos::Array<value_type> red_basis_vals(sz);
  Teuchos::Array<value_type> pce_vals(d);
  Phi.shape(sz, nqp);
  for (int k=0; k<nqp; k++) {
    ordinal_type jdx = 0;
    for (int j=0; j<pce.size(); j++) {

      // Exclude constant pce's
      if (is_invariant[j] != -1) {

	// Use the identity mapping for invariant subspaces
	if (is_invariant[j] >= 0)
	  pce_vals[jdx] = points[k][is_invariant[j]];
	else
	  pce_vals[jdx] = pce[j].evaluate(points[k], basis_vals[k]);
	jdx++;

      }

    }
    tensor_lanczos_basis->evaluateBases(pce_vals, red_basis_vals);
    for (int i=0; i<sz; i++)
      Phi(i,k) = red_basis_vals[i];
  }

  bool verbose = params.get("Verbose", false);
 
  // Compute matrix A mapping reduced space to original
  A.shape(pce_sz, sz);
  ordinal_type ret = 
    A.multiply(Teuchos::NO_TRANS, Teuchos::TRANS, 1.0, Psi, Phi, 0.0);
  TEUCHOS_ASSERT(ret == 0);
  //print_matlab(std::cout << "A = " << std::endl, A);

  // Compute pseudo-inverse of A mapping original space to reduced
  // A = U*S*V^T -> A^+ = V*S^+*U^T = (S^+*V^T)^T*U^T where 
  // S^+ is a diagonal matrix comprised of the inverse of the diagonal of S
  // for each nonzero, and zero otherwise
  Teuchos::Array<value_type> sigma;
  SDM U, Vt;
  value_type rank_threshold = params.get("Rank Threshold", 1.0e-12);
  ordinal_type rank = svd_threshold(rank_threshold, A, sigma, U, Vt);
  Ainv.shape(sz, pce_sz);
  TEUCHOS_ASSERT(rank == Vt.numRows());
  for (ordinal_type i=0; i<Vt.numRows(); i++)
    for (ordinal_type j=0; j<Vt.numCols(); j++)
      Vt(i,j) = Vt(i,j) / sigma[i];
  ret = Ainv.multiply(Teuchos::TRANS, Teuchos::TRANS, 1.0, Vt, U, 0.0);
  TEUCHOS_ASSERT(ret == 0);
  //print_matlab(std::cout << "Ainv = " << std::endl, Ainv);

  if (verbose) {
    std::cout << "rank = " << rank << std::endl;
    
    std::cout << "diag(S) = [";
    for (ordinal_type i=0; i<rank; i++)
      std::cout << sigma[i] << " ";
    std::cout << "]" << std::endl;

    // Check A = U*S*V^T
    SDM SVt(rank, Vt.numCols());
    for (ordinal_type i=0; i<Vt.numRows(); i++)
      for (ordinal_type j=0; j<Vt.numCols(); j++)
	SVt(i,j) = Vt(i,j) * sigma[i] * sigma[i];  // since we divide by sigma 
                                                   // above
    SDM err_A(pce_sz,sz);
    err_A.assign(A);
    ret = err_A.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, -1.0, U, SVt, 
			 1.0);
    TEUCHOS_ASSERT(ret == 0);
    std::cout << "||A - U*S*V^T||_infty = " << err_A.normInf() << std::endl;
    //print_matlab(std::cout << "A - U*S*V^T = " << std::endl, err_A);
 
    // Check Ainv*A == I
    SDM err(sz,sz);
    err.putScalar(0.0);
    for (ordinal_type i=0; i<sz; i++)
      err(i,i) = 1.0;
    ret = err.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, Ainv, A, 
		       -1.0);
    TEUCHOS_ASSERT(ret == 0);
    std::cout << "||Ainv*A - I||_infty = " << err.normInf() << std::endl;
    //print_matlab(std::cout << "Ainv*A-I = " << std::endl, err);

    // Check A*Ainv == I
    SDM err2(pce_sz,pce_sz);
    err2.putScalar(0.0);
    for (ordinal_type i=0; i<pce_sz; i++)
      err2(i,i) = 1.0;
    ret = err2.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, A, Ainv, -1.0);
    TEUCHOS_ASSERT(ret == 0);
    std::cout << "||A*Ainv - I||_infty = " << err2.normInf() << std::endl;
    //print_matlab(std::cout << "A*Ainv-I = " << std::endl, err2);
  }
}
Stokhos::ProductLanczosGramSchmidtPCEBasis<ordinal_type, value_type>::
ProductLanczosGramSchmidtPCEBasis(
  ordinal_type max_p,
  const Teuchos::Array< Stokhos::OrthogPolyApprox<ordinal_type, value_type> >& pce,
  const Teuchos::RCP<const Stokhos::Quadrature<ordinal_type, value_type> >& quad,
  const Teuchos::RCP< const Stokhos::Sparse3Tensor<ordinal_type, value_type> >& Cijk,
  const Teuchos::ParameterList& params_) :
  name("Product Lanczos Gram-Schmidt PCE Basis"),
  params(params_),
  p(max_p)
{
  Teuchos::RCP<const Stokhos::OrthogPolyBasis<ordinal_type,value_type> > pce_basis = pce[0].basis();
  pce_sz = pce_basis->size();

  // Check if basis is a product basis
  Teuchos::RCP<const Stokhos::ProductBasis<ordinal_type,value_type> > prod_basis = Teuchos::rcp_dynamic_cast<const Stokhos::ProductBasis<ordinal_type,value_type> >(pce_basis);
  Teuchos::Array< Teuchos::RCP<const OneDOrthogPolyBasis<ordinal_type,value_type> > > coord_bases;
  if (prod_basis != Teuchos::null)
    coord_bases = prod_basis->getCoordinateBases();

  // Build Lanczos basis for each pce
  bool project = params.get("Project", true);
  bool normalize = params.get("Normalize", true);
  bool limit_integration_order = params.get("Limit Integration Order", false);
  bool use_stieltjes = params.get("Use Old Stieltjes Method", false);
  Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double > > > coordinate_bases;
  Teuchos::Array<int> is_invariant(pce.size(),-2);
  for (ordinal_type i=0; i<pce.size(); i++) {

    // Check for pce's lying in invariant subspaces, which are pce's that
    // depend on only a single dimension.  In this case use the corresponding
    // original coordinate basis.  Convention is:  -2 -- not invariant, -1 --
    // constant, i >= 0 pce depends only on dimension i
    if (prod_basis != Teuchos::null)
      is_invariant[i] = isInvariant(pce[i]);
    if (is_invariant[i] >= 0) {
      coordinate_bases.push_back(coord_bases[is_invariant[i]]);
    }

    // Exclude constant pce's from the basis since they don't represent
    // stochastic dimensions
    else if (is_invariant[i] != -1) {
      if (use_stieltjes) {
	coordinate_bases.push_back(
	  Teuchos::rcp(
	    new Stokhos::StieltjesPCEBasis<ordinal_type,value_type>(
	      p, Teuchos::rcp(&(pce[i]),false), quad, false,
	      normalize, project, Cijk)));
      }
      else {
	if (project) 
	  coordinate_bases.push_back(
	    Teuchos::rcp(
	      new Stokhos::LanczosProjPCEBasis<ordinal_type,value_type>(
		p, Teuchos::rcp(&(pce[i]),false), Cijk,
		normalize, limit_integration_order)));
	else
	  coordinate_bases.push_back(
	    Teuchos::rcp(
	      new Stokhos::LanczosPCEBasis<ordinal_type,value_type>(
		p, Teuchos::rcp(&(pce[i]),false), quad,
		normalize, limit_integration_order)));
      }
    }
  }
  d = coordinate_bases.size();

  // Build tensor product basis
  tensor_lanczos_basis = 
    Teuchos::rcp(
      new Stokhos::CompletePolynomialBasis<ordinal_type,value_type>(
	coordinate_bases,
	params.get("Cijk Drop Tolerance", 1.0e-15),
	params.get("Use Old Cijk Algorithm", false)));

  // Build Psi matrix -- Psi_ij = Psi_i(x^j)*w_j/<Psi_i^2>
  const Teuchos::Array<value_type>& weights = quad->getQuadWeights();
  const Teuchos::Array< Teuchos::Array<value_type> >& points = 
    quad->getQuadPoints(); 
  const Teuchos::Array< Teuchos::Array<value_type> >& basis_vals = 
    quad->getBasisAtQuadPoints();
  ordinal_type nqp = weights.size();
  SDM Psi(pce_sz, nqp);
  for (ordinal_type i=0; i<pce_sz; i++)
    for (ordinal_type k=0; k<nqp; k++)
      Psi(i,k) = basis_vals[k][i]*weights[k]/pce_basis->norm_squared(i);

  // Build Phi matrix -- Phi_ij = Phi_i(y(x^j))
  sz = tensor_lanczos_basis->size();
  Teuchos::Array<value_type> red_basis_vals(sz);
  Teuchos::Array<value_type> pce_vals(d);
  SDM Phi(sz, nqp);
  SDM F(nqp, d);
  for (int k=0; k<nqp; k++) {
    ordinal_type jdx = 0;
    for (int j=0; j<pce.size(); j++) {

      // Exclude constant pce's
      if (is_invariant[j] != -1) {

	// Use the identity mapping for invariant subspaces
	if (is_invariant[j] >= 0)
	  pce_vals[jdx] = points[k][is_invariant[j]];
	else
	  pce_vals[jdx] = pce[j].evaluate(points[k], basis_vals[k]);
	F(k,jdx) = pce_vals[jdx];
	jdx++;

      }

    }
    tensor_lanczos_basis->evaluateBases(pce_vals, red_basis_vals);
    for (int i=0; i<sz; i++)
      Phi(i,k) = red_basis_vals[i];
  }

  bool verbose = params.get("Verbose", false);
 
  // Compute matrix A mapping reduced space to original
  SDM A(pce_sz, sz);
  ordinal_type ret = 
    A.multiply(Teuchos::NO_TRANS, Teuchos::TRANS, 1.0, Psi, Phi, 0.0);
  TEUCHOS_ASSERT(ret == 0);

  // Rescale columns of A to have unit norm
  const Teuchos::Array<value_type>& basis_norms = pce_basis->norm_squared();
  for (ordinal_type j=0; j<sz; j++) {
    value_type nrm = 0.0;
    for (ordinal_type i=0; i<pce_sz; i++)
      nrm += A(i,j)*A(i,j)*basis_norms[i];
    nrm = std::sqrt(nrm);
    for (ordinal_type i=0; i<pce_sz; i++)
      A(i,j) /= nrm;
  }

  // Compute our new basis -- each column of Qp is the coefficients of the
  // new basis in the original basis. Constraint pivoting so first d+1
  // columns and included in Qp.
  value_type rank_threshold = params.get("Rank Threshold", 1.0e-12);
  std::string  orthogonalization_method = 
    params.get("Orthogonalization Method", "Householder");
  Teuchos::Array<value_type> w(pce_sz, 1.0);
  SDM R;
  Teuchos::Array<ordinal_type> piv(sz);
  for (int i=0; i<d+1; i++)
    piv[i] = 1;
  typedef Stokhos::OrthogonalizationFactory<ordinal_type,value_type> SOF;
  sz = SOF::createOrthogonalBasis(
    orthogonalization_method, rank_threshold, verbose, A, w, Qp, R, piv);

  // Original basis at quadrature points -- needed to transform expansions
  // in this basis back to original
  SDM B(nqp, pce_sz);
  for (ordinal_type i=0; i<nqp; i++)
    for (ordinal_type j=0; j<pce_sz; j++)
      B(i,j) = basis_vals[i][j];

  // Evaluate new basis at original quadrature points
  Q.reshape(nqp, sz);
  ret = Q.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, B, Qp, 0.0);
  TEUCHOS_ASSERT(ret == 0);

  // Compute reduced quadrature rule
  Stokhos::ReducedQuadratureFactory<ordinal_type,value_type> quad_factory(
    params.sublist("Reduced Quadrature"));
  Teuchos::SerialDenseMatrix<ordinal_type, value_type> Q2;
  reduced_quad = quad_factory.createReducedQuadrature(Q, Q2, F, weights);

  // Basis is orthonormal by construction
  norms.resize(sz, 1.0);
}
Ejemplo n.º 7
0
// Right-hand side for hyperbolic PDE in divergence form
//
//       q_t = -( f(q,x,y,t)_x + g(q,x,y,t)_y ) + Psi(q,x,y,t)
//
void LaxWendroff_Unst(double dt,
    const mesh& Mesh, const edge_data_Unst& EdgeData,
    dTensor3& aux,                  // SetBndValues modifies ghost cells
    dTensor3& q,                    // SetBndValues modifies ghost cells
    dTensor3& Lstar, dTensor1& smax)
{

    const int NumElems      = Mesh.get_NumElems();
    const int NumPhysElems  = Mesh.get_NumPhysElems();
    const int NumEdges      = Mesh.get_NumEdges();
    const int meqn          = q.getsize(2);
    const int kmax          = q.getsize(3);
    const int maux          = aux.getsize(2);
    const int space_order   = dogParams.get_space_order();
    dTensor3 EdgeFluxIntegral(NumElems,meqn,kmax);
    dTensor3 ElemFluxIntegral(NumElems,meqn,kmax);
    dTensor3              Psi(NumElems,meqn,kmax);

    // ---------------------------------------------------------
    // Boundary Conditions
    SetBndValues_Unst(Mesh, &q, &aux);
    // ---------------------------------------------------------

    // --------------------------------------------------------------------- //
    // Part 0: Compute the Lax-Wendroff "flux" function:
    //
    // Here, we include the extra information about time derivatives.
    // --------------------------------------------------------------------- //
    dTensor3 F(NumElems, meqn, kmax );  F.setall(0.);
    dTensor3 G(NumElems, meqn, kmax );  G.setall(0.);
    L2ProjectLxW_Unst( dogParams.get_time_order(), 1.0, 0.5*dt, dt*dt/6.0, 1, NumElems,
        space_order, space_order, space_order, space_order, Mesh,
        &q, &aux, &F, &G, &FluxFunc, &DFluxFunc, &D2FluxFunc );

    // ---------------------------------------------------------
    // Part I: compute source term
    // --------------------------------------------------------- 
    if ( dogParams.get_source_term()>0 )
    {        
        // eprintf("error: have not implemented source term for LxW solver.");
        printf("Source term has not been implemented for LxW solver.  Terminating program.");
        exit(1);
    }
    Lstar.setall(0.);
    // ---------------------------------------------------------


    // ---------------------------------------------------------
    // Part II: compute flux integral on element edges
    // ---------------------------------------------------------

    // Loop over all interior edges
    EdgeFluxIntegral.setall(0.);
    ElemFluxIntegral.setall(0.);

#pragma omp parallel for
    // Loop over all interior edges
    for (int i=1; i<=NumEdges; i++)
    {
        // Edge coordinates
        double x1 = Mesh.get_edge(i,1);
        double y1 = Mesh.get_edge(i,2);
        double x2 = Mesh.get_edge(i,3);
        double y2 = Mesh.get_edge(i,4);

        // Elements on either side of edge
        int ileft  = Mesh.get_eelem(i,1);
        int iright = Mesh.get_eelem(i,2);  
        double Areal = Mesh.get_area_prim(ileft);
        double Arear = Mesh.get_area_prim(iright);

        // Scaled normal to edge
        dTensor1 nhat(2);      
        nhat.set(1, (y2-y1) );
        nhat.set(2, (x1-x2) );

        // Variables to store flux integrals along edge
        dTensor2 Fr_tmp(meqn,dogParams.get_space_order());
        dTensor2 Fl_tmp(meqn,dogParams.get_space_order());

        // Loop over number of quadrature points along each edge
        for (int ell=1; ell<=dogParams.get_space_order(); ell++)
        {
            dTensor1   Ql(meqn),   Qr(meqn);
            dTensor1  ffl(meqn),  ffr(meqn);  // << -- NEW PART -- >>
            dTensor1 Auxl(maux), Auxr(maux);

            // Riemann data - q
            for (int m=1; m<=meqn; m++)
            {
                Ql.set(m, 0.0 );
                Qr.set(m, 0.0 );

                // << -- NEW PART, ffl and ffr -- >> //
                ffl.set(m, 0.0 );
                ffr.set(m, 0.0 );

                for (int k=1; k<=kmax; k++)
                {
                    Ql.set(m, Ql.get(m) + EdgeData.phi_left->get(i,ell,k) 
                            *q.get(ileft, m,k) );
                    Qr.set(m, Qr.get(m) + EdgeData.phi_right->get(i,ell,k)
                            *q.get(iright,m,k) );

                    // << -- NEW PART, ffl and ffr -- >> //
                    // Is this the correct way to use the normal vector?
                    ffl.set(m, ffl.get(m) + EdgeData.phi_left->get (i, ell, k) * ( 
                        nhat.get(1)*F.get( ileft, m, k) + nhat.get(2)*G.get( ileft, m, k) ) );

                    ffr.set(m, ffr.get(m) + EdgeData.phi_right->get(i, ell, k) * (
                        nhat.get(1)*F.get(iright, m, k) + nhat.get(2)*G.get(iright, m, k) ) );

                }
            }

            // Riemann data - aux
            for (int m=1; m<=maux; m++)
            {
                Auxl.set(m, 0.0 );
                Auxr.set(m, 0.0 );

                for (int k=1; k<=kmax; k++)
                {
                    Auxl.set(m, Auxl.get(m) + EdgeData.phi_left->get(i,ell,k)  * aux.get(ileft, m,k) );
                    Auxr.set(m, Auxr.get(m) + EdgeData.phi_right->get(i,ell,k) * aux.get(iright,m,k) );
                }
            }

            // Solve Riemann problem
            dTensor1 xedge(2);
            double s = EdgeData.xpts1d->get(ell);
            xedge.set(1, x1 + 0.5*(s+1.0)*(x2-x1) );
            xedge.set(2, y1 + 0.5*(s+1.0)*(y2-y1) );

            // Solve the Riemann problem for this edge
            dTensor1 Fl(meqn), Fr(meqn);

            // Use the time-averaged fluxes to define left and right values for
            // the Riemann solver.
            const double smax_edge = RiemannSolveLxW(
                    nhat, xedge, Ql, Qr, Auxl, Auxr, ffl, ffr, Fl, Fr);
            smax.set(i, Max(smax_edge,smax.get(i)) );

            // Construct fluxes
            for (int m=1; m<=meqn; m++)
            {
                Fr_tmp.set(m,ell, Fr.get(m) );
                Fl_tmp.set(m,ell, Fl.get(m) );
            }
        }

        // Add edge integral to line integral around the full element
        for (int m=1; m<=meqn; m++)
        for (int k=1; k<=kmax; k++)
        {
            double Fl_sum = 0.0;
            double Fr_sum = 0.0;
            for (int ell=1; ell<=dogParams.get_space_order(); ell++)
            {
                Fl_sum = Fl_sum + 0.5*EdgeData.wgts1d->get(ell)
                    *EdgeData.phi_left->get(i,ell,k) *Fl_tmp.get(m,ell);
                Fr_sum = Fr_sum + 0.5*EdgeData.wgts1d->get(ell)
                    *EdgeData.phi_right->get(i,ell,k)*Fr_tmp.get(m,ell);
            }
            EdgeFluxIntegral.set(ileft, m,k, EdgeFluxIntegral.get(ileft, m,k) + Fl_sum/Areal );
            EdgeFluxIntegral.set(iright,m,k, EdgeFluxIntegral.get(iright,m,k) - Fr_sum/Arear );
        }
    }
    // ---------------------------------------------------------

    // ---------------------------------------------------------
    // Part III: compute intra-element contributions
    // ---------------------------------------------------------
    if( dogParams.get_space_order() > 1 )
    {
        L2ProjectGradAddLegendre_Unst(1, NumPhysElems, space_order, 
            Mesh, &F, &G, &ElemFluxIntegral );
    }
    // ---------------------------------------------------------

    // ---------------------------------------------------------
    // Part IV: construct Lstar
    // ---------------------------------------------------------
    if (dogParams.get_source_term()==0)  // Without Source Term
    { 
#pragma omp parallel for
        for (int i=1; i<=NumPhysElems; i++)	
        for (int m=1; m<=meqn; m++)
        for (int k=1; k<=kmax; k++)
        {
            double tmp = ElemFluxIntegral.get(i,m,k) - EdgeFluxIntegral.get(i,m,k);
            Lstar.set(i,m,k, tmp );	      
        }
    }
    else  // With Source Term
    {
#pragma omp parallel for
        for (int i=1; i<=NumPhysElems; i++)
        for (int m=1; m<=meqn; m++)
        for (int k=1; k<=kmax; k++)
        {
//          double tmp = ElemFluxIntegral.get(i,m,k) 
//              - EdgeFluxIntegral.get(i,m,k)
//              + Psi.get(i,m,k);

//          Lstar.set(i,m,k, tmp );

            printf("Source term has not been implemented for LxW solver.  Terminating program.");
            exit(1);
        }
    }
    // ---------------------------------------------------------

    // ---------------------------------------------------------
    // Part V: add extra contributions to Lstar
    // ---------------------------------------------------------
    // Call LstarExtra
    LstarExtra_Unst(Mesh, &q, &aux, &Lstar);
    // ---------------------------------------------------------

    // ---------------------------------------------------------
    // Part VI: artificial viscosity limiter
    // ---------------------------------------------------------  
//  if (dogParams.get_space_order()>1  &&
//          dogParams.using_viscosity_limiter())
//  {  ArtificialViscosity(&aux,&q,&Lstar);  }
    // ---------------------------------------------------------

}
Ejemplo n.º 8
0
void PseudoGen::plot_siesta_grid()
{
  double A = 0.125e-01;
  double B = 0.774610055208e-04;
  int npts = 1141;
  RadialGrid_t* siesta_grid = new LogGridZero<double>;
  siesta_grid->set(A,B,npts);
  RadialOrbital_t VCharge_siesta_grid(siesta_grid);
  RadialOrbital_t VCharge(Psi(0));
  for(int ob=0; ob<Psi.size(); ob++)
  {
    for(int j=0; j<VCharge.size(); j++)
    {
      VCharge(j)+= Psi(ob,j)*Psi(ob,j);
      // VCharge(j)+= AEorbitals[ob](j)*AEorbitals[ob](j);
    }
  }
  int imin = 0;
  value_type deriv = (VCharge(imin+1)-VCharge(imin))/VCharge.dr(imin);
  VCharge.spline(imin,deriv,VCharge.size()-1,0.0);
  Transform2GridFunctor<OneDimGridFunctor<value_type>,
                        OneDimGridFunctor<value_type> > transform(VCharge,VCharge_siesta_grid);
  transform.generate();
  cout << "Total valence charge = " << integrate_RK2(VCharge) << endl;
  cout << "Total valence charge = " << integrate_RK2(VCharge_siesta_grid) << endl;
  RadialOrbital_t PP(siesta_grid);
  value_type prefactor = -2.0*4.0;
  for(int i=0; i<npts; i++)
  {
    value_type r =  siesta_grid->r(i);
    value_type SJ_num = 1.0-exp(-Params(0)*r);
    value_type SJ_den = 1.0+exp(-Params(0)*(r-Params(1)));
    PP(i) = prefactor*(SJ_num/SJ_den);
  }
  char* fname = "Ge.siesta_grid.psf";
  ofstream siesta(fname);
  cout << "Writing Pseudopential to file " << fname << endl;
  siesta << " Radial grid follows" << endl;
  int nlines = (npts-1)/4;
  int remainder = npts-1-nlines*4;
  siesta.precision(12);
  siesta.setf(ios::scientific,ios::floatfield);
  siesta << setiosflags(ios::uppercase);
  int j=1;
  for(int i=0; i<nlines; i++)
  {
    siesta << setw(20) << siesta_grid->r(j)
           << setw(20) << siesta_grid->r(j+1)
           << setw(20) << siesta_grid->r(j+2)
           << setw(20) << siesta_grid->r(j+3)
           << endl;
    j+=4;
  }
  if(remainder)
  {
    for(int i=j; i<npts; i++)
      siesta << setw(20) << siesta_grid->r(i);
    siesta << endl;
  }
  siesta << " Down Pseudopotential follows (l on next line)" << endl;
  siesta << "  0" << endl;
  j=1;
  for(int i=0; i<nlines; i++)
  {
    siesta << setw(20) << PP(j)
           << setw(20) << PP(j+1)
           << setw(20) << PP(j+2)
           << setw(20) << PP(j+3)
           << endl;
    j+=4;
  }
  if(remainder)
  {
    for(int i=j; i<npts; i++)
      siesta << setw(20) << PP(i);
    siesta << endl;
  }
  siesta << " Down Pseudopotential follows (l on next line)" << endl;
  siesta << "  1" << endl;
  j=1;
  for(int i=0; i<nlines; i++)
  {
    siesta << setw(20) << PP(j)
           << setw(20) << PP(j+1)
           << setw(20) << PP(j+2)
           << setw(20) << PP(j+3)
           << endl;
    j+=4;
  }
  if(remainder)
  {
    for(int i=j; i<npts; i++)
      siesta << setw(20) << PP(i);
    siesta << endl;
  }
  siesta << " Down Pseudopotential follows (l on next line)" << endl;
  siesta << "  2" << endl;
  j=1;
  for(int i=0; i<nlines; i++)
  {
    siesta << setw(20) << PP(j)
           << setw(20) << PP(j+1)
           << setw(20) << PP(j+2)
           << setw(20) << PP(j+3)
           << endl;
    j+=4;
  }
  if(remainder)
  {
    for(int i=j; i<npts; i++)
      siesta << setw(20) << PP(i);
    siesta << endl;
  }
  siesta << " Down Pseudopotential follows (l on next line)" << endl;
  siesta << "  3" << endl;
  j=1;
  for(int i=0; i<nlines; i++)
  {
    siesta << setw(20) << PP(j)
           << setw(20) << PP(j+1)
           << setw(20) << PP(j+2)
           << setw(20) << PP(j+3)
           << endl;
    j+=4;
  }
  if(remainder)
  {
    for(int i=0; i<remainder; i++)
      siesta << setw(20) << PP(i);
    siesta << endl;
  }
  double CC = 0.0;
  siesta << " Core charge follows" << endl;
  for(int i=0; i<nlines; i++)
  {
    siesta << setw(20) << CC
           << setw(20) << CC
           << setw(20) << CC
           << setw(20) << CC
           << endl;
  }
  if(remainder)
  {
    for(int i=j; i<npts; i++)
      siesta << setw(20) << CC;
    siesta << endl;
  }
  siesta << " Valence charge follows" << endl;
  j=1;
  for(int i=0; i<nlines; i++)
  {
    siesta << setw(20) << VCharge_siesta_grid(j)
           << setw(20) << VCharge_siesta_grid(j+1)
           << setw(20) << VCharge_siesta_grid(j+2)
           << setw(20) << VCharge_siesta_grid(j+3)
           << endl;
    j+=4;
  }
  if(remainder)
  {
    for(int i=j; i<npts; i++)
      siesta << setw(20) << VCharge_siesta_grid(i);
    siesta << endl;
  }
  siesta.close();
}
Ejemplo n.º 9
0
void ConstructL_Unst(
    const double t,
    const dTensor2* vel_vec,
    const mesh& Mesh,
    const edge_data_Unst& EdgeData,
    dTensor3& aux, // SetBndValues_Unst modifies ghost cells
    dTensor3& q,   // SetBndValues_Unst modifies ghost cells
    dTensor3& Lstar, 
    dTensor1& smax)
{

    const int NumElems      = Mesh.get_NumElems();
    const int NumPhysElems  = Mesh.get_NumPhysElems();
    const int NumEdges      = Mesh.get_NumEdges();
    const int meqn          = q.getsize(2);
    const int kmax          = q.getsize(3);
    const int maux          = aux.getsize(2);
    const int space_order   = dogParams.get_space_order();

    dTensor3 EdgeFluxIntegral(NumElems,meqn,kmax);
    dTensor3 ElemFluxIntegral(NumElems,meqn,kmax);
    dTensor3              Psi(NumElems,meqn,kmax);


    // ---------------------------------------------------------
    // Boundary Conditions
    SetBndValues_Unst(Mesh,&q,&aux);  
    
    // Positivity limiter
    void ApplyPosLimiter_Unst(const mesh& Mesh, const dTensor3& aux, dTensor3& q);
    if( dogParams.using_moment_limiter() )
    { ApplyPosLimiter_Unst(Mesh, aux, q); }
    // ---------------------------------------------------------

    // ---------------------------------------------------------
    // Part I: compute flux integral on element edges
    // ---------------------------------------------------------

    // Loop over all interior edges and solve Riemann problems
    // dTensor1 nvec(2);

    // Loop over all interior edges
    EdgeFluxIntegral.setall(0.);
    ElemFluxIntegral.setall(0.);

    // Loop over all interior edges
#pragma omp parallel for
    for (int i=1; i<=NumEdges; i++)
    {
        // Edge coordinates
        double x1 = Mesh.get_edge(i,1);
        double y1 = Mesh.get_edge(i,2);
        double x2 = Mesh.get_edge(i,3);
        double y2 = Mesh.get_edge(i,4);

        // Elements on either side of edge
        int ileft  = Mesh.get_eelem(i,1);
        int iright = Mesh.get_eelem(i,2);  
        double Areal = Mesh.get_area_prim(ileft);
        double Arear = Mesh.get_area_prim(iright);

        // Scaled normal to edge
        dTensor1 nhat(2);      
        nhat.set(1, (y2-y1) );
        nhat.set(2, (x1-x2) );

        // Variables to store flux integrals along edge
        dTensor2 Fr_tmp(meqn,dogParams.get_space_order());
        dTensor2 Fl_tmp(meqn,dogParams.get_space_order());

        // Loop over number of quadrature points along each edge
        for (int ell=1; ell<=dogParams.get_space_order(); ell++)
        {
            dTensor1 Ql(meqn),Qr(meqn);
            dTensor1 Auxl(maux),Auxr(maux);	  

            // Riemann data - q
            for (int m=1; m<=meqn; m++)
            {
                Ql.set(m, 0.0 );
                Qr.set(m, 0.0 );

                for (int k=1; k<=kmax; k++)
                {
                    Ql.set(m, Ql.get(m) + EdgeData.phi_left->get(i,ell,k) 
                            *q.get(ileft, m,k) );
                    Qr.set(m, Qr.get(m) + EdgeData.phi_right->get(i,ell,k)
                            *q.get(iright,m,k) );
                }

            }


            // Riemann data - aux
            for (int m=1; m<=maux; m++)
            {
                Auxl.set(m, 0.0 );
                Auxr.set(m, 0.0 );

                for (int k=1; k<=kmax; k++)
                {
                    Auxl.set(m, Auxl.get(m) + EdgeData.phi_left->get(i,ell,k)
                            *aux.get(ileft, m,k) );
                    Auxr.set(m, Auxr.get(m) + EdgeData.phi_right->get(i,ell,k)
                            *aux.get(iright,m,k) );
                }
            }

            // Solve Riemann problem
            dTensor1 xedge(2);
            double s = EdgeData.xpts1d->get(ell);
            xedge.set(1, x1 + 0.5*(s+1.0)*(x2-x1) );
            xedge.set(2, y1 + 0.5*(s+1.0)*(y2-y1) );
            dTensor1 Fl(meqn),Fr(meqn);
            const double smax_edge = RiemannSolve(vel_vec, nhat, xedge, Ql, Qr, Auxl, Auxr, Fl, Fr);
            smax.set(i, Max(smax_edge,smax.get(i)) );

            // Construct fluxes
            for (int m=1; m<=meqn; m++)
            {
                Fr_tmp.set(m,ell, Fr.get(m) );
                Fl_tmp.set(m,ell, Fl.get(m) );
            }
        }

        // Add edge integral to line integral around the full element
        for (int m=1; m<=meqn; m++)
        for (int k=1; k<=kmax; k++)
        {
            double Fl_sum = 0.0;
            double Fr_sum = 0.0;
            for (int ell=1; ell<=dogParams.get_space_order(); ell++)
            {
                Fl_sum = Fl_sum + 0.5*EdgeData.wgts1d->get(ell)
                    *EdgeData.phi_left->get(i,ell,k) *Fl_tmp.get(m,ell);
                Fr_sum = Fr_sum + 0.5*EdgeData.wgts1d->get(ell)
                    *EdgeData.phi_right->get(i,ell,k)*Fr_tmp.get(m,ell);
            }
            EdgeFluxIntegral.set(ileft, m,k, EdgeFluxIntegral.get(ileft, m,k) + Fl_sum/Areal );
            EdgeFluxIntegral.set(iright,m,k, EdgeFluxIntegral.get(iright,m,k) - Fr_sum/Arear );
        }
    }
    // ---------------------------------------------------------

    // ---------------------------------------------------------
    // Part II: compute intra-element contributions
    // ---------------------------------------------------------
    L2ProjectGrad_Unst(vel_vec, 1,NumPhysElems,
            space_order,space_order,space_order,space_order,
            Mesh,&q,&aux,&ElemFluxIntegral,&FluxFunc);
    // ---------------------------------------------------------

    // ---------------------------------------------------------
    // Part III: compute source term
    // --------------------------------------------------------- 
    if ( dogParams.get_source_term()>0 )
    {        
        // Set source term on computational grid
        // Set values and apply L2-projection
        L2Project_Unst(t, vel_vec, 1,NumPhysElems,
                space_order,space_order,space_order,space_order,
                Mesh,&q,&aux,&Psi,&SourceTermFunc);
    }
    // ---------------------------------------------------------

    // ---------------------------------------------------------
    // Part IV: construct Lstar
    // ---------------------------------------------------------
    if (dogParams.get_source_term()==0)  // Without Source Term
    { 
#pragma omp parallel for
        for (int i=1; i<=NumPhysElems; i++)	
        for (int m=1; m<=meqn; m++)
        for (int k=1; k<=kmax; k++)
        {
            double tmp = ElemFluxIntegral.get(i,m,k) - EdgeFluxIntegral.get(i,m,k);
            Lstar.set(i,m,k, tmp );	      
        }
    }
    else  // With Source Term
    {
#pragma omp parallel for
        for (int i=1; i<=NumPhysElems; i++)
        for (int m=1; m<=meqn; m++)
        for (int k=1; k<=kmax; k++)
        {
            double tmp = ElemFluxIntegral.get(i,m,k) 
                - EdgeFluxIntegral.get(i,m,k)
                + Psi.get(i,m,k);

            Lstar.set(i,m,k, tmp );
        }
    }
    // ---------------------------------------------------------

    // ---------------------------------------------------------
    // Part V: add extra contributions to Lstar
    // ---------------------------------------------------------
    // Call LstarExtra
    LstarExtra_Unst(Mesh,&q,&aux,&Lstar);
    // ---------------------------------------------------------

}