SolutionInstance TubeLF::Integrate(d dt) { // Integrate using Lax-Friedrich method d t=sol.getTime(); d newt = t + dt; // Define new solutioninstance SolutionInstance newsol(gp); newsol.setTime(newt); const vd& oldrho=sol.rho(); const vd& oldm=sol.m(); const vd& oldrhoE=sol.rhoE(); vd& rho=newsol.rho_ref(); vd& m=newsol.m_ref(); vd& rhoE=newsol.rhoE_ref(); // Fluxes from previous solution vd Cflux=sol.Cflux(); vd Mflux=sol.Mflux(); vd Eflux=sol.Eflux(); { // Left boundary d la = dt/dx; rho(0) = oldrho(0); rho(0)+=-la*(Cflux(1)-Cflux(0)); d oldu0=oldm(0)/oldrho(0); // std::cout << "oldu:"<< oldu0 << std::endl; d momfluxl = pow(oldm(0), 2)/oldrho(0) + pleft(t); m(0) = oldm(0); m(0)+=-la*(Mflux(1)-momfluxl); rhoE(0) = oldrhoE(0); rhoE(0)+=-la*(Eflux(1)-Eflux(0)); } // End left boundary { // Inner nodes d lambda = dt/(2*dx); rho.subvec(1,gp-2)=0.5*(oldrho.head(gp-2) + oldrho.tail(gp-2)); rho.subvec(1,gp-2)+=-lambda*(Cflux.tail(gp-2) -Cflux.head(gp-2)); m.subvec(1,gp-2)=0.5*(oldm.head(gp-2) + oldm.tail(gp-2)); m.subvec(1,gp-2)+=-lambda*(Mflux.tail(gp-2) -Mflux.head(gp-2)); rhoE.subvec(1,gp-2)=0.5*(oldrhoE.head(gp-2) + oldrhoE.tail(gp-2)); rhoE.subvec(1,gp-2)+=-lambda*(Eflux.tail(gp-2) -Eflux.head(gp-2)); } // End inner nodes { // Right boundary int i = gp - 1; d la = dt/dx; rho(i) = oldrho(i); rho(i)+=-la*(0-Cflux(i-1)); m(i) = 0; rhoE(i) = oldrhoE(i); rhoE(i)+=-la*(0-Eflux(i-1)); } // End right boundary return newsol; }
SolutionInstance TubeMCM::Integrate(d dt){ // Integrate using // MacCormack method d t=sol.getTime(); d newt=t+dt; d lambda=dt/dx; SolutionInstance predictor(gp); { // Predictor step const vd& oldrho=sol.rho(); const vd& oldm=sol.m(); const vd& oldrhoE=sol.rhoE(); vd& prho=predictor.rho_ref(); vd& pm=predictor.m_ref(); vd& prhoE=predictor.rhoE_ref(); // Fluxes from previous solution vd Cflux=sol.Cflux(); vd Mflux=sol.Mflux(); vd Eflux=sol.Eflux(); // Density prho.tail(gp-1)=oldrho.tail(gp-1) -lambda*(Cflux.tail(gp-1)-Cflux.head(gp-1)); // The first element prho(0)=oldrho(0)-lambda*(Cflux(1)-Cflux(0)); // Momentum d oldu0=oldm(0)/oldrho(0); d momfluxl = pow(oldm(0), 2)/oldrho(0) + pleft(t); pm.tail(gp-1)=oldm.tail(gp-1) -lambda*(Mflux.tail(gp-1)-Mflux.head(gp-1)); // The first element pm(0)=oldm(0)-lambda*(Mflux(1)-momfluxl); pm(gp-1)=0; // Energy prhoE.tail(gp-1)=oldrhoE.tail(gp-1) -lambda*(Eflux.tail(gp-1)-Eflux.head(gp-1)); // The first element prhoE(0)=oldrhoE(0)-lambda*(Eflux(1)-Eflux(0)); } SolutionInstance corrector(gp); // Temp test hack: corrector=predictor; corrector.setTime(newt); return corrector; } // Integrate(dt)
ordinal_type Stokhos::CGDivisionExpansionStrategy<ordinal_type,value_type,node_type>:: CG(const Teuchos::SerialDenseMatrix<ordinal_type, value_type> & A, Teuchos::SerialDenseMatrix<ordinal_type,value_type> & X, const Teuchos::SerialDenseMatrix<ordinal_type,value_type> & B, ordinal_type max_iter, value_type tolerance, ordinal_type prec_iter, ordinal_type order , ordinal_type m, ordinal_type PrecNum, const Teuchos::SerialDenseMatrix<ordinal_type, value_type> & M, ordinal_type diag) { ordinal_type n = A.numRows(); ordinal_type k=0; value_type resid; Teuchos::SerialDenseMatrix<ordinal_type, value_type> Ax(n,1); Ax.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,1.0, A, X, 0.0); Teuchos::SerialDenseMatrix<ordinal_type, value_type> r(Teuchos::Copy,B); r-=Ax; resid=r.normFrobenius(); Teuchos::SerialDenseMatrix<ordinal_type, value_type> p(r); Teuchos::SerialDenseMatrix<ordinal_type, value_type> rho(1,1); Teuchos::SerialDenseMatrix<ordinal_type, value_type> oldrho(1,1); Teuchos::SerialDenseMatrix<ordinal_type, value_type> pAp(1,1); Teuchos::SerialDenseMatrix<ordinal_type, value_type> Ap(n,1); value_type b; value_type a; while (resid > tolerance && k < max_iter){ Teuchos::SerialDenseMatrix<ordinal_type, value_type> z(r); //Solve Mz=r if (PrecNum != 0){ if (PrecNum == 1){ Stokhos::DiagPreconditioner<ordinal_type, value_type> precond(M); precond.ApplyInverse(r,z,prec_iter); } else if (PrecNum == 2){ Stokhos::JacobiPreconditioner<ordinal_type, value_type> precond(M); precond.ApplyInverse(r,z,2); } else if (PrecNum == 3){ Stokhos::GSPreconditioner<ordinal_type, value_type> precond(M,0); precond.ApplyInverse(r,z,1); } else if (PrecNum == 4){ Stokhos::SchurPreconditioner<ordinal_type, value_type> precond(M, order, m, diag); precond.ApplyInverse(r,z,prec_iter); } } rho.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,1.0, r, z, 0.0); if (k==0){ p.assign(z); rho.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, r, z, 0.0); } else { b=rho(0,0)/oldrho(0,0); p.scale(b); p+=z; } Ap.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,1.0, A, p, 0.0); pAp.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,1.0, p, Ap, 0.0); a=rho(0,0)/pAp(0,0); Teuchos::SerialDenseMatrix<ordinal_type, value_type> scalep(p); scalep.scale(a); X+=scalep; Ap.scale(a); r-=Ap; oldrho.assign(rho); resid=r.normFrobenius(); k++; } //std::cout << "iteration count " << k << std::endl; return 0; }
// CG int CG(const Teuchos::SerialDenseMatrix<int, double> & A, Teuchos::SerialDenseMatrix<int,double> X,const Teuchos::SerialDenseMatrix<int,double> & B, int max_iter, double tolerance, Stokhos::DiagPreconditioner<int,double> prec) { int n; int k=0; double resid; n=A.numRows(); std::cout << "A= " << A << std::endl; std::cout << "B= " << B << std::endl; Teuchos::SerialDenseMatrix<int, double> Ax(n,1); Ax.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,1.0, A, X, 0.0); Teuchos::SerialDenseMatrix<int, double> r(B); r-=Ax; resid=r.normFrobenius(); Teuchos::SerialDenseMatrix<int, double> rho(1,1); Teuchos::SerialDenseMatrix<int, double> oldrho(1,1); Teuchos::SerialDenseMatrix<int, double> pAp(1,1); Teuchos::SerialDenseMatrix<int, double> Ap(n,1); double b; double a; Teuchos::SerialDenseMatrix<int, double> p(r); while (resid > tolerance && k < max_iter){ Teuchos::SerialDenseMatrix<int, double> z(r); //z=M-1r // prec.ApplyInverse(r,z); rho.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,1.0, r, z, 0.0); if (k==0){ p.assign(z); rho.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, r, z, 0.0); } else { b=rho(0,0)/oldrho(0,0); p.scale(b); p+=z; } Ap.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,1.0, A, p, 0.0); pAp.multiply(Teuchos::TRANS,Teuchos::NO_TRANS,1.0, p, Ap, 0.0); a=rho(0,0)/pAp(0,0); Teuchos::SerialDenseMatrix<int, double> scalep(p); scalep.scale(a); X+=scalep; Ap.scale(a); r-=Ap; oldrho.assign(rho); resid=r.normFrobenius(); k++; } std::cout << "X= " << X << std::endl; return 0; }