double evaluate_q (const NumberArray<NDIM, RawScalar>& xyz) { typedef DualNumber<RawScalar, NumberArray<NDIM, RawScalar> > FirstDerivType; typedef DualNumber<FirstDerivType, NumberArray<NDIM, FirstDerivType> > SecondDerivType; typedef DualNumber<SecondDerivType, NumberArray<NDIM, SecondDerivType> > ThirdDerivType; typedef ThirdDerivType ADScalar; // Treat velocity as a vector NumberArray<NDIM, ADScalar> U; ADScalar x = ADScalar(xyz[0],NumberArrayUnitVector<NDIM, 0, RawScalar>::value()); ADScalar y = ADScalar(xyz[1],NumberArrayUnitVector<NDIM, 1, RawScalar>::value()); ADScalar z = ADScalar(xyz[2],NumberArrayUnitVector<NDIM, 2, RawScalar>::value()); // Arbitrary manufactured solutions U[0] = a * helper_f(x) + helper_g(y).derivatives()[1] + helper_h(z).derivatives()[2]; U[1] = b * helper_f(x).derivatives()[0] + helper_g(y) + helper_h(z).derivatives()[2]; U[2] = c * helper_f(x).derivatives()[0] + helper_g(y).derivatives()[1] + helper_h(z); ADScalar P = d * helper_f(x) + helper_gt(y) + helper_h(z); // NS equation residuals NumberArray<NDIM, RawScalar> Q_rho_u = raw_value( // convective term divergence(U.outerproduct(U)) // pressure - P.derivatives() // dissipation + nu * divergence(gradient(U))); return raw_value(Q_rho_u[0]); }
Scalar MASA::navierstokes_3d_incompressible<Scalar>::eval_q_u(Scalar x1, Scalar y1, Scalar z1) { typedef DualNumber<Scalar, NumberArray<NDIM, Scalar> > FirstDerivType; typedef DualNumber<FirstDerivType, NumberArray<NDIM, FirstDerivType> > SecondDerivType; typedef DualNumber<SecondDerivType, NumberArray<NDIM, SecondDerivType> > ThirdDerivType; typedef ThirdDerivType ADScalar; // Treat velocity as a vector NumberArray<NDIM, ADScalar> U; ADScalar x = ADScalar(x1,NumberArrayUnitVector<NDIM, 0, Scalar>::value()); ADScalar y = ADScalar(y1,NumberArrayUnitVector<NDIM, 1, Scalar>::value()); ADScalar z = ADScalar(z1,NumberArrayUnitVector<NDIM, 2, Scalar>::value()); // Arbitrary manufactured solutions U[0] = a * helper_f(beta,kx,x) * helper_g(y).derivatives()[1] * helper_h(gamma,kz,z).derivatives()[2]; U[1] = b * helper_f(beta,kx,x).derivatives()[0] * helper_g(y) * helper_h(gamma,kz,z).derivatives()[2]; U[2] = c * helper_f(beta,kx,x).derivatives()[0] * helper_g(y).derivatives()[1] * helper_h(gamma,kz,z); ADScalar P = d * helper_f(beta,kx,x) * helper_gt(y) * helper_h(gamma,kz,z); // NS equation residuals NumberArray<NDIM, Scalar> Q_rho_u = raw_value( // convective term divergence(U.outerproduct(U)) // pressure - P.derivatives() // dissipation + nu * divergence(gradient(U))); return -Q_rho_u[0]; }
Scalar MASA::ad_cns_3d_crossterms<Scalar>::eval_q_e(Scalar x1, Scalar y1, Scalar z1) const { using std::cos; typedef DualNumber<Scalar, NumberArray<NDIM, Scalar> > FirstDerivType; typedef DualNumber<FirstDerivType, NumberArray<NDIM, FirstDerivType> > SecondDerivType; typedef SecondDerivType ADScalar; // Treat velocity as a vector NumberArray<NDIM, ADScalar> U; const ADScalar x = ADScalar(x1,NumberArrayUnitVector<NDIM, 0, Scalar>::value()); const ADScalar y = ADScalar(y1,NumberArrayUnitVector<NDIM, 1, Scalar>::value()); const ADScalar z = ADScalar(z1,NumberArrayUnitVector<NDIM, 2, Scalar>::value()); // Arbitrary manufactured solution U[0] = u_0 + u_x * cos(a_ux * PI * x / L) * u_y * cos(a_uy * PI * y / L) * cos(a_uy * PI * z / L); U[1] = v_0 + v_x * cos(a_vx * PI * x / L) * v_y * cos(a_vy * PI * y / L) * cos(a_vy * PI * z / L); U[2] = w_0 + w_x * cos(a_wx * PI * x / L) * w_y * cos(a_wy * PI * y / L) * cos(a_wy * PI * z / L); ADScalar RHO = rho_0 + rho_x * cos(a_rhox * PI * x / L) * rho_y * cos(a_rhoy * PI * y / L) * cos(a_rhoz * PI * z / L); ADScalar P = p_0 + p_x * cos(a_px * PI * x / L) * p_y * cos(a_py * PI * y / L) * cos(a_pz * PI * z / L); // Temperature ADScalar T = P / RHO / R; // Perfect gas energies ADScalar E = 1./(Gamma-1.)*P/RHO; ADScalar ET = E + .5 * U.dot(U); // The shear strain tensor NumberArray<NDIM, typename ADScalar::derivatives_type> GradU = gradient(U); // The identity tensor I NumberArray<NDIM, NumberArray<NDIM, Scalar> > Identity = NumberArray<NDIM, Scalar>::identity(); // The shear stress tensor NumberArray<NDIM, NumberArray<NDIM, ADScalar> > Tau = mu * (GradU + transpose(GradU) - 2./3.*divergence(U)*Identity); // Temperature flux NumberArray<NDIM, ADScalar> q = -k * T.derivatives(); // Euler equation residuals // Scalar Q_rho = raw_value(divergence(RHO*U)); // NumberArray<NDIM, Scalar> Q_rho_u = // raw_value(divergence(RHO*U.outerproduct(U) - Tau) + P.derivatives()); // energy equation Scalar Q_rho_e = raw_value(divergence((RHO*ET+P)*U + q - Tau.dot(U))); return Q_rho_e; }
bool link_det_lu( size_t size , size_t repeat , CppAD::vector<double> &matrix , CppAD::vector<double> &gradient ) { // speed test global option values if( global_onetape || global_atomic ) return false; if( global_memory || global_optimize ) return false; // ----------------------------------------------------- // setup // // object for computing determinant typedef fadbad::B<double> ADScalar; typedef CppAD::vector<ADScalar> ADVector; CppAD::det_by_lu<ADScalar> Det(size); size_t i; // temporary index size_t m = 1; // number of dependent variables size_t n = size * size; // number of independent variables ADScalar detA; // AD value of the determinant ADVector A(n); // AD version of matrix // ------------------------------------------------------ while(repeat--) { // get the next matrix CppAD::uniform_01(n, matrix); // set independent variable values for(i = 0; i < n; i++) A[i] = matrix[i]; // compute the determinant detA = Det(A); // create function object f : A -> detA detA.diff(0, m); // index 0 of m dependent variables // evaluate and return gradient using reverse mode for(i =0; i < n; i++) gradient[i] = A[i].d(0); // partial detA w.r.t A[i] } // --------------------------------------------------------- return true; }
bool link_poly( size_t size , size_t repeat , CppAD::vector<double> &a , // coefficients of polynomial CppAD::vector<double> &z , // polynomial argument value CppAD::vector<double> &ddp ) // second derivative w.r.t z { if( global_option["atomic"] ) return false; if( global_option["memory"] || global_option["onetape"] || global_option["optimize"] ) return false; // ----------------------------------------------------- // setup typedef Sacado::Tay::Taylor<double> ADScalar; CppAD::vector<ADScalar> A(size); size_t i; // temporary index ADScalar Z; // domain space AD value ADScalar P; // range space AD value unsigned int order = 2; // order of Taylor coefficients Z.resize(order+1, false); P.resize(order+1, false); // choose the polynomial coefficients CppAD::uniform_01(size, a); // AD copy of the polynomial coefficients for(i = 0; i < size; i++) A[i] = a[i]; // ------------------------------------------------------ while(repeat--) { // get the next argument value CppAD::uniform_01(1, z); // independent variable value Z.fastAccessCoeff(0) = z[0]; // argument value Z.fastAccessCoeff(1) = 1.; // first order coefficient Z.fastAccessCoeff(2) = 0.; // second order coefficient // AD computation of the dependent variable P = CppAD::Poly(0, A, Z); // second derivative is twice second order Taylor coefficient ddp[0] = 2. * P.fastAccessCoeff(2); } // ------------------------------------------------------ return true; }
double evaluate_q (const NumberArray<NDIM, ADScalar>& xyz, const int ret) { typedef typename RawType<ADScalar>::value_type Scalar; const Scalar PI = std::acos(Scalar(-1)); const Scalar k = 1.38; const Scalar u_0 = 200.23; const Scalar u_x = 1.1; const Scalar u_y = 1.08; const Scalar v_0 = 1.2; const Scalar v_x = 1.6; const Scalar v_y = .47; const Scalar rho_0 = 100.02; const Scalar rho_x = 2.22; const Scalar rho_y = 0.8; const Scalar p_0 = 150.2; const Scalar p_x = .91; const Scalar p_y = .623; const Scalar a_px = .165; const Scalar a_py = .612; const Scalar a_rhox = 1.0; const Scalar a_rhoy = 1.0; const Scalar a_ux = .1987; const Scalar a_uy = 1.189; const Scalar a_vx = 1.91; const Scalar a_vy = 1.0; const Scalar Gamma = 1.01; const Scalar mu = .918; const Scalar L = 3.02; const ADScalar& x = xyz[0]; const ADScalar& y = xyz[1]; // Treat velocity as a vector NumberArray<NDIM, ADScalar> U; // Arbitrary manufactured solution U[0] = u_0 + u_x * std::sin(a_ux * PI * x / L) + u_y * std::cos(a_uy * PI * y / L); U[1] = v_0 + v_x * std::cos(a_vx * PI * x / L) + v_y * std::sin(a_vy * PI * y / L); ADScalar RHO = rho_0 + rho_x * std::sin(a_rhox * PI * x / L) + rho_y * std::cos(a_rhoy * PI * y / L); ADScalar P = p_0 + p_x * std::cos(a_px * PI * x / L) + p_y * std::sin(a_py * PI * y / L); // Perfect gas energies ADScalar E = 1./(Gamma-1.)*P/RHO; ADScalar ET = E + .5 * U.dot(U); // Euler equation residuals Scalar Q_rho = raw_value(divergence(RHO*U)); NumberArray<NDIM, Scalar> Q_rho_u = raw_value(divergence(RHO*U.outerproduct(U)) + P.derivatives()); // energy equation Scalar Q_rho_e = raw_value(divergence((RHO*ET+P)*U)); // Scalar Q_rho_e = raw_value(divergence((RHO*U*ET)+(P*U))); switch(ret) { // u case 1: return Q_rho_u[0]; break; // v case 2: return Q_rho_u[1]; break; // rho case 3: return Q_rho; break; // energy case 4: return Q_rho_e; break; default: std::cout << "something is wrong!\n"; exit; } return 0; }
double evaluate_q (const NumberArray<NDIM, ADScalar>& xyz, const int ret) { typedef typename RawType<ADScalar>::value_type Scalar; const Scalar PI = std::acos(Scalar(-1)); const Scalar R = masa_get_param("R"); const Scalar u_0 = masa_get_param("u_0"); const Scalar u_x = masa_get_param("u_x"); const Scalar u_y = masa_get_param("u_y"); const Scalar v_0 = masa_get_param("v_0"); const Scalar v_x = masa_get_param("v_x"); const Scalar v_y = masa_get_param("v_y"); const Scalar rho_0 = masa_get_param("rho_0"); const Scalar rho_x = masa_get_param("rho_x"); const Scalar rho_y = masa_get_param("rho_y"); const Scalar p_0 = masa_get_param("p_0"); const Scalar p_x = masa_get_param("p_x"); const Scalar p_y = masa_get_param("p_y"); const Scalar a_px = masa_get_param("a_px"); const Scalar a_py = masa_get_param("a_py"); const Scalar a_rhox = masa_get_param("a_rhox"); const Scalar a_rhoy = masa_get_param("a_rhoy"); const Scalar a_ux = masa_get_param("a_ux"); const Scalar a_uy = masa_get_param("a_uy"); const Scalar a_vx = masa_get_param("a_vx"); const Scalar a_vy = masa_get_param("a_vy"); const Scalar Gamma = masa_get_param("Gamma"); const Scalar L = masa_get_param("L"); const Scalar mu = masa_get_param("mu"); const Scalar k = masa_get_param("k"); const ADScalar& x = xyz[0]; const ADScalar& y = xyz[1]; // Treat velocity as a vector NumberArray<NDIM, ADScalar> U; // Arbitrary manufactured solution U[0] = u_0 + u_x * std::cos(a_ux * PI * x / L) * u_y * std::cos(a_uy * PI * y / L); U[1] = v_0 + v_x * std::cos(a_vx * PI * x / L) * v_y * std::cos(a_vy * PI * y / L); ADScalar RHO = rho_0 + rho_x * std::cos(a_rhox * PI * x / L) * rho_y * std::cos(a_rhoy * PI * y / L); ADScalar P = p_0 + p_x * std::cos(a_px * PI * x / L) * p_y * std::cos(a_py * PI * y / L); // Temperature ADScalar T = P / RHO / R; // Perfect gas energies ADScalar E = 1./(Gamma-1.)*P/RHO; ADScalar ET = E + .5 * U.dot(U); // The shear strain tensor NumberArray<NDIM, typename ADScalar::derivatives_type> GradU = gradient(U); // The identity tensor I NumberArray<NDIM, NumberArray<NDIM, Scalar> > Identity = NumberArray<NDIM, Scalar>::identity(); // The shear stress tensor NumberArray<NDIM, NumberArray<NDIM, ADScalar> > Tau = mu * (GradU + transpose(GradU) - 2./3.*divergence(U)*Identity); // Temperature flux NumberArray<NDIM, ADScalar> q = -k * T.derivatives(); // Euler equation residuals Scalar Q_rho = raw_value(divergence(RHO*U)); NumberArray<NDIM, Scalar> Q_rho_u = raw_value(divergence(RHO*U.outerproduct(U) - Tau) + P.derivatives()); // energy equation Scalar Q_rho_e = raw_value(divergence((RHO*ET+P)*U + q - Tau.dot(U))); switch(ret) { // u case 1: return Q_rho_u[0]; break; // v case 2: return Q_rho_u[1]; break; // rho case 3: return Q_rho; break; // energy case 4: return Q_rho_e; break; default: std::cout << "something is wrong!\n"; exit(1); } }