virtual void compute_solution(const PhysData &inner_cell_data, const RealVectorNDIM &boundary_face_normal, RealVectorNEQS &boundary_face_solution) { set_meanflow_properties(inner_cell_data); RealVectorNEQS char_cell_sol; RealVectorNEQS char_bdry_sol; outward_normal = flx_pt_plane_jacobian_normal->get().plane_unit_normal[cell_flx_pt] * flx_pt_plane_jacobian_normal->get().sf->flx_pt_sign(cell_flx_pt); // COMMENTED HERE IS A STANDARD FORM NOT BASED ON CHARACTERISTIC THEORY // velocity on the inside of the face // rho0u[XX] = inner_cell_data.solution[1]; // rho0u[YY] = inner_cell_data.solution[2]; // // velocity in outward_normal direction // rho0u_normal = rho0u.transpose()*outward_normal; // // Modify velocity to become the outside velocity of the face, // // and being the mirror of the inside velocity // rho0u.noalias() -= 2.*rho0u_normal*outward_normal; // boundary_face_solution = inner_cell_data.solution; // boundary_face_solution[1] = rho0u[XX]; // boundary_face_solution[2] = rho0u[YY]; cons_to_char(inner_cell_data.solution,outward_normal,char_cell_sol); const Real& S = char_cell_sol[0]; const Real& Omega = char_cell_sol[1]; const Real& Aplus = char_cell_sol[2]; const Real& Amin = char_cell_sol[3]; char_bdry_sol[0] = S; char_bdry_sol[1] = Omega; char_bdry_sol[2] = Aplus; char_bdry_sol[3] = Aplus; // Amin = Aplus is the magic here char_to_cons(char_bdry_sol,outward_normal,boundary_face_solution); }
virtual void compute_solution(const PhysData &inner_cell_data, const RealVectorNDIM &boundary_face_normal, RealVectorNEQS &boundary_face_solution) { RealVectorNEQS char_cell_sol; RealVectorNEQS char_bdry_sol; const RealVectorNDIM& unit_normal = flx_pt_plane_jacobian_normal->get().plane_unit_normal[cell_flx_pt] * flx_pt_plane_jacobian_normal->get().sf->flx_pt_sign(cell_flx_pt); Real nx = unit_normal[XX]; Real ny = unit_normal[YY]; cons_to_char(inner_cell_data.solution,unit_normal,char_cell_sol); const Real& S = char_cell_sol[0]; const Real& Omega = char_cell_sol[1]; const Real& Aplus = char_cell_sol[2]; const Real& Amin = char_cell_sol[3]; const Real omega = Aplus-Amin; const Real A = Aplus+Amin; char_bdry_sol[0] = S; char_bdry_sol[1] = Omega; char_bdry_sol[2] = Aplus; char_bdry_sol[3] = Amin; char_to_cons(char_bdry_sol,unit_normal,boundary_face_solution); }
virtual void compute_solution(const PhysData &inner_cell_data, const RealVectorNDIM &boundary_face_normal, RealVectorNEQS &boundary_face_solution) { enum {ENTR=0,OMEGA=1,APLUS=2,AMIN=3}; RealMatrix J((int)NDIM,(int)NDIM); RealMatrix Jinv((int)NDIM,(int)NDIM); Real detJ; RealMatrix nodes; inner_cell->get().space->support().geometry_space().allocate_coordinates(nodes); inner_cell->get().space->support().geometry_space().put_coordinates(nodes,inner_cell->get().idx); inner_cell->get().space->support().element_type().compute_jacobian(inner_cell->get().sf->flx_pts().row(cell_flx_pt),nodes,J); Jinv = J.inverse(); detJ = J.determinant(); // Real Jxi = Jinv.row(KSI).norm(); // Real Jeta = Jinv.row(ETA).norm(); // std::cout << "Jxi = " << Jxi << " Jeta = " << Jeta << std::endl; outward_normal = flx_pt_plane_jacobian_normal->get().plane_unit_normal[cell_flx_pt] * flx_pt_plane_jacobian_normal->get().sf->flx_pt_sign(cell_flx_pt); const RealRowVector& n = outward_normal; RealRowVector s((int)NDIM); s << n[YY], -n[XX]; // std::cout << "n = " << n << std::endl; // std::cout << "s = " << s << std::endl; // RealVector U0(2); // U0[XX] = options().value< std::vector<Real> >("U0")[XX]; // U0[YY] = options().value< std::vector<Real> >("U0")[YY]; // Real u0n = U0.dot(n); // Real u0s = U0.dot(s); RealRowVector mapped_n = n * detJ * Jinv; RealRowVector mapped_s = s * detJ * Jinv; // std::cout << "mapped_n = " << mapped_n << std::endl; // std::cout << "mapped_s = " << mapped_s << std::endl; // if ( std::abs(outward_normal[XX]-1.) > 1e-10) // throw common::BadValue(FromHere(), "outward_normal incorrect"); for (Uint f=0; f<inner_cell->get().sf->nb_flx_pts(); ++f) { cons_to_char(cons_flx_pt_solution[f],outward_normal,char_flx_pt_solution[f]); } // Extrapolation BC char_bdry_solution[ENTR ] = char_flx_pt_solution[cell_flx_pt][ENTR ]; char_bdry_solution[OMEGA] = char_flx_pt_solution[cell_flx_pt][OMEGA]; char_bdry_solution[APLUS] = char_flx_pt_solution[cell_flx_pt][APLUS]; char_bdry_solution[AMIN ] = char_flx_pt_solution[cell_flx_pt][AMIN ]; sf_deriv_xi.resize(inner_cell->get().sf->nb_flx_pts()); sf_deriv_eta.resize(inner_cell->get().sf->nb_flx_pts()); sf_deriv_n.resize(inner_cell->get().sf->nb_flx_pts()); sf_deriv_s.resize(inner_cell->get().sf->nb_flx_pts()); inner_cell->get().sf->compute_flux_derivative(KSI,inner_cell->get().sf->flx_pts().row(cell_flx_pt),sf_deriv_xi); inner_cell->get().sf->compute_flux_derivative(ETA,inner_cell->get().sf->flx_pts().row(cell_flx_pt),sf_deriv_eta); for (Uint j=0; j<inner_cell->get().sf->nb_flx_pts(); ++j) { sf_deriv_n[j] = mapped_n[KSI] * sf_deriv_xi[j] + mapped_n[ETA] * sf_deriv_eta[j]; sf_deriv_s[j] = mapped_s[KSI] * sf_deriv_xi[j] + mapped_s[ETA] * sf_deriv_eta[j]; } std::vector<Real> omega(inner_cell->get().sf->nb_flx_pts()); Real dAmindn = 0.; Real dAminds = 0.; Real dAplusdn = 0.; Real dAplusds = 0.; Real dOmegadn = 0.; Real dOmegads = 0.; Real domegadn = 0.; Real domegads = 0.; for (Uint j=0; j<inner_cell->get().sf->nb_flx_pts(); ++j) { dOmegadn += char_flx_pt_solution[j][OMEGA] * sf_deriv_n[j]; dOmegads += char_flx_pt_solution[j][OMEGA] * sf_deriv_s[j]; dAmindn += char_flx_pt_solution[j][AMIN ] * sf_deriv_n[j]; dAminds += char_flx_pt_solution[j][AMIN ] * sf_deriv_s[j]; dAplusdn += char_flx_pt_solution[j][APLUS] * sf_deriv_n[j]; dAplusds += char_flx_pt_solution[j][APLUS] * sf_deriv_s[j]; omega[j] = 0.5*(char_flx_pt_solution[j][APLUS] - char_flx_pt_solution[j][AMIN]); domegadn += omega[j] * sf_deriv_n[j]; domegads += omega[j] * sf_deriv_s[j]; } // dA/dn + dOmega/ds = 0 // dAplus/dn - dAmin/dn = - 2 dOmega/ds // 0 < (Aplus-Amin)/(Omega) < 1 --> tangent flow dominates // (Aplus-Amin)/(Omega) > 1 --> normal flow dominates // std::cout << "gradx = " << sf_deriv_xi.transpose() << std::endl; // std::cout << "dAmindxi_internal = " << dAmindxi_internal << std::endl; // Try 1 // dAmin/dt + (u0+c0)dAmin/dn + c0 dAmin/ds - c0 dOmega/ds = 0 // dAmindn = 1./(m_u0n-m_c0) * ( (m_u0n+m_c0)*dAmindn - 2.*m_c0*dOmegads ); // Try 2! dAmin/dt + u0n dOmega/ds + u0s dAmin/dn = 0 // dAmindn = dOmegads; // dAmindn = -dAplusdn --> dAmindn = dOmegads // dAmindn/dAplusdn = dAmindn/dOmegads // BC divzero // dAmindn = dAplusdn + 2*dOmegads; // BC dAdt + u0n dAdn = 0 boils to same as divzero when u0s=0 // dAmindn = 1./m_c0*(u0s*dAminds+u0s*dAplusds+m_c0*dAplusdn+2*m_c0*dOmegads); // Aplus*Amin > 0 --> pulse // Aplus*Amin < 0 --> vortex // Aplus + Amin = 0 --> vortex // Aplus - Amin = 0 --> pulse // Aplus+Amin = // Real ratio = ( std::abs(dAmindn) < 1e-12 ? 0. : dAmindn/dOmegads); // static Real i = 0.; // static Real avg_ratio = ratio; // static Real max_ratio = ratio; // static Real min_ratio = ratio; // if (ratio != 0 && std::abs(ratio) < 2) // { // max_ratio = std::max(max_ratio,ratio); // min_ratio = std::min(min_ratio,ratio); // avg_ratio = i/(i+1.) * avg_ratio + 1./(i+1.) * ratio; // ++i; //// std::cout << "ratio = " << ratio << "\t i = " << i << "\t avg = " << avg_ratio << " \t max = " << max_ratio << " \t min = " << min_ratio << std::endl; // } // vortex: ratio = 1. alpha = 0 // pulse: ratio = 0.5 alpha = 1 // Real alpha = std::max(0., std::min(1., 2.* (1.-std::abs(ratio)) )); // std::cout << "alpha = " << alpha << std::endl; Real alpha = options().value<Real>("alpha"); dAmindn = (1.-alpha)*dOmegads + alpha*dAmindn; // dAmindn = dAmindn + 2.*dAmindn/dAplusdn*dOmegads; // dAmindn = 0.;//dOmegads; // Hedstrom: dAmin/dt = 0 // --> (u0n - c0) dAmin/dn + u0s dAmin/ds + c0 dOmega/ds = 0 // dAmindn = 1./(m_u0n-m_c0)*(-m_u0s*dAminds - m_c0*dOmegads); // dAmin/dt + u0n dAmin/dn + u0s dAmin/ds = 0 // dAmindn = 1./(m_u0n+m_c0)*(m_u0n*dAmindn - m_c0*dOmegads); // Try 3 // dAmindn = 2.*dOmegads + dAplusdn; // replace = dAmindxi_internal + 2.*dOmegadeta; // replace = -dAmindxi_internal; // replace = -dAplusdxi; // replace = dAmindxi_internal; // replace = 2./(m_u0n-m_c0) * ( m_u0n/2.*dAmindxi_internal -m_c0/2.*dAplusdxi -m_c0*dOmegadeta ); // // Also modify equation for omega: // dAplusdn = -dAmindn; // Real A = 0.5*(char_flx_pt_solution[cell_flx_pt][APLUS] + char_flx_pt_solution[cell_flx_pt][AMIN ]); // dAplusdn = -dAmindn; char_bdry_solution[AMIN ] = dAmindn; // char_bdry_solution[APLUS] = dAplusdn; for (Uint j=0; j<inner_cell->get().sf->nb_flx_pts(); ++j) { if (j!=cell_flx_pt) { char_bdry_solution[AMIN ] -= char_flx_pt_solution[j][AMIN ] * sf_deriv_n[j]; // char_bdry_solution[APLUS] -= char_flx_pt_solution[j][APLUS] * sf_deriv_xi[j]; } } char_bdry_solution[AMIN ] /= sf_deriv_n[cell_flx_pt]; // Real A = 0.5*(char_flx_pt_solution[cell_flx_pt][APLUS] + char_flx_pt_solution[cell_flx_pt][AMIN]); // char_bdry_solution[APLUS] = 2.*A - char_bdry_solution[AMIN]; // char_bdry_solution[APLUS] /= sf_deriv_xi[cell_flx_pt]; //// std::cout << char_bdry_solution[AMIN] << std::endl; // compute_optimization(char_bdry_solution[OMEGA],char_bdry_solution[APLUS],char_bdry_solution[AMIN]); // char_bdry_solution[APLUS] = char_flx_pt_solution[cell_flx_pt][APLUS]; // compute_optimization_2(char_bdry_solution[OMEGA],char_bdry_solution[AMIN]); char_to_cons(char_bdry_solution,outward_normal,boundary_face_solution); }