LDFE_quad::LDFE_quad(int param) { /* Calculate number of LDFE ranges */ order = param; // Quadrature order int num_LDFE = 2 * pow(2, order); // Number of LDFE regions /* Calculate quadrature directions */ double delta_gamma = (pi / num_LDFE) / 4.0; // Gamma from node to nearest LDFE edge double gamma_current = 0.0; mat gamma(num_LDFE, 2); for (int i=0; i<num_LDFE; i++) { gamma(i, 0) = gamma_current + delta_gamma; // Left node gamma gamma(i, 1) = gamma(i, 0) + 2.0 * delta_gamma; // Right node gamma gamma_current = gamma_current + 4.0 * delta_gamma; } /* Solve the basis functions of each LDFE range */ mat A = mat(2, 2); mat B = eye<mat>(2, 2); mat C = mat(3, 3); vec wgt = vec(2); wgts.set_size(num_LDFE, 2); // Resize matrix storing all LDFE range weights dirs.set_size(num_LDFE, 2); // Resize matrix storing all LDFE range directions basis.resize(num_LDFE); // Resize vector storing all LDFE basis functions for (int i=0; i<num_LDFE; i++){ for (int j=0; j<2; j++){ A(j, 0) = 1.0; A(j, 1) = cos(gamma(i, j)); } C = solve(A, B); // Solve for the basis functions /* Solve for the weights of each LDFE range */ double gamma_max = gamma(i, 1) + delta_gamma; double gamma_min = gamma(i, 0) - delta_gamma; for (int j=0; j<2; j++){ wgt(j) = C(0, j) * (gamma_max - gamma_min) + \ C(1, j) * (sin(gamma_max) - sin(gamma_min)); } /* Store quadrature directions, weights and basis functions */ for (int j=0; j<2; j++) { dirs(i, j) = cos(gamma(i, j)); wgts(i, j) = wgt(j) / pi * 2.0; } basis[i] = C; } }
void OnTouchDown_RequestToTopFocused(CursorEventArgs&& e) { IWidget& wgt(e.GetSender()); if(e.Strategy != RoutedEventArgs::Bubble) RequestToTop(wgt); if(e.Strategy == RoutedEventArgs::Direct) ClearFocusingOf(wgt); if(e.Strategy != RoutedEventArgs::Tunnel) RequestFocus(wgt); }
int WalkerControlBase::doNotBranch(int iter, MCWalkerConfiguration& W) { MCWalkerConfiguration::iterator it(W.begin()); MCWalkerConfiguration::iterator it_end(W.end()); RealType esum=0.0,e2sum=0.0,wsum=0.0,ecum=0.0, w2sum=0.0; RealType r2_accepted=0.0,r2_proposed=0.0; for(; it!=it_end; ++it) { r2_accepted+=(*it)->Properties(R2ACCEPTED); r2_proposed+=(*it)->Properties(R2PROPOSED); RealType e((*it)->Properties(LOCALENERGY)); int nc= std::min(static_cast<int>((*it)->Multiplicity),MaxCopy); RealType wgt((*it)->Weight); esum += wgt*e; e2sum += wgt*e*e; wsum += wgt; w2sum += wgt*wgt; ecum += e; } //temp is an array to perform reduction operations std::fill(curData.begin(),curData.end(),0); curData[ENERGY_INDEX]=esum; curData[ENERGY_SQ_INDEX]=e2sum; curData[WALKERSIZE_INDEX]=W.getActiveWalkers(); curData[WEIGHT_INDEX]=wsum; curData[EREF_INDEX]=ecum; curData[R2ACCEPTED_INDEX]=r2_accepted; curData[R2PROPOSED_INDEX]=r2_proposed; myComm->allreduce(curData); measureProperties(iter); trialEnergy=EnsembleProperty.Energy; W.EnsembleProperty=EnsembleProperty; //return the current data return W.getGlobalNumWalkers(); }
/** evaluate curData and mark the bad/good walkers */ int WalkerControlBase::sortWalkers(MCWalkerConfiguration& W) { MCWalkerConfiguration::iterator it(W.begin()); vector<Walker_t*> bad,good_rn; vector<int> ncopy_rn; NumWalkers=0; MCWalkerConfiguration::iterator it_end(W.end()); RealType esum=0.0,e2sum=0.0,wsum=0.0,ecum=0.0, w2sum=0.0, besum=0.0, bwgtsum=0.0; RealType r2_accepted=0.0,r2_proposed=0.0; int nrn(0),ncr(0); while(it != it_end) { bool inFN=(((*it)->ReleasedNodeAge)==0); if ((*it)->ReleasedNodeAge==1) ncr+=1; int nc= std::min(static_cast<int>((*it)->Multiplicity),MaxCopy); r2_accepted+=(*it)->Properties(R2ACCEPTED); r2_proposed+=(*it)->Properties(R2PROPOSED); RealType e((*it)->Properties(LOCALENERGY)); RealType bfe((*it)->Properties(ALTERNATEENERGY)); RealType rnwgt(0.0); if (inFN) rnwgt=((*it)->Properties(SIGN)); // RealType wgt((*it)->Weight); RealType wgt(0.0); if (inFN) wgt=((*it)->Weight); esum += wgt*e; e2sum += wgt*e*e; wsum += wgt; w2sum += wgt*wgt; ecum += e; besum += bfe*rnwgt*wgt; bwgtsum += rnwgt*wgt; if((nc) && (inFN)) { NumWalkers += nc; good_w.push_back(*it); ncopy_w.push_back(nc-1); } else if (nc) { NumWalkers += nc; nrn+=nc; good_rn.push_back(*it); ncopy_rn.push_back(nc-1); } else { bad.push_back(*it); } ++it; } //temp is an array to perform reduction operations std::fill(curData.begin(),curData.end(),0); //update curData curData[ENERGY_INDEX]=esum; curData[ENERGY_SQ_INDEX]=e2sum; curData[WALKERSIZE_INDEX]=W.getActiveWalkers(); curData[WEIGHT_INDEX]=wsum; curData[EREF_INDEX]=ecum; curData[R2ACCEPTED_INDEX]=r2_accepted; curData[R2PROPOSED_INDEX]=r2_proposed; curData[FNSIZE_INDEX]=static_cast<RealType>(good_w.size()); curData[RNONESIZE_INDEX]=static_cast<RealType>(ncr); curData[RNSIZE_INDEX]=nrn; curData[B_ENERGY_INDEX]=besum; curData[B_WGT_INDEX]=bwgtsum; ////this should be move //W.EnsembleProperty.NumSamples=curData[WALKERSIZE_INDEX]; //W.EnsembleProperty.Weight=curData[WEIGHT_INDEX]; //W.EnsembleProperty.Energy=(esum/=wsum); //W.EnsembleProperty.Variance=(e2sum/wsum-esum*esum); //W.EnsembleProperty.Variance=(e2sum*wsum-esum*esum)/(wsum*wsum-w2sum); //remove bad walkers empty the container for(int i=0; i<bad.size(); i++) delete bad[i]; if (!WriteRN) { if(good_w.empty()) { app_error() << "All the walkers have died. Abort. " << endl; APP_ABORT("WalkerControlBase::sortWalkers"); } int sizeofgood = good_w.size(); //check if the projected number of walkers is too small or too large if(NumWalkers>Nmax) { int nsub=0; int nsub_target=(NumWalkers-nrn)-static_cast<int>(0.9*Nmax); int i=0; while(i< sizeofgood && nsub<nsub_target) { if(ncopy_w[i]) {ncopy_w[i]--; nsub++;} ++i; } NumWalkers -= nsub; } else if(NumWalkers < Nmin) { int nadd=0; int nadd_target = static_cast<int>(Nmin*1.1)-(NumWalkers-nrn); if(nadd_target> sizeofgood) { app_warning() << "The number of walkers is running low. Requested walkers " << nadd_target << " good walkers = " << sizeofgood << endl; } int i=0; while(i< sizeofgood && nadd<nadd_target) { ncopy_w[i]++; ++nadd;++i; } NumWalkers += nadd; } } else { it=good_rn.begin(); it_end=good_rn.end(); int indy(0); while(it!=it_end) { good_w.push_back(*it); ncopy_w.push_back(ncopy_rn[indy]); it++,indy++; } } return NumWalkers; }
int WalkerControlBase::doNotBranch(int iter, MCWalkerConfiguration& W) { MCWalkerConfiguration::iterator it(W.begin()); MCWalkerConfiguration::iterator it_end(W.end()); RealType esum=0.0,e2sum=0.0,wsum=0.0,ecum=0.0, w2sum=0.0, besum=0.0, bwgtsum=0.0; RealType r2_accepted=0.0,r2_proposed=0.0; int nrn(0),ncr(0),nfn(0),ngoodfn(0); for(; it!=it_end;++it) { bool inFN=(((*it)->ReleasedNodeAge)==0); int nc= std::min(static_cast<int>((*it)->Multiplicity),MaxCopy); if ((*it)->ReleasedNodeAge==1) ncr+=1; else if ((*it)->ReleasedNodeAge==0) { nfn+=1; ngoodfn+=nc; } r2_accepted+=(*it)->Properties(R2ACCEPTED); r2_proposed+=(*it)->Properties(R2PROPOSED); RealType e((*it)->Properties(LOCALENERGY)); RealType bfe((*it)->Properties(ALTERNATEENERGY)); RealType rnwgt(0.0); if (inFN) rnwgt=((*it)->Properties(SIGN)); else nrn+=nc; // RealType wgt((*it)->Weight); RealType wgt(0.0); if (inFN) wgt=((*it)->Weight); esum += wgt*e; e2sum += wgt*e*e; wsum += wgt; w2sum += wgt*wgt; ecum += e; besum += bfe*rnwgt*wgt; bwgtsum += rnwgt*wgt; } //temp is an array to perform reduction operations std::fill(curData.begin(),curData.end(),0); curData[ENERGY_INDEX]=esum; curData[ENERGY_SQ_INDEX]=e2sum; curData[WALKERSIZE_INDEX]=W.getActiveWalkers(); curData[WEIGHT_INDEX]=wsum; curData[EREF_INDEX]=ecum; curData[R2ACCEPTED_INDEX]=r2_accepted; curData[R2PROPOSED_INDEX]=r2_proposed; curData[FNSIZE_INDEX]=static_cast<RealType>(nfn); curData[RNONESIZE_INDEX]=static_cast<RealType>(ncr); curData[RNSIZE_INDEX]=nrn; curData[B_ENERGY_INDEX]=besum; curData[B_WGT_INDEX]=bwgtsum; myComm->allreduce(curData); measureProperties(iter); trialEnergy=EnsembleProperty.Energy; W.EnsembleProperty=EnsembleProperty; return W.getActiveWalkers(); }
void L2Project_interface(int mopt, int run,int istart, int iend, const dTensor2& node, const dTensorBC3& qin, const dTensorBC3& auxin, const dTensor4 qI, const dTensor4 auxI,dTensor4& Implicit,double dt, const dTensor1 interf2global, const dTensorBC1 global2interf, const dTensor2 dxi, dTensorBC3& Fout, dTensor4& FI, void (*Func)(const dTensor1&, const dTensor2&, const dTensor2&, dTensor2&)) { const int kmax = dogParams.get_space_order(); const int meqn = qin.getsize(2); const int maux = auxin.getsize(2); const int mlength = Fout.getsize(2); const int mpoints = Fout.getsize(3); int mtmp = iMax(1,6-mopt);//iMax(1,mpoints-mopt); dTensor1 wgt(mtmp), spts(mtmp),rspts(mtmp),lspts(mtmp); dTensor2 phi(mtmp,kmax), phi_x(mtmp,kmax), rIphi_x(mtmp,kmax), lIphi_x(mtmp,kmax); // ----------------- // Quick error check // ----------------- if (meqn<1 || maux <0 || mpoints<1 || mpoints>6 || mlength<1 || mopt < 0 || mopt > 1) { printf(" Error in L2project.cpp ... \n"); printf(" meqn = %i\n",meqn); printf(" maux = %i\n",maux); printf(" mpoints = %i\n",mpoints); printf(" mlength = %i\n",mlength); printf(" istart = %i\n",istart); printf(" iend = %i\n",iend); printf(" mopts = %i\n",mopt); printf("\n"); exit(1); } // --------------------------------------------- // Check for trivial case in the case of mopt==1 // --------------------------------------------- if ( mpoints == mopt ) { Fout.setall(0.); } else { // Set quadrature weights and points void SetQuadPts(dTensor1&,dTensor1&); SetQuadPts(wgt,spts); // Sample basis function at quadrature points void SampleBasis(const dTensor1&,dTensor2&); SampleBasis(spts,phi); // Sample gradient of basis function at quadrature points void SampleBasisGrad(const dTensor1&,dTensor2&); void SampleBasisGrad_variable(const dTensor1&,dTensor2&,double); SampleBasisGrad(spts,phi_x); // ---------------------------------- // Loop over all elements of interest // ---------------------------------- const double xlow = dogParamsCart1.get_xlow(); const double dx = dogParamsCart1.get_dx(); #pragma omp parallel for for (int i=istart; i<=iend; i++) { if(abs(global2interf.get(i))<1.0e-1) { double xc = xlow + (double(i)-0.5)*dx; // Each of these three items needs to be private to each thread .. dTensor1 xpts(mtmp); dTensor2 qvals(mtmp,meqn); dTensor2 auxvals(mtmp,maux); dTensor2 fvals(mtmp,mlength); // Loop over each quadrature point for (int m=1; m<=mtmp; m++) { // grid point x xpts.set( m, xc + 0.5*dx*spts.get(m) ); // Solution values (q) at each grid point for (int me=1; me<=meqn; me++) { qvals.set(m,me, 0.0 ); for (int k=1; k<=mpoints; k++) { qvals.set(m,me, qvals.get(m,me) + phi.get(m,k) * qin.get(i,me,k) ); } } // Auxiliary values (aux) at each grid point for (int ma=1; ma<=maux; ma++) { auxvals.set(m,ma, 0.0 ); for (int k=1; k<=mpoints; k++) { auxvals.set(m,ma, auxvals.get(m,ma) + phi.get(m,k) * auxin.get(i,ma,k) ); } } } // Call user-supplied function to set fvals Func(xpts,qvals,auxvals,fvals); // Evaluate integrals if (mopt==0) // project onto Legendre basis { for (int m1=1; m1<=mlength; m1++) for (int m2=1; m2<=mpoints; m2++) { double tmp = 0.0; for (int k=1; k<=mtmp; k++) { tmp += wgt.get(k)*fvals.get(k,m1)*phi.get(k,m2); } Fout.set(i,m1,m2, 0.5*tmp ); } } else // project onto derivatives of Legendre basis { for (int m1=1; m1<=mlength; m1++) for (int m2=1; m2<=mpoints; m2++) { double tmp = 0.0; for (int k=1; k<=mtmp; k++) { tmp += wgt.get(k)*fvals.get(k,m1)*phi_x.get(k,m2); } Fout.set(i,m1,m2, 0.5*tmp ); } } } else if(run==1) { int iint=int(global2interf.get(i)); double xc1 = xlow + (double(i)-1.0)*dx+0.5*dxi.get(iint,1); double xc2 = xlow + (double(i)-1.0)*dx+dxi.get(iint,1)+0.5*dxi.get(iint,2); double dxl=dxi.get(iint,1); double dxr=dxi.get(iint,2); // Each of these three items needs to be private to each thread .. dTensor1 xptsl(mtmp); dTensor2 qvalsl(mtmp,meqn); dTensor2 auxvalsl(mtmp,maux); dTensor2 fvalsl(mtmp,mlength); dTensor1 xptsr(mtmp); dTensor2 qvalsr(mtmp,meqn); dTensor2 auxvalsr(mtmp,maux); dTensor2 fvalsr(mtmp,mlength); //SampleBasisGrad_variable(lspts,lIphi_x,dxl); //SampleBasisGrad_variable(rspts,rIphi_x,dxr); //SampleBasisGrad_variable(lspts,lIphi_x,1.0); //SampleBasisGrad_variable(rspts,rIphi_x,1.0); SampleBasisGrad_variable(spts,lIphi_x,1.0); SampleBasisGrad_variable(spts,rIphi_x,1.0); // Loop over each quadrature point for (int m=1; m<=mtmp; m++) { // grid point x xptsl.set( m, xc1 + 0.5*dxl*spts.get(m) ); xptsr.set( m, xc2 + 0.5*dxr*spts.get(m) ); // Solution values (q) at each grid point for (int me=1; me<=meqn; me++) { qvalsl.set(m,me, 0.0 ); qvalsr.set(m,me, 0.0 ); for (int k=1; k<=mpoints; k++) { qvalsl.set(m,me, qvalsl.get(m,me) + phi.get(m,k) * qI.get(1,iint,me,k) ); qvalsr.set(m,me, qvalsr.get(m,me) + phi.get(m,k) * qI.get(2,iint,me,k) ); } } // Auxiliary values (aux) at each grid point for (int ma=1; ma<=maux; ma++) { auxvalsl.set(m,ma, 0.0 ); auxvalsr.set(m,ma, 0.0 ); for (int k=1; k<=mpoints; k++) { auxvalsl.set(m,ma, auxvalsl.get(m,ma) + phi.get(m,k) * auxI.get(1,iint,ma,k) ); auxvalsr.set(m,ma, auxvalsr.get(m,ma) + phi.get(m,k) * auxI.get(2,iint,ma,k) ); } } //printf("xcl=%e xtryl= %e \n",xc1,dxl); //printf("xcr=%e xtryr= %e \n",xc2,dxr); } // Call user-supplied function to set fvals Func(xptsl,qvalsl,auxvalsl,fvalsl); Func(xptsr,qvalsr,auxvalsr,fvalsr); /* for (int m=1; m<=mtmp; m++) { printf("xtryl= %e \n",xptsl.get(m)); printf("xtryr= %e \n",xptsr.get(m)); printf("qtryl= %e \n",qvalsl.get(m,1)); printf("qtryr= %e \n",qvalsr.get(m,1)); }*/ //printf("i=%d iint=%d q= %e %e \n",i,iint,qI.get(1,iint,1,1),qI.get(1,iint,1,2)); //printf("2i=%d iint=%d q= %e %e \n",i,iint,Iq.qget(2,iint,1,1),qI.get(2,iint,1,2)); /* for (inti m=1; m<=mtmp; m++) { printf("Points HERE! %d %e %e %e %e \n",m,xptsl.get(m),fvalsl.get(m,1),xptsr.get(m),fvalsl.get(m,1)); }*/ // Evaluate integrals if (mopt==0) // project onto Legendre basis { for (int m1=1; m1<=mlength; m1++) for (int m2=1; m2<=mpoints; m2++) { double tmpl = 0.0; double tmpr = 0.0; for (int k=1; k<=mtmp; k++) { tmpl += wgt.get(k)*fvalsl.get(k,m1)*phi.get(k,m2); tmpr += wgt.get(k)*fvalsr.get(k,m1)*phi.get(k,m2); } FI.set(1,iint,m1,m2, 0.5*tmpl ); FI.set(2,iint,m1,m2, 0.5*tmpr ); } } else // project onto derivatives of Legendre basis { double Ul=auxI.get(1,iint,1,1); double Ur=auxI.get(2,iint,1,1); /* for (int m1=1; m1<=mlength; m1++) for (int m2=1; m2<=mpoints; m2++) { double tmpl = 0.0; double tmpr = 0.0; for (int k=1; k<=mtmp; k++) { tmpl += wgt.get(k)*fvalsl.get(k,m1)*lIphi_x.get(k,m2); tmpr += wgt.get(k)*fvalsr.get(k,m1)*rIphi_x.get(k,m2); } FI.set(1,iint,m1,m2, 0.5*tmpl ); FI.set(2,iint,m1,m2, 0.5*tmpr ); }*/ for (int m2=1; m2<=mpoints; m2++) for (int m3=1; m3<=mpoints; m3++) { double tmponl = 0.0; double tmponr = 0.0; double tmpIl = 0.0; double tmpIr = 0.0; for (int k=1; k<=mtmp; k++) { tmpIl += wgt.get(k)*Ul*phi.get(k,m3)*lIphi_x.get(k,m2); tmpIr += wgt.get(k)*Ur*phi.get(k,m3)*rIphi_x.get(k,m2); tmponl += wgt.get(k)*Ul*phi.get(k,m3)*phi_x.get(k,m2); tmponr += wgt.get(k)*Ur*phi.get(k,m3)*phi_x.get(k,m2); } // Implicit.set(iint,m1,m2,m3, Implicit.get(iint,m1,m2,m3)-0.5*tmpIl ); //Implicit.set(iint,m1,kmax+m2,kmax+m3, Implicit.get(iint,m1,kmax+m2,kmax+m3)-0.5*tmpIr ); //Implicit.set(iint,m1,m2,m3, Implicit.get(iint,m1,m2,m3)+0.5*tmpIl ); //Implicit.set(iint,m1,kmax+m2,kmax+m3, Implicit.get(iint,m1,kmax+m2,kmax+m3)+0.5*tmpIr ); Implicit.set(iint,1,m2,m3, Implicit.get(iint,1,m2,m3)-0.5*tmpIl ); Implicit.set(iint,1,kmax+m2,kmax+m3, Implicit.get(iint,1,kmax+m2,kmax+m3)-0.5*tmpIl ); Implicit.set(iint,1,2*kmax+m2,2*kmax+m3, Implicit.get(iint,1,2*kmax+m2,2*kmax+m3)-0.5*tmpIl ); Implicit.set(iint,1,3*kmax+m2,3*kmax+m3, Implicit.get(iint,1,3*kmax+m2,3*kmax+m3)-0.5*tmpIr ); Implicit.set(iint,1,4*kmax+m2,4*kmax+m3, Implicit.get(iint,1,4*kmax+m2,4*kmax+m3)-0.5*tmpIr ); Implicit.set(iint,1,5*kmax+m2,5*kmax+m3, Implicit.get(iint,1,5*kmax+m2,5*kmax+m3)-0.5*tmpIr ); //if(abs(tmpIl)>1.0e-12 || abs(tmpIr)>1.0e-12) //{printf("HERE2!!!! %e %e \n",0.5*tmpIl,0.5*tmpIr);} } /* for(int m2=1;m2<=mpoints;m2++) { double tmp1=0.0; double tmp2=0.0; for (int m3=1;m3<=mpoints;m3++) { double tmpIl = 0.0; double tmpIr = 0.0; for (int k=1; k<=mtmp; k++) { tmpIl += wgt.get(k)*Ul*phi.get(k,m3)*lIphi_x.get(k,m2); tmpIr += wgt.get(k)*Ur*phi.get(k,m3)*rIphi_x.get(k,m2); } tmp1=tmp1+0.5*tmpIl*qI.get(1,iint,1,m3); tmp2=tmp2+0.5*tmpIr*qI.get(2,iint,1,m3); } //printf("HERE left! %e \n",tmp1-FI.get(1,1,1,m2)); //printf("HERE right! %e \n",tmp2-FI.get(2,1,1,m2)); }*/ } } } } }
LDFE_quad_eq::LDFE_quad_eq(int param) { /* Calculate number of LDFE ranges */ order = param; // Quadrature order int num_LDFE = 2 * pow(2, order); // Number of LDFE regions /* Calculate even quadrature weights */ double delta_gamma = pi / num_LDFE; double wgt_even = delta_gamma / 2.0; /* Initialize common parameters */ double gamma_current = 0.0; double gamma_min; double gamma_max; double gamma_center; vec dir = vec(2); mat A = mat(2, 2); mat B = eye<mat>(2, 2); mat C = mat(3, 3); vec wgt = vec(2); wgts.set_size(num_LDFE, 2); // Resize matrix storing all LDFE range weights dirs.set_size(num_LDFE, 2); // Resize matrix storing all LDFE range directions basis.resize(num_LDFE); // Resize vector storing all LDFE basis functions double RE_old; double RE_new; double ratio_old; double ratio_new; double ratio_temp; int converged; int iter_counter; double delta; for (int r=0; r<num_LDFE; r++) { /* First quadrature direction guess */ gamma_min = gamma_current; gamma_max = gamma_current + delta_gamma; gamma_current = gamma_max; gamma_center = (gamma_max + gamma_min) / 2.0; ratio_old = 0.5; dir(0) = gamma_center - ratio_old * delta_gamma / 2.0; dir(1) = gamma_center + ratio_old * delta_gamma / 2.0; /* Solve for basis functions */ for (int j=0; j<2; j++){ A(j, 0) = 1.0; A(j, 1) = cos(dir(j)); } C = solve(A, B); // Solve for the basis functions /* Solve for weights */ for (int j=0; j<2; j++){ wgt(j) = C(0, j) * (gamma_max - gamma_min) + \ C(1, j) * (sin(gamma_max) - sin(gamma_min)); } /* Calculate relative error using first direction guess */ RE_old = (wgt(0) - wgt_even) / wgt_even; /* Second ratio guess */ ratio_new = 0.75; /* Iterate until weights are equal */ converged = 0; iter_counter = 0; while (converged == 0 && iter_counter < 100) { /* New quadrature directions */ dir(0) = gamma_center - ratio_new * delta_gamma / 2.0; dir(1) = gamma_center + ratio_new * delta_gamma / 2.0; /* New quadrature basis functions */ for (int j=0; j<2; j++){ A(j, 0) = 1.0; A(j, 1) = cos(dir(j)); } C = solve(A, B); // Solve for the basis functions /* New quadrature weights */ for (int j=0; j<2; j++){ wgt(j) = C(0, j) * (gamma_max - gamma_min) + \ C(1, j) * (sin(gamma_max) - sin(gamma_min)); } /* Calculate new relative error */ RE_new = (wgt(0) - wgt_even) / wgt_even; /* Calculate next direction guess */ if (RE_old == RE_new && iter_counter == 1) { ratio_temp = ratio_new; ratio_new = (ratio_old + ratio_new) / 2.0; ratio_old = ratio_temp; iter_counter++; } else { delta = ((ratio_new - ratio_old) / (RE_new - RE_old)) * RE_new; /* Check for convergence */ if (abs(delta) < 1.e-12) { converged = 1; } else { RE_old = RE_new; ratio_old = ratio_new; ratio_new = ratio_new - delta; iter_counter++; } } } /* Store quadrature directions, weights and basis functions */ for (int j=0; j<2; j++) { dirs(r, j) = cos(dir(j)); wgts(r, j) = wgt(j) / pi * 2.0; } basis[r] = C; } }
// semi-lagrangian solver void DogSolverCart2::DogSolveUser(double tstart, double tend) { // this accomodates the maximum number of stages allowed for the // split method ... and is a work in progress ... const int MAX_STAGES = 13; const edge_data& EdgeData = Legendre2d::instance().get_edgeData(); dTensorBC3& smax = fetch_smax(); DogStateCart2* dogStateCart2 = &fetch_state(); dTensorBC4& qnew = fetch_state().fetch_q(); dTensorBC4& qold = fetch_state_old().fetch_q(); dTensorBC4& aux = fetch_state().fetch_aux(); const int nv = dogParams.get_nv(); const double* cflv = dogParams.get_cflv(); // -------------------------------------------------------------- // define local variables int m_accept; const int mx = qnew.getsize(1); const int my = qnew.getsize(2); const int maux = aux.getsize(3); const int meqn = qnew.getsize(3); const int kmax = qnew.getsize(4); const int mbc = qnew.getmbc(); const int ndims = 2; int n_step = 0; double t = tstart; double tn = t; double told = 0.0; double dt = get_dt(); const double CFL_max = cflv[1]; const double CFL_target = cflv[2]; double cfl = 0.0; double dtmin = dt; double dtmax = dt; dTensorBC4 qstar(mx,my,meqn,kmax,mbc); //temporary place holder dTensorBC4 aux_old(mx,my,maux,kmax,mbc); ////////////////////////////////////////////////////////////////////////// // Setup for manipulating velocities. Store 2 arrays, 1 for each velocity ////////////////////////////////////////////////////////////////////////// // array for storing advection speeds in each cell const int mpoints = int((1+4*kmax-int(sqrt(1+8*kmax)))/2); const int mpoints1d = int(sqrt(mpoints)); const int morder = mpoints1d; dTensorBC2 u1(my, mpoints1d, mbc, ndims-1); // speed, u(y) (ndims == 1 ) dTensorBC2 u2(mx, mpoints1d, mbc, ndims-1); // speed, v(x) (ndims == 1 ) ////////Set up any extra state variables associated with this problem ///// SL_state sl_state; sl_state.split_time = new dTensor2(MAX_STAGES, 2); sl_state.aux1d = new dTensorBC4( Max(mx,my), 2, 4, mpoints1d, mbc, 1); sl_state.node1d = new dTensor2(mx+1,1); for( int i=1; i <=(mx+1); i++) { sl_state.node1d->set(i, 1, dogParamsCart2.get_xl(i) ); } sl_state.qold = &qold; sl_state.qnew = &qnew; const double dx = dogParamsCart2.get_dx(); const double dy = dogParamsCart2.get_dy(); // sample grid points (gauss points) dTensor2* spts = new dTensor2(mpoints, 2); //legendre polys evaluated at spts dTensor2 phi(mpoints, kmax); dTensor1 x1d(mpoints1d); dTensor1 wgt(mpoints1d); void setGaussPoints1d(dTensor1& w1d, dTensor1& x1d); setGaussPoints1d(wgt, x1d); // Tensor product Gaussian Quadrature // See note at top of code in how mpoints are arranged here... int k=0; for (int m1=1; m1<=(mpoints1d); m1++) for (int m2=1; m2<=(mpoints1d); m2++) { k = k+1; //save gauss quad grid point location on interval [-1,1]^2 spts->set(k,2, x1d.get(m1) ); spts->set(k,1, x1d.get(m2) ); } //evaluate the legendre polynomials at sample points for(int m=1; m <= mpoints; m++) { double xi, xi2,xi3,xi4, eta, eta2,eta3,eta4; //find xi and eta (point to be evaluated) xi = spts->get(m,1); eta = spts->get(m,2); xi2 = xi*xi; xi3 = xi*xi2; xi4 = xi*xi3; eta2 = eta*eta; eta3 = eta*eta2; eta4 = eta*eta3; // Legendre basis functions evaluated at (xi,eta) in the // interval [-1,1]x[-1,1]. switch( mpoints1d ) { case 5: // fifth order phi.set( m,15, 105.0/8.0*eta4 - 45.0/4.0*eta2 + 9.0/8.0 ); phi.set( m,14, 105.0/8.0*xi4 - 45.0/4.0*xi2 + 9.0/8.0 ); phi.set( m,13, 5.0/4.0*(3.0*xi2 - 1.0)*(3.0*eta2 - 1.0) ); phi.set( m,12, sq3*sq7*(2.5*eta3 - 1.5*eta)*xi ); phi.set( m,11, sq3*sq7*(2.5*xi3 - 1.5*xi)*eta ); case 4: // fourth order phi.set( m,10, sq7*(2.5*eta3 - 1.5*eta) ); phi.set( m,9, sq7*(2.5*xi3 - 1.5*xi) ); phi.set( m,8, sq3*sq5*xi*(1.5*eta2 - 0.5) ); phi.set( m,7, sq3*sq5*eta*(1.5*xi2 - 0.5) ); case 3: // third order phi.set( m,6, sq5*(1.5*eta2 - 0.5) ); phi.set( m,5, sq5*(1.5*xi2 - 0.5) ); phi.set( m,4, 3.0*xi*eta ); case 2: // second order phi.set( m,3, sq3*eta ); phi.set( m,2, sq3*xi ); case 1: // first order phi.set( m,1, 1.0 ); } }//end of evaluating legendre polys at sample grid points indexed by spts delete spts; /////////////////////////////////////////////////////////////////////////// double time1, time2; // running time values time1 = GetTime(); //running time for this program (can remove this..) // fourth order splitting coefficients dTensor1* dt_stages; if( dogParams.get_time_order() >= 2 ) { dt_stages = new dTensor1(MAX_STAGES); sl_state.dt_stages = dt_stages; } /////////////////////////////////////////////////////////////////////////// // Main Time Stepping Loop /////////////////////////////////////////////////////////////////////////// while (t<tend) { // initialize time step m_accept = 0; n_step = n_step + 1; // check if max number of time steps exceeded if (n_step>nv) { cout << " Error in DogSolveAdvec.cpp: "<< " Exceeded allowed # of time steps " << endl; cout << " n_step = " << n_step << endl; cout << " nv = " << nv << endl; cout << endl; exit(1); } // copy qnew and aux in case we reject the step CopyQ(qnew,qold); CopyQ(qnew,qstar); CopyQ(aux,aux_old); // keep trying until we get a dt that does not violate CFL condition while (m_accept==0) { // set current time told = t; tn = t; if (told+dt > tend) { dt = tend - told; } t = told + dt; // Set initial maximum wave speed to zero (this will be saved in // SetAdvecSpeed) for (int i=(1-mbc); i<=(mx+mbc); i++) for (int j=(1-mbc); j<=(my+mbc); j++) { smax.set(i,j,1, 0.0e0 ); smax.set(i,j,2, 0.0e0 ); } sl_state.dt = dt; sl_state.t = sl_state.tn = tn; void InitSLState( const dTensorBC4& q, const dTensorBC4& aux, SL_state& sl_state ); InitSLState( qnew, aux, sl_state ); CopyQ(qold, qstar); ///////////////////////////////////// // Perform a full time step ///////////////////////////////////// switch ( dogParams.get_time_order() ) { case 0: // used for testing - dont' take any time steps! BeforeStep (dt, aux, qnew, *this); AfterStep (dt, aux, qnew, *this); perror( " case 0: Not taking a time step! " ); break; case 1: // 1st order in time, no corrections sl_state.t = tn; BeforeStep(dt, aux, qstar, *this); SetAdvecSpeed(phi, qstar, aux, smax, 1, u1, u2, sl_state); SetAdvecSpeed(phi, qstar, aux, smax, 2, u1, u2, sl_state); StepAdvec(dt, qold, qstar, aux, u1, u2, 1, sl_state); StepAdvec(dt, qstar, qnew, aux, u1, u2, 2, sl_state); break; case 2: // 2nd order in time (strang split method) SetSplitTime(dt, 2, tn, sl_state, dt_stages ); sl_state.stage_num = 1; sl_state.t = tn; SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(0.5*dt, qstar, qnew, aux, u1, u2, 1, sl_state ); // Poisson solve called in BeforeStep for VP system // BeforeStep(dt, aux, qstar ); sl_state.stage_num = 2; BeforeStep(dt, aux, qnew, *this); sl_state.t = tn; SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(dt, qnew, qstar, aux, u1, u2, 2, sl_state ); sl_state.stage_num = 3; sl_state.t = tn + 0.5*dt; StepAdvec(0.5*dt, qstar, qnew, aux, u1, u2, 1, sl_state); break; case 4: // 4th order method (Yoshida Splitting) // initial setup ... Save all appropriate times into SL_state SetSplitTime(dt, 4, tn, sl_state, dt_stages ); /////////////////////////////////////////////////////////// ///// There are 7 stages for Yoshida Splitting ///// /////////////////////////////////////////////////////////// ///////// stage 1: A ////////////////////////////////////// sl_state.stage_num = 1; sl_state.t = sl_state.split_time->get(1,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(1), qstar, qnew, aux, u1, u2, 1, sl_state ); ///////// stage 2: B ////////////////////////////////////// sl_state.stage_num = 2; sl_state.t = sl_state.split_time->get(2,2); SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(2), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 3: A ////////////////////////////////////// sl_state.stage_num = 3; sl_state.t = sl_state.split_time->get(3,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(3), qstar , qnew, aux, u1, u2, 1, sl_state); ///////// stage 4: B ////////////////////////////////////// sl_state.stage_num = 4; sl_state.t = sl_state.split_time->get(4,2); SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(4), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 5: A ////////////////////////////////////// sl_state.stage_num = 5; sl_state.t = sl_state.split_time->get(5,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(5), qstar, qnew, aux, u1, u2, 1, sl_state); ///////// stage 6: B ////////////////////////////////////// sl_state.stage_num = 6; sl_state.t = sl_state.split_time->get(6,2); SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(6), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 7: A ////////////////////////////////////// sl_state.stage_num = 7; sl_state.t = sl_state.split_time->get(7,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(7), qstar , qnew, aux, u1, u2, 1, sl_state); //////////////// --- Experimental New Time Stepping --- /////////////////// // ///////// stage 1: A ////////////////////////////////////// // sl_state.stage_num = 1; // sl_state.t = sl_state.split_time->get(1,1); // SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); // StepAdvec(sl_state.dt_stages->get(1), qstar, qnew, aux, u1, u2, 1, sl_state ); // ///////// stage 2: B ////////////////////////////////////// // sl_state.stage_num = 2; // sl_state.t = sl_state.split_time->get(2,2); // SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state); // StepAdvec(sl_state.dt_stages->get(2), qnew, qstar, aux, u1, u2, 2, sl_state); // ///////// stage 3: A ////////////////////////////////////// // sl_state.stage_num = 3; // sl_state.t = sl_state.split_time->get(3,1); // StepAdvec(sl_state.dt_stages->get(3), qstar , qnew, aux, u1, u2, 1, sl_state); // ///////// stage 4: B ////////////////////////////////////// // sl_state.stage_num = 4; // sl_state.t = sl_state.split_time->get(4,2); // SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); // StepAdvec(sl_state.dt_stages->get(4), qnew, qstar, aux, u1, u2, 2, sl_state); // ///////// stage 5: A ////////////////////////////////////// // sl_state.stage_num = 5; // sl_state.t = sl_state.split_time->get(5,1); // StepAdvec(sl_state.dt_stages->get(5), qstar, qnew, aux, u1, u2, 1, sl_state); // ///////// stage 6: B ////////////////////////////////////// // sl_state.stage_num = 6; // sl_state.t = sl_state.split_time->get(6,2); // SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); // StepAdvec(sl_state.dt_stages->get(6), qnew, qstar, aux, u1, u2, 2, sl_state); // ///////// stage 7: A ////////////////////////////////////// // sl_state.stage_num = 7; // sl_state.t = sl_state.split_time->get(7,1); // StepAdvec(sl_state.dt_stages->get(7), qstar , qnew, aux, u1, u2, 1, sl_state); // ///////// stage 8: B ////////////////////////////////////// // sl_state.stage_num = 8; // sl_state.t = sl_state.split_time->get(8,2); // SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); // StepAdvec(sl_state.dt_stages->get(8), qnew, qstar, aux, u1, u2, 2, sl_state); // ///////// stage 9: A ////////////////////////////////////// // sl_state.stage_num = 9; // sl_state.t = sl_state.split_time->get(9,1); // StepAdvec(sl_state.dt_stages->get(9), qstar , qnew, aux, u1, u2, 1, sl_state); // ///////// stage 10: B ////////////////////////////////////// // sl_state.stage_num = 10; // sl_state.t = sl_state.split_time->get(10,2); // SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); // StepAdvec(sl_state.dt_stages->get(10), qnew, qstar, aux, u1, u2, 2, sl_state); // ///////// stage 11: A ////////////////////////////////////// // sl_state.stage_num = 11; // sl_state.t = sl_state.split_time->get(11,1); // StepAdvec(sl_state.dt_stages->get(11), qstar , qnew, aux, u1, u2, 1, sl_state); // ///////// stage 12: B ////////////////////////////////////// // sl_state.stage_num = 12; // sl_state.t = sl_state.split_time->get(12,2); // SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); // StepAdvec(sl_state.dt_stages->get(12), qnew, qstar, aux, u1, u2, 2, sl_state); // ///////// stage 13: A ////////////////////////////////////// // sl_state.stage_num = 13; // sl_state.t = sl_state.split_time->get(13,1); // StepAdvec(sl_state.dt_stages->get(13), qstar , qnew, aux, u1, u2, 1, sl_state); //////////////// --- Experimental New Time Stepping --- /////////////////// break; case 6: // 6th order method (SRKN Splitting) // Added by Pierson Guthrey 5/22/2015 // initial setup ... Save all appropriate times into SL_state SetSplitTime(dt, 6, tn, sl_state, dt_stages ); ///////// stage 1: A ////////////////////////////////////// sl_state.stage_num = 1; sl_state.t = sl_state.split_time->get(1,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(1), qstar, qnew, aux, u1, u2, 1, sl_state ); ///////// stage 2: B ////////////////////////////////////// sl_state.stage_num = 2; sl_state.t = sl_state.split_time->get(2,2); SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(2), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 3: A ////////////////////////////////////// sl_state.stage_num = 3; sl_state.t = sl_state.split_time->get(3,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(3), qstar , qnew, aux, u1, u2, 1, sl_state); ///////// stage 4: B ////////////////////////////////////// sl_state.stage_num = 4; sl_state.t = sl_state.split_time->get(4,2); SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(4), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 5: A ////////////////////////////////////// sl_state.stage_num = 5; sl_state.t = sl_state.split_time->get(5,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(5), qstar, qnew, aux, u1, u2, 1, sl_state ); ///////// stage 6: B ////////////////////////////////////// sl_state.stage_num = 6; sl_state.t = sl_state.split_time->get(6,2); SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(6), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 7: A ////////////////////////////////////// sl_state.stage_num = 7; sl_state.t = sl_state.split_time->get(7,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(7), qstar , qnew, aux, u1, u2, 1, sl_state); ///////// stage 8: B ////////////////////////////////////// sl_state.stage_num = 8; sl_state.t = sl_state.split_time->get(8,2); SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(8), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 9: A ////////////////////////////////////// sl_state.stage_num = 9; sl_state.t = sl_state.split_time->get(9,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(9), qstar, qnew, aux, u1, u2, 1, sl_state ); ///////// stage 10: B ////////////////////////////////////// sl_state.stage_num = 10; sl_state.t = sl_state.split_time->get(10,2); SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(10), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 11: A ////////////////////////////////////// sl_state.stage_num = 11; sl_state.t = sl_state.split_time->get(11,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(11), qstar , qnew, aux, u1, u2, 1, sl_state); ///////// stage 12: B ////////////////////////////////////// sl_state.stage_num = 12; sl_state.t = sl_state.split_time->get(12,2); SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(12), qnew, qstar, aux, u1, u2, 2, sl_state); ///////// stage 13: A ////////////////////////////////////// sl_state.stage_num = 13; sl_state.t = sl_state.split_time->get(13,1); SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state); StepAdvec(sl_state.dt_stages->get(13), qstar , qnew, aux, u1, u2, 1, sl_state); default: // still here? too bad! Pick a valid time stepping // method fprintf(stderr, "Bad time stepping method chosen in DogSolveAdvec\n"); fprintf(stderr, "dogParams.get_time_order() = %d\n", dogParams.get_time_order()); exit(1); }// end of taking a full time step // compute cfl number cfl = GetCFL(dt); // output time step information if (dogParams.get_verbosity()>0) { cout << setprecision(3); cout << "DogSolve2D ... Step" << setw(5) << n_step; cout << " CFL =" << setw(6) << fixed << cfl; cout << " dt =" << setw(11) << scientific << dt; cout << " t =" << setw(11) << scientific << t << endl; } if (cfl>0.0) { dt = Min(dogParams.get_max_dt(),dt*CFL_target/cfl); } else { dt = dogParams.get_max_dt(); } // see whether to accept or reject this step if (cfl<=CFL_max) { // accept m_accept = 1; dogStateCart2->set_time(t); dogParams.set_time(t); // time hack } else { //reject t = told; if (dogParams.get_verbosity()>0) { cout<<"DogSolve2D rejecting step..."; cout<<"CFL number too large"; cout<<endl; // find index of larger value... int imax = 1; int jmax = 1; int dmax = 1; for( int i = 1; i <= smax.getsize(1); i++ ) for( int j = 1; j <= smax.getsize(2); j++ ) for( int d = 1; d <= ndims; d++ ) { if( smax.get(i,j,d) > smax.get(imax,jmax,dmax) ) { imax = i; jmax = j; dmax = d;} } printf(" imax = %d, jmax = %d, dmax = %d\n", imax, jmax, dmax ); printf(" smax(imax,jmax,dmax) = %3.2e\n", smax.get(imax, jmax, dmax ) ); } // copy qold into qnew CopyQ(qold,qnew); CopyQ(aux_old,aux); } } void AfterFullSLTimeStep( dTensorBC4& aux, dTensorBC4& qnew, double t ); AfterFullSLTimeStep(aux, qnew, t ); // apply the limiter - This way global integrals stay positive void ApplyPosLimiter(const dTensorBC4& aux, dTensorBC4& q); if(dogParams.using_moment_limiter()) { ApplyPosLimiter(aux, qnew); } // compute conservation and print to file ConSoln(aux,qnew,t); } void AfterSLFrame(double dt, dTensorBC4& aux, dTensorBC4& q, DogSolverCart2& solver, SL_state sl_state ); AfterSLFrame(dt, aux, qnew, *this, sl_state ); // set initial time step for next call to DogSolveAdvec set_dt(dt); // Clock the running time for this call to DogSolveAdvec time2 = GetTime(); if(dogParams.get_verbosity()>0) { cout << " DogSolveAdvec Running Time = " << setw(3) << time2 - time1 << " seconds" << endl << endl; } if( dogParams.get_time_order() >= 2 ) { delete dt_stages; } delete sl_state.split_time; delete sl_state.aux1d; delete sl_state.node1d; }
////////////////////////////////////////////////////////////////////////////// // Function for stepping advection equation forward in time. // // The advection equation: q_t + u q_x = 0. // // It is assumed that aux(1,1,1) = u is constant. // ////////////////////////////////////////////////////////////////////////////// void StepAdvecFluxForm(const double& dt, const dTensor2& node, dTensorBC3& auxvals, dTensorBC1& smax, const dTensorBC3& qold, dTensorBC3& qnew) { void SetBndValues(const dTensor2& node, dTensorBC3& aux, dTensorBC3& q); SetBndValues(node, auxvals, qnew); //-local parameters -----------------------------------------------------// const int melems = qnew.getsize(1); //number of elements in grid const int meqn = qnew.getsize(2); //number of equations const int kmax = qnew.getsize(3); //number of polynomials const int mbc = qnew.getmbc(); //number of ghost cells //-----------------------------------------------------------------------// //save the center of each grid cell const double dx = node.get(2,1)-node.get(1,1); const double speed = auxvals.get(1,1,1); for(int j=1-mbc; j<=melems+mbc; j++) { smax.set(j, Max(smax.get(j), fabs(speed) ) ); } // compute quadrature points for where Q needs to be sampled const double s_area = 2.0; const double large_eta = speed*dt/dx; // integration points and weights (for interior) const int mpts = 5; dTensor1 wgt( mpts ), spts( mpts ); dTensor2 phi( mpts, 5), phi_x(mpts, 5); if( kmax > 1 ) { void setGaussPoints1d(dTensor1& x1d, dTensor1& w1d); void evaluateLegendrePolys( const double dx, const dTensor1& spts, dTensor2& phi, dTensor2& phi_x); setGaussPoints1d( spts, wgt ); evaluateLegendrePolys(dx, spts, phi, phi_x); } #pragma omp parallel for for(int i=1; i<=melems; i++) { //loop over each equation for(int me=1; me<= meqn; me++) { dg_cell* dgc = new dg_cell(); for( int k=1; k <= kmax; k++) { double qnp1 = qold.get(i,me,k); if( k > 1 ) { // interior integral for( int m=1; m <= mpts; m++ ) { double a = spts.get(m) - 2.0 * large_eta; double b = spts.get(m); int ishift = get_shift_index( a ); double integral = 0.0; if( ishift == 0 ) { // no shift takes place, can simply integrate from a to b for( int kq = 1; kq <= kmax; kq++ ) { integral += qold.get(i, me, kq) * dgc->integratePhi( a, b, kq ); } } else if( ishift < 0 ) { // integral at the shifted value for( int kq = 1; kq <= kmax; kq++ ) { integral += qold.get(i+ishift, me, kq) * dgc->integratePhi( shift_xi(a), 1.0, kq ); } // integrals between i and ishift for( int n=-1; n > ishift; n-- ) { integral += qold.get(i + n, meqn, 1) * dgc->integratePhi(-1.0, 1.0, 1); } // integral inside current cell for( int kq = 1; kq <= kmax; kq++ ) { integral += qold.get(i, me, kq) * dgc->integratePhi( -1.0, spts.get(m), kq ); } } else { printf(" StepAdvecFluxForm.cpp problem can't handle negative velocities yet\n"); exit(1); } qnp1 += 0.25 * dx * wgt.get(m) * phi_x.get(m,k) * integral; } } // left flux double a = -1.0 - 2.0 * large_eta; int ishift = get_shift_index( a ); double Fm = 0.0; if( ishift < 0 ) { for( int kq = 1; kq <= kmax; kq++ ) { Fm += qold.get(i+ishift, me, kq) * dgc->integratePhi( shift_xi(a), 1.0, kq ) / 2.0; } for( int n=-1; n > ishift; n-- ) { Fm += qold.get(i+n, me, 1); } } Fm *= sqrt(2*k-1) * pow(-1, k+1 ); // right flux double Fp = 0.0; a += 2.0; ishift = get_shift_index( a ); if( ishift < 1 ) { for( int kq = 1; kq <= kmax; kq++ ) { Fp += qold.get(i+ishift, me, kq) * dgc->integratePhi( shift_xi(a), 1.0, kq ) / 2.0; } } for( int n=0; n > ishift; n-- ) { Fp += qold.get(i+n, me, 1); } Fp *= sqrt(2*k-1); qnew.set(i, me, k, qnp1 - ( Fp - Fm ) ); } delete dgc; }//end of loop over each cell }//end of loop over each eqn void SetBndValues(const dTensor2& node, dTensorBC3& aux, dTensorBC3& q); SetBndValues(node, auxvals, qnew); }