//! @brief Return the effective modal mass for the i-th mode. double XC::EigenSOE::getEffectiveModalMass(int i) const { const double tau= getModalParticipationFactor(i); const Vector ev= getEigenvector(i); const int sz= ev.Size(); boost::numeric::ublas::vector<double> fi_mode(sz); for(int i= 0;i<sz;i++) fi_mode(i)= ev(i); boost::numeric::ublas::vector<double> J(sz,1.0); const double p= boost::numeric::ublas::inner_prod(fi_mode,prod(massMatrix,J)); return tau*p; }
//! @brief Returns the modal participation factor for the mode. double XC::EigenSOE::getModalParticipationFactor(int mode) const { const Vector ev= getEigenvector(mode); const size_t sz= ev.Size(); if((massMatrix.size1()!=sz) || (massMatrix.size2()!=sz)) std::cerr << "EigenSOE::getModalParticipationFactor; ERROR " << "the eigenvector has dimension " << sz << " and the mass matrix " << massMatrix.size1() << "x" << massMatrix.size2() << ".\n"; boost::numeric::ublas::vector<double> fi_mode(sz); for(size_t i= 0;i<sz;i++) fi_mode(i)= ev(i); const boost::numeric::ublas::vector<double> J(sz,1.0); const double num= boost::numeric::ublas::inner_prod(fi_mode,prod(massMatrix,J)); const boost::numeric::ublas::vector<double> tmp= prod(massMatrix,fi_mode); const double denom= boost::numeric::ublas::inner_prod(fi_mode,tmp); return num/denom; }
//! @brief Returns the distribution factors for the i-th mode. XC::Vector XC::EigenSOE::getDistributionFactor(int i) const { return getModalParticipationFactor(i)*getEigenvector(i); }
/*--------------------------------------------------- * Calculate the inviscid flux in x direction * ------------------------------------------------*/ void fluxF(double **rhs) { int i, ir, ii, il, j, jj, jr, ic, s, k, ik, iv; double ph[maxeqn], phi_N[maxeqn], dsm[5], dsp[5], Fplus[6][maxeqn], UU[maxeqn], Fminus[6][maxeqn], dFplus[5][maxeqn], dFminus[5][maxeqn], LF[maxeqn], qave[maxeqn], f06[maxeqn], le[maxeqn][maxeqn], re[maxeqn][maxeqn], phip, phim, sum1, sum2, sum3, c, alf, maxLamda, pave, tave, gave, te, temp, xix, xiy, yas; double lf[6] = {0., -1./12., 7./12., 7./12., -1./12., 0.}; void boundX(); double phin(double fa, double fb, double fc, double fd); void allocateFlux(int nlen, struct strct_flux *f); void freeFlux(int nlen, struct strct_flux *f); void getEigenvector(double qave[], double p, double t, double ga, double kx, double ky, double (*le)[maxeqn], double (*re)[maxeqn]); ir = config1.ni + config1.Ng; jr = config1.nj + config1.Ng; boundX(); allocateFlux(I0, &U1d); for(j=config1.Ng; j<jr; j++) { for(i=0; i<I0; i++) { /*---- convert to 1D-array ----*/ ic = i*J0 + j; U1d.yas[i] = mesh.yaks[ic]; U1d.xix[i] = mesh.y_et[ic]/U1d.yas[i]; U1d.xiy[i] = -mesh.x_et[ic]/U1d.yas[i]; U1d.rho[i] = Ug.q[ic][0]; U1d.u[i] = Ug.q[ic][1]; U1d.v[i] = Ug.q[ic][2]; U1d.e[i] = Ug.q[ic][3]; U1d.p[i] = Ug.pre[ic]; U1d.t[i] = Ug.tem[ic]; U1d.gam[i] = Ug.gam[ic]; } il = config1.Ng - 1; for(i = il; i<ir; i++) // loop for all the i faces { /*---- 1. obtain the averaged value ----*/ xix = 0.5*(U1d.xix[i] + U1d.xix[i+1]); xiy = 0.5*(U1d.xiy[i] + U1d.xiy[i+1]); yas = 0.5*(U1d.yas[i] + U1d.yas[i+1]); pave = 0.5*(U1d.p[i] + U1d.p[i+1]); tave = 0.5*(U1d.t[i] + U1d.t[i+1]); gave = 0.5*(U1d.gam[i] + U1d.gam[i+1]); qave[0] = 0.5*(U1d.rho[i] + U1d.rho[i+1]); qave[1] = 0.5*(U1d.u[i] + U1d.u[i+1]); qave[2] = 0.5*(U1d.v[i] + U1d.v[i+1]); qave[3] = 0.5*(U1d.e[i] + U1d.e[i+1]); /*---- 2. calculate eigenvector ----*/ getEigenvector(qave,pave,tave,gave,xix,xiy,le,re); /*---- 3. calculate split Flux and central term from the six stencils cells ----*/ maxLamda = 0.; for(k=0; k<=5; k++) { ik = i-2 + k; te = U1d.u[ik]*U1d.xix[ik] + U1d.v[ik]*U1d.xiy[ik]; alf = sqrt(U1d.xix[ik]*U1d.xix[ik] + U1d.xiy[ik]*U1d.xiy[ik]); c = sqrt(U1d.gam[ik]*U1d.p[ik]/U1d.rho[ik]); temp = fabs(te) + c*alf; if(temp > maxLamda) maxLamda = temp; } for(iv=0; iv<neqn; iv++) LF[iv] = 0.; for(k=0; k<=5; k++) { ik = i-2 + k; /* i-2, i-1, i, i+1, i+2, i+3. * The corresponding cells begin with 2-2 = 0, * end with (NI+2)+3 = NI+5 */ te = U1d.u[ik]*U1d.xix[ik] + U1d.v[ik]*U1d.xiy[ik]; f06[0] = U1d.yas[ik] * U1d.rho[ik]*te; f06[1] = U1d.yas[ik] * (U1d.rho[ik]*U1d.u[ik]*te + U1d.xix[ik]*U1d.p[ik]); f06[2] = U1d.yas[ik] * (U1d.rho[ik]*U1d.v[ik]*te + U1d.xiy[ik]*U1d.p[ik]); f06[3] = U1d.yas[ik] * (U1d.rho[ik]*U1d.e[ik] + U1d.p[ik])*te; UU[0] = U1d.rho[ik]; UU[1] = U1d.rho[ik]*U1d.u[ik]; UU[2] = U1d.rho[ik]*U1d.v[ik]; UU[3] = U1d.rho[ik]*U1d.e[ik]; for(iv=0; iv<neqn; iv++) { Fplus[k][iv] = 0.5*(f06[iv] + maxLamda*UU[iv]*yas); Fminus[k][iv] = 0.5*(f06[iv] - maxLamda*UU[iv]*yas); LF[iv] = LF[iv] + lf[k]*f06[iv]; } } /*---- 4. calculate delta flux ----*/ for(k=0; k<=4; k++) for(iv=0; iv<neqn; iv++) { dFplus[k][iv] = Fplus[k+1][iv] - Fplus[k][iv]; dFminus[k][iv] = Fminus[k+1][iv] - Fminus[k][iv]; } /*---- 5. Approximate the fluxes in local characteristic field ----*/ for(s=0; s<neqn; s++) { for(k=0; k<=4; k++) { sum1 = 0.; sum2 = 0.; for (iv = 0; iv<neqn; iv++) { sum1 = sum1 + dFplus[k][iv]*le[s][iv]; sum2 = sum2 + dFminus[k][iv]*le[s][iv]; } dsp[k] = sum1; dsm[k] = sum2; } phip = phin(dsp[0], dsp[1], dsp[2], dsp[3]); phim = phin(dsm[4], dsm[3], dsm[2], dsm[1]); ph[s] = -phip + phim; } /*---- 6. Project back to the component space, get the upwind flux ----*/ for(s=0; s<neqn; s++) { sum3 = 0.; for(iv=0; iv<neqn; iv++) sum3 = sum3 + ph[iv]*re[s][iv]; phi_N[s] = sum3; } /*---- 7. get the final flux ----*/ for(iv=0; iv<neqn; iv++) U1d.flux[i][iv] = LF[iv] + phi_N[iv]; } jj = j-config1.Ng; for(i=config1.Ng; i<ir; i++) { ii = i - config1.Ng; ic = ii*config1.nj + jj; for(iv=0; iv<neqn; iv++) rhs[ic][iv] = - (U1d.flux[i][iv] - U1d.flux[i-1][iv])/dxc; } } freeFlux(I0, &U1d); }
/*--------------------------------------------------- * Calculate the inviscid flux in y direction * ------------------------------------------------*/ void fluxG(double **rhs) { int i, ir, ii, j, jr, jj, jl, ic, s, k, jk, iv; double ph[maxeqn], phi_N[maxeqn], dsm[5], dsp[5], Fplus[6][maxeqn], UU[maxeqn], Fminus[6][maxeqn], dFplus[5][maxeqn] , dFminus[5][maxeqn], LF[maxeqn], qave[maxeqn], f06[maxeqn], le[maxeqn][maxeqn], re[maxeqn][maxeqn], phip, phim, sum1, sum2, sum3, c, alf, maxLamda, pave, tave, gave, te, temp, etx, ety, yas; double lf[6] = {0., -1./12., 7./12., 7./12., -1./12., 0.}; double phin(double fa, double fb, double fc, double fd); void boundY(); void allocateFlux(int nlen, struct strct_flux *f); void freeFlux(int nlen, struct strct_flux *f); void getEigenvector(double qave[], double p, double t, double ga, double kx, double ky, double (*le)[maxeqn], double (*re)[maxeqn]); ir = config1.ni + config1.Ng; jr = config1.nj + config1.Ng; boundY(); allocateFlux(J0,&U1d); for(i=config1.Ng; i<ir; i++) { for(j=0; j<J0; j++) { /*---- convert to 1D-array ----*/ ic = i*J0 + j; U1d.yas[j] = mesh.yaks[ic]; U1d.etx[j] = -mesh.y_xi[ic]/U1d.yas[j]; U1d.ety[j] = mesh.x_xi[ic]/U1d.yas[j]; U1d.rho[j] = Ug.q[ic][0]; U1d.u[j] = Ug.q[ic][1]; U1d.v[j] = Ug.q[ic][2]; U1d.e[j] = Ug.q[ic][3]; U1d.p[j] = Ug.pre[ic]; U1d.t[j] = Ug.tem[ic]; U1d.gam[j] = Ug.gam[ic]; } jl = config1.Ng - 1; for(j=jl; j<jr; j++) // loop for j faces { etx = 0.5*(U1d.etx[j] + U1d.etx[j+1]); ety = 0.5*(U1d.ety[j] + U1d.ety[j+1]); yas = 0.5*(U1d.yas[j] + U1d.yas[j+1]); pave = 0.5*(U1d.p[j] + U1d.p[j+1]); tave = 0.5*(U1d.t[j] + U1d.t[j+1]); gave = 0.5*(U1d.gam[j] + U1d.gam[j+1]); qave[0] = 0.5*(U1d.rho[j] + U1d.rho[j+1]); qave[1] = 0.5*(U1d.u[j] + U1d.u[j+1]); qave[2] = 0.5*(U1d.v[j] + U1d.v[j+1]); qave[3] = 0.5*(U1d.e[j] + U1d.e[j+1]); getEigenvector(qave,pave,tave,gave,etx,ety,le,re); maxLamda = 0.; for(k=0; k<=5; k++) { jk = j-2 + k; te = U1d.u[jk]*U1d.etx[jk] + U1d.v[jk]*U1d.ety[jk]; alf = sqrt(U1d.etx[jk]*U1d.etx[jk] + U1d.ety[jk]*U1d.ety[jk]); c = sqrt(U1d.gam[jk]*U1d.p[jk]/(U1d.rho[jk])); temp = fabs(te) + c*alf; if(temp > maxLamda) maxLamda = temp; } for(iv=0; iv<neqn; iv++) LF[iv] = 0.; for(k=0; k<=5; k++) { jk = j-2 + k; te = U1d.u[jk]*U1d.etx[jk] + U1d.v[jk]*U1d.ety[jk]; f06[0] = U1d.yas[jk] * U1d.rho[jk]*te; f06[1] = U1d.yas[jk] * (U1d.rho[jk]*U1d.u[jk]*te + U1d.etx[jk]*U1d.p[jk]); f06[2] = U1d.yas[jk] * (U1d.rho[jk]*U1d.v[jk]*te + U1d.ety[jk]*U1d.p[jk]); f06[3] = U1d.yas[jk] * (U1d.rho[jk]*U1d.e[jk] + U1d.p[jk])*te; UU[0] = U1d.rho[jk]; UU[1] = U1d.rho[jk]*U1d.u[jk]; UU[2] = U1d.rho[jk]*U1d.v[jk]; UU[3] = U1d.rho[jk]*U1d.e[jk]; for(iv=0; iv<neqn; iv++) { Fplus[k][iv] = 0.5*(f06[iv] + maxLamda*UU[iv]*yas); Fminus[k][iv] = 0.5*(f06[iv] - maxLamda*UU[iv]*yas); LF[iv] = LF[iv] + lf[k]*f06[iv]; } } for(k=0; k<=4; k++) for(iv = 0; iv<neqn; iv++) { dFplus[k][iv] = Fplus[k+1][iv] - Fplus[k][iv]; dFminus[k][iv] = Fminus[k+1][iv] - Fminus[k][iv]; } for(s=0; s<neqn; s++) { for(k=0; k<=4; k++) { sum1 = 0.; sum2 = 0.; for (iv=0; iv<neqn; iv++) { sum1 = sum1 + dFplus[k][iv]*le[s][iv]; sum2 = sum2 + dFminus[k][iv]*le[s][iv]; } dsp[k] = sum1; dsm[k] = sum2; } phip = phin(dsp[0], dsp[1], dsp[2], dsp[3]); phim = phin(dsm[4], dsm[3], dsm[2], dsm[1]); ph[s] = -phip + phim; } for(s=0; s<neqn; s++) { sum3 = 0.; for(iv = 0; iv<neqn; iv++) sum3 = sum3 + ph[iv]*re[s][iv]; phi_N[s] = sum3; } for(iv=0; iv<neqn; iv++) U1d.flux[j][iv] = LF[iv] + phi_N[iv]; } ii = i - config1.Ng; for(j=config1.Ng; j<jr; j++) { jj = j - config1.Ng; ic = ii*config1.nj + jj; for(iv=0; iv<neqn; iv++) rhs[ic][iv] = rhs[ic][iv] -(U1d.flux[j][iv] - U1d.flux[j-1][iv])/dyc; } } freeFlux(J0, &U1d); }