doublereal LiquidTransport::getElectricConduct() { vector_fp gradT(m_nDim,0.0); vector_fp gradX(m_nDim * m_nsp); vector_fp gradV(m_nDim); for (size_t i = 0; i < m_nDim; i++) { for (size_t k = 0; k < m_nsp; k++) { gradX[ i*m_nDim + k] = 0.0; } gradV[i] = 1.0; } set_Grad_T(&gradT[0]); set_Grad_X(&gradX[0]); set_Grad_V(&gradV[0]); vector_fp fluxes(m_nsp * m_nDim); doublereal current; getSpeciesFluxesExt(m_nDim, &fluxes[0]); //sum over species charges, fluxes, Faraday to get current // Since we want the scalar conductivity, we need only consider one-dim for (size_t i = 0; i < 1; i++) { current = 0.0; for (size_t k = 0; k < m_nsp; k++) { current += m_chargeSpecies[k] * Faraday * fluxes[k] / m_mw[k]; } //divide by unit potential gradient current /= - gradV[i]; } return current; }
void softAbsMetric::fPrepareSpatialGradients() { // Compute the discrete Jacobian of the SoftAbs transform double delta = 0; double lambda = 0; double alphaLambda = 0; double sdx = 0; for(int i = 0; i < mDim; ++i) { for(int j = 0; j <= i; ++j) { delta = mEigenDeco.eigenvalues()(i) - mEigenDeco.eigenvalues()(j); if(fabs(delta) < 1e-10) { lambda = mEigenDeco.eigenvalues()(i); alphaLambda = mSoftAbsAlpha * lambda; if(fabs(alphaLambda) < 1e-4) { mPseudoJ(i, j) = (2.0 / 3.0) * alphaLambda * (1.0 - (2.0 / 15.0) * alphaLambda * alphaLambda); } else if(fabs(alphaLambda) > 18) { mPseudoJ(i, j) = lambda > 0 ? 1 : -1; } else { sdx = sinh(mSoftAbsAlpha * lambda) / lambda; mPseudoJ(i, j) = (mSoftAbsLambda(i) - mSoftAbsAlpha / (sdx * sdx) ) / lambda; } } else { mPseudoJ(i, j) = ( mSoftAbsLambda(i) - mSoftAbsLambda(j) ) / delta; } } } // And make sure the gradient has been calculated gradV(); // Along with the third-derivative tensor for(int i = 0; i < mDim; ++i) fComputeGradH(i); }
void constMetric::fEvolveP(const double epsilon) { mP -= epsilon * gradV(); }
void FilterAeroForces::v_Update( const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields, const NekDouble &time) { // Only output every m_outputFrequency. if ((m_index++) % m_outputFrequency) { return; } int n, cnt, elmtid, nq, offset, nt, boundary; nt = pFields[0]->GetNpoints(); int dim = pFields.num_elements()-1; StdRegions::StdExpansionSharedPtr elmt; Array<OneD, int> BoundarytoElmtID; Array<OneD, int> BoundarytoTraceID; Array<OneD, MultiRegions::ExpListSharedPtr> BndExp; Array<OneD, const NekDouble> P(nt); Array<OneD, const NekDouble> U(nt); Array<OneD, const NekDouble> V(nt); Array<OneD, const NekDouble> W(nt); Array<OneD, Array<OneD, NekDouble> > gradU(dim); Array<OneD, Array<OneD, NekDouble> > gradV(dim); Array<OneD, Array<OneD, NekDouble> > gradW(dim); Array<OneD, Array<OneD, NekDouble> > fgradU(dim); Array<OneD, Array<OneD, NekDouble> > fgradV(dim); Array<OneD, Array<OneD, NekDouble> > fgradW(dim); Array<OneD, NekDouble> values; LibUtilities::CommSharedPtr vComm = pFields[0]->GetComm(); NekDouble Fx,Fy,Fz,Fxp,Fxv,Fyp,Fyv,Fzp,Fzv; Fxp = 0.0; // x-component of the force due to pressure difference Fxv = 0.0; // x-component of the force due to viscous stress Fx = 0.0; // x-component of the force (total) Fx = Fxp + Fxv (Drag) Fyp = 0.0; // y-component of the force due to pressure difference Fyv = 0.0; // y-component of the force due to viscous stress Fy = 0.0; // y-component of the force (total) Fy = Fyp + Fyv (Lift) Fzp = 0.0; // z-component of the force due to pressure difference Fzv = 0.0; // z-component of the force due to viscous stress Fz = 0.0; // z-component of the force (total) Fz = Fzp + Fzv (Side) NekDouble rho = (m_session->DefinesParameter("rho")) ? (m_session->GetParameter("rho")) : 1; NekDouble mu = rho*m_session->GetParameter("Kinvis"); for(int i = 0; i < pFields.num_elements(); ++i) { pFields[i]->SetWaveSpace(false); pFields[i]->BwdTrans(pFields[i]->GetCoeffs(), pFields[i]->UpdatePhys()); pFields[i]->SetPhysState(true); } // Homogeneous 1D case Compute forces on all WALL boundaries // This only has to be done on the zero (mean) Fourier mode. if(m_isHomogeneous1D) { if(vComm->GetColumnComm()->GetRank() == 0) { pFields[0]->GetPlane(0)->GetBoundaryToElmtMap( BoundarytoElmtID,BoundarytoTraceID); BndExp = pFields[0]->GetPlane(0)->GetBndCondExpansions(); StdRegions::StdExpansion1DSharedPtr bc; // loop over the types of boundary conditions for(cnt = n = 0; n < BndExp.num_elements(); ++n) { if(m_boundaryRegionIsInList[n] == 1) { for(int i = 0; i < BndExp[n]->GetExpSize(); ++i, cnt++) { // find element of this expansion. elmtid = BoundarytoElmtID[cnt]; elmt = pFields[0]->GetPlane(0)->GetExp(elmtid); nq = elmt->GetTotPoints(); offset = pFields[0]->GetPlane(0)->GetPhys_Offset(elmtid); // Initialise local arrays for the velocity // gradients size of total number of quadrature // points for each element (hence local). for(int j = 0; j < dim; ++j) { gradU[j] = Array<OneD, NekDouble>(nq,0.0); gradV[j] = Array<OneD, NekDouble>(nq,0.0); gradW[j] = Array<OneD, NekDouble>(nq,0.0); } // identify boundary of element boundary = BoundarytoTraceID[cnt]; // Extract fields U = pFields[0]->GetPlane(0)->GetPhys() + offset; V = pFields[1]->GetPlane(0)->GetPhys() + offset; P = pFields[3]->GetPlane(0)->GetPhys() + offset; // compute the gradients elmt->PhysDeriv(U,gradU[0],gradU[1]); elmt->PhysDeriv(V,gradV[0],gradV[1]); // Get face 1D expansion from element expansion bc = boost::dynamic_pointer_cast<LocalRegions ::Expansion1D> (BndExp[n]->GetExp(i)); // number of points on the boundary int nbc = bc->GetTotPoints(); // several vectors for computing the forces Array<OneD, NekDouble> Pb(nbc,0.0); for(int j = 0; j < dim; ++j) { fgradU[j] = Array<OneD, NekDouble>(nbc,0.0); fgradV[j] = Array<OneD, NekDouble>(nbc,0.0); } Array<OneD, NekDouble> drag_t(nbc,0.0); Array<OneD, NekDouble> lift_t(nbc,0.0); Array<OneD, NekDouble> drag_p(nbc,0.0); Array<OneD, NekDouble> lift_p(nbc,0.0); Array<OneD, NekDouble> temp(nbc,0.0); Array<OneD, NekDouble> temp2(nbc,0.0); // identify boundary of element . boundary = BoundarytoTraceID[cnt]; // extraction of the pressure and wss on the // boundary of the element elmt->GetEdgePhysVals(boundary,bc,P,Pb); for(int j = 0; j < dim; ++j) { elmt->GetEdgePhysVals(boundary,bc,gradU[j], fgradU[j]); elmt->GetEdgePhysVals(boundary,bc,gradV[j], fgradV[j]); } //normals of the element const Array<OneD, Array<OneD, NekDouble> > &normals = elmt->GetEdgeNormal(boundary); // // Compute viscous tractive forces on wall from // // t_i = - T_ij * n_j (minus sign for force // exerted BY fluid ON wall), // // where // // T_ij = viscous stress tensor (here in Cartesian // coords) // dU_i dU_j // = RHO * KINVIS * ( ---- + ---- ) . // dx_j dx_i //a) DRAG TERMS //-rho*kinvis*(2*du/dx*nx+(du/dy+dv/dx)*ny Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,drag_t,1); Vmath::Vmul(nbc,drag_t,1,normals[1],1,drag_t,1); Vmath::Smul(nbc,2.0,fgradU[0],1,fgradU[0],1); Vmath::Vmul(nbc,fgradU[0],1,normals[0],1,temp2,1); Vmath::Smul(nbc,0.5,fgradU[0],1,fgradU[0],1); Vmath::Vadd(nbc,temp2,1,drag_t,1,drag_t,1); Vmath::Smul(nbc,-mu,drag_t,1,drag_t,1); //zero temporary storage vector Vmath::Zero(nbc,temp,0); Vmath::Zero(nbc,temp2,0); //b) LIFT TERMS //-rho*kinvis*(2*dv/dy*nx+(du/dy+dv/dx)*nx Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,lift_t,1); Vmath::Vmul(nbc,lift_t,1,normals[0],1,lift_t,1); Vmath::Smul(nbc,2.0,fgradV[1],1,fgradV[1],1); Vmath::Vmul(nbc,fgradV[1],1,normals[1],1,temp2,1); Vmath::Smul(nbc,-0.5,fgradV[1],1,fgradV[1],1); Vmath::Vadd(nbc,temp2,1,lift_t,1,lift_t,1); Vmath::Smul(nbc,-mu,lift_t,1,lift_t,1); // Compute normal tractive forces on all WALL // boundaries Vmath::Vvtvp(nbc,Pb,1,normals[0],1, drag_p,1,drag_p, 1); Vmath::Vvtvp(nbc,Pb,1,normals[1],1, lift_p,1,lift_p,1); //integration over the boundary Fxv += bc->Integral(drag_t); Fyv += bc->Integral(lift_t); Fxp += bc->Integral(drag_p); Fyp += bc->Integral(lift_p); } } else { cnt += BndExp[n]->GetExpSize(); } } } for(int i = 0; i < pFields.num_elements(); ++i) { pFields[i]->SetWaveSpace(true); pFields[i]->BwdTrans(pFields[i]->GetCoeffs(), pFields[i]->UpdatePhys()); pFields[i]->SetPhysState(false); } } //3D WALL case else if(dim==3 && !m_isHomogeneous1D) { pFields[0]->GetBoundaryToElmtMap(BoundarytoElmtID, BoundarytoTraceID); BndExp = pFields[0]->GetBndCondExpansions(); LocalRegions::Expansion2DSharedPtr bc; // loop over the types of boundary conditions for(cnt = n = 0; n < BndExp.num_elements(); ++n) { if(m_boundaryRegionIsInList[n] == 1) { for(int i = 0; i < BndExp[n]->GetExpSize(); ++i, cnt++) { // find element of this expansion. elmtid = BoundarytoElmtID[cnt]; elmt = pFields[0]->GetExp(elmtid); nq = elmt->GetTotPoints(); offset = pFields[0]->GetPhys_Offset(elmtid); // Initialise local arrays for the velocity // gradients size of total number of quadrature // points for each element (hence local). for(int j = 0; j < dim; ++j) { gradU[j] = Array<OneD, NekDouble>(nq,0.0); gradV[j] = Array<OneD, NekDouble>(nq,0.0); gradW[j] = Array<OneD, NekDouble>(nq,0.0); } //identify boundary of element boundary = BoundarytoTraceID[cnt]; //Extract fields U = pFields[0]->GetPhys() + offset; V = pFields[1]->GetPhys() + offset; W = pFields[2]->GetPhys() + offset; P = pFields[3]->GetPhys() + offset; //compute the gradients elmt->PhysDeriv(U,gradU[0],gradU[1],gradU[2]); elmt->PhysDeriv(V,gradV[0],gradV[1],gradV[2]); elmt->PhysDeriv(W,gradW[0],gradW[1],gradW[2]); // Get face 2D expansion from element expansion bc = boost::dynamic_pointer_cast<LocalRegions ::Expansion2D> (BndExp[n]->GetExp(i)); //number of points on the boundary int nbc = bc->GetTotPoints(); //several vectors for computing the forces Array<OneD, NekDouble> Pb(nbc,0.0); for(int j = 0; j < dim; ++j) { fgradU[j] = Array<OneD, NekDouble>(nbc,0.0); fgradV[j] = Array<OneD, NekDouble>(nbc,0.0); fgradW[j] = Array<OneD, NekDouble>(nbc,0.0); } Array<OneD, NekDouble> drag_t(nbc,0.0); Array<OneD, NekDouble> lift_t(nbc,0.0); Array<OneD, NekDouble> side_t(nbc,0.0); Array<OneD, NekDouble> drag_p(nbc,0.0); Array<OneD, NekDouble> lift_p(nbc,0.0); Array<OneD, NekDouble> side_p(nbc,0.0); Array<OneD, NekDouble> temp(nbc,0.0); Array<OneD, NekDouble> temp2(nbc,0.0); // identify boundary of element . boundary = BoundarytoTraceID[cnt]; // extraction of the pressure and wss on the // boundary of the element elmt->GetFacePhysVals(boundary,bc,P,Pb); for(int j = 0; j < dim; ++j) { elmt->GetFacePhysVals(boundary,bc,gradU[j], fgradU[j]); elmt->GetFacePhysVals(boundary,bc,gradV[j], fgradV[j]); elmt->GetFacePhysVals(boundary,bc,gradW[j], fgradW[j]); } // normals of the element const Array<OneD, Array<OneD, NekDouble> > &normals = elmt->GetFaceNormal(boundary); // // Compute viscous tractive forces on wall from // // t_i = - T_ij * n_j (minus sign for force // exerted BY fluid ON wall), // // where // // T_ij = viscous stress tensor (here in Cartesian // coords) // dU_i dU_j // = RHO * KINVIS * ( ---- + ---- ) . // dx_j dx_i //a) DRAG TERMS //-rho*kinvis* // (2*du/dx*nx+(du/dy+dv/dx)*ny+(du/dz+dw/dx)*nz) Vmath::Vadd(nbc,fgradU[2],1,fgradW[0],1,temp,1); Vmath::Neg(nbc,temp,1); Vmath::Vmul(nbc,temp,1,normals[2],1,temp,1); Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,drag_t,1); Vmath::Neg(nbc,drag_t,1); Vmath::Vmul(nbc,drag_t,1,normals[1],1,drag_t,1); Vmath::Smul(nbc,-2.0,fgradU[0],1,fgradU[0],1); Vmath::Vmul(nbc,fgradU[0],1,normals[0],1,temp2,1); Vmath::Smul(nbc,-0.5,fgradU[0],1,fgradU[0],1); Vmath::Vadd(nbc,temp,1,temp2,1,temp,1); Vmath::Vadd(nbc,temp,1,drag_t,1,drag_t,1); Vmath::Smul(nbc,mu,drag_t,1,drag_t,1); //zero temporary storage vector Vmath::Zero(nbc,temp,0); Vmath::Zero(nbc,temp2,0); //b) LIFT TERMS //-rho*kinvis* // (2*dv/dy*nx+(du/dy+dv/dx)*nx+(dv/dz+dw/dy)*nz) Vmath::Vadd(nbc,fgradV[2],1,fgradW[1],1,temp,1); Vmath::Neg(nbc,temp,1); Vmath::Vmul(nbc,temp,1,normals[2],1,temp,1); Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,lift_t,1); Vmath::Neg(nbc,lift_t,1); Vmath::Vmul(nbc,lift_t,1,normals[0],1,lift_t,1); Vmath::Smul(nbc,-2.0,fgradV[1],1,fgradV[1],1); Vmath::Vmul(nbc,fgradV[1],1,normals[1],1,temp2,1); Vmath::Smul(nbc,-0.5,fgradV[1],1,fgradV[1],1); Vmath::Vadd(nbc,temp,1,temp2,1,temp,1); Vmath::Vadd(nbc,temp,1,lift_t,1,lift_t,1); Vmath::Smul(nbc,mu,lift_t,1,lift_t,1); //zero temporary storage vector Vmath::Zero(nbc,temp,0); Vmath::Zero(nbc,temp2,0); //b) SIDE TERMS //-rho*kinvis* // (2*dv/dy*nx+(du/dy+dv/dx)*nx+(dv/dz+dw/dy)*nz) Vmath::Vadd(nbc,fgradV[2],1,fgradW[1],1,temp,1); Vmath::Neg(nbc,temp,1); Vmath::Vmul(nbc,temp,1,normals[1],1,temp,1); Vmath::Vadd(nbc,fgradU[2],1,fgradW[0],1,side_t,1); Vmath::Neg(nbc,side_t,1); Vmath::Vmul(nbc,side_t,1,normals[0],1,side_t,1); Vmath::Smul(nbc,-2.0,fgradW[2],1,fgradW[2],1); Vmath::Vmul(nbc,fgradW[2],1,normals[2],1,temp2,1); Vmath::Smul(nbc,-0.5,fgradW[2],1,fgradW[2],1); Vmath::Vadd(nbc,temp,1,temp2,1,temp,1); Vmath::Vadd(nbc,temp,1,side_t,1,side_t,1); Vmath::Smul(nbc,mu,side_t,1,side_t,1); // Compute normal tractive forces on all WALL // boundaries Vmath::Vvtvp(nbc,Pb,1,normals[0],1, drag_p,1,drag_p,1); Vmath::Vvtvp(nbc,Pb,1,normals[1],1, lift_p,1,lift_p,1); Vmath::Vvtvp(nbc,Pb,1,normals[2],1, side_p,1,side_p,1); //integration over the boundary Fxv += bc->Expansion::Integral(drag_t); Fyv += bc->Expansion::Integral(lift_t); Fzv += bc->Expansion::Integral(side_t); Fxp += bc->Expansion::Integral(drag_p); Fyp += bc->Expansion::Integral(lift_p); Fzp += bc->Expansion::Integral(side_p); } } else { cnt += BndExp[n]->GetExpSize(); } } } //2D WALL Condition else { pFields[0]->GetBoundaryToElmtMap(BoundarytoElmtID, BoundarytoTraceID); BndExp = pFields[0]->GetBndCondExpansions(); StdRegions::StdExpansion1DSharedPtr bc; // loop over the types of boundary conditions for(cnt = n = 0; n < BndExp.num_elements(); ++n) { if(m_boundaryRegionIsInList[n] == 1) { for(int i = 0; i < BndExp[n]->GetExpSize(); ++i, cnt++) { elmtid = BoundarytoElmtID[cnt]; elmt = pFields[0]->GetExp(elmtid); nq = elmt->GetTotPoints(); offset = pFields[0]->GetPhys_Offset(elmtid); for(int j = 0; j < dim; ++j) { gradU[j] = Array<OneD, NekDouble>(nq,0.0); gradV[j] = Array<OneD, NekDouble>(nq,0.0); } boundary = BoundarytoTraceID[cnt]; U = pFields[0]->GetPhys() + offset; V = pFields[1]->GetPhys() + offset; P = pFields[2]->GetPhys() + offset; elmt->PhysDeriv(U,gradU[0],gradU[1]); elmt->PhysDeriv(V,gradV[0],gradV[1]); bc = boost::dynamic_pointer_cast<LocalRegions ::Expansion1D> (BndExp[n]->GetExp(i)); int nbc = bc->GetTotPoints(); Array<OneD, NekDouble> Pb(nbc,0.0); Array<OneD, NekDouble> drag_t(nbc,0.0); Array<OneD, NekDouble> lift_t(nbc,0.0); Array<OneD, NekDouble> drag_p(nbc,0.0); Array<OneD, NekDouble> lift_p(nbc,0.0); Array<OneD, NekDouble> temp(nbc,0.0); boundary = BoundarytoTraceID[cnt]; elmt->GetEdgePhysVals(boundary,bc,P,Pb); for(int j = 0; j < dim; ++j) { fgradU[j] = Array<OneD, NekDouble>(nbc,0.0); fgradV[j] = Array<OneD, NekDouble>(nbc,0.0); } for(int j = 0; j < dim; ++j) { elmt->GetEdgePhysVals(boundary,bc,gradU[j], fgradU[j]); elmt->GetEdgePhysVals(boundary,bc,gradV[j], fgradV[j]); } const Array<OneD, Array<OneD, NekDouble> > &normals = elmt->GetEdgeNormal(boundary); Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,drag_t,1); Vmath::Neg(nbc,drag_t,1); Vmath::Vmul(nbc,drag_t,1,normals[1],1,drag_t,1); Vmath::Smul(nbc,-2.0,fgradU[0],1,fgradU[0],1); Vmath::Vmul(nbc,fgradU[0],1,normals[0],1,temp,1); Vmath::Vadd(nbc,temp,1,drag_t,1,drag_t,1); Vmath::Smul(nbc,mu,drag_t,1,drag_t,1); Vmath::Vadd(nbc,fgradU[1],1,fgradV[0],1,lift_t,1); Vmath::Neg(nbc,lift_t,1); Vmath::Vmul(nbc,lift_t,1,normals[0],1,lift_t,1); Vmath::Smul(nbc,-2.0,fgradV[1],1,fgradV[1],1); Vmath::Vmul(nbc,fgradV[1],1,normals[1],1,temp,1); Vmath::Vadd(nbc,temp,1,lift_t,1,lift_t,1); Vmath::Smul(nbc,mu,lift_t,1,lift_t,1); Vmath::Vvtvp(nbc,Pb,1,normals[0],1, drag_p,1,drag_p,1); Vmath::Vvtvp(nbc,Pb,1,normals[1],1, lift_p,1,lift_p,1); Fxp += bc->Integral(drag_p); Fyp += bc->Integral(lift_p); Fxv += bc->Integral(drag_t); Fyp += bc->Integral(lift_t); } } else { cnt += BndExp[n]->GetExpSize(); } } } vComm->AllReduce(Fxp, LibUtilities::ReduceSum); vComm->AllReduce(Fxv, LibUtilities::ReduceSum); Fx = Fxp + Fxv; vComm->AllReduce(Fyp, LibUtilities::ReduceSum); vComm->AllReduce(Fyv, LibUtilities::ReduceSum); Fy = Fyp + Fyv; vComm->AllReduce(Fzp, LibUtilities::ReduceSum); vComm->AllReduce(Fzv, LibUtilities::ReduceSum); Fz = Fzp + Fzv; if (vComm->GetRank() == 0) { m_outputStream.width(8); m_outputStream << setprecision(6) << time; m_outputStream.width(25); m_outputStream << setprecision(8) << Fxp; m_outputStream.width(25); m_outputStream << setprecision(8) << Fxv; m_outputStream.width(25); m_outputStream << setprecision(8) << Fx; m_outputStream.width(25); m_outputStream << setprecision(8) << Fyp; m_outputStream.width(25); m_outputStream << setprecision(8) << Fyv; m_outputStream.width(25); m_outputStream << setprecision(8) << Fy; m_outputStream.width(25); m_outputStream << setprecision(8) << Fzp; m_outputStream.width(25); m_outputStream << setprecision(8) << Fzv; m_outputStream.width(25); m_outputStream << setprecision(8) << Fz; m_outputStream << endl; } }
void denseFisherMetric::checkEvolution(const double epsilon) { baseHamiltonian::checkEvolution(epsilon); // Metric std::cout.precision(6); int width = 12; int nColumn = 6; std::cout << "Gradient of the Fisher-Rao metric (dG^{jk}/dq^{i}):" << std::endl; std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; std::cout << " " << std::setw(width) << std::left << "Component" << std::setw(width) << std::left << "Row" << std::setw(width) << std::left << "Column" << std::setw(width) << std::left << "Analytic" << std::setw(width) << std::left << "Finite" << std::setw(width) << std::left << "Delta /" << std::endl; std::cout << " " << std::setw(width) << std::left << "(i)" << std::setw(width) << std::left << "(j)" << std::setw(width) << std::left << "(k)" << std::setw(width) << std::left << "Derivative" << std::setw(width) << std::left << "Difference" << std::setw(width) << std::left << "Stepsize^{2}" << std::endl; std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; for(int k = 0; k < mDim; ++k) { fComputeG(); fComputeGradG(k); MatrixXd temp = MatrixXd::Zero(mDim, mDim); mQ(k) += epsilon; fComputeG(); temp += mG; mQ(k) -= 2.0 * epsilon; fComputeG(); temp -= mG; mQ(k ) += epsilon; temp /= 2.0 * epsilon; for(int i = 0; i < mDim; ++i) { for(int j = 0; j < mDim; ++j) { std::cout << " " << std::setw(width) << std::left << k << std::setw(width) << std::left << i << std::setw(width) << std::left << j << std::setw(width) << std::left << mGradG(i, j) << std::setw(width) << std::left << temp(i, j) << std::setw(width) << std::left << (mGradG(i, j) - temp(i, j)) / (epsilon * epsilon) << std::endl; } } } std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; std::cout << std::endl; // Hamiltonian fComputeCholeskyG(); mC = mGL.solve(mP); gradV(); std::cout << "pDot (-dH/dq^{i}):" << std::endl; std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; std::cout << " " << std::setw(width) << std::left << "Component" << std::setw(width) << std::left << "Analytic" << std::setw(width) << std::left << "Finite" << std::setw(width) << std::left << "Delta /" << std::endl; std::cout << " " << std::setw(width) << std::left << "(i)" << std::setw(width) << std::left << "Derivative" << std::setw(width) << std::left << "Difference" << std::setw(width) << std::left << "Stepsize^{2}" << std::endl; std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; for(int i = 0; i < mDim; ++i) { // Finite Differences double temp = 0.0; mQ(i) += epsilon; temp -= H(); mQ(i) -= 2.0 * epsilon; temp += H(); mQ(i) += epsilon; temp /= 2.0 * epsilon; // Exact fComputeGradG(i); double minusGradH = -0.5 * mGL.solve(mGradG).trace(); mAuxVector = mGradG * mC; minusGradH += 0.5 * mC.dot(mAuxVector); minusGradH -= mGradV(i); std::cout << " " << std::setw(width) << std::left << i << std::setw(width) << std::left << minusGradH << std::setw(width) << std::left << temp << std::setw(width) << std::left << (minusGradH - temp) / (epsilon * epsilon) << std::endl; } std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; std::cout << std::endl; }
void softAbsMetric::checkEvolution(const double epsilon) { baseHamiltonian::checkEvolution(epsilon); // Hessian std::cout.precision(6); int width = 12; int nColumn = 5; std::cout << "Potential Hessian (d^{2}V/dq^{i}dq^{j}):" << std::endl; std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; std::cout << " " << std::setw(width) << std::left << "Row" << std::setw(width) << std::left << "Column" << std::setw(width) << std::left << "Analytic" << std::setw(width) << std::left << "Finite" << std::setw(width) << std::left << "Delta / " << std::endl; std::cout << " " << std::setw(width) << std::left << "(i)" << std::setw(width) << std::left << "(j)" << std::setw(width) << std::left << "Derivative" << std::setw(width) << std::left << "Difference" << std::setw(width) << std::left << "Stepsize^{2}" << std::endl; std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; fComputeH(); for(int i = 0; i < mDim; ++i) { VectorXd temp = VectorXd::Zero(mDim); mQ(i) += epsilon; temp += gradV(); mQ(i) -= 2.0 * epsilon; temp -= gradV(); mQ(i) += epsilon; temp /= 2.0 * epsilon; for(int j = 0; j < mDim; ++j) { std::cout << " " << std::setw(width) << std::left << i << std::setw(width) << std::left << j << std::setw(width) << std::left << mH(i, j) << std::setw(width) << std::left << temp(j) << std::setw(width) << std::left << (mH(i, j) - temp(j)) / (epsilon * epsilon) << std::endl; } } std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; std::cout << std::endl; // Gradient of the Hessian std::cout.precision(6); width = 12; nColumn = 6; std::cout << "Gradient of the Hessian (d^{3}V/dq^{i}dq^{j}dq^{k}):" << std::endl; std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; std::cout << " " << std::setw(width) << std::left << "Component" << std::setw(width) << std::left << "Row" << std::setw(width) << std::left << "Column" << std::setw(width) << std::left << "Analytic" << std::setw(width) << std::left << "Finite" << std::setw(width) << std::left << "Delta /" << std::endl; std::cout << " " << std::setw(width) << std::left << "(i)" << std::setw(width) << std::left << "(j)" << std::setw(width) << std::left << "(k)" << std::setw(width) << std::left << "Derivative" << std::setw(width) << std::left << "Difference" << std::setw(width) << std::left << "Stepsize^{2}" << std::endl; std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; for(int k = 0; k < mDim; ++k) { mAuxMatrixOne.setZero(); mQ(k) += epsilon; fComputeH(); mAuxMatrixOne += mH; mQ(k) -= 2.0 * epsilon; fComputeH(); mAuxMatrixOne -= mH; mQ(k) += epsilon; mAuxMatrixOne /= 2.0 * epsilon; fComputeGradH(k); for(int i = 0; i < mDim; ++i) { for(int j = 0; j < mDim; ++j) { std::cout << " " << std::setw(width) << std::left << k << std::setw(width) << std::left << i << std::setw(width) << std::left << j << std::setw(width) << std::left << mGradH.block(0, k * mDim, mDim, mDim)(i, j) << std::setw(width) << std::left << mAuxMatrixOne(i, j) << std::setw(width) << std::left << (mGradH.block(0, k * mDim, mDim, mDim)(i, j) - mAuxMatrixOne(i, j)) / (epsilon * epsilon) << std::endl; } } } std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; std::cout << std::endl; // Metric std::cout.precision(6); width = 12; nColumn = 6; std::cout << "Gradient of the metric (dLambda^{jk}/dq^{i}):" << std::endl; std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; std::cout << " " << std::setw(width) << std::left << "Component" << std::setw(width) << std::left << "Row" << std::setw(width) << std::left << "Column" << std::setw(width) << std::left << "Analytic" << std::setw(width) << std::left << "Finite" << std::setw(width) << std::left << "Delta /" << std::endl; std::cout << " " << std::setw(width) << std::left << "(i)" << std::setw(width) << std::left << "(j)" << std::setw(width) << std::left << "(k)" << std::setw(width) << std::left << "Derivative" << std::setw(width) << std::left << "Difference" << std::setw(width) << std::left << "Epsilon^{2}" << std::endl; std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; fComputeMetric(); fPrepareSpatialGradients(); for(int k = 0; k < mDim; ++k) { // Approximate metric gradient MatrixXd temp = MatrixXd::Zero(mDim, mDim); MatrixXd G = MatrixXd::Zero(mDim, mDim); mQ(k) += epsilon; fComputeMetric(); G.noalias() = mEigenDeco.eigenvectors() * mSoftAbsLambda.asDiagonal() * mEigenDeco.eigenvectors().transpose(); temp += G; mQ(k) -= 2.0 * epsilon; fComputeMetric(); G.noalias() = mEigenDeco.eigenvectors() * mSoftAbsLambda.asDiagonal() * mEigenDeco.eigenvectors().transpose(); temp -= G; mQ(k) += epsilon; temp /= 2.0 * epsilon; // Exact metric gradient fComputeMetric(); fComputeGradH(k); mAuxMatrixOne.noalias() = mGradH.block(0, k * mDim, mDim, mDim) * mEigenDeco.eigenvectors(); mAuxMatrixTwo.noalias() = mEigenDeco.eigenvectors().transpose() * mAuxMatrixOne; mAuxMatrixOne.noalias() = mPseudoJ.cwiseProduct(mAuxMatrixTwo); mCacheMatrix.noalias() = mAuxMatrixOne * mEigenDeco.eigenvectors().transpose(); MatrixXd gradG = mEigenDeco.eigenvectors() * mCacheMatrix; // Compare for(int i = 0; i < mDim; ++i) { for(int j = 0; j < mDim; ++j) { std::cout << " " << std::setw(width) << std::left << k << std::setw(width) << std::left << i << std::setw(width) << std::left << j << std::setw(width) << std::left << gradG(i, j) << std::setw(width) << std::left << temp(i, j) << std::setw(width) << std::left << (gradG(i, j) - temp(i, j)) / (epsilon * epsilon) << std::endl; } } } std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; std::cout << std::endl; // Hamiltonian VectorXd gradH = dTaudq(); gradH += dPhidq(); std::cout << "pDot (-dH/dq^{i}):" << std::endl; std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; std::cout << " " << std::setw(width) << std::left << "Component" << std::setw(width) << std::left << "Analytic" << std::setw(width) << std::left << "Finite" << std::setw(width) << std::left << "Delta /" << std::endl; std::cout << " " << std::setw(width) << std::left << "(i)" << std::setw(width) << std::left << "Derivative" << std::setw(width) << std::left << "Difference" << std::setw(width) << std::left << "Epsilon^{2}" << std::endl; std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; for(int i = 0; i < mDim; ++i) { // Finite Differences double temp = 0.0; mQ(i) += epsilon; temp -= H(); mQ(i) -= 2.0 * epsilon; temp += H(); mQ(i) += epsilon; temp /= 2.0 * epsilon; // Exact double minusGradH = -gradH(i); std::cout << " " << std::setw(width) << std::left << i << std::setw(width) << std::left << minusGradH << std::setw(width) << std::left << temp << std::setw(width) << std::left << (minusGradH - temp) / (epsilon * epsilon) << std::endl; } std::cout << " " << std::setw(nColumn * width) << std::setfill('-') << "" << std::setfill(' ') << std::endl; std::cout << std::endl; }