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; }
/** @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(); }
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; }
//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); }
// 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); } // --------------------------------------------------------- }
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(); }
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); // --------------------------------------------------------- }