void ComputeElecField(double t, const dTensor2& node, const dTensorBC3& qvals, dTensorBC3& aux, dTensorBC3& Evals) { void ConvertBC(const dTensor2& node, const int mbc1, const int mbc2, const double tmp1, const double tmp2, const dTensorBC3& Fvals, double& gamma, double& beta); void PoissonSolve(const int mstart, const dTensor2& node, const double gamma, const double beta, const dTensorBC3& Fvals, dTensorBC3& qvals); const int melems = qvals.getsize(1); const int meqn = qvals.getsize(2); const int kmax = qvals.getsize(3); const int mbc = qvals.getmbc(); dTensorBC3 fvals(melems, 1 , kmax, mbc); // right hand side function // phi(mx,1,kmax1d) = 'electric' field // phi(mx,2,kmax1d) = potential (not unique!) dTensorBC3 phi(melems, 2, kmax, mbc); // Electric field and potential for(int i=1; i<= melems; i++) for(int k=1; k<=kmax; k++) { fvals.set(i, 1, k, qvals.get(i,1,k) - aux.get(i,1,k) ); } ////////////////////////////////////////////////////////////////////////// // Solve for electric field and potential ////////////////////////////////////////////////////////////////////////// // periodic boundary conditions: alpha = beta = 0; // gamma = delta will be forced provided \int f = 0. double gamma, beta; ConvertBC(node, 1, 1, 0.0, 0.0, fvals, gamma, beta); PoissonSolve(1, node, gamma, beta, fvals, phi); ////////////////////////////////////////////////////////////////////////// // Save results into Evals ////////////////////////////////////////////////////////////////////////// for(int i = 1; i <= melems; i++ ) for(int k=1; k <= kmax; k++ ) { Evals.set(i, 1, k, phi.get(i, 1, k) ); } }// end of Compute Electric Field
void ComputeElecPotential(double t, const dTensor2& node, const dTensorBC3& qvals, dTensorBC3& aux, dTensorBC3& phi) { ///////////////////////////////////////////////////////////////////////// // This function is only ever called in Output.cpp -- the purpose is to // print the moments for both the electric potential, as well as the // electric field ///////////////////////////////////////////////////////////////////////// // --------------------- Function Declarations -------------------------// void ConvertBC(const dTensor2& node, const int mbc1, const int mbc2, const double tmp1, const double tmp2, const dTensorBC3& Fvals, double& gamma, double& beta); void PoissonSolve(const int mstart, const dTensor2& node, const double gamma, const double beta, const dTensorBC3& Fvals, dTensorBC3& qvals); // --------------------- Function Declarations -------------------------// // --------------------- Local Variables -------------------------------// const int melems = qvals.getsize(1); const int meqn = qvals.getsize(2); const int kmax = qvals.getsize(3); const int mbc = qvals.getmbc(); dTensorBC3 fvals(melems, 2 , kmax, mbc, 1); // right hand side function for(int i=1; i<= melems; i++) for(int k=1; k<=kmax; k++) { double tmp = qvals.get(i,1,k); fvals.set(i, 1, k, tmp - aux.get(i,1,k) ); } ////////////////////////////////////////////////////////////////////////// // Solve for electric field and potential ////////////////////////////////////////////////////////////////////////// // periodic boundary conditions: alpha = beta = 0; // gamma = delta will be forced provided \int f = 0. double gamma, beta; ConvertBC(node, 1, 1, 0.0, 0.0, fvals, gamma, beta); PoissonSolve(1, node, gamma, beta, fvals, phi); }
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)); }*/ } } } } }
static int trim_ns(bam1_t *b, void *data) { int ret = 0; opts_t *op((opts_t *)data); std::vector<uint8_t> aux(bam_get_aux(b), bam_get_aux(b) + bam_get_l_aux(b)); int tmp; uint8_t *const seq(bam_get_seq(b)); uint32_t *const cigar(bam_get_cigar(b)); //op->n_cigar = b->core.n_cigar; op->resize(b->l_data); // Make sure it's big enough to hold everything. memcpy(op->data, b->data, b->core.l_qname); // Get #Ns at the beginning for(tmp = 0; bam_seqi(seq, tmp) == dlib::htseq::HTS_N; ++tmp); const int n_start(tmp); if(tmp == b->core.l_qseq - 1) // all bases are N -- garbage read ret |= op->skip_all_ns; // Get #Ns at the end for(tmp = b->core.l_qseq - 1; bam_seqi(seq, tmp) == dlib::htseq::HTS_N; --tmp); const int n_end(b->core.l_qseq - 1 - tmp); // Get new length for read int final_len(b->core.l_qseq - n_end - n_start); if(final_len < 0) final_len = 0; if(final_len < op->min_trimmed_len) // Too short. ret |= 1; // Copy in qual and all of aux. if(n_end) { if((tmp = bam_cigar_oplen(cigar[b->core.n_cigar - 1]) - n_end) == 0) { LOG_DEBUG("Entire cigar operation is the softclip. Decrease the number of new cigar operations.\n"); --b->core.n_cigar; } else { LOG_DEBUG("Updating second cigar operation in-place.\n"); cigar[b->core.n_cigar - 1] = bam_cigar_gen(tmp, BAM_CSOFT_CLIP); } } // Get new n_cigar. if((tmp = bam_cigar_oplen(*cigar) - n_start) == 0) { memcpy(op->data + b->core.l_qname, cigar + 1, (--b->core.n_cigar) << 2); // << 2 for 4 bit per cigar op } else { if(n_start) *cigar = bam_cigar_gen(tmp, BAM_CSOFT_CLIP); memcpy(op->data + b->core.l_qname, cigar, b->core.n_cigar << 2); } uint8_t *opseq(op->data + b->core.l_qname + (b->core.n_cigar << 2)); // Pointer to the seq region of new data field. for(tmp = 0; tmp < final_len >> 1; ++tmp) opseq[tmp] = (bam_seqi(seq, ((tmp << 1) + n_start)) << 4) | (bam_seqi(seq, (tmp << 1) + n_start + 1)); if(final_len & 1) opseq[tmp] = (bam_seqi(seq, ((tmp << 1) + n_start)) << 4); tmp = bam_get_l_aux(b); memcpy(opseq + ((final_len + 1) >> 1), bam_get_qual(b) + n_start, final_len + tmp); // Switch data strings std::swap(op->data, b->data); b->core.l_qseq = final_len; memcpy(bam_get_aux(b), aux.data(), aux.size()); b->l_data = (bam_get_aux(b) - b->data) + aux.size(); if(n_end) bam_aux_append(b, "NE", 'i', sizeof(int), (uint8_t *)&n_end); if(n_start) bam_aux_append(b, "NS", 'i', sizeof(int), (uint8_t *)&n_start); const uint32_t *pvar((uint32_t *)dlib::array_tag(b, "PV")); tmp = b->core.flag & BAM_FREVERSE ? n_end: n_start; if(pvar) { std::vector<uint32_t>pvals(pvar + tmp, pvar + final_len + tmp); bam_aux_del(b, (uint8_t *)(pvar) - 6); dlib::bam_aux_array_append(b, "PV", 'I', sizeof(uint32_t), final_len, (uint8_t *)pvals.data()); } const uint32_t *fvar((uint32_t *)dlib::array_tag(b, "FA")); if(fvar) { std::vector<uint32_t>fvals(fvar + tmp, fvar + final_len + tmp); bam_aux_del(b, (uint8_t *)(fvar) - 6); dlib::bam_aux_array_append(b, "FA", 'I', sizeof(uint32_t), final_len, (uint8_t *)fvals.data()); } return ret; }
// All-purpose routine for computing the L2-projection // of various functions onto the gradient of the Legendre basis // (Unstructured grid version) // void L2ProjectGrad_Unst( const dTensor2* vel_vec, const int istart, const int iend, const int QuadOrder, const int BasisOrder_qin, const int BasisOrder_auxin, const int BasisOrder_fout, const mesh& Mesh, const dTensor3* qin, const dTensor3* auxin, dTensor3* fout, void (*Func)(const dTensor2* vel_vec, const dTensor2&,const dTensor2&, const dTensor2&,dTensor3&)) { // starting and ending indeces const int NumElems = Mesh.get_NumElems(); assert_ge(istart,1); assert_le(iend,NumElems); // qin variable assert_eq(NumElems,qin->getsize(1)); const int meqn = qin->getsize(2); const int kmax_qin = qin->getsize(3); assert_eq(kmax_qin,(BasisOrder_qin*(BasisOrder_qin+1))/2); // auxin variable assert_eq(NumElems,auxin->getsize(1)); const int maux = auxin->getsize(2); const int kmax_auxin = auxin->getsize(3); assert_eq(kmax_auxin,(BasisOrder_auxin*(BasisOrder_auxin+1))/2); // fout variables assert_eq(NumElems,fout->getsize(1)); const int mcomps_out = fout->getsize(2); const int kmax_fout = fout->getsize(3); assert_eq(kmax_fout,(BasisOrder_fout*(BasisOrder_fout+1))/2); // number of quadrature points assert_ge(QuadOrder,1); assert_le(QuadOrder,5); int mpoints; switch ( QuadOrder ) { case 1: mpoints = 0; break; case 2: mpoints = 1; break; case 3: mpoints = 6; break; case 4: mpoints = 7; break; case 5: mpoints = 16; break; } // trivial case if ( QuadOrder==1 ) { for (int i=istart; i<=iend; i++) for (int m=1; m<=mcomps_out; m++) for (int k=1; k<=kmax_fout; k++) { fout->set(i,m,k, 0.0 ); } } else { const int kmax = iMax(iMax(kmax_qin,kmax_auxin),kmax_fout); dTensor2 spts(mpoints,2); dTensor1 wgts(mpoints); dTensor2 xpts(mpoints,2); dTensor2 qvals(mpoints,meqn); dTensor2 auxvals(mpoints,maux); dTensor3 fvals(mpoints,mcomps_out,2); dTensor2 mu(mpoints,kmax); // monomial basis (non-orthogonal) dTensor2 phi(mpoints,kmax); // Legendre basis (orthogonal) dTensor2 mu_xi(mpoints,kmax_fout); // xi-derivative of monomial basis (non-orthogonal) dTensor2 mu_eta(mpoints,kmax_fout); // eta-derivative of monomial basis (non-orthogonal) dTensor2 phi_xi(mpoints,kmax_fout); // xi-derivative of Legendre basis (orthogonal) dTensor2 phi_eta(mpoints,kmax_fout); // eta-derivative of Legendre basis (orthogonal) dTensor2 phi_x(mpoints,kmax_fout); // x-derivative of Legendre basis (orthogonal) dTensor2 phi_y(mpoints,kmax_fout); // y-derivative of Legendre basis (orthogonal) switch ( QuadOrder ) { case 2: spts.set(1,1, 0.0 ); spts.set(1,2, 0.0 ); wgts.set(1, 0.5 ); break; case 3: spts.set(1,1, 0.112615157582632 ); spts.set(1,2, 0.112615157582632 ); spts.set(2,1, -0.225230315165263 ); spts.set(2,2, 0.112615157582632 ); spts.set(3,1, 0.112615157582632 ); spts.set(3,2, -0.225230315165263 ); spts.set(4,1, -0.241757119823562 ); spts.set(4,2, -0.241757119823562 ); spts.set(5,1, 0.483514239647126 ); spts.set(5,2, -0.241757119823562 ); spts.set(6,1, -0.241757119823562 ); spts.set(6,2, 0.483514239647126 ); wgts.set(1, 0.1116907948390055 ); wgts.set(2, 0.1116907948390055 ); wgts.set(3, 0.1116907948390055 ); wgts.set(4, 0.0549758718276610 ); wgts.set(5, 0.0549758718276610 ); wgts.set(6, 0.0549758718276610 ); break; case 4: spts.set(1,1, 0.000000000000000 ); spts.set(1,2, 0.000000000000000 ); spts.set(2,1, 0.136808730771782 ); spts.set(2,2, 0.136808730771782 ); spts.set(3,1, -0.273617461543563 ); spts.set(3,2, 0.136808730771782 ); spts.set(4,1, 0.136808730771782 ); spts.set(4,2, -0.273617461543563 ); spts.set(5,1, -0.232046826009877 ); spts.set(5,2, -0.232046826009877 ); spts.set(6,1, 0.464093652019754 ); spts.set(6,2, -0.232046826009877 ); spts.set(7,1, -0.232046826009877 ); spts.set(7,2, 0.464093652019754 ); wgts.set(1, 0.1125000000000000 ); wgts.set(2, 0.0661970763942530 ); wgts.set(3, 0.0661970763942530 ); wgts.set(4, 0.0661970763942530 ); wgts.set(5, 0.0629695902724135 ); wgts.set(6, 0.0629695902724135 ); wgts.set(7, 0.0629695902724135 ); break; case 5: spts.set(1,1, 0.000000000000000 ); spts.set(1,2, 0.000000000000000 ); spts.set(2,1, 0.125959254959390 ); spts.set(2,2, 0.125959254959390 ); spts.set(3,1, -0.251918509918779 ); spts.set(3,2, 0.125959254959390 ); spts.set(4,1, 0.125959254959390 ); spts.set(4,2, -0.251918509918779 ); spts.set(5,1, -0.162764025581573 ); spts.set(5,2, -0.162764025581573 ); spts.set(6,1, 0.325528051163147 ); spts.set(6,2, -0.162764025581573 ); spts.set(7,1, -0.162764025581573 ); spts.set(7,2, 0.325528051163147 ); spts.set(8,1, -0.282786105016302 ); spts.set(8,2, -0.282786105016302 ); spts.set(9,1, 0.565572210032605 ); spts.set(9,2, -0.282786105016302 ); spts.set(10,1, -0.282786105016302 ); spts.set(10,2, 0.565572210032605 ); spts.set(11,1, -0.324938555923375 ); spts.set(11,2, -0.070220503698695 ); spts.set(12,1, -0.324938555923375 ); spts.set(12,2, 0.395159059622071 ); spts.set(13,1, -0.070220503698695 ); spts.set(13,2, -0.324938555923375 ); spts.set(14,1, -0.070220503698695 ); spts.set(14,2, 0.395159059622071 ); spts.set(15,1, 0.395159059622071 ); spts.set(15,2, -0.324938555923375 ); spts.set(16,1, 0.395159059622071 ); spts.set(16,2, -0.070220503698695 ); wgts.set(1, 0.0721578038388935 ); wgts.set(2, 0.0475458171336425 ); wgts.set(3, 0.0475458171336425 ); wgts.set(4, 0.0475458171336425 ); wgts.set(5, 0.0516086852673590 ); wgts.set(6, 0.0516086852673590 ); wgts.set(7, 0.0516086852673590 ); wgts.set(8, 0.0162292488115990 ); wgts.set(9, 0.0162292488115990 ); wgts.set(10, 0.0162292488115990 ); wgts.set(11, 0.0136151570872175 ); wgts.set(12, 0.0136151570872175 ); wgts.set(13, 0.0136151570872175 ); wgts.set(14, 0.0136151570872175 ); wgts.set(15, 0.0136151570872175 ); wgts.set(16, 0.0136151570872175 ); break; } // Loop over each quadrature point and construct monomial polys for (int m=1; m<=mpoints; m++) { // coordinates const double xi = spts.get(m,1); const double xi2 = xi*xi; const double xi3 = xi2*xi; const double xi4 = xi3*xi; const double eta = spts.get(m,2); const double eta2 = eta*eta; const double eta3 = eta2*eta; const double eta4 = eta3*eta; // monomial basis functions at each gaussian quadrature point switch( kmax ) { case 15: // fifth order mu.set(m, 15, eta4 ); mu.set(m, 14, xi4 ); mu.set(m, 13, xi2*eta2 ); mu.set(m, 12, eta3*xi ); mu.set(m, 11, xi3*eta ); case 10: // fourth order mu.set(m, 10, eta3 ); mu.set(m, 9, xi3 ); mu.set(m, 8, xi*eta2 ); mu.set(m, 7, eta*xi2 ); case 6: // third order mu.set(m, 6, eta2 ); mu.set(m, 5, xi2 ); mu.set(m, 4, xi*eta ); case 3: // second order mu.set(m, 3, eta ); mu.set(m, 2, xi ); case 1: // first order mu.set(m, 1, 1.0 ); break; } // Loop over each quadrature point and construct Legendre polys for (int i=1; i<=kmax; i++) { double tmp = 0.0; for (int j=1; j<=i; j++) { tmp = tmp + Mmat[i-1][j-1]*mu.get(m,j); } phi.set(m,i, tmp ); } // Gradient of monomial basis functions at each gaussian quadrature point switch( kmax_fout ) { case 15: // fifth order mu_xi.set( m,15, 0.0 ); mu_xi.set( m,14, 4.0*xi3 ); mu_xi.set( m,13, 2.0*xi*eta2 ); mu_xi.set( m,12, eta3 ); mu_xi.set( m,11, 3.0*xi2*eta ); mu_eta.set( m,15, 4.0*eta3 ); mu_eta.set( m,14, 0.0 ); mu_eta.set( m,13, 2.0*xi2*eta ); mu_eta.set( m,12, 3.0*eta2*xi ); mu_eta.set( m,11, xi3 ); case 10: // fourth order mu_xi.set( m,10, 0.0 ); mu_xi.set( m,9, 3.0*xi2 ); mu_xi.set( m,8, eta2 ); mu_xi.set( m,7, 2.0*eta*xi ); mu_eta.set( m,10, 3.0*eta2 ); mu_eta.set( m,9, 0.0 ); mu_eta.set( m,8, 2.0*eta*xi ); mu_eta.set( m,7, xi2 ); case 6: // third order mu_xi.set( m,6, 0.0 ); mu_xi.set( m,5, 2.0*xi ); mu_xi.set( m,4, eta ); mu_eta.set( m,6, 2.0*eta ); mu_eta.set( m,5, 0.0 ); mu_eta.set( m,4, xi ); case 3: // second order mu_xi.set( m,3, 0.0 ); mu_xi.set( m,2, 1.0 ); mu_eta.set( m,3, 1.0 ); mu_eta.set( m,2, 0.0 ); case 1: // first order mu_xi.set( m,1, 0.0 ); mu_eta.set( m,1, 0.0 ); break; } // Loop over each quadrature point and construct Legendre polys for (int i=1; i<=kmax_fout; i++) { double tmp1 = 0.0; double tmp2 = 0.0; for (int j=1; j<=i; j++) { tmp1 = tmp1 + Mmat[i-1][j-1]*mu_xi.get(m,j); tmp2 = tmp2 + Mmat[i-1][j-1]*mu_eta.get(m,j); } phi_xi.set(m,i, tmp1 ); phi_eta.set(m,i, tmp2 ); } } // ------------------------------------------------------------- // Loop over every grid cell indexed by user supplied parameters // described by istart...iend // ------------------------------------------------------------- #pragma omp parallel for for (int i=istart; i<=iend; i++) { // Find center of current cell const int i1 = Mesh.get_tnode(i,1); const int i2 = Mesh.get_tnode(i,2); const int i3 = Mesh.get_tnode(i,3); const double x1 = Mesh.get_node(i1,1); const double y1 = Mesh.get_node(i1,2); const double x2 = Mesh.get_node(i2,1); const double y2 = Mesh.get_node(i2,2); const double x3 = Mesh.get_node(i3,1); const double y3 = Mesh.get_node(i3,2); const double xc = (x1+x2+x3)/3.0; const double yc = (y1+y2+y3)/3.0; // Compute q, aux and fvals at each Gaussian Quadrature point // for this current cell indexed by (i,j) // Save results into dTensor2 qvals, auxvals and fvals. for (int m=1; m<=mpoints; m++) { // convert phi_xi and phi_eta derivatives // to phi_x and phi_y derivatives through Jacobian for (int k=1; k<=kmax_fout; k++) { phi_x.set(m,k, Mesh.get_jmat(i,1,1)*phi_xi.get(m,k) + Mesh.get_jmat(i,1,2)*phi_eta.get(m,k) ); phi_y.set(m,k, Mesh.get_jmat(i,2,1)*phi_xi.get(m,k) + Mesh.get_jmat(i,2,2)*phi_eta.get(m,k) ); } // point on the unit triangle const double s = spts.get(m,1); const double t = spts.get(m,2); // point on the physical triangle xpts.set(m,1, xc + (x2-x1)*s + (x3-x1)*t ); xpts.set(m,2, yc + (y2-y1)*s + (y3-y1)*t ); // 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<=kmax_qin; 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<=kmax_auxin; 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(vel_vec, xpts, qvals, auxvals, fvals); // Evaluate integral on current cell (project onto Legendre basis) // using Gaussian Quadrature for the integration for (int m1=1; m1<=mcomps_out; m1++) for (int m2=1; m2<=kmax_fout; m2++) { double tmp = 0.0; for (int k=1; k<=mpoints; k++) { tmp = tmp + wgts.get(k)* ( fvals.get(k,m1,1)*phi_x.get(k,m2) + fvals.get(k,m1,2)*phi_y.get(k,m2) ); } fout->set(i, m1, m2, 2.0*tmp ); } } } }
// Modified version of the all purpose routine L2Project specifically written // for projecting the "time-averaged" flux function onto the basis function. // // This routine also returns the coefficients of the Lax Wendroff Flux // Function when expanded with legendre basis functions, and therefore the // basis expansions produced by this routine can be used for all of the // Riemann solves. // // --------------------------------------------------------------------- // Inputs should have the following sizes: // TODO - document the inputs here // --------------------------------------------------------------------- void L2ProjectLxW_Unst( const int mterms, const double alpha, const double beta_dt, const double charlie_dt, const int istart, const int iend, // Start-stop indices const int QuadOrder, const int BasisOrder_qin, const int BasisOrder_auxin, const int BasisOrder_fout, const mesh& Mesh, const dTensor3* qin, const dTensor3* auxin, // state vector dTensor3* F, dTensor3* G, // time-averaged Flux function void FluxFunc (const dTensor2& xpts, const dTensor2& Q, const dTensor2& Aux, dTensor3& flux), void DFluxFunc (const dTensor2& xpts, const dTensor2& Q, const dTensor2& aux, dTensor4& Dflux), void D2FluxFunc (const dTensor2& xpts, const dTensor2& Q, const dTensor2& aux, dTensor5& D2flux) ) { if( fabs( alpha ) < 1e-14 && fabs( beta_dt ) < 1e-14 && fabs( charlie_dt ) < 1e-14 ) { F->setall(0.); G->setall(0.); return; } // starting and ending indices const int NumElems = Mesh.get_NumElems(); assert_ge(istart,1); assert_le(iend,NumElems); // qin variable assert_eq(NumElems,qin->getsize(1)); const int meqn = qin->getsize(2); const int kmax_qin = qin->getsize(3); assert_eq(kmax_qin,(BasisOrder_qin*(BasisOrder_qin+1))/2); // auxin variable assert_eq(NumElems,auxin->getsize(1)); const int maux = auxin->getsize(2); const int kmax_auxin = auxin->getsize(3); assert_eq(kmax_auxin,(BasisOrder_auxin*(BasisOrder_auxin+1))/2); // fout variables assert_eq(NumElems, F->getsize(1)); const int mcomps_out = F->getsize(2); const int kmax_fout = F->getsize(3); assert_eq(kmax_fout, (BasisOrder_fout*(BasisOrder_fout+1))/2 ); // number of quadrature points assert_ge(QuadOrder, 1); assert_le(QuadOrder, 5); // Number of quadrature points int mpoints; switch( QuadOrder ) { case 1: mpoints = 1; break; case 2: mpoints = 3; break; case 3: mpoints = 6; break; case 4: mpoints = 12; break; case 5: mpoints = 16; break; } const int kmax = iMax(iMax(kmax_qin, kmax_auxin), kmax_fout); dTensor2 phi(mpoints, kmax); // Legendre basis (orthogonal) dTensor2 spts(mpoints, 2); // List of quadrature points dTensor1 wgts(mpoints); // List of quadrature weights setQuadPoints_Unst( QuadOrder, wgts, spts ); // ---------------------------------------------------------------------- // // Evaluate the basis functions at each point SetLegendreAtPoints_Unst(spts, phi); // ---------------------------------------------------------------------- // // ---------------------------------------------------------------------- // // First-order derivatives dTensor2 phi_xi (mpoints, kmax ); dTensor2 phi_eta(mpoints, kmax ); SetLegendreGrad_Unst( spts, phi_xi, phi_eta ); // ---------------------------------------------------------------------- // // ---------------------------------------------------------------------- // // Second-order derivatives dTensor2 phi_xi2 (mpoints, kmax ); dTensor2 phi_xieta(mpoints, kmax ); dTensor2 phi_eta2 (mpoints, kmax ); LegendreDiff2_Unst(spts, &phi_xi2, &phi_xieta, &phi_eta2 ); // ---------------------------------------------------------------------- // // ------------------------------------------------------------- // // Loop over every grid cell indexed by user supplied parameters // // described by istart...iend, jstart...jend // // ------------------------------------------------------------- // #pragma omp parallel for for (int i=istart; i<=iend; i++) { // These need to be defined locally. Each mesh element carries its // own change of basis matrix, so these need to be recomputed for // each element. The canonical derivatives, phi_xi, and phi_eta can // be computed and shared for each element. // First-order derivatives dTensor2 phi_x(mpoints, kmax_fout); // x-derivative of Legendre basis (orthogonal) dTensor2 phi_y(mpoints, kmax_fout); // y-derivative of Legendre basis (orthogonal) // Second-order derivatives dTensor2 phi_xx(mpoints, kmax_fout); // xx-derivative of Legendre basis (orthogonal) dTensor2 phi_xy(mpoints, kmax_fout); // xy-derivative of Legendre basis (orthogonal) dTensor2 phi_yy(mpoints, kmax_fout); // yy-derivative of Legendre basis (orthogonal) //find center of current cell const int i1 = Mesh.get_tnode(i,1); const int i2 = Mesh.get_tnode(i,2); const int i3 = Mesh.get_tnode(i,3); // Corners: const double x1 = Mesh.get_node(i1,1); const double y1 = Mesh.get_node(i1,2); const double x2 = Mesh.get_node(i2,1); const double y2 = Mesh.get_node(i2,2); const double x3 = Mesh.get_node(i3,1); const double y3 = Mesh.get_node(i3,2); // Center of current cell: const double xc = (x1+x2+x3)/3.0; const double yc = (y1+y2+y3)/3.0; // Variables that need to be written to, and therefore are // created for each thread dTensor2 xpts (mpoints, 2); dTensor2 qvals (mpoints, meqn); dTensor2 auxvals(mpoints, maux); // local storage for Flux function its Jacobian, and the Hessian: dTensor3 fvals(mpoints, meqn, 2); // flux function (vector) dTensor4 A(mpoints, meqn, meqn, 2); // Jacobian of flux dTensor5 H(mpoints, meqn, meqn, meqn, 2); // Hessian of flux // Compute q, aux and fvals at each Gaussian Quadrature point // for this current cell indexed by (i,j) // Save results into dTensor2 qvals, auxvals and fvals. for (int m=1; m<= mpoints; m++) { // convert phi_xi and phi_eta derivatives // to phi_x and phi_y derivatives through Jacobian // // Note that: // // pd_x = J11 pd_xi + J12 pd_eta and // pd_y = J21 pd_xi + J22 pd_eta. // // Squaring these operators yields the second derivatives. for (int k=1; k<=kmax_fout; k++) { phi_x.set(m,k, Mesh.get_jmat(i,1,1)*phi_xi.get(m,k) + Mesh.get_jmat(i,1,2)*phi_eta.get(m,k) ); phi_y.set(m,k, Mesh.get_jmat(i,2,1)*phi_xi.get(m,k) + Mesh.get_jmat(i,2,2)*phi_eta.get(m,k) ); phi_xx.set(m,k, Mesh.get_jmat(i,1,1)*Mesh.get_jmat(i,1,1)*phi_xi2.get(m,k) + Mesh.get_jmat(i,1,1)*Mesh.get_jmat(i,1,2)*phi_xieta.get(m,k) + Mesh.get_jmat(i,1,2)*Mesh.get_jmat(i,1,2)*phi_eta2.get(m,k) ); phi_xy.set(m,k, Mesh.get_jmat(i,1,1)*Mesh.get_jmat(i,2,1)*phi_xi2.get(m,k) +(Mesh.get_jmat(i,1,2)*Mesh.get_jmat(i,2,1) + Mesh.get_jmat(i,1,1)*Mesh.get_jmat(i,2,2))*phi_xieta.get(m,k) + Mesh.get_jmat(i,1,2)*Mesh.get_jmat(i,2,2)*phi_eta2.get(m,k) ); phi_yy.set(m,k, Mesh.get_jmat(i,2,1)*Mesh.get_jmat(i,2,1)*phi_xi2.get(m,k) + Mesh.get_jmat(i,2,1)*Mesh.get_jmat(i,2,2)*phi_xieta.get(m,k) + Mesh.get_jmat(i,2,2)*Mesh.get_jmat(i,2,2)*phi_eta2.get(m,k) ); } // point on the unit triangle const double s = spts.get(m,1); const double t = spts.get(m,2); // point on the physical triangle xpts.set(m,1, xc + (x2-x1)*s + (x3-x1)*t ); xpts.set(m,2, yc + (y2-y1)*s + (y3-y1)*t ); // 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<=kmax_qin; 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<=kmax_auxin; k++) { auxvals.set(m,ma, auxvals.get(m,ma) + phi.get(m,k) * auxin->get(i,ma,k) ); } } } // ----------------------------------------------------------------- // // // Part I: // // Project the flux function onto the basis // functions. This is the term of order O( 1 ) in the // "time-averaged" Taylor expansion of f and g. // // ----------------------------------------------------------------- // // Call user-supplied function to set fvals FluxFunc(xpts, qvals, auxvals, fvals); // Evaluate integral on current cell (project onto Legendre basis) // using Gaussian Quadrature for the integration // // TODO - do we want to optimize this by looking into using transposes, // as has been done in the 2d/cart code? (5/14/2014) -DS for (int me=1; me<=mcomps_out; me++) for (int k=1; k<=kmax; k++) { double tmp1 = 0.0; double tmp2 = 0.0; for (int mp=1; mp <= mpoints; mp++) { tmp1 += wgts.get(mp)*fvals.get(mp, me, 1)*phi.get(mp, k); tmp2 += wgts.get(mp)*fvals.get(mp, me, 2)*phi.get(mp, k); } F->set(i, me, k, 2.0*tmp1 ); G->set(i, me, k, 2.0*tmp2 ); } // ----------------------------------------------------------------- // // // Part II: // // Project the derivative of the flux function onto the basis // functions. This is the term of order O( \dt ) in the // "time-averaged" Taylor expansion of f and g. // // ----------------------------------------------------------------- // // ----------------------------------------------------------------- // // Compute pointwise values for fx+gy: // // We can't multiply fvals of f, and g, // by alpha, otherwise we compute the wrong derivative here! // dTensor2 fx_plus_gy( mpoints, meqn ); fx_plus_gy.setall(0.); for( int mp=1; mp <= mpoints; mp++ ) for( int me=1; me <= meqn; me++ ) { double tmp = 0.; for( int k=2; k <= kmax; k++ ) { tmp += F->get( i, me, k ) * phi_x.get( mp, k ); tmp += G->get( i, me, k ) * phi_y.get( mp, k ); } fx_plus_gy.set( mp, me, tmp ); } // Call user-supplied Jacobian to set f'(q) and g'(q): DFluxFunc( xpts, qvals, auxvals, A ); // place-holders for point values of // f'(q)( fx + gy ) and g'(q)( fx + gy ): dTensor2 dt_times_fdot( mpoints, meqn ); dTensor2 dt_times_gdot( mpoints, meqn ); // Compute point values for f'(q) * (fx+gy) and g'(q) * (fx+gy): for( int mp=1; mp <= mpoints; mp++ ) for( int m1=1; m1 <= meqn; m1++ ) { double tmp1 = 0.; double tmp2 = 0.; for( int m2=1; m2 <= meqn; m2++ ) { tmp1 += A.get(mp, m1, m2, 1 ) * fx_plus_gy.get(mp, m2); tmp2 += A.get(mp, m1, m2, 2 ) * fx_plus_gy.get(mp, m2); } dt_times_fdot.set( mp, m1, -beta_dt*tmp1 ); dt_times_gdot.set( mp, m1, -beta_dt*tmp2 ); } // --- Third-order terms --- // // // These are the terms that are O( \dt^2 ) in the "time-averaged" // flux function. dTensor2 f_tt( mpoints, meqn ); f_tt.setall(0.); dTensor2 g_tt( mpoints, meqn ); g_tt.setall(0.); if( mterms > 2 ) { // Construct the Hessian at each (quadrature) point D2FluxFunc( xpts, qvals, auxvals, H ); // Second-order derivative terms dTensor2 qx_vals (mpoints, meqn); qx_vals.setall(0.); dTensor2 qy_vals (mpoints, meqn); qy_vals.setall(0.); dTensor2 fxx_vals(mpoints, meqn); fxx_vals.setall(0.); dTensor2 gxx_vals(mpoints, meqn); gxx_vals.setall(0.); dTensor2 fxy_vals(mpoints, meqn); fxy_vals.setall(0.); dTensor2 gxy_vals(mpoints, meqn); gxy_vals.setall(0.); dTensor2 fyy_vals(mpoints, meqn); fyy_vals.setall(0.); dTensor2 gyy_vals(mpoints, meqn); gyy_vals.setall(0.); for( int m=1; m <= mpoints; m++ ) for( int me=1; me <= meqn; me++ ) { // Can start at k=1, because derivative of a constant is // zero. double tmp_qx = 0.; double tmp_qy = 0.; for( int k=2; k <= kmax; k++ ) { tmp_qx += phi_x.get(m,k) * qin->get(i,me,k); tmp_qy += phi_y.get(m,k) * qin->get(i,me,k); } qx_vals.set(m,me, tmp_qx ); qy_vals.set(m,me, tmp_qy ); // First non-zero terms start at third-order. for( int k=4; k <= kmax; k++ ) { fxx_vals.set(m,me, fxx_vals.get(m,me) + phi_xx.get(m,k)*F->get(i,me,k) ); gxx_vals.set(m,me, gxx_vals.get(m,me) + phi_xx.get(m,k)*G->get(i,me,k) ); fxy_vals.set(m,me, fxy_vals.get(m,me) + phi_xy.get(m,k)*F->get(i,me,k) ); gxy_vals.set(m,me, gxy_vals.get(m,me) + phi_xy.get(m,k)*G->get(i,me,k) ); fyy_vals.set(m,me, fyy_vals.get(m,me) + phi_yy.get(m,k)*F->get(i,me,k) ); gyy_vals.set(m,me, gyy_vals.get(m,me) + phi_yy.get(m,k)*G->get(i,me,k) ); } } // ----------------------------------- // // Part I: Compute (f_x + g_y)_{,t} // ----------------------------------- // // Compute terms that get multiplied by \pd2{ f }{ q } and \pd2{ g }{ q }. dTensor2 fx_plus_gy_t( mpoints, meqn ); for( int m = 1; m <= mpoints; m++ ) for( int me = 1; me <= meqn; me++ ) { double tmp = 0.; // Terms that get multiplied by the Hessian: for( int m1=1; m1 <= meqn; m1++ ) for( int m2=1; m2 <= meqn; m2++ ) { tmp += H.get(m,me,m1,m2,1)*qx_vals.get(m,m1)*fx_plus_gy.get(m,m2); tmp += H.get(m,me,m1,m2,2)*qy_vals.get(m,m1)*fx_plus_gy.get(m,m2); } // Terms that get multiplied by f'(q) and g'(q): for( int m1=1; m1 <= meqn; m1++ ) { tmp += A.get(m,me,m1,1)*( fxx_vals.get(m,m1)+gxy_vals.get(m,m1) ); tmp += A.get(m,me,m1,2)*( fxy_vals.get(m,m1)+gyy_vals.get(m,m1) ); } fx_plus_gy_t.set( m, me, tmp ); } // ----------------------------------- // // Part II: Compute // f'(q) * fx_plus_gy_t and // g'(q) * fx_plus_gy_t // ----------------------------------- // // Add in the third term that gets multiplied by A: for( int m=1; m <= mpoints; m++ ) for( int m1=1; m1 <= meqn; m1++ ) { double tmp1 = 0.; double tmp2 = 0.; for( int m2=1; m2 <= meqn; m2++ ) { tmp1 += A.get(m,m1,m2,1)*fx_plus_gy_t.get(m,m2); tmp2 += A.get(m,m1,m2,2)*fx_plus_gy_t.get(m,m2); } f_tt.set( m, m1, tmp1 ); g_tt.set( m, m1, tmp2 ); } // ----------------------------------------------- // // Part III: Add in contributions from // f''(q) * (fx_plus_gy, fx_plus_gy ) and // g''(q) * (fx_plus_gy, fx_plus_gy ). // ----------------------------------------------- // for( int m =1; m <= mpoints; m++ ) for( int me =1; me <= meqn; me++ ) { double tmp1 = 0.; double tmp2 = 0.; // Terms that get multiplied by the Hessian: for( int m1=1; m1 <= meqn; m1++ ) for( int m2=1; m2 <= meqn; m2++ ) { tmp1 += H.get(m,me,m1,m2,1)*fx_plus_gy.get(m,m1)*fx_plus_gy.get(m,m2); tmp2 += H.get(m,me,m1,m2,2)*fx_plus_gy.get(m,m1)*fx_plus_gy.get(m,m2); } f_tt.set( m, me, f_tt.get(m,me) + tmp1 ); g_tt.set( m, me, g_tt.get(m,me) + tmp2 ); } } // End of computing "third"-order terms // ---------------------------------------------------------- // // // Construct basis coefficients (integrate_on_current_cell) // // ---------------------------------------------------------- // for (int me=1; me<=mcomps_out; me++) for (int k=1; k<=kmax; k++) { double tmp1 = 0.0; double tmp2 = 0.0; for (int mp=1; mp<=mpoints; mp++) { tmp1 += wgts.get(mp)*phi.get(mp,k)*( dt_times_fdot.get(mp, me) + charlie_dt*f_tt.get(mp, me) ); tmp2 += wgts.get(mp)*phi.get(mp,k)*( dt_times_gdot.get(mp, me) + charlie_dt*g_tt.get(mp, me) ); } F->set(i,me,k, F->get(i,me,k) + 2.0*tmp1 ); G->set(i,me,k, G->get(i,me,k) + 2.0*tmp2 ); } } }