diff --git a/src/ADTypes.hpp b/src/ADTypes.hpp index b2e2e437b..7a597be51 100644 --- a/src/ADTypes.hpp +++ b/src/ADTypes.hpp @@ -26,6 +26,15 @@ using codi_HessianComputationType = codi::RealReversePrimalIndexGen< codi::Real //using RadFadType = codi_JacobianComputationType; ///< Reverse only mode that only allows Jacobian computation. using RadType = codi_JacobianComputationType; ///< CoDiPaco reverse-AD type for first derivatives. using RadFadType = codi_HessianComputationType ; ///< Nested reverse-forward mode type for Jacobian and Hessian computation using TapeHelper. + +/// Tape helper class derived from CoDiPack +template +class codi_TapeHelper : public codi::TapeHelper +{ +public: + /// Returns reference to codi::TapeHelper::inputValues which can be used in PHiLiP to add inputs that have already been registered in the global tape. + std::vector& getinputValues() {return this->inputValues;} +}; } // PHiLiP namespace #endif diff --git a/src/dg/dg_base.cpp b/src/dg/dg_base.cpp index c60e35a2a..c5390f175 100644 --- a/src/dg/dg_base.cpp +++ b/src/dg/dg_base.cpp @@ -448,28 +448,28 @@ bool DGBase::current_cell_should_do_the_work ( Assert(0==1, dealii::ExcMessage("Should not have reached here. Somehow another possible case has not been considered when two cells have the same coarseness.")); return false; } - + template -template -void DGBase::assemble_cell_residual ( - const DoFCellAccessorType1 ¤t_cell, - const DoFCellAccessorType2 ¤t_metric_cell, +template +void DGBase::assemble_cell_residual_and_ad_derivatives ( + const dealii::TriaActiveIterator> ¤t_cell, + const dealii::TriaActiveIterator> ¤t_metric_cell, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, - dealii::hp::FEValues &fe_values_collection_volume, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - dealii::hp::FEFaceValues &fe_values_collection_face_ext, - dealii::hp::FESubfaceValues &fe_values_collection_subface, - dealii::hp::FEValues &fe_values_collection_volume_lagrange, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::mapping_shape_functions &mapping_basis, - const bool compute_auxiliary_right_hand_side, - dealii::LinearAlgebra::distributed::Vector &rhs, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + const bool compute_auxiliary_right_hand_side,//flag on whether computing the Auxiliary variable's equations' residuals + dealii::LinearAlgebra::distributed::Vector &rhs, std::array,dim> &rhs_aux) { std::vector current_dofs_indices; @@ -480,11 +480,16 @@ void DGBase::assemble_cell_residual ( const dealii::FESystem ¤t_fe_ref = fe_collection[i_fele]; const unsigned int n_dofs_curr_cell = current_fe_ref.n_dofs_per_cell(); - + // Local vector contribution from each cell - dealii::Vector current_cell_rhs (n_dofs_curr_cell); // Defaults to 0.0 initialization + std::vector current_cell_rhs (n_dofs_curr_cell); // Defaults to 0.0 initialization // Local vector contribution from each cell for Auxiliary equations - std::vector> current_cell_rhs_aux (n_dofs_curr_cell);// Defaults to 0.0 initialization + dealii::Tensor<1,dim,std::vector> current_cell_rhs_aux;// Defaults to 0.0 initialization + if(compute_auxiliary_right_hand_side){ + for(int idim=0; idim::assemble_cell_residual ( const dealii::types::global_dof_index current_cell_index = current_cell->active_cell_index(); - std::array,dim> mapping_support_points; //if have source term need to store vol flux nodes. const bool store_vol_flux_nodes = all_parameters->manufactured_convergence_study_param.manufactured_solution_param.use_manufactured_source_term; //for boundary conditions not periodic we need surface flux nodes //should change this flag to something like if have face on boundary not periodic in the future const bool store_surf_flux_nodes = (all_parameters->use_periodic_bc) ? false : true; - OPERATOR::metric_operators metric_oper_int(nstate, poly_degree, grid_degree, - store_vol_flux_nodes, - store_surf_flux_nodes); + OPERATOR::metric_operators metric_oper_int(nstate, poly_degree, grid_degree, + store_vol_flux_nodes, + store_surf_flux_nodes); //flag to terminate if strong form and implicit if((this->all_parameters->use_weak_form==false) && (this->all_parameters->ode_solver_param.ode_solver_type - == Parameters::ODESolverParam::ODESolverEnum::implicit_solver)) + == Parameters::ODESolverParam::ODESolverEnum::implicit_solver) + && this->use_auxiliary_eq) { - pcout<<"ERROR: Implicit does not currently work for strong form. Aborting..."< &fe_metric = this->high_order_grid->fe_system; + std::vector local_metric_coeff_int(fe_metric.dofs_per_cell); + + if (compute_dRdW || compute_dRdX || compute_d2R) + { + tape.setActive(); + } + for (unsigned int idof = 0; idof < n_metric_dofs_cell; ++idof) + { + const real val = this->high_order_grid->volume_nodes[current_metric_dofs_indices[idof]]; + local_metric_coeff_int[idof] = val; + + if (compute_dRdX || compute_d2R) + { + tape.registerInput(local_metric_coeff_int[idof]); + } + else + { + tape.deactivateValue(local_metric_coeff_int[idof]); + } + } - assemble_volume_term_and_build_operators( + // Compute metric Jacobians of current cell here. + std::array,dim> mapping_support_points; + build_volume_metric_operators(poly_degree, grid_degree, local_metric_coeff_int, metric_oper_int, mapping_basis, mapping_support_points); + + //set tape position for metric jacobian int + Position tape_position_metric_jacobian_int = tape.getPosition(); + + assemble_volume_codi_taped_derivatives_ad( current_cell, current_cell_index, current_dofs_indices, @@ -540,9 +578,10 @@ void DGBase::assemble_cell_residual ( current_fe_ref, current_cell_rhs, current_cell_rhs_aux, + local_metric_coeff_int, compute_auxiliary_right_hand_side, compute_dRdW, compute_dRdX, compute_d2R); - + (void) fe_values_collection_face_int; (void) fe_values_collection_face_ext; (void) fe_values_collection_subface; @@ -556,8 +595,10 @@ void DGBase::assemble_cell_residual ( const real penalty = evaluate_penalty_scaling (current_cell, iface, fe_collection); const unsigned int boundary_id = current_face->boundary_id(); - - assemble_boundary_term_and_build_operators( + + tape.reset(tape_position_metric_jacobian_int); + tape.clearAdjoints(); + assemble_boundary_codi_taped_derivatives_ad( current_cell, current_cell_index, iface, @@ -569,9 +610,7 @@ void DGBase::assemble_cell_residual ( grid_degree, soln_basis_int, flux_basis_int, - flux_basis_stiffness, soln_basis_projection_oper_int, - soln_basis_projection_oper_ext, metric_oper_int, mapping_basis, mapping_support_points, @@ -579,6 +618,7 @@ void DGBase::assemble_cell_residual ( current_fe_ref, current_cell_rhs, current_cell_rhs_aux, + local_metric_coeff_int, compute_auxiliary_right_hand_side, compute_dRdW, compute_dRdX, compute_d2R); @@ -595,7 +635,7 @@ void DGBase::assemble_cell_residual ( Assert (current_cell->periodic_neighbor(iface).state() == dealii::IteratorState::valid, dealii::ExcInternalError()); const unsigned int n_dofs_neigh_cell = fe_collection[neighbor_cell->active_fe_index()].n_dofs_per_cell(); - dealii::Vector neighbor_cell_rhs (n_dofs_neigh_cell); // Defaults to 0.0 initialization + std::vector neighbor_cell_rhs (n_dofs_neigh_cell); // Defaults to 0.0 initialization // Obtain the mapping from local dof indices to global dof indices for neighbor cell neighbor_dofs_indices.resize(n_dofs_neigh_cell); @@ -618,11 +658,14 @@ void DGBase::assemble_cell_residual ( const unsigned int poly_degree_ext = i_fele_n; const unsigned int grid_degree_ext = this->high_order_grid->fe_system.tensor_degree(); //constructor doesn't build anything - OPERATOR::metric_operators metric_oper_ext(nstate, poly_degree_ext, grid_degree_ext, + OPERATOR::metric_operators metric_oper_ext(nstate, poly_degree_ext, grid_degree_ext, store_vol_flux_nodes, store_surf_flux_nodes); - assemble_face_term_and_build_operators( + tape.reset(tape_position_metric_jacobian_int); + tape.clearAdjoints(); + const dealii::FESystem &neighbor_fe_ref = fe_collection[i_fele_n]; + assemble_face_codi_taped_derivatives_ad( current_cell, neighbor_cell, current_cell_index, @@ -630,6 +673,11 @@ void DGBase::assemble_cell_residual ( iface, neighbor_iface, penalty, + fe_values_collection_face_int, + fe_values_collection_face_ext, + fe_values_collection_subface, + current_fe_ref, + neighbor_fe_ref, current_dofs_indices, neighbor_dofs_indices, current_metric_dofs_indices, @@ -649,8 +697,7 @@ void DGBase::assemble_cell_residual ( metric_oper_ext, mapping_basis, mapping_support_points, - fe_values_collection_face_int, - fe_values_collection_face_ext, + local_metric_coeff_int, current_cell_rhs, neighbor_cell_rhs, current_cell_rhs_aux, @@ -692,7 +739,7 @@ void DGBase::assemble_cell_residual ( const int i_fele_n = neighbor_cell->active_fe_index();//, i_quad_n = i_fele_n, i_mapp_n = 0; const unsigned int n_dofs_neigh_cell = fe_collection[i_fele_n].n_dofs_per_cell(); - dealii::Vector neighbor_cell_rhs (n_dofs_neigh_cell); // Defaults to 0.0 initialization + std::vector neighbor_cell_rhs (n_dofs_neigh_cell); // Defaults to 0.0 initialization // Obtain the mapping from local dof indices to global dof indices for neighbor cell neighbor_dofs_indices.resize(n_dofs_neigh_cell); @@ -709,19 +756,26 @@ void DGBase::assemble_cell_residual ( const unsigned int poly_degree_ext = i_fele_n; const unsigned int grid_degree_ext = this->high_order_grid->fe_system.tensor_degree(); //Check if the poly degree or mapping changed order, in which case, then we re-compute the corresponding basis - OPERATOR::metric_operators metric_oper_ext(nstate, poly_degree_ext, grid_degree_ext, + OPERATOR::metric_operators metric_oper_ext(nstate, poly_degree_ext, grid_degree_ext, store_vol_flux_nodes, store_surf_flux_nodes); - assemble_subface_term_and_build_operators( + tape.reset(tape_position_metric_jacobian_int); + tape.clearAdjoints(); + const dealii::FESystem &neighbor_fe_ref = fe_collection[i_fele_n]; + assemble_face_codi_taped_derivatives_ad( current_cell, neighbor_cell, current_cell_index, neighbor_cell_index, iface, neighbor_iface, - neighbor_i_subface, penalty, + fe_values_collection_face_int, + fe_values_collection_face_ext, + fe_values_collection_subface, + current_fe_ref, + neighbor_fe_ref, current_dofs_indices, neighbor_dofs_indices, current_metric_dofs_indices, @@ -741,15 +795,16 @@ void DGBase::assemble_cell_residual ( metric_oper_ext, mapping_basis, mapping_support_points, - fe_values_collection_face_int, - fe_values_collection_subface, + local_metric_coeff_int, current_cell_rhs, neighbor_cell_rhs, current_cell_rhs_aux, rhs, rhs_aux, compute_auxiliary_right_hand_side, - compute_dRdW, compute_dRdX, compute_d2R); + compute_dRdW, compute_dRdX, compute_d2R, + true, + neighbor_i_subface); } // CASE 5: NEIGHBOR CELL HAS SAME COARSENESS // Therefore, we need to choose one of them to do the work @@ -766,7 +821,7 @@ void DGBase::assemble_cell_residual ( const unsigned int n_dofs_neigh_cell = fe_collection[neighbor_cell->active_fe_index()].n_dofs_per_cell(); // Local rhs contribution from neighbor - dealii::Vector neighbor_cell_rhs (n_dofs_neigh_cell); // Defaults to 0.0 initialization + std::vector neighbor_cell_rhs (n_dofs_neigh_cell); // Defaults to 0.0 initialization // Obtain the mapping from local dof indices to global dof indices for neighbor cell neighbor_dofs_indices.resize(n_dofs_neigh_cell); @@ -788,11 +843,14 @@ void DGBase::assemble_cell_residual ( // For now high_order_grid only handles all cells of same grid degree. const unsigned int grid_degree_ext = this->high_order_grid->fe_system.tensor_degree(); //Check if the poly degree or mapping changed order, in which case, then we re-compute the corresponding basis - OPERATOR::metric_operators metric_oper_ext(nstate, poly_degree_ext, grid_degree_ext, + OPERATOR::metric_operators metric_oper_ext(nstate, poly_degree_ext, grid_degree_ext, store_vol_flux_nodes, store_surf_flux_nodes); - assemble_face_term_and_build_operators( + tape.reset(tape_position_metric_jacobian_int); + tape.clearAdjoints(); + const dealii::FESystem &neighbor_fe_ref = fe_collection[i_fele_n]; + assemble_face_codi_taped_derivatives_ad( current_cell, neighbor_cell, current_cell_index, @@ -800,6 +858,11 @@ void DGBase::assemble_cell_residual ( iface, neighbor_iface, penalty, + fe_values_collection_face_int, + fe_values_collection_face_ext, + fe_values_collection_subface, + current_fe_ref, + neighbor_fe_ref, current_dofs_indices, neighbor_dofs_indices, current_metric_dofs_indices, @@ -819,8 +882,7 @@ void DGBase::assemble_cell_residual ( metric_oper_ext, mapping_basis, mapping_support_points, - fe_values_collection_face_int, - fe_values_collection_face_ext, + local_metric_coeff_int, current_cell_rhs, neighbor_cell_rhs, current_cell_rhs_aux, @@ -834,12 +896,17 @@ void DGBase::assemble_cell_residual ( // but will be evaluated when we visit the other cell. } } // end of face loop + + if(compute_dRdW || compute_dRdX || compute_d2R) + { + tape.setPassive(); + } if(compute_auxiliary_right_hand_side) { // Add local contribution from current cell to global vector - for (unsigned int i=0; i::assemble_cell_residual ( } } +template +template +void DGBase::assemble_volume_codi_taped_derivatives_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_dofs_indices, + const std::vector &metric_dofs_indices, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + const dealii::FESystem &fe_soln, + std::vector &local_rhs_cell, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + std::vector &local_metric_coeff_int, + const bool compute_auxiliary_right_hand_side, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) +{ + const unsigned int n_soln_dofs = fe_soln.dofs_per_cell; + + AssertDimension (n_soln_dofs, soln_dofs_indices.size()); + + const unsigned int n_metric_dofs = this->high_order_grid->fe_system.dofs_per_cell; + + std::vector local_dual(n_soln_dofs); + for (unsigned int itest=0; itestdual[global_residual_row]; + } + + + unsigned int w_start=0, w_end=0, x_start=0, x_end=0; + if(compute_dRdW || compute_dRdX || compute_d2R) + { + automatic_differentiation_indexing_1( compute_dRdW, compute_dRdX, compute_d2R, + n_soln_dofs, n_metric_dofs, + w_start, w_end, x_start, x_end ); + } + + using TH = codi_TapeHelper; + TH th; + typename adtype::TapeType &tape = adtype::getGlobalTape(); + if (compute_dRdX || compute_d2R) { + for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { + th.getinputValues().push_back(local_metric_coeff_int[idof].getGradientData()); + } + } + + std::vector local_solution(fe_soln.dofs_per_cell); + for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { + const real val = this->solution(soln_dofs_indices[idof]); + local_solution[idof] = val; + + if (compute_dRdW || compute_d2R) { + th.registerInput(local_solution[idof]); + } else { + tape.deactivateValue(local_solution[idof]); + } + } + dealii::Tensor<1,dim,std::vector> local_aux_solution; + for(unsigned int idim=0; idimuse_auxiliary_eq){//only if use auxiliary equation has the auxiliary solution initialized + const real val = this->auxiliary_solution[idim](soln_dofs_indices[idof]); + local_aux_solution[idim][idof] = val; + } + + if ((compute_dRdW || compute_d2R) && this->use_auxiliary_eq) { + th.registerInput(local_aux_solution[idim][idof]); + } else { + tape.deactivateValue(local_aux_solution[idim][idof]); + } + } + } + + adtype dual_dot_residual = 0.0; + std::vector rhs(n_soln_dofs); + dealii::Tensor<1,dim,std::vector> rhs_aux; + if(compute_auxiliary_right_hand_side){ + for(int idim=0; idim(rhs_aux[idim][itest]); + AssertIsFinite(local_auxiliary_RHS[idim][itest]); + } + } + } + else{ + for (unsigned int itest=0; itest(rhs[itest]); + AssertIsFinite(local_rhs_cell[itest]); + } + } + + if (compute_dRdW) { + typename TH::JacobianType& jac = th.createJacobian(); + th.evalJacobian(jac); + for (unsigned int itest=0; itest residual_derivatives(n_soln_dofs); + for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { + const unsigned int i_dx = idof+w_start; + residual_derivatives[idof] = jac(itest,i_dx); + AssertIsFinite(residual_derivatives[idof]); + } + const bool elide_zero_values = false; + this->system_matrix.add(soln_dofs_indices[itest], soln_dofs_indices, residual_derivatives, elide_zero_values); + } + th.deleteJacobian(jac); + } + + if (compute_dRdX) { + typename TH::JacobianType& jac = th.createJacobian(); + th.evalJacobian(jac); + for (unsigned int itest=0; itest residual_derivatives(n_metric_dofs); + for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { + const unsigned int i_dx = idof+x_start; + residual_derivatives[idof] = jac(itest,i_dx); + } + this->dRdXv.add(soln_dofs_indices[itest], metric_dofs_indices, residual_derivatives); + } + th.deleteJacobian(jac); + } + + if (compute_d2R) { + typename TH::HessianType& hes = th.createHessian(); + th.evalHessian(hes); + + int i_dependent = (compute_dRdW || compute_dRdX) ? n_soln_dofs : 0; + + std::vector dWidW(n_soln_dofs); + std::vector dWidX(n_metric_dofs); + std::vector dXidX(n_metric_dofs); + + for (unsigned int idof=0; idofd2RdWdW.add(soln_dofs_indices[idof], soln_dofs_indices, dWidW); + + for (unsigned int jdof=0; jdofd2RdWdX.add(soln_dofs_indices[idof], metric_dofs_indices, dWidX); + } + + for (unsigned int idof=0; idofd2RdXdX.add(metric_dofs_indices[idof], metric_dofs_indices, dXidX); + } + + th.deleteHessian(hes); + } + + for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { + tape.deactivateValue(local_solution[idof]); + for(int idim=0; idim +template +void DGBase::assemble_boundary_codi_taped_derivatives_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const unsigned int iface, + const unsigned int boundary_id, + const real penalty, + const std::vector &soln_dofs_indices, + const std::vector &metric_dofs_indices, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + const dealii::FESystem &fe_soln, + std::vector &local_rhs_cell, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + std::vector &local_metric_coeff, + const bool compute_auxiliary_right_hand_side, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) +{ + const unsigned int n_soln_dofs = fe_soln.dofs_per_cell; + const unsigned int n_metric_dofs = this->high_order_grid->fe_system.dofs_per_cell; + + AssertDimension (n_soln_dofs, soln_dofs_indices.size()); + + std::vector local_solution(fe_soln.dofs_per_cell); + + unsigned int w_start=0, w_end=0, x_start=0, x_end=0; + if(compute_dRdW || compute_dRdX || compute_d2R) + { + automatic_differentiation_indexing_1( compute_dRdW, compute_dRdX, compute_d2R, + n_soln_dofs, n_metric_dofs, + w_start, w_end, x_start, x_end ); + } + + using TH = codi_TapeHelper; + TH th; + typename adtype::TapeType &tape = adtype::getGlobalTape(); + if (compute_dRdX || compute_d2R) { + for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { + th.getinputValues().push_back(local_metric_coeff[idof].getGradientData()); + } + } + + for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { + const real val = this->solution(soln_dofs_indices[idof]); + local_solution[idof] = val; + + if (compute_dRdW || compute_d2R) { + th.registerInput(local_solution[idof]); + } else { + tape.deactivateValue(local_solution[idof]); + } + } + + dealii::Tensor<1,dim,std::vector> local_aux_solution; + for(int idim=0; idimuse_auxiliary_eq){ + const real val = this->auxiliary_solution[idim](soln_dofs_indices[idof]); + local_aux_solution[idim][idof] = val; + } + + if ((compute_dRdW || compute_d2R) && this->use_auxiliary_eq) { + th.registerInput(local_aux_solution[idim][idof]); + } else { + tape.deactivateValue(local_aux_solution[idim][idof]); + } + } + } + + + std::vector local_dual(n_soln_dofs); + for (unsigned int itest=0; itestdual[soln_dofs_indices[itest]]; + } + + std::vector rhs(n_soln_dofs); + dealii::Tensor<1,dim,std::vector> aux_rhs; + if(compute_auxiliary_right_hand_side){ + for(int idim=0; idim(rhs[itest]); + AssertIsFinite(local_rhs_cell[itest]); + } + + if(compute_auxiliary_right_hand_side){ + for(int idim=0; idim(aux_rhs[idim][itest]); + AssertIsFinite(local_auxiliary_RHS[idim][itest]); + } + } + } + + if (compute_dRdW) { + typename TH::JacobianType& jac = th.createJacobian(); + th.evalJacobian(jac); + for (unsigned int itest=0; itest residual_derivatives(n_soln_dofs); + for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { + const unsigned int i_dx = idof+w_start; + residual_derivatives[idof] = jac(itest,i_dx); + AssertIsFinite(residual_derivatives[idof]); + } + const bool elide_zero_values = false; + this->system_matrix.add(soln_dofs_indices[itest], soln_dofs_indices, residual_derivatives, elide_zero_values); + } + th.deleteJacobian(jac); + + } + + if (compute_dRdX) { + typename TH::JacobianType& jac = th.createJacobian(); + th.evalJacobian(jac); + for (unsigned int itest=0; itest residual_derivatives(n_metric_dofs); + for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { + const unsigned int i_dx = idof+x_start; + residual_derivatives[idof] = jac(itest,i_dx); + } + this->dRdXv.add(soln_dofs_indices[itest], metric_dofs_indices, residual_derivatives); + } + th.deleteJacobian(jac); + } + + if (compute_d2R) { + typename TH::HessianType& hes = th.createHessian(); + th.evalHessian(hes); + + int i_dependent = (compute_dRdW || compute_dRdX) ? n_soln_dofs : 0; + + std::vector dWidW(n_soln_dofs); + std::vector dWidX(n_metric_dofs); + std::vector dXidX(n_metric_dofs); + + for (unsigned int idof=0; idofd2RdWdW.add(soln_dofs_indices[idof], soln_dofs_indices, dWidW); + + for (unsigned int jdof=0; jdofd2RdWdX.add(soln_dofs_indices[idof], metric_dofs_indices, dWidX); + } + + for (unsigned int idof=0; idofd2RdXdX.add(metric_dofs_indices[idof], metric_dofs_indices, dXidX); + } + + th.deleteHessian(hes); + } + for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { + tape.deactivateValue(local_solution[idof]); + } + +} + +template +template +void DGBase::assemble_face_codi_taped_derivatives_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + typename dealii::DoFHandler::active_cell_iterator neighbor_cell, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const real penalty, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + const dealii::FESystem &fe_int, + const dealii::FESystem &fe_ext, + const std::vector &soln_dofs_indices_int, + const std::vector &soln_dofs_indices_ext, + const std::vector &metric_dofs_indices_int, + const std::vector &metric_dofs_indices_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const unsigned int grid_degree_int, + const unsigned int grid_degree_ext, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + std::vector &metric_coeff_int, + std::vector &local_rhs_int_cell, + std::vector &local_rhs_ext_cell, + dealii::Tensor<1,dim,std::vector> ¤t_cell_rhs_aux, + dealii::LinearAlgebra::distributed::Vector &rhs, + std::array,dim> &rhs_aux, + const bool compute_auxiliary_right_hand_side, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + const bool is_a_subface, + const unsigned int neighbor_i_subface) +{ + const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; + const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; + const unsigned int n_soln_dofs_int = fe_int.dofs_per_cell; + const unsigned int n_soln_dofs_ext = fe_ext.dofs_per_cell; + + AssertDimension (n_soln_dofs_int, soln_dofs_indices_int.size()); + AssertDimension (n_soln_dofs_ext, soln_dofs_indices_ext.size()); + + std::vector soln_coeff_int(fe_int.dofs_per_cell); + std::vector soln_coeff_ext(fe_ext.dofs_per_cell); + std::vector metric_coeff_ext(fe_metric.dofs_per_cell); + dealii::Tensor<1,dim,std::vector> aux_soln_coeff_int; + dealii::Tensor<1,dim,std::vector> aux_soln_coeff_ext; + + // Current derivative ordering is: metric_int, metric_ext, soln_int, soln_ext + unsigned int w_int_start=0, w_int_end=0, w_ext_start=0, w_ext_end=0, + x_int_start=0, x_int_end=0, x_ext_start=0, x_ext_end=0; + if(compute_dRdW || compute_dRdX || compute_d2R) + { + automatic_differentiation_indexing_2( + compute_dRdW, compute_dRdX, compute_d2R, + n_soln_dofs_int, n_soln_dofs_ext, n_metric_dofs, + w_int_start, w_int_end, w_ext_start, w_ext_end, + x_int_start, x_int_end, x_ext_start, x_ext_end); + } + + using TH = codi_TapeHelper; + TH th; + typename adtype::TapeType &tape = adtype::getGlobalTape(); + + if (compute_dRdX || compute_d2R) { + for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { + th.getinputValues().push_back(metric_coeff_int[idof].getGradientData()); + } + } + + for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { + const real val = this->high_order_grid->volume_nodes[metric_dofs_indices_ext[idof]]; + metric_coeff_ext[idof] = val; + if (compute_dRdX || compute_d2R) { + th.registerInput(metric_coeff_ext[idof]); + } else { + tape.deactivateValue(metric_coeff_ext[idof]); + } + } + for (unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) { + const real val = this->solution(soln_dofs_indices_int[idof]); + soln_coeff_int[idof] = val; + if (compute_dRdW || compute_d2R) { + th.registerInput(soln_coeff_int[idof]); + } else { + tape.deactivateValue(soln_coeff_int[idof]); + } + } + for (unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) { + const real val = this->solution(soln_dofs_indices_ext[idof]); + soln_coeff_ext[idof] = val; + if (compute_dRdW || compute_d2R) { + th.registerInput(soln_coeff_ext[idof]); + } else { + tape.deactivateValue(soln_coeff_ext[idof]); + } + } + for(int idim=0; idimuse_auxiliary_eq){ + const real val = this->auxiliary_solution[idim](soln_dofs_indices_int[idof]); + aux_soln_coeff_int[idim][idof] = val; + } + if ((compute_dRdW || compute_d2R) && this->use_auxiliary_eq) { + th.registerInput(aux_soln_coeff_int[idim][idof]); + } else { + tape.deactivateValue(aux_soln_coeff_int[idim][idof]); + } + } + for (unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) { + if(this->use_auxiliary_eq){ + const real val = this->auxiliary_solution[idim](soln_dofs_indices_ext[idof]); + aux_soln_coeff_ext[idim][idof] = val; + } + if ((compute_dRdW || compute_d2R) && this->use_auxiliary_eq) { + th.registerInput(aux_soln_coeff_ext[idim][idof]); + } else { + tape.deactivateValue(aux_soln_coeff_ext[idim][idof]); + } + } + } + + std::vector dual_int(n_soln_dofs_int); + std::vector dual_ext(n_soln_dofs_ext); + + for (unsigned int itest=0; itestdual[global_residual_row]; + } + for (unsigned int itest=0; itestdual[global_residual_row]; + } + + std::vector rhs_int(n_soln_dofs_int); + std::vector rhs_ext(n_soln_dofs_ext); + dealii::Tensor<1,dim,std::vector> aux_rhs_int; + dealii::Tensor<1,dim,std::vector> aux_rhs_ext; + if(compute_auxiliary_right_hand_side){ + for(int idim=0; idim(aux_rhs_int[idim][itest_int]); + } + // for (unsigned int itest_ext=0; itest_ext(aux_rhs_ext[idim][itest_ext]); + // } + + // Add local contribution from neighbor cell to global vector + for (unsigned int itest_ext=0; itest_ext(aux_rhs_ext[idim][itest_ext]); + } + } + } + else{ + for (unsigned int itest_int=0; itest_int(rhs_int[itest_int]); + } + for (unsigned int itest_ext=0; itest_ext(rhs_ext[itest_ext]); + } + + // Add local contribution from neighbor cell to global vector + for (unsigned int itest_ext=0; itest_ext residual_derivatives(n_soln_dofs_int); + + for (unsigned int itest_int=0; itest_intsystem_matrix.add(soln_dofs_indices_int[itest_int], soln_dofs_indices_int, residual_derivatives, elide_zero_values); + + // dR_int_dW_ext + residual_derivatives.resize(n_soln_dofs_ext); + for (unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) { + const unsigned int i_dx = idof+w_ext_start; + residual_derivatives[idof] = jac(i_dependent,i_dx); + } + this->system_matrix.add(soln_dofs_indices_int[itest_int], soln_dofs_indices_ext, residual_derivatives, elide_zero_values); + } + + for (unsigned int itest_ext=0; itest_extsystem_matrix.add(soln_dofs_indices_ext[itest_ext], soln_dofs_indices_int, residual_derivatives, elide_zero_values); + + // dR_ext_dW_ext + residual_derivatives.resize(n_soln_dofs_ext); + for (unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) { + const unsigned int i_dx = idof+w_ext_start; + residual_derivatives[idof] = jac(i_dependent,i_dx); + } + this->system_matrix.add(soln_dofs_indices_ext[itest_ext], soln_dofs_indices_ext, residual_derivatives, elide_zero_values); + } + } + + if (compute_dRdX) { + std::vector residual_derivatives(n_metric_dofs); + + for (unsigned int itest_int=0; itest_intdRdXv.add(soln_dofs_indices_int[itest_int], metric_dofs_indices_int, residual_derivatives); + + // dR_int_dX_ext + for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { + const unsigned int i_dx = idof+x_ext_start; + residual_derivatives[idof] = jac(i_dependent,i_dx); + } + this->dRdXv.add(soln_dofs_indices_int[itest_int], metric_dofs_indices_ext, residual_derivatives); + } + + for (unsigned int itest_ext=0; itest_extdRdXv.add(soln_dofs_indices_ext[itest_ext], metric_dofs_indices_int, residual_derivatives); + + // dR_ext_dX_ext + for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { + const unsigned int i_dx = idof+x_ext_start; + residual_derivatives[idof] = jac(i_dependent,i_dx); + } + this->dRdXv.add(soln_dofs_indices_ext[itest_ext], metric_dofs_indices_ext, residual_derivatives); + } + } + + th.deleteJacobian(jac); + } + + if (compute_d2R) { + typename TH::HessianType& hes = th.createHessian(); + th.evalHessian(hes); + + std::vector dWidW(n_soln_dofs_int); + std::vector dWidX(n_metric_dofs); + std::vector dXidX(n_metric_dofs); + + int i_dependent = (compute_dRdW || compute_dRdX) ? n_soln_dofs_int + n_soln_dofs_ext : 0; + + for (unsigned int idof=0; idofd2RdWdW.add(soln_dofs_indices_int[idof], soln_dofs_indices_int, dWidW); + + // dWint_dWext + for (unsigned int jdof=0; jdofd2RdWdW.add(soln_dofs_indices_int[idof], soln_dofs_indices_ext, dWidW); + + // dWint_dXint + for (unsigned int jdof=0; jdofd2RdWdX.add(soln_dofs_indices_int[idof], metric_dofs_indices_int, dWidX); + + // dWint_dXext + for (unsigned int jdof=0; jdofd2RdWdX.add(soln_dofs_indices_int[idof], metric_dofs_indices_ext, dWidX); + } + + for (unsigned int idof=0; idofd2RdXdX.add(metric_dofs_indices_int[idof], metric_dofs_indices_int, dXidX); + + // dXint_dXext + for (unsigned int jdof=0; jdofd2RdXdX.add(metric_dofs_indices_int[idof], metric_dofs_indices_ext, dXidX); + } + + dWidW.resize(n_soln_dofs_ext); + + for (unsigned int idof=0; idofd2RdWdW.add(soln_dofs_indices_ext[idof], soln_dofs_indices_int, dWidW); + + // dWext_dWext + for (unsigned int jdof=0; jdofd2RdWdW.add(soln_dofs_indices_ext[idof], soln_dofs_indices_ext, dWidW); + + // dWext_dXint + for (unsigned int jdof=0; jdofd2RdWdX.add(soln_dofs_indices_ext[idof], metric_dofs_indices_int, dWidX); + + // dWext_dXext + for (unsigned int jdof=0; jdofd2RdWdX.add(soln_dofs_indices_ext[idof], metric_dofs_indices_ext, dWidX); + } + + for (unsigned int idof=0; idofd2RdXdX.add(metric_dofs_indices_ext[idof], metric_dofs_indices_int, dXidX); + + // dXext_dXext + for (unsigned int jdof=0; jdofd2RdXdX.add(metric_dofs_indices_ext[idof], metric_dofs_indices_ext, dXidX); + } + + th.deleteHessian(hes); + } + + for (unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) { + tape.deactivateValue(soln_coeff_int[idof]); + } + for (unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) { + tape.deactivateValue(soln_coeff_ext[idof]); + } + for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { + tape.deactivateValue(metric_coeff_ext[idof]); + } + for(int idim=0; idim +template +double DGBase::getValue(const real2 &x) +{ + if constexpr (std::is_same::value) { + return x; + } else { + return getValue(x.value()); + } +} + +template +void DGBase::automatic_differentiation_indexing_1( + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + const unsigned int n_soln_dofs, const unsigned int n_metric_dofs, + unsigned int &w_start, unsigned int &w_end, + unsigned int &x_start, unsigned int &x_end) +{ + w_start = 0; + w_end = 0; + x_start = 0; + x_end = 0; + if (compute_d2R || (compute_dRdW && compute_dRdX)) { + x_start = 0; + x_end = x_start + n_metric_dofs; + w_start = x_end; + w_end = w_start + n_soln_dofs; + } else if (compute_dRdW) { + x_start = 0; + x_end = x_start + 0; + w_start = x_end; + w_end = w_start + n_soln_dofs; + } else if (compute_dRdX) { + x_start = 0; + x_end = x_start + n_metric_dofs; + w_start = x_end; + w_end = w_start + 0; + } //else { + // std::cout << "Called the derivative version of the residual without requesting the derivative" << std::endl; + //} +} + +template +void DGBase::automatic_differentiation_indexing_2( + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + const unsigned int n_soln_dofs_int, const unsigned int n_soln_dofs_ext, const unsigned int n_metric_dofs, + unsigned int &w_int_start, unsigned int &w_int_end, unsigned int &w_ext_start, unsigned int &w_ext_end, + unsigned int &x_int_start, unsigned int &x_int_end, unsigned int &x_ext_start, unsigned int &x_ext_end) +{ + // Current derivative order is: metric_int, metric_ext, soln_int, soln_ext + w_int_start = 0; w_int_end = 0; w_ext_start = 0; w_ext_end = 0; + x_int_start = 0; x_int_end = 0; x_ext_start = 0; x_ext_end = 0; + if (compute_d2R || (compute_dRdW && compute_dRdX)) { + x_int_start = 0; + x_int_end = x_int_start + n_metric_dofs; + x_ext_start = x_int_end; + x_ext_end = x_ext_start + n_metric_dofs; + w_int_start = x_ext_end; + w_int_end = w_int_start + n_soln_dofs_int; + w_ext_start = w_int_end; + w_ext_end = w_ext_start + n_soln_dofs_ext; + } else if (compute_dRdW) { + x_int_start = 0; + x_int_end = 0; + x_ext_start = 0; + x_ext_end = 0; + w_int_start = x_ext_end; + w_int_end = w_int_start + n_soln_dofs_int; + w_ext_start = w_int_end; + w_ext_end = w_ext_start + n_soln_dofs_ext; + } else if (compute_dRdX) { + x_int_start = 0; + x_int_end = x_int_start + n_metric_dofs; + x_ext_start = x_int_end; + x_ext_end = x_ext_start + n_metric_dofs; + w_int_start = x_ext_end; + w_int_end = w_int_start + 0; + w_ext_start = w_int_end; + w_ext_end = w_ext_start + 0; + } //else { + //std::cout << "Called the derivative version of the residual without requesting the derivative" << std::endl; + //} +} + + template void DGBase::set_dual(const dealii::LinearAlgebra::distributed::Vector &dual_input) { @@ -1046,14 +2139,14 @@ void DGBase::reinit_operators_for_cell_residual_loop( const unsigned int poly_degree_int, const unsigned int poly_degree_ext, const unsigned int /*grid_degree*/, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::mapping_shape_functions &mapping_basis) + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis) { soln_basis_int.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree_int], oneD_quadrature_collection[poly_degree_int]); soln_basis_int.build_1D_gradient_operator(oneD_fe_collection_1state[poly_degree_int], oneD_quadrature_collection[poly_degree_int]); @@ -1214,14 +2307,14 @@ void DGBase::assemble_residual (const bool compute_dRdW, cons dealii::hp::FEValues fe_values_collection_volume_lagrange (mapping_collection, fe_collection_lagrange, volume_quadrature_collection, this->volume_update_flags); const unsigned int init_grid_degree = high_order_grid->fe_system.tensor_degree(); - OPERATOR::basis_functions soln_basis_int(1, max_degree, init_grid_degree); - OPERATOR::basis_functions soln_basis_ext(1, max_degree, init_grid_degree); - OPERATOR::basis_functions flux_basis_int(1, max_degree, init_grid_degree); - OPERATOR::basis_functions flux_basis_ext(1, max_degree, init_grid_degree); - OPERATOR::local_basis_stiffness flux_basis_stiffness(1, max_degree, init_grid_degree, true); - OPERATOR::vol_projection_operator soln_basis_projection_oper_int(1, max_degree, init_grid_degree); - OPERATOR::vol_projection_operator soln_basis_projection_oper_ext(1, max_degree, init_grid_degree); - OPERATOR::mapping_shape_functions mapping_basis(1, init_grid_degree, init_grid_degree); + OPERATOR::basis_functions soln_basis_int(1, max_degree, init_grid_degree); + OPERATOR::basis_functions soln_basis_ext(1, max_degree, init_grid_degree); + OPERATOR::basis_functions flux_basis_int(1, max_degree, init_grid_degree); + OPERATOR::basis_functions flux_basis_ext(1, max_degree, init_grid_degree); + OPERATOR::local_basis_stiffness flux_basis_stiffness(1, max_degree, init_grid_degree, true); + OPERATOR::vol_projection_operator soln_basis_projection_oper_int(1, max_degree, init_grid_degree); + OPERATOR::vol_projection_operator soln_basis_projection_oper_ext(1, max_degree, init_grid_degree); + OPERATOR::mapping_shape_functions mapping_basis(1, init_grid_degree, init_grid_degree); reinit_operators_for_cell_residual_loop( max_degree, max_degree, init_grid_degree, @@ -1244,7 +2337,7 @@ void DGBase::assemble_residual (const bool compute_dRdW, cons if(all_parameters->pde_type == Parameters::AllParameters::PartialDifferentialEquation::physics_model) update_model_variables(); // assembles and solves for auxiliary variable if necessary. - assemble_auxiliary_residual(); + assemble_auxiliary_residual(compute_dRdW, compute_dRdX, compute_d2R); dealii::Timer timer; if(all_parameters->store_residual_cpu_time){ @@ -1254,28 +2347,54 @@ void DGBase::assemble_residual (const bool compute_dRdW, cons auto metric_cell = high_order_grid->dof_handler_grid.begin_active(); for (auto soln_cell = dof_handler.begin_active(); soln_cell != dof_handler.end(); ++soln_cell, ++metric_cell) { if (!soln_cell->is_locally_owned()) continue; - + // Add right-hand side contributions this cell can compute - assemble_cell_residual ( - soln_cell, - metric_cell, - compute_dRdW, compute_dRdX, compute_d2R, - fe_values_collection_volume, - fe_values_collection_face_int, - fe_values_collection_face_ext, - fe_values_collection_subface, - fe_values_collection_volume_lagrange, - soln_basis_int, - soln_basis_ext, - flux_basis_int, - flux_basis_ext, - flux_basis_stiffness, - soln_basis_projection_oper_int, - soln_basis_projection_oper_ext, - mapping_basis, - false, - right_hand_side, - auxiliary_right_hand_side); + if(compute_d2R) + { + assemble_cell_residual_and_ad_derivatives( + soln_cell, + metric_cell, + compute_dRdW, compute_dRdX, compute_d2R, + fe_values_collection_volume, + fe_values_collection_face_int, + fe_values_collection_face_ext, + fe_values_collection_subface, + fe_values_collection_volume_lagrange, + soln_basis_int, + soln_basis_ext, + flux_basis_int, + flux_basis_ext, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + mapping_basis, + false, + right_hand_side, + auxiliary_right_hand_side); + } + else + { + assemble_cell_residual_and_ad_derivatives( + soln_cell, + metric_cell, + compute_dRdW, compute_dRdX, compute_d2R, + fe_values_collection_volume, + fe_values_collection_face_int, + fe_values_collection_face_ext, + fe_values_collection_subface, + fe_values_collection_volume_lagrange, + soln_basis_int, + soln_basis_ext, + flux_basis_int, + flux_basis_ext, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + mapping_basis, + false, + right_hand_side, + auxiliary_right_hand_side); + } } // end of cell loop if(all_parameters->store_residual_cpu_time){ @@ -1906,7 +3025,7 @@ void DGBase::allocate_system ( right_hand_side.reinit(locally_owned_dofs, ghost_dofs, mpi_communicator); right_hand_side.add(1.0); // Avoid 0 initial residual for output and logarithmic visualization. - allocate_dual_vector(); + allocate_dual_vector(compute_d2R); // Set use_auxiliary_eq flag set_use_auxiliary_eq(); @@ -2022,12 +3141,12 @@ template void DGBase::reinit_operators_for_mass_matrix( const bool Cartesian_element, const unsigned int poly_degree, const unsigned int grid_degree, - OPERATOR::mapping_shape_functions &mapping_basis, - OPERATOR::basis_functions &basis, - OPERATOR::local_mass &reference_mass_matrix, - OPERATOR::local_Flux_Reconstruction_operator &reference_FR, - OPERATOR::local_Flux_Reconstruction_operator_aux &reference_FR_aux, - OPERATOR::derivative_p &deriv_p) + OPERATOR::mapping_shape_functions &mapping_basis, + OPERATOR::basis_functions &basis, + OPERATOR::local_mass &reference_mass_matrix, + OPERATOR::local_Flux_Reconstruction_operator &reference_FR, + OPERATOR::local_Flux_Reconstruction_operator_aux &reference_FR_aux, + OPERATOR::derivative_p &deriv_p) { using FR_enum = Parameters::AllParameters::Flux_Reconstruction; const FR_enum FR_Type = this->all_parameters->flux_reconstruction_type; @@ -2112,12 +3231,12 @@ void DGBase::evaluate_mass_matrices (bool do_inverse_mass_mat // setup 1D operators for ONE STATE. We loop over states in assembly for speedup. const unsigned int init_grid_degree = high_order_grid->fe_system.tensor_degree(); - OPERATOR::mapping_shape_functions mapping_basis(1, max_degree, init_grid_degree);//first set at max degree - OPERATOR::basis_functions basis(1, max_degree, init_grid_degree); - OPERATOR::local_mass reference_mass_matrix(1, max_degree, init_grid_degree);//first set at max degree - OPERATOR::local_Flux_Reconstruction_operator reference_FR(1, max_degree, init_grid_degree, FR_Type); - OPERATOR::local_Flux_Reconstruction_operator_aux reference_FR_aux(1, max_degree, init_grid_degree, FR_Type_Aux); - OPERATOR::derivative_p deriv_p(1, max_degree, init_grid_degree); + OPERATOR::mapping_shape_functions mapping_basis(1, max_degree, init_grid_degree);//first set at max degree + OPERATOR::basis_functions basis(1, max_degree, init_grid_degree); + OPERATOR::local_mass reference_mass_matrix(1, max_degree, init_grid_degree);//first set at max degree + OPERATOR::local_Flux_Reconstruction_operator reference_FR(1, max_degree, init_grid_degree, FR_Type); + OPERATOR::local_Flux_Reconstruction_operator_aux reference_FR_aux(1, max_degree, init_grid_degree, FR_Type_Aux); + OPERATOR::derivative_p deriv_p(1, max_degree, init_grid_degree); auto first_cell = dof_handler.begin_active(); const bool Cartesian_first_element = (first_cell->manifold_id() == dealii::numbers::flat_manifold_id); @@ -2158,8 +3277,8 @@ void DGBase::evaluate_mass_matrices (bool do_inverse_mass_mat const dealii::FESystem &fe_metric = high_order_grid->fe_system; const unsigned int n_metric_dofs = high_order_grid->fe_system.dofs_per_cell; const unsigned int n_grid_nodes = n_metric_dofs/dim; - std::vector metric_dof_indices(n_metric_dofs); - metric_cell->get_dof_indices (metric_dof_indices); + std::vector metric_dofs_indices(n_metric_dofs); + metric_cell->get_dof_indices (metric_dofs_indices); // get mapping_support points std::array,dim> mapping_support_points; for(int idim=0; idim::evaluate_mass_matrices (bool do_inverse_mass_mat } const std::vector &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering(curr_grid_degree); for (unsigned int idof = 0; idof< n_metric_dofs; ++idof) { - const real val = (high_order_grid->volume_nodes[metric_dof_indices[idof]]); + const real val = (high_order_grid->volume_nodes[metric_dofs_indices[idof]]); const unsigned int istate = fe_metric.system_to_component_index(idof).first; const unsigned int ishape = fe_metric.system_to_component_index(idof).second; const unsigned int igrid_node = index_renumbering[ishape]; @@ -2231,11 +3350,11 @@ void DGBase::evaluate_local_metric_dependent_mass_matrix_and_ const unsigned int n_dofs_cell, const std::vector dofs_indices, OPERATOR::metric_operators &metric_oper, - OPERATOR::basis_functions &basis, - OPERATOR::local_mass &reference_mass_matrix, - OPERATOR::local_Flux_Reconstruction_operator &reference_FR, - OPERATOR::local_Flux_Reconstruction_operator_aux &reference_FR_aux, - OPERATOR::derivative_p &deriv_p) + OPERATOR::basis_functions &basis, + OPERATOR::local_mass &reference_mass_matrix, + OPERATOR::local_Flux_Reconstruction_operator &reference_FR, + OPERATOR::local_Flux_Reconstruction_operator_aux &reference_FR_aux, + OPERATOR::derivative_p &deriv_p) { using FR_enum = Parameters::AllParameters::Flux_Reconstruction; const FR_enum FR_Type = this->all_parameters->flux_reconstruction_type; @@ -2456,13 +3575,13 @@ void DGBase::apply_inverse_global_mass_matrix( const FR_Aux_enum FR_Type_Aux = this->all_parameters->flux_reconstruction_aux_type; const unsigned int init_grid_degree = high_order_grid->fe_system.tensor_degree(); - OPERATOR::mapping_shape_functions mapping_basis(1, init_grid_degree, init_grid_degree); + OPERATOR::mapping_shape_functions mapping_basis(1, init_grid_degree, init_grid_degree); - OPERATOR::FR_mass_inv mass_inv(1, max_degree, init_grid_degree, FR_Type); - OPERATOR::FR_mass_inv_aux mass_inv_aux(1, max_degree, init_grid_degree, FR_Type_Aux); + OPERATOR::FR_mass_inv mass_inv(1, max_degree, init_grid_degree, FR_Type); + OPERATOR::FR_mass_inv_aux mass_inv_aux(1, max_degree, init_grid_degree, FR_Type_Aux); - OPERATOR::vol_projection_operator_FR projection_oper(1, max_degree, init_grid_degree, FR_Type, true); - OPERATOR::vol_projection_operator_FR_aux projection_oper_aux(1, max_degree, init_grid_degree, FR_Type_Aux, true); + OPERATOR::vol_projection_operator_FR projection_oper(1, max_degree, init_grid_degree, FR_Type, true); + OPERATOR::vol_projection_operator_FR_aux projection_oper_aux(1, max_degree, init_grid_degree, FR_Type_Aux, true); mapping_basis.build_1D_shape_functions_at_volume_flux_nodes(high_order_grid->oneD_fe_system, oneD_quadrature_collection[max_degree]); @@ -2528,8 +3647,8 @@ void DGBase::apply_inverse_global_mass_matrix( // get mapping support points and determinant of Jacobian // setup metric cell - std::vector metric_dof_indices(n_metric_dofs); - metric_cell->get_dof_indices (metric_dof_indices); + std::vector metric_dofs_indices(n_metric_dofs); + metric_cell->get_dof_indices (metric_dofs_indices); // get mapping_support points std::array,dim> mapping_support_points; for(int idim=0; idim::apply_inverse_global_mass_matrix( } const std::vector &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering(grid_degree); for (unsigned int idof = 0; idof< n_metric_dofs; ++idof) { - const real val = (high_order_grid->volume_nodes[metric_dof_indices[idof]]); + const real val = (high_order_grid->volume_nodes[metric_dofs_indices[idof]]); const unsigned int istate = fe_metric.system_to_component_index(idof).first; const unsigned int ishape = fe_metric.system_to_component_index(idof).second; const unsigned int igrid_node = index_renumbering[ishape]; @@ -2633,12 +3752,12 @@ void DGBase::apply_global_mass_matrix( const FR_Aux_enum FR_Type_Aux = this->all_parameters->flux_reconstruction_aux_type; const unsigned int init_grid_degree = high_order_grid->fe_system.tensor_degree(); - OPERATOR::mapping_shape_functions mapping_basis(1, max_degree, init_grid_degree); + OPERATOR::mapping_shape_functions mapping_basis(1, max_degree, init_grid_degree); - OPERATOR::FR_mass mass(1, max_degree, init_grid_degree, FR_Type); - OPERATOR::FR_mass_aux mass_aux(1, max_degree, init_grid_degree, FR_Type_Aux); + OPERATOR::FR_mass mass(1, max_degree, init_grid_degree, FR_Type); + OPERATOR::FR_mass_aux mass_aux(1, max_degree, init_grid_degree, FR_Type_Aux); - OPERATOR::vol_projection_operator projection_oper(1, max_degree, init_grid_degree); + OPERATOR::vol_projection_operator projection_oper(1, max_degree, init_grid_degree); mapping_basis.build_1D_shape_functions_at_volume_flux_nodes(high_order_grid->oneD_fe_system, oneD_quadrature_collection[max_degree]); @@ -2694,8 +3813,8 @@ void DGBase::apply_global_mass_matrix( //get mapping support points and determinant of Jacobian //setup metric cell - std::vector metric_dof_indices(n_metric_dofs); - metric_cell->get_dof_indices (metric_dof_indices); + std::vector metric_dofs_indices(n_metric_dofs); + metric_cell->get_dof_indices (metric_dofs_indices); // get mapping_support points std::array,dim> mapping_support_points; for(int idim=0; idim::apply_global_mass_matrix( } const std::vector &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering(grid_degree); for (unsigned int idof = 0; idof< n_metric_dofs; ++idof) { - const real val = (high_order_grid->volume_nodes[metric_dof_indices[idof]]); + const real val = (high_order_grid->volume_nodes[metric_dofs_indices[idof]]); const unsigned int istate = fe_metric.system_to_component_index(idof).first; const unsigned int ishape = fe_metric.system_to_component_index(idof).second; const unsigned int igrid_node = index_renumbering[ishape]; @@ -3046,69 +4165,139 @@ template FadFadType DGBase>::discontinuity_sensor(const dealii::Quadrature &volume_quadrature, const std::vector< RadFadType > &soln_coeff_high, const dealii::FiniteElement &fe_high, const std::vector &jac_det); -template void -DGBase>::assemble_cell_residual>,dealii::TriaActiveIterator>>( + +template void +DGBase>::assemble_cell_residual_and_ad_derivatives ( const dealii::TriaActiveIterator> ¤t_cell, const dealii::TriaActiveIterator> ¤t_metric_cell, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, - dealii::hp::FEValues &fe_values_collection_volume, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - dealii::hp::FEFaceValues &fe_values_collection_face_ext, - dealii::hp::FESubfaceValues &fe_values_collection_subface, - dealii::hp::FEValues &fe_values_collection_volume_lagrange, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::mapping_shape_functions &mapping_basis, - const bool compute_auxiliary_right_hand_side, - dealii::LinearAlgebra::distributed::Vector &rhs, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + const bool compute_auxiliary_right_hand_side,//flag on whether computing the Auxiliary variable's equations' residuals + dealii::LinearAlgebra::distributed::Vector &rhs, std::array,PHILIP_DIM> &rhs_aux); -template void -DGBase>::assemble_cell_residual>,dealii::TriaActiveIterator>>( +template void +DGBase>::assemble_cell_residual_and_ad_derivatives ( const dealii::TriaActiveIterator> ¤t_cell, const dealii::TriaActiveIterator> ¤t_metric_cell, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, - dealii::hp::FEValues &fe_values_collection_volume, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - dealii::hp::FEFaceValues &fe_values_collection_face_ext, - dealii::hp::FESubfaceValues &fe_values_collection_subface, - dealii::hp::FEValues &fe_values_collection_volume_lagrange, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::mapping_shape_functions &mapping_basis, - const bool compute_auxiliary_right_hand_side, - dealii::LinearAlgebra::distributed::Vector &rhs, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + const bool compute_auxiliary_right_hand_side,//flag on whether computing the Auxiliary variable's equations' residuals + dealii::LinearAlgebra::distributed::Vector &rhs, std::array,PHILIP_DIM> &rhs_aux); -template void -DGBase>::assemble_cell_residual>,dealii::TriaActiveIterator>>( +template void +DGBase>::assemble_cell_residual_and_ad_derivatives ( const dealii::TriaActiveIterator> ¤t_cell, const dealii::TriaActiveIterator> ¤t_metric_cell, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, - dealii::hp::FEValues &fe_values_collection_volume, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - dealii::hp::FEFaceValues &fe_values_collection_face_ext, - dealii::hp::FESubfaceValues &fe_values_collection_subface, - dealii::hp::FEValues &fe_values_collection_volume_lagrange, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::mapping_shape_functions &mapping_basis, - const bool compute_auxiliary_right_hand_side, - dealii::LinearAlgebra::distributed::Vector &rhs, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + const bool compute_auxiliary_right_hand_side,//flag on whether computing the Auxiliary variable's equations' residuals + dealii::LinearAlgebra::distributed::Vector &rhs, + std::array,PHILIP_DIM> &rhs_aux); + +template void +DGBase>::assemble_cell_residual_and_ad_derivatives ( + const dealii::TriaActiveIterator> ¤t_cell, + const dealii::TriaActiveIterator> ¤t_metric_cell, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + const bool compute_auxiliary_right_hand_side,//flag on whether computing the Auxiliary variable's equations' residuals + dealii::LinearAlgebra::distributed::Vector &rhs, std::array,PHILIP_DIM> &rhs_aux); + + + +template void +DGBase>::assemble_cell_residual_and_ad_derivatives ( + const dealii::TriaActiveIterator> ¤t_cell, + const dealii::TriaActiveIterator> ¤t_metric_cell, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + const bool compute_auxiliary_right_hand_side,//flag on whether computing the Auxiliary variable's equations' residuals + dealii::LinearAlgebra::distributed::Vector &rhs, + std::array,PHILIP_DIM> &rhs_aux); + +template void +DGBase>::assemble_cell_residual_and_ad_derivatives ( + const dealii::TriaActiveIterator> ¤t_cell, + const dealii::TriaActiveIterator> ¤t_metric_cell, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + const bool compute_auxiliary_right_hand_side,//flag on whether computing the Auxiliary variable's equations' residuals + dealii::LinearAlgebra::distributed::Vector &rhs, + std::array,PHILIP_DIM> &rhs_aux); + } // PHiLiP namespace diff --git a/src/dg/dg_base.hpp b/src/dg/dg_base.hpp index c1d1a5e79..f14274beb 100644 --- a/src/dg/dg_base.hpp +++ b/src/dg/dg_base.hpp @@ -217,48 +217,48 @@ class DGBase /// Builds needed operators for cell residual loop. void reinit_operators_for_cell_residual_loop( - const unsigned int poly_degree_int, - const unsigned int poly_degree_ext, - const unsigned int grid_degree, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::mapping_shape_functions &mapping_basis); + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis); /// Builds needed operators to compute mass matrices/inverses efficiently. void reinit_operators_for_mass_matrix( - const bool Cartesian_element, - const unsigned int poly_degree, - const unsigned int grid_degree, - OPERATOR::mapping_shape_functions &mapping_basis, - OPERATOR::basis_functions &basis, - OPERATOR::local_mass &reference_mass_matrix, - OPERATOR::local_Flux_Reconstruction_operator &reference_FR, - OPERATOR::local_Flux_Reconstruction_operator_aux &reference_FR_aux, - OPERATOR::derivative_p &deriv_p); + const bool Cartesian_element, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::mapping_shape_functions &mapping_basis, + OPERATOR::basis_functions &basis, + OPERATOR::local_mass &reference_mass_matrix, + OPERATOR::local_Flux_Reconstruction_operator &reference_FR, + OPERATOR::local_Flux_Reconstruction_operator_aux &reference_FR_aux, + OPERATOR::derivative_p &deriv_p); /// Allocates and evaluates the mass matrices for the entire grid void evaluate_mass_matrices (bool do_inverse_mass_matrix = false); /// Evaluates the metric dependent local mass matrices and inverses, then sets them in the global matrices. void evaluate_local_metric_dependent_mass_matrix_and_set_in_global_mass_matrix( - const bool Cartesian_element,//Flag if cell is Cartesian - const bool do_inverse_mass_matrix, - const unsigned int poly_degree, - const unsigned int curr_grid_degree, - const unsigned int n_quad_pts, - const unsigned int n_dofs_cell, - const std::vector dofs_indices, - OPERATOR::metric_operators &metric_oper, - OPERATOR::basis_functions &basis, - OPERATOR::local_mass &reference_mass_matrix, - OPERATOR::local_Flux_Reconstruction_operator &reference_FR, - OPERATOR::local_Flux_Reconstruction_operator_aux &reference_FR_aux, - OPERATOR::derivative_p &deriv_p); + const bool Cartesian_element,//Flag if cell is Cartesian + const bool do_inverse_mass_matrix, + const unsigned int poly_degree, + const unsigned int curr_grid_degree, + const unsigned int n_quad_pts, + const unsigned int n_dofs_cell, + const std::vector dofs_indices, + OPERATOR::metric_operators &metric_oper, + OPERATOR::basis_functions &basis, + OPERATOR::local_mass &reference_mass_matrix, + OPERATOR::local_Flux_Reconstruction_operator &reference_FR, + OPERATOR::local_Flux_Reconstruction_operator_aux &reference_FR_aux, + OPERATOR::derivative_p &deriv_p); /// Applies the inverse of the local metric dependent mass matrices when the global is not stored. /** We use matrix-free methods to apply the inverse of the local mass matrix on-the-fly @@ -568,28 +568,443 @@ class DGBase * perform the work on all the faces. * All the active cells must be traversed to ensure that the right hand side is correct. */ - template - void assemble_cell_residual ( - const DoFCellAccessorType1 ¤t_cell, - const DoFCellAccessorType2 ¤t_metric_cell, + template + void assemble_cell_residual_and_ad_derivatives ( + const dealii::TriaActiveIterator> ¤t_cell, + const dealii::TriaActiveIterator> ¤t_metric_cell, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, dealii::hp::FEValues &fe_values_collection_volume, dealii::hp::FEFaceValues &fe_values_collection_face_int, dealii::hp::FEFaceValues &fe_values_collection_face_ext, dealii::hp::FESubfaceValues &fe_values_collection_subface, dealii::hp::FEValues &fe_values_collection_volume_lagrange, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::mapping_shape_functions &mapping_basis, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, const bool compute_auxiliary_right_hand_side,//flag on whether computing the Auxiliary variable's equations' residuals dealii::LinearAlgebra::distributed::Vector &rhs, std::array,dim> &rhs_aux); + template + void assemble_volume_codi_taped_derivatives_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_dofs_indices, + const std::vector &metric_dof_indices, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + const dealii::FESystem &fe_soln, + std::vector &local_rhs_cell, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + std::vector &local_metric_coeff_int, + const bool compute_auxiliary_right_hand_side, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); + + template + void assemble_boundary_codi_taped_derivatives_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const unsigned int iface, + const unsigned int boundary_id, + const real penalty, + const std::vector &soln_dofs_indices, + const std::vector &metric_dof_indices, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + const dealii::FESystem &fe_soln, + std::vector &local_rhs_cell, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + std::vector &local_metric_coeff, + const bool compute_auxiliary_right_hand_side, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); + + template + void assemble_face_codi_taped_derivatives_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + typename dealii::DoFHandler::active_cell_iterator neighbor_cell, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const real penalty, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + const dealii::FESystem &fe_int, + const dealii::FESystem &fe_ext, + const std::vector &soln_dofs_indices_int, + const std::vector &soln_dofs_indices_ext, + const std::vector &metric_dofs_indices_int, + const std::vector &metric_dofs_indices_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const unsigned int grid_degree_int, + const unsigned int grid_degree_ext, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + std::vector &metric_coeff_int, + std::vector &local_rhs_int_cell, + std::vector &local_rhs_ext_cell, + dealii::Tensor<1,dim,std::vector> ¤t_cell_rhs_aux, + dealii::LinearAlgebra::distributed::Vector &rhs, + std::array,dim> &rhs_aux, + const bool compute_auxiliary_right_hand_side, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + const bool is_a_subface = false, + const unsigned int neighbor_i_subface = 0); + + virtual void assemble_volume_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const std::vector &soln_dofs_indices, + const std::vector &metric_dofs_indices, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + const dealii::FESystem &fe_soln, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + double &dual_dot_residual) =0; + + virtual void assemble_volume_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const std::vector &soln_dofs_indices, + const std::vector &metric_dofs_indices, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + const dealii::FESystem &fe_soln, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + codi_JacobianComputationType &dual_dot_residual) =0; + + virtual void assemble_volume_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const std::vector &soln_dofs_indices, + const std::vector &metric_dofs_indices, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + const dealii::FESystem &fe_soln, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + codi_HessianComputationType &dual_dot_residual) =0; + + virtual void assemble_boundary_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const unsigned int face_number, + const unsigned int boundary_id, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + const dealii::FESystem &fe_soln, + const real penalty, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + double &dual_dot_residual) =0; + + virtual void assemble_boundary_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const unsigned int face_number, + const unsigned int boundary_id, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + const dealii::FESystem &fe_soln, + const real penalty, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + codi_JacobianComputationType &dual_dot_residual) =0; + + virtual void assemble_boundary_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const unsigned int face_number, + const unsigned int boundary_id, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + const dealii::FESystem &fe_soln, + const real penalty, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + codi_HessianComputationType &dual_dot_residual) =0; + + virtual void assemble_face_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + typename dealii::DoFHandler::active_cell_iterator neighbor_cell, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const std::vector &soln_coeff_int, + const std::vector &soln_coeff_ext, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_int, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_ext, + const std::vector &metric_coefF_int, + const std::vector &metric_coefF_ext, + const std::vector< double > &dual_int, + const std::vector< double > &dual_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const unsigned int grid_degree_int, + const unsigned int grid_degree_ext, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + const dealii::FESystem &fe_int, + const dealii::FESystem &fe_ext, + const real penalty, + std::vector &rhs_int, + std::vector &rhs_ext, + dealii::Tensor<1,dim,std::vector> &aux_rhs_int, + dealii::Tensor<1,dim,std::vector> &aux_rhs_ext, + const bool compute_auxiliary_right_hand_side, + double &dual_dot_residual, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + const bool is_a_subface, + const unsigned int neighbor_i_subface) =0; + + virtual void assemble_face_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + typename dealii::DoFHandler::active_cell_iterator neighbor_cell, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const std::vector &soln_coeff_int, + const std::vector &soln_coeff_ext, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_int, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_ext, + const std::vector &metric_coefF_int, + const std::vector &metric_coefF_ext, + const std::vector< double > &dual_int, + const std::vector< double > &dual_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const unsigned int grid_degree_int, + const unsigned int grid_degree_ext, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + const dealii::FESystem &fe_int, + const dealii::FESystem &fe_ext, + const real penalty, + std::vector &rhs_int, + std::vector &rhs_ext, + dealii::Tensor<1,dim,std::vector> &aux_rhs_int, + dealii::Tensor<1,dim,std::vector> &aux_rhs_ext, + const bool compute_auxiliary_right_hand_side, + codi_JacobianComputationType &dual_dot_residual, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + const bool is_a_subface, + const unsigned int neighbor_i_subface) =0; + + virtual void assemble_face_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + typename dealii::DoFHandler::active_cell_iterator neighbor_cell, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const std::vector &soln_coeff_int, + const std::vector &soln_coeff_ext, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_int, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_ext, + const std::vector &metric_coefF_int, + const std::vector &metric_coefF_ext, + const std::vector< double > &dual_int, + const std::vector< double > &dual_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const unsigned int grid_degree_int, + const unsigned int grid_degree_ext, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + const dealii::FESystem &fe_int, + const dealii::FESystem &fe_ext, + const real penalty, + std::vector &rhs_int, + std::vector &rhs_ext, + dealii::Tensor<1,dim,std::vector> &aux_rhs_int, + dealii::Tensor<1,dim,std::vector> &aux_rhs_ext, + const bool compute_auxiliary_right_hand_side, + codi_HessianComputationType &dual_dot_residual, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + const bool is_a_subface, + const unsigned int neighbor_i_subface) =0; + + /// Returns the value from a CoDiPack variable. + /** The recursive calling allows to retrieve nested CoDiPack types. + */ + template + double getValue(const real2 &x); + + /// Derivative indexing when only 1 cell is concerned. + /// Derivatives are ordered such that x comes first with index 0, then w. + /// If derivatives with respect to x are not needed, then derivatives + /// with respect to w will start at index 0. This function is for a single + /// cell's DoFs. + void automatic_differentiation_indexing_1( + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + const unsigned int n_soln_dofs, const unsigned int n_metric_dofs, + unsigned int &w_start, unsigned int &w_end, + unsigned int &x_start, unsigned int &x_end); + + /// Derivative indexing when 2 cells are concerned. + /// Derivatives are ordered such that x comes first with index 0, then w. + /// If derivatives with respect to x are not needed, then derivatives + /// with respect to w will start at index 0. This function is for a single + /// cell's DoFs. + void automatic_differentiation_indexing_2( + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + const unsigned int n_soln_dofs_int, const unsigned int n_soln_dofs_ext, const unsigned int n_metric_dofs, + unsigned int &w_int_start, unsigned int &w_int_end, unsigned int &w_ext_start, unsigned int &w_ext_end, + unsigned int &x_int_start, unsigned int &x_int_end, unsigned int &x_ext_start, unsigned int &x_ext_end); /// Finite Element Collection for p-finite-element to represent the solution /** This is a collection of FESystems */ const dealii::hp::FECollection fe_collection; @@ -670,188 +1085,7 @@ class DGBase /// Artificial dissipation coefficients dealii::LinearAlgebra::distributed::Vector artificial_dissipation_c0; - /// Builds the necessary operators/fe values and assembles volume residual. - virtual void assemble_volume_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const std::vector &cell_dofs_indices, - const std::vector &metric_dof_indices, - const unsigned int poly_degree, - const unsigned int grid_degree, - OPERATOR::basis_functions &soln_basis, - OPERATOR::basis_functions &flux_basis, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::metric_operators &metric_oper, - OPERATOR::mapping_shape_functions &mapping_basis, - std::array,dim> &mapping_support_points, - dealii::hp::FEValues &fe_values_collection_volume, - dealii::hp::FEValues &fe_values_collection_volume_lagrange, - const dealii::FESystem ¤t_fe_ref, - dealii::Vector &local_rhs_int_cell, - std::vector> &local_auxiliary_RHS, - const bool compute_auxiliary_right_hand_side, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) = 0; - - /// Builds the necessary operators/fe values and assembles boundary residual. - virtual void assemble_boundary_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const unsigned int iface, - const unsigned int boundary_id, - const real penalty, - const std::vector &cell_dofs_indices, - const std::vector &metric_dof_indices, - const unsigned int poly_degree, - const unsigned int grid_degree, - OPERATOR::basis_functions &soln_basis, - OPERATOR::basis_functions &flux_basis, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::metric_operators &metric_oper, - OPERATOR::mapping_shape_functions &mapping_basis, - std::array,dim> &mapping_support_points, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - const dealii::FESystem ¤t_fe_ref, - dealii::Vector &local_rhs_int_cell, - std::vector> &local_auxiliary_RHS, - const bool compute_auxiliary_right_hand_side, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) = 0; - - /// Builds the necessary operators/fe values and assembles face residual. - virtual void assemble_face_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator cell, - typename dealii::DoFHandler::active_cell_iterator neighbor_cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const unsigned int iface, - const unsigned int neighbor_iface, - const real penalty, - const std::vector ¤t_dofs_indices, - const std::vector &neighbor_dofs_indices, - const std::vector ¤t_metric_dofs_indices, - const std::vector &neighbor_metric_dofs_indices, - const unsigned int poly_degree_int, - const unsigned int poly_degree_ext, - const unsigned int grid_degree_int, - const unsigned int grid_degree_ext, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::metric_operators &metric_oper_int, - OPERATOR::metric_operators &metric_oper_ext, - OPERATOR::mapping_shape_functions &mapping_basis, - std::array,dim> &mapping_support_points, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - dealii::hp::FEFaceValues &fe_values_collection_face_ext, - dealii::Vector ¤t_cell_rhs, - dealii::Vector &neighbor_cell_rhs, - std::vector> ¤t_cell_rhs_aux, - dealii::LinearAlgebra::distributed::Vector &rhs, - std::array,dim> &rhs_aux, - const bool compute_auxiliary_right_hand_side, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) = 0; - - /// Builds the necessary operators/fe values and assembles subface residual. - virtual void assemble_subface_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator cell, - typename dealii::DoFHandler::active_cell_iterator neighbor_cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const unsigned int iface, - const unsigned int neighbor_iface, - const unsigned int neighbor_i_subface, - const real penalty, - const std::vector ¤t_dofs_indices, - const std::vector &neighbor_dofs_indices, - const std::vector ¤t_metric_dofs_indices, - const std::vector &neighbor_metric_dofs_indices, - const unsigned int poly_degree_int, - const unsigned int poly_degree_ext, - const unsigned int grid_degree_int, - const unsigned int grid_degree_ext, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::metric_operators &metric_oper_int, - OPERATOR::metric_operators &metric_oper_ext, - OPERATOR::mapping_shape_functions &mapping_basis, - std::array,dim> &mapping_support_points, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - dealii::hp::FESubfaceValues &fe_values_collection_subface, - dealii::Vector ¤t_cell_rhs, - dealii::Vector &neighbor_cell_rhs, - std::vector> ¤t_cell_rhs_aux, - dealii::LinearAlgebra::distributed::Vector &rhs, - std::array,dim> &rhs_aux, - const bool compute_auxiliary_right_hand_side, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) = 0; - protected: - /// Evaluate the integral over the cell volume and the specified derivatives. - /** Compute both the right-hand side and the corresponding block of dRdW, dRdX, and/or d2R. */ - virtual void assemble_volume_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::FEValues &,//fe_values_vol, - const dealii::FESystem &fe, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - dealii::Vector &local_rhs_cell, - const dealii::FEValues &/*fe_values_lagrange*/, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) = 0; - /// Evaluate the integral over the cell edges that are on domain boundaries and the specified derivatives. - /** Compute both the right-hand side and the corresponding block of dRdW, dRdX, and/or d2R. */ - virtual void assemble_boundary_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const unsigned int face_number, - const unsigned int boundary_id, - const dealii::FEFaceValuesBase &fe_values_boundary, - const real penalty, - const dealii::FESystem &fe, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - dealii::Vector &local_rhs_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) = 0; - /// Evaluate the integral over the internal cell edges and its specified derivatives. - /** Compute both the right-hand side and the block of the Jacobian. - * This adds the contribution to both cell's residual and effectively - * computes 4 block contributions to dRdX blocks. */ - virtual void assemble_face_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const std::pair face_subface_int, - const std::pair face_subface_ext, - const typename dealii::QProjector::DataSetDescriptor face_data_set_int, - const typename dealii::QProjector::DataSetDescriptor face_data_set_ext, - const dealii::FEFaceValuesBase &,//fe_values_int, - const dealii::FEFaceValuesBase &,//fe_values_ext, - const real penalty, - const dealii::FESystem &fe_int, - const dealii::FESystem &fe_ext, - const dealii::Quadrature &face_quadrature, - const std::vector &metric_dof_indices_int, - const std::vector &metric_dof_indices_ext, - const std::vector &soln_dof_indices_int, - const std::vector &soln_dof_indices_ext, - dealii::Vector &local_rhs_int_cell, - dealii::Vector &local_rhs_ext_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) = 0; - /// Evaluate the integral over the cell volume virtual void assemble_volume_term_explicit( typename dealii::DoFHandler::active_cell_iterator cell, @@ -880,12 +1114,35 @@ class DGBase void allocate_auxiliary_equation (); /// Asembles the auxiliary equations' residuals and solves. - virtual void assemble_auxiliary_residual () = 0; + virtual void assemble_auxiliary_residual (const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) = 0; /// Allocate the dual vector for optimization. /** Currently only used in weak form. */ - virtual void allocate_dual_vector () = 0; + virtual void allocate_dual_vector (const bool compute_d2R) = 0; + + /// Builds volume metric operators (metric cofactor and determinant of metric Jacobian). + virtual void build_volume_metric_operators( + const unsigned int poly_degree, + const unsigned int grid_degree, + const std::vector &metric_coeffs, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points) =0; + virtual void build_volume_metric_operators( + const unsigned int poly_degree, + const unsigned int grid_degree, + const std::vector &metric_coeffs, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points) =0; + virtual void build_volume_metric_operators( + const unsigned int poly_degree, + const unsigned int grid_degree, + const std::vector &metric_coeffs, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points) =0; protected: MPI_Comm mpi_communicator; ///< MPI communicator diff --git a/src/dg/dg_base_state.cpp b/src/dg/dg_base_state.cpp index e4aeea6d9..30efab978 100644 --- a/src/dg/dg_base_state.cpp +++ b/src/dg/dg_base_state.cpp @@ -180,7 +180,7 @@ void DGBaseState::update_model_variables() { template void DGBaseState::set_use_auxiliary_eq() { - this->use_auxiliary_eq = pde_physics_double->has_nonzero_diffusion; + this->use_auxiliary_eq = (pde_physics_double->has_nonzero_diffusion && !this->all_parameters->use_weak_form) ? true : false; } template @@ -236,4 +236,4 @@ BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_SHARED, _, POSSIBLE_NSTATE) template class DGBaseState >; BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_TRIA, _, POSSIBLE_NSTATE) -} // namespace PHiLiP \ No newline at end of file +} // namespace PHiLiP diff --git a/src/dg/dg_base_state.hpp b/src/dg/dg_base_state.hpp index 615cd42cf..8eaa163cc 100644 --- a/src/dg/dg_base_state.hpp +++ b/src/dg/dg_base_state.hpp @@ -113,6 +113,7 @@ class DGBaseState : public DGBase /** Usually called after setting physics. */ void reset_numerical_fluxes(); + }; // end of DGBaseState class } // namespace PHiLiP diff --git a/src/dg/strong_dg.cpp b/src/dg/strong_dg.cpp index 903b2d8d9..fe750a547 100644 --- a/src/dg/strong_dg.cpp +++ b/src/dg/strong_dg.cpp @@ -17,6 +17,18 @@ #include "strong_dg.hpp" +/// Returns the value from a CoDiPack variable. +/** The recursive calling allows to retrieve nested CoDiPack types. + */ +template +double getValue(const real &x) { + if constexpr (std::is_same::value) { + return x; + } else { + return getValue(x.value()); + } +} + namespace PHiLiP { template @@ -29,34 +41,74 @@ DGStrong::DGStrong( : DGBaseState::DGBaseState(parameters_input, degree, max_degree_input, grid_degree_input, triangulation_input) { } +template +template +void DGStrong::build_volume_metric_operators( + const unsigned int poly_degree, + const unsigned int grid_degree, + const std::vector &metric_coeffs, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points) +{ + const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; + const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; + const unsigned int n_grid_nodes = n_metric_dofs / dim; + //Rewrite the high_order_grid->volume_nodes in a way we can use sum-factorization on. + //That is, splitting up the vector by the dimension. + for(int idim=0; idim &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering(grid_degree); + for (unsigned int idof = 0; idof< n_metric_dofs; ++idof) { + const adtype val = metric_coeffs[idof]; + const unsigned int istate = fe_metric.system_to_component_index(idof).first; + const unsigned int ishape = fe_metric.system_to_component_index(idof).second; + const unsigned int igrid_node = index_renumbering[ishape]; + mapping_support_points[istate][igrid_node] = val; + } + metric_oper.build_volume_metric_operators( + this->volume_quadrature_collection[poly_degree].size(), n_grid_nodes, + mapping_support_points, + mapping_basis, + this->all_parameters->use_invariant_curl_form); +} + /*********************************************************** * * Build operators and solve for RHS * ***********************************************************/ + template -void DGStrong::assemble_volume_term_and_build_operators( +template +void DGStrong::assemble_volume_term_and_build_operators_ad_templated( typename dealii::DoFHandler::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, - const std::vector &cell_dofs_indices, - const std::vector &metric_dof_indices, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &/*metric_coeffs*/, + const std::vector &local_dual, + const std::vector &/*soln_dofs_indices*/, + const std::vector &/*metric_dofs_indices*/, const unsigned int poly_degree, const unsigned int grid_degree, - OPERATOR::basis_functions &soln_basis, - OPERATOR::basis_functions &flux_basis, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::metric_operators &metric_oper, - OPERATOR::mapping_shape_functions &mapping_basis, - std::array,dim> &mapping_support_points, + const Physics::PhysicsBase &physics, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &/*mapping_support_points*/, dealii::hp::FEValues &/*fe_values_collection_volume*/, dealii::hp::FEValues &/*fe_values_collection_volume_lagrange*/, - const dealii::FESystem &/*current_fe_ref*/, - dealii::Vector &local_rhs_int_cell, - std::vector> &local_auxiliary_RHS, + const dealii::FESystem &/*fe_soln*/, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, const bool compute_auxiliary_right_hand_side, - const bool /*compute_dRdW*/, const bool /*compute_dRdX*/, const bool /*compute_d2R*/) + adtype &dual_dot_residual) { // Check if the current cell's poly degree etc is different then previous cell's. // If the current cell's poly degree is different, then we recompute the 1D @@ -73,34 +125,36 @@ void DGStrong::assemble_volume_term_and_build_operator mapping_basis); } - const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; - const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; - const unsigned int n_grid_nodes = n_metric_dofs / dim; - //Rewrite the high_order_grid->volume_nodes in a way we can use sum-factorization on. - //That is, splitting up the vector by the dimension. - for(int idim=0; idim &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering(grid_degree); - for (unsigned int idof = 0; idof< n_metric_dofs; ++idof) { - const real val = (this->high_order_grid->volume_nodes[metric_dof_indices[idof]]); - const unsigned int istate = fe_metric.system_to_component_index(idof).first; - const unsigned int ishape = fe_metric.system_to_component_index(idof).second; - const unsigned int igrid_node = index_renumbering[ishape]; - mapping_support_points[istate][igrid_node] = val; + //Fetch the modal soln coefficients and the modal auxiliary soln coefficients + //We immediately separate them by state as to be able to use sum-factorization + //in the interpolation operator. If we left it by n_dofs_cell, then the matrix-vector + //mult would sum the states at the quadrature point. + const unsigned int n_dofs_cell = this->fe_collection[poly_degree].dofs_per_cell; + const unsigned int n_shape_fns = n_dofs_cell / nstate; + std::array,nstate> soln_coeff; + std::array>,nstate> aux_soln_coeff; + for (unsigned int idof = 0; idof < n_dofs_cell; ++idof) { + const unsigned int istate = this->fe_collection[poly_degree].system_to_component_index(idof).first; + const unsigned int ishape = this->fe_collection[poly_degree].system_to_component_index(idof).second; + if(ishape == 0) + soln_coeff[istate].resize(n_shape_fns); + soln_coeff[istate][ishape] = soln_coeffs[idof]; + for(int idim=0; idimuse_auxiliary_eq){ + aux_soln_coeff[istate][idim][ishape] = aux_soln_coeffs[idim][idof]; + } + else{ + aux_soln_coeff[istate][idim][ishape] = 0.0; + } + } } - //build the volume metric cofactor matrix and the determinant of the volume metric Jacobian - //Also, computes the physical volume flux nodes if needed from flag passed to constructor in dg.cpp - metric_oper.build_volume_metric_operators( - this->volume_quadrature_collection[poly_degree].size(), n_grid_nodes, - mapping_support_points, - mapping_basis, - this->all_parameters->use_invariant_curl_form); if(compute_auxiliary_right_hand_side){ - assemble_volume_term_auxiliary_equation ( - cell_dofs_indices, + assemble_volume_term_auxiliary_equation( + soln_coeff, poly_degree, soln_basis, flux_basis, @@ -108,44 +162,54 @@ void DGStrong::assemble_volume_term_and_build_operator local_auxiliary_RHS); } else{ - assemble_volume_term_strong( + assemble_volume_term_strong( cell, current_cell_index, - cell_dofs_indices, + soln_coeff, + aux_soln_coeff, poly_degree, soln_basis, flux_basis, flux_basis_stiffness, soln_basis_projection_oper_int, metric_oper, - local_rhs_int_cell); + physics, + rhs); + for(unsigned int idof=0; idof -void DGStrong::assemble_boundary_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator /*cell*/, - const dealii::types::global_dof_index current_cell_index, - const unsigned int iface, - const unsigned int boundary_id, - const real penalty, - const std::vector &cell_dofs_indices, - const std::vector &/*metric_dof_indices*/, - const unsigned int poly_degree, - const unsigned int /*grid_degree*/, - OPERATOR::basis_functions &soln_basis, - OPERATOR::basis_functions &flux_basis, - OPERATOR::local_basis_stiffness &/*flux_basis_stiffness*/, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_ext*/, - OPERATOR::metric_operators &metric_oper, - OPERATOR::mapping_shape_functions &mapping_basis, - std::array,dim> &mapping_support_points, - dealii::hp::FEFaceValues &/*fe_values_collection_face_int*/, - const dealii::FESystem &/*current_fe_ref*/, - dealii::Vector &local_rhs_int_cell, - std::vector> &local_auxiliary_RHS, - const bool compute_auxiliary_right_hand_side, - const bool /*compute_dRdW*/, const bool /*compute_dRdX*/, const bool /*compute_d2R*/) +template +void DGStrong::assemble_boundary_term_and_build_operators_ad_templated( + typename dealii::DoFHandler::active_cell_iterator /*cell*/, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &/*metric_coeffs*/, + const std::vector &local_dual, + const unsigned int face_number, + const unsigned int boundary_id, + const Physics::PhysicsBase &physics, + const NumericalFlux::NumericalFluxConvective &conv_num_flux, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + const unsigned int poly_degree, + const unsigned int /*grid_degree*/, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &/*fe_values_collection_face_int*/, + const dealii::FESystem &/*fe_soln*/, + const real penalty, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + adtype &dual_dot_residual) { const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; @@ -153,72 +217,117 @@ void DGStrong::assemble_boundary_term_and_build_operat const unsigned int n_grid_nodes = n_metric_dofs / dim; //build the surface metric operators for interior metric_oper.build_facet_metric_operators( - iface, + face_number, this->face_quadrature_collection[poly_degree].size(), n_grid_nodes, mapping_support_points, mapping_basis, this->all_parameters->use_invariant_curl_form); + //Fetch the modal soln coefficients and the modal auxiliary soln coefficients + //We immediately separate them by state as to be able to use sum-factorization + //in the interpolation operator. If we left it by n_dofs_cell, then the matrix-vector + //mult would sum the states at the quadrature point. + const unsigned int n_dofs_cell = this->fe_collection[poly_degree].dofs_per_cell; + const unsigned int n_shape_fns = n_dofs_cell / nstate; + std::array,nstate> soln_coeff; + std::array>,nstate> aux_soln_coeff; + for (unsigned int idof = 0; idof < n_dofs_cell; ++idof) { + const unsigned int istate = this->fe_collection[poly_degree].system_to_component_index(idof).first; + const unsigned int ishape = this->fe_collection[poly_degree].system_to_component_index(idof).second; + if(ishape == 0) + soln_coeff[istate].resize(n_shape_fns); + soln_coeff[istate][ishape] = soln_coeffs[idof]; + for(int idim=0; idimuse_auxiliary_eq){ + aux_soln_coeff[istate][idim][ishape] = aux_soln_coeffs[idim][idof]; + } + else{ + aux_soln_coeff[istate][idim][ishape] = 0.0; + } + } + } if(compute_auxiliary_right_hand_side){ - assemble_boundary_term_auxiliary_equation ( - iface, current_cell_index, poly_degree, - boundary_id, cell_dofs_indices, + assemble_boundary_term_auxiliary_equation ( + face_number, current_cell_index, + soln_coeff, + poly_degree, + boundary_id, soln_basis, metric_oper, + physics, + diss_num_flux, local_auxiliary_RHS); } else{ - assemble_boundary_term_strong ( - iface, + assemble_boundary_term_strong ( + face_number, current_cell_index, + soln_coeff, aux_soln_coeff, boundary_id, poly_degree, penalty, - cell_dofs_indices, soln_basis, flux_basis, soln_basis_projection_oper_int, metric_oper, - local_rhs_int_cell); + physics, conv_num_flux, diss_num_flux, + rhs); + for(unsigned int idof=0; idof -void DGStrong::assemble_face_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator /*cell*/, - typename dealii::DoFHandler::active_cell_iterator neighbor_cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const unsigned int iface, - const unsigned int neighbor_iface, - const real penalty, - const std::vector ¤t_dofs_indices, - const std::vector &neighbor_dofs_indices, - const std::vector &/*current_metric_dofs_indices*/, - const std::vector &neighbor_metric_dofs_indices, - const unsigned int poly_degree_int, - const unsigned int poly_degree_ext, - const unsigned int /*grid_degree_int*/, - const unsigned int grid_degree_ext, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::metric_operators &metric_oper_int, - OPERATOR::metric_operators &metric_oper_ext, - OPERATOR::mapping_shape_functions &mapping_basis, - std::array,dim> &mapping_support_points, - dealii::hp::FEFaceValues &/*fe_values_collection_face_int*/, - dealii::hp::FEFaceValues &/*fe_values_collection_face_ext*/, - dealii::Vector ¤t_cell_rhs, - dealii::Vector &neighbor_cell_rhs, - std::vector> ¤t_cell_rhs_aux, - dealii::LinearAlgebra::distributed::Vector &rhs, - std::array,dim> &rhs_aux, - const bool compute_auxiliary_right_hand_side, - const bool /*compute_dRdW*/, const bool /*compute_dRdX*/, const bool /*compute_d2R*/) +template +void DGStrong::assemble_face_term_and_build_operators_ad_templated( + typename dealii::DoFHandler::active_cell_iterator /*cell*/, + typename dealii::DoFHandler::active_cell_iterator /*neighbor_cell*/, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const std::vector &soln_coeffs_int, + const std::vector &soln_coeffs_ext, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs_int, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs_ext, + const std::vector &/*metric_coeff_int*/, + const std::vector &metric_coeff_ext, + const std::vector< double > &dual_int, + const std::vector< double > &dual_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const unsigned int /*grid_degree_int*/, + const unsigned int grid_degree_ext, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + const Physics::PhysicsBase &physics, + const NumericalFlux::NumericalFluxConvective &conv_num_flux, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + dealii::hp::FEFaceValues &/*fe_values_collection_face_int*/, + dealii::hp::FEFaceValues &/*fe_values_collection_face_ext*/, + dealii::hp::FESubfaceValues &/*fe_values_collection_subface*/, + const dealii::FESystem &/*fe_int*/, + const dealii::FESystem &/*fe_ext*/, + const real penalty, + std::vector &rhs_int, + std::vector &rhs_ext, + dealii::Tensor<1,dim,std::vector> &aux_rhs_int, + dealii::Tensor<1,dim,std::vector> &aux_rhs_ext, + const bool compute_auxiliary_right_hand_side, + adtype &dual_dot_residual, + const bool /*is_a_subface*/, + const unsigned int /*neighbor_i_subface*/) { const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; @@ -249,13 +358,13 @@ void DGStrong::assemble_face_term_and_build_operators( //get neighbor metric operator //rewrite the high_order_grid->volume_nodes in a way we can use sum-factorization on. //that is, splitting up the vector by the dimension. - std::array,dim> mapping_support_points_neigh; + std::array,dim> mapping_support_points_neigh; for(int idim=0; idim &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering(grid_degree_ext); for (unsigned int idof = 0; idof< n_metric_dofs; ++idof) { - const real val = (this->high_order_grid->volume_nodes[neighbor_metric_dofs_indices[idof]]); + const adtype val = metric_coeff_ext[idof]; const unsigned int istate = fe_metric.system_to_component_index(idof).first; const unsigned int ishape = fe_metric.system_to_component_index(idof).second; const unsigned int igrid_node = index_renumbering[ishape]; @@ -269,123 +378,93 @@ void DGStrong::assemble_face_term_and_build_operators( this->all_parameters->use_invariant_curl_form); } + const unsigned int n_dofs_int = this->fe_collection[poly_degree_int].dofs_per_cell; + const unsigned int n_dofs_ext = this->fe_collection[poly_degree_ext].dofs_per_cell; + const unsigned int n_shape_fns_int = n_dofs_int / nstate; + const unsigned int n_shape_fns_ext = n_dofs_ext / nstate; + // Extract interior modal coefficients of solution + std::array,nstate> soln_coeff_int; + std::array>,nstate> aux_soln_coeff_int; + for (unsigned int idof = 0; idof < n_dofs_int; ++idof) { + const unsigned int istate = this->fe_collection[poly_degree_int].system_to_component_index(idof).first; + const unsigned int ishape = this->fe_collection[poly_degree_int].system_to_component_index(idof).second; + if(ishape == 0) + soln_coeff_int[istate].resize(n_shape_fns_int); + + soln_coeff_int[istate][ishape] = soln_coeffs_int[idof]; + for(int idim=0; idimuse_auxiliary_eq){ + aux_soln_coeff_int[istate][idim][ishape] = aux_soln_coeffs_int[idim][idof]; + } + else{ + aux_soln_coeff_int[istate][idim][ishape] = 0.0; + } + } + } + + // Extract exterior modal coefficients of solution + std::array,nstate> soln_coeff_ext; + std::array>,nstate> aux_soln_coeff_ext; + for (unsigned int idof = 0; idof < n_dofs_ext; ++idof) { + const unsigned int istate = this->fe_collection[poly_degree_ext].system_to_component_index(idof).first; + const unsigned int ishape = this->fe_collection[poly_degree_ext].system_to_component_index(idof).second; + if(ishape == 0){ + soln_coeff_ext[istate].resize(n_shape_fns_ext); + } + soln_coeff_ext[istate][ishape] = soln_coeffs_ext[idof]; + for(int idim=0; idimuse_auxiliary_eq){ + aux_soln_coeff_ext[istate][idim][ishape] = aux_soln_coeffs_ext[idim][idof]; + } + else{ + aux_soln_coeff_ext[istate][idim][ishape] = 0.0; + } + } + } + if(compute_auxiliary_right_hand_side){ - const unsigned int n_dofs_neigh_cell = this->fe_collection[neighbor_cell->active_fe_index()].n_dofs_per_cell(); - std::vector> neighbor_cell_rhs_aux (n_dofs_neigh_cell ); // defaults to 0.0 initialization - assemble_face_term_auxiliary_equation ( + assemble_face_term_auxiliary_equation ( iface, neighbor_iface, current_cell_index, neighbor_cell_index, + soln_coeff_int, soln_coeff_ext, poly_degree_int, poly_degree_ext, - current_dofs_indices, neighbor_dofs_indices, soln_basis_int, soln_basis_ext, metric_oper_int, - current_cell_rhs_aux, neighbor_cell_rhs_aux); - // add local contribution from neighbor cell to global vector - for (unsigned int i=0; i ( iface, neighbor_iface, current_cell_index, neighbor_cell_index, + soln_coeff_int, soln_coeff_ext, + aux_soln_coeff_int, aux_soln_coeff_ext, poly_degree_int, poly_degree_ext, penalty, - current_dofs_indices, neighbor_dofs_indices, soln_basis_int, soln_basis_ext, flux_basis_int, flux_basis_ext, soln_basis_projection_oper_int, soln_basis_projection_oper_ext, metric_oper_int, metric_oper_ext, - current_cell_rhs, neighbor_cell_rhs); - // add local contribution from neighbor cell to global vector - const unsigned int n_dofs_neigh_cell = this->fe_collection[neighbor_cell->active_fe_index()].n_dofs_per_cell(); - for (unsigned int i=0; i -void DGStrong::assemble_subface_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator cell, - typename dealii::DoFHandler::active_cell_iterator neighbor_cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const unsigned int iface, - const unsigned int neighbor_iface, - const unsigned int /*neighbor_i_subface*/, - const real penalty, - const std::vector ¤t_dofs_indices, - const std::vector &neighbor_dofs_indices, - const std::vector ¤t_metric_dofs_indices, - const std::vector &neighbor_metric_dofs_indices, - const unsigned int poly_degree_int, - const unsigned int poly_degree_ext, - const unsigned int grid_degree_int, - const unsigned int grid_degree_ext, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::metric_operators &metric_oper_int, - OPERATOR::metric_operators &metric_oper_ext, - OPERATOR::mapping_shape_functions &mapping_basis, - std::array,dim> &mapping_support_points, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - dealii::hp::FESubfaceValues &/*fe_values_collection_subface*/, - dealii::Vector ¤t_cell_rhs, - dealii::Vector &neighbor_cell_rhs, - std::vector> ¤t_cell_rhs_aux, - dealii::LinearAlgebra::distributed::Vector &rhs, - std::array,dim> &rhs_aux, - const bool compute_auxiliary_right_hand_side, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) -{ - assemble_face_term_and_build_operators( - cell, - neighbor_cell, - current_cell_index, - neighbor_cell_index, - iface, - neighbor_iface, - penalty, - current_dofs_indices, - neighbor_dofs_indices, - current_metric_dofs_indices, - neighbor_metric_dofs_indices, - poly_degree_int, - poly_degree_ext, - grid_degree_int, - grid_degree_ext, - soln_basis_int, - soln_basis_ext, - flux_basis_int, - flux_basis_ext, - flux_basis_stiffness, - soln_basis_projection_oper_int, - soln_basis_projection_oper_ext, - metric_oper_int, - metric_oper_ext, - mapping_basis, - mapping_support_points, - fe_values_collection_face_int, - fe_values_collection_face_int, - current_cell_rhs, - neighbor_cell_rhs, - current_cell_rhs_aux, - rhs, - rhs_aux, - compute_auxiliary_right_hand_side, - compute_dRdW, compute_dRdX, compute_d2R); - -} /******************************************************************* * * @@ -395,7 +474,7 @@ void DGStrong::assemble_subface_term_and_build_operato *******************************************************************/ template -void DGStrong::assemble_auxiliary_residual() +void DGStrong::assemble_auxiliary_residual(const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) { using PDE_enum = Parameters::AllParameters::PartialDifferentialEquation; using ODE_enum = Parameters::ODESolverParam::ODESolverEnum; @@ -423,14 +502,14 @@ void DGStrong::assemble_auxiliary_residual() dealii::hp::FEValues fe_values_collection_volume_lagrange (mapping_collection, this->fe_collection_lagrange, this->volume_quadrature_collection, this->volume_update_flags); - OPERATOR::basis_functions soln_basis_int(1, this->max_degree, this->max_grid_degree); - OPERATOR::basis_functions soln_basis_ext(1, this->max_degree, this->max_grid_degree); - OPERATOR::basis_functions flux_basis_int(1, this->max_degree, this->max_grid_degree); - OPERATOR::basis_functions flux_basis_ext(1, this->max_degree, this->max_grid_degree); - OPERATOR::local_basis_stiffness flux_basis_stiffness(1, this->max_degree, this->max_grid_degree); - OPERATOR::mapping_shape_functions mapping_basis(1, this->max_grid_degree, this->max_grid_degree); - OPERATOR::vol_projection_operator soln_basis_projection_oper_int(1, this->max_degree, this->max_grid_degree); - OPERATOR::vol_projection_operator soln_basis_projection_oper_ext(1, this->max_degree, this->max_grid_degree); + OPERATOR::basis_functions soln_basis_int(1, this->max_degree, this->max_grid_degree); + OPERATOR::basis_functions soln_basis_ext(1, this->max_degree, this->max_grid_degree); + OPERATOR::basis_functions flux_basis_int(1, this->max_degree, this->max_grid_degree); + OPERATOR::basis_functions flux_basis_ext(1, this->max_degree, this->max_grid_degree); + OPERATOR::local_basis_stiffness flux_basis_stiffness(1, this->max_degree, this->max_grid_degree); + OPERATOR::mapping_shape_functions mapping_basis(1, this->max_grid_degree, this->max_grid_degree); + OPERATOR::vol_projection_operator soln_basis_projection_oper_int(1, this->max_degree, this->max_grid_degree); + OPERATOR::vol_projection_operator soln_basis_projection_oper_ext(1, this->max_degree, this->max_grid_degree); this->reinit_operators_for_cell_residual_loop( this->max_degree, this->max_degree, this->max_grid_degree, @@ -445,26 +524,53 @@ void DGStrong::assemble_auxiliary_residual() for (auto soln_cell = this->dof_handler.begin_active(); soln_cell != this->dof_handler.end(); ++soln_cell, ++metric_cell) { if (!soln_cell->is_locally_owned()) continue; - this->assemble_cell_residual ( - soln_cell, - metric_cell, - false, false, false, - fe_values_collection_volume, - fe_values_collection_face_int, - fe_values_collection_face_ext, - fe_values_collection_subface, - fe_values_collection_volume_lagrange, - soln_basis_int, - soln_basis_ext, - flux_basis_int, - flux_basis_ext, - flux_basis_stiffness, - soln_basis_projection_oper_int, - soln_basis_projection_oper_ext, - mapping_basis, - true, - this->right_hand_side, - this->auxiliary_right_hand_side); + // Add right-hand side contributions this cell can compute + if(compute_d2R) + { + this->template assemble_cell_residual_and_ad_derivatives( + soln_cell, + metric_cell, + compute_dRdW, compute_dRdX, compute_d2R, + fe_values_collection_volume, + fe_values_collection_face_int, + fe_values_collection_face_ext, + fe_values_collection_subface, + fe_values_collection_volume_lagrange, + soln_basis_int, + soln_basis_ext, + flux_basis_int, + flux_basis_ext, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + mapping_basis, + true, + this->right_hand_side, + this->auxiliary_right_hand_side); + } + else + { + this->template assemble_cell_residual_and_ad_derivatives( + soln_cell, + metric_cell, + compute_dRdW, compute_dRdX, compute_d2R, + fe_values_collection_volume, + fe_values_collection_face_int, + fe_values_collection_face_ext, + fe_values_collection_subface, + fe_values_collection_volume_lagrange, + soln_basis_int, + soln_basis_ext, + flux_basis_int, + flux_basis_ext, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + mapping_basis, + true, + this->right_hand_side, + this->auxiliary_right_hand_side); + } } // end of cell loop for(int idim=0; idim::assemble_auxiliary_residual() **************************************************/ template +template void DGStrong::assemble_volume_term_auxiliary_equation( - const std::vector ¤t_dofs_indices, + const std::array,nstate> &soln_coeff, const unsigned int poly_degree, - OPERATOR::basis_functions &soln_basis, - OPERATOR::basis_functions &flux_basis, - OPERATOR::metric_operators &metric_oper, - std::vector> &local_auxiliary_RHS) + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::metric_operators &metric_oper, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS) { //Please see header file for exact formula we are solving. const unsigned int n_quad_pts = this->volume_quadrature_collection[poly_degree].size(); @@ -512,24 +619,10 @@ void DGStrong::assemble_volume_term_auxiliary_equation const unsigned int n_shape_fns = n_dofs_cell / nstate; const std::vector &quad_weights = this->volume_quadrature_collection[poly_degree].get_weights(); - //Fetch the modal soln coefficients and the modal auxiliary soln coefficients - //We immediately separate them by state as to be able to use sum-factorization - //in the interpolation operator. If we left it by n_dofs_cell, then the matrix-vector - //mult would sum the states at the quadrature point. - //That is why the basis functions are of derived class state rather than base. - std::array,nstate> soln_coeff; - for (unsigned int idof = 0; idof < n_dofs_cell; ++idof) { - const unsigned int istate = this->fe_collection[poly_degree].system_to_component_index(idof).first; - const unsigned int ishape = this->fe_collection[poly_degree].system_to_component_index(idof).second; - if(ishape == 0) - soln_coeff[istate].resize(n_shape_fns); - - soln_coeff[istate][ishape] = DGBase::solution(current_dofs_indices[idof]); - } //Interpolate each state to the quadrature points using sum-factorization //with the basis functions in each reference direction. for(int istate=0; istate soln_at_q(n_quad_pts); + std::vector soln_at_q(n_quad_pts); //interpolate soln coeff to volume cubature nodes soln_basis.matrix_vector_mult_1D(soln_coeff[istate], soln_at_q, soln_basis.oneD_vol_operator); @@ -538,7 +631,7 @@ void DGStrong::assemble_volume_term_auxiliary_equation //Cicchino, Alexander, et al. "Provably stable flux reconstruction high-order methods on curvilinear elements." Journal of Computational Physics 463 (2022): 111259. //apply gradient of reference basis functions on the solution at volume cubature nodes - dealii::Tensor<1,dim,std::vector> ref_gradient_basis_fns_times_soln; + dealii::Tensor<1,dim,std::vector> ref_gradient_basis_fns_times_soln; for(int idim=0; idim::assemble_volume_term_auxiliary_equation //transform the gradient into a physical gradient operator scaled by determinant of metric Jacobian //then apply the inner product in each direction for(int idim=0; idim phys_gradient_u(n_quad_pts); + std::vector phys_gradient_u(n_quad_pts); for(unsigned int iquad=0; iquad::assemble_volume_term_auxiliary_equation } } //Note that we let the determiant of the metric Jacobian cancel off between the integral and physical gradient - std::vector rhs(n_shape_fns); + std::vector rhs(n_shape_fns); soln_basis.inner_product_1D(phys_gradient_u, quad_weights, rhs, soln_basis.oneD_vol_operator, @@ -565,22 +658,25 @@ void DGStrong::assemble_volume_term_auxiliary_equation //write the the auxiliary rhs for the test function. for(unsigned int ishape=0; ishape +template void DGStrong::assemble_boundary_term_auxiliary_equation( - const unsigned int iface, - const dealii::types::global_dof_index current_cell_index, - const unsigned int poly_degree, - const unsigned int boundary_id, - const std::vector &dofs_indices, - OPERATOR::basis_functions &soln_basis, - OPERATOR::metric_operators &metric_oper, - std::vector> &local_auxiliary_RHS) + const unsigned int iface, + const dealii::types::global_dof_index current_cell_index, + const std::array,nstate> &soln_coeff, + const unsigned int poly_degree, + const unsigned int boundary_id, + OPERATOR::basis_functions &soln_basis, + OPERATOR::metric_operators &metric_oper, + const Physics::PhysicsBase &pde_physics, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS) { (void) current_cell_index; @@ -588,23 +684,10 @@ void DGStrong::assemble_boundary_term_auxiliary_equati const unsigned int n_quad_pts_vol = this->volume_quadrature_collection[poly_degree].size(); const unsigned int n_dofs = this->fe_collection[poly_degree].dofs_per_cell; const unsigned int n_shape_fns = n_dofs / nstate; - AssertDimension (n_dofs, dofs_indices.size()); - - //Extract interior modal coefficients of solution - std::array,nstate> soln_coeff; - for (unsigned int idof = 0; idof < n_dofs; ++idof) { - const unsigned int istate = this->fe_collection[poly_degree].system_to_component_index(idof).first; - const unsigned int ishape = this->fe_collection[poly_degree].system_to_component_index(idof).second; - //allocate - if(ishape == 0) - soln_coeff[istate].resize(n_shape_fns); - //solve - soln_coeff[istate][ishape] = DGBase::solution(dofs_indices[idof]); - } //Interpolate soln to facet, and gradient to facet. - std::array,nstate> soln_at_surf_q; - std::array>,nstate> ref_grad_soln_at_vol_q; + std::array,nstate> soln_at_surf_q; + std::array>,nstate> ref_grad_soln_at_vol_q; for(int istate=0; istate::assemble_boundary_term_auxiliary_equati } // Get physical gradient of solution on the surface - std::array>,nstate> phys_grad_soln_at_surf_q; + std::array>,nstate> phys_grad_soln_at_surf_q; for(int istate=0; istate phys_gradient_u(n_quad_pts_vol); + std::vector phys_gradient_u(n_quad_pts_vol); for(unsigned int iquad=0; iquad::assemble_boundary_term_auxiliary_equati //evaluate physical facet fluxes dot product with physical unit normal scaled by determinant of metric facet Jacobian //the outward reference normal dircetion. const dealii::Tensor<1,dim,double> unit_ref_normal_int = dealii::GeometryInfo::unit_normal_vector[iface]; - std::array>,nstate> surf_num_flux_minus_surf_soln_dot_normal; + std::array>,nstate> surf_num_flux_minus_surf_soln_dot_normal; for(unsigned int iquad=0; iquad metric_cofactor_surf; + dealii::Tensor<2,dim,adtype> metric_cofactor_surf; for(int idim=0; idim soln_state; - std::array,nstate> phys_grad_soln_state; + std::array soln_state; + std::array,nstate> phys_grad_soln_state; for(int istate=0; istate::assemble_boundary_term_auxiliary_equati } } //numerical fluxes - dealii::Tensor<1,dim,real> unit_phys_normal_int; + dealii::Tensor<1,dim,adtype> unit_phys_normal_int; metric_oper.transform_reference_to_physical(unit_ref_normal_int, metric_cofactor_surf, unit_phys_normal_int); - const double face_Jac_norm_scaled = unit_phys_normal_int.norm(); + adtype face_Jac_norm_scaled = 0.0; + for(int idim=0; idim soln_boundary; - std::array,nstate> grad_soln_boundary; - dealii::Point surf_flux_node; + std::array soln_boundary; + std::array,nstate> grad_soln_boundary; + dealii::Point surf_flux_node; for(int idim=0; idimpde_physics_double->boundary_face_values (boundary_id, surf_flux_node, unit_phys_normal_int, soln_state, phys_grad_soln_state, soln_boundary, grad_soln_boundary); + pde_physics.boundary_face_values (boundary_id, surf_flux_node, unit_phys_normal_int, soln_state, phys_grad_soln_state, soln_boundary, grad_soln_boundary); - std::array diss_soln_num_flux; - diss_soln_num_flux = this->diss_num_flux_double->evaluate_solution_flux(soln_state, soln_boundary, unit_phys_normal_int); + std::array diss_soln_num_flux; + diss_soln_num_flux = diss_num_flux.evaluate_solution_flux(soln_state, soln_boundary, unit_phys_normal_int); for(int istate=0; istate::assemble_boundary_term_auxiliary_equati const std::vector &surf_quad_weights = this->face_quadrature_collection[poly_degree].get_weights(); for(int istate=0; istate rhs(n_shape_fns); + std::vector rhs(n_shape_fns); soln_basis.inner_product_surface_1D(iface, surf_num_flux_minus_surf_soln_dot_normal[istate][idim], @@ -711,26 +798,30 @@ void DGStrong::assemble_boundary_term_auxiliary_equati soln_basis.oneD_vol_operator, false, 1.0);//it's added since auxiliary is EQUAL to the gradient of the soln for(unsigned int ishape=0; ishape +template void DGStrong::assemble_face_term_auxiliary_equation( - const unsigned int iface, const unsigned int neighbor_iface, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const unsigned int poly_degree_int, - const unsigned int poly_degree_ext, - const std::vector &dof_indices_int, - const std::vector &dof_indices_ext, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::metric_operators &metric_oper_int, - std::vector> &local_auxiliary_RHS_int, - std::vector> &local_auxiliary_RHS_ext) + const unsigned int iface, + const unsigned int neighbor_iface, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const std::array,nstate> &soln_coeff_int, + const std::array,nstate> &soln_coeff_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::metric_operators &metric_oper_int, + const Physics::PhysicsBase &/*pde_physics*/, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS_int, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS_ext) { (void) current_cell_index; (void) neighbor_cell_index; @@ -743,36 +834,9 @@ void DGStrong::assemble_face_term_auxiliary_equation( const unsigned int n_shape_fns_int = n_dofs_int / nstate; const unsigned int n_shape_fns_ext = n_dofs_ext / nstate; - AssertDimension (n_dofs_int, dof_indices_int.size()); - AssertDimension (n_dofs_ext, dof_indices_ext.size()); - - //Extract interior modal coefficients of solution - std::array,nstate> soln_coeff_int; - for (unsigned int idof = 0; idof < n_dofs_int; ++idof) { - const unsigned int istate = this->fe_collection[poly_degree_int].system_to_component_index(idof).first; - const unsigned int ishape = this->fe_collection[poly_degree_int].system_to_component_index(idof).second; - //allocate - if(ishape == 0) soln_coeff_int[istate].resize(n_shape_fns_int); - - //solve - soln_coeff_int[istate][ishape] = DGBase::solution(dof_indices_int[idof]); - } - - //Extract exterior modal coefficients of solution - std::array,nstate> soln_coeff_ext; - for (unsigned int idof = 0; idof < n_dofs_ext; ++idof) { - const unsigned int istate = this->fe_collection[poly_degree_ext].system_to_component_index(idof).first; - const unsigned int ishape = this->fe_collection[poly_degree_ext].system_to_component_index(idof).second; - //allocate - if(ishape == 0) soln_coeff_ext[istate].resize(n_shape_fns_ext); - - //solve - soln_coeff_ext[istate][ishape] = DGBase::solution(dof_indices_ext[idof]); - } - //Interpolate soln modal coefficients to the facet - std::array,nstate> soln_at_surf_q_int; - std::array,nstate> soln_at_surf_q_ext; + std::array,nstate> soln_at_surf_q_int; + std::array,nstate> soln_at_surf_q_ext; for(int istate=0; istate::assemble_face_term_auxiliary_equation( //evaluate physical facet fluxes dot product with physical unit normal scaled by determinant of metric facet Jacobian //the outward reference normal dircetion. const dealii::Tensor<1,dim,double> unit_ref_normal_int = dealii::GeometryInfo::unit_normal_vector[iface]; - std::array>,nstate> surf_num_flux_minus_surf_soln_int_dot_normal; - std::array>,nstate> surf_num_flux_minus_surf_soln_ext_dot_normal; + std::array>,nstate> surf_num_flux_minus_surf_soln_int_dot_normal; + std::array>,nstate> surf_num_flux_minus_surf_soln_ext_dot_normal; for (unsigned int iquad=0; iquad metric_cofactor_surf; + dealii::Tensor<2,dim,adtype> metric_cofactor_surf; for(int idim=0; idim unit_phys_normal_int; + dealii::Tensor<1,dim,adtype> unit_phys_normal_int; metric_oper_int.transform_reference_to_physical(unit_ref_normal_int, metric_cofactor_surf, unit_phys_normal_int); - const double face_Jac_norm_scaled = unit_phys_normal_int.norm(); + adtype face_Jac_norm_scaled = 0.0; + for(int idim=0; idim diss_soln_num_flux; - std::array soln_state_int; - std::array soln_state_ext; + std::array diss_soln_num_flux; + std::array soln_state_int; + std::array soln_state_ext; for(int istate=0; istatediss_num_flux_double->evaluate_solution_flux(soln_state_int, soln_state_ext, unit_phys_normal_int); + diss_soln_num_flux = diss_num_flux.evaluate_solution_flux(soln_state_int, soln_state_ext, unit_phys_normal_int); for(int istate=0; istate::assemble_face_term_auxiliary_equation( const std::vector &surf_quad_weights = this->face_quadrature_collection[poly_degree_int].get_weights(); for(int istate=0; istate rhs_int(n_shape_fns_int); + std::vector rhs_int(n_shape_fns_int); soln_basis_int.inner_product_surface_1D(iface, surf_num_flux_minus_surf_soln_int_dot_normal[istate][idim], @@ -852,9 +920,9 @@ void DGStrong::assemble_face_term_auxiliary_equation( false, 1.0);//it's added since auxiliary is EQUAL to the gradient of the soln for(unsigned int ishape=0; ishape rhs_ext(n_shape_fns_ext); + std::vector rhs_ext(n_shape_fns_ext); soln_basis_ext.inner_product_surface_1D(neighbor_iface, surf_num_flux_minus_surf_soln_ext_dot_normal[istate][idim], @@ -864,7 +932,7 @@ void DGStrong::assemble_face_term_auxiliary_equation( false, 1.0);//it's added since auxiliary is EQUAL to the gradient of the soln for(unsigned int ishape=0; ishape::assemble_face_term_auxiliary_equation( * ****************************************************/ template +template void DGStrong::assemble_volume_term_strong( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const std::vector &cell_dofs_indices, - const unsigned int poly_degree, - OPERATOR::basis_functions &soln_basis, - OPERATOR::basis_functions &flux_basis, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper, - OPERATOR::metric_operators &metric_oper, - dealii::Vector &local_rhs_int_cell) + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::array,nstate> &soln_coeff, + const std::array>,nstate> &aux_soln_coeff, + const unsigned int poly_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper, + OPERATOR::metric_operators &metric_oper, + const Physics::PhysicsBase &pde_physics, + std::vector &local_rhs_int_cell) { (void) current_cell_index; @@ -898,34 +969,10 @@ void DGStrong::assemble_volume_term_strong( const std::vector &vol_quad_weights = this->volume_quadrature_collection[poly_degree].get_weights(); const std::vector &oneD_vol_quad_weights = this->oneD_quadrature_collection[poly_degree].get_weights(); - AssertDimension (n_dofs_cell, cell_dofs_indices.size()); - // Fetch the modal soln coefficients and the modal auxiliary soln coefficients - // We immediately separate them by state as to be able to use sum-factorization - // in the interpolation operator. If we left it by n_dofs_cell, then the matrix-vector - // mult would sum the states at the quadrature point. - std::array,nstate> soln_coeff; - std::array>,nstate> aux_soln_coeff; - for (unsigned int idof = 0; idof < n_dofs_cell; ++idof) { - const unsigned int istate = this->fe_collection[poly_degree].system_to_component_index(idof).first; - const unsigned int ishape = this->fe_collection[poly_degree].system_to_component_index(idof).second; - if(ishape == 0) - soln_coeff[istate].resize(n_shape_fns); - soln_coeff[istate][ishape] = DGBase::solution(cell_dofs_indices[idof]); - for(int idim=0; idimuse_auxiliary_eq){ - aux_soln_coeff[istate][idim][ishape] = DGBase::auxiliary_solution[idim](cell_dofs_indices[idof]); - } - else{ - aux_soln_coeff[istate][idim][ishape] = 0.0; - } - } - } - std::array,nstate> soln_at_q; - std::array>,nstate> aux_soln_at_q; //auxiliary sol at flux nodes - std::vector> soln_at_q_for_max_CFL(n_quad_pts);//Need soln written in a different for to use pre-existing max CFL function + std::array,nstate> soln_at_q; + std::array>,nstate> aux_soln_at_q; //auxiliary sol at flux nodes + std::vector> soln_at_q_for_max_CFL(n_quad_pts);//Need soln written in a different for to use pre-existing max CFL function // Interpolate each state to the quadrature points using sum-factorization // with the basis functions in each reference direction. for(int istate=0; istate::assemble_volume_term_strong( soln_basis.oneD_vol_operator); } for(unsigned int iquad=0; iquad(soln_at_q[istate][iquad]); } } @@ -963,9 +1010,9 @@ void DGStrong::assemble_volume_term_strong( } } // Get max_dt_cell for time_scaled_solution with pseudotime - real cell_volume_estimate = 0.0; + double cell_volume_estimate = 0.0; for (unsigned int iquad=0; iquad(metric_oper.det_Jac_vol[iquad]) * vol_quad_weights[iquad]; } const real cell_volume = cell_volume_estimate; const real diameter = cell->diameter(); @@ -975,26 +1022,26 @@ void DGStrong::assemble_volume_term_strong( this->max_dt_cell[current_cell_index] = this->evaluate_CFL ( soln_at_q_for_max_CFL, max_artificial_diss, cell_radius, poly_degree); //get entropy projected variables - std::array,nstate> entropy_var_at_q; - std::array,nstate> projected_entropy_var_at_q; + std::array,nstate> entropy_var_at_q; + std::array,nstate> projected_entropy_var_at_q; if (this->all_parameters->use_split_form || this->all_parameters->use_curvilinear_split_form){ for(int istate=0; istate soln_state; + std::array soln_state; for(int istate=0; istate entropy_var; - entropy_var = this->pde_physics_double->compute_entropy_variables(soln_state); + std::array entropy_var; + entropy_var = pde_physics.compute_entropy_variables(soln_state); for(int istate=0; istate entropy_var_coeff(n_shape_fns);; + std::vector entropy_var_coeff(n_shape_fns);; soln_basis_projection_oper.matrix_vector_mult_1D(entropy_var_at_q[istate], entropy_var_coeff, soln_basis_projection_oper.oneD_vol_operator); @@ -1009,13 +1056,13 @@ void DGStrong::assemble_volume_term_strong( //From the paper: Cicchino, Alexander, et al. "Provably stable flux reconstruction high-order methods on curvilinear elements." Journal of Computational Physics 463 (2022): 111259. //For conservative DG, we compute the reference flux as per Eq. (9), to then recover the second volume integral in Eq. (17). //For curvilinear split-form in Eq. (22), we apply a two-pt flux of the metric-cofactor matrix on the matrix operator constructed by the entropy stable/conservtive 2pt flux. - std::array>,nstate> conv_ref_flux_at_q; - std::array>,nstate> diffusive_ref_flux_at_q; - std::array,nstate> source_at_q; - std::array,nstate> physical_source_at_q; + std::array>,nstate> conv_ref_flux_at_q; + std::array>,nstate> diffusive_ref_flux_at_q; + std::array,nstate> source_at_q; + std::array,nstate> physical_source_at_q; // The matrix of two-pt fluxes for Hadamard products - std::array,dim>,nstate> conv_ref_2pt_flux_at_q; + std::array,dim>,nstate> conv_ref_2pt_flux_at_q; //Hadamard tensor-product sparsity pattern std::vector> Hadamard_rows_sparsity(n_quad_pts * n_quad_pts_1D);//size n^{d+1} std::vector> Hadamard_columns_sparsity(n_quad_pts * n_quad_pts_1D); @@ -1023,7 +1070,7 @@ void DGStrong::assemble_volume_term_strong( if (this->all_parameters->use_split_form || this->all_parameters->use_curvilinear_split_form){ for(int istate=0; istate::assemble_volume_term_strong( for (unsigned int iquad=0; iquad soln_state; - std::array,nstate> aux_soln_state; + std::array soln_state; + std::array,nstate> aux_soln_state; for(int istate=0; istate::assemble_volume_term_strong( // Copy Metric Cofactor in a way can use for transforming Tensor Blocks to reference space // The way it is stored in metric_operators is to use sum-factorization in each direction, // but here it is cleaner to apply a reference transformation in each Tensor block returned by physics. - dealii::Tensor<2,dim,real> metric_cofactor; + dealii::Tensor<2,dim,adtype> metric_cofactor; for(int idim=0; idim::assemble_volume_term_strong( // Evaluate physical convective flux // If 2pt flux, transform to reference at construction to improve performance. // We technically use a REFERENCE 2pt flux for all entropy stable schemes. - std::array,nstate> conv_phys_flux; + std::array,nstate> conv_phys_flux; if (this->all_parameters->use_split_form || this->all_parameters->use_curvilinear_split_form){ //get the soln for iquad from projected entropy variables - std::array entropy_var; + std::array entropy_var; for(int istate=0; istatepde_physics_double->compute_conservative_variables_from_entropy_variables (entropy_var); + soln_state = pde_physics.compute_conservative_variables_from_entropy_variables (entropy_var); //loop over all the non-zero entries for "sum-factorized" Hadamard product that corresponds to the iquad. for(unsigned int row_index = iquad * n_quad_pts_1D, column_index = 0; @@ -1083,72 +1130,78 @@ void DGStrong::assemble_volume_term_strong( for(int ref_dim=0; ref_dim metric_cofactor_flux_basis; + dealii::Tensor<2,dim,adtype> metric_cofactor_flux_basis; for(int idim=0; idim soln_state_flux_basis; - std::array entropy_var_flux_basis; + std::array soln_state_flux_basis; + std::array entropy_var_flux_basis; for(int istate=0; istatepde_physics_double->compute_conservative_variables_from_entropy_variables (entropy_var_flux_basis); + soln_state_flux_basis = pde_physics.compute_conservative_variables_from_entropy_variables (entropy_var_flux_basis); //Compute the physical flux - std::array,nstate> conv_phys_flux_2pt; - conv_phys_flux_2pt = this->pde_physics_double->convective_numerical_split_flux(soln_state, soln_state_flux_basis); + std::array,nstate> conv_phys_flux_2pt; + conv_phys_flux_2pt = pde_physics.convective_numerical_split_flux(soln_state, soln_state_flux_basis); for(int istate=0; istate conv_ref_flux_2pt; + dealii::Tensor<1,dim,adtype> conv_ref_flux_2pt; //For each state, transform the physical flux to a reference flux. + dealii::Tensor<2,dim,adtype> metric_cofactor_split; + for(int idim=0; idimpde_physics_double->convective_flux (soln_state); + conv_phys_flux = pde_physics.convective_flux (soln_state); } //Diffusion - std::array,nstate> diffusive_phys_flux; + std::array,nstate> diffusive_phys_flux; //Compute the physical dissipative flux - diffusive_phys_flux = this->pde_physics_double->dissipative_flux(soln_state, aux_soln_state, current_cell_index); + diffusive_phys_flux = pde_physics.dissipative_flux(soln_state, aux_soln_state, current_cell_index); // Manufactured source - std::array manufactured_source; + std::array manufactured_source; if(this->all_parameters->manufactured_convergence_study_param.manufactured_solution_param.use_manufactured_source_term) { - dealii::Point vol_flux_node; + dealii::Point vol_flux_node; for(int idim=0; idimpde_physics_double->source_term (vol_flux_node, soln_state, this->current_time, current_cell_index); + manufactured_source = pde_physics.source_term (vol_flux_node, soln_state, this->current_time, current_cell_index); } // Physical source - std::array physical_source; - if(this->pde_physics_double->has_nonzero_physical_source) { - dealii::Point vol_flux_node; + std::array physical_source; + if(pde_physics.has_nonzero_physical_source) { + dealii::Point vol_flux_node; for(int idim=0; idimpde_physics_double->physical_source_term (vol_flux_node, soln_state, aux_soln_state, current_cell_index); + physical_source = pde_physics.physical_source_term (vol_flux_node, soln_state, aux_soln_state, current_cell_index); } //Write the values in a way that we can use sum-factorization on. for(int istate=0; istate conv_ref_flux; - dealii::Tensor<1,dim,real> diffusive_ref_flux; + dealii::Tensor<1,dim,adtype> conv_ref_flux; + dealii::Tensor<1,dim,adtype> diffusive_ref_flux; //Trnasform to reference fluxes if (this->all_parameters->use_split_form || this->all_parameters->use_curvilinear_split_form){ //Do Nothing. @@ -1195,7 +1248,7 @@ void DGStrong::assemble_volume_term_strong( } source_at_q[istate][iquad] = manufactured_source[istate]; } - if(this->pde_physics_double->has_nonzero_physical_source) { + if(pde_physics.has_nonzero_physical_source) { if(iquad == 0){ physical_source_at_q[istate].resize(n_quad_pts); } @@ -1223,8 +1276,8 @@ void DGStrong::assemble_volume_term_strong( for(int istate=0; istate conv_flux_divergence(n_quad_pts); - std::vector diffusive_flux_divergence(n_quad_pts); + std::vector conv_flux_divergence(n_quad_pts); + std::vector diffusive_flux_divergence(n_quad_pts); if (this->all_parameters->use_split_form || this->all_parameters->use_curvilinear_split_form){ //2pt flux Hadamard Product, and then multiply by vector of ones scaled by 1. @@ -1233,15 +1286,15 @@ void DGStrong::assemble_volume_term_strong( // sum-factorization type algorithm that exploits the structure of the flux basis in the reference space to have O(n^{d+1}). for(int ref_dim=0; ref_dim divergence_ref_flux_Hadamard_product(n_quad_pts, n_quad_pts_1D); - flux_basis.Hadamard_product(flux_basis_stiffness_skew_symm_oper_sparse[ref_dim], conv_ref_2pt_flux_at_q[istate][ref_dim], divergence_ref_flux_Hadamard_product); + std::vector divergence_ref_flux_Hadamard_product(n_quad_pts * n_quad_pts_1D); + flux_basis.Hadamard_product_AD_vector(flux_basis_stiffness_skew_symm_oper_sparse[ref_dim], conv_ref_2pt_flux_at_q[istate][ref_dim], divergence_ref_flux_Hadamard_product); //Hadamard product times the vector of ones. for(unsigned int iquad=0; iquad::assemble_volume_term_strong( // rhs = - \divergence( Fconv + Fdiss ) + source // Since we have done an integration by parts, the volume term resulting from the divergence of Fconv and Fdiss // is negative. Therefore, negative of negative means we add that volume term to the right-hand-side - std::vector rhs(n_shape_fns); + std::vector rhs(n_shape_fns); // Convective if (this->all_parameters->use_split_form || this->all_parameters->use_curvilinear_split_form){ @@ -1285,42 +1338,49 @@ void DGStrong::assemble_volume_term_strong( // Manufactured source if(this->all_parameters->manufactured_convergence_study_param.manufactured_solution_param.use_manufactured_source_term) { - std::vector JxW(n_quad_pts); + std::vector JxWxsource(n_quad_pts); for(unsigned int iquad=0; iquad ones(n_quad_pts, 1.0); + soln_basis.inner_product_1D(JxWxsource, ones, rhs, soln_basis.oneD_vol_operator, true, 1.0); } // Physical source - if(this->pde_physics_double->has_nonzero_physical_source) { - std::vector JxW(n_quad_pts); + if(pde_physics.has_nonzero_physical_source) { + std::vector JxWxphys_source(n_quad_pts); for(unsigned int iquad=0; iquad ones(n_quad_pts, 1.0); + soln_basis.inner_product_1D(JxWxphys_source, ones, rhs, soln_basis.oneD_vol_operator, true, 1.0); } for(unsigned int ishape=0; ishape +template void DGStrong::assemble_boundary_term_strong( - const unsigned int iface, - const dealii::types::global_dof_index current_cell_index, - const unsigned int boundary_id, - const unsigned int poly_degree, - const real penalty, - const std::vector &dof_indices, - OPERATOR::basis_functions &soln_basis, - OPERATOR::basis_functions &flux_basis, - OPERATOR::vol_projection_operator &soln_basis_projection_oper, - OPERATOR::metric_operators &metric_oper, - dealii::Vector &local_rhs_cell) + const unsigned int iface, + const dealii::types::global_dof_index current_cell_index, + const std::array,nstate> &soln_coeff, + const std::array>,nstate> &aux_soln_coeff, + const unsigned int boundary_id, + const unsigned int poly_degree, + const real penalty, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper, + OPERATOR::metric_operators &metric_oper, + const Physics::PhysicsBase &pde_physics, + const NumericalFlux::NumericalFluxConvective &conv_num_flux, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + std::vector &local_rhs_cell) { (void) current_cell_index; @@ -1331,43 +1391,12 @@ void DGStrong::assemble_boundary_term_strong( const unsigned int n_shape_fns = n_dofs / nstate; const std::vector &face_quad_weights = this->face_quadrature_collection[poly_degree].get_weights(); - AssertDimension (n_dofs, dof_indices.size()); - - // Fetch the modal soln coefficients and the modal auxiliary soln coefficients - // We immediately separate them by state as to be able to use sum-factorization - // in the interpolation operator. If we left it by n_dofs_cell, then the matrix-vector - // mult would sum the states at the quadrature point. - std::array,nstate> soln_coeff; - std::array>,nstate> aux_soln_coeff; - for (unsigned int idof = 0; idof < n_dofs; ++idof) { - const unsigned int istate = this->fe_collection[poly_degree].system_to_component_index(idof).first; - const unsigned int ishape = this->fe_collection[poly_degree].system_to_component_index(idof).second; - // allocate - if(ishape == 0){ - soln_coeff[istate].resize(n_shape_fns); - } - // solve - soln_coeff[istate][ishape] = DGBase::solution(dof_indices[idof]); - for(int idim=0; idimuse_auxiliary_eq){ - aux_soln_coeff[istate][idim][ishape] = DGBase::auxiliary_solution[idim](dof_indices[idof]); - } - else{ - aux_soln_coeff[istate][idim][ishape] = 0.0; - } - } - } // Interpolate the modal coefficients to the volume cubature nodes. - std::array,nstate> soln_at_vol_q; - std::array>,nstate> aux_soln_at_vol_q; + std::array,nstate> soln_at_vol_q; + std::array>,nstate> aux_soln_at_vol_q; // Interpolate modal soln coefficients to the facet. - std::array,nstate> soln_at_surf_q; - std::array>,nstate> aux_soln_at_surf_q; + std::array,nstate> soln_at_surf_q; + std::array>,nstate> aux_soln_at_surf_q; for(int istate=0; istate::assemble_boundary_term_strong( // Compute reference volume fluxes in both interior and exterior cells. // First we do interior. - std::array>,nstate> conv_ref_flux_at_vol_q; - std::array>,nstate> diffusive_ref_flux_at_vol_q; + std::array>,nstate> conv_ref_flux_at_vol_q; + std::array>,nstate> diffusive_ref_flux_at_vol_q; for (unsigned int iquad=0; iquad metric_cofactor_vol; + dealii::Tensor<2,dim,adtype> metric_cofactor_vol; for(int idim=0; idim soln_state; - std::array,nstate> aux_soln_state; + std::array soln_state; + std::array,nstate> aux_soln_state; for(int istate=0; istate::assemble_boundary_term_strong( } // Evaluate physical convective flux - std::array,nstate> conv_phys_flux; + std::array,nstate> conv_phys_flux; if(!this->all_parameters->use_split_form && !this->all_parameters->use_curvilinear_split_form){ - conv_phys_flux = this->pde_physics_double->convective_flux (soln_state); + conv_phys_flux = pde_physics.convective_flux (soln_state); } // Compute the physical dissipative flux - std::array,nstate> diffusive_phys_flux; - diffusive_phys_flux = this->pde_physics_double->dissipative_flux(soln_state, aux_soln_state, current_cell_index); + std::array,nstate> diffusive_phys_flux; + diffusive_phys_flux = pde_physics.dissipative_flux(soln_state, aux_soln_state, current_cell_index); // Write the values in a way that we can use sum-factorization on. for(int istate=0; istate conv_ref_flux; - dealii::Tensor<1,dim,real> diffusive_ref_flux; + dealii::Tensor<1,dim,adtype> conv_ref_flux; + dealii::Tensor<1,dim,adtype> diffusive_ref_flux; // transform the conservative convective physical flux to reference space if(!this->all_parameters->use_split_form && !this->all_parameters->use_curvilinear_split_form){ metric_oper.transform_physical_to_reference( @@ -1479,8 +1508,8 @@ void DGStrong::assemble_boundary_term_strong( const dealii::Tensor<1,dim,double> unit_ref_normal_int = dealii::GeometryInfo::unit_normal_vector[iface]; const int dim_not_zero = iface / 2;//reference direction of face integer division - std::array,nstate> conv_int_vol_ref_flux_interp_to_face_dot_ref_normal; - std::array,nstate> diffusive_int_vol_ref_flux_interp_to_face_dot_ref_normal; + std::array,nstate> conv_int_vol_ref_flux_interp_to_face_dot_ref_normal; + std::array,nstate> diffusive_int_vol_ref_flux_interp_to_face_dot_ref_normal; for(int istate=0; istate::assemble_boundary_term_strong( //pages 355 (Eq. 57 with text around it) and page 359 (Eq 86 and text below it). // First, transform the volume conservative solution at volume cubature nodes to entropy variables. - std::array,nstate> entropy_var_vol; + std::array,nstate> entropy_var_vol; for(unsigned int iquad=0; iquad soln_state; + std::array soln_state; for(int istate=0; istate entropy_var; - entropy_var = this->pde_physics_double->compute_entropy_variables(soln_state); + std::array entropy_var; + entropy_var = pde_physics.compute_entropy_variables(soln_state); for(int istate=0; istate::assemble_boundary_term_strong( } //project it onto the solution basis functions and interpolate it - std::array,nstate> projected_entropy_var_vol; - std::array,nstate> projected_entropy_var_surf; + std::array,nstate> projected_entropy_var_vol; + std::array,nstate> projected_entropy_var_surf; for(int istate=0; istate entropy_var_coeff(n_shape_fns); + std::vector entropy_var_coeff(n_shape_fns); soln_basis_projection_oper.matrix_vector_mult_1D(entropy_var_vol[istate], entropy_var_coeff, soln_basis_projection_oper.oneD_vol_operator); @@ -1563,17 +1592,17 @@ void DGStrong::assemble_boundary_term_strong( flux_basis.sum_factorized_Hadamard_surface_sparsity_pattern(n_face_quad_pts, n_quad_pts_1D, Hadamard_rows_sparsity, Hadamard_columns_sparsity, dim_not_zero); } - std::array,nstate> surf_vol_ref_2pt_flux_interp_surf; - std::array,nstate> surf_vol_ref_2pt_flux_interp_vol; + std::array,nstate> surf_vol_ref_2pt_flux_interp_surf; + std::array,nstate> surf_vol_ref_2pt_flux_interp_vol; if(this->all_parameters->use_split_form || this->all_parameters->use_curvilinear_split_form){ //get surface-volume hybrid 2pt flux from Eq.(15) in Chan, Jesse. "Skew-symmetric entropy stable modal discontinuous Galerkin formulations." Journal of Scientific Computing 81.1 (2019): 459-485. - std::array,nstate> surface_ref_2pt_flux; + std::array,nstate> surface_ref_2pt_flux; //make use of the sparsity pattern from above to assemble only n^d non-zero entries without ever allocating not computing zeros. for(int istate=0; istate metric_cofactor_surf; + dealii::Tensor<2,dim,adtype> metric_cofactor_surf; for(int idim=0; idim::assemble_boundary_term_strong( } //Compute the conservative values on the facet from the interpolated entorpy variables. - std::array entropy_var_face; + std::array entropy_var_face; for(int istate=0; istate soln_state_face; - soln_state_face= this->pde_physics_double->compute_conservative_variables_from_entropy_variables (entropy_var_face); + std::array soln_state_face; + soln_state_face= pde_physics.compute_conservative_variables_from_entropy_variables (entropy_var_face); //only do the n_quad_1D vol points that give non-zero entries from Hadamard product. for(unsigned int row_index = iquad_face * n_quad_pts_1D, column_index = 0; @@ -1602,34 +1631,40 @@ void DGStrong::assemble_boundary_term_strong( // Copy Metric Cofactor in a way can use for transforming Tensor Blocks to reference space // The way it is stored in metric_operators is to use sum-factorization in each direction, // but here it is cleaner to apply a reference transformation in each Tensor block returned by physics. - dealii::Tensor<2,dim,real> metric_cofactor_vol; + dealii::Tensor<2,dim,adtype> metric_cofactor_vol; for(int idim=0; idim entropy_var; + std::array entropy_var; for(int istate=0; istate soln_state; - soln_state = this->pde_physics_double->compute_conservative_variables_from_entropy_variables (entropy_var); + std::array soln_state; + soln_state = pde_physics.compute_conservative_variables_from_entropy_variables (entropy_var); //Note that the flux basis is collocated on the volume cubature set so we don't need to evaluate the entropy variables //on the volume set then transform back to the conservative variables since the flux basis volume //projection is identity. //Compute the physical flux - std::array,nstate> conv_phys_flux_2pt; - conv_phys_flux_2pt = this->pde_physics_double->convective_numerical_split_flux(soln_state, soln_state_face); + std::array,nstate> conv_phys_flux_2pt; + conv_phys_flux_2pt = pde_physics.convective_numerical_split_flux(soln_state, soln_state_face); for(int istate=0; istate conv_ref_flux_2pt; + dealii::Tensor<1,dim,adtype> conv_ref_flux_2pt; //For each state, transform the physical flux to a reference flux. + dealii::Tensor<2,dim,adtype> metric_cofactor_split; + for(int idim=0; idim::assemble_boundary_term_strong( // Eq.(15) in Chan, Jesse. "Skew-symmetric entropy stable modal discontinuous Galerkin formulations." Journal of Scientific Computing 81.1 (2019): 459-485. for(int istate=0; istate surface_ref_2pt_flux_int_Hadamard_with_surf_oper(n_face_quad_pts, n_quad_pts_1D); - flux_basis.Hadamard_product(surf_oper_sparse, + std::vector surface_ref_2pt_flux_int_Hadamard_with_surf_oper(n_face_quad_pts * n_quad_pts_1D); + flux_basis.Hadamard_product_AD_vector(surf_oper_sparse, surface_ref_2pt_flux[istate], surface_ref_2pt_flux_int_Hadamard_with_surf_oper); //sum with reference unit normal @@ -1661,11 +1696,11 @@ void DGStrong::assemble_boundary_term_strong( for(unsigned int iface_quad=0; iface_quad::assemble_boundary_term_strong( //the outward reference normal dircetion. - std::array,nstate> conv_flux_dot_normal; - std::array,nstate> diss_flux_dot_normal_diff; + std::array,nstate> conv_flux_dot_normal; + std::array,nstate> diss_flux_dot_normal_diff; // Get surface numerical fluxes for (unsigned int iquad=0; iquad::assemble_boundary_term_strong( // but here it is cleaner to apply a reference transformation in each Tensor block returned by physics. // Note that for a conforming mesh, the facet metric cofactor matrix is the same from either interioir or exterior metric terms. // This is verified for the metric computations in: unit_tests/operator_tests/surface_conforming_test.cpp - dealii::Tensor<2,dim,real> metric_cofactor_surf; + dealii::Tensor<2,dim,adtype> metric_cofactor_surf; for(int idim=0; idim unit_phys_normal_int; + dealii::Tensor<1,dim,adtype> unit_phys_normal_int; metric_oper.transform_reference_to_physical(unit_ref_normal_int, metric_cofactor_surf, unit_phys_normal_int); - const double face_Jac_norm_scaled = unit_phys_normal_int.norm(); + adtype face_Jac_norm_scaled = 0.0; + for(int idim=0; idim entropy_var_face_int; - std::array,nstate> aux_soln_state_int; - std::array soln_interp_to_face_int; + std::array entropy_var_face_int; + std::array,nstate> aux_soln_state_int; + std::array soln_interp_to_face_int; for(int istate=0; istate::assemble_boundary_term_strong( } //extract solution on surface from projected entropy variables - std::array soln_state_int; - soln_state_int = this->pde_physics_double->compute_conservative_variables_from_entropy_variables (entropy_var_face_int); + std::array soln_state_int; + soln_state_int = pde_physics.compute_conservative_variables_from_entropy_variables (entropy_var_face_int); if(!this->all_parameters->use_split_form && !this->all_parameters->use_curvilinear_split_form){ @@ -1721,9 +1760,9 @@ void DGStrong::assemble_boundary_term_strong( } } - std::array soln_boundary; - std::array,nstate> grad_soln_boundary; - dealii::Point surf_flux_node; + std::array soln_boundary; + std::array,nstate> grad_soln_boundary; + dealii::Point surf_flux_node; for(int idim=0; idim::assemble_boundary_term_strong( //or solution from the projected entropy variables. //Now, it uses projected entropy variables for NSFR, and solution //interpolated to face for conservative DG. - this->pde_physics_double->boundary_face_values (boundary_id, surf_flux_node, unit_phys_normal_int, soln_state_int, aux_soln_state_int, soln_boundary, grad_soln_boundary); + pde_physics.boundary_face_values (boundary_id, surf_flux_node, unit_phys_normal_int, soln_state_int, aux_soln_state_int, soln_boundary, grad_soln_boundary); // Convective numerical flux. - std::array conv_num_flux_dot_n_at_q; - conv_num_flux_dot_n_at_q = this->conv_num_flux_double->evaluate_flux(soln_state_int, soln_boundary, unit_phys_normal_int); + std::array conv_num_flux_dot_n_at_q; + conv_num_flux_dot_n_at_q = conv_num_flux.evaluate_flux(soln_state_int, soln_boundary, unit_phys_normal_int); // Dissipative numerical flux - std::array diss_auxi_num_flux_dot_n_at_q; - diss_auxi_num_flux_dot_n_at_q = this->diss_num_flux_double->evaluate_auxiliary_flux( + std::array diss_auxi_num_flux_dot_n_at_q; + diss_auxi_num_flux_dot_n_at_q = diss_num_flux.evaluate_auxiliary_flux( current_cell_index, current_cell_index, 0.0, 0.0, soln_interp_to_face_int, soln_boundary, @@ -1761,7 +1800,7 @@ void DGStrong::assemble_boundary_term_strong( //solve rhs for(int istate=0; istate rhs(n_shape_fns); + std::vector rhs(n_shape_fns); //Convective flux on the facet if(this->all_parameters->use_split_form || this->all_parameters->use_curvilinear_split_form){ std::vector ones_surf(n_face_quad_pts, 1.0); @@ -1798,32 +1837,39 @@ void DGStrong::assemble_boundary_term_strong( true, -1.0);//adding=true, scaled by factor=-1.0 bc subtract it for(unsigned int ishape=0; ishape +template void DGStrong::assemble_face_term_strong( - const unsigned int iface, const unsigned int neighbor_iface, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const unsigned int poly_degree_int, - const unsigned int poly_degree_ext, - const real penalty, - const std::vector &dof_indices_int, - const std::vector &dof_indices_ext, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::metric_operators &metric_oper_int, - OPERATOR::metric_operators &metric_oper_ext, - dealii::Vector &local_rhs_int_cell, - dealii::Vector &local_rhs_ext_cell) + const unsigned int iface, + const unsigned int neighbor_iface, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const std::array,nstate> &soln_coeff_int, + const std::array,nstate> &soln_coeff_ext, + const std::array>,nstate> &aux_soln_coeff_int, + const std::array>,nstate> &aux_soln_coeff_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const real penalty, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + const Physics::PhysicsBase &pde_physics, + const NumericalFlux::NumericalFluxConvective &conv_num_flux, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + std::vector &local_rhs_int_cell, + std::vector &local_rhs_ext_cell) { (void) current_cell_index; (void) neighbor_cell_index; @@ -1841,65 +1887,16 @@ void DGStrong::assemble_face_term_strong( const unsigned int n_shape_fns_int = n_dofs_int / nstate; const unsigned int n_shape_fns_ext = n_dofs_ext / nstate; - AssertDimension (n_dofs_int, dof_indices_int.size()); - AssertDimension (n_dofs_ext, dof_indices_ext.size()); - - // Extract interior modal coefficients of solution - std::array,nstate> soln_coeff_int; - std::array>,nstate> aux_soln_coeff_int; - for (unsigned int idof = 0; idof < n_dofs_int; ++idof) { - const unsigned int istate = this->fe_collection[poly_degree_int].system_to_component_index(idof).first; - const unsigned int ishape = this->fe_collection[poly_degree_int].system_to_component_index(idof).second; - if(ishape == 0) - soln_coeff_int[istate].resize(n_shape_fns_int); - - soln_coeff_int[istate][ishape] = DGBase::solution(dof_indices_int[idof]); - for(int idim=0; idimuse_auxiliary_eq){ - aux_soln_coeff_int[istate][idim][ishape] = DGBase::auxiliary_solution[idim](dof_indices_int[idof]); - } - else{ - aux_soln_coeff_int[istate][idim][ishape] = 0.0; - } - } - } - - // Extract exterior modal coefficients of solution - std::array,nstate> soln_coeff_ext; - std::array>,nstate> aux_soln_coeff_ext; - for (unsigned int idof = 0; idof < n_dofs_ext; ++idof) { - const unsigned int istate = this->fe_collection[poly_degree_ext].system_to_component_index(idof).first; - const unsigned int ishape = this->fe_collection[poly_degree_ext].system_to_component_index(idof).second; - if(ishape == 0){ - soln_coeff_ext[istate].resize(n_shape_fns_ext); - } - soln_coeff_ext[istate][ishape] = DGBase::solution(dof_indices_ext[idof]); - for(int idim=0; idimuse_auxiliary_eq){ - aux_soln_coeff_ext[istate][idim][ishape] = DGBase::auxiliary_solution[idim](dof_indices_ext[idof]); - } - else{ - aux_soln_coeff_ext[istate][idim][ishape] = 0.0; - } - } - } - // Interpolate the modal coefficients to the volume cubature nodes. - std::array,nstate> soln_at_vol_q_int; - std::array,nstate> soln_at_vol_q_ext; - std::array>,nstate> aux_soln_at_vol_q_int; - std::array>,nstate> aux_soln_at_vol_q_ext; + std::array,nstate> soln_at_vol_q_int; + std::array,nstate> soln_at_vol_q_ext; + std::array>,nstate> aux_soln_at_vol_q_int; + std::array>,nstate> aux_soln_at_vol_q_ext; // Interpolate modal soln coefficients to the facet. - std::array,nstate> soln_at_surf_q_int; - std::array,nstate> soln_at_surf_q_ext; - std::array>,nstate> aux_soln_at_surf_q_int; - std::array>,nstate> aux_soln_at_surf_q_ext; + std::array,nstate> soln_at_surf_q_int; + std::array,nstate> soln_at_surf_q_ext; + std::array>,nstate> aux_soln_at_surf_q_int; + std::array>,nstate> aux_soln_at_surf_q_ext; for(int istate=0; istate::assemble_face_term_strong( // Compute reference volume fluxes in both interior and exterior cells. // First we do interior. - std::array>,nstate> conv_ref_flux_at_vol_q_int; - std::array>,nstate> diffusive_ref_flux_at_vol_q_int; + std::array>,nstate> conv_ref_flux_at_vol_q_int; + std::array>,nstate> diffusive_ref_flux_at_vol_q_int; for (unsigned int iquad=0; iquad metric_cofactor_vol_int; + dealii::Tensor<2,dim,adtype> metric_cofactor_vol_int; for(int idim=0; idim soln_state; - std::array,nstate> aux_soln_state; + std::array soln_state; + std::array,nstate> aux_soln_state; for(int istate=0; istate::assemble_face_term_strong( } // Evaluate physical convective flux - std::array,nstate> conv_phys_flux; + std::array,nstate> conv_phys_flux; //Only for conservtive DG do we interpolate volume fluxes to the facet if(!this->all_parameters->use_split_form && !this->all_parameters->use_curvilinear_split_form){ - conv_phys_flux = this->pde_physics_double->convective_flux (soln_state); + conv_phys_flux = pde_physics.convective_flux (soln_state); } // Compute the physical dissipative flux - std::array,nstate> diffusive_phys_flux; - diffusive_phys_flux = this->pde_physics_double->dissipative_flux(soln_state, aux_soln_state, current_cell_index); + std::array,nstate> diffusive_phys_flux; + diffusive_phys_flux = pde_physics.dissipative_flux(soln_state, aux_soln_state, current_cell_index); // Write the values in a way that we can use sum-factorization on. for(int istate=0; istate conv_ref_flux; - dealii::Tensor<1,dim,real> diffusive_ref_flux; + dealii::Tensor<1,dim,adtype> conv_ref_flux; + dealii::Tensor<1,dim,adtype> diffusive_ref_flux; // transform the conservative convective physical flux to reference space if(!this->all_parameters->use_split_form && !this->all_parameters->use_curvilinear_split_form){ metric_oper_int.transform_physical_to_reference( @@ -2024,20 +2021,20 @@ void DGStrong::assemble_face_term_strong( // Next we do exterior volume reference fluxes. // Note we split the quad integrals because the interior and exterior could be of different poly basis - std::array>,nstate> conv_ref_flux_at_vol_q_ext; - std::array>,nstate> diffusive_ref_flux_at_vol_q_ext; + std::array>,nstate> conv_ref_flux_at_vol_q_ext; + std::array>,nstate> diffusive_ref_flux_at_vol_q_ext; for (unsigned int iquad=0; iquad metric_cofactor_vol_ext; + dealii::Tensor<2,dim,adtype> metric_cofactor_vol_ext; for(int idim=0; idim soln_state; - std::array,nstate> aux_soln_state; + std::array soln_state; + std::array,nstate> aux_soln_state; for(int istate=0; istate::assemble_face_term_strong( } // Evaluate physical convective flux - std::array,nstate> conv_phys_flux; + std::array,nstate> conv_phys_flux; if(!this->all_parameters->use_split_form && !this->all_parameters->use_curvilinear_split_form){ - conv_phys_flux = this->pde_physics_double->convective_flux (soln_state); + conv_phys_flux = pde_physics.convective_flux (soln_state); } // Compute the physical dissipative flux - std::array,nstate> diffusive_phys_flux; - diffusive_phys_flux = this->pde_physics_double->dissipative_flux(soln_state, aux_soln_state, neighbor_cell_index); + std::array,nstate> diffusive_phys_flux; + diffusive_phys_flux = pde_physics.dissipative_flux(soln_state, aux_soln_state, neighbor_cell_index); // Write the values in a way that we can use sum-factorization on. for(int istate=0; istate conv_ref_flux; - dealii::Tensor<1,dim,real> diffusive_ref_flux; + dealii::Tensor<1,dim,adtype> conv_ref_flux; + dealii::Tensor<1,dim,adtype> diffusive_ref_flux; // transform the conservative convective physical flux to reference space if(!this->all_parameters->use_split_form && !this->all_parameters->use_curvilinear_split_form){ metric_oper_ext.transform_physical_to_reference( @@ -2101,10 +2098,10 @@ void DGStrong::assemble_face_term_strong( const int dim_not_zero_int = iface / 2;//reference direction of face integer division const int dim_not_zero_ext = neighbor_iface / 2;//reference direction of face integer division - std::array,nstate> conv_int_vol_ref_flux_interp_to_face_dot_ref_normal; - std::array,nstate> conv_ext_vol_ref_flux_interp_to_face_dot_ref_normal; - std::array,nstate> diffusive_int_vol_ref_flux_interp_to_face_dot_ref_normal; - std::array,nstate> diffusive_ext_vol_ref_flux_interp_to_face_dot_ref_normal; + std::array,nstate> conv_int_vol_ref_flux_interp_to_face_dot_ref_normal; + std::array,nstate> conv_ext_vol_ref_flux_interp_to_face_dot_ref_normal; + std::array,nstate> diffusive_int_vol_ref_flux_interp_to_face_dot_ref_normal; + std::array,nstate> diffusive_ext_vol_ref_flux_interp_to_face_dot_ref_normal; for(int istate=0; istate::assemble_face_term_strong( //pages 355 (Eq. 57 with text around it) and page 359 (Eq 86 and text below it). // First, transform the volume conservative solution at volume cubature nodes to entropy variables. - std::array,nstate> entropy_var_vol_int; + std::array,nstate> entropy_var_vol_int; for(unsigned int iquad=0; iquad soln_state; + std::array soln_state; for(int istate=0; istate entropy_var; - entropy_var = this->pde_physics_double->compute_entropy_variables(soln_state); + std::array entropy_var; + entropy_var = pde_physics.compute_entropy_variables(soln_state); for(int istate=0; istate::assemble_face_term_strong( entropy_var_vol_int[istate][iquad] = entropy_var[istate]; } } - std::array,nstate> entropy_var_vol_ext; + std::array,nstate> entropy_var_vol_ext; for(unsigned int iquad=0; iquad soln_state; + std::array soln_state; for(int istate=0; istate entropy_var; - entropy_var = this->pde_physics_double->compute_entropy_variables(soln_state); + std::array entropy_var; + entropy_var = pde_physics.compute_entropy_variables(soln_state); for(int istate=0; istate::assemble_face_term_strong( } //project it onto the solution basis functions and interpolate it - std::array,nstate> projected_entropy_var_vol_int; - std::array,nstate> projected_entropy_var_vol_ext; - std::array,nstate> projected_entropy_var_surf_int; - std::array,nstate> projected_entropy_var_surf_ext; + std::array,nstate> projected_entropy_var_vol_int; + std::array,nstate> projected_entropy_var_vol_ext; + std::array,nstate> projected_entropy_var_surf_int; + std::array,nstate> projected_entropy_var_surf_ext; for(int istate=0; istate::assemble_face_term_strong( projected_entropy_var_surf_ext[istate].resize(n_face_quad_pts); //interior - std::vector entropy_var_coeff_int(n_shape_fns_int); + std::vector entropy_var_coeff_int(n_shape_fns_int); soln_basis_projection_oper_int.matrix_vector_mult_1D(entropy_var_vol_int[istate], entropy_var_coeff_int, soln_basis_projection_oper_int.oneD_vol_operator); @@ -2212,7 +2209,7 @@ void DGStrong::assemble_face_term_strong( soln_basis_int.oneD_vol_operator); //exterior - std::vector entropy_var_coeff_ext(n_shape_fns_ext); + std::vector entropy_var_coeff_ext(n_shape_fns_ext); soln_basis_projection_oper_ext.matrix_vector_mult_1D(entropy_var_vol_ext[istate], entropy_var_coeff_ext, soln_basis_projection_oper_ext.oneD_vol_operator); @@ -2241,21 +2238,21 @@ void DGStrong::assemble_face_term_strong( flux_basis_ext.sum_factorized_Hadamard_surface_sparsity_pattern(n_face_quad_pts, n_quad_pts_1D_ext, Hadamard_rows_sparsity_ext, Hadamard_columns_sparsity_ext, dim_not_zero_ext); } - std::array,nstate> surf_vol_ref_2pt_flux_interp_surf_int; - std::array,nstate> surf_vol_ref_2pt_flux_interp_surf_ext; - std::array,nstate> surf_vol_ref_2pt_flux_interp_vol_int; - std::array,nstate> surf_vol_ref_2pt_flux_interp_vol_ext; + std::array,nstate> surf_vol_ref_2pt_flux_interp_surf_int; + std::array,nstate> surf_vol_ref_2pt_flux_interp_surf_ext; + std::array,nstate> surf_vol_ref_2pt_flux_interp_vol_int; + std::array,nstate> surf_vol_ref_2pt_flux_interp_vol_ext; if(this->all_parameters->use_split_form || this->all_parameters->use_curvilinear_split_form){ //get surface-volume hybrid 2pt flux from Eq.(15) in Chan, Jesse. "Skew-symmetric entropy stable modal discontinuous Galerkin formulations." Journal of Scientific Computing 81.1 (2019): 459-485. - std::array,nstate> surface_ref_2pt_flux_int; - std::array,nstate> surface_ref_2pt_flux_ext; + std::array,nstate> surface_ref_2pt_flux_int; + std::array,nstate> surface_ref_2pt_flux_ext; //make use of the sparsity pattern from above to assemble only n^d non-zero entries without ever allocating not computing zeros. for(int istate=0; istate metric_cofactor_surf; + dealii::Tensor<2,dim,adtype> metric_cofactor_surf; for(int idim=0; idim::assemble_face_term_strong( } //Compute the conservative values on the facet from the interpolated entorpy variables. - std::array entropy_var_face_int; - std::array entropy_var_face_ext; + std::array entropy_var_face_int; + std::array entropy_var_face_ext; for(int istate=0; istate soln_state_face_int; - soln_state_face_int = this->pde_physics_double->compute_conservative_variables_from_entropy_variables (entropy_var_face_int); - std::array soln_state_face_ext; - soln_state_face_ext = this->pde_physics_double->compute_conservative_variables_from_entropy_variables (entropy_var_face_ext); + std::array soln_state_face_int; + soln_state_face_int = pde_physics.compute_conservative_variables_from_entropy_variables (entropy_var_face_int); + std::array soln_state_face_ext; + soln_state_face_ext = pde_physics.compute_conservative_variables_from_entropy_variables (entropy_var_face_ext); //only do the n_quad_1D vol points that give non-zero entries from Hadamard product. for(unsigned int row_index = iquad_face * n_quad_pts_1D_int, column_index = 0; @@ -2288,34 +2285,41 @@ void DGStrong::assemble_face_term_strong( // Copy Metric Cofactor in a way can use for transforming Tensor Blocks to reference space // The way it is stored in metric_operators is to use sum-factorization in each direction, // but here it is cleaner to apply a reference transformation in each Tensor block returned by physics. - dealii::Tensor<2,dim,real> metric_cofactor_vol_int; + dealii::Tensor<2,dim,adtype> metric_cofactor_vol_int; for(int idim=0; idim entropy_var; + std::array entropy_var; for(int istate=0; istate soln_state; - soln_state = this->pde_physics_double->compute_conservative_variables_from_entropy_variables (entropy_var); + std::array soln_state; + soln_state = pde_physics.compute_conservative_variables_from_entropy_variables (entropy_var); //Note that the flux basis is collocated on the volume cubature set so we don't need to evaluate the entropy variables //on the volume set then transform back to the conservative variables since the flux basis volume //projection is identity. //Compute the physical flux - std::array,nstate> conv_phys_flux_2pt; - conv_phys_flux_2pt = this->pde_physics_double->convective_numerical_split_flux(soln_state, soln_state_face_int); + std::array,nstate> conv_phys_flux_2pt; + conv_phys_flux_2pt = pde_physics.convective_numerical_split_flux(soln_state, soln_state_face_int); for(int istate=0; istate conv_ref_flux_2pt; + dealii::Tensor<1,dim,adtype> conv_ref_flux_2pt; + //For each state, transform the physical flux to a reference flux. //For each state, transform the physical flux to a reference flux. + dealii::Tensor<2,dim,adtype> metric_cofactor_split; + for(int idim=0; idim::assemble_face_term_strong( // Copy Metric Cofactor in a way can use for transforming Tensor Blocks to reference space // The way it is stored in metric_operators is to use sum-factorization in each direction, // but here it is cleaner to apply a reference transformation in each Tensor block returned by physics. - dealii::Tensor<2,dim,real> metric_cofactor_vol_ext; + dealii::Tensor<2,dim,adtype> metric_cofactor_vol_ext; for(int idim=0; idim entropy_var; + std::array entropy_var; for(int istate=0; istate soln_state; - soln_state = this->pde_physics_double->compute_conservative_variables_from_entropy_variables (entropy_var); + std::array soln_state; + soln_state = pde_physics.compute_conservative_variables_from_entropy_variables (entropy_var); //Compute the physical flux - std::array,nstate> conv_phys_flux_2pt; - conv_phys_flux_2pt = this->pde_physics_double->convective_numerical_split_flux(soln_state, soln_state_face_ext); + std::array,nstate> conv_phys_flux_2pt; + conv_phys_flux_2pt = pde_physics.convective_numerical_split_flux(soln_state, soln_state_face_ext); for(int istate=0; istate conv_ref_flux_2pt; + dealii::Tensor<1,dim,adtype> conv_ref_flux_2pt; //For each state, transform the physical flux to a reference flux. + dealii::Tensor<2,dim,adtype> metric_cofactor_split; + for(int idim=0; idim::assemble_face_term_strong( // Eq.(15) in Chan, Jesse. "Skew-symmetric entropy stable modal discontinuous Galerkin formulations." Journal of Scientific Computing 81.1 (2019): 459-485. for(int istate=0; istate surface_ref_2pt_flux_int_Hadamard_with_surf_oper(n_face_quad_pts, n_quad_pts_1D_int); - flux_basis_int.Hadamard_product(surf_oper_sparse_int, + std::vector surface_ref_2pt_flux_int_Hadamard_with_surf_oper(n_face_quad_pts * n_quad_pts_1D_int); + flux_basis_int.Hadamard_product_AD_vector(surf_oper_sparse_int, surface_ref_2pt_flux_int[istate], surface_ref_2pt_flux_int_Hadamard_with_surf_oper); - dealii::FullMatrix surface_ref_2pt_flux_ext_Hadamard_with_surf_oper(n_face_quad_pts, n_quad_pts_1D_ext); - flux_basis_ext.Hadamard_product(surf_oper_sparse_ext, + std::vector surface_ref_2pt_flux_ext_Hadamard_with_surf_oper(n_face_quad_pts * n_quad_pts_1D_ext); + flux_basis_ext.Hadamard_product_AD_vector(surf_oper_sparse_ext, surface_ref_2pt_flux_ext[istate], surface_ref_2pt_flux_ext_Hadamard_with_surf_oper); //sum with reference unit normal @@ -2402,20 +2412,20 @@ void DGStrong::assemble_face_term_strong( for(unsigned int iface_quad=0; iface_quad::assemble_face_term_strong( // Evaluate reference numerical fluxes. - std::array,nstate> conv_num_flux_dot_n; - std::array,nstate> diss_auxi_num_flux_dot_n; + std::array,nstate> conv_num_flux_dot_n; + std::array,nstate> diss_auxi_num_flux_dot_n; for (unsigned int iquad=0; iquad metric_cofactor_surf; + dealii::Tensor<2,dim,adtype> metric_cofactor_surf; for(int idim=0; idim entropy_var_face_int; - std::array entropy_var_face_ext; - std::array,nstate> aux_soln_state_int; - std::array,nstate> aux_soln_state_ext; - std::array soln_interp_to_face_int; - std::array soln_interp_to_face_ext; + std::array entropy_var_face_int; + std::array entropy_var_face_ext; + std::array,nstate> aux_soln_state_int; + std::array,nstate> aux_soln_state_ext; + std::array soln_interp_to_face_int; + std::array soln_interp_to_face_ext; for(int istate=0; istate::assemble_face_term_strong( } } - std::array soln_state_int; - soln_state_int = this->pde_physics_double->compute_conservative_variables_from_entropy_variables (entropy_var_face_int); - std::array soln_state_ext; - soln_state_ext = this->pde_physics_double->compute_conservative_variables_from_entropy_variables (entropy_var_face_ext); + std::array soln_state_int; + soln_state_int = pde_physics.compute_conservative_variables_from_entropy_variables (entropy_var_face_int); + std::array soln_state_ext; + soln_state_ext = pde_physics.compute_conservative_variables_from_entropy_variables (entropy_var_face_ext); if(!this->all_parameters->use_split_form && !this->all_parameters->use_curvilinear_split_form){ @@ -2472,21 +2482,25 @@ void DGStrong::assemble_face_term_strong( } // numerical fluxes - dealii::Tensor<1,dim,real> unit_phys_normal_int; + dealii::Tensor<1,dim,adtype> unit_phys_normal_int; metric_oper_int.transform_reference_to_physical(unit_ref_normal_int, metric_cofactor_surf, unit_phys_normal_int); - const double face_Jac_norm_scaled = unit_phys_normal_int.norm(); + adtype face_Jac_norm_scaled = 0.0; + for(int idim=0; idim conv_num_flux_dot_n_at_q; - std::array diss_auxi_num_flux_dot_n_at_q; + std::array conv_num_flux_dot_n_at_q; + std::array diss_auxi_num_flux_dot_n_at_q; // Convective numerical flux. - conv_num_flux_dot_n_at_q = this->conv_num_flux_double->evaluate_flux(soln_state_int, soln_state_ext, unit_phys_normal_int); + conv_num_flux_dot_n_at_q = conv_num_flux.evaluate_flux(soln_state_int, soln_state_ext, unit_phys_normal_int); // dissipative numerical flux - diss_auxi_num_flux_dot_n_at_q = this->diss_num_flux_double->evaluate_auxiliary_flux( + diss_auxi_num_flux_dot_n_at_q = diss_num_flux.evaluate_auxiliary_flux( current_cell_index, neighbor_cell_index, 0.0, 0.0, soln_interp_to_face_int, soln_interp_to_face_ext, @@ -2515,7 +2529,7 @@ void DGStrong::assemble_face_term_strong( const std::vector &surf_quad_weights = this->face_quadrature_collection[poly_degree_int].get_weights(); for(int istate=0; istate rhs_int(n_shape_fns_int); + std::vector rhs_int(n_shape_fns_int); // convective flux if(this->all_parameters->use_split_form || this->all_parameters->use_curvilinear_split_form){ @@ -2563,11 +2577,11 @@ void DGStrong::assemble_face_term_strong( for(unsigned int ishape=0; ishape rhs_ext(n_shape_fns_ext); + std::vector rhs_ext(n_shape_fns_ext); // convective flux if(this->all_parameters->use_split_form || this->all_parameters->use_curvilinear_split_form){ @@ -2616,500 +2630,12 @@ void DGStrong::assemble_face_term_strong( for(unsigned int ishape=0; ishape -void DGStrong::assemble_boundary_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator /*cell*/, - const dealii::types::global_dof_index /*current_cell_index*/, - const unsigned int ,//face_number, - const unsigned int /*boundary_id*/, - const dealii::FEFaceValuesBase &/*fe_values_boundary*/, - const real /*penalty*/, - const dealii::FESystem &,//fe, - const dealii::Quadrature &,//quadrature, - const std::vector &,//metric_dof_indices, - const std::vector &/*soln_dof_indices*/, - dealii::Vector &/*local_rhs_int_cell*/, - const bool /*compute_dRdW*/, - const bool /*compute_dRdX*/, - const bool /*compute_d2R*/) -{ - //Do nothing - -// (void) current_cell_index; -// assert(compute_dRdW); assert(!compute_dRdX); assert(!compute_d2R); -// (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R; -// using ADArray = std::array; -// using ADArrayTensor1 = std::array< dealii::Tensor<1,dim,FadType>, nstate >; -// -// const unsigned int n_dofs_cell = fe_values_boundary.dofs_per_cell; -// const unsigned int n_face_quad_pts = fe_values_boundary.n_quadrature_points; -// -// AssertDimension (n_dofs_cell, soln_dof_indices.size()); -// -// const std::vector &JxW = fe_values_boundary.get_JxW_values (); -// const std::vector> &normals = fe_values_boundary.get_normal_vectors (); -// -// std::vector residual_derivatives(n_dofs_cell); -// -// std::vector soln_int(n_face_quad_pts); -// std::vector soln_ext(n_face_quad_pts); -// -// std::vector soln_grad_int(n_face_quad_pts); -// std::vector soln_grad_ext(n_face_quad_pts); -// -// std::vector conv_num_flux_dot_n(n_face_quad_pts); -// std::vector diss_soln_num_flux(n_face_quad_pts); // u* -// std::vector diss_flux_jump_int(n_face_quad_pts); // u*-u_int -// std::vector diss_flux_jump_ext(n_face_quad_pts); // u*-u_int -// std::vector diss_auxi_num_flux_dot_n(n_face_quad_pts); // sigma* -// -// std::vector conv_phys_flux(n_face_quad_pts); -// -// // AD variable -// std::vector< FadType > soln_coeff_int(n_dofs_cell); -// const unsigned int n_total_indep = n_dofs_cell; -// for (unsigned int idof = 0; idof < n_dofs_cell; ++idof) { -// soln_coeff_int[idof] = DGBase::solution(soln_dof_indices[idof]); -// soln_coeff_int[idof].diff(idof, n_total_indep); -// } -// -// for (unsigned int iquad=0; iquad > quad_pts = fe_values_boundary.get_quadrature_points(); -// for (unsigned int iquad=0; iquad normal_int = normals[iquad]; -// const dealii::Tensor<1,dim,FadType> normal_ext = -normal_int; -// -// for (unsigned int idof=0; idof real_quad_point = quad_pts[iquad]; -// dealii::Point ad_point; -// for (int d=0;dpde_physics_fad->boundary_face_values (boundary_id, ad_point, normal_int, soln_int[iquad], soln_grad_int[iquad], soln_ext[iquad], soln_grad_ext[iquad]); -// -// // -// // Evaluate physical convective flux, physical dissipative flux -// // Following the the boundary treatment given by -// // Hartmann, R., Numerical Analysis of Higher Order Discontinuous Galerkin Finite Element Methods, -// // Institute of Aerodynamics and Flow Technology, DLR (German Aerospace Center), 2008. -// // Details given on page 93 -// //conv_num_flux_dot_n[iquad] = DGBaseState::conv_num_flux_fad->evaluate_flux(soln_ext[iquad], soln_ext[iquad], normal_int); -// -// // So, I wasn't able to get Euler manufactured solutions to converge when F* = F*(Ubc, Ubc) -// // Changing it back to the standdard F* = F*(Uin, Ubc) -// // This is known not be adjoint consistent as per the paper above. Page 85, second to last paragraph. -// // Losing 2p+1 OOA on functionals for all PDEs. -// conv_num_flux_dot_n[iquad] = DGBaseState::conv_num_flux_fad->evaluate_flux(soln_int[iquad], soln_ext[iquad], normal_int); -// -// // Used for strong form -// // Which physical convective flux to use? -// conv_phys_flux[iquad] = this->pde_physics_fad->convective_flux (soln_int[iquad]); -// -// // Notice that the flux uses the solution given by the Dirichlet or Neumann boundary condition -// diss_soln_num_flux[iquad] = DGBaseState::diss_num_flux_fad->evaluate_solution_flux(soln_ext[iquad], soln_ext[iquad], normal_int); -// -// ADArrayTensor1 diss_soln_jump_int; -// ADArrayTensor1 diss_soln_jump_ext; -// for (int s=0; spde_physics_fad->dissipative_flux (soln_int[iquad], diss_soln_jump_int, current_cell_index); -// diss_flux_jump_ext[iquad] = this->pde_physics_fad->dissipative_flux (soln_ext[iquad], diss_soln_jump_ext, neighbor_cell_index); -// -// diss_auxi_num_flux_dot_n[iquad] = DGBaseState::diss_num_flux_fad->evaluate_auxiliary_flux( -// current_cell_index, neighbor_cell_index, -// 0.0, 0.0, -// soln_int[iquad], soln_ext[iquad], -// soln_grad_int[iquad], soln_grad_ext[iquad], -// normal_int, penalty, true); -// } -// -// // Boundary integral -// for (unsigned int itest=0; itestall_parameters->ode_solver_param.ode_solver_type == Parameters::ODESolverParam::ODESolverEnum::implicit_solver) { -// for (unsigned int idof = 0; idof < n_dofs_cell; ++idof) { -// //residual_derivatives[idof] = rhs.fastAccessDx(idof); -// residual_derivatives[idof] = rhs.fastAccessDx(idof); -// } -// this->system_matrix.add(soln_dof_indices[itest], soln_dof_indices, residual_derivatives); -// } -// } -} - -template -void DGStrong::assemble_volume_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator /*cell*/, - const dealii::types::global_dof_index /*current_cell_index*/, - const dealii::FEValues &/*fe_values_vol*/, - const dealii::FESystem &,//fe, - const dealii::Quadrature &,//quadrature, - const std::vector &,//metric_dof_indices, - const std::vector &/*cell_dofs_indices*/, - dealii::Vector &/*local_rhs_int_cell*/, - const dealii::FEValues &/*fe_values_lagrange*/, - const bool /*compute_dRdW*/, - const bool /*compute_dRdX*/, - const bool /*compute_d2R*/) -{ - //Do nothing - -// (void) current_cell_index; -// assert(compute_dRdW); assert(!compute_dRdX); assert(!compute_d2R); -// (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R; -// using ADArray = std::array; -// using ADArrayTensor1 = std::array< dealii::Tensor<1,dim,FadType>, nstate >; -// -// const unsigned int n_quad_pts = fe_values_vol.n_quadrature_points; -// const unsigned int n_dofs_cell = fe_values_vol.dofs_per_cell; -// -// AssertDimension (n_dofs_cell, cell_dofs_indices.size()); -// -// const std::vector &JxW = fe_values_vol.get_JxW_values (); -// -// std::vector residual_derivatives(n_dofs_cell); -// -// std::vector< ADArray > soln_at_q(n_quad_pts); -// std::vector< ADArrayTensor1 > soln_grad_at_q(n_quad_pts); // Tensor initialize with zeros -// -// std::vector< ADArrayTensor1 > conv_phys_flux_at_q(n_quad_pts); -// std::vector< ADArrayTensor1 > diss_phys_flux_at_q(n_quad_pts); -// std::vector< ADArray > source_at_q(n_quad_pts); -// -// // AD variable -// std::vector< FadType > soln_coeff(n_dofs_cell); -// for (unsigned int idof = 0; idof < n_dofs_cell; ++idof) { -// soln_coeff[idof] = DGBase::solution(cell_dofs_indices[idof]); -// soln_coeff[idof].diff(idof, n_dofs_cell); -// } -// for (unsigned int iquad=0; iquad1) std::cout << "Momentum " << soln_at_q[iquad][1] << std::endl; -// //std::cout << "Energy " << soln_at_q[iquad][nstate-1] << std::endl; -// // Evaluate physical convective flux and source term -// conv_phys_flux_at_q[iquad] = DGBaseState::pde_physics_double->convective_flux (soln_at_q[iquad]); -// diss_phys_flux_at_q[iquad] = DGBaseState::pde_physics_double->dissipative_flux (soln_at_q[iquad], soln_grad_at_q[iquad], current_cell_index); -// if(this->all_parameters->manufactured_convergence_study_param.manufactured_solution_param.use_manufactured_source_term) { -// source_at_q[iquad] = DGBaseState::pde_physics_double->source_term (fe_values_vol.quadrature_point(iquad), soln_at_q[iquad], current_cell_index, DGBase::current_time); -// } -// } -// -// -// // Evaluate flux divergence by interpolating the flux -// // Since we have nodal values of the flux, we use the Lagrange polynomials to obtain the gradients at the quadrature points. -// //const dealii::FEValues &fe_values_lagrange = this->fe_values_collection_volume_lagrange.get_present_fe_values(); -// std::vector flux_divergence(n_quad_pts); -// -// std::array,nstate>,dim> f; -// std::array,nstate>,dim> g; -// -// for (int istate = 0; istateall_parameters->manufactured_convergence_study_param.manufactured_solution_param.use_manufactured_source_term) { -// rhs = rhs + fe_values_vol.shape_value_component(itest,iquad,istate) * source_at_q[iquad][istate] * JxW[iquad]; -// } -// } -// //local_rhs_int_cell(itest) += rhs; -// -// } -} - - -template -void DGStrong::assemble_face_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator /*cell*/, - const dealii::types::global_dof_index /*current_cell_index*/, - const dealii::types::global_dof_index /*neighbor_cell_index*/, - const std::pair /*face_subface_int*/, - const std::pair /*face_subface_ext*/, - const typename dealii::QProjector::DataSetDescriptor /*face_data_set_int*/, - const typename dealii::QProjector::DataSetDescriptor /*face_data_set_ext*/, - const dealii::FEFaceValuesBase &/*fe_values_int*/, - const dealii::FEFaceValuesBase &/*fe_values_ext*/, - const real /*penalty*/, - const dealii::FESystem &,//fe_int, - const dealii::FESystem &,//fe_ext, - const dealii::Quadrature &,//face_quadrature_int, - const std::vector &,//metric_dof_indices_int, - const std::vector &,//metric_dof_indices_ext, - const std::vector &/*soln_dof_indices_int*/, - const std::vector &/*soln_dof_indices_ext*/, - dealii::Vector &/*local_rhs_int_cell*/, - dealii::Vector &/*local_rhs_ext_cell*/, - const bool /*compute_dRdW*/, - const bool /*compute_dRdX*/, - const bool /*compute_d2R*/) -{ - //Do nothing - -// (void) current_cell_index; -// (void) neighbor_cell_index; -// assert(compute_dRdW); assert(!compute_dRdX); assert(!compute_d2R); -// (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R; -// using ADArray = std::array; -// using ADArrayTensor1 = std::array< dealii::Tensor<1,dim,FadType>, nstate >; -// -// // Use quadrature points of neighbor cell -// // Might want to use the maximum n_quad_pts1 and n_quad_pts2 -// const unsigned int n_face_quad_pts = fe_values_ext.n_quadrature_points; -// -// const unsigned int n_dofs_int = fe_values_int.dofs_per_cell; -// const unsigned int n_dofs_ext = fe_values_ext.dofs_per_cell; -// -// AssertDimension (n_dofs_int, soln_dof_indices_int.size()); -// AssertDimension (n_dofs_ext, soln_dof_indices_ext.size()); -// -// // Jacobian and normal should always be consistent between two elements -// // even for non-conforming meshes? -// const std::vector &JxW_int = fe_values_int.get_JxW_values (); -// const std::vector > &normals_int = fe_values_int.get_normal_vectors (); -// -// // AD variable -// std::vector soln_coeff_int_ad(n_dofs_int); -// std::vector soln_coeff_ext_ad(n_dofs_ext); -// -// -// // Jacobian blocks -// std::vector dR1_dW1(n_dofs_int); -// std::vector dR1_dW2(n_dofs_ext); -// std::vector dR2_dW1(n_dofs_int); -// std::vector dR2_dW2(n_dofs_ext); -// -// std::vector conv_num_flux_dot_n(n_face_quad_pts); -// std::vector conv_phys_flux_int(n_face_quad_pts); -// std::vector conv_phys_flux_ext(n_face_quad_pts); -// -// // Interpolate solution to the face quadrature points -// std::vector< ADArray > soln_int(n_face_quad_pts); -// std::vector< ADArray > soln_ext(n_face_quad_pts); -// -// std::vector< ADArrayTensor1 > soln_grad_int(n_face_quad_pts); // Tensor initialize with zeros -// std::vector< ADArrayTensor1 > soln_grad_ext(n_face_quad_pts); // Tensor initialize with zeros -// -// std::vector diss_soln_num_flux(n_face_quad_pts); // u* -// std::vector diss_auxi_num_flux_dot_n(n_face_quad_pts); // sigma* -// -// std::vector diss_flux_jump_int(n_face_quad_pts); // u*-u_int -// std::vector diss_flux_jump_ext(n_face_quad_pts); // u*-u_ext -// // AD variable -// const unsigned int n_total_indep = n_dofs_int + n_dofs_ext; -// for (unsigned int idof = 0; idof < n_dofs_int; ++idof) { -// soln_coeff_int_ad[idof] = DGBase::solution(soln_dof_indices_int[idof]); -// soln_coeff_int_ad[idof].diff(idof, n_total_indep); -// } -// for (unsigned int idof = 0; idof < n_dofs_ext; ++idof) { -// soln_coeff_ext_ad[idof] = DGBase::solution(soln_dof_indices_ext[idof]); -// soln_coeff_ext_ad[idof].diff(idof+n_dofs_int, n_total_indep); -// } -// for (unsigned int iquad=0; iquad normal_int = normals_int[iquad]; -// const dealii::Tensor<1,dim,FadType> normal_ext = -normal_int; -// -// // Interpolate solution to face -// for (unsigned int idof=0; idof1) std::cout << "Momentum int" << soln_int[iquad][1] << std::endl; -// //std::cout << "Energy int" << soln_int[iquad][nstate-1] << std::endl; -// //std::cout << "Density ext" << soln_ext[iquad][0] << std::endl; -// //if(nstate>1) std::cout << "Momentum ext" << soln_ext[iquad][1] << std::endl; -// //std::cout << "Energy ext" << soln_ext[iquad][nstate-1] << std::endl; -// -// // Evaluate physical convective flux, physical dissipative flux, and source term -// conv_num_flux_dot_n[iquad] = DGBaseState::conv_num_flux_fad->evaluate_flux(soln_int[iquad], soln_ext[iquad], normal_int); -// -// conv_phys_flux_int[iquad] = this->pde_physics_fad->convective_flux (soln_int[iquad]); -// conv_phys_flux_ext[iquad] = this->pde_physics_fad->convective_flux (soln_ext[iquad]); -// -// diss_soln_num_flux[iquad] = DGBaseState::diss_num_flux_fad->evaluate_solution_flux(soln_int[iquad], soln_ext[iquad], normal_int); -// -// ADArrayTensor1 diss_soln_jump_int, diss_soln_jump_ext; -// for (int s=0; spde_physics_fad->dissipative_flux (soln_int[iquad], diss_soln_jump_int, current_cell_index); -// diss_flux_jump_ext[iquad] = this->pde_physics_fad->dissipative_flux (soln_ext[iquad], diss_soln_jump_ext, neighbor_cell_index); -// -// diss_auxi_num_flux_dot_n[iquad] = DGBaseState::diss_num_flux_fad->evaluate_auxiliary_flux( -// current_cell_index, neighbor_cell_index, -// 0.0, 0.0, -// soln_int[iquad], soln_ext[iquad], -// soln_grad_int[iquad], soln_grad_ext[iquad], -// normal_int, penalty); -// } -// -// // From test functions associated with interior cell point of view -// for (unsigned int itest_int=0; itest_intall_parameters->ode_solver_param.ode_solver_type == Parameters::ODESolverParam::ODESolverEnum::implicit_solver) { -// for (unsigned int idof = 0; idof < n_dofs_int; ++idof) { -// dR1_dW1[idof] = rhs.fastAccessDx(idof); -// } -// for (unsigned int idof = 0; idof < n_dofs_ext; ++idof) { -// dR1_dW2[idof] = rhs.fastAccessDx(n_dofs_int+idof); -// } -// this->system_matrix.add(soln_dof_indices_int[itest_int], soln_dof_indices_int, dR1_dW1); -// this->system_matrix.add(soln_dof_indices_int[itest_int], soln_dof_indices_ext, dR1_dW2); -// } -// } -// -// // From test functions associated with neighbour cell point of view -// for (unsigned int itest_ext=0; itest_extall_parameters->ode_solver_param.ode_solver_type == Parameters::ODESolverParam::ODESolverEnum::implicit_solver) { -// for (unsigned int idof = 0; idof < n_dofs_int; ++idof) { -// dR2_dW1[idof] = rhs.fastAccessDx(idof); -// } -// for (unsigned int idof = 0; idof < n_dofs_ext; ++idof) { -// dR2_dW2[idof] = rhs.fastAccessDx(n_dofs_int+idof); -// } -// this->system_matrix.add(soln_dof_indices_ext[itest_ext], soln_dof_indices_int, dR2_dW1); -// this->system_matrix.add(soln_dof_indices_ext[itest_ext], soln_dof_indices_ext, dR2_dW2); -// } -// } -} - /******************************************************* * * EXPLICIT @@ -3133,9 +2659,11 @@ void DGStrong::assemble_volume_term_explicit( template -void DGStrong::allocate_dual_vector() +void DGStrong::allocate_dual_vector(const bool compute_d2R) { - //Do nothing. + if(compute_d2R){ + this->dual.reinit(this->locally_owned_dofs, this->ghost_dofs, this->mpi_communicator); + } } // using default MeshType = Triangulation diff --git a/src/dg/strong_dg.hpp b/src/dg/strong_dg.hpp index 35c295555..7ee4ea0c1 100644 --- a/src/dg/strong_dg.hpp +++ b/src/dg/strong_dg.hpp @@ -33,10 +33,10 @@ class DGStrong: public DGBaseState * Quaegebeur, Nadarajah, Navah and Zwanenburg 2019: Stability of Energy Stable Flux * Reconstruction for the Diffusion Problem Using Compact Numerical Fluxes */ - void assemble_auxiliary_residual (); + void assemble_auxiliary_residual (const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); /// Allocate the dual vector for optimization. - void allocate_dual_vector (); + void allocate_dual_vector (const bool compute_d2R); private: /// Assembles the auxiliary equations' cell residuals. @@ -48,133 +48,729 @@ class DGStrong: public DGBaseState protected: /// Builds the necessary operators and assembles volume residual for either primary or auxiliary. - void assemble_volume_term_and_build_operators( + template + void assemble_volume_term_and_build_operators_ad_templated( typename dealii::DoFHandler::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, - const std::vector &cell_dofs_indices, - const std::vector &metric_dof_indices, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const std::vector &soln_dofs_indices, + const std::vector &metric_dofs_indices, const unsigned int poly_degree, const unsigned int grid_degree, - OPERATOR::basis_functions &soln_basis, - OPERATOR::basis_functions &flux_basis, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::metric_operators &metric_oper, - OPERATOR::mapping_shape_functions &mapping_basis, - std::array,dim> &mapping_support_points, + const Physics::PhysicsBase &physics, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, dealii::hp::FEValues &/*fe_values_collection_volume*/, dealii::hp::FEValues &/*fe_values_collection_volume_lagrange*/, - const dealii::FESystem &/*current_fe_ref*/, - dealii::Vector &local_rhs_int_cell, - std::vector> &local_auxiliary_RHS, + const dealii::FESystem &/*fe_soln*/, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, const bool compute_auxiliary_right_hand_side, - const bool /*compute_dRdW*/, const bool /*compute_dRdX*/, const bool /*compute_d2R*/); - - /// Builds the necessary operators and assembles boundary residual for either primary or auxiliary. - void assemble_boundary_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator /*cell*/, + adtype &dual_dot_residual); + + void assemble_volume_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, - const unsigned int iface, - const unsigned int boundary_id, - const real penalty, - const std::vector &cell_dofs_indices, - const std::vector &metric_dof_indices, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const std::vector &soln_dofs_indices, + const std::vector &metric_dofs_indices, const unsigned int poly_degree, const unsigned int grid_degree, - OPERATOR::basis_functions &soln_basis, - OPERATOR::basis_functions &flux_basis, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::metric_operators &metric_oper, - OPERATOR::mapping_shape_functions &mapping_basis, - std::array,dim> &mapping_support_points, - dealii::hp::FEFaceValues &/*fe_values_collection_face_int*/, - const dealii::FESystem &/*current_fe_ref*/, - dealii::Vector &local_rhs_int_cell, - std::vector> &local_auxiliary_RHS, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + const dealii::FESystem &fe_soln, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, const bool compute_auxiliary_right_hand_side, - const bool /*compute_dRdW*/, const bool /*compute_dRdX*/, const bool /*compute_d2R*/); + double &dual_dot_residual) override + { + assemble_volume_term_and_build_operators_ad_templated( + cell, + current_cell_index, + soln_coeffs, + aux_soln_coeffs, + metric_coeffs, + local_dual, + soln_dofs_indices, + metric_dofs_indices, + poly_degree, + grid_degree, + *(DGBaseState::pde_physics_double), + soln_basis, + flux_basis, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + metric_oper, + mapping_basis, + mapping_support_points, + fe_values_collection_volume, + fe_values_collection_volume_lagrange, + fe_soln, + rhs, + local_auxiliary_RHS, + compute_auxiliary_right_hand_side, + dual_dot_residual); + } + + void assemble_volume_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const std::vector &soln_dofs_indices, + const std::vector &metric_dofs_indices, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + const dealii::FESystem &fe_soln, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + codi_JacobianComputationType &dual_dot_residual) override + { + assemble_volume_term_and_build_operators_ad_templated( + cell, + current_cell_index, + soln_coeffs, + aux_soln_coeffs, + metric_coeffs, + local_dual, + soln_dofs_indices, + metric_dofs_indices, + poly_degree, + grid_degree, + *(DGBaseState::pde_physics_rad), + soln_basis, + flux_basis, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + metric_oper, + mapping_basis, + mapping_support_points, + fe_values_collection_volume, + fe_values_collection_volume_lagrange, + fe_soln, + rhs, + local_auxiliary_RHS, + compute_auxiliary_right_hand_side, + dual_dot_residual); + } + + void assemble_volume_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const std::vector &soln_dofs_indices, + const std::vector &metric_dofs_indices, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + const dealii::FESystem &fe_soln, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + codi_HessianComputationType &dual_dot_residual) override + { + assemble_volume_term_and_build_operators_ad_templated( + cell, + current_cell_index, + soln_coeffs, + aux_soln_coeffs, + metric_coeffs, + local_dual, + soln_dofs_indices, + metric_dofs_indices, + poly_degree, + grid_degree, + *(DGBaseState::pde_physics_rad_fad), + soln_basis, + flux_basis, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + metric_oper, + mapping_basis, + mapping_support_points, + fe_values_collection_volume, + fe_values_collection_volume_lagrange, + fe_soln, + rhs, + local_auxiliary_RHS, + compute_auxiliary_right_hand_side, + dual_dot_residual); + } - /// Builds the necessary operators and assembles face residual. - void assemble_face_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator /*cell*/, - typename dealii::DoFHandler::active_cell_iterator /*neighbor_cell*/, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const unsigned int iface, - const unsigned int neighbor_iface, - const real penalty, - const std::vector ¤t_dofs_indices, - const std::vector &neighbor_dofs_indices, - const std::vector ¤t_metric_dofs_indices, - const std::vector &neighbor_metric_dofs_indices, - const unsigned int poly_degree_int, - const unsigned int poly_degree_ext, - const unsigned int grid_degree_int, - const unsigned int grid_degree_ext, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::metric_operators &metric_oper_int, - OPERATOR::metric_operators &metric_oper_ext, - OPERATOR::mapping_shape_functions &mapping_basis, - std::array,dim> &mapping_support_points, - dealii::hp::FEFaceValues &/*fe_values_collection_face_int*/, - dealii::hp::FEFaceValues &/*fe_values_collection_face_ext*/, - dealii::Vector ¤t_cell_rhs, - dealii::Vector &neighbor_cell_rhs, - std::vector> ¤t_cell_rhs_aux, - dealii::LinearAlgebra::distributed::Vector &rhs, - std::array,dim> &rhs_aux, - const bool compute_auxiliary_right_hand_side, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); + /// Builds the necessary operators and assembles boundary residual for either primary or auxiliary. + template + void assemble_boundary_term_and_build_operators_ad_templated( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const unsigned int face_number, + const unsigned int boundary_id, + const Physics::PhysicsBase &physics, + const NumericalFlux::NumericalFluxConvective &conv_num_flux, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &/*fe_values_collection_face_int*/, + const dealii::FESystem &/*fe_soln*/, + const real penalty, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + adtype &dual_dot_residual); + + void assemble_boundary_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const unsigned int face_number, + const unsigned int boundary_id, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + const dealii::FESystem &fe_soln, + const real penalty, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + double &dual_dot_residual) override + { + assemble_boundary_term_and_build_operators_ad_templated( + cell, + current_cell_index, + soln_coeffs, + aux_soln_coeffs, + metric_coeffs, + local_dual, + face_number, + boundary_id, + *(DGBaseState::pde_physics_double), + *(DGBaseState::conv_num_flux_double), + *(DGBaseState::diss_num_flux_double), + poly_degree, + grid_degree, + soln_basis, + flux_basis, + soln_basis_projection_oper_int, + metric_oper, + mapping_basis, + mapping_support_points, + fe_values_collection_face_int, + fe_soln, + penalty, + rhs, + local_auxiliary_RHS, + compute_auxiliary_right_hand_side, + dual_dot_residual); + } + + void assemble_boundary_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const unsigned int face_number, + const unsigned int boundary_id, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + const dealii::FESystem &fe_soln, + const real penalty, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + codi_JacobianComputationType &dual_dot_residual) override + { + assemble_boundary_term_and_build_operators_ad_templated( + cell, + current_cell_index, + soln_coeffs, + aux_soln_coeffs, + metric_coeffs, + local_dual, + face_number, + boundary_id, + *(DGBaseState::pde_physics_rad), + *(DGBaseState::conv_num_flux_rad), + *(DGBaseState::diss_num_flux_rad), + poly_degree, + grid_degree, + soln_basis, + flux_basis, + soln_basis_projection_oper_int, + metric_oper, + mapping_basis, + mapping_support_points, + fe_values_collection_face_int, + fe_soln, + penalty, + rhs, + local_auxiliary_RHS, + compute_auxiliary_right_hand_side, + dual_dot_residual); + } + + void assemble_boundary_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const unsigned int face_number, + const unsigned int boundary_id, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + const dealii::FESystem &fe_soln, + const real penalty, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + codi_HessianComputationType &dual_dot_residual) override + { + assemble_boundary_term_and_build_operators_ad_templated( + cell, + current_cell_index, + soln_coeffs, + aux_soln_coeffs, + metric_coeffs, + local_dual, + face_number, + boundary_id, + *(DGBaseState::pde_physics_rad_fad), + *(DGBaseState::conv_num_flux_rad_fad), + *(DGBaseState::diss_num_flux_rad_fad), + poly_degree, + grid_degree, + soln_basis, + flux_basis, + soln_basis_projection_oper_int, + metric_oper, + mapping_basis, + mapping_support_points, + fe_values_collection_face_int, + fe_soln, + penalty, + rhs, + local_auxiliary_RHS, + compute_auxiliary_right_hand_side, + dual_dot_residual); + } + + template + void assemble_face_term_and_build_operators_ad_templated( + typename dealii::DoFHandler::active_cell_iterator cell, + typename dealii::DoFHandler::active_cell_iterator neighbor_cell, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const std::vector &soln_coeffs_int, + const std::vector &soln_coeffs_ext, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs_int, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs_ext, + const std::vector &metric_coeff_int, + const std::vector &metric_coeff_ext, + const std::vector< double > &dual_int, + const std::vector< double > &dual_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const unsigned int grid_degree_int, + const unsigned int grid_degree_ext, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + const Physics::PhysicsBase &physics, + const NumericalFlux::NumericalFluxConvective &conv_num_flux, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + dealii::hp::FEFaceValues &/*fe_values_collection_face_int*/, + dealii::hp::FEFaceValues &/*fe_values_collection_face_ext*/, + dealii::hp::FESubfaceValues &/*fe_values_collection_subface*/, + const dealii::FESystem &/*fe_int*/, + const dealii::FESystem &/*fe_ext*/, + const real penalty, + std::vector &rhs_int, + std::vector &rhs_ext, + dealii::Tensor<1,dim,std::vector> &aux_rhs_int, + dealii::Tensor<1,dim,std::vector> &aux_rhs_ext, + const bool compute_auxiliary_right_hand_side, + adtype &dual_dot_residual, + const bool /*is_a_subface*/, + const unsigned int /*neighbor_i_subface*/); + + void assemble_face_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + typename dealii::DoFHandler::active_cell_iterator neighbor_cell, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const std::vector &soln_coeff_int, + const std::vector &soln_coeff_ext, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_int, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_ext, + const std::vector &metric_coeff_int, + const std::vector &metric_coeff_ext, + const std::vector< double > &dual_int, + const std::vector< double > &dual_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const unsigned int grid_degree_int, + const unsigned int grid_degree_ext, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + const dealii::FESystem &fe_int, + const dealii::FESystem &fe_ext, + const real penalty, + std::vector &rhs_int, + std::vector &rhs_ext, + dealii::Tensor<1,dim,std::vector> &aux_rhs_int, + dealii::Tensor<1,dim,std::vector> &aux_rhs_ext, + const bool compute_auxiliary_right_hand_side, + double &dual_dot_residual, + const bool /*compute_dRdW*/, const bool /*compute_dRdX*/, const bool /*compute_d2R*/, + const bool is_a_subface, + const unsigned int neighbor_i_subface) override + { + assemble_face_term_and_build_operators_ad_templated( + cell, + neighbor_cell, + current_cell_index, + neighbor_cell_index, + iface, + neighbor_iface, + soln_coeff_int, + soln_coeff_ext, + aux_soln_coeff_int, + aux_soln_coeff_ext, + metric_coeff_int, + metric_coeff_ext, + dual_int, + dual_ext, + poly_degree_int, + poly_degree_ext, + grid_degree_int, + grid_degree_ext, + soln_basis_int, + soln_basis_ext, + flux_basis_int, + flux_basis_ext, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + metric_oper_int, + metric_oper_ext, + mapping_basis, + mapping_support_points, + *(DGBaseState::pde_physics_double), + *(DGBaseState::conv_num_flux_double), + *(DGBaseState::diss_num_flux_double), + fe_values_collection_face_int, + fe_values_collection_face_ext, + fe_values_collection_subface, + fe_int, + fe_ext, + penalty, + rhs_int, + rhs_ext, + aux_rhs_int, + aux_rhs_ext, + compute_auxiliary_right_hand_side, + dual_dot_residual, + is_a_subface, + neighbor_i_subface); + } - /// Builds the necessary operators and assembles subface residual. - /** Not verified - */ - void assemble_subface_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator cell, - typename dealii::DoFHandler::active_cell_iterator neighbor_cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const unsigned int iface, - const unsigned int neighbor_iface, - const unsigned int /*neighbor_i_subface*/, - const real penalty, - const std::vector ¤t_dofs_indices, - const std::vector &neighbor_dofs_indices, - const std::vector ¤t_metric_dofs_indices, - const std::vector &neighbor_metric_dofs_indices, - const unsigned int poly_degree_int, - const unsigned int poly_degree_ext, - const unsigned int grid_degree_int, - const unsigned int grid_degree_ext, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::metric_operators &metric_oper_int, - OPERATOR::metric_operators &metric_oper_ext, - OPERATOR::mapping_shape_functions &mapping_basis, - std::array,dim> &mapping_support_points, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - dealii::hp::FESubfaceValues &/*fe_values_collection_subface*/, - dealii::Vector ¤t_cell_rhs, - dealii::Vector &neighbor_cell_rhs, - std::vector> ¤t_cell_rhs_aux, - dealii::LinearAlgebra::distributed::Vector &rhs, - std::array,dim> &rhs_aux, - const bool compute_auxiliary_right_hand_side, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); + + void assemble_face_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + typename dealii::DoFHandler::active_cell_iterator neighbor_cell, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const std::vector &soln_coeff_int, + const std::vector &soln_coeff_ext, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_int, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_ext, + const std::vector &metric_coeff_int, + const std::vector &metric_coeff_ext, + const std::vector< double > &dual_int, + const std::vector< double > &dual_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const unsigned int grid_degree_int, + const unsigned int grid_degree_ext, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + const dealii::FESystem &fe_int, + const dealii::FESystem &fe_ext, + const real penalty, + std::vector &rhs_int, + std::vector &rhs_ext, + dealii::Tensor<1,dim,std::vector> &aux_rhs_int, + dealii::Tensor<1,dim,std::vector> &aux_rhs_ext, + const bool compute_auxiliary_right_hand_side, + codi_JacobianComputationType &dual_dot_residual, + const bool /*compute_dRdW*/, const bool /*compute_dRdX*/, const bool /*compute_d2R*/, + const bool is_a_subface, + const unsigned int neighbor_i_subface) override + { + assemble_face_term_and_build_operators_ad_templated( + cell, + neighbor_cell, + current_cell_index, + neighbor_cell_index, + iface, + neighbor_iface, + soln_coeff_int, + soln_coeff_ext, + aux_soln_coeff_int, + aux_soln_coeff_ext, + metric_coeff_int, + metric_coeff_ext, + dual_int, + dual_ext, + poly_degree_int, + poly_degree_ext, + grid_degree_int, + grid_degree_ext, + soln_basis_int, + soln_basis_ext, + flux_basis_int, + flux_basis_ext, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + metric_oper_int, + metric_oper_ext, + mapping_basis, + mapping_support_points, + *(DGBaseState::pde_physics_rad), + *(DGBaseState::conv_num_flux_rad), + *(DGBaseState::diss_num_flux_rad), + fe_values_collection_face_int, + fe_values_collection_face_ext, + fe_values_collection_subface, + fe_int, + fe_ext, + penalty, + rhs_int, + rhs_ext, + aux_rhs_int, + aux_rhs_ext, + compute_auxiliary_right_hand_side, + dual_dot_residual, + is_a_subface, + neighbor_i_subface); + } + + void assemble_face_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + typename dealii::DoFHandler::active_cell_iterator neighbor_cell, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const std::vector &soln_coeff_int, + const std::vector &soln_coeff_ext, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_int, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_ext, + const std::vector &metric_coeff_int, + const std::vector &metric_coeff_ext, + const std::vector< double > &dual_int, + const std::vector< double > &dual_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const unsigned int grid_degree_int, + const unsigned int grid_degree_ext, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + const dealii::FESystem &fe_int, + const dealii::FESystem &fe_ext, + const real penalty, + std::vector &rhs_int, + std::vector &rhs_ext, + dealii::Tensor<1,dim,std::vector> &aux_rhs_int, + dealii::Tensor<1,dim,std::vector> &aux_rhs_ext, + const bool compute_auxiliary_right_hand_side, + codi_HessianComputationType &dual_dot_residual, + const bool /*compute_dRdW*/, const bool /*compute_dRdX*/, const bool /*compute_d2R*/, + const bool is_a_subface, + const unsigned int neighbor_i_subface) override + { + assemble_face_term_and_build_operators_ad_templated( + cell, + neighbor_cell, + current_cell_index, + neighbor_cell_index, + iface, + neighbor_iface, + soln_coeff_int, + soln_coeff_ext, + aux_soln_coeff_int, + aux_soln_coeff_ext, + metric_coeff_int, + metric_coeff_ext, + dual_int, + dual_ext, + poly_degree_int, + poly_degree_ext, + grid_degree_int, + grid_degree_ext, + soln_basis_int, + soln_basis_ext, + flux_basis_int, + flux_basis_ext, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + metric_oper_int, + metric_oper_ext, + mapping_basis, + mapping_support_points, + *(DGBaseState::pde_physics_rad_fad), + *(DGBaseState::conv_num_flux_rad_fad), + *(DGBaseState::diss_num_flux_rad_fad), + fe_values_collection_face_int, + fe_values_collection_face_ext, + fe_values_collection_subface, + fe_int, + fe_ext, + penalty, + rhs_int, + rhs_ext, + aux_rhs_int, + aux_rhs_ext, + compute_auxiliary_right_hand_side, + dual_dot_residual, + is_a_subface, + neighbor_i_subface); + } public: ///Evaluate the volume RHS for the auxiliary equation. @@ -182,25 +778,29 @@ class DGStrong: public DGBaseState * \int_{\mathbf{\Omega}_r} \chi_i(\mathbf{\xi}^r) \left( \nabla^r(u) \right)\mathbf{C}_m(\mathbf{\xi}^r) d\mathbf{\Omega}_r,\:\forall i=1,\dots,N_p. * \f] */ + template void assemble_volume_term_auxiliary_equation( - const std::vector ¤t_dofs_indices, - const unsigned int poly_degree, - OPERATOR::basis_functions &soln_basis, - OPERATOR::basis_functions &flux_basis, - OPERATOR::metric_operators &metric_oper, - std::vector> &local_auxiliary_RHS); + const std::array,nstate> &soln_coeff, + const unsigned int poly_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::metric_operators &metric_oper, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS); protected: /// Evaluate the boundary RHS for the auxiliary equation. + template void assemble_boundary_term_auxiliary_equation( const unsigned int iface, const dealii::types::global_dof_index current_cell_index, + const std::array,nstate> &soln_coeff, const unsigned int poly_degree, const unsigned int boundary_id, - const std::vector &dofs_indices, - OPERATOR::basis_functions &soln_basis, - OPERATOR::metric_operators &metric_oper, - std::vector> &local_auxiliary_RHS); + OPERATOR::basis_functions &soln_basis, + OPERATOR::metric_operators &metric_oper, + const Physics::PhysicsBase &pde_physics, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS); public: /// Evaluate the facet RHS for the auxiliary equation. @@ -209,20 +809,23 @@ class DGStrong: public DGBaseState * - u\right]d\mathbf{\Gamma}_r,\:\forall i=1,\dots,N_p. * \f] */ + template void assemble_face_term_auxiliary_equation( const unsigned int iface, const unsigned int neighbor_iface, const dealii::types::global_dof_index current_cell_index, const dealii::types::global_dof_index neighbor_cell_index, + const std::array,nstate> &soln_coeff_int, + const std::array,nstate> &soln_coeff_ext, const unsigned int poly_degree_int, const unsigned int poly_degree_ext, - const std::vector &dof_indices_int, - const std::vector &dof_indices_ext, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::metric_operators &metric_oper_int, - std::vector> &local_auxiliary_RHS_int, - std::vector> &local_auxiliary_RHS_ext); + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::metric_operators &metric_oper_int, + const Physics::PhysicsBase &pde_physics, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS_int, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS_ext); protected: /// Strong form primary equation's volume right-hand-side. @@ -243,31 +846,39 @@ class DGStrong: public DGBaseState * where \f$ (\mathbf{F})_{ij} = 0.5\left( \mathbf{C}_m(\mathbf{\xi}_i^r)+\mathbf{C}_m(\mathbf{\xi}_j^r) \right) \cdot \mathbf{f}_s(\mathbf{u}(\mathbf{\xi}_i^r),\mathbf{u}(\mathbf{\xi}_j^r)) \f$; that is, the * matrix of REFERENCE two-point entropy conserving fluxes. */ + template void assemble_volume_term_strong( typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const std::vector &cell_dofs_indices, - const unsigned int poly_degree, - OPERATOR::basis_functions &soln_basis, - OPERATOR::basis_functions &flux_basis, - OPERATOR::local_basis_stiffness &flux_basis_stiffness, - OPERATOR::vol_projection_operator &soln_basis_projection_oper, - OPERATOR::metric_operators &metric_oper, - dealii::Vector &local_rhs_int_cell); + const dealii::types::global_dof_index current_cell_index, + const std::array,nstate> &soln_coeff, + const std::array>,nstate> &aux_soln_coeff, + const unsigned int poly_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper, + OPERATOR::metric_operators &metric_oper, + const Physics::PhysicsBase &pde_physics, + std::vector &local_rhs_int_cell); /// Strong form primary equation's boundary right-hand-side. + template void assemble_boundary_term_strong( - const unsigned int iface, - const dealii::types::global_dof_index current_cell_index, - const unsigned int boundary_id, - const unsigned int poly_degree, - const real penalty, - const std::vector &dof_indices, - OPERATOR::basis_functions &soln_basis, - OPERATOR::basis_functions &flux_basis, - OPERATOR::vol_projection_operator &soln_basis_projection_oper, - OPERATOR::metric_operators &metric_oper, - dealii::Vector &local_rhs_cell); + const unsigned int iface, + const dealii::types::global_dof_index current_cell_index, + const std::array,nstate> &soln_coeff, + const std::array>,nstate> &aux_soln_coeff, + const unsigned int boundary_id, + const unsigned int poly_degree, + const real penalty, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper, + OPERATOR::metric_operators &metric_oper, + const Physics::PhysicsBase &pde_physics, + const NumericalFlux::NumericalFluxConvective &conv_num_flux, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + std::vector &local_rhs_cell); /// Strong form primary equation's facet right-hand-side. /** @@ -278,83 +889,34 @@ class DGStrong: public DGBaseState * ,\:\forall i=1,\dots,N_p. * \f] */ + template void assemble_face_term_strong( - const unsigned int iface, - const unsigned int neighbor_iface, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const unsigned int poly_degree_int, - const unsigned int poly_degree_ext, - const real penalty, - const std::vector &dof_indices_int, - const std::vector &dof_indices_ext, - OPERATOR::basis_functions &soln_basis_int, - OPERATOR::basis_functions &soln_basis_ext, - OPERATOR::basis_functions &flux_basis_int, - OPERATOR::basis_functions &flux_basis_ext, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, - OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, - OPERATOR::metric_operators &metric_oper_int, - OPERATOR::metric_operators &metric_oper_ext, - dealii::Vector &local_rhs_int_cell, - dealii::Vector &local_rhs_ext_cell); + const unsigned int iface, + const unsigned int neighbor_iface, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const std::array,nstate> &soln_coeff_int, + const std::array,nstate> &soln_coeff_ext, + const std::array>,nstate> &aux_soln_coeff_int, + const std::array>,nstate> &aux_soln_coeff_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const real penalty, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + const Physics::PhysicsBase &pde_physics, + const NumericalFlux::NumericalFluxConvective &conv_num_flux, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + std::vector &local_rhs_int_cell, + std::vector &local_rhs_ext_cell); protected: - /// Evaluate the integral over the cell volume and the specified derivatives. - /** Compute both the right-hand side and the corresponding block of dRdW, dRdX, and/or d2R. */ - void assemble_volume_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::FEValues &,//fe_values_vol, - const dealii::FESystem &fe, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - dealii::Vector &local_rhs_cell, - const dealii::FEValues &/*fe_values_lagrange*/, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - - /// Assemble boundary term derivatives - void assemble_boundary_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const unsigned int face_number, - const unsigned int boundary_id, - const dealii::FEFaceValuesBase &fe_values_boundary, - const real penalty, - const dealii::FESystem &fe, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - dealii::Vector &local_rhs_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - - /// Evaluate the integral over the internal cell edges and its specified derivatives. - /** Compute both the right-hand side and the block of the Jacobian. - * This adds the contribution to both cell's residual and effectively - * computes 4 block contributions to dRdX blocks. */ - void assemble_face_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const std::pair face_subface_int, - const std::pair face_subface_ext, - const typename dealii::QProjector::DataSetDescriptor face_data_set_int, - const typename dealii::QProjector::DataSetDescriptor face_data_set_ext, - const dealii::FEFaceValuesBase &,//fe_values_int, - const dealii::FEFaceValuesBase &,//fe_values_ext, - const real penalty, - const dealii::FESystem &fe_int, - const dealii::FESystem &fe_ext, - const dealii::Quadrature &face_quadrature, - const std::vector &metric_dof_indices_int, - const std::vector &metric_dof_indices_ext, - const std::vector &soln_dof_indices_int, - const std::vector &soln_dof_indices_ext, - dealii::Vector &local_rhs_int_cell, - dealii::Vector &local_rhs_ext_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - /// Evaluate the integral over the cell volume void assemble_volume_term_explicit( typename dealii::DoFHandler::active_cell_iterator cell, @@ -367,8 +929,50 @@ class DGStrong: public DGBaseState dealii::Vector ¤t_cell_rhs, const dealii::FEValues &fe_values_lagrange); + using DGBase::pcout; ///< Parallel std::cout that only outputs on mpi_rank==0 + +public: + /// Builds volume metric operators (metric cofactor and determinant of metric Jacobian). + template + void build_volume_metric_operators( + const unsigned int poly_degree, + const unsigned int grid_degree, + const std::vector &metric_coeffs, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points); + void build_volume_metric_operators( + const unsigned int poly_degree, + const unsigned int grid_degree, + const std::vector &metric_coeffs, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points) + { + build_volume_metric_operators(poly_degree, grid_degree, metric_coeffs, metric_oper, mapping_basis, mapping_support_points); + } + void build_volume_metric_operators( + const unsigned int poly_degree, + const unsigned int grid_degree, + const std::vector &metric_coeffs, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points) + { + build_volume_metric_operators(poly_degree, grid_degree, metric_coeffs, metric_oper, mapping_basis, mapping_support_points); + } + void build_volume_metric_operators( + const unsigned int poly_degree, + const unsigned int grid_degree, + const std::vector &metric_coeffs, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points) + { + build_volume_metric_operators(poly_degree, grid_degree, metric_coeffs, metric_oper, mapping_basis, mapping_support_points); + } }; // end of DGStrong class diff --git a/src/dg/weak_dg.cpp b/src/dg/weak_dg.cpp index d60c4c9c1..ba20ac915 100644 --- a/src/dg/weak_dg.cpp +++ b/src/dg/weak_dg.cpp @@ -21,7 +21,6 @@ #define KOPRIVA_METRICS_VOL #define KOPRIVA_METRICS_FACE #define KOPRIVA_METRICS_BOUNDARY -//#define FADFAD namespace { template using Coord = std::array; @@ -143,87 +142,6 @@ real1 norm(const dealii::Tensor<1, dim, real1> x) { return sqrt(val); } -/// Derivative indexing when only 1 cell is concerned. -/// Derivatives are ordered such that w comes first with index 0, then x. -/// If derivatives with respect to w are not needed, then derivatives -/// with respect to x will start at index 0. This function is for a single -/// cell's DoFs. -void automatic_differentiation_indexing_1( - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, - const unsigned int n_soln_dofs, const unsigned int n_metric_dofs, - unsigned int &w_start, unsigned int &w_end, - unsigned int &x_start, unsigned int &x_end) -{ - w_start = 0; - w_end = 0; - x_start = 0; - x_end = 0; - if (compute_d2R || (compute_dRdW && compute_dRdX)) { - w_start = 0; - w_end = w_start + n_soln_dofs; - x_start = w_end; - x_end = x_start + n_metric_dofs; - } else if (compute_dRdW) { - w_start = 0; - w_end = w_start + n_soln_dofs; - x_start = w_end; - x_end = x_start + 0; - } else if (compute_dRdX) { - w_start = 0; - w_end = w_start + 0; - x_start = w_end; - x_end = x_start + n_metric_dofs; - } else { - std::cout << "Called the derivative version of the residual without requesting the derivative" << std::endl; - } -} - -/// Derivative indexing when 2 cells are concerned. -/// Derivatives are ordered such that w comes first with index 0, then x. -/// If derivatives with respect to w are not needed, then derivatives -/// with respect to x will start at index 0. This function is for a single -/// cell's DoFs. -void automatic_differentiation_indexing_2( - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, - const unsigned int n_soln_dofs_int, const unsigned int n_soln_dofs_ext, const unsigned int n_metric_dofs, - unsigned int &w_int_start, unsigned int &w_int_end, unsigned int &w_ext_start, unsigned int &w_ext_end, - unsigned int &x_int_start, unsigned int &x_int_end, unsigned int &x_ext_start, unsigned int &x_ext_end) -{ - // Current derivative order is: soln_int, soln_ext, metric_int, metric_ext - w_int_start = 0; w_int_end = 0; w_ext_start = 0; w_ext_end = 0; - x_int_start = 0; x_int_end = 0; x_ext_start = 0; x_ext_end = 0; - if (compute_d2R || (compute_dRdW && compute_dRdX)) { - w_int_start = 0; - w_int_end = w_int_start + n_soln_dofs_int; - w_ext_start = w_int_end; - w_ext_end = w_ext_start + n_soln_dofs_ext; - x_int_start = w_ext_end; - x_int_end = x_int_start + n_metric_dofs; - x_ext_start = x_int_end; - x_ext_end = x_ext_start + n_metric_dofs; - } else if (compute_dRdW) { - w_int_start = 0; - w_int_end = w_int_start + n_soln_dofs_int; - w_ext_start = w_int_end; - w_ext_end = w_ext_start + n_soln_dofs_ext; - x_int_start = w_ext_end; - x_int_end = x_int_start + 0; - x_ext_start = x_int_end; - x_ext_end = x_ext_start + 0; - } else if (compute_dRdX) { - w_int_start = 0; - w_int_end = w_int_start + 0; - w_ext_start = w_int_end; - w_ext_end = w_ext_start + 0; - x_int_start = w_ext_end; - x_int_end = x_int_start + n_metric_dofs; - x_ext_start = x_int_end; - x_ext_end = x_ext_start + n_metric_dofs; - } else { - std::cout << "Called the derivative version of the residual without requesting the derivative" << std::endl; - } -} - template bool check_same_coords ( const std::vector> &unit_quad_pts_int, @@ -979,1831 +897,516 @@ void DGWeak::assemble_boundary_term( } } -#ifdef FADFAD + +template +dealii::Quadrature project_face_quadrature( + const dealii::Quadrature &face_quadrature_lower_dim, const std::pair face_subface_pair, + const typename dealii::QProjector::DataSetDescriptor face_data_set) { + dealii::Quadrature face_quadrature; + + if constexpr (dim == 3) { + const dealii::Quadrature all_faces_quad = + face_subface_pair.second == -1 ? dealii::QProjector::project_to_all_faces( + dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim) + : dealii::QProjector::project_to_all_subfaces( + dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim); + const unsigned int n_face_quad_pts = face_quadrature_lower_dim.size(); + std::vector> points(n_face_quad_pts); + std::vector weights(n_face_quad_pts); + for (unsigned int iquad = 0; iquad < n_face_quad_pts; ++iquad) { + points[iquad] = all_faces_quad.point(iquad + face_data_set); + weights[iquad] = all_faces_quad.weight(iquad + face_data_set); + } + face_quadrature = dealii::Quadrature(points, weights); + + } else { + (void) face_data_set; + if (face_subface_pair.second == -1) { + face_quadrature = dealii::QProjector::project_to_face( + dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim, face_subface_pair.first); + } else { + face_quadrature = dealii::QProjector::project_to_subface( + dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim, face_subface_pair.first, + face_subface_pair.second, dealii::RefinementCase::isotropic_refinement); + } + } + return face_quadrature; +} + template -void DGWeak::assemble_boundary_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator /*cell*/, +template +void DGWeak::assemble_face_term( + typename dealii::DoFHandler::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, - const unsigned int face_number, - const unsigned int boundary_id, - const dealii::FEFaceValuesBase &fe_values_boundary, + const dealii::types::global_dof_index neighbor_cell_index, + const LocalSolution &soln_int, + const LocalSolution &soln_ext, + const LocalSolution &metric_int, + const LocalSolution &metric_ext, + const std::vector< double > &dual_int, + const std::vector< double > &dual_ext, + const std::pair face_subface_int, + const std::pair face_subface_ext, + const typename dealii::QProjector::DataSetDescriptor face_data_set_int, + const typename dealii::QProjector::DataSetDescriptor face_data_set_ext, + const Physics::PhysicsBase &physics, + const NumericalFlux::NumericalFluxConvective &conv_num_flux, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + const dealii::FEFaceValuesBase &fe_values_int, + const dealii::FEFaceValuesBase &fe_values_ext, const real penalty, - const dealii::FESystem &fe_soln, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - dealii::Vector &local_rhs_cell, + const dealii::Quadrature &face_quadrature, + std::vector &rhs_int, + std::vector &rhs_ext, + real2 &dual_dot_residual, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) { - (void) current_cell_index; - using adtype = FadFadType; - - const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; - const unsigned int n_soln_dofs = fe_values_boundary.dofs_per_cell; - const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; - - (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R; - const bool compute_metric_derivatives = true;//(!compute_dRdX && !compute_d2R) ? false : true; - AssertDimension (n_soln_dofs, soln_dof_indices.size()); + (void) compute_dRdW; + const unsigned int n_soln_dofs_int = soln_int.finite_element.dofs_per_cell; + const unsigned int n_soln_dofs_ext = soln_ext.finite_element.dofs_per_cell; + const unsigned int n_face_quad_pts = face_quadrature.size(); - std::vector< adtype > soln_coeff(n_soln_dofs); - std::vector< adtype > coords_coeff(n_metric_dofs); + dual_dot_residual = 0.0; + for (unsigned int itest=0; itest; + using DirectionalState = DirectionalState; + using Tensor1D = dealii::Tensor<1,dim,real2>; + using Tensor2D = dealii::Tensor<2,dim,real2>; - unsigned int i_derivative = 0; - const unsigned int n_total_indep = x_end; + dealii::Quadrature face_quadrature_int = project_face_quadrature(face_quadrature, face_subface_int, face_data_set_int); + dealii::Quadrature face_quadrature_ext = project_face_quadrature(face_quadrature, face_subface_ext, face_data_set_ext); - for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { - const real val = this->solution(soln_dof_indices[idof]); - soln_coeff[idof] = val; - soln_coeff[idof].val() = val; + (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R; + const bool compute_metric_derivatives = true; //(!compute_dRdX && !compute_d2R) ? false : true; - if (compute_dRdW || compute_d2R) soln_coeff[idof].diff(i_derivative, n_total_indep); - if (compute_d2R) soln_coeff[idof].val().diff(i_derivative, n_total_indep); + const std::vector> &unit_quad_pts_int = face_quadrature_int.get_points(); + const std::vector> &unit_quad_pts_ext = face_quadrature_ext.get_points(); - if (compute_dRdW || compute_d2R) i_derivative++; - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const real val = this->high_order_grid->volume_nodes[metric_dof_indices[idof]]; - coords_coeff[idof] = val; - coords_coeff[idof].val() = val; - if (compute_dRdX || compute_d2R) coords_coeff[idof].diff(i_derivative, n_total_indep); - if (compute_d2R) coords_coeff[idof].val().diff(i_derivative, n_total_indep); - if (compute_dRdX || compute_d2R) i_derivative++; - } + // Use the metric Jacobian from the interior cell + std::vector metric_jac_int = evaluate_metric_jacobian (unit_quad_pts_int, metric_int); + std::vector metric_jac_ext = evaluate_metric_jacobian (unit_quad_pts_ext, metric_ext); - AssertDimension(i_derivative, n_total_indep); + const dealii::Tensor<1,dim,real> unit_normal_int = dealii::GeometryInfo::unit_normal_vector[face_subface_int.first]; + const dealii::Tensor<1,dim,real> unit_normal_ext = dealii::GeometryInfo::unit_normal_vector[face_subface_ext.first]; - std::vector local_dual(n_soln_dofs); - for (unsigned int itest=0; itestdual[soln_dof_indices[itest]]; - } + // Use quadrature points of neighbor cell + // Might want to use the maximum n_quad_pts1 and n_quad_pts2 + //const unsigned int n_face_quad_pts = fe_values_ext.n_quadrature_points; - const auto &physics = *(DGBaseState::pde_physics_fad_fad); - const auto &conv_num_flux = *(DGBaseState::conv_num_flux_fad_fad); - const auto &diss_num_flux = *(DGBaseState::diss_num_flux_fad_fad); + //const real2 cell_diameter_int = fe_values_int.get_cell()->diameter(); + //const real2 cell_diameter_ext = fe_values_ext.get_cell()->diameter(); + //const real2 artificial_diss_coeff_int = this->all_parameters->artificial_dissipation_param.add_artificial_dissipation ? + // this->discontinuity_sensor(cell_diameter_int, soln_int.coefficients, fe_values_int.get_fe()) + // : 0.0; + //const real2 artificial_diss_coeff_ext = this->all_parameters->artificial_dissipation_param.add_artificial_dissipation ? + // this->discontinuity_sensor(cell_diameter_ext, soln_ext.coefficients, fe_values_ext.get_fe()) + // : 0.0; + const real2 artificial_diss_coeff_int = this->all_parameters->artificial_dissipation_param.add_artificial_dissipation ? + this->artificial_dissipation_coeffs[current_cell_index] + : 0.0; + const real2 artificial_diss_coeff_ext = this->all_parameters->artificial_dissipation_param.add_artificial_dissipation ? + this->artificial_dissipation_coeffs[neighbor_cell_index] + : 0.0; - std::vector rhs(n_soln_dofs); - adtype dual_dot_residual; - assemble_boundary_term( - cell, - current_cell_index, - soln_coeff, - coords_coeff, - local_dual, - face_number, - boundary_id, - physics, - conv_num_flux, - diss_num_flux, - fe_values_boundary, - penalty, - fe_soln, - fe_metric, - quadrature, - rhs, - dual_dot_residual, - compute_metric_derivatives); + (void) artificial_diss_coeff_int; + (void) artificial_diss_coeff_ext; + typename dealii::DoFHandler::active_cell_iterator artificial_dissipation_cell( + this->triangulation.get(), cell->level(), cell->index(), &(this->dof_handler_artificial_dissipation)); + const unsigned int n_dofs_arti_diss = this->fe_q_artificial_dissipation.dofs_per_cell; + std::vector dof_indices_artificial_dissipation(n_dofs_arti_diss); + artificial_dissipation_cell->get_dof_indices (dof_indices_artificial_dissipation); - for (unsigned int itest=0; itest artificial_diss_coeff_at_q(n_face_quad_pts); + for (unsigned int iquad=0; iquad residual_derivatives(n_soln_dofs); - for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { - const unsigned int i_dx = idof+w_start; - residual_derivatives[idof] = rhs[itest].dx(i_dx).val(); - AssertIsFinite(residual_derivatives[idof]); - } - const bool elide_zero_values = false; - this->system_matrix.add(soln_dof_indices[itest], soln_dof_indices, residual_derivatives, elide_zero_values); - } - if (compute_dRdX) { - std::vector residual_derivatives(n_metric_dofs); - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const unsigned int i_dx = idof+x_start; - residual_derivatives[idof] = rhs[itest].dx(i_dx).val(); + if ( this->all_parameters->artificial_dissipation_param.add_artificial_dissipation ) { + const dealii::Point point = unit_quad_pts_int[iquad]; + for (unsigned int idof=0; idofartificial_dissipation_c0[index] * this->fe_q_artificial_dissipation.shape_value(idof, point); } - this->dRdXv.add(soln_dof_indices[itest], metric_dof_indices, residual_derivatives); } - + artificial_diss_coeff_at_q[iquad] = 0.0; } - if (compute_d2R) { - std::vector dWidW(n_soln_dofs); - std::vector dWidX(n_metric_dofs); - std::vector dXidX(n_metric_dofs); - for (unsigned int idof=0; idof jacobian_determinant_int(n_face_quad_pts); + std::vector jacobian_determinant_ext(n_face_quad_pts); + std::vector jacobian_transpose_inverse_int(n_face_quad_pts); + std::vector jacobian_transpose_inverse_ext(n_face_quad_pts); - for (unsigned int jdof=0; jdofd2RdWdW.add(soln_dof_indices[idof], soln_dof_indices, dWidW); + for (unsigned int iquad=0; iquadd2RdWdX.add(soln_dof_indices[idof], metric_dof_indices, dWidX); + jacobian_transpose_inverse_int[iquad] = dealii::transpose(dealii::invert(metric_jac_int[iquad])); + jacobian_transpose_inverse_ext[iquad] = dealii::transpose(dealii::invert(metric_jac_ext[iquad])); } - for (unsigned int idof=0; idofd2RdXdX.add(metric_dof_indices[idof], metric_dof_indices, dXidX); - } + if constexpr (dim != 1) { + evaluate_covariant_metric_jacobian ( face_quadrature_int, metric_int, jacobian_transpose_inverse_int, jacobian_determinant_int); + evaluate_covariant_metric_jacobian ( face_quadrature_ext, metric_ext, jacobian_transpose_inverse_ext, jacobian_determinant_ext); } -} #endif -template -template -void DGWeak::assemble_boundary_codi_taped_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const unsigned int face_number, - const unsigned int boundary_id, - const dealii::FEFaceValuesBase &fe_values_boundary, - const real penalty, - const dealii::FESystem &fe_soln, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - const Physics::PhysicsBase &physics, - const NumericalFlux::NumericalFluxConvective &conv_num_flux, - const NumericalFlux::NumericalFluxDissipative &diss_num_flux, - dealii::Vector &local_rhs_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) -{ - const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; - const unsigned int n_soln_dofs = fe_values_boundary.dofs_per_cell; - const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; + // Note: This is ignored when use_periodic_bc is set to true -- this variable has no other function when dim!=1 + if(this->all_parameters->use_periodic_bc == false) { + check_same_coords(unit_quad_pts_int, unit_quad_pts_ext, metric_int, metric_ext, 1e-10); + } - (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R; - const bool compute_metric_derivatives = true;//(!compute_dRdX && !compute_d2R) ? false : true; - AssertDimension (n_soln_dofs, soln_dof_indices.size()); + // Compute metrics + std::vector phys_unit_normal_int(n_face_quad_pts), phys_unit_normal_ext(n_face_quad_pts); + std::vector surface_jac_det(n_face_quad_pts); + std::vector faceJxW(n_face_quad_pts); - LocalSolution local_solution(fe_soln); - LocalSolution local_metric(fe_metric); + dealii::FullMatrix interpolation_operator_int(n_soln_dofs_int, n_face_quad_pts); + dealii::FullMatrix interpolation_operator_ext(n_soln_dofs_ext, n_face_quad_pts); + std::array,dim> gradient_operator_int, gradient_operator_ext; + for (int d=0;d(n_soln_dofs_int, n_face_quad_pts)); + gradient_operator_ext[d].reinit(dealii::TableIndices<2>(n_soln_dofs_ext, n_face_quad_pts)); + } - unsigned int w_start, w_end, x_start, x_end; - automatic_differentiation_indexing_1( compute_dRdW, compute_dRdX, compute_d2R, - n_soln_dofs, n_metric_dofs, - w_start, w_end, x_start, x_end ); + for (unsigned int iquad=0; iquad; - TH th; - adtype::getGlobalTape(); - if (compute_dRdW || compute_dRdX || compute_d2R) { - th.startRecording(); - } - for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { - const real val = this->solution(soln_dof_indices[idof]); - local_solution.coefficients[idof] = val; + real2 surface_jac_det_int, surface_jac_det_ext; - if (compute_dRdW || compute_d2R) { - th.registerInput(local_solution.coefficients[idof]); - } else { - adtype::getGlobalTape().deactivateValue(local_solution.coefficients[idof]); - } - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const real val = this->high_order_grid->volume_nodes[metric_dof_indices[idof]]; - local_metric.coefficients[idof] = val; + if (compute_metric_derivatives) { - if (compute_dRdX || compute_d2R) { - th.registerInput(local_metric.coefficients[idof]); - } else { - adtype::getGlobalTape().deactivateValue(local_metric.coefficients[idof]); - } - } + const real2 jac_det_int = jacobian_determinant_int[iquad]; + const real2 jac_det_ext = jacobian_determinant_ext[iquad]; - std::vector local_dual(n_soln_dofs); - for (unsigned int itest=0; itestdual[soln_dof_indices[itest]]; - } + const Tensor2D jac_inv_tran_int = jacobian_transpose_inverse_int[iquad]; + const Tensor2D jac_inv_tran_ext = jacobian_transpose_inverse_ext[iquad]; - std::vector rhs(n_soln_dofs); - adtype dual_dot_residual; - assemble_boundary_term( - cell, - current_cell_index, - local_solution, - local_metric, - local_dual, - face_number, - boundary_id, - physics, - conv_num_flux, - diss_num_flux, - fe_values_boundary, - penalty, - quadrature, - rhs, - dual_dot_residual, - compute_metric_derivatives); - - if (compute_dRdW || compute_dRdX) { - for (unsigned int itest=0; itest(rhs[itest]); - AssertIsFinite(local_rhs_cell(itest)); - } - - if (compute_dRdW) { - typename TH::JacobianType& jac = th.createJacobian(); - th.evalJacobian(jac); - for (unsigned int itest=0; itest residual_derivatives(n_soln_dofs); - for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { - const unsigned int i_dx = idof+w_start; - residual_derivatives[idof] = jac(itest,i_dx); - AssertIsFinite(residual_derivatives[idof]); - } - const bool elide_zero_values = false; - this->system_matrix.add(soln_dof_indices[itest], soln_dof_indices, residual_derivatives, elide_zero_values); - } - th.deleteJacobian(jac); - - } - - if (compute_dRdX) { - typename TH::JacobianType& jac = th.createJacobian(); - th.evalJacobian(jac); - for (unsigned int itest=0; itest residual_derivatives(n_metric_dofs); - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const unsigned int i_dx = idof+x_start; - residual_derivatives[idof] = jac(itest,i_dx); - } - this->dRdXv.add(soln_dof_indices[itest], metric_dof_indices, residual_derivatives); - } - th.deleteJacobian(jac); - } - - - if (compute_d2R) { - typename TH::HessianType& hes = th.createHessian(); - th.evalHessian(hes); - - int i_dependent = (compute_dRdW || compute_dRdX) ? n_soln_dofs : 0; - - std::vector dWidW(n_soln_dofs); - std::vector dWidX(n_metric_dofs); - std::vector dXidX(n_metric_dofs); - - for (unsigned int idof=0; idofd2RdWdW.add(soln_dof_indices[idof], soln_dof_indices, dWidW); - - for (unsigned int jdof=0; jdofd2RdWdX.add(soln_dof_indices[idof], metric_dof_indices, dWidX); - } - - for (unsigned int idof=0; idofd2RdXdX.add(metric_dof_indices[idof], metric_dof_indices, dXidX); - } - - th.deleteHessian(hes); - } - for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { - adtype::getGlobalTape().deactivateValue(local_solution.coefficients[idof]); - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - adtype::getGlobalTape().deactivateValue(local_metric.coefficients[idof]); - } - -} - -template -void DGWeak::assemble_boundary_residual( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const unsigned int face_number, - const unsigned int boundary_id, - const dealii::FEFaceValuesBase &fe_values_boundary, - const real penalty, - const dealii::FESystem &fe_soln, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - const Physics::PhysicsBase &physics, - const NumericalFlux::NumericalFluxConvective &conv_num_flux, - const NumericalFlux::NumericalFluxDissipative &diss_num_flux, - dealii::Vector &local_rhs_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) -{ - const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; - const unsigned int n_soln_dofs = fe_values_boundary.dofs_per_cell; - const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; - - (void) compute_dRdW; - (void) compute_dRdX; - (void) compute_d2R; - - const bool compute_metric_derivatives = true; //= (!compute_dRdX && !compute_d2R) ? false : true; - AssertDimension (n_soln_dofs, soln_dof_indices.size()); - - LocalSolution local_solution(fe_soln); - LocalSolution local_metric(fe_metric); - - for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { - const real val = this->solution(soln_dof_indices[idof]); - local_solution.coefficients[idof] = val; - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const real val = this->high_order_grid->volume_nodes[metric_dof_indices[idof]]; - local_metric.coefficients[idof] = val; - } - - std::vector local_dual(n_soln_dofs); - for (unsigned int itest=0; itestdual[soln_dof_indices[itest]]; - } - - std::vector rhs(n_soln_dofs); - real dual_dot_residual; - assemble_boundary_term( - cell, - current_cell_index, - local_solution, - local_metric, - local_dual, - face_number, - boundary_id, - physics, - conv_num_flux, - diss_num_flux, - fe_values_boundary, - penalty, - quadrature, - rhs, - dual_dot_residual, - compute_metric_derivatives); - - for (unsigned int itest=0; itest(rhs[itest]); - AssertIsFinite(local_rhs_cell(itest)); - } - -} - -#ifndef FADFAD -template -void DGWeak::assemble_boundary_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const unsigned int face_number, - const unsigned int boundary_id, - const dealii::FEFaceValuesBase &fe_values_boundary, - const real penalty, - const dealii::FESystem &fe_soln, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - dealii::Vector &local_rhs_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) -{ - (void) current_cell_index; - if (compute_d2R) { - assemble_boundary_codi_taped_derivatives( - cell, - current_cell_index, - face_number, - boundary_id, - fe_values_boundary, - penalty, - fe_soln, - quadrature, - metric_dof_indices, - soln_dof_indices, - *(DGBaseState::pde_physics_rad_fad), - *(DGBaseState::conv_num_flux_rad_fad), - *(DGBaseState::diss_num_flux_rad_fad), - local_rhs_cell, - compute_dRdW, compute_dRdX, compute_d2R); - } else if (compute_dRdW || compute_dRdX) { - assemble_boundary_codi_taped_derivatives( - cell, - current_cell_index, - face_number, - boundary_id, - fe_values_boundary, - penalty, - fe_soln, - quadrature, - metric_dof_indices, - soln_dof_indices, - *(DGBaseState::pde_physics_rad), - *(DGBaseState::conv_num_flux_rad), - *(DGBaseState::diss_num_flux_rad), - local_rhs_cell, - compute_dRdW, compute_dRdX, compute_d2R); - } else { - assemble_boundary_residual( - cell, - current_cell_index, - face_number, - boundary_id, - fe_values_boundary, - penalty, - fe_soln, - quadrature, - metric_dof_indices, - soln_dof_indices, - *(DGBaseState::pde_physics_double), - *(DGBaseState::conv_num_flux_double), - *(DGBaseState::diss_num_flux_double), - local_rhs_cell, - compute_dRdW, compute_dRdX, compute_d2R); - } -} -#endif - - - -template -dealii::Quadrature project_face_quadrature( - const dealii::Quadrature &face_quadrature_lower_dim, const std::pair face_subface_pair, - const typename dealii::QProjector::DataSetDescriptor face_data_set) { - dealii::Quadrature face_quadrature; - - if constexpr (dim == 3) { - const dealii::Quadrature all_faces_quad = - face_subface_pair.second == -1 ? dealii::QProjector::project_to_all_faces( - dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim) - : dealii::QProjector::project_to_all_subfaces( - dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim); - const unsigned int n_face_quad_pts = face_quadrature_lower_dim.size(); - std::vector> points(n_face_quad_pts); - std::vector weights(n_face_quad_pts); - for (unsigned int iquad = 0; iquad < n_face_quad_pts; ++iquad) { - points[iquad] = all_faces_quad.point(iquad + face_data_set); - weights[iquad] = all_faces_quad.weight(iquad + face_data_set); - } - face_quadrature = dealii::Quadrature(points, weights); - - } else { - (void) face_data_set; - if (face_subface_pair.second == -1) { - face_quadrature = dealii::QProjector::project_to_face( - dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim, face_subface_pair.first); - } else { - face_quadrature = dealii::QProjector::project_to_subface( - dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim, face_subface_pair.first, - face_subface_pair.second, dealii::RefinementCase::isotropic_refinement); - } - } - return face_quadrature; -} - -template -template -void DGWeak::assemble_face_term( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const LocalSolution &soln_int, - const LocalSolution &soln_ext, - const LocalSolution &metric_int, - const LocalSolution &metric_ext, - const std::vector< double > &dual_int, - const std::vector< double > &dual_ext, - const std::pair face_subface_int, - const std::pair face_subface_ext, - const typename dealii::QProjector::DataSetDescriptor face_data_set_int, - const typename dealii::QProjector::DataSetDescriptor face_data_set_ext, - const Physics::PhysicsBase &physics, - const NumericalFlux::NumericalFluxConvective &conv_num_flux, - const NumericalFlux::NumericalFluxDissipative &diss_num_flux, - const dealii::FEFaceValuesBase &fe_values_int, - const dealii::FEFaceValuesBase &fe_values_ext, - const real penalty, - const dealii::Quadrature &face_quadrature, - std::vector &rhs_int, - std::vector &rhs_ext, - real2 &dual_dot_residual, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) -{ - (void) compute_dRdW; - const unsigned int n_soln_dofs_int = soln_int.finite_element.dofs_per_cell; - const unsigned int n_soln_dofs_ext = soln_ext.finite_element.dofs_per_cell; - const unsigned int n_face_quad_pts = face_quadrature.size(); - - dual_dot_residual = 0.0; - for (unsigned int itest=0; itest; - using DirectionalState = DirectionalState; - using Tensor1D = dealii::Tensor<1,dim,real2>; - using Tensor2D = dealii::Tensor<2,dim,real2>; - - dealii::Quadrature face_quadrature_int = project_face_quadrature(face_quadrature, face_subface_int, face_data_set_int); - dealii::Quadrature face_quadrature_ext = project_face_quadrature(face_quadrature, face_subface_ext, face_data_set_ext); - - (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R; - const bool compute_metric_derivatives = true; //(!compute_dRdX && !compute_d2R) ? false : true; - - const std::vector> &unit_quad_pts_int = face_quadrature_int.get_points(); - const std::vector> &unit_quad_pts_ext = face_quadrature_ext.get_points(); - - - - // Use the metric Jacobian from the interior cell - std::vector metric_jac_int = evaluate_metric_jacobian (unit_quad_pts_int, metric_int); - std::vector metric_jac_ext = evaluate_metric_jacobian (unit_quad_pts_ext, metric_ext); - - const dealii::Tensor<1,dim,real> unit_normal_int = dealii::GeometryInfo::unit_normal_vector[face_subface_int.first]; - const dealii::Tensor<1,dim,real> unit_normal_ext = dealii::GeometryInfo::unit_normal_vector[face_subface_ext.first]; - - // Use quadrature points of neighbor cell - // Might want to use the maximum n_quad_pts1 and n_quad_pts2 - //const unsigned int n_face_quad_pts = fe_values_ext.n_quadrature_points; - - //const real2 cell_diameter_int = fe_values_int.get_cell()->diameter(); - //const real2 cell_diameter_ext = fe_values_ext.get_cell()->diameter(); - //const real2 artificial_diss_coeff_int = this->all_parameters->artificial_dissipation_param.add_artificial_dissipation ? - // this->discontinuity_sensor(cell_diameter_int, soln_int.coefficients, fe_values_int.get_fe()) - // : 0.0; - //const real2 artificial_diss_coeff_ext = this->all_parameters->artificial_dissipation_param.add_artificial_dissipation ? - // this->discontinuity_sensor(cell_diameter_ext, soln_ext.coefficients, fe_values_ext.get_fe()) - // : 0.0; - const real2 artificial_diss_coeff_int = this->all_parameters->artificial_dissipation_param.add_artificial_dissipation ? - this->artificial_dissipation_coeffs[current_cell_index] - : 0.0; - const real2 artificial_diss_coeff_ext = this->all_parameters->artificial_dissipation_param.add_artificial_dissipation ? - this->artificial_dissipation_coeffs[neighbor_cell_index] - : 0.0; - - (void) artificial_diss_coeff_int; - (void) artificial_diss_coeff_ext; - typename dealii::DoFHandler::active_cell_iterator artificial_dissipation_cell( - this->triangulation.get(), cell->level(), cell->index(), &(this->dof_handler_artificial_dissipation)); - const unsigned int n_dofs_arti_diss = this->fe_q_artificial_dissipation.dofs_per_cell; - std::vector dof_indices_artificial_dissipation(n_dofs_arti_diss); - artificial_dissipation_cell->get_dof_indices (dof_indices_artificial_dissipation); - - std::vector artificial_diss_coeff_at_q(n_face_quad_pts); - for (unsigned int iquad=0; iquadall_parameters->artificial_dissipation_param.add_artificial_dissipation ) { - const dealii::Point point = unit_quad_pts_int[iquad]; - for (unsigned int idof=0; idofartificial_dissipation_c0[index] * this->fe_q_artificial_dissipation.shape_value(idof, point); - } - } - artificial_diss_coeff_at_q[iquad] = 0.0; - } - - std::vector jacobian_determinant_int(n_face_quad_pts); - std::vector jacobian_determinant_ext(n_face_quad_pts); - std::vector jacobian_transpose_inverse_int(n_face_quad_pts); - std::vector jacobian_transpose_inverse_ext(n_face_quad_pts); - - for (unsigned int iquad=0; iquad ( face_quadrature_int, metric_int, jacobian_transpose_inverse_int, jacobian_determinant_int); - evaluate_covariant_metric_jacobian ( face_quadrature_ext, metric_ext, jacobian_transpose_inverse_ext, jacobian_determinant_ext); - } -#endif - - // Note: This is ignored when use_periodic_bc is set to true -- this variable has no other function when dim!=1 - if(this->all_parameters->use_periodic_bc == false) { - check_same_coords(unit_quad_pts_int, unit_quad_pts_ext, metric_int, metric_ext, 1e-10); - } - - // Compute metrics - std::vector phys_unit_normal_int(n_face_quad_pts), phys_unit_normal_ext(n_face_quad_pts); - std::vector surface_jac_det(n_face_quad_pts); - std::vector faceJxW(n_face_quad_pts); - - dealii::FullMatrix interpolation_operator_int(n_soln_dofs_int, n_face_quad_pts); - dealii::FullMatrix interpolation_operator_ext(n_soln_dofs_ext, n_face_quad_pts); - std::array,dim> gradient_operator_int, gradient_operator_ext; - for (int d=0;d(n_soln_dofs_int, n_face_quad_pts)); - gradient_operator_ext[d].reinit(dealii::TableIndices<2>(n_soln_dofs_ext, n_face_quad_pts)); - } - - for (unsigned int iquad=0; iquad::value) { - bool valid_metrics = true; - // surface_jac_det is the 'volume' compression/expansion of the face w.r.t. the reference cell, - // analogous to volume jacobian determinant. - // - // When the cells have the same coarseness, their surface Jacobians must be the same. - // - // When the cells do not have the same coarseness, their surface Jacobians will not be the same. - // Therefore, we must use the Jacobians coming from the smaller face since it accurately represents - // the surface area being integrated. - if (face_subface_int.second == -1 && face_subface_ext.second == -1) { - if(abs(surface_jac_det_int-surface_jac_det_ext) > this->all_parameters->matching_surface_jac_det_tolerance) { - pcout << std::endl; - pcout << "iquad " << iquad << " Non-matching surface jacobians, int = " - << surface_jac_det_int << ", ext = " << surface_jac_det_ext << ", diff = " - << abs(surface_jac_det_int-surface_jac_det_ext) << std::endl; - - assert(abs(surface_jac_det_int-surface_jac_det_ext) < this->all_parameters->matching_surface_jac_det_tolerance); - valid_metrics = false; - } - } - real2 diff_norm = 0; - for (int d=0;d 1e-10) { - std::cout << std::setprecision(std::numeric_limits::digits10 + 1); - std::cout << "Non-matching normals. Error norm: " << diff_norm << std::endl; - for (int d=0;d ref_shape_grad = soln_int.finite_element.shape_grad(idof,unit_quad_pts_int[iquad]); - const Tensor1D phys_shape_grad = vmult(jac_inv_tran_int, ref_shape_grad); - for (int d=0;d ref_shape_grad = soln_ext.finite_element.shape_grad(idof,unit_quad_pts_ext[iquad]); - const Tensor1D phys_shape_grad = vmult(jac_inv_tran_ext, ref_shape_grad); - for (int d=0;d surface_jac_det_ext) { - // Interior is the large face. - // Exterior is the small face. - surface_jac_det[iquad] = surface_jac_det_ext; - //phys_unit_normal_ext[iquad] = -phys_unit_normal_int[iquad]; - } else { - // Exterior is the large face. - // Interior is the small face. - surface_jac_det[iquad] = surface_jac_det_int; - //phys_unit_normal_int[iquad] = -phys_unit_normal_ext[iquad]; - } - - faceJxW[iquad] = surface_jac_det[iquad] * face_quadrature_int.weight(iquad); - } - - - // Interpolate solution - std::vector soln_int_at_q = soln_int.evaluate_values(unit_quad_pts_int); - std::vector soln_ext_at_q = soln_ext.evaluate_values(unit_quad_pts_ext); - - // Interpolate solution gradient - std::vector soln_grad_int(n_face_quad_pts), soln_grad_ext(n_face_quad_pts); - for (unsigned int iquad=0; iquadall_parameters->diss_num_flux_type == DissFlux::bassi_rebay_2) { - - const dealii::FiniteElement &base_fe_int = soln_int.finite_element.get_sub_fe(0,1); - const dealii::FiniteElement &base_fe_ext = soln_ext.finite_element.get_sub_fe(0,1); - const unsigned int n_base_dofs_int = base_fe_int.n_dofs_per_cell(); - const unsigned int n_base_dofs_ext = base_fe_ext.n_dofs_per_cell(); - - // Obtain solution jump - std::vector soln_jump_int(n_face_quad_pts); - std::vector soln_jump_ext(n_face_quad_pts); - for (unsigned int iquad=0; iquad lifting_op_R_rhs_int(n_base_dofs_int); - for (unsigned int idof_base=0; idof_base lifting_op_R_rhs_ext(n_base_dofs_ext); - for (unsigned int idof_base=0; idof_base soln_grad_corr_int(n_base_dofs_int), soln_grad_corr_ext(n_base_dofs_ext); - compute_br2_correction(soln_int.finite_element, metric_int, lifting_op_R_rhs_int, soln_grad_corr_int); - compute_br2_correction(soln_ext.finite_element, metric_ext, lifting_op_R_rhs_ext, soln_grad_corr_ext); - - correct_the_gradient( soln_grad_corr_int, soln_int.finite_element, soln_jump_int, interpolation_operator_int, gradient_operator_int, soln_grad_int); - correct_the_gradient( soln_grad_corr_ext, soln_ext.finite_element, soln_jump_ext, interpolation_operator_ext, gradient_operator_ext, soln_grad_ext); - - } - - - State conv_num_flux_dot_n; - State diss_soln_num_flux; // u* - State diss_auxi_num_flux_dot_n; // sigma* - - DirectionalState diss_flux_jump_int; // u*-u_int - DirectionalState diss_flux_jump_ext; // u*-u_ext - - for (unsigned int iquad=0; iquadall_parameters->artificial_dissipation_param.add_artificial_dissipation) { - const DirectionalState artificial_diss_flux_jump_int = DGBaseState::artificial_dissip->calc_artificial_dissipation_flux(soln_int_at_q[iquad], diss_soln_jump_int,artificial_diss_coeff_at_q[iquad]); - const DirectionalState artificial_diss_flux_jump_ext = DGBaseState::artificial_dissip->calc_artificial_dissipation_flux(soln_ext_at_q[iquad], diss_soln_jump_ext,artificial_diss_coeff_at_q[iquad]); - for (int s=0; s -void DGWeak::assemble_face_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const std::pair face_subface_int, - const std::pair face_subface_ext, - const typename dealii::QProjector::DataSetDescriptor face_data_set_int, - const typename dealii::QProjector::DataSetDescriptor face_data_set_ext, - const dealii::FEFaceValuesBase &fe_values_int, - const dealii::FEFaceValuesBase &fe_values_ext, - const real penalty, - const dealii::FESystem &soln_int.finite_element, - const dealii::FESystem &soln_ext.finite_element, - const dealii::Quadrature &face_quadrature, - const std::vector &metric_dof_indices_int, - const std::vector &metric_dof_indices_ext, - const std::vector &soln_dof_indices_int, - const std::vector &soln_dof_indices_ext, - dealii::Vector &local_rhs_int_cell, - dealii::Vector &local_rhs_ext_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) -{ - (void) current_cell_index; - (void) neighbor_cell_index; - using adtype = FadFadType; - using ADArray = std::array; - using ADArrayTensor1 = std::array< dealii::Tensor<1,dim,adtype>, nstate >; - - const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; - const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; - const unsigned int n_soln_dofs_int = soln_int.finite_element.dofs_per_cell; - const unsigned int n_soln_dofs_ext = soln_ext.finite_element.dofs_per_cell; - - AssertDimension (n_soln_dofs_int, soln_dof_indices_int.size()); - AssertDimension (n_soln_dofs_ext, soln_dof_indices_ext.size()); - - std::vector< adtype > coords_coeff_int(n_metric_dofs); - std::vector< adtype > coords_coeff_ext(n_metric_dofs); - std::vector< adtype > soln_int.coefficients(n_soln_dofs_int); - std::vector< adtype > soln_ext.coefficients(n_soln_dofs_ext); - - // Current derivative ordering is: soln_int, soln_ext, metric_int, metric_ext - unsigned int w_int_start, w_int_end, w_ext_start, w_ext_end, - x_int_start, x_int_end, x_ext_start, x_ext_end; - automatic_differentiation_indexing_2( - compute_dRdW, compute_dRdX, compute_d2R, - n_soln_dofs_int, n_soln_dofs_ext, n_metric_dofs, - w_int_start, w_int_end, w_ext_start, w_ext_end, - x_int_start, x_int_end, x_ext_start, x_ext_end); - - const unsigned int n_total_indep = x_ext_end; - unsigned int i_derivative = 0; - - for (unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) { - const real val = this->solution(soln_dof_indices_int[idof]); - soln_int.coefficients[idof] = val; - soln_int.coefficients[idof].val() = val; - - if (compute_dRdW || compute_d2R) soln_int.coefficients[idof].diff(i_derivative, n_total_indep); - if (compute_d2R) soln_int.coefficients[idof].val().diff(i_derivative, n_total_indep); - if (compute_dRdW || compute_d2R) i_derivative++; - } - for (unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) { - const real val = this->solution(soln_dof_indices_ext[idof]); - soln_ext.coefficients[idof] = val; - soln_ext.coefficients[idof].val() = val; - - if (compute_dRdW || compute_d2R) soln_ext.coefficients[idof].diff(i_derivative, n_total_indep); - if (compute_d2R) soln_ext.coefficients[idof].val().diff(i_derivative, n_total_indep); - if (compute_dRdW || compute_d2R) i_derivative++; - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const real val = this->high_order_grid->volume_nodes[metric_dof_indices_int[idof]]; - coords_coeff_int[idof] = val; - coords_coeff_int[idof].val() = val; - - if (compute_dRdX || compute_d2R) coords_coeff_int[idof].diff(i_derivative, n_total_indep); - if (compute_d2R) coords_coeff_int[idof].val().diff(i_derivative, n_total_indep); - if (compute_dRdX || compute_d2R) i_derivative++; - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const real val = this->high_order_grid->volume_nodes[metric_dof_indices_ext[idof]]; - coords_coeff_ext[idof] = val; - coords_coeff_ext[idof].val() = val; - - if (compute_dRdX || compute_d2R) coords_coeff_ext[idof].diff(i_derivative, n_total_indep); - if (compute_d2R) coords_coeff_ext[idof].val().diff(i_derivative, n_total_indep); - if (compute_dRdX || compute_d2R) i_derivative++; - } - AssertDimension(i_derivative, n_total_indep); - - std::vector dual_int(n_soln_dofs_int); - std::vector dual_ext(n_soln_dofs_ext); - - for (unsigned int itest=0; itestdual[global_residual_row]; - } - for (unsigned int itest=0; itestdual[global_residual_row]; - } - - std::vector rhs_int(n_soln_dofs_int); - std::vector rhs_ext(n_soln_dofs_ext); - adtype dual_dot_residual; - - const auto &physics = *(DGBaseState::pde_physics_fad_fad); - const auto &conv_num_flux = *(DGBaseState::conv_num_flux_fad_fad); - const auto &diss_num_flux = *(DGBaseState::diss_num_flux_fad_fad); - assemble_face_term( - cell, - current_cell_index, - neighbor_cell_index, - soln_int.coefficients, - soln_ext.coefficients, - coords_coeff_int, - coords_coeff_ext, - dual_int, - dual_ext, - face_subface_int, - face_subface_ext, - face_data_set_int, - face_data_set_ext, - physics, - conv_num_flux, - diss_num_flux, - fe_values_int, - fe_values_ext, - penalty, - soln_int.finite_element, - soln_ext.finite_element, - fe_metric, - face_quadrature_int, - face_quadrature_ext, - rhs_int, - rhs_ext, - dual_dot_residual, - compute_dRdW, compute_dRdX, compute_d2R); - - for (unsigned int itest_int=0; itest_int residual_derivatives(n_soln_dofs_int); - for (unsigned int itest_int=0; itest_intsystem_matrix.add(soln_dof_indices_int[itest_int], soln_dof_indices_int, residual_derivatives, elide_zero_values); - - // dR_int_dW_ext - residual_derivatives.resize(n_soln_dofs_ext); - for (unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) { - const unsigned int i_dx = idof+w_ext_start; - residual_derivatives[idof] = rhs_int[itest_int].dx(i_dx).val(); - } - this->system_matrix.add(soln_dof_indices_int[itest_int], soln_dof_indices_ext, residual_derivatives, elide_zero_values); - } - - for (unsigned int itest_ext=0; itest_extsystem_matrix.add(soln_dof_indices_ext[itest_ext], soln_dof_indices_int, residual_derivatives, elide_zero_values); - - // dR_ext_dW_ext - residual_derivatives.resize(n_soln_dofs_ext); - for (unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) { - const unsigned int i_dx = idof+w_ext_start; - residual_derivatives[idof] = rhs_ext[itest_ext].dx(i_dx).val(); - } - this->system_matrix.add(soln_dof_indices_ext[itest_ext], soln_dof_indices_ext, residual_derivatives, elide_zero_values); - } - } - if (compute_dRdX) { - std::vector residual_derivatives(n_metric_dofs); - for (unsigned int itest_int=0; itest_intdRdXv.add(soln_dof_indices_int[itest_int], metric_dof_indices_int, residual_derivatives); - - // dR_int_dX_ext - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const unsigned int i_dx = idof+x_ext_start; - residual_derivatives[idof] = rhs_int[itest_int].dx(i_dx).val(); - } - this->dRdXv.add(soln_dof_indices_int[itest_int], metric_dof_indices_ext, residual_derivatives); - } - for (unsigned int itest_ext=0; itest_ext residual_derivatives(n_metric_dofs); - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const unsigned int i_dx = idof+x_int_start; - residual_derivatives[idof] = rhs_ext[itest_ext].dx(i_dx).val(); - } - this->dRdXv.add(soln_dof_indices_ext[itest_ext], metric_dof_indices_int, residual_derivatives); - - // dR_ext_dX_ext - // residual_derivatives.resize(n_metric_dofs); - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const unsigned int i_dx = idof+x_ext_start; - residual_derivatives[idof] = rhs_ext[itest_ext].dx(i_dx).val(); - } - this->dRdXv.add(soln_dof_indices_ext[itest_ext], metric_dof_indices_ext, residual_derivatives); - } - } - - if (compute_d2R) { - std::vector dWidWint(n_soln_dofs_int); - std::vector dWidWext(n_soln_dofs_ext); - std::vector dWidX(n_metric_dofs); - std::vector dXidX(n_metric_dofs); - // dWint - for (unsigned int idof=0; idofd2RdWdW.add(soln_dof_indices_int[idof], soln_dof_indices_int, dWidWint); - - // dWint_dWext - for (unsigned int jdof=0; jdofd2RdWdW.add(soln_dof_indices_int[idof], soln_dof_indices_ext, dWidWext); - - // dWint_dXint - for (unsigned int jdof=0; jdofd2RdWdX.add(soln_dof_indices_int[idof], metric_dof_indices_int, dWidX); - // dWint_dXext - for (unsigned int jdof=0; jdofd2RdWdX.add(soln_dof_indices_int[idof], metric_dof_indices_ext, dWidX); - } - // dWext - for (unsigned int idof=0; idofd2RdWdW.add(soln_dof_indices_ext[idof], soln_dof_indices_int, dWidWint); + if (std::is_same::value) { + bool valid_metrics = true; + // surface_jac_det is the 'volume' compression/expansion of the face w.r.t. the reference cell, + // analogous to volume jacobian determinant. + // + // When the cells have the same coarseness, their surface Jacobians must be the same. + // + // When the cells do not have the same coarseness, their surface Jacobians will not be the same. + // Therefore, we must use the Jacobians coming from the smaller face since it accurately represents + // the surface area being integrated. + if (face_subface_int.second == -1 && face_subface_ext.second == -1) { + if(abs(surface_jac_det_int-surface_jac_det_ext) > this->all_parameters->matching_surface_jac_det_tolerance) { + pcout << std::endl; + pcout << "iquad " << iquad << " Non-matching surface jacobians, int = " + << surface_jac_det_int << ", ext = " << surface_jac_det_ext << ", diff = " + << abs(surface_jac_det_int-surface_jac_det_ext) << std::endl; - // dWext_dWext - for (unsigned int jdof=0; jdofd2RdWdW.add(soln_dof_indices_ext[idof], soln_dof_indices_ext, dWidWext); + assert(abs(surface_jac_det_int-surface_jac_det_ext) < this->all_parameters->matching_surface_jac_det_tolerance); + valid_metrics = false; + } + } + real2 diff_norm = 0; + for (int d=0;d 1e-10) { + std::cout << std::setprecision(std::numeric_limits::digits10 + 1); + std::cout << "Non-matching normals. Error norm: " << diff_norm << std::endl; + for (int d=0;dd2RdWdX.add(soln_dof_indices_ext[idof], metric_dof_indices_int, dWidX); + //phys_unit_normal_ext[iquad] = -phys_unit_normal_int[iquad];//normal_ext / area_ext; Must use opposite normal to be consistent with explicit - // dWext_dXext - for (unsigned int jdof=0; jdof ref_shape_grad = soln_int.finite_element.shape_grad(idof,unit_quad_pts_int[iquad]); + const Tensor1D phys_shape_grad = vmult(jac_inv_tran_int, ref_shape_grad); + for (int d=0;dd2RdWdX.add(soln_dof_indices_ext[idof], metric_dof_indices_ext, dWidX); - } - - // dXint - for (unsigned int idof=0; idof ref_shape_grad = soln_ext.finite_element.shape_grad(idof,unit_quad_pts_ext[iquad]); + const Tensor1D phys_shape_grad = vmult(jac_inv_tran_ext, ref_shape_grad); + for (int d=0;dd2RdXdX.add(metric_dof_indices_int[idof], metric_dof_indices_int, dWidX); - // dXint_dXext - for (unsigned int jdof=0; jdofd2RdXdX.add(metric_dof_indices_int[idof], metric_dof_indices_ext, dWidX); - } - // dXext - for (unsigned int idof=0; idofd2RdXdX.add(metric_dof_indices_ext[idof], metric_dof_indices_int, dWidX); - - // dXext_dXext - for (unsigned int jdof=0; jdofd2RdXdX.add(metric_dof_indices_ext[idof], metric_dof_indices_ext, dWidX); - } - } -} -#endif - -#ifndef FADFAD -template -template -void DGWeak::assemble_face_codi_taped_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const std::pair face_subface_int, - const std::pair face_subface_ext, - const typename dealii::QProjector::DataSetDescriptor face_data_set_int, - const typename dealii::QProjector::DataSetDescriptor face_data_set_ext, - const dealii::FEFaceValuesBase &fe_values_int, - const dealii::FEFaceValuesBase &fe_values_ext, - const real penalty, - const dealii::FESystem &fe_int, - const dealii::FESystem &fe_ext, - const dealii::Quadrature &face_quadrature, - const std::vector &metric_dof_indices_int, - const std::vector &metric_dof_indices_ext, - const std::vector &soln_dof_indices_int, - const std::vector &soln_dof_indices_ext, - const Physics::PhysicsBase &physics, - const NumericalFlux::NumericalFluxConvective &conv_num_flux, - const NumericalFlux::NumericalFluxDissipative &diss_num_flux, - dealii::Vector &local_rhs_int_cell, - dealii::Vector &local_rhs_ext_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) -{ - const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; - const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; - const unsigned int n_soln_dofs_int = fe_int.dofs_per_cell; - const unsigned int n_soln_dofs_ext = fe_ext.dofs_per_cell; + surface_jac_det_int = fe_values_int.JxW(iquad)/face_quadrature_int.weight(iquad); + surface_jac_det_ext = fe_values_ext.JxW(iquad)/face_quadrature_ext.weight(iquad); - AssertDimension (n_soln_dofs_int, soln_dof_indices_int.size()); - AssertDimension (n_soln_dofs_ext, soln_dof_indices_ext.size()); - - LocalSolution soln_int(fe_int); - LocalSolution soln_ext(fe_ext); - LocalSolution metric_int(fe_metric); - LocalSolution metric_ext(fe_metric); - - // Current derivative ordering is: soln_int, soln_ext, metric_int, metric_ext - unsigned int w_int_start, w_int_end, w_ext_start, w_ext_end, - x_int_start, x_int_end, x_ext_start, x_ext_end; - automatic_differentiation_indexing_2( - compute_dRdW, compute_dRdX, compute_d2R, - n_soln_dofs_int, n_soln_dofs_ext, n_metric_dofs, - w_int_start, w_int_end, w_ext_start, w_ext_end, - x_int_start, x_int_end, x_ext_start, x_ext_end); - - using TH = codi::TapeHelper; - TH th; - adtype::getGlobalTape(); - if (compute_dRdW || compute_dRdX || compute_d2R) { - th.startRecording(); - } - for (unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) { - const real val = this->solution(soln_dof_indices_int[idof]); - soln_int.coefficients[idof] = val; - if (compute_dRdW || compute_d2R) { - th.registerInput(soln_int.coefficients[idof]); - } else { - adtype::getGlobalTape().deactivateValue(soln_int.coefficients[idof]); - } - } - for (unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) { - const real val = this->solution(soln_dof_indices_ext[idof]); - soln_ext.coefficients[idof] = val; - if (compute_dRdW || compute_d2R) { - th.registerInput(soln_ext.coefficients[idof]); - } else { - adtype::getGlobalTape().deactivateValue(soln_ext.coefficients[idof]); - } - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const real val = this->high_order_grid->volume_nodes[metric_dof_indices_int[idof]]; - metric_int.coefficients[idof] = val; - if (compute_dRdX || compute_d2R) { - th.registerInput(metric_int.coefficients[idof]); - } else { - adtype::getGlobalTape().deactivateValue(metric_int.coefficients[idof]); + phys_unit_normal_int[iquad] = fe_values_int.normal_vector(iquad); + phys_unit_normal_ext[iquad] = -phys_unit_normal_int[iquad]; // Must use opposite normal to be consistent with explicit } - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const real val = this->high_order_grid->volume_nodes[metric_dof_indices_ext[idof]]; - metric_ext.coefficients[idof] = val; - if (compute_dRdX || compute_d2R) { - th.registerInput(metric_ext.coefficients[idof]); + // When the cells do not have the same coarseness, their surface Jacobians will not be the same. + // Therefore, we must use the Jacobians coming from the smaller face since it accurately represents + // the surface area being computed. + // + // Note that it is possible for the smaller cell to have larger surface Jacobians than the larger cell, + // but not at the same physical location. + if ( surface_jac_det_int > surface_jac_det_ext) { + // Interior is the large face. + // Exterior is the small face. + surface_jac_det[iquad] = surface_jac_det_ext; + //phys_unit_normal_ext[iquad] = -phys_unit_normal_int[iquad]; } else { - adtype::getGlobalTape().deactivateValue(metric_ext.coefficients[idof]); + // Exterior is the large face. + // Interior is the small face. + surface_jac_det[iquad] = surface_jac_det_int; + //phys_unit_normal_int[iquad] = -phys_unit_normal_ext[iquad]; } + + faceJxW[iquad] = surface_jac_det[iquad] * face_quadrature_int.weight(iquad); } - std::vector dual_int(n_soln_dofs_int); - std::vector dual_ext(n_soln_dofs_ext); - for (unsigned int itest=0; itestdual[global_residual_row]; - } - for (unsigned int itest=0; itestdual[global_residual_row]; - } + // Interpolate solution + std::vector soln_int_at_q = soln_int.evaluate_values(unit_quad_pts_int); + std::vector soln_ext_at_q = soln_ext.evaluate_values(unit_quad_pts_ext); - std::vector rhs_int(n_soln_dofs_int); - std::vector rhs_ext(n_soln_dofs_ext); - adtype dual_dot_residual; + // Interpolate solution gradient + std::vector soln_grad_int(n_face_quad_pts), soln_grad_ext(n_face_quad_pts); + for (unsigned int iquad=0; iquad(rhs_int[itest_int]); - } - for (unsigned int itest_ext=0; itest_ext(rhs_ext[itest_ext]); - } - - if (compute_dRdW || compute_dRdX) { - typename TH::JacobianType& jac = th.createJacobian(); - th.evalJacobian(jac); - - if (compute_dRdW) { - std::vector residual_derivatives(n_soln_dofs_int); - - for (unsigned int itest_int=0; itest_intsystem_matrix.add(soln_dof_indices_int[itest_int], soln_dof_indices_int, residual_derivatives, elide_zero_values); - - // dR_int_dW_ext - residual_derivatives.resize(n_soln_dofs_ext); - for (unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) { - const unsigned int i_dx = idof+w_ext_start; - residual_derivatives[idof] = jac(i_dependent,i_dx); - } - this->system_matrix.add(soln_dof_indices_int[itest_int], soln_dof_indices_ext, residual_derivatives, elide_zero_values); - } + // Assemble BR2 gradient correction right-hand side - for (unsigned int itest_ext=0; itest_extall_parameters->diss_num_flux_type == DissFlux::bassi_rebay_2) { - int i_dependent = n_soln_dofs_int + itest_ext; + const dealii::FiniteElement &base_fe_int = soln_int.finite_element.get_sub_fe(0,1); + const dealii::FiniteElement &base_fe_ext = soln_ext.finite_element.get_sub_fe(0,1); + const unsigned int n_base_dofs_int = base_fe_int.n_dofs_per_cell(); + const unsigned int n_base_dofs_ext = base_fe_ext.n_dofs_per_cell(); - // dR_ext_dW_int - residual_derivatives.resize(n_soln_dofs_int); - for (unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) { - const unsigned int i_dx = idof+w_int_start; - residual_derivatives[idof] = jac(i_dependent,i_dx); - } - const bool elide_zero_values = false; - this->system_matrix.add(soln_dof_indices_ext[itest_ext], soln_dof_indices_int, residual_derivatives, elide_zero_values); - - // dR_ext_dW_ext - residual_derivatives.resize(n_soln_dofs_ext); - for (unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) { - const unsigned int i_dx = idof+w_ext_start; - residual_derivatives[idof] = jac(i_dependent,i_dx); + // Obtain solution jump + std::vector soln_jump_int(n_face_quad_pts); + std::vector soln_jump_ext(n_face_quad_pts); + for (unsigned int iquad=0; iquadsystem_matrix.add(soln_dof_indices_ext[itest_ext], soln_dof_indices_ext, residual_derivatives, elide_zero_values); } } - if (compute_dRdX) { - std::vector residual_derivatives(n_metric_dofs); - for (unsigned int itest_int=0; itest_int lifting_op_R_rhs_int(n_base_dofs_int); + for (unsigned int idof_base=0; idof_basedRdXv.add(soln_dof_indices_int[itest_int], metric_dof_indices_int, residual_derivatives); + for (unsigned int iquad=0; iquaddRdXv.add(soln_dof_indices_int[itest_int], metric_dof_indices_ext, residual_derivatives); + } + } - for (unsigned int itest_ext=0; itest_ext lifting_op_R_rhs_ext(n_base_dofs_ext); + for (unsigned int idof_base=0; idof_basedRdXv.add(soln_dof_indices_ext[itest_ext], metric_dof_indices_int, residual_derivatives); + for (unsigned int iquad=0; iquaddRdXv.add(soln_dof_indices_ext[itest_ext], metric_dof_indices_ext, residual_derivatives); + } } - th.deleteJacobian(jac); - } - - if (compute_d2R) { - typename TH::HessianType& hes = th.createHessian(); - th.evalHessian(hes); + std::vector soln_grad_corr_int(n_base_dofs_int), soln_grad_corr_ext(n_base_dofs_ext); + compute_br2_correction(soln_int.finite_element, metric_int, lifting_op_R_rhs_int, soln_grad_corr_int); + compute_br2_correction(soln_ext.finite_element, metric_ext, lifting_op_R_rhs_ext, soln_grad_corr_ext); - std::vector dWidW(n_soln_dofs_int); - std::vector dWidX(n_metric_dofs); - std::vector dXidX(n_metric_dofs); + correct_the_gradient( soln_grad_corr_int, soln_int.finite_element, soln_jump_int, interpolation_operator_int, gradient_operator_int, soln_grad_int); + correct_the_gradient( soln_grad_corr_ext, soln_ext.finite_element, soln_jump_ext, interpolation_operator_ext, gradient_operator_ext, soln_grad_ext); - int i_dependent = (compute_dRdW || compute_dRdX) ? n_soln_dofs_int + n_soln_dofs_ext : 0; + } - for (unsigned int idof=0; idofd2RdWdW.add(soln_dof_indices_int[idof], soln_dof_indices_int, dWidW); + DirectionalState diss_flux_jump_int; // u*-u_int + DirectionalState diss_flux_jump_ext; // u*-u_ext - // dWint_dWext - for (unsigned int jdof=0; jdofd2RdWdW.add(soln_dof_indices_int[idof], soln_dof_indices_ext, dWidW); + for (unsigned int iquad=0; iquadd2RdWdX.add(soln_dof_indices_int[idof], metric_dof_indices_int, dWidX); + // Evaluate physical convective flux, physical dissipative flux, and source term + conv_num_flux_dot_n = conv_num_flux.evaluate_flux(soln_int_at_q[iquad], soln_ext_at_q[iquad], phys_unit_normal_int[iquad]); + diss_soln_num_flux = diss_num_flux.evaluate_solution_flux(soln_int_at_q[iquad], soln_ext_at_q[iquad], phys_unit_normal_int[iquad]); - // dWint_dXext - for (unsigned int jdof=0; jdofd2RdWdX.add(soln_dof_indices_int[idof], metric_dof_indices_ext, dWidX); } + diss_flux_jump_int = physics.dissipative_flux (soln_int_at_q[iquad], diss_soln_jump_int, current_cell_index); + diss_flux_jump_ext = physics.dissipative_flux (soln_ext_at_q[iquad], diss_soln_jump_ext, neighbor_cell_index); - for (unsigned int idof=0; idofd2RdXdX.add(metric_dof_indices_int[idof], metric_dof_indices_int, dXidX); - - // dXint_dXext - for (unsigned int jdof=0; jdofall_parameters->artificial_dissipation_param.add_artificial_dissipation) { + const DirectionalState artificial_diss_flux_jump_int = DGBaseState::artificial_dissip->calc_artificial_dissipation_flux(soln_int_at_q[iquad], diss_soln_jump_int,artificial_diss_coeff_at_q[iquad]); + const DirectionalState artificial_diss_flux_jump_ext = DGBaseState::artificial_dissip->calc_artificial_dissipation_flux(soln_ext_at_q[iquad], diss_soln_jump_ext,artificial_diss_coeff_at_q[iquad]); + for (int s=0; sd2RdXdX.add(metric_dof_indices_int[idof], metric_dof_indices_ext, dXidX); } - dWidW.resize(n_soln_dofs_ext); - - for (unsigned int idof=0; idofd2RdWdW.add(soln_dof_indices_ext[idof], soln_dof_indices_int, dWidW); + diss_auxi_num_flux_dot_n = diss_num_flux.evaluate_auxiliary_flux( + current_cell_index, + neighbor_cell_index, + artificial_diss_coeff_at_q[iquad], + artificial_diss_coeff_at_q[iquad], + soln_int_at_q[iquad], soln_ext_at_q[iquad], + soln_grad_int[iquad], soln_grad_ext[iquad], + phys_unit_normal_int[iquad], penalty); - // dWext_dWext - for (unsigned int jdof=0; jdofd2RdWdW.add(soln_dof_indices_ext[idof], soln_dof_indices_ext, dWidW); + // From test functions associated with interior cell point of view + for (unsigned int itest_int=0; itest_intd2RdWdX.add(soln_dof_indices_ext[idof], metric_dof_indices_int, dWidX); - // dWext_dXext - for (unsigned int jdof=0; jdofd2RdWdX.add(soln_dof_indices_ext[idof], metric_dof_indices_ext, dWidX); + rhs_int[itest_int] += rhs; + dual_dot_residual += dual_int[itest_int]*rhs; } - for (unsigned int idof=0; idofd2RdXdX.add(metric_dof_indices_ext[idof], metric_dof_indices_int, dXidX); - for (unsigned int jdof=0; jdofd2RdXdX.add(metric_dof_indices_ext[idof], metric_dof_indices_ext, dXidX); + rhs_ext[itest_ext] += rhs; + dual_dot_residual += dual_ext[itest_ext]*rhs; } - - th.deleteHessian(hes); - } - - for (unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) { - adtype::getGlobalTape().deactivateValue(soln_int.coefficients[idof]); - } - for (unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) { - adtype::getGlobalTape().deactivateValue(soln_ext.coefficients[idof]); - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - adtype::getGlobalTape().deactivateValue(metric_int.coefficients[idof]); - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - adtype::getGlobalTape().deactivateValue(metric_ext.coefficients[idof]); - } + } // Quadrature point loop } -template -void DGWeak::assemble_face_residual( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const std::pair face_subface_int, - const std::pair face_subface_ext, - const typename dealii::QProjector::DataSetDescriptor face_data_set_int, - const typename dealii::QProjector::DataSetDescriptor face_data_set_ext, - const dealii::FEFaceValuesBase &fe_values_int, - const dealii::FEFaceValuesBase &fe_values_ext, - const real penalty, - const dealii::FESystem &fe_int, - const dealii::FESystem &fe_ext, - const dealii::Quadrature &face_quadrature, - const std::vector &metric_dof_indices_int, - const std::vector &metric_dof_indices_ext, - const std::vector &soln_dof_indices_int, - const std::vector &soln_dof_indices_ext, - const Physics::PhysicsBase &physics, - const NumericalFlux::NumericalFluxConvective &conv_num_flux, - const NumericalFlux::NumericalFluxDissipative &diss_num_flux, - dealii::Vector &local_rhs_int_cell, - dealii::Vector &local_rhs_ext_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) -{ - const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; - const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; - const unsigned int n_soln_dofs_int = fe_int.dofs_per_cell; - const unsigned int n_soln_dofs_ext = fe_ext.dofs_per_cell; - - AssertDimension (n_soln_dofs_int, soln_dof_indices_int.size()); - AssertDimension (n_soln_dofs_ext, soln_dof_indices_ext.size()); - - LocalSolution soln_int(fe_int); - LocalSolution soln_ext(fe_ext); - LocalSolution metric_int(fe_metric); - LocalSolution metric_ext(fe_metric); - - for (unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) { - const real val = this->solution(soln_dof_indices_int[idof]); - soln_int.coefficients[idof] = val; - } - for (unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) { - const real val = this->solution(soln_dof_indices_ext[idof]); - soln_ext.coefficients[idof] = val; - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const real val = this->high_order_grid->volume_nodes[metric_dof_indices_int[idof]]; - metric_int.coefficients[idof] = val; - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const real val = this->high_order_grid->volume_nodes[metric_dof_indices_ext[idof]]; - metric_ext.coefficients[idof] = val; - } - - std::vector dual_int(n_soln_dofs_int); - std::vector dual_ext(n_soln_dofs_ext); - - for (unsigned int itest=0; itestdual[global_residual_row]; - } - for (unsigned int itest=0; itestdual[global_residual_row]; - } - - std::vector rhs_int(n_soln_dofs_int); - std::vector rhs_ext(n_soln_dofs_ext); - real dual_dot_residual; - - assemble_face_term( - cell, - current_cell_index, - neighbor_cell_index, - soln_int, soln_ext, metric_int, metric_ext, - dual_int, - dual_ext, - face_subface_int, - face_subface_ext, - face_data_set_int, - face_data_set_ext, - physics, - conv_num_flux, - diss_num_flux, - fe_values_int, - fe_values_ext, - penalty, - face_quadrature, - rhs_int, - rhs_ext, - dual_dot_residual, - compute_dRdW, compute_dRdX, compute_d2R); - - for (unsigned int itest_int=0; itest_int(rhs_int[itest_int]); - } - for (unsigned int itest_ext=0; itest_ext(rhs_ext[itest_ext]); - } - -} -#endif template template @@ -3042,614 +1645,62 @@ void DGWeak::assemble_volume_term( // is negative. Therefore, negative of negative means we add that volume term to the right-hand-side for (unsigned int itest=0; itestall_parameters->manufactured_convergence_study_param.manufactured_solution_param.use_manufactured_source_term) { - rhs[itest] = rhs[itest] + interpolation_operator[itest][iquad]* source_at_q[iquad][istate] * JxW_iquad; - } - } - dual_dot_residual += local_dual[itest]*rhs[itest]; - } -} - -#ifdef FADFAD -template -void DGWeak::assemble_volume_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::FEValues &fe_values_vol, - const dealii::FESystem &fe_soln, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - dealii::Vector &local_rhs_cell, - const dealii::FEValues &/*fe_values_lagrange*/, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) -{ - (void) current_cell_index; - - using ADArray = std::array; - using ADArrayTensor1 = std::array< dealii::Tensor<1,dim,FadFadType>, nstate >; - - const unsigned int n_soln_dofs = fe_soln.dofs_per_cell; - - AssertDimension (n_soln_dofs, soln_dof_indices.size()); - - const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; - const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; - - std::vector coords_coeff(n_metric_dofs); - std::vector soln_coeff(n_soln_dofs); - - std::vector local_dual(n_soln_dofs); - for (unsigned int itest=0; itestdual[global_residual_row]; - } - - (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R; - const bool compute_metric_derivatives = true;//(!compute_dRdX && !compute_d2R) ? false : true; - - unsigned int w_start, w_end, x_start, x_end; - automatic_differentiation_indexing_1( compute_dRdW, compute_dRdX, compute_d2R, - n_soln_dofs, n_metric_dofs, - w_start, w_end, x_start, x_end ); - - unsigned int i_derivative = 0; - const unsigned int n_total_indep = x_end; - - for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { - const real val = this->solution(soln_dof_indices[idof]); - soln_coeff[idof] = val; - soln_coeff[idof].val() = val; - - if (compute_dRdW || compute_d2R) soln_coeff[idof].diff(i_derivative, n_total_indep); - if (compute_d2R) soln_coeff[idof].val().diff(i_derivative, n_total_indep); - - if (compute_dRdW || compute_d2R) i_derivative++; - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const real val = this->high_order_grid->volume_nodes[metric_dof_indices[idof]]; - coords_coeff[idof] = val; - coords_coeff[idof].val() = val; - - if (compute_dRdX || compute_d2R) coords_coeff[idof].diff(i_derivative, n_total_indep); - if (compute_d2R) coords_coeff[idof].val().diff(i_derivative, n_total_indep); - - if (compute_dRdX || compute_d2R) i_derivative++; - } - - AssertDimension(i_derivative, n_total_indep); - - FadFadType dual_dot_residual = 0.0; - std::vector rhs(n_soln_dofs); - assemble_volume_term( - cell, - current_cell_index, - soln_coeff, coords_coeff, local_dual, - fe_soln, fe_metric, quadrature, - *(DGBaseState::pde_physics_fad_fad), - rhs, dual_dot_residual, - compute_metric_derivatives, fe_values_vol); - - // Weak form - // The right-hand side sends all the term to the side of the source term - // Therefore, - // \divergence ( Fconv + Fdiss ) = source - // has the right-hand side - // rhs = - \divergence( Fconv + Fdiss ) + source - // Since we have done an integration by parts, the volume term resulting from the divergence of Fconv and Fdiss - // is negative. Therefore, negative of negative means we add that volume term to the right-hand-side - for (unsigned int itest=0; itest residual_derivatives(n_soln_dofs); - for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { - const unsigned int i_dx = idof+w_start; - residual_derivatives[idof] = rhs[itest].dx(i_dx).val(); - AssertIsFinite(residual_derivatives[idof]); - } - const bool elide_zero_values = false; - this->system_matrix.add(soln_dof_indices[itest], soln_dof_indices, residual_derivatives, elide_zero_values); - } - if (compute_dRdX) { - std::vector residual_derivatives(n_metric_dofs); - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const unsigned int i_dx = idof+x_start; - residual_derivatives[idof] = rhs[itest].dx(i_dx).val(); - } - this->dRdXv.add(soln_dof_indices[itest], metric_dof_indices, residual_derivatives); - } - //if (compute_d2R) { - // const unsigned int global_residual_row = soln_dof_indices[itest]; - // dual_dot_residual += this->dual[global_residual_row]*rhs[itest]; - //} - - local_rhs_cell(itest) += rhs[itest].val().val(); - AssertIsFinite(local_rhs_cell(itest)); - - } - - - if (compute_d2R) { - - std::vector dWidW(n_soln_dofs); - std::vector dWidX(n_metric_dofs); - std::vector dXidX(n_metric_dofs); - - for (unsigned int idof=0; idofd2RdWdW.add(soln_dof_indices[idof], soln_dof_indices, dWidW); - - for (unsigned int jdof=0; jdofd2RdWdX.add(soln_dof_indices[idof], metric_dof_indices, dWidX); - } - - for (unsigned int idof=0; idofd2RdXdX.add(metric_dof_indices[idof], metric_dof_indices, dXidX); - } - } - -} -#endif -#ifndef FADFAD -template -template -void DGWeak::assemble_volume_codi_taped_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::FEValues &fe_values_vol, - const dealii::FESystem &fe_soln, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - dealii::Vector &local_rhs_cell, - const dealii::FEValues &fe_values_lagrange, - const Physics::PhysicsBase &physics, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) -{ - (void) fe_values_lagrange; - - using adtype = real2; - - const unsigned int n_soln_dofs = fe_soln.dofs_per_cell; - - AssertDimension (n_soln_dofs, soln_dof_indices.size()); - - const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; - const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; - - LocalSolution local_solution(fe_soln); - LocalSolution local_metric(fe_metric); - - std::vector local_dual(n_soln_dofs); - for (unsigned int itest=0; itestdual[global_residual_row]; - } - - (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R; - const bool compute_metric_derivatives = true;//(!compute_dRdX && !compute_d2R) ? false : true; - - unsigned int w_start, w_end, x_start, x_end; - automatic_differentiation_indexing_1( compute_dRdW, compute_dRdX, compute_d2R, - n_soln_dofs, n_metric_dofs, - w_start, w_end, x_start, x_end ); - - using TH = codi::TapeHelper; - TH th; - adtype::getGlobalTape(); - if (compute_dRdW || compute_dRdX || compute_d2R) { - th.startRecording(); - } - for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { - const real val = this->solution(soln_dof_indices[idof]); - local_solution.coefficients[idof] = val; - - if (compute_dRdW || compute_d2R) { - th.registerInput(local_solution.coefficients[idof]); - } else { - adtype::getGlobalTape().deactivateValue(local_solution.coefficients[idof]); - } - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const real val = this->high_order_grid->volume_nodes[metric_dof_indices[idof]]; - local_metric.coefficients[idof] = val; - - if (compute_dRdX || compute_d2R) { - th.registerInput(local_metric.coefficients[idof]); - } else { - adtype::getGlobalTape().deactivateValue(local_metric.coefficients[idof]); - } - } - - adtype dual_dot_residual = 0.0; - std::vector rhs(n_soln_dofs); - assemble_volume_term( - cell, - current_cell_index, - local_solution, local_metric, - local_dual, - quadrature, - physics, - rhs, dual_dot_residual, - compute_metric_derivatives, fe_values_vol); - - if (compute_dRdW || compute_dRdX) { - for (unsigned int itest=0; itest(rhs[itest]); - AssertIsFinite(local_rhs_cell(itest)); - } - - if (compute_dRdW) { - typename TH::JacobianType& jac = th.createJacobian(); - th.evalJacobian(jac); - for (unsigned int itest=0; itest residual_derivatives(n_soln_dofs); - for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { - const unsigned int i_dx = idof+w_start; - residual_derivatives[idof] = jac(itest,i_dx); - AssertIsFinite(residual_derivatives[idof]); - } - const bool elide_zero_values = false; - this->system_matrix.add(soln_dof_indices[itest], soln_dof_indices, residual_derivatives, elide_zero_values); - } - th.deleteJacobian(jac); - - } - - if (compute_dRdX) { - typename TH::JacobianType& jac = th.createJacobian(); - th.evalJacobian(jac); - for (unsigned int itest=0; itest residual_derivatives(n_metric_dofs); - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const unsigned int i_dx = idof+x_start; - residual_derivatives[idof] = jac(itest,i_dx); - } - this->dRdXv.add(soln_dof_indices[itest], metric_dof_indices, residual_derivatives); - } - th.deleteJacobian(jac); - } - - - if (compute_d2R) { - typename TH::HessianType& hes = th.createHessian(); - th.evalHessian(hes); - - int i_dependent = (compute_dRdW || compute_dRdX) ? n_soln_dofs : 0; - - std::vector dWidW(n_soln_dofs); - std::vector dWidX(n_metric_dofs); - std::vector dXidX(n_metric_dofs); + const unsigned int istate = local_solution.finite_element.system_to_component_index(itest).first; - for (unsigned int idof=0; idofd2RdWdW.add(soln_dof_indices[idof], soln_dof_indices, dWidW); - - for (unsigned int jdof=0; jdofd2RdWdX.add(soln_dof_indices[idof], metric_dof_indices, dWidX); - } - - for (unsigned int idof=0; idofall_parameters->manufactured_convergence_study_param.manufactured_solution_param.use_manufactured_source_term) { + rhs[itest] = rhs[itest] + interpolation_operator[itest][iquad]* source_at_q[iquad][istate] * JxW_iquad; } - this->d2RdXdX.add(metric_dof_indices[idof], metric_dof_indices, dXidX); } - - th.deleteHessian(hes); - } - - for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { - adtype::getGlobalTape().deactivateValue(local_solution.coefficients[idof]); - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - adtype::getGlobalTape().deactivateValue(local_metric.coefficients[idof]); + dual_dot_residual += local_dual[itest]*rhs[itest]; } - } -template -void DGWeak::assemble_volume_residual( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::FEValues &fe_values_vol, - const dealii::FESystem &fe_soln, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - dealii::Vector &local_rhs_cell, - const dealii::FEValues &fe_values_lagrange, - const Physics::PhysicsBase &physics, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) -{ - (void) fe_values_lagrange; - (void) compute_dRdW; - (void) compute_dRdX; - (void) compute_d2R; - assert( !compute_dRdW && !compute_dRdX && !compute_d2R); - (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R; - const bool compute_metric_derivatives = true;//(!compute_dRdX && !compute_d2R) ? false : true; - - const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; - const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; - const unsigned int n_soln_dofs = fe_soln.dofs_per_cell; - - AssertDimension (n_soln_dofs, soln_dof_indices.size()); - - LocalSolution local_solution(fe_soln); - LocalSolution local_metric(fe_metric); - - std::vector local_dual(n_soln_dofs); - for (unsigned int itest=0; itestdual[global_residual_row]; - } - - for (unsigned int idof = 0; idof < n_soln_dofs; ++idof) { - const real val = this->solution(soln_dof_indices[idof]); - local_solution.coefficients[idof] = val; - } - for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { - const real val = this->high_order_grid->volume_nodes[metric_dof_indices[idof]]; - local_metric.coefficients[idof] = val; - } - - double dual_dot_residual = 0.0; - std::vector rhs(n_soln_dofs); - assemble_volume_term( - cell, - current_cell_index, - local_solution, local_metric, local_dual, - quadrature, - physics, - rhs, dual_dot_residual, - compute_metric_derivatives, fe_values_vol); - - for (unsigned int itest=0; itest(rhs[itest]); - AssertIsFinite(local_rhs_cell(itest)); - } -} template -void DGWeak::assemble_volume_term_derivatives( +template +void DGWeak::assemble_volume_term_and_build_operators_ad_templated( typename dealii::DoFHandler::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, - const dealii::FEValues &fe_values_vol, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &/*aux_soln_coeffs*/, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const std::vector &soln_dofs_indices, + const std::vector &metric_dofs_indices, + const unsigned int poly_degree, + const unsigned int grid_degree, + const Physics::PhysicsBase &physics, + OPERATOR::basis_functions &/*soln_basis*/, + OPERATOR::basis_functions &/*flux_basis*/, + OPERATOR::local_basis_stiffness &/*flux_basis_stiffness*/, + OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_int*/, + OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_ext*/, + OPERATOR::metric_operators &/*metric_oper*/, + OPERATOR::mapping_shape_functions &/*mapping_basis*/, + std::array,dim> &/*mapping_support_points*/, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, const dealii::FESystem &fe_soln, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - dealii::Vector &local_rhs_cell, - const dealii::FEValues &fe_values_lagrange, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) -{ - (void) current_cell_index; - (void) fe_values_lagrange; - if (compute_d2R) { - assemble_volume_codi_taped_derivatives( - cell, - current_cell_index, - fe_values_vol, - fe_soln, quadrature, - metric_dof_indices, soln_dof_indices, - local_rhs_cell, - fe_values_lagrange, - *(DGBaseState::pde_physics_rad_fad), - compute_dRdW, compute_dRdX, compute_d2R); - } else if (compute_dRdW || compute_dRdX) { - assemble_volume_codi_taped_derivatives( - cell, - current_cell_index, - fe_values_vol, - fe_soln, quadrature, - metric_dof_indices, soln_dof_indices, - local_rhs_cell, - fe_values_lagrange, - *(DGBaseState::pde_physics_rad), - compute_dRdW, compute_dRdX, compute_d2R); - } else { - assemble_volume_residual( - cell, - current_cell_index, - fe_values_vol, - fe_soln, quadrature, - metric_dof_indices, soln_dof_indices, - local_rhs_cell, - fe_values_lagrange, - *(DGBaseState::pde_physics_double), - compute_dRdW, compute_dRdX, compute_d2R); - } -} - -template -void DGWeak::assemble_face_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const std::pair face_subface_int, - const std::pair face_subface_ext, - const typename dealii::QProjector::DataSetDescriptor face_data_set_int, - const typename dealii::QProjector::DataSetDescriptor face_data_set_ext, - const dealii::FEFaceValuesBase &fe_values_int, - const dealii::FEFaceValuesBase &fe_values_ext, - const real penalty, - const dealii::FESystem &fe_int, - const dealii::FESystem &fe_ext, - const dealii::Quadrature &face_quadrature, - const std::vector &metric_dof_indices_int, - const std::vector &metric_dof_indices_ext, - const std::vector &soln_dof_indices_int, - const std::vector &soln_dof_indices_ext, - dealii::Vector &local_rhs_int_cell, - dealii::Vector &local_rhs_ext_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) -{ - (void) current_cell_index; - (void) neighbor_cell_index; - if (compute_d2R) { - assemble_face_codi_taped_derivatives( - cell, - current_cell_index, - neighbor_cell_index, - face_subface_int, - face_subface_ext, - face_data_set_int, - face_data_set_ext, - fe_values_int, - fe_values_ext, - penalty, - fe_int, - fe_ext, - face_quadrature, - metric_dof_indices_int, - metric_dof_indices_ext, - soln_dof_indices_int, - soln_dof_indices_ext, - *(DGBaseState::pde_physics_rad_fad), - *(DGBaseState::conv_num_flux_rad_fad), - *(DGBaseState::diss_num_flux_rad_fad), - local_rhs_int_cell, - local_rhs_ext_cell, - compute_dRdW, compute_dRdX, compute_d2R); - } else if (compute_dRdW || compute_dRdX) { - assemble_face_codi_taped_derivatives( - cell, - current_cell_index, - neighbor_cell_index, - face_subface_int, - face_subface_ext, - face_data_set_int, - face_data_set_ext, - fe_values_int, - fe_values_ext, - penalty, - fe_int, - fe_ext, - face_quadrature, - metric_dof_indices_int, - metric_dof_indices_ext, - soln_dof_indices_int, - soln_dof_indices_ext, - *(DGBaseState::pde_physics_rad), - *(DGBaseState::conv_num_flux_rad), - *(DGBaseState::diss_num_flux_rad), - local_rhs_int_cell, - local_rhs_ext_cell, - compute_dRdW, compute_dRdX, compute_d2R); - } else { - assemble_face_residual( - cell, - current_cell_index, - neighbor_cell_index, - face_subface_int, - face_subface_ext, - face_data_set_int, - face_data_set_ext, - fe_values_int, - fe_values_ext, - penalty, - fe_int, - fe_ext, - face_quadrature, - metric_dof_indices_int, - metric_dof_indices_ext, - soln_dof_indices_int, - soln_dof_indices_ext, - *(DGBaseState::pde_physics_double), - *(DGBaseState::conv_num_flux_double), - *(DGBaseState::diss_num_flux_double), - local_rhs_int_cell, - local_rhs_ext_cell, - compute_dRdW, compute_dRdX, compute_d2R); - } -} -#endif - - -template -void DGWeak::assemble_volume_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const std::vector &cell_dofs_indices, - const std::vector &metric_dof_indices, - const unsigned int poly_degree, - const unsigned int grid_degree, - OPERATOR::basis_functions &/*soln_basis*/, - OPERATOR::basis_functions &/*flux_basis*/, - OPERATOR::local_basis_stiffness &/*flux_basis_stiffness*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_int*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_ext*/, - OPERATOR::metric_operators &/*metric_oper*/, - OPERATOR::mapping_shape_functions &/*mapping_basis*/, - std::array,dim> &/*mapping_support_points*/, - dealii::hp::FEValues &fe_values_collection_volume, - dealii::hp::FEValues &fe_values_collection_volume_lagrange, - const dealii::FESystem ¤t_fe_ref, - dealii::Vector &local_rhs_int_cell, - std::vector> &/*local_auxiliary_RHS*/, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &/*local_auxiliary_RHS*/, const bool /*compute_auxiliary_right_hand_side*/, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) + adtype &dual_dot_residual) { // Current reference element related to this physical cell const int i_fele = cell->active_fe_index(); @@ -3659,218 +1710,210 @@ void DGWeak::assemble_volume_term_and_build_operators( dealii::TriaIterator> cell_iterator = static_cast> > (cell); fe_values_collection_volume_lagrange.reinit (cell_iterator, i_quad, i_mapp, i_fele); - const dealii::FEValues &fe_values_volume = fe_values_collection_volume.get_present_fe_values(); + const dealii::FEValues &fe_values_vol = fe_values_collection_volume.get_present_fe_values(); const dealii::FEValues &fe_values_lagrange = fe_values_collection_volume_lagrange.get_present_fe_values(); + + const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; + const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; + const unsigned int n_soln_dofs = fe_soln.dofs_per_cell; + + dealii::Vector local_rhs_dummy (n_soln_dofs); //Note the explicit is called first to set the max_dt_cell to a non-zero value. assemble_volume_term_explicit ( cell, current_cell_index, - fe_values_volume, - cell_dofs_indices, - metric_dof_indices, + fe_values_vol, + soln_dofs_indices, + metric_dofs_indices, poly_degree, grid_degree, - local_rhs_int_cell, + local_rhs_dummy, fe_values_lagrange); - //set current rhs to zero since the explicit call was just to set the max_dt_cell. - local_rhs_int_cell*=0.0; - assemble_volume_term_derivatives ( - cell, - current_cell_index, - fe_values_volume, current_fe_ref, this->volume_quadrature_collection[i_quad], - metric_dof_indices, cell_dofs_indices, - local_rhs_int_cell, fe_values_lagrange, - compute_dRdW, compute_dRdX, compute_d2R); -} + const dealii::Quadrature &quadrature = this->volume_quadrature_collection[i_quad]; + -template -void DGWeak::assemble_boundary_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const unsigned int iface, - const unsigned int boundary_id, - const real penalty, - const std::vector &cell_dofs_indices, - const std::vector &metric_dof_indices, - const unsigned int /*poly_degree*/, - const unsigned int /*grid_degree*/, - OPERATOR::basis_functions &/*soln_basis*/, - OPERATOR::basis_functions &/*flux_basis*/, - OPERATOR::local_basis_stiffness &/*flux_basis_stiffness*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_int*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_ext*/, - OPERATOR::metric_operators &/*metric_oper*/, - OPERATOR::mapping_shape_functions &/*mapping_basis*/, - std::array,dim> &/*mapping_support_points*/, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - const dealii::FESystem ¤t_fe_ref, - dealii::Vector &local_rhs_int_cell, - std::vector> &/*local_auxiliary_RHS*/, - const bool /*compute_auxiliary_right_hand_side*/, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) -{ - // Current reference element related to this physical cell - const int i_fele = cell->active_fe_index(); - const int i_quad = i_fele; - const int i_mapp = 0; + LocalSolution local_solution(fe_soln); + LocalSolution local_metric(fe_metric); + for(unsigned int i=0; i &fe_values_face_int = fe_values_collection_face_int.get_present_fe_values(); - const dealii::Quadrature face_quadrature = this->face_quadrature_collection[i_quad]; - assemble_boundary_term_derivatives ( + const bool compute_metric_derivatives = true; + + assemble_volume_term( cell, current_cell_index, - iface, boundary_id, fe_values_face_int, penalty, - current_fe_ref, face_quadrature, - metric_dof_indices, cell_dofs_indices, local_rhs_int_cell, - compute_dRdW, compute_dRdX, compute_d2R); + local_solution, local_metric, + local_dual, + quadrature, + physics, + rhs, dual_dot_residual, + compute_metric_derivatives, fe_values_vol); } template -void DGWeak::assemble_face_term_and_build_operators( +template +void DGWeak::assemble_boundary_term_and_build_operators_ad_templated( typename dealii::DoFHandler::active_cell_iterator cell, - typename dealii::DoFHandler::active_cell_iterator neighbor_cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const unsigned int iface, - const unsigned int neighbor_iface, - const real penalty, - const std::vector ¤t_dofs_indices, - const std::vector &neighbor_dofs_indices, - const std::vector ¤t_metric_dofs_indices, - const std::vector &neighbor_metric_dofs_indices, - const unsigned int /*poly_degree_int*/, - const unsigned int /*poly_degree_ext*/, - const unsigned int /*grid_degree_int*/, - const unsigned int /*grid_degree_ext*/, - OPERATOR::basis_functions &/*soln_basis_int*/, - OPERATOR::basis_functions &/*soln_basis_ext*/, - OPERATOR::basis_functions &/*flux_basis_int*/, - OPERATOR::basis_functions &/*flux_basis_ext*/, - OPERATOR::local_basis_stiffness &/*flux_basis_stiffness*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_int*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_ext*/, - OPERATOR::metric_operators &/*metric_oper_int*/, - OPERATOR::metric_operators &/*metric_oper_ext*/, - OPERATOR::mapping_shape_functions &/*mapping_basis*/, - std::array,dim> &/*mapping_support_points*/, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - dealii::hp::FEFaceValues &fe_values_collection_face_ext, - dealii::Vector ¤t_cell_rhs, - dealii::Vector &neighbor_cell_rhs, - std::vector> &/*current_cell_rhs_aux*/, - dealii::LinearAlgebra::distributed::Vector &rhs, - std::array,dim> &/*rhs_aux*/, - const bool /*compute_auxiliary_right_hand_side*/, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &/*aux_soln_coeffs*/, + const std::vector &metric_coeffs, + const std::vector< real > &local_dual, + const unsigned int face_number, + const unsigned int boundary_id, + const Physics::PhysicsBase &physics, + const NumericalFlux::NumericalFluxConvective &conv_num_flux, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + const unsigned int /*poly_degree*/, + const unsigned int /*grid_degree*/, + OPERATOR::basis_functions &/*soln_basis*/, + OPERATOR::basis_functions &/*flux_basis*/, + OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_int*/, + OPERATOR::metric_operators &/*metric_oper*/, + OPERATOR::mapping_shape_functions &/*mapping_basis*/, + std::array,dim> &/*mapping_support_points*/, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + const dealii::FESystem &fe_soln, + const real penalty, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &/*local_auxiliary_RHS*/, + const bool /*compute_auxiliary_right_hand_side*/, + adtype &dual_dot_residual) { // Current reference element related to this physical cell const int i_fele = cell->active_fe_index(); const int i_quad = i_fele; const int i_mapp = 0; - const int i_fele_n = neighbor_cell->active_fe_index(), i_quad_n = i_fele_n, i_mapp_n = 0; - - fe_values_collection_face_int.reinit (cell, iface, i_quad, i_mapp, i_fele); - fe_values_collection_face_ext.reinit (neighbor_cell, neighbor_iface, i_quad_n, i_mapp_n, i_fele_n); - //only need to compute fevalues for the weak form. - const dealii::FEFaceValues &fe_values_face_int = fe_values_collection_face_int.get_present_fe_values(); - const dealii::FEFaceValues &fe_values_face_ext = fe_values_collection_face_ext.get_present_fe_values(); - const dealii::Quadrature &used_face_quadrature = this->face_quadrature_collection[(i_quad_n > i_quad) ? i_quad_n : i_quad]; // Use larger quadrature order on the face + fe_values_collection_face_int.reinit (cell, face_number, i_quad, i_mapp, i_fele); + const dealii::FEFaceValues &fe_values_boundary = fe_values_collection_face_int.get_present_fe_values(); + const dealii::Quadrature quadrature = this->face_quadrature_collection[i_quad]; + + const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; + const unsigned int n_soln_dofs = fe_values_boundary.dofs_per_cell; + const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; + LocalSolution local_solution(fe_soln); + LocalSolution local_metric(fe_metric); + for(unsigned int i=0; i face_subface_int = std::make_pair(iface, -1); - std::pair face_subface_ext = std::make_pair(neighbor_iface, -1); - const auto face_data_set_int = dealii::QProjector::DataSetDescriptor::face ( - dealii::ReferenceCell::get_hypercube(dim), - iface, - cell->face_orientation(iface), - cell->face_flip(iface), - cell->face_rotation(iface), - used_face_quadrature.size()); - const auto face_data_set_ext = dealii::QProjector::DataSetDescriptor::face ( - dealii::ReferenceCell::get_hypercube(dim), - neighbor_iface, - neighbor_cell->face_orientation(neighbor_iface), - neighbor_cell->face_flip(neighbor_iface), - neighbor_cell->face_rotation(neighbor_iface), - used_face_quadrature.size()); - - assemble_face_term_derivatives ( + assemble_boundary_term( cell, current_cell_index, - neighbor_cell_index, - face_subface_int, face_subface_ext, - face_data_set_int, - face_data_set_ext, - fe_values_face_int, fe_values_face_ext, + local_solution, + local_metric, + local_dual, + face_number, + boundary_id, + physics, + conv_num_flux, + diss_num_flux, + fe_values_boundary, penalty, - this->fe_collection[i_fele], this->fe_collection[i_fele_n], - used_face_quadrature, - current_metric_dofs_indices, neighbor_metric_dofs_indices, - current_dofs_indices, neighbor_dofs_indices, - current_cell_rhs, neighbor_cell_rhs, - compute_dRdW, compute_dRdX, compute_d2R); - - // Add local contribution from neighbor cell to global vector - const unsigned int n_dofs_neigh_cell = this->fe_collection[neighbor_cell->active_fe_index()].n_dofs_per_cell(); - for (unsigned int i=0; i -void DGWeak::assemble_subface_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator cell, - typename dealii::DoFHandler::active_cell_iterator neighbor_cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const unsigned int iface, - const unsigned int neighbor_iface, - const unsigned int neighbor_i_subface, - const real penalty, - const std::vector ¤t_dofs_indices, - const std::vector &neighbor_dofs_indices, - const std::vector ¤t_metric_dofs_indices, - const std::vector &neighbor_metric_dofs_indices, - const unsigned int /*poly_degree_int*/, - const unsigned int /*poly_degree_ext*/, - const unsigned int /*grid_degree_int*/, - const unsigned int /*grid_degree_ext*/, - OPERATOR::basis_functions &/*soln_basis_int*/, - OPERATOR::basis_functions &/*soln_basis_ext*/, - OPERATOR::basis_functions &/*flux_basis_int*/, - OPERATOR::basis_functions &/*flux_basis_ext*/, - OPERATOR::local_basis_stiffness &/*flux_basis_stiffness*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_int*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_ext*/, - OPERATOR::metric_operators &/*metric_oper_int*/, - OPERATOR::metric_operators &/*metric_oper_ext*/, - OPERATOR::mapping_shape_functions &/*mapping_basis*/, - std::array,dim> &/*mapping_support_points*/, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - dealii::hp::FESubfaceValues &fe_values_collection_subface, - dealii::Vector ¤t_cell_rhs, - dealii::Vector &neighbor_cell_rhs, - std::vector> &/*current_cell_rhs_aux*/, - dealii::LinearAlgebra::distributed::Vector &rhs, - std::array,dim> &/*rhs_aux*/, - const bool /*compute_auxiliary_right_hand_side*/, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R) +template +void DGWeak::assemble_face_term_and_build_operators_ad_templated( + typename dealii::DoFHandler::active_cell_iterator cell, + typename dealii::DoFHandler::active_cell_iterator neighbor_cell, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const std::vector &soln_int, + const std::vector &soln_ext, + const dealii::Tensor<1,dim,std::vector> &/*aux_soln_coeff_int*/, + const dealii::Tensor<1,dim,std::vector> &/*aux_soln_coeff_ext*/, + const std::vector &metric_int, + const std::vector &metric_ext, + const std::vector< double > &dual_int, + const std::vector< double > &dual_ext, + const unsigned int /*poly_degree_int*/, + const unsigned int /*poly_degree_ext*/, + const unsigned int /*grid_degree_int*/, + const unsigned int /*grid_degree_ext*/, + OPERATOR::basis_functions &/*soln_basis_int*/, + OPERATOR::basis_functions &/*soln_basis_ext*/, + OPERATOR::basis_functions &/*flux_basis_int*/, + OPERATOR::basis_functions &/*flux_basis_ext*/, + OPERATOR::local_basis_stiffness &/*flux_basis_stiffness*/, + OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_int*/, + OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_ext*/, + OPERATOR::metric_operators &/*metric_oper_int*/, + OPERATOR::metric_operators &/*metric_oper_ext*/, + OPERATOR::mapping_shape_functions &/*mapping_basis*/, + std::array,dim> &/*mapping_support_points*/, + const Physics::PhysicsBase &physics, + const NumericalFlux::NumericalFluxConvective &conv_num_flux, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + const dealii::FESystem &fe_int, + const dealii::FESystem &fe_ext, + const real penalty, + std::vector &rhs_int, + std::vector &rhs_ext, + dealii::Tensor<1,dim,std::vector> &/*aux_rhs_int*/, + dealii::Tensor<1,dim,std::vector> &/*aux_rhs_ext*/, + const bool /*compute_auxiliary_right_hand_side*/, + adtype &dual_dot_residual, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + const bool is_a_subface, + const unsigned int neighbor_i_subface) { - // Current reference element related to this physical cell + const dealii::FESystem &fe_metric = this->high_order_grid->fe_system; + const unsigned int n_metric_dofs = fe_metric.dofs_per_cell; + const unsigned int n_soln_dofs_int = fe_int.dofs_per_cell; + const unsigned int n_soln_dofs_ext = fe_ext.dofs_per_cell; + const int i_fele = cell->active_fe_index(); const int i_quad = i_fele; const int i_mapp = 0; - const int i_fele_n = neighbor_cell->active_fe_index(), i_quad_n = i_fele_n, i_mapp_n = 0; + const int i_fele_n = neighbor_cell->active_fe_index(); + const int i_quad_n = i_fele_n; + const int i_mapp_n = 0; fe_values_collection_face_int.reinit (cell, iface, i_quad, i_mapp, i_fele); - fe_values_collection_subface.reinit (neighbor_cell, neighbor_iface, neighbor_i_subface, i_quad_n, i_mapp_n, i_fele_n); - const dealii::FEFaceValues &fe_values_face_int = fe_values_collection_face_int.get_present_fe_values(); - const dealii::FESubfaceValues &fe_values_face_ext = fe_values_collection_subface.get_present_fe_values(); - const dealii::Quadrature &used_face_quadrature = this->face_quadrature_collection[(i_quad_n > i_quad) ? i_quad_n : i_quad]; // Use larger quadrature order on the face + const dealii::Quadrature &face_quadrature = this->face_quadrature_collection[(i_quad_n > i_quad) ? i_quad_n : i_quad]; // Use larger quadrature order on the face + + LocalSolution local_soln_int(fe_int); + LocalSolution local_soln_ext(fe_ext); + LocalSolution local_metric_int(fe_metric); + LocalSolution local_metric_ext(fe_metric); + + for (unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) { + local_soln_int.coefficients[idof] = soln_int[idof]; + } + for (unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) { + local_soln_ext.coefficients[idof] = soln_ext[idof]; + } + for (unsigned int idof = 0; idof < n_metric_dofs; ++idof) { + local_metric_int.coefficients[idof] = metric_int[idof]; + local_metric_ext.coefficients[idof] = metric_ext[idof]; + } + std::pair face_subface_int = std::make_pair(iface, -1); - std::pair face_subface_ext = std::make_pair(neighbor_iface, (int)neighbor_i_subface); const auto face_data_set_int = dealii::QProjector::DataSetDescriptor::face( dealii::ReferenceCell::get_hypercube(dim), @@ -3878,51 +1921,94 @@ void DGWeak::assemble_subface_term_and_build_operators cell->face_orientation(iface), cell->face_flip(iface), cell->face_rotation(iface), - used_face_quadrature.size()); - const auto face_data_set_ext = dealii::QProjector::DataSetDescriptor::subface ( - dealii::ReferenceCell::get_hypercube(dim), - neighbor_iface, - neighbor_i_subface, - neighbor_cell->face_orientation(neighbor_iface), - neighbor_cell->face_flip(neighbor_iface), - neighbor_cell->face_rotation(neighbor_iface), - used_face_quadrature.size(), - neighbor_cell->subface_case(neighbor_iface)); - - assemble_face_term_derivatives ( - cell, - current_cell_index, - neighbor_cell_index, - face_subface_int, face_subface_ext, - face_data_set_int, - face_data_set_ext, - fe_values_face_int, fe_values_face_ext, - penalty, - this->fe_collection[i_fele], this->fe_collection[i_fele_n], - used_face_quadrature, - current_metric_dofs_indices, neighbor_metric_dofs_indices, - current_dofs_indices, neighbor_dofs_indices, - current_cell_rhs, neighbor_cell_rhs, - compute_dRdW, compute_dRdX, compute_d2R); - - // Add local contribution from neighbor cell to global vector - const unsigned int n_dofs_neigh_cell = this->fe_collection[neighbor_cell->active_fe_index()].n_dofs_per_cell(); - for (unsigned int i=0; i &fe_values_face_ext = fe_values_collection_subface.get_present_fe_values(); + std::pair face_subface_ext = std::make_pair(neighbor_iface, (int)neighbor_i_subface); + const auto face_data_set_ext = dealii::QProjector::DataSetDescriptor::subface ( + dealii::ReferenceCell::get_hypercube(dim), + neighbor_iface, + neighbor_i_subface, + neighbor_cell->face_orientation(neighbor_iface), + neighbor_cell->face_flip(neighbor_iface), + neighbor_cell->face_rotation(neighbor_iface), + face_quadrature.size(), + neighbor_cell->subface_case(neighbor_iface)); + assemble_face_term( + cell, + current_cell_index, + neighbor_cell_index, + local_soln_int, local_soln_ext, local_metric_int, local_metric_ext, + dual_int, + dual_ext, + face_subface_int, + face_subface_ext, + face_data_set_int, + face_data_set_ext, + physics, + conv_num_flux, + diss_num_flux, + fe_values_face_int, + fe_values_face_ext, + penalty, + face_quadrature, + rhs_int, + rhs_ext, + dual_dot_residual, + compute_dRdW, compute_dRdX, compute_d2R); } - + else + { + fe_values_collection_face_ext.reinit (neighbor_cell, neighbor_iface, i_quad_n, i_mapp_n, i_fele_n); + const dealii::FEFaceValues &fe_values_face_ext = fe_values_collection_face_ext.get_present_fe_values(); + std::pair face_subface_ext = std::make_pair(neighbor_iface, -1); + const auto face_data_set_ext = dealii::QProjector::DataSetDescriptor::face ( + dealii::ReferenceCell::get_hypercube(dim), + neighbor_iface, + neighbor_cell->face_orientation(neighbor_iface), + neighbor_cell->face_flip(neighbor_iface), + neighbor_cell->face_rotation(neighbor_iface), + face_quadrature.size()); + assemble_face_term( + cell, + current_cell_index, + neighbor_cell_index, + local_soln_int, local_soln_ext, local_metric_int, local_metric_ext, + dual_int, + dual_ext, + face_subface_int, + face_subface_ext, + face_data_set_int, + face_data_set_ext, + physics, + conv_num_flux, + diss_num_flux, + fe_values_face_int, + fe_values_face_ext, + penalty, + face_quadrature, + rhs_int, + rhs_ext, + dual_dot_residual, + compute_dRdW, compute_dRdX, compute_d2R); + } + } template -void DGWeak::assemble_auxiliary_residual () +void DGWeak::assemble_auxiliary_residual (const bool /*compute_dRdW*/, const bool /*compute_dRdX*/, const bool /*compute_d2R*/) { //Do Nothing. } template -void DGWeak::allocate_dual_vector () +void DGWeak::allocate_dual_vector (const bool compute_d2R) { - this->dual.reinit(this->locally_owned_dofs, this->ghost_dofs, this->mpi_communicator); + if(compute_d2R) + this->dual.reinit(this->locally_owned_dofs, this->ghost_dofs, this->mpi_communicator); } // using default MeshType = Triangulation diff --git a/src/dg/weak_dg.hpp b/src/dg/weak_dg.hpp index d53d77b51..2051addbd 100644 --- a/src/dg/weak_dg.hpp +++ b/src/dg/weak_dg.hpp @@ -30,138 +30,11 @@ class DGWeak : public DGBaseState private: - /// Builds the necessary fe values and assembles volume residual. - void assemble_volume_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const std::vector &cell_dofs_indices, - const std::vector &metric_dof_indices, - const unsigned int poly_degree, - const unsigned int grid_degree, - OPERATOR::basis_functions &/*soln_basis*/, - OPERATOR::basis_functions &/*flux_basis*/, - OPERATOR::local_basis_stiffness &/*flux_basis_stiffness*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_int*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_ext*/, - OPERATOR::metric_operators &/*metric_oper*/, - OPERATOR::mapping_shape_functions &/*mapping_basis*/, - std::array,dim> &/*mapping_support_points*/, - dealii::hp::FEValues &fe_values_collection_volume, - dealii::hp::FEValues &fe_values_collection_volume_lagrange, - const dealii::FESystem ¤t_fe_ref, - dealii::Vector &local_rhs_int_cell, - std::vector> &/*local_auxiliary_RHS*/, - const bool /*compute_auxiliary_right_hand_side*/, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - - /// Builds the necessary fe values and assembles boundary residual. - void assemble_boundary_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const unsigned int iface, - const unsigned int boundary_id, - const real penalty, - const std::vector &cell_dofs_indices, - const std::vector &metric_dof_indices, - const unsigned int poly_degree, - const unsigned int grid_degree, - OPERATOR::basis_functions &/*soln_basis*/, - OPERATOR::basis_functions &/*flux_basis*/, - OPERATOR::local_basis_stiffness &/*flux_basis_stiffness*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_int*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_ext*/, - OPERATOR::metric_operators &/*metric_oper*/, - OPERATOR::mapping_shape_functions &/*mapping_basis*/, - std::array,dim> &/*mapping_support_points*/, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - const dealii::FESystem ¤t_fe_ref, - dealii::Vector &local_rhs_int_cell, - std::vector> &/*local_auxiliary_RHS*/, - const bool /*compute_auxiliary_right_hand_side*/, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - - /// Builds the necessary fe values and assembles face residual. - void assemble_face_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator cell, - typename dealii::DoFHandler::active_cell_iterator neighbor_cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const unsigned int iface, - const unsigned int neighbor_iface, - const real penalty, - const std::vector ¤t_dofs_indices, - const std::vector &neighbor_dofs_indices, - const std::vector ¤t_metric_dofs_indices, - const std::vector &neighbor_metric_dofs_indices, - const unsigned int /*poly_degree_int*/, - const unsigned int /*poly_degree_ext*/, - const unsigned int /*grid_degree_int*/, - const unsigned int /*grid_degree_ext*/, - OPERATOR::basis_functions &/*soln_basis_int*/, - OPERATOR::basis_functions &/*soln_basis_ext*/, - OPERATOR::basis_functions &/*flux_basis_int*/, - OPERATOR::basis_functions &/*flux_basis_ext*/, - OPERATOR::local_basis_stiffness &/*flux_basis_stiffness*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_int*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_ext*/, - OPERATOR::metric_operators &/*metric_oper_int*/, - OPERATOR::metric_operators &/*metric_oper_ext*/, - OPERATOR::mapping_shape_functions &/*mapping_basis*/, - std::array,dim> &/*mapping_support_points*/, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - dealii::hp::FEFaceValues &fe_values_collection_face_ext, - dealii::Vector ¤t_cell_rhs, - dealii::Vector &neighbor_cell_rhs, - std::vector> &/*current_cell_rhs_aux*/, - dealii::LinearAlgebra::distributed::Vector &rhs, - std::array,dim> &/*rhs_aux*/, - const bool /*compute_auxiliary_right_hand_side*/, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - - /// Builds the necessary fe values and assembles subface residual. - void assemble_subface_term_and_build_operators( - typename dealii::DoFHandler::active_cell_iterator cell, - typename dealii::DoFHandler::active_cell_iterator neighbor_cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const unsigned int iface, - const unsigned int neighbor_iface, - const unsigned int neighbor_i_subface, - const real penalty, - const std::vector ¤t_dofs_indices, - const std::vector &neighbor_dofs_indices, - const std::vector ¤t_metric_dofs_indices, - const std::vector &neighbor_metric_dofs_indices, - const unsigned int /*poly_degree_int*/, - const unsigned int /*poly_degree_ext*/, - const unsigned int /*grid_degree_int*/, - const unsigned int /*grid_degree_ext*/, - OPERATOR::basis_functions &/*soln_basis_int*/, - OPERATOR::basis_functions &/*soln_basis_ext*/, - OPERATOR::basis_functions &/*flux_basis_int*/, - OPERATOR::basis_functions &/*flux_basis_ext*/, - OPERATOR::local_basis_stiffness &/*flux_basis_stiffness*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_int*/, - OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_ext*/, - OPERATOR::metric_operators &/*metric_oper_int*/, - OPERATOR::metric_operators &/*metric_oper_ext*/, - OPERATOR::mapping_shape_functions &/*mapping_basis*/, - std::array,dim> &/*mapping_support_points*/, - dealii::hp::FEFaceValues &fe_values_collection_face_int, - dealii::hp::FESubfaceValues &fe_values_collection_subface, - dealii::Vector ¤t_cell_rhs, - dealii::Vector &neighbor_cell_rhs, - std::vector> &/*current_cell_rhs_aux*/, - dealii::LinearAlgebra::distributed::Vector &rhs, - std::array,dim> &/*rhs_aux*/, - const bool /*compute_auxiliary_right_hand_side*/, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - /// Assembles the auxiliary equations' residuals and solves for the auxiliary variables. - void assemble_auxiliary_residual (); + void assemble_auxiliary_residual (const bool /*compute_dRdW*/, const bool /*compute_dRdX*/, const bool /*compute_d2R*/); /// Allocate the dual vector for optimization. - void allocate_dual_vector (); + void allocate_dual_vector (const bool compute_d2R); /// Main function responsible for evaluating the integral over the cell volume and the specified derivatives. /** This function templates the solution and metric coefficients in order to possible AD the residual. @@ -230,204 +103,735 @@ class DGWeak : public DGBaseState std::vector &rhs_ext, real2 &dual_dot_residual, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - -private: - - /// Preparation of CoDiPack taping for volume integral, and derivative evaluation. - /** Compute both the right-hand side and the corresponding block of dRdW, dRdX, and/or d2R. - * Uses CoDiPack to automatically differentiate the functions. - */ - template - void assemble_volume_codi_taped_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::FEValues &fe_values_vol, - const dealii::FESystem &fe_soln, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - dealii::Vector &local_rhs_cell, - const dealii::FEValues &fe_values_lagrange, - const Physics::PhysicsBase &physics, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - - /// Preparation of CoDiPack taping for boundary integral, and derivative evaluation. - /** Compute both the right-hand side and the corresponding block of dRdW, dRdX, and/or d2R. - * Uses CoDiPack to automatically differentiate the functions. - */ - template - void assemble_boundary_codi_taped_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const unsigned int face_number, - const unsigned int boundary_id, - const dealii::FEFaceValuesBase &fe_values_boundary, - const real penalty, - const dealii::FESystem &fe_soln, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - const Physics::PhysicsBase &physics, - const NumericalFlux::NumericalFluxConvective &conv_num_flux, - const NumericalFlux::NumericalFluxDissipative &diss_num_flux, - dealii::Vector &local_rhs_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - - /// Preparation of CoDiPack taping for internal cell faces integrals, and derivative evaluation. - /** Compute both the right-hand side and the corresponding block of dRdW, dRdX, and/or d2R. - * Uses CoDiPack to automatically differentiate the functions. - * This adds the contribution to both cell's residual and effectively - * computes 4 block contributions to dRdX blocks. - */ + template - void assemble_face_codi_taped_derivatives( + void assemble_volume_term_and_build_operators_ad_templated( typename dealii::DoFHandler::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const std::pair face_subface_int, - const std::pair face_subface_ext, - const typename dealii::QProjector::DataSetDescriptor face_data_set_int, - const typename dealii::QProjector::DataSetDescriptor face_data_set_ext, - const dealii::FEFaceValuesBase &,//fe_values_int, - const dealii::FEFaceValuesBase &,//fe_values_ext, - const real penalty, - const dealii::FESystem &fe_int, - const dealii::FESystem &fe_ext, - const dealii::Quadrature &face_quadrature, - const std::vector &metric_dof_indices_int, - const std::vector &metric_dof_indices_ext, - const std::vector &soln_dof_indices_int, - const std::vector &soln_dof_indices_ext, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &/*aux_soln_coeffs*/, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const std::vector &soln_dofs_indices, + const std::vector &metric_dofs_indices, + const unsigned int poly_degree, + const unsigned int grid_degree, const Physics::PhysicsBase &physics, - const NumericalFlux::NumericalFluxConvective &conv_num_flux, - const NumericalFlux::NumericalFluxDissipative &diss_num_flux, - dealii::Vector &local_rhs_int_cell, - dealii::Vector &local_rhs_ext_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - - -private: - - /// Evaluate the integral over the cell volume and the specified derivatives. - /** Compute both the right-hand side and the corresponding block of dRdW, dRdX, and/or d2R. */ - virtual void assemble_volume_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::FEValues &,//fe_values_vol, - const dealii::FESystem &fe, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - dealii::Vector &local_rhs_cell, - const dealii::FEValues &/*fe_values_lagrange*/, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - - - /// Evaluate the integral over the cell edges that are on domain boundaries and the specified derivatives. - /** Compute both the right-hand side and the corresponding block of dRdW, dRdX, and/or d2R. */ - void assemble_boundary_term_derivatives( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const unsigned int face_number, - const unsigned int boundary_id, - const dealii::FEFaceValuesBase &fe_values_boundary, - const real penalty, - const dealii::FESystem &fe, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - dealii::Vector &local_rhs_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - - - /// Evaluate the integral over the internal cell edges and its specified derivatives. - /** Compute both the right-hand side and the block of the Jacobian. - * This adds the contribution to both cell's residual and effectively - * computes 4 block contributions to dRdX blocks. */ - void assemble_face_term_derivatives( + OPERATOR::basis_functions &/*soln_basis*/, + OPERATOR::basis_functions &/*flux_basis*/, + OPERATOR::local_basis_stiffness &/*flux_basis_stiffness*/, + OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_int*/, + OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_ext*/, + OPERATOR::metric_operators &/*metric_oper*/, + OPERATOR::mapping_shape_functions &/*mapping_basis*/, + std::array,dim> &/*mapping_support_points*/, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + const dealii::FESystem &fe_soln, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &/*local_auxiliary_RHS*/, + const bool /*compute_auxiliary_right_hand_side*/, + adtype &dual_dot_residual); + + void assemble_volume_term_and_build_operators_ad( typename dealii::DoFHandler::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const std::pair face_subface_int, - const std::pair face_subface_ext, - const typename dealii::QProjector::DataSetDescriptor face_data_set_int, - const typename dealii::QProjector::DataSetDescriptor face_data_set_ext, - const dealii::FEFaceValuesBase &,//fe_values_int, - const dealii::FEFaceValuesBase &,//fe_values_ext, - const real penalty, - const dealii::FESystem &fe_int, - const dealii::FESystem &fe_ext, - const dealii::Quadrature &face_quadrature, - const std::vector &metric_dof_indices_int, - const std::vector &metric_dof_indices_ext, - const std::vector &soln_dof_indices_int, - const std::vector &soln_dof_indices_ext, - dealii::Vector &local_rhs_int_cell, - dealii::Vector &local_rhs_ext_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - -private: - /// Evaluate the integral over the cell volume. - /** Compute the right-hand side only. */ - void assemble_volume_residual( + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const std::vector &soln_dofs_indices, + const std::vector &metric_dofs_indices, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, + const dealii::FESystem &fe_soln, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + double &dual_dot_residual) override + { + assemble_volume_term_and_build_operators_ad_templated( + cell, + current_cell_index, + soln_coeffs, + aux_soln_coeffs, + metric_coeffs, + local_dual, + soln_dofs_indices, + metric_dofs_indices, + poly_degree, + grid_degree, + *(DGBaseState::pde_physics_double), + soln_basis, + flux_basis, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + metric_oper, + mapping_basis, + mapping_support_points, + fe_values_collection_volume, + fe_values_collection_volume_lagrange, + fe_soln, + rhs, + local_auxiliary_RHS, + compute_auxiliary_right_hand_side, + dual_dot_residual); + } + + void assemble_volume_term_and_build_operators_ad( typename dealii::DoFHandler::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, - const dealii::FEValues &fe_values_vol, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const std::vector &soln_dofs_indices, + const std::vector &metric_dofs_indices, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, const dealii::FESystem &fe_soln, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - dealii::Vector &local_rhs_cell, - const dealii::FEValues &fe_values_lagrange, - const Physics::PhysicsBase &physics, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); - - /// Evaluate the integral over the boundary. - /** Compute the right-hand side only. */ - void assemble_boundary_residual( + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + codi_JacobianComputationType &dual_dot_residual) override + { + assemble_volume_term_and_build_operators_ad_templated( + cell, + current_cell_index, + soln_coeffs, + aux_soln_coeffs, + metric_coeffs, + local_dual, + soln_dofs_indices, + metric_dofs_indices, + poly_degree, + grid_degree, + *(DGBaseState::pde_physics_rad), + soln_basis, + flux_basis, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + metric_oper, + mapping_basis, + mapping_support_points, + fe_values_collection_volume, + fe_values_collection_volume_lagrange, + fe_soln, + rhs, + local_auxiliary_RHS, + compute_auxiliary_right_hand_side, + dual_dot_residual); + } + + void assemble_volume_term_and_build_operators_ad( typename dealii::DoFHandler::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, - const unsigned int face_number, - const unsigned int boundary_id, - const dealii::FEFaceValuesBase &fe_values_boundary, - const real penalty, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const std::vector &soln_dofs_indices, + const std::vector &metric_dofs_indices, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEValues &fe_values_collection_volume, + dealii::hp::FEValues &fe_values_collection_volume_lagrange, const dealii::FESystem &fe_soln, - const dealii::Quadrature &quadrature, - const std::vector &metric_dof_indices, - const std::vector &soln_dof_indices, - const Physics::PhysicsBase &physics, - const NumericalFlux::NumericalFluxConvective &conv_num_flux, - const NumericalFlux::NumericalFluxDissipative &diss_num_flux, - dealii::Vector &local_rhs_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + codi_HessianComputationType &dual_dot_residual) override + { + assemble_volume_term_and_build_operators_ad_templated( + cell, + current_cell_index, + soln_coeffs, + aux_soln_coeffs, + metric_coeffs, + local_dual, + soln_dofs_indices, + metric_dofs_indices, + poly_degree, + grid_degree, + *(DGBaseState::pde_physics_rad_fad), + soln_basis, + flux_basis, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + metric_oper, + mapping_basis, + mapping_support_points, + fe_values_collection_volume, + fe_values_collection_volume_lagrange, + fe_soln, + rhs, + local_auxiliary_RHS, + compute_auxiliary_right_hand_side, + dual_dot_residual); + } + + template + void assemble_boundary_term_and_build_operators_ad_templated( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &/*aux_soln_coeffs*/, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const unsigned int face_number, + const unsigned int boundary_id, + const Physics::PhysicsBase &physics, + const NumericalFlux::NumericalFluxConvective &conv_num_flux, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + const unsigned int /*poly_degree*/, + const unsigned int /*grid_degree*/, + OPERATOR::basis_functions &/*soln_basis*/, + OPERATOR::basis_functions &/*flux_basis*/, + OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_int*/, + OPERATOR::metric_operators &/*metric_oper*/, + OPERATOR::mapping_shape_functions &/*mapping_basis*/, + std::array,dim> &/*mapping_support_points*/, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + const dealii::FESystem &fe_soln, + const real penalty, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &/*local_auxiliary_RHS*/, + const bool /*compute_auxiliary_right_hand_side*/, + adtype &dual_dot_residual); + + void assemble_boundary_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const unsigned int face_number, + const unsigned int boundary_id, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + const dealii::FESystem &fe_soln, + const real penalty, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + double &dual_dot_residual) override + { + assemble_boundary_term_and_build_operators_ad_templated( + cell, + current_cell_index, + soln_coeffs, + aux_soln_coeffs, + metric_coeffs, + local_dual, + face_number, + boundary_id, + *(DGBaseState::pde_physics_double), + *(DGBaseState::conv_num_flux_double), + *(DGBaseState::diss_num_flux_double), + poly_degree, + grid_degree, + soln_basis, + flux_basis, + soln_basis_projection_oper_int, + metric_oper, + mapping_basis, + mapping_support_points, + fe_values_collection_face_int, + fe_soln, + penalty, + rhs, + local_auxiliary_RHS, + compute_auxiliary_right_hand_side, + dual_dot_residual); + } + + void assemble_boundary_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const unsigned int face_number, + const unsigned int boundary_id, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + const dealii::FESystem &fe_soln, + const real penalty, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + codi_JacobianComputationType &dual_dot_residual) override + { + assemble_boundary_term_and_build_operators_ad_templated( + cell, + current_cell_index, + soln_coeffs, + aux_soln_coeffs, + metric_coeffs, + local_dual, + face_number, + boundary_id, + *(DGBaseState::pde_physics_rad), + *(DGBaseState::conv_num_flux_rad), + *(DGBaseState::diss_num_flux_rad), + poly_degree, + grid_degree, + soln_basis, + flux_basis, + soln_basis_projection_oper_int, + metric_oper, + mapping_basis, + mapping_support_points, + fe_values_collection_face_int, + fe_soln, + penalty, + rhs, + local_auxiliary_RHS, + compute_auxiliary_right_hand_side, + dual_dot_residual); + } + + void assemble_boundary_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + const dealii::types::global_dof_index current_cell_index, + const std::vector &soln_coeffs, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeffs, + const std::vector &metric_coeffs, + const std::vector &local_dual, + const unsigned int face_number, + const unsigned int boundary_id, + const unsigned int poly_degree, + const unsigned int grid_degree, + OPERATOR::basis_functions &soln_basis, + OPERATOR::basis_functions &flux_basis, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + const dealii::FESystem &fe_soln, + const real penalty, + std::vector &rhs, + dealii::Tensor<1,dim,std::vector> &local_auxiliary_RHS, + const bool compute_auxiliary_right_hand_side, + codi_HessianComputationType &dual_dot_residual) override + { + assemble_boundary_term_and_build_operators_ad_templated( + cell, + current_cell_index, + soln_coeffs, + aux_soln_coeffs, + metric_coeffs, + local_dual, + face_number, + boundary_id, + *(DGBaseState::pde_physics_rad_fad), + *(DGBaseState::conv_num_flux_rad_fad), + *(DGBaseState::diss_num_flux_rad_fad), + poly_degree, + grid_degree, + soln_basis, + flux_basis, + soln_basis_projection_oper_int, + metric_oper, + mapping_basis, + mapping_support_points, + fe_values_collection_face_int, + fe_soln, + penalty, + rhs, + local_auxiliary_RHS, + compute_auxiliary_right_hand_side, + dual_dot_residual); + } + + template + void assemble_face_term_and_build_operators_ad_templated( + typename dealii::DoFHandler::active_cell_iterator cell, + typename dealii::DoFHandler::active_cell_iterator neighbor_cell, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const std::vector &soln_coeff_int, + const std::vector &soln_coeff_ext, + const dealii::Tensor<1,dim,std::vector> &/*aux_soln_coeff_int*/, + const dealii::Tensor<1,dim,std::vector> &/*aux_soln_coeff_ext*/, + const std::vector &metric_coeff_int, + const std::vector &metric_coeff_ext, + const std::vector< double > &dual_int, + const std::vector< double > &dual_ext, + const unsigned int /*poly_degree_int*/, + const unsigned int /*poly_degree_ext*/, + const unsigned int /*grid_degree_int*/, + const unsigned int /*grid_degree_ext*/, + OPERATOR::basis_functions &/*soln_basis_int*/, + OPERATOR::basis_functions &/*soln_basis_ext*/, + OPERATOR::basis_functions &/*flux_basis_int*/, + OPERATOR::basis_functions &/*flux_basis_ext*/, + OPERATOR::local_basis_stiffness &/*flux_basis_stiffness*/, + OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_int*/, + OPERATOR::vol_projection_operator &/*soln_basis_projection_oper_ext*/, + OPERATOR::metric_operators &/*metric_oper_int*/, + OPERATOR::metric_operators &/*metric_oper_ext*/, + OPERATOR::mapping_shape_functions &/*mapping_basis*/, + std::array,dim> &/*mapping_support_points*/, + const Physics::PhysicsBase &physics, + const NumericalFlux::NumericalFluxConvective &conv_num_flux, + const NumericalFlux::NumericalFluxDissipative &diss_num_flux, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + const dealii::FESystem &fe_int, + const dealii::FESystem &fe_ext, + const real penalty, + std::vector &rhs_int, + std::vector &rhs_ext, + dealii::Tensor<1,dim,std::vector> &/*aux_rhs_int*/, + dealii::Tensor<1,dim,std::vector> &/*aux_rhs_ext*/, + const bool /*compute_auxiliary_right_hand_side*/, + adtype &dual_dot_residual, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + const bool is_a_subface, + const unsigned int neighbor_i_subface); + + void assemble_face_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + typename dealii::DoFHandler::active_cell_iterator neighbor_cell, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const std::vector &soln_coeff_int, + const std::vector &soln_coeff_ext, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_int, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_ext, + const std::vector &metric_coeff_int, + const std::vector &metric_coeff_ext, + const std::vector< double > &dual_int, + const std::vector< double > &dual_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const unsigned int grid_degree_int, + const unsigned int grid_degree_ext, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + const dealii::FESystem &fe_int, + const dealii::FESystem &fe_ext, + const real penalty, + std::vector &rhs_int, + std::vector &rhs_ext, + dealii::Tensor<1,dim,std::vector> &aux_rhs_int, + dealii::Tensor<1,dim,std::vector> &aux_rhs_ext, + const bool compute_auxiliary_right_hand_side, + double &dual_dot_residual, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + const bool is_a_subface, + const unsigned int neighbor_i_subface) override + { + assemble_face_term_and_build_operators_ad_templated( + cell, + neighbor_cell, + current_cell_index, + neighbor_cell_index, + iface, + neighbor_iface, + soln_coeff_int, + soln_coeff_ext, + aux_soln_coeff_int, + aux_soln_coeff_ext, + metric_coeff_int, + metric_coeff_ext, + dual_int, + dual_ext, + poly_degree_int, + poly_degree_ext, + grid_degree_int, + grid_degree_ext, + soln_basis_int, + soln_basis_ext, + flux_basis_int, + flux_basis_ext, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + metric_oper_int, + metric_oper_ext, + mapping_basis, + mapping_support_points, + *(DGBaseState::pde_physics_double), + *(DGBaseState::conv_num_flux_double), + *(DGBaseState::diss_num_flux_double), + fe_values_collection_face_int, + fe_values_collection_face_ext, + fe_values_collection_subface, + fe_int, + fe_ext, + penalty, + rhs_int, + rhs_ext, + aux_rhs_int, + aux_rhs_ext, + compute_auxiliary_right_hand_side, + dual_dot_residual, + compute_dRdW, compute_dRdX, compute_d2R, + is_a_subface, + neighbor_i_subface); + } - /// Evaluate the integral over the internal face. - /** Compute the right-hand side only. */ - void assemble_face_residual( - typename dealii::DoFHandler::active_cell_iterator cell, - const dealii::types::global_dof_index current_cell_index, - const dealii::types::global_dof_index neighbor_cell_index, - const std::pair face_subface_int, - const std::pair face_subface_ext, - const typename dealii::QProjector::DataSetDescriptor face_data_set_int, - const typename dealii::QProjector::DataSetDescriptor face_data_set_ext, - const dealii::FEFaceValuesBase &,//fe_values_int, - const dealii::FEFaceValuesBase &,//fe_values_ext, - const real penalty, - const dealii::FESystem &fe_int, - const dealii::FESystem &fe_ext, - const dealii::Quadrature &face_quadrature, - const std::vector &metric_dof_indices_int, - const std::vector &metric_dof_indices_ext, - const std::vector &soln_dof_indices_int, - const std::vector &soln_dof_indices_ext, - const Physics::PhysicsBase &physics, - const NumericalFlux::NumericalFluxConvective &conv_num_flux, - const NumericalFlux::NumericalFluxDissipative &diss_num_flux, - dealii::Vector &local_rhs_int_cell, - dealii::Vector &local_rhs_ext_cell, - const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R); + + void assemble_face_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + typename dealii::DoFHandler::active_cell_iterator neighbor_cell, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const std::vector &soln_coeff_int, + const std::vector &soln_coeff_ext, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_int, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_ext, + const std::vector &metric_coeff_int, + const std::vector &metric_coeff_ext, + const std::vector< double > &dual_int, + const std::vector< double > &dual_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const unsigned int grid_degree_int, + const unsigned int grid_degree_ext, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + const dealii::FESystem &fe_int, + const dealii::FESystem &fe_ext, + const real penalty, + std::vector &rhs_int, + std::vector &rhs_ext, + dealii::Tensor<1,dim,std::vector> &aux_rhs_int, + dealii::Tensor<1,dim,std::vector> &aux_rhs_ext, + const bool compute_auxiliary_right_hand_side, + codi_JacobianComputationType &dual_dot_residual, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + const bool is_a_subface, + const unsigned int neighbor_i_subface) override + { + assemble_face_term_and_build_operators_ad_templated( + cell, + neighbor_cell, + current_cell_index, + neighbor_cell_index, + iface, + neighbor_iface, + soln_coeff_int, + soln_coeff_ext, + aux_soln_coeff_int, + aux_soln_coeff_ext, + metric_coeff_int, + metric_coeff_ext, + dual_int, + dual_ext, + poly_degree_int, + poly_degree_ext, + grid_degree_int, + grid_degree_ext, + soln_basis_int, + soln_basis_ext, + flux_basis_int, + flux_basis_ext, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + metric_oper_int, + metric_oper_ext, + mapping_basis, + mapping_support_points, + *(DGBaseState::pde_physics_rad), + *(DGBaseState::conv_num_flux_rad), + *(DGBaseState::diss_num_flux_rad), + fe_values_collection_face_int, + fe_values_collection_face_ext, + fe_values_collection_subface, + fe_int, + fe_ext, + penalty, + rhs_int, + rhs_ext, + aux_rhs_int, + aux_rhs_ext, + compute_auxiliary_right_hand_side, + dual_dot_residual, + compute_dRdW, compute_dRdX, compute_d2R, + is_a_subface, + neighbor_i_subface); + } + void assemble_face_term_and_build_operators_ad( + typename dealii::DoFHandler::active_cell_iterator cell, + typename dealii::DoFHandler::active_cell_iterator neighbor_cell, + const dealii::types::global_dof_index current_cell_index, + const dealii::types::global_dof_index neighbor_cell_index, + const unsigned int iface, + const unsigned int neighbor_iface, + const std::vector &soln_coeff_int, + const std::vector &soln_coeff_ext, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_int, + const dealii::Tensor<1,dim,std::vector> &aux_soln_coeff_ext, + const std::vector &metric_coeff_int, + const std::vector &metric_coeff_ext, + const std::vector< double > &dual_int, + const std::vector< double > &dual_ext, + const unsigned int poly_degree_int, + const unsigned int poly_degree_ext, + const unsigned int grid_degree_int, + const unsigned int grid_degree_ext, + OPERATOR::basis_functions &soln_basis_int, + OPERATOR::basis_functions &soln_basis_ext, + OPERATOR::basis_functions &flux_basis_int, + OPERATOR::basis_functions &flux_basis_ext, + OPERATOR::local_basis_stiffness &flux_basis_stiffness, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_int, + OPERATOR::vol_projection_operator &soln_basis_projection_oper_ext, + OPERATOR::metric_operators &metric_oper_int, + OPERATOR::metric_operators &metric_oper_ext, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points, + dealii::hp::FEFaceValues &fe_values_collection_face_int, + dealii::hp::FEFaceValues &fe_values_collection_face_ext, + dealii::hp::FESubfaceValues &fe_values_collection_subface, + const dealii::FESystem &fe_int, + const dealii::FESystem &fe_ext, + const real penalty, + std::vector &rhs_int, + std::vector &rhs_ext, + dealii::Tensor<1,dim,std::vector> &aux_rhs_int, + dealii::Tensor<1,dim,std::vector> &aux_rhs_ext, + const bool compute_auxiliary_right_hand_side, + codi_HessianComputationType &dual_dot_residual, + const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, + const bool is_a_subface, + const unsigned int neighbor_i_subface) override + { + assemble_face_term_and_build_operators_ad_templated( + cell, + neighbor_cell, + current_cell_index, + neighbor_cell_index, + iface, + neighbor_iface, + soln_coeff_int, + soln_coeff_ext, + aux_soln_coeff_int, + aux_soln_coeff_ext, + metric_coeff_int, + metric_coeff_ext, + dual_int, + dual_ext, + poly_degree_int, + poly_degree_ext, + grid_degree_int, + grid_degree_ext, + soln_basis_int, + soln_basis_ext, + flux_basis_int, + flux_basis_ext, + flux_basis_stiffness, + soln_basis_projection_oper_int, + soln_basis_projection_oper_ext, + metric_oper_int, + metric_oper_ext, + mapping_basis, + mapping_support_points, + *(DGBaseState::pde_physics_rad_fad), + *(DGBaseState::conv_num_flux_rad_fad), + *(DGBaseState::diss_num_flux_rad_fad), + fe_values_collection_face_int, + fe_values_collection_face_ext, + fe_values_collection_subface, + fe_int, + fe_ext, + penalty, + rhs_int, + rhs_ext, + aux_rhs_int, + aux_rhs_ext, + compute_auxiliary_right_hand_side, + dual_dot_residual, + compute_dRdW, compute_dRdX, compute_d2R, + is_a_subface, + neighbor_i_subface); + } + +private: /// Evaluate the integral over the cell volume void assemble_volume_term_explicit( typename dealii::DoFHandler::active_cell_iterator cell, @@ -442,6 +846,51 @@ class DGWeak : public DGBaseState using DGBase::pcout; ///< Parallel std::cout that only outputs on mpi_rank==0 + +public: + /// Builds volume metric operators (metric cofactor and determinant of metric Jacobian). + template + void build_volume_metric_operators( + const unsigned int /*poly_degree*/, + const unsigned int /*grid_degree*/, + const std::vector &/*metric_coeffs*/, + OPERATOR::metric_operators &/*metric_oper*/, + OPERATOR::mapping_shape_functions &/*mapping_basis*/, + std::array,dim> &/*mapping_support_points*/) + { + //Do Nothing. + } + void build_volume_metric_operators( + const unsigned int poly_degree, + const unsigned int grid_degree, + const std::vector &metric_coeffs, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points) + { + build_volume_metric_operators(poly_degree, grid_degree, metric_coeffs, metric_oper, mapping_basis, mapping_support_points); + } + void build_volume_metric_operators( + const unsigned int poly_degree, + const unsigned int grid_degree, + const std::vector &metric_coeffs, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points) + { + build_volume_metric_operators(poly_degree, grid_degree, metric_coeffs, metric_oper, mapping_basis, mapping_support_points); + } + void build_volume_metric_operators( + const unsigned int poly_degree, + const unsigned int grid_degree, + const std::vector &metric_coeffs, + OPERATOR::metric_operators &metric_oper, + OPERATOR::mapping_shape_functions &mapping_basis, + std::array,dim> &mapping_support_points) + { + build_volume_metric_operators(poly_degree, grid_degree, metric_coeffs, metric_oper, mapping_basis, mapping_support_points); + } + }; // end of DGWeak class } // PHiLiP namespace diff --git a/src/flow_solver/flow_solver_cases/limiter_convergence_tests.cpp b/src/flow_solver/flow_solver_cases/limiter_convergence_tests.cpp index 8110cc657..76f7011ce 100644 --- a/src/flow_solver/flow_solver_cases/limiter_convergence_tests.cpp +++ b/src/flow_solver/flow_solver_cases/limiter_convergence_tests.cpp @@ -109,8 +109,8 @@ void LimiterConvergenceTests::check_limiter_principle(DGBaseall_param.flow_solver_param.poly_degree; //Constructor for the operators - OPERATOR::basis_functions soln_basis(1, poly_degree, init_grid_degree); - OPERATOR::vol_projection_operator soln_basis_projection_oper(1, dg.max_degree, init_grid_degree); + OPERATOR::basis_functions soln_basis(1, poly_degree, init_grid_degree); + OPERATOR::vol_projection_operator soln_basis_projection_oper(1, dg.max_degree, init_grid_degree); // Build the oneD operator to perform interpolation/projection @@ -217,4 +217,4 @@ void LimiterConvergenceTests::compute_unsteady_data_and_write_to_ta #endif } -} \ No newline at end of file +} diff --git a/src/flow_solver/flow_solver_cases/non_periodic_cube_flow.cpp b/src/flow_solver/flow_solver_cases/non_periodic_cube_flow.cpp index 336cb2fc8..a8aa2def2 100644 --- a/src/flow_solver/flow_solver_cases/non_periodic_cube_flow.cpp +++ b/src/flow_solver/flow_solver_cases/non_periodic_cube_flow.cpp @@ -69,8 +69,8 @@ void NonPeriodicCubeFlow::check_positivity_density(DGBaseall_param.flow_solver_param.poly_degree; //Constructor for the operators - OPERATOR::basis_functions soln_basis(1, poly_degree, init_grid_degree); - OPERATOR::vol_projection_operator soln_basis_projection_oper(1, dg.max_degree, init_grid_degree); + OPERATOR::basis_functions soln_basis(1, poly_degree, init_grid_degree); + OPERATOR::vol_projection_operator soln_basis_projection_oper(1, dg.max_degree, init_grid_degree); // Build the oneD operator to perform interpolation/projection @@ -164,4 +164,4 @@ void NonPeriodicCubeFlow::compute_unsteady_data_and_write_to_table( template class NonPeriodicCubeFlow ; #endif } // FlowSolver namespace -} // PHiLiP namespace \ No newline at end of file +} // PHiLiP namespace diff --git a/src/flow_solver/flow_solver_cases/periodic_entropy_tests.cpp b/src/flow_solver/flow_solver_cases/periodic_entropy_tests.cpp index 2aeb68b73..126464809 100644 --- a/src/flow_solver/flow_solver_cases/periodic_entropy_tests.cpp +++ b/src/flow_solver/flow_solver_cases/periodic_entropy_tests.cpp @@ -84,8 +84,8 @@ double PeriodicEntropyTests::compute_integrated_quantities(DGBase soln_basis(1, poly_degree, grid_degree); - OPERATOR::mapping_shape_functions mapping_basis(1, poly_degree, grid_degree); + OPERATOR::basis_functions soln_basis(1, poly_degree, grid_degree); + OPERATOR::mapping_shape_functions mapping_basis(1, poly_degree, grid_degree); // Build basis function volume operator and gradient operator from 1D finite element for 1 state. soln_basis.build_1D_volume_operator(dg.oneD_fe_collection_1state[poly_degree], quad_1D); soln_basis.build_1D_gradient_operator(dg.oneD_fe_collection_1state[poly_degree], quad_1D); diff --git a/src/flow_solver/flow_solver_cases/periodic_turbulence.cpp b/src/flow_solver/flow_solver_cases/periodic_turbulence.cpp index 50fd7b120..39cee4055 100644 --- a/src/flow_solver/flow_solver_cases/periodic_turbulence.cpp +++ b/src/flow_solver/flow_solver_cases/periodic_turbulence.cpp @@ -178,12 +178,12 @@ void PeriodicTurbulence::output_velocity_field( dealii::FE_DGQArbitraryNodes<1,1> equidistant_finite_element(vol_quad_equidistant_1D); const unsigned int init_grid_degree = dg->high_order_grid->fe_system.tensor_degree(); - OPERATOR::basis_functions soln_basis(1, dg->max_degree, init_grid_degree); + OPERATOR::basis_functions soln_basis(1, dg->max_degree, init_grid_degree); soln_basis.build_1D_volume_operator(dg->oneD_fe_collection_1state[dg->max_degree], vol_quad_equidistant_1D); soln_basis.build_1D_gradient_operator(dg->oneD_fe_collection_1state[dg->max_degree], vol_quad_equidistant_1D); // mapping basis for the equidistant node set because we output the physical coordinates - OPERATOR::mapping_shape_functions mapping_basis_at_equidistant(1, dg->max_degree, init_grid_degree); + OPERATOR::mapping_shape_functions mapping_basis_at_equidistant(1, dg->max_degree, init_grid_degree); mapping_basis_at_equidistant.build_1D_shape_functions_at_grid_nodes(dg->high_order_grid->oneD_fe_system, dg->high_order_grid->oneD_grid_nodes); mapping_basis_at_equidistant.build_1D_shape_functions_at_flux_nodes(dg->high_order_grid->oneD_fe_system, vol_quad_equidistant_1D, dg->oneD_face_quadrature); @@ -340,8 +340,8 @@ void PeriodicTurbulence::compute_and_update_integrated_quantities(D const unsigned int grid_degree = dg.high_order_grid->fe_system.tensor_degree(); const unsigned int poly_degree = dg.max_degree; // Construct the basis functions and mapping shape functions. - OPERATOR::basis_functions soln_basis(1, poly_degree, grid_degree); - OPERATOR::mapping_shape_functions mapping_basis(1, poly_degree, grid_degree); + OPERATOR::basis_functions soln_basis(1, poly_degree, grid_degree); + OPERATOR::mapping_shape_functions mapping_basis(1, poly_degree, grid_degree); // Build basis function volume operator and gradient operator from 1D finite element for 1 state. soln_basis.build_1D_volume_operator(dg.oneD_fe_collection_1state[poly_degree], quad_extra_1D); soln_basis.build_1D_gradient_operator(dg.oneD_fe_collection_1state[poly_degree], quad_extra_1D); @@ -560,14 +560,14 @@ double PeriodicTurbulence::compute_current_integrated_numerical_ent const unsigned int n_quad_pts = dg->volume_quadrature_collection[poly_degree].size(); const unsigned int n_shape_fns = n_dofs_cell / nstate; - OPERATOR::vol_projection_operator vol_projection(1, poly_degree, dg->max_grid_degree); + OPERATOR::vol_projection_operator vol_projection(1, poly_degree, dg->max_grid_degree); vol_projection.build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]); // Construct the basis functions and mapping shape functions. - OPERATOR::basis_functions soln_basis(1, poly_degree, dg->max_grid_degree); + OPERATOR::basis_functions soln_basis(1, poly_degree, dg->max_grid_degree); soln_basis.build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]); - OPERATOR::mapping_shape_functions mapping_basis(1, poly_degree, dg->max_grid_degree); + OPERATOR::mapping_shape_functions mapping_basis(1, poly_degree, dg->max_grid_degree); mapping_basis.build_1D_shape_functions_at_grid_nodes(dg->high_order_grid->oneD_fe_system, dg->high_order_grid->oneD_grid_nodes); mapping_basis.build_1D_shape_functions_at_flux_nodes(dg->high_order_grid->oneD_fe_system, dg->oneD_quadrature_collection[poly_degree], dg->oneD_face_quadrature); diff --git a/src/limiter/maximum_principle_limiter.cpp b/src/limiter/maximum_principle_limiter.cpp index 135c4e4d2..ad1ef010a 100644 --- a/src/limiter/maximum_principle_limiter.cpp +++ b/src/limiter/maximum_principle_limiter.cpp @@ -123,8 +123,8 @@ void MaximumPrincipleLimiter::limit( //modal coefficients. const unsigned int init_grid_degree = grid_degree; //Constructor for the operators - OPERATOR::basis_functions soln_basis(1, max_degree, init_grid_degree); - OPERATOR::vol_projection_operator soln_basis_projection_oper(1, max_degree, init_grid_degree); + OPERATOR::basis_functions soln_basis(1, max_degree, init_grid_degree); + OPERATOR::vol_projection_operator soln_basis_projection_oper(1, max_degree, init_grid_degree); // Build the oneD operator to perform interpolation/projection @@ -229,4 +229,4 @@ template class MaximumPrincipleLimiter ; template class MaximumPrincipleLimiter ; template class MaximumPrincipleLimiter ; template class MaximumPrincipleLimiter ; -} // PHiLiP namespace \ No newline at end of file +} // PHiLiP namespace diff --git a/src/limiter/positivity_preserving_limiter.cpp b/src/limiter/positivity_preserving_limiter.cpp index 3eb43d06a..a27246dcf 100644 --- a/src/limiter/positivity_preserving_limiter.cpp +++ b/src/limiter/positivity_preserving_limiter.cpp @@ -197,8 +197,8 @@ void PositivityPreservingLimiter::limit( const unsigned int init_grid_degree = grid_degree; // Constructor for the operators - OPERATOR::basis_functions soln_basis(1, max_degree, init_grid_degree); - OPERATOR::vol_projection_operator soln_basis_projection_oper(1, max_degree, init_grid_degree); + OPERATOR::basis_functions soln_basis(1, max_degree, init_grid_degree); + OPERATOR::vol_projection_operator soln_basis_projection_oper(1, max_degree, init_grid_degree); // Build the oneD operator to perform interpolation/projection soln_basis.build_1D_volume_operator(oneD_fe_collection_1state[max_degree], oneD_quadrature_collection[max_degree]); @@ -333,4 +333,4 @@ template class PositivityPreservingLimiter ; template class PositivityPreservingLimiter ; template class PositivityPreservingLimiter ; template class PositivityPreservingLimiter ; -} // PHiLiP namespace \ No newline at end of file +} // PHiLiP namespace diff --git a/src/limiter/tvb_limiter.cpp b/src/limiter/tvb_limiter.cpp index eb15bd073..6690526e1 100644 --- a/src/limiter/tvb_limiter.cpp +++ b/src/limiter/tvb_limiter.cpp @@ -123,7 +123,7 @@ std::array TVBLimiter::get_neighbour_cell_avg( const dealii::LinearAlgebra::distributed::Vector& solution, const dealii::hp::FECollection& fe_collection, const dealii::hp::QCollection& volume_quadrature_collection, - OPERATOR::basis_functions soln_basis, + OPERATOR::basis_functions soln_basis, const int poly_degree, const std::vector& neigh_dofs_indices, const unsigned int n_dofs_neigh_cell) @@ -193,8 +193,8 @@ void TVBLimiter::limit( //modal coefficients. const unsigned int init_grid_degree = grid_degree; //Constructor for the operators - OPERATOR::basis_functions soln_basis(1, max_degree, init_grid_degree); - OPERATOR::vol_projection_operator soln_basis_projection_oper(1, max_degree, init_grid_degree); + OPERATOR::basis_functions soln_basis(1, max_degree, init_grid_degree); + OPERATOR::vol_projection_operator soln_basis_projection_oper(1, max_degree, init_grid_degree); //build the oneD operator to perform interpolation/projection @@ -306,4 +306,4 @@ template class TVBLimiter ; template class TVBLimiter ; template class TVBLimiter ; #endif -} // PHiLiP namespace \ No newline at end of file +} // PHiLiP namespace diff --git a/src/limiter/tvb_limiter.h b/src/limiter/tvb_limiter.h index e58b41c59..fd694f1cc 100644 --- a/src/limiter/tvb_limiter.h +++ b/src/limiter/tvb_limiter.h @@ -38,7 +38,7 @@ class TVBLimiter : public BoundPreservingLimiterState const dealii::LinearAlgebra::distributed::Vector& solution, const dealii::hp::FECollection& fe_collection, const dealii::hp::QCollection& volume_quadrature_collection, - OPERATOR::basis_functions soln_basis, + OPERATOR::basis_functions soln_basis, const int poly_degree, const std::vector& neigh_dofs_indices, const unsigned int n_dofs_neigh_cell); diff --git a/src/ode_solver/relaxation_runge_kutta/root_finding_rrk_ode_solver.cpp b/src/ode_solver/relaxation_runge_kutta/root_finding_rrk_ode_solver.cpp index 736f98abb..880faf9b7 100644 --- a/src/ode_solver/relaxation_runge_kutta/root_finding_rrk_ode_solver.cpp +++ b/src/ode_solver/relaxation_runge_kutta/root_finding_rrk_ode_solver.cpp @@ -239,16 +239,16 @@ real RootFindingRRKODESolver::compute_integrated_numerical_en const unsigned int n_quad_pts = dg->volume_quadrature_collection[poly_degree].size(); const unsigned int n_shape_fns = n_dofs_cell / nstate; - OPERATOR::vol_projection_operator vol_projection(1, poly_degree, dg->max_grid_degree); + OPERATOR::vol_projection_operator vol_projection(1, poly_degree, dg->max_grid_degree); vol_projection.build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]); // Construct the basis functions and mapping shape functions. - OPERATOR::basis_functions soln_basis(1, poly_degree, dg->max_grid_degree); + OPERATOR::basis_functions soln_basis(1, poly_degree, dg->max_grid_degree); soln_basis.build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]); - OPERATOR::mapping_shape_functions mapping_basis(1, poly_degree, dg->max_grid_degree); + OPERATOR::mapping_shape_functions mapping_basis(1, poly_degree, dg->max_grid_degree); mapping_basis.build_1D_shape_functions_at_grid_nodes(dg->high_order_grid->oneD_fe_system, dg->high_order_grid->oneD_grid_nodes); mapping_basis.build_1D_shape_functions_at_flux_nodes(dg->high_order_grid->oneD_fe_system, diff --git a/src/ode_solver/relaxation_runge_kutta/runge_kutta_store_entropy.cpp b/src/ode_solver/relaxation_runge_kutta/runge_kutta_store_entropy.cpp index 351b463a1..eb7b4442c 100644 --- a/src/ode_solver/relaxation_runge_kutta/runge_kutta_store_entropy.cpp +++ b/src/ode_solver/relaxation_runge_kutta/runge_kutta_store_entropy.cpp @@ -50,10 +50,10 @@ dealii::LinearAlgebra::distributed::Vector RKNumEntropyvolume_quadrature_collection[poly_degree].size(); const unsigned int n_shape_fns = n_dofs_cell / nstate; //We have to project the vector of entropy variables because the mass matrix has an interpolation from solution nodes built into it. - OPERATOR::vol_projection_operator vol_projection(1, poly_degree, dg->max_grid_degree); + OPERATOR::vol_projection_operator vol_projection(1, poly_degree, dg->max_grid_degree); vol_projection.build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]); - OPERATOR::basis_functions soln_basis(1, poly_degree, dg->max_grid_degree); + OPERATOR::basis_functions soln_basis(1, poly_degree, dg->max_grid_degree); soln_basis.build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]); dealii::LinearAlgebra::distributed::Vector entropy_var_hat_global(dg->right_hand_side); diff --git a/src/operators/operators.cpp b/src/operators/operators.cpp index 706c3add8..3ae49387b 100644 --- a/src/operators/operators.cpp +++ b/src/operators/operators.cpp @@ -38,8 +38,8 @@ namespace PHiLiP { namespace OPERATOR { //Constructor -template -OperatorsBase::OperatorsBase( +template +OperatorsBase::OperatorsBase( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input) @@ -51,8 +51,8 @@ OperatorsBase::OperatorsBase( , pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(mpi_communicator)==0) {} -template -dealii::FullMatrix OperatorsBase::tensor_product( +template +dealii::FullMatrix OperatorsBase::tensor_product( const dealii::FullMatrix &basis_x, const dealii::FullMatrix &basis_y, const dealii::FullMatrix &basis_z) @@ -102,8 +102,8 @@ dealii::FullMatrix OperatorsBase::tensor_product( } } -template -dealii::FullMatrix OperatorsBase::tensor_product_state( +template +dealii::FullMatrix OperatorsBase::tensor_product_state( const int nstate, const dealii::FullMatrix &basis_x, const dealii::FullMatrix &basis_y, @@ -169,8 +169,8 @@ dealii::FullMatrix OperatorsBase::tensor_product_state return tens_prod; } -template -double OperatorsBase::compute_factorial(double n) +template +double OperatorsBase::compute_factorial(double n) { if ((n==0)||(n==1)) return 1; @@ -184,16 +184,17 @@ double OperatorsBase::compute_factorial(double n) * **********************************/ //Constructor -template -SumFactorizedOperators::SumFactorizedOperators( +template +SumFactorizedOperators::SumFactorizedOperators( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input) - : OperatorsBase::OperatorsBase(nstate_input, max_degree_input, grid_degree_input) + : OperatorsBase::OperatorsBase(nstate_input, max_degree_input, grid_degree_input) {} -template -void SumFactorizedOperators::matrix_vector_mult( +template +template +void SumFactorizedOperators::matrix_vector_mult( const std::vector &input_vect, std::vector &output_vect, const dealii::FullMatrix &basis_x, @@ -232,80 +233,76 @@ void SumFactorizedOperators::matrix_vector_mult( } } if constexpr (dim==2){ - //convert the input vector to matrix - dealii::FullMatrix input_mat(columns_x, columns_y); - for(unsigned int idof=0; idof temp(rows_x * columns_y); + for(unsigned int x_dir =0; x_dir temp(rows_x, columns_y); - basis_x.mmult(temp, input_mat);//apply x tensor product - dealii::FullMatrix output_mat(rows_y, rows_x); - basis_y.mTmult(output_mat, temp);//apply y tensor product - //convert mat back to vect - for(unsigned int iquad=0; iquad input_mat(columns_x, columns_y * columns_z); - for(unsigned int idof=0; idof temp(rows_x, columns_y * columns_z); - basis_x.mmult(temp, input_mat);//apply x tensor product - //convert to have y dofs ie/ change the stride - dealii::FullMatrix temp2(columns_y, rows_x * columns_z); - for(unsigned int iquad=0; iquad transformed_x(rows_x * columns_y * columns_z); + for(unsigned int x_dir=0; x_dir temp3(rows_y, rows_x * columns_z); - basis_y.mmult(temp3, temp2);//apply y tensor product - dealii::FullMatrix temp4(columns_z, rows_x * rows_y); - //convert to have z dofs ie/ change the stride - for(unsigned int iquad=0; iquad transformed_x_and_y(rows_y * rows_x * columns_z); + for(unsigned int y_dir=0; y_dir output_mat(rows_z, rows_x * rows_y); - basis_z.mmult(output_mat, temp4); - //convert mat to vect - for(unsigned int iquad=0; iquad -void SumFactorizedOperators::matrix_vector_mult_1D( +template +template +void SumFactorizedOperators::matrix_vector_mult_1D( const std::vector &input_vect, std::vector &output_vect, const dealii::FullMatrix &basis_x, @@ -315,8 +312,9 @@ void SumFactorizedOperators::matrix_vector_mult_1D( this->matrix_vector_mult(input_vect, output_vect, basis_x, basis_x, basis_x, adding, factor); } -template -void SumFactorizedOperators::matrix_vector_mult_surface_1D( +template +template +void SumFactorizedOperators::matrix_vector_mult_surface_1D( const unsigned int face_number, const std::vector &input_vect, std::vector &output_vect, @@ -340,11 +338,12 @@ void SumFactorizedOperators::matrix_vector_mult_surface_1D( } -template -void SumFactorizedOperators::inner_product_surface_1D( +template +template +void SumFactorizedOperators::inner_product_surface_1D( const unsigned int face_number, const std::vector &input_vect, - const std::vector &weight_vect, + const std::vector &weight_vect, std::vector &output_vect, const std::array,2> &basis_surf, const dealii::FullMatrix &basis_vol, @@ -365,8 +364,9 @@ void SumFactorizedOperators::inner_product_surface_1D( this->inner_product(input_vect, weight_vect, output_vect, basis_vol, basis_vol, basis_surf[1], adding, factor); } -template -void SumFactorizedOperators::divergence_matrix_vector_mult_1D( +template +template +void SumFactorizedOperators::divergence_matrix_vector_mult_1D( const dealii::Tensor<1,dim,std::vector> &input_vect, std::vector &output_vect, const dealii::FullMatrix &basis, @@ -377,8 +377,9 @@ void SumFactorizedOperators::divergence_matrix_vector_mult_1D( gradient_basis, gradient_basis, gradient_basis); } -template -void SumFactorizedOperators::divergence_matrix_vector_mult( +template +template +void SumFactorizedOperators::divergence_matrix_vector_mult( const dealii::Tensor<1,dim,std::vector> &input_vect, std::vector &output_vect, const dealii::FullMatrix &basis_x, @@ -410,8 +411,9 @@ void SumFactorizedOperators::divergence_matrix_vector_mult( } } -template -void SumFactorizedOperators::gradient_matrix_vector_mult_1D( +template +template +void SumFactorizedOperators::gradient_matrix_vector_mult_1D( const std::vector &input_vect, dealii::Tensor<1,dim,std::vector> &output_vect, const dealii::FullMatrix &basis, @@ -422,8 +424,9 @@ void SumFactorizedOperators::gradient_matrix_vector_mult_1D( gradient_basis, gradient_basis, gradient_basis); } -template -void SumFactorizedOperators::gradient_matrix_vector_mult( +template +template +void SumFactorizedOperators::gradient_matrix_vector_mult( const std::vector &input_vect, dealii::Tensor<1,dim,std::vector> &output_vect, const dealii::FullMatrix &basis_x, @@ -456,10 +459,11 @@ void SumFactorizedOperators::gradient_matrix_vector_mult( } } -template -void SumFactorizedOperators::inner_product( +template +template +void SumFactorizedOperators::inner_product( const std::vector &input_vect, - const std::vector &weight_vect, + const std::vector &weight_vect, std::vector &output_vect, const dealii::FullMatrix &basis_x, const dealii::FullMatrix &basis_y, @@ -512,7 +516,7 @@ void SumFactorizedOperators::inner_product( } } - std::vector new_input_vect(input_vect.size()); + std::vector new_input_vect(input_vect.size()); for(unsigned int iquad=0; iquad::inner_product( this->matrix_vector_mult(new_input_vect, output_vect, basis_x_trans, basis_y_trans, basis_z_trans, adding, factor); } -template -void SumFactorizedOperators::inner_product_1D( +template +template +void SumFactorizedOperators::inner_product_1D( const std::vector &input_vect, - const std::vector &weight_vect, + const std::vector &weight_vect, std::vector &output_vect, const dealii::FullMatrix &basis_x, const bool adding, @@ -532,11 +537,11 @@ void SumFactorizedOperators::inner_product_1D( this->inner_product(input_vect, weight_vect, output_vect, basis_x, basis_x, basis_x, adding, factor); } -template -void SumFactorizedOperators::divergence_two_pt_flux_Hadamard_product( - const dealii::Tensor<1,dim,dealii::FullMatrix> &input_mat, - std::vector &output_vect, - const std::vector &weights, +template +void SumFactorizedOperators::divergence_two_pt_flux_Hadamard_product( + const dealii::Tensor<1,dim,dealii::FullMatrix> &input_mat, + std::vector &output_vect, + const std::vector &weights, const dealii::FullMatrix &basis, const double scaling) { @@ -598,12 +603,12 @@ void SumFactorizedOperators::divergence_two_pt_flux_Hadamard_p } } -template -void SumFactorizedOperators::surface_two_pt_flux_Hadamard_product( - const dealii::FullMatrix &input_mat, - std::vector &output_vect_vol, - std::vector &output_vect_surf, - const std::vector &weights, +template +void SumFactorizedOperators::surface_two_pt_flux_Hadamard_product( + const dealii::FullMatrix &input_mat, + std::vector &output_vect_vol, + std::vector &output_vect_surf, + const std::vector &weights, const std::array,2> &surf_basis, const unsigned int iface, const unsigned int dim_not_zero, @@ -678,12 +683,12 @@ void SumFactorizedOperators::surface_two_pt_flux_Hadamard_prod -template -void SumFactorizedOperators::two_pt_flux_Hadamard_product( - const dealii::FullMatrix &input_mat, - dealii::FullMatrix &output_mat, +template +void SumFactorizedOperators::two_pt_flux_Hadamard_product( + const dealii::FullMatrix &input_mat, + dealii::FullMatrix &output_mat, const dealii::FullMatrix &basis, - const std::vector &weights, + const std::vector &weights, const int direction) { assert(input_mat.size() == output_mat.size()); @@ -791,11 +796,11 @@ void SumFactorizedOperators::two_pt_flux_Hadamard_product( } } -template -void SumFactorizedOperators::Hadamard_product( - const dealii::FullMatrix &input_mat1, - const dealii::FullMatrix &input_mat2, - dealii::FullMatrix &output_mat) +template +void SumFactorizedOperators::Hadamard_product( + const dealii::FullMatrix &input_mat1, + const dealii::FullMatrix &input_mat2, + dealii::FullMatrix &output_mat) { const unsigned int rows = input_mat1.m(); const unsigned int columns = input_mat1.n(); @@ -810,8 +815,27 @@ void SumFactorizedOperators::Hadamard_product( } } -template -void SumFactorizedOperators::sum_factorized_Hadamard_sparsity_pattern( +template +template +void SumFactorizedOperators::Hadamard_product_AD_vector( + const dealii::FullMatrix &input_mat, + const std::vector &input_vect, + std::vector &output_vect) +{ + const unsigned int rows = input_mat.m(); + const unsigned int columns = input_mat.n(); + assert(rows * columns == input_vect.size()); + + for(unsigned int irow=0; irow +void SumFactorizedOperators::sum_factorized_Hadamard_sparsity_pattern( const unsigned int rows_size, const unsigned int columns_size, std::vector> &rows, @@ -875,8 +899,8 @@ void SumFactorizedOperators::sum_factorized_Hadamard_sparsity_ } } } -template -void SumFactorizedOperators::sum_factorized_Hadamard_basis_assembly( +template +void SumFactorizedOperators::sum_factorized_Hadamard_basis_assembly( const unsigned int rows_size_1D, const unsigned int columns_size_1D, const std::vector> &rows, @@ -928,8 +952,8 @@ void SumFactorizedOperators::sum_factorized_Hadamard_basis_ass } } -template -void SumFactorizedOperators::sum_factorized_Hadamard_surface_sparsity_pattern( +template +void SumFactorizedOperators::sum_factorized_Hadamard_surface_sparsity_pattern( const unsigned int rows_size, const unsigned int columns_size, std::vector &rows, @@ -996,8 +1020,8 @@ void SumFactorizedOperators::sum_factorized_Hadamard_surface_s } } } -template -void SumFactorizedOperators::sum_factorized_Hadamard_surface_basis_assembly( +template +void SumFactorizedOperators::sum_factorized_Hadamard_surface_basis_assembly( const unsigned int rows_size, const unsigned int columns_size_1D, const std::vector &rows, @@ -1067,19 +1091,19 @@ void SumFactorizedOperators::sum_factorized_Hadamard_surface_b * ******************************************/ -template -basis_functions::basis_functions( +template +basis_functions::basis_functions( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void basis_functions::build_1D_volume_operator( +template +void basis_functions::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -1098,8 +1122,8 @@ void basis_functions::build_1D_volume_operator( } } -template -void basis_functions::build_1D_gradient_operator( +template +void basis_functions::build_1D_gradient_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -1118,8 +1142,8 @@ void basis_functions::build_1D_gradient_operator( } } -template -void basis_functions::build_1D_surface_operator( +template +void basis_functions::build_1D_surface_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<0> &face_quadrature) { @@ -1145,8 +1169,8 @@ void basis_functions::build_1D_surface_operator( } } -template -void basis_functions::build_1D_surface_gradient_operator( +template +void basis_functions::build_1D_surface_gradient_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<0> &face_quadrature) { @@ -1172,19 +1196,19 @@ void basis_functions::build_1D_surface_gradient_operator( } } -template -vol_integral_basis::vol_integral_basis( +template +vol_integral_basis::vol_integral_basis( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void vol_integral_basis::build_1D_volume_operator( +template +void vol_integral_basis::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -1204,19 +1228,19 @@ void vol_integral_basis::build_1D_volume_operator( } } -template -local_mass::local_mass( +template +local_mass::local_mass( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void local_mass::build_1D_volume_operator( +template +void local_mass::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -1249,11 +1273,11 @@ void local_mass::build_1D_volume_operator( } } -template -dealii::FullMatrix local_mass::build_dim_mass_matrix( +template +dealii::FullMatrix local_mass::build_dim_mass_matrix( const int nstate, const unsigned int n_dofs, const unsigned int n_quad_pts, - basis_functions &basis, + basis_functions &basis, const std::vector &det_Jac, const std::vector &quad_weights) @@ -1288,21 +1312,21 @@ dealii::FullMatrix local_mass::build_dim_mass_matrix( return mass_matrix_dim; } -template -local_basis_stiffness::local_basis_stiffness( +template +local_basis_stiffness::local_basis_stiffness( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input, const bool store_skew_symmetric_form_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) , store_skew_symmetric_form(store_skew_symmetric_form_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void local_basis_stiffness::build_1D_volume_operator( +template +void local_basis_stiffness::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -1341,26 +1365,26 @@ void local_basis_stiffness::build_1D_volume_operator( } } -template -modal_basis_differential_operator::modal_basis_differential_operator( +template +modal_basis_differential_operator::modal_basis_differential_operator( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void modal_basis_differential_operator::build_1D_volume_operator( +template +void modal_basis_differential_operator::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { const unsigned int n_dofs = finite_element.dofs_per_cell; - local_mass mass_matrix(this->nstate, this->max_degree, this->max_grid_degree); + local_mass mass_matrix(this->nstate, this->max_degree, this->max_grid_degree); mass_matrix.build_1D_volume_operator(finite_element, quadrature); - local_basis_stiffness stiffness(this->nstate, this->max_degree, this->max_grid_degree); + local_basis_stiffness stiffness(this->nstate, this->max_degree, this->max_grid_degree); stiffness.build_1D_volume_operator(finite_element, quadrature); //allocate this->oneD_vol_operator.reinit(n_dofs,n_dofs); @@ -1370,19 +1394,19 @@ void modal_basis_differential_operator::build_1D_volume_operat inv_mass.mmult(this->oneD_vol_operator, stiffness.oneD_vol_operator); } -template -derivative_p::derivative_p( +template +derivative_p::derivative_p( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void derivative_p::build_1D_volume_operator( +template +void derivative_p::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -1394,7 +1418,7 @@ void derivative_p::build_1D_volume_operator( this->oneD_vol_operator[idof][idof] = 1.0;//set it equal to identity } //get modal basis differential operator - modal_basis_differential_operator diff_oper(this->nstate, this->max_degree, this->max_grid_degree); + modal_basis_differential_operator diff_oper(this->nstate, this->max_degree, this->max_grid_degree); diff_oper.build_1D_volume_operator(finite_element, quadrature); //loop and solve for(unsigned int idegree=0; idegree< this->max_degree; idegree++){ @@ -1404,13 +1428,13 @@ void derivative_p::build_1D_volume_operator( } } -template -local_Flux_Reconstruction_operator::local_Flux_Reconstruction_operator( +template +local_Flux_Reconstruction_operator::local_Flux_Reconstruction_operator( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input, const Parameters::AllParameters::Flux_Reconstruction FR_param_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) , FR_param_type(FR_param_input) { //Initialize to the max degrees @@ -1419,8 +1443,8 @@ local_Flux_Reconstruction_operator::local_Flux_Reconstruction_ get_FR_correction_parameter(this->max_degree, FR_param); } -template -void local_Flux_Reconstruction_operator::get_Huynh_g2_parameter ( +template +void local_Flux_Reconstruction_operator::get_Huynh_g2_parameter ( const unsigned int curr_cell_degree, double &c) { @@ -1430,8 +1454,8 @@ void local_Flux_Reconstruction_operator::get_Huynh_g2_paramete c = 2.0 * (curr_cell_degree+1)/( curr_cell_degree*((2.0*curr_cell_degree+1.0)*(pow(pfact*cp,2)))); c/=2.0;//since orthonormal } -template -void local_Flux_Reconstruction_operator::get_spectral_difference_parameter ( +template +void local_Flux_Reconstruction_operator::get_spectral_difference_parameter ( const unsigned int curr_cell_degree, double &c) { @@ -1441,8 +1465,8 @@ void local_Flux_Reconstruction_operator::get_spectral_differen c = 2.0 * (curr_cell_degree)/( (curr_cell_degree+1.0)*((2.0*curr_cell_degree+1.0)*(pow(pfact*cp,2)))); c/=2.0;//since orthonormal } -template -void local_Flux_Reconstruction_operator::get_c_negative_FR_parameter ( +template +void local_Flux_Reconstruction_operator::get_c_negative_FR_parameter ( const unsigned int curr_cell_degree, double &c) { @@ -1452,16 +1476,16 @@ void local_Flux_Reconstruction_operator::get_c_negative_FR_par c = - 2.0 / ( pow((2.0*curr_cell_degree+1.0)*(pow(pfact*cp,2)),1.0)); c/=2.0;//since orthonormal } -template -void local_Flux_Reconstruction_operator::get_c_negative_divided_by_two_FR_parameter ( +template +void local_Flux_Reconstruction_operator::get_c_negative_divided_by_two_FR_parameter ( const unsigned int curr_cell_degree, double &c) { get_c_negative_FR_parameter(curr_cell_degree, c); c/=2.0; } -template -void local_Flux_Reconstruction_operator::get_c_plus_parameter ( +template +void local_Flux_Reconstruction_operator::get_c_plus_parameter ( const unsigned int curr_cell_degree, double &c) { @@ -1488,8 +1512,8 @@ void local_Flux_Reconstruction_operator::get_c_plus_parameter c/=pow(pow(2.0,curr_cell_degree),2);//since ref elem [0,1] } -template -void local_Flux_Reconstruction_operator::get_FR_correction_parameter ( +template +void local_Flux_Reconstruction_operator::get_FR_correction_parameter ( const unsigned int curr_cell_degree, double &c) { @@ -1518,8 +1542,8 @@ void local_Flux_Reconstruction_operator::get_FR_correction_par get_c_plus_parameter(curr_cell_degree, c); } } -template -void local_Flux_Reconstruction_operator::build_local_Flux_Reconstruction_operator( +template +void local_Flux_Reconstruction_operator::build_local_Flux_Reconstruction_operator( const dealii::FullMatrix &local_Mass_Matrix, const dealii::FullMatrix &pth_derivative, const unsigned int n_dofs, @@ -1534,8 +1558,8 @@ void local_Flux_Reconstruction_operator::build_local_Flux_Reco } -template -void local_Flux_Reconstruction_operator::build_1D_volume_operator( +template +void local_Flux_Reconstruction_operator::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -1543,17 +1567,17 @@ void local_Flux_Reconstruction_operator::build_1D_volume_opera //allocate the volume operator this->oneD_vol_operator.reinit(n_dofs, n_dofs); //build the FR correction operator - derivative_p pth_derivative(this->nstate, this->max_degree, this->max_grid_degree); + derivative_p pth_derivative(this->nstate, this->max_degree, this->max_grid_degree); pth_derivative.build_1D_volume_operator(finite_element, quadrature); - local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); + local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); local_Mass_Matrix.build_1D_volume_operator(finite_element, quadrature); //solves build_local_Flux_Reconstruction_operator(local_Mass_Matrix.oneD_vol_operator, pth_derivative.oneD_vol_operator, n_dofs, FR_param, this->oneD_vol_operator); } -template -dealii::FullMatrix local_Flux_Reconstruction_operator::build_dim_Flux_Reconstruction_operator_directly( +template +dealii::FullMatrix local_Flux_Reconstruction_operator::build_dim_Flux_Reconstruction_operator_directly( const int nstate, const unsigned int n_dofs, dealii::FullMatrix &pth_deriv, @@ -1613,8 +1637,8 @@ dealii::FullMatrix local_Flux_Reconstruction_operator: return Flux_Reconstruction_operator; } -template -dealii::FullMatrix local_Flux_Reconstruction_operator::build_dim_Flux_Reconstruction_operator( +template +dealii::FullMatrix local_Flux_Reconstruction_operator::build_dim_Flux_Reconstruction_operator( const dealii::FullMatrix &local_Mass_Matrix, const int nstate, const unsigned int n_dofs) @@ -1649,13 +1673,13 @@ dealii::FullMatrix local_Flux_Reconstruction_operator: } -template -local_Flux_Reconstruction_operator_aux::local_Flux_Reconstruction_operator_aux( +template +local_Flux_Reconstruction_operator_aux::local_Flux_Reconstruction_operator_aux( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input, const Parameters::AllParameters::Flux_Reconstruction_Aux FR_param_aux_input) - : local_Flux_Reconstruction_operator::local_Flux_Reconstruction_operator(nstate_input, max_degree_input, grid_degree_input, Parameters::AllParameters::Flux_Reconstruction::cDG) + : local_Flux_Reconstruction_operator::local_Flux_Reconstruction_operator(nstate_input, max_degree_input, grid_degree_input, Parameters::AllParameters::Flux_Reconstruction::cDG) , FR_param_aux_type(FR_param_aux_input) { //Initialize to the max degrees @@ -1664,8 +1688,8 @@ local_Flux_Reconstruction_operator_aux::local_Flux_Reconstruct get_FR_aux_correction_parameter(this->max_degree, FR_param_aux); } -template -void local_Flux_Reconstruction_operator_aux::get_FR_aux_correction_parameter ( +template +void local_Flux_Reconstruction_operator_aux::get_FR_aux_correction_parameter ( const unsigned int curr_cell_degree, double &k) { @@ -1692,16 +1716,16 @@ void local_Flux_Reconstruction_operator_aux::get_FR_aux_correc this->get_c_plus_parameter(curr_cell_degree, k); } } -template -void local_Flux_Reconstruction_operator_aux::build_1D_volume_operator( +template +void local_Flux_Reconstruction_operator_aux::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { const unsigned int n_dofs = finite_element.dofs_per_cell; //build the FR correction operator - derivative_p pth_derivative(this->nstate, this->max_degree, this->max_grid_degree); + derivative_p pth_derivative(this->nstate, this->max_degree, this->max_grid_degree); pth_derivative.build_1D_volume_operator(finite_element, quadrature); - local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); + local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); local_Mass_Matrix.build_1D_volume_operator(finite_element, quadrature); //allocate the volume operator this->oneD_vol_operator.reinit(n_dofs, n_dofs); @@ -1709,35 +1733,35 @@ void local_Flux_Reconstruction_operator_aux::build_1D_volume_o this->build_local_Flux_Reconstruction_operator(local_Mass_Matrix.oneD_vol_operator, pth_derivative.oneD_vol_operator, n_dofs, FR_param_aux, this->oneD_vol_operator); } -template -vol_projection_operator::vol_projection_operator( +template +vol_projection_operator::vol_projection_operator( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void vol_projection_operator::compute_local_vol_projection_operator( +template +void vol_projection_operator::compute_local_vol_projection_operator( const dealii::FullMatrix &norm_matrix_inverse, const dealii::FullMatrix &integral_vol_basis, dealii::FullMatrix &volume_projection) { norm_matrix_inverse.mTmult(volume_projection, integral_vol_basis); } -template -void vol_projection_operator::build_1D_volume_operator( +template +void vol_projection_operator::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { const unsigned int n_dofs = finite_element.dofs_per_cell; const unsigned int n_quad_pts = quadrature.size(); - vol_integral_basis integral_vol_basis(this->nstate, this->max_degree, this->max_grid_degree); + vol_integral_basis integral_vol_basis(this->nstate, this->max_degree, this->max_grid_degree); integral_vol_basis.build_1D_volume_operator(finite_element, quadrature); - local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); + local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); local_Mass_Matrix.build_1D_volume_operator(finite_element, quadrature); dealii::FullMatrix mass_inv(n_dofs); mass_inv.invert(local_Mass_Matrix.oneD_vol_operator); @@ -1747,14 +1771,14 @@ void vol_projection_operator::build_1D_volume_operator( compute_local_vol_projection_operator(mass_inv, integral_vol_basis.oneD_vol_operator, this->oneD_vol_operator); } -template -vol_projection_operator_FR::vol_projection_operator_FR( +template +vol_projection_operator_FR::vol_projection_operator_FR( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input, const Parameters::AllParameters::Flux_Reconstruction FR_param_input, const bool store_transpose_input) - : vol_projection_operator::vol_projection_operator(nstate_input, max_degree_input, grid_degree_input) + : vol_projection_operator::vol_projection_operator(nstate_input, max_degree_input, grid_degree_input) , store_transpose(store_transpose_input) , FR_param_type(FR_param_input) { @@ -1762,16 +1786,16 @@ vol_projection_operator_FR::vol_projection_operator_FR( current_degree = max_degree_input; } -template -void vol_projection_operator_FR::build_1D_volume_operator( +template +void vol_projection_operator_FR::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { const unsigned int n_dofs = finite_element.dofs_per_cell; const unsigned int n_quad_pts = quadrature.size(); - vol_integral_basis integral_vol_basis(this->nstate, this->max_degree, this->max_grid_degree); + vol_integral_basis integral_vol_basis(this->nstate, this->max_degree, this->max_grid_degree); integral_vol_basis.build_1D_volume_operator(finite_element, quadrature); - FR_mass_inv local_FR_Mass_Matrix_inv(this->nstate, this->max_degree, this->max_grid_degree, FR_param_type); + FR_mass_inv local_FR_Mass_Matrix_inv(this->nstate, this->max_degree, this->max_grid_degree, FR_param_type); local_FR_Mass_Matrix_inv.build_1D_volume_operator(finite_element, quadrature); //allocate the volume operator this->oneD_vol_operator.reinit(n_dofs, n_quad_pts); @@ -1787,14 +1811,14 @@ void vol_projection_operator_FR::build_1D_volume_operator( } } } -template -vol_projection_operator_FR_aux::vol_projection_operator_FR_aux( +template +vol_projection_operator_FR_aux::vol_projection_operator_FR_aux( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input, const Parameters::AllParameters::Flux_Reconstruction_Aux FR_param_input, const bool store_transpose_input) - : vol_projection_operator::vol_projection_operator(nstate_input, max_degree_input, grid_degree_input) + : vol_projection_operator::vol_projection_operator(nstate_input, max_degree_input, grid_degree_input) , store_transpose(store_transpose_input) , FR_param_type(FR_param_input) { @@ -1802,16 +1826,16 @@ vol_projection_operator_FR_aux::vol_projection_operator_FR_aux current_degree = max_degree_input; } -template -void vol_projection_operator_FR_aux::build_1D_volume_operator( +template +void vol_projection_operator_FR_aux::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { const unsigned int n_dofs = finite_element.dofs_per_cell; const unsigned int n_quad_pts = quadrature.size(); - vol_integral_basis integral_vol_basis(this->nstate, this->max_degree, this->max_grid_degree); + vol_integral_basis integral_vol_basis(this->nstate, this->max_degree, this->max_grid_degree); integral_vol_basis.build_1D_volume_operator(finite_element, quadrature); - FR_mass_inv_aux local_FR_Mass_Matrix_inv(this->nstate, this->max_degree, this->max_grid_degree, FR_param_type); + FR_mass_inv_aux local_FR_Mass_Matrix_inv(this->nstate, this->max_degree, this->max_grid_degree, FR_param_type); local_FR_Mass_Matrix_inv.build_1D_volume_operator(finite_element, quadrature); //allocate the volume operator this->oneD_vol_operator.reinit(n_dofs, n_quad_pts); @@ -1828,28 +1852,28 @@ void vol_projection_operator_FR_aux::build_1D_volume_operator( } } -template -FR_mass_inv::FR_mass_inv( +template +FR_mass_inv::FR_mass_inv( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input, const Parameters::AllParameters::Flux_Reconstruction FR_param_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) , FR_param_type(FR_param_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void FR_mass_inv::build_1D_volume_operator( +template +void FR_mass_inv::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { const unsigned int n_dofs = finite_element.dofs_per_cell; - local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); + local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); local_Mass_Matrix.build_1D_volume_operator(finite_element, quadrature); - local_Flux_Reconstruction_operator local_FR_oper(this->nstate, this->max_degree, this->max_grid_degree, FR_param_type); + local_Flux_Reconstruction_operator local_FR_oper(this->nstate, this->max_degree, this->max_grid_degree, FR_param_type); local_FR_oper.build_1D_volume_operator(finite_element, quadrature); dealii::FullMatrix FR_mass_matrix(n_dofs); FR_mass_matrix.add(1.0, local_Mass_Matrix.oneD_vol_operator, 1.0, local_FR_oper.oneD_vol_operator); @@ -1859,28 +1883,28 @@ void FR_mass_inv::build_1D_volume_operator( this->oneD_vol_operator.invert(FR_mass_matrix); } -template -FR_mass_inv_aux::FR_mass_inv_aux( +template +FR_mass_inv_aux::FR_mass_inv_aux( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input, const Parameters::AllParameters::Flux_Reconstruction_Aux FR_param_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) , FR_param_type(FR_param_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void FR_mass_inv_aux::build_1D_volume_operator( +template +void FR_mass_inv_aux::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { const unsigned int n_dofs = finite_element.dofs_per_cell; - local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); + local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); local_Mass_Matrix.build_1D_volume_operator(finite_element, quadrature); - local_Flux_Reconstruction_operator_aux local_FR_oper(this->nstate, this->max_degree, this->max_grid_degree, FR_param_type); + local_Flux_Reconstruction_operator_aux local_FR_oper(this->nstate, this->max_degree, this->max_grid_degree, FR_param_type); local_FR_oper.build_1D_volume_operator(finite_element, quadrature); dealii::FullMatrix FR_mass_matrix(n_dofs); FR_mass_matrix.add(1.0, local_Mass_Matrix.oneD_vol_operator, 1.0, local_FR_oper.oneD_vol_operator); @@ -1889,28 +1913,28 @@ void FR_mass_inv_aux::build_1D_volume_operator( //solves this->oneD_vol_operator.invert(FR_mass_matrix); } -template -FR_mass::FR_mass( +template +FR_mass::FR_mass( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input, const Parameters::AllParameters::Flux_Reconstruction FR_param_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) , FR_param_type(FR_param_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void FR_mass::build_1D_volume_operator( +template +void FR_mass::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { const unsigned int n_dofs = finite_element.dofs_per_cell; - local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); + local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); local_Mass_Matrix.build_1D_volume_operator(finite_element, quadrature); - local_Flux_Reconstruction_operator local_FR_oper(this->nstate, this->max_degree, this->max_grid_degree, FR_param_type); + local_Flux_Reconstruction_operator local_FR_oper(this->nstate, this->max_degree, this->max_grid_degree, FR_param_type); local_FR_oper.build_1D_volume_operator(finite_element, quadrature); dealii::FullMatrix FR_mass_matrix(n_dofs); FR_mass_matrix.add(1.0, local_Mass_Matrix.oneD_vol_operator, 1.0, local_FR_oper.oneD_vol_operator); @@ -1919,28 +1943,28 @@ void FR_mass::build_1D_volume_operator( //solves this->oneD_vol_operator.add(1.0, FR_mass_matrix); } -template -FR_mass_aux::FR_mass_aux( +template +FR_mass_aux::FR_mass_aux( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input, const Parameters::AllParameters::Flux_Reconstruction_Aux FR_param_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) , FR_param_type(FR_param_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void FR_mass_aux::build_1D_volume_operator( +template +void FR_mass_aux::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { const unsigned int n_dofs = finite_element.dofs_per_cell; - local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); + local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); local_Mass_Matrix.build_1D_volume_operator(finite_element, quadrature); - local_Flux_Reconstruction_operator_aux local_FR_oper(this->nstate, this->max_degree, this->max_grid_degree, FR_param_type); + local_Flux_Reconstruction_operator_aux local_FR_oper(this->nstate, this->max_degree, this->max_grid_degree, FR_param_type); local_FR_oper.build_1D_volume_operator(finite_element, quadrature); dealii::FullMatrix FR_mass_matrix(n_dofs); FR_mass_matrix.add(1.0, local_Mass_Matrix.oneD_vol_operator, 1.0, local_FR_oper.oneD_vol_operator); @@ -1950,19 +1974,19 @@ void FR_mass_aux::build_1D_volume_operator( this->oneD_vol_operator.add(1.0, FR_mass_matrix); } -template -vol_integral_gradient_basis::vol_integral_gradient_basis( +template +vol_integral_gradient_basis::vol_integral_gradient_basis( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void vol_integral_gradient_basis::build_1D_gradient_operator( +template +void vol_integral_gradient_basis::build_1D_gradient_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -1988,19 +2012,19 @@ void vol_integral_gradient_basis::build_1D_gradient_operator( * *************************************/ -template -face_integral_basis::face_integral_basis( +template +face_integral_basis::face_integral_basis( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void face_integral_basis::build_1D_surface_operator( +template +void face_integral_basis::build_1D_surface_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<0> &face_quadrature) { @@ -2028,32 +2052,32 @@ void face_integral_basis::build_1D_surface_operator( } } -template -lifting_operator::lifting_operator( +template +lifting_operator::lifting_operator( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void lifting_operator::build_1D_volume_operator( +template +void lifting_operator::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { const unsigned int n_dofs = finite_element.dofs_per_cell; - local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); + local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); local_Mass_Matrix.build_1D_volume_operator(finite_element, quadrature); //allocate the volume operator this->oneD_vol_operator.reinit(n_dofs, n_dofs); //solves this->oneD_vol_operator.add(1.0, local_Mass_Matrix.oneD_vol_operator); } -template -void lifting_operator::build_local_surface_lifting_operator( +template +void lifting_operator::build_local_surface_lifting_operator( const unsigned int n_dofs, const dealii::FullMatrix &norm_matrix, const dealii::FullMatrix &face_integral, @@ -2063,8 +2087,8 @@ void lifting_operator::build_local_surface_lifting_operator( norm_inv.invert(norm_matrix); norm_inv.mTmult(lifting, face_integral); } -template -void lifting_operator::build_1D_surface_operator( +template +void lifting_operator::build_1D_surface_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<0> &face_quadrature) { @@ -2072,7 +2096,7 @@ void lifting_operator::build_1D_surface_operator( const unsigned int n_dofs = finite_element.dofs_per_cell; const unsigned int n_faces_1D = n_faces / dim; //create surface integral of basis functions - face_integral_basis basis_int_facet(this->nstate, this->max_degree, this->max_grid_degree); + face_integral_basis basis_int_facet(this->nstate, this->max_degree, this->max_grid_degree); basis_int_facet.build_1D_surface_operator(finite_element, face_quadrature); //loop and store for(unsigned int iface=0; iface::build_1D_surface_operator( } } -template -lifting_operator_FR::lifting_operator_FR( +template +lifting_operator_FR::lifting_operator_FR( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input, const Parameters::AllParameters::Flux_Reconstruction FR_param_input) - : lifting_operator::lifting_operator(nstate_input, max_degree_input, grid_degree_input) + : lifting_operator::lifting_operator(nstate_input, max_degree_input, grid_degree_input) , FR_param_type(FR_param_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void lifting_operator_FR::build_1D_volume_operator( +template +void lifting_operator_FR::build_1D_volume_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { const unsigned int n_dofs = finite_element.dofs_per_cell; - local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); + local_mass local_Mass_Matrix(this->nstate, this->max_degree, this->max_grid_degree); local_Mass_Matrix.build_1D_volume_operator(finite_element, quadrature); - local_Flux_Reconstruction_operator local_FR(this->nstate, this->max_degree, this->max_grid_degree, FR_param_type); + local_Flux_Reconstruction_operator local_FR(this->nstate, this->max_degree, this->max_grid_degree, FR_param_type); local_FR.build_1D_volume_operator(finite_element, quadrature); //allocate the volume operator this->oneD_vol_operator.reinit(n_dofs, n_dofs); @@ -2111,8 +2135,8 @@ void lifting_operator_FR::build_1D_volume_operator( this->oneD_vol_operator.add(1.0, local_Mass_Matrix.oneD_vol_operator); this->oneD_vol_operator.add(1.0, local_FR.oneD_vol_operator); } -template -void lifting_operator_FR::build_1D_surface_operator( +template +void lifting_operator_FR::build_1D_surface_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<0> &face_quadrature) { @@ -2120,7 +2144,7 @@ void lifting_operator_FR::build_1D_surface_operator( const unsigned int n_dofs = finite_element.dofs_per_cell; const unsigned int n_faces_1D = n_faces / dim; //create surface integral of basis functions - face_integral_basis basis_int_facet(this->nstate, this->max_degree, this->max_grid_degree); + face_integral_basis basis_int_facet(this->nstate, this->max_degree, this->max_grid_degree); basis_int_facet.build_1D_surface_operator(finite_element, face_quadrature); //loop and store for(unsigned int iface=0; iface::build_1D_surface_operator( * ******************************************************************************/ -template -mapping_shape_functions::mapping_shape_functions( +template +mapping_shape_functions::mapping_shape_functions( const int nstate_input, const unsigned int max_degree_input, const unsigned int grid_degree_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) , mapping_shape_functions_grid_nodes(nstate_input, max_degree_input, grid_degree_input) , mapping_shape_functions_flux_nodes(nstate_input, max_degree_input, grid_degree_input) { @@ -2151,8 +2175,8 @@ mapping_shape_functions::mapping_shape_functions( current_grid_degree = grid_degree_input; } -template -void mapping_shape_functions::build_1D_shape_functions_at_grid_nodes( +template +void mapping_shape_functions::build_1D_shape_functions_at_grid_nodes( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -2160,8 +2184,8 @@ void mapping_shape_functions::build_1D_shape_functions_at_grid mapping_shape_functions_grid_nodes.build_1D_volume_operator(finite_element, quadrature); mapping_shape_functions_grid_nodes.build_1D_gradient_operator(finite_element, quadrature); } -template -void mapping_shape_functions::build_1D_shape_functions_at_flux_nodes( +template +void mapping_shape_functions::build_1D_shape_functions_at_flux_nodes( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature, const dealii::Quadrature<0> &face_quadrature) @@ -2172,8 +2196,8 @@ void mapping_shape_functions::build_1D_shape_functions_at_flux mapping_shape_functions_flux_nodes.build_1D_surface_gradient_operator(finite_element, face_quadrature); } -template -void mapping_shape_functions::build_1D_shape_functions_at_volume_flux_nodes( +template +void mapping_shape_functions::build_1D_shape_functions_at_volume_flux_nodes( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -2195,7 +2219,7 @@ metric_operators::metric_operators( const bool store_vol_flux_nodes_input, const bool store_surf_flux_nodes_input, const bool store_Jacobian_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate_input, max_degree_input, grid_degree_input) , store_Jacobian(store_Jacobian_input) , store_vol_flux_nodes(store_vol_flux_nodes_input) , store_surf_flux_nodes(store_surf_flux_nodes_input) @@ -2222,12 +2246,12 @@ void metric_operators::transform_reference_to_physical( dealii::Tensor<1,dim,real> &phys) { for(int idim=0; idim::transform_reference_unit_normal_to_phys std::vector> &phys) { for(unsigned int iquad=0; iquad::build_determinant_volume_metric_Jacobia const unsigned int n_quad_pts, const unsigned int /*n_metric_dofs*/,//dofs of metric basis. NOTE: this is the number of mapping support points const std::array,dim> &mapping_support_points, - mapping_shape_functions &mapping_basis) + mapping_shape_functions &mapping_basis) { det_Jac_vol.resize(n_quad_pts); //compute determinant of metric Jacobian @@ -2295,7 +2321,7 @@ void metric_operators::build_volume_metric_operators( const unsigned int n_quad_pts, const unsigned int n_metric_dofs,//dofs of metric basis. NOTE: this is the number of mapping support points const std::array,dim> &mapping_support_points, - mapping_shape_functions &mapping_basis, + mapping_shape_functions &mapping_basis, const bool use_invariant_curl_form) { det_Jac_vol.resize(n_quad_pts); @@ -2353,7 +2379,7 @@ void metric_operators::build_facet_metric_operators( const unsigned int n_quad_pts, const unsigned int n_metric_dofs,//dofs of metric basis. NOTE: this is the number of mapping support points const std::array,dim> &mapping_support_points, - mapping_shape_functions &mapping_basis, + mapping_shape_functions &mapping_basis, const bool use_invariant_curl_form) { det_Jac_surf.resize(n_quad_pts); @@ -2490,7 +2516,7 @@ void metric_operators::build_determinant_metric_Jacobian( //mapping support points must be passed as a vector[dim][n_metric_dofs] assert(pow(this->max_grid_degree+1,dim) == mapping_support_points[0].size()); - std::vector> Jacobian_flux_nodes(n_quad_pts); + std::vector> Jacobian_flux_nodes(n_quad_pts); this->build_metric_Jacobian(n_quad_pts, mapping_support_points, basis_x_flux_nodes, @@ -2546,7 +2572,7 @@ void metric_operators::build_local_metric_cofactor_matrix( std::fill(metric_cofactor[0][0].begin(), metric_cofactor[0][0].end(), 1.0); } if (dim == 2){ - std::vector> Jacobian_flux_nodes(n_quad_pts); + std::vector> Jacobian_flux_nodes(n_quad_pts); this->build_metric_Jacobian(n_quad_pts, mapping_support_points, basis_x_flux_nodes, @@ -2739,25 +2765,25 @@ void metric_operators::compute_local_3D_cofactor( * **********************************/ //Constructor -template -SumFactorizedOperatorsState::SumFactorizedOperatorsState( +template +SumFactorizedOperatorsState::SumFactorizedOperatorsState( const unsigned int max_degree_input, const unsigned int grid_degree_input) - : SumFactorizedOperators::SumFactorizedOperators(nstate, max_degree_input, grid_degree_input) + : SumFactorizedOperators::SumFactorizedOperators(nstate, max_degree_input, grid_degree_input) {} -template -basis_functions_state::basis_functions_state( +template +basis_functions_state::basis_functions_state( const unsigned int max_degree_input, const unsigned int grid_degree_input) - : SumFactorizedOperatorsState::SumFactorizedOperatorsState(max_degree_input, grid_degree_input) + : SumFactorizedOperatorsState::SumFactorizedOperatorsState(max_degree_input, grid_degree_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void basis_functions_state::build_1D_volume_state_operator( +template +void basis_functions_state::build_1D_volume_state_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -2780,8 +2806,8 @@ void basis_functions_state::build_1D_volume_state_opera } } -template -void basis_functions_state::build_1D_gradient_state_operator( +template +void basis_functions_state::build_1D_gradient_state_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -2801,8 +2827,8 @@ void basis_functions_state::build_1D_gradient_state_ope } } } -template -void basis_functions_state::build_1D_surface_state_operator( +template +void basis_functions_state::build_1D_surface_state_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<0> &face_quadrature) { @@ -2828,18 +2854,18 @@ void basis_functions_state::build_1D_surface_state_oper } } -template -flux_basis_functions_state::flux_basis_functions_state( +template +flux_basis_functions_state::flux_basis_functions_state( const unsigned int max_degree_input, const unsigned int grid_degree_input) - : SumFactorizedOperatorsState::SumFactorizedOperatorsState(max_degree_input, grid_degree_input) + : SumFactorizedOperatorsState::SumFactorizedOperatorsState(max_degree_input, grid_degree_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void flux_basis_functions_state::build_1D_volume_state_operator( +template +void flux_basis_functions_state::build_1D_volume_state_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -2861,8 +2887,8 @@ void flux_basis_functions_state::build_1D_volume_state_ } } -template -void flux_basis_functions_state::build_1D_gradient_state_operator( +template +void flux_basis_functions_state::build_1D_gradient_state_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -2881,8 +2907,8 @@ void flux_basis_functions_state::build_1D_gradient_stat } } } -template -void flux_basis_functions_state::build_1D_surface_state_operator( +template +void flux_basis_functions_state::build_1D_surface_state_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<0> &face_quadrature) { @@ -2906,18 +2932,18 @@ void flux_basis_functions_state::build_1D_surface_state } -template -local_flux_basis_stiffness::local_flux_basis_stiffness( +template +local_flux_basis_stiffness::local_flux_basis_stiffness( const unsigned int max_degree_input, const unsigned int grid_degree_input) - : flux_basis_functions_state::flux_basis_functions_state(max_degree_input, grid_degree_input) + : flux_basis_functions_state::flux_basis_functions_state(max_degree_input, grid_degree_input) { //Initialize to the max degrees current_degree = max_degree_input; } -template -void local_flux_basis_stiffness::build_1D_volume_state_operator( +template +void local_flux_basis_stiffness::build_1D_volume_state_operator( const dealii::FESystem<1,1> &finite_element, const dealii::Quadrature<1> &quadrature) { @@ -2946,62 +2972,584 @@ void local_flux_basis_stiffness::build_1D_volume_state_ } -template class OperatorsBase ; +template class OperatorsBase ; -template class SumFactorizedOperators ; +template class SumFactorizedOperators ; -template class SumFactorizedOperatorsState ; -template class SumFactorizedOperatorsState ; -template class SumFactorizedOperatorsState ; -template class SumFactorizedOperatorsState ; -template class SumFactorizedOperatorsState ; +template class SumFactorizedOperatorsState ; +template class SumFactorizedOperatorsState ; +template class SumFactorizedOperatorsState ; +template class SumFactorizedOperatorsState ; +template class SumFactorizedOperatorsState ; -template class basis_functions ; -template class vol_integral_basis ; -template class local_mass ; -template class local_basis_stiffness ; -template class modal_basis_differential_operator ; -template class derivative_p ; -template class local_Flux_Reconstruction_operator ; -template class local_Flux_Reconstruction_operator_aux ; -template class vol_projection_operator ; -template class vol_projection_operator_FR ; -template class vol_projection_operator_FR_aux ; -template class FR_mass_inv ; -template class FR_mass_inv_aux ; -template class FR_mass ; -template class FR_mass_aux ; -template class vol_integral_gradient_basis ; +template class basis_functions ; +template class vol_integral_basis ; +template class local_mass ; +template class local_basis_stiffness ; +template class modal_basis_differential_operator ; +template class derivative_p ; +template class local_Flux_Reconstruction_operator ; +template class local_Flux_Reconstruction_operator_aux ; +template class vol_projection_operator ; +template class vol_projection_operator_FR ; +template class vol_projection_operator_FR_aux ; +template class FR_mass_inv ; +template class FR_mass_inv_aux ; +template class FR_mass ; +template class FR_mass_aux ; +template class vol_integral_gradient_basis ; //template class basis_at_facet_cubature ; -template class face_integral_basis ; -template class lifting_operator ; -template class lifting_operator_FR ; +template class face_integral_basis ; +template class lifting_operator ; +template class lifting_operator_FR ; -template class mapping_shape_functions ; +template class mapping_shape_functions ; template class metric_operators ; +template class metric_operators ; +template class metric_operators ; +template class metric_operators ; +template class metric_operators ; //template class vol_metric_operators ; //template class vol_determinant_metric_Jacobian; //template class vol_metric_cofactor; //template class surface_metric_cofactor; // -template class basis_functions_state ; -template class basis_functions_state ; -template class basis_functions_state ; -template class basis_functions_state ; -template class basis_functions_state ; - -template class flux_basis_functions_state ; -template class flux_basis_functions_state ; -template class flux_basis_functions_state ; -template class flux_basis_functions_state ; -template class flux_basis_functions_state ; -template class local_flux_basis_stiffness ; -template class local_flux_basis_stiffness ; -template class local_flux_basis_stiffness ; -template class local_flux_basis_stiffness ; -template class local_flux_basis_stiffness ; +template class basis_functions_state ; +template class basis_functions_state ; +template class basis_functions_state ; +template class basis_functions_state ; +template class basis_functions_state ; + +template class flux_basis_functions_state ; +template class flux_basis_functions_state ; +template class flux_basis_functions_state ; +template class flux_basis_functions_state ; +template class flux_basis_functions_state ; +template class local_flux_basis_stiffness ; +template class local_flux_basis_stiffness ; +template class local_flux_basis_stiffness ; +template class local_flux_basis_stiffness ; +template class local_flux_basis_stiffness ; + +template void SumFactorizedOperators::matrix_vector_mult( + const std::vector &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const bool adding, + const double factor); +template void SumFactorizedOperators::matrix_vector_mult( + const std::vector &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const bool adding, + const double factor); +template void SumFactorizedOperators::matrix_vector_mult( + const std::vector &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const bool adding, + const double factor); +template void SumFactorizedOperators::matrix_vector_mult( + const std::vector &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const bool adding, + const double factor); +template void SumFactorizedOperators::matrix_vector_mult( + const std::vector &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const bool adding, + const double factor); + +template void SumFactorizedOperators::divergence_matrix_vector_mult( + const dealii::Tensor<1,PHILIP_DIM,std::vector> &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const dealii::FullMatrix &gradient_basis_x, + const dealii::FullMatrix &gradient_basis_y, + const dealii::FullMatrix &gradient_basis_z); +template void SumFactorizedOperators::divergence_matrix_vector_mult( + const dealii::Tensor<1,PHILIP_DIM,std::vector> &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const dealii::FullMatrix &gradient_basis_x, + const dealii::FullMatrix &gradient_basis_y, + const dealii::FullMatrix &gradient_basis_z); +template void SumFactorizedOperators::divergence_matrix_vector_mult( + const dealii::Tensor<1,PHILIP_DIM,std::vector> &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const dealii::FullMatrix &gradient_basis_x, + const dealii::FullMatrix &gradient_basis_y, + const dealii::FullMatrix &gradient_basis_z); +template void SumFactorizedOperators::divergence_matrix_vector_mult( + const dealii::Tensor<1,PHILIP_DIM,std::vector> &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const dealii::FullMatrix &gradient_basis_x, + const dealii::FullMatrix &gradient_basis_y, + const dealii::FullMatrix &gradient_basis_z); +template void SumFactorizedOperators::divergence_matrix_vector_mult( + const dealii::Tensor<1,PHILIP_DIM,std::vector> &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const dealii::FullMatrix &gradient_basis_x, + const dealii::FullMatrix &gradient_basis_y, + const dealii::FullMatrix &gradient_basis_z); + +template void SumFactorizedOperators::divergence_matrix_vector_mult_1D( + const dealii::Tensor<1,PHILIP_DIM,std::vector> &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis, + const dealii::FullMatrix &gradient_basis); +template void SumFactorizedOperators::divergence_matrix_vector_mult_1D( + const dealii::Tensor<1,PHILIP_DIM,std::vector> &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis, + const dealii::FullMatrix &gradient_basis); +template void SumFactorizedOperators::divergence_matrix_vector_mult_1D( + const dealii::Tensor<1,PHILIP_DIM,std::vector> &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis, + const dealii::FullMatrix &gradient_basis); +template void SumFactorizedOperators::divergence_matrix_vector_mult_1D( + const dealii::Tensor<1,PHILIP_DIM,std::vector> &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis, + const dealii::FullMatrix &gradient_basis); +template void SumFactorizedOperators::divergence_matrix_vector_mult_1D( + const dealii::Tensor<1,PHILIP_DIM,std::vector> &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis, + const dealii::FullMatrix &gradient_basis); + + +template void SumFactorizedOperators::gradient_matrix_vector_mult( + const std::vector &input_vect, + dealii::Tensor<1,PHILIP_DIM,std::vector> &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const dealii::FullMatrix &gradient_basis_x, + const dealii::FullMatrix &gradient_basis_y, + const dealii::FullMatrix &gradient_basis_z); +template void SumFactorizedOperators::gradient_matrix_vector_mult( + const std::vector &input_vect, + dealii::Tensor<1,PHILIP_DIM,std::vector> &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const dealii::FullMatrix &gradient_basis_x, + const dealii::FullMatrix &gradient_basis_y, + const dealii::FullMatrix &gradient_basis_z); +template void SumFactorizedOperators::gradient_matrix_vector_mult( + const std::vector &input_vect, + dealii::Tensor<1,PHILIP_DIM,std::vector> &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const dealii::FullMatrix &gradient_basis_x, + const dealii::FullMatrix &gradient_basis_y, + const dealii::FullMatrix &gradient_basis_z); +template void SumFactorizedOperators::gradient_matrix_vector_mult( + const std::vector &input_vect, + dealii::Tensor<1,PHILIP_DIM,std::vector> &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const dealii::FullMatrix &gradient_basis_x, + const dealii::FullMatrix &gradient_basis_y, + const dealii::FullMatrix &gradient_basis_z); +template void SumFactorizedOperators::gradient_matrix_vector_mult( + const std::vector &input_vect, + dealii::Tensor<1,PHILIP_DIM,std::vector> &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const dealii::FullMatrix &gradient_basis_x, + const dealii::FullMatrix &gradient_basis_y, + const dealii::FullMatrix &gradient_basis_z); + +template void SumFactorizedOperators::gradient_matrix_vector_mult_1D( + const std::vector &input_vect, + dealii::Tensor<1,PHILIP_DIM,std::vector> &output_vect, + const dealii::FullMatrix &basis, + const dealii::FullMatrix &gradient_basis); +template void SumFactorizedOperators::gradient_matrix_vector_mult_1D( + const std::vector &input_vect, + dealii::Tensor<1,PHILIP_DIM,std::vector> &output_vect, + const dealii::FullMatrix &basis, + const dealii::FullMatrix &gradient_basis); +template void SumFactorizedOperators::gradient_matrix_vector_mult_1D( + const std::vector &input_vect, + dealii::Tensor<1,PHILIP_DIM,std::vector> &output_vect, + const dealii::FullMatrix &basis, + const dealii::FullMatrix &gradient_basis); +template void SumFactorizedOperators::gradient_matrix_vector_mult_1D( + const std::vector &input_vect, + dealii::Tensor<1,PHILIP_DIM,std::vector> &output_vect, + const dealii::FullMatrix &basis, + const dealii::FullMatrix &gradient_basis); +template void SumFactorizedOperators::gradient_matrix_vector_mult_1D( + const std::vector &input_vect, + dealii::Tensor<1,PHILIP_DIM,std::vector> &output_vect, + const dealii::FullMatrix &basis, + const dealii::FullMatrix &gradient_basis); + + +template void SumFactorizedOperators::inner_product( + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::inner_product( + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::inner_product( + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::inner_product( + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::inner_product( + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const dealii::FullMatrix &basis_y, + const dealii::FullMatrix &basis_z, + const bool adding = false, + const double factor = 1.0); + +//template void SumFactorizedOperators::divergence_two_pt_flux_Hadamard_product( +// const dealii::Tensor<1,PHILIP_DIM,dealii::FullMatrix> &input_mat, +// std::vector &output_vect, +// const std::vector &weights, +// const dealii::FullMatrix &basis, +// const double scaling = 2.0);//the only direction that isn't identity +//template void SumFactorizedOperators::divergence_two_pt_flux_Hadamard_product( +// const dealii::Tensor<1,PHILIP_DIM,dealii::FullMatrix> &input_mat, +// std::vector &output_vect, +// const std::vector &weights, +// const dealii::FullMatrix &basis, +// const double scaling = 2.0);//the only direction that isn't identity +//template void SumFactorizedOperators::divergence_two_pt_flux_Hadamard_product( +// const dealii::Tensor<1,PHILIP_DIM,dealii::FullMatrix> &input_mat, +// std::vector &output_vect, +// const std::vector &weights, +// const dealii::FullMatrix &basis, +// const double scaling = 2.0);//the only direction that isn't identity +//template void SumFactorizedOperators::divergence_two_pt_flux_Hadamard_product( +// const dealii::Tensor<1,PHILIP_DIM,dealii::FullMatrix> &input_mat, +// std::vector &output_vect, +// const std::vector &weights, +// const dealii::FullMatrix &basis, +// const double scaling = 2.0);//the only direction that isn't identity +//template void SumFactorizedOperators::divergence_two_pt_flux_Hadamard_product( +// const dealii::Tensor<1,PHILIP_DIM,dealii::FullMatrix> &input_mat, +// std::vector &output_vect, +// const std::vector &weights, +// const dealii::FullMatrix &basis, +// const double scaling = 2.0);//the only direction that isn't identity +// +//template void SumFactorizedOperators::surface_two_pt_flux_Hadamard_product( +// const dealii::FullMatrix &input_mat, +// std::vector &output_vect_vol, +// std::vector &output_vect_surf, +// const std::vector &weights, +// const std::array,2> &surf_basis, +// const unsigned int iface, +// const unsigned int PHILIP_DIM_not_zero, +// const double scaling = 2.0); +//template void SumFactorizedOperators::surface_two_pt_flux_Hadamard_product( +// const dealii::FullMatrix &input_mat, +// std::vector &output_vect_vol, +// std::vector &output_vect_surf, +// const std::vector &weights, +// const std::array,2> &surf_basis, +// const unsigned int iface, +// const unsigned int PHILIP_DIM_not_zero, +// const double scaling = 2.0); +//template void SumFactorizedOperators::surface_two_pt_flux_Hadamard_product( +// const dealii::FullMatrix &input_mat, +// std::vector &output_vect_vol, +// std::vector &output_vect_surf, +// const std::vector &weights, +// const std::array,2> &surf_basis, +// const unsigned int iface, +// const unsigned int PHILIP_DIM_not_zero, +// const double scaling = 2.0); +//template void SumFactorizedOperators::surface_two_pt_flux_Hadamard_product( +// const dealii::FullMatrix &input_mat, +// std::vector &output_vect_vol, +// std::vector &output_vect_surf, +// const std::vector &weights, +// const std::array,2> &surf_basis, +// const unsigned int iface, +// const unsigned int PHILIP_DIM_not_zero, +// const double scaling = 2.0); +//template void SumFactorizedOperators::surface_two_pt_flux_Hadamard_product( +// const dealii::FullMatrix &input_mat, +// std::vector &output_vect_vol, +// std::vector &output_vect_surf, +// const std::vector &weights, +// const std::array,2> &surf_basis, +// const unsigned int iface, +// const unsigned int PHILIP_DIM_not_zero, +// const double scaling = 2.0); +// +//template void SumFactorizedOperators::two_pt_flux_Hadamard_product( +// const dealii::FullMatrix &input_mat, +// dealii::FullMatrix &output_mat, +// const dealii::FullMatrix &basis,//the only direction that isn't identity +// const std::vector &weights,//vector storing diagonal entries for case not identity +// const int direction);//direction for the derivative that corresponds to basis +//template void SumFactorizedOperators::two_pt_flux_Hadamard_product( +// const dealii::FullMatrix &input_mat, +// dealii::FullMatrix &output_mat, +// const dealii::FullMatrix &basis,//the only direction that isn't identity +// const std::vector &weights,//vector storing diagonal entries for case not identity +// const int direction);//direction for the derivative that corresponds to basis +//template void SumFactorizedOperators::two_pt_flux_Hadamard_product( +// const dealii::FullMatrix &input_mat, +// dealii::FullMatrix &output_mat, +// const dealii::FullMatrix &basis,//the only direction that isn't identity +// const std::vector &weights,//vector storing diagonal entries for case not identity +// const int direction);//direction for the derivative that corresponds to basis +//template void SumFactorizedOperators::two_pt_flux_Hadamard_product( +// const dealii::FullMatrix &input_mat, +// dealii::FullMatrix &output_mat, +// const dealii::FullMatrix &basis,//the only direction that isn't identity +// const std::vector &weights,//vector storing diagonal entries for case not identity +// const int direction);//direction for the derivative that corresponds to basis +//template void SumFactorizedOperators::two_pt_flux_Hadamard_product( +// const dealii::FullMatrix &input_mat, +// dealii::FullMatrix &output_mat, +// const dealii::FullMatrix &basis,//the only direction that isn't identity +// const std::vector &weights,//vector storing diagonal entries for case not identity +// const int direction);//direction for the derivative that corresponds to basis + +template void SumFactorizedOperators::matrix_vector_mult_1D( + const std::vector &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::matrix_vector_mult_1D( + const std::vector &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::matrix_vector_mult_1D( + const std::vector &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::matrix_vector_mult_1D( + const std::vector &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::matrix_vector_mult_1D( + const std::vector &input_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const bool adding = false, + const double factor = 1.0); + +template void SumFactorizedOperators::inner_product_1D( + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::inner_product_1D( + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::inner_product_1D( + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::inner_product_1D( + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::inner_product_1D( + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector &output_vect, + const dealii::FullMatrix &basis_x, + const bool adding = false, + const double factor = 1.0); + +template void SumFactorizedOperators::matrix_vector_mult_surface_1D( + const unsigned int face_number, + const std::vector &input_vect, + std::vector &output_vect, + const std::array,2> &basis_surf,//only 2 faces in 1D + const dealii::FullMatrix &basis_vol, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::matrix_vector_mult_surface_1D( + const unsigned int face_number, + const std::vector &input_vect, + std::vector &output_vect, + const std::array,2> &basis_surf,//only 2 faces in 1D + const dealii::FullMatrix &basis_vol, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::matrix_vector_mult_surface_1D( + const unsigned int face_number, + const std::vector &input_vect, + std::vector &output_vect, + const std::array,2> &basis_surf,//only 2 faces in 1D + const dealii::FullMatrix &basis_vol, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::matrix_vector_mult_surface_1D( + const unsigned int face_number, + const std::vector &input_vect, + std::vector &output_vect, + const std::array,2> &basis_surf,//only 2 faces in 1D + const dealii::FullMatrix &basis_vol, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::matrix_vector_mult_surface_1D( + const unsigned int face_number, + const std::vector &input_vect, + std::vector &output_vect, + const std::array,2> &basis_surf,//only 2 faces in 1D + const dealii::FullMatrix &basis_vol, + const bool adding = false, + const double factor = 1.0); + + +template void SumFactorizedOperators::inner_product_surface_1D( + const unsigned int face_number, + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector< double> &output_vect, + const std::array,2> &basis_surf,//only 2 faces in 1D + const dealii::FullMatrix &basis_vol, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::inner_product_surface_1D( + const unsigned int face_number, + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector< FadType> &output_vect, + const std::array,2> &basis_surf,//only 2 faces in 1D + const dealii::FullMatrix &basis_vol, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::inner_product_surface_1D( + const unsigned int face_number, + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector< RadType> &output_vect, + const std::array,2> &basis_surf,//only 2 faces in 1D + const dealii::FullMatrix &basis_vol, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::inner_product_surface_1D( + const unsigned int face_number, + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector< FadFadType> &output_vect, + const std::array,2> &basis_surf,//only 2 faces in 1D + const dealii::FullMatrix &basis_vol, + const bool adding = false, + const double factor = 1.0); +template void SumFactorizedOperators::inner_product_surface_1D( + const unsigned int face_number, + const std::vector &input_vect, + const std::vector &weight_vect, + std::vector< RadFadType> &output_vect, + const std::array,2> &basis_surf,//only 2 faces in 1D + const dealii::FullMatrix &basis_vol, + const bool adding = false, + const double factor = 1.0); + +template void SumFactorizedOperators::Hadamard_product_AD_vector( + const dealii::FullMatrix &input_mat, + const std::vector &input_vect, + std::vector< double> &output_vect); +template void SumFactorizedOperators::Hadamard_product_AD_vector( + const dealii::FullMatrix &input_mat, + const std::vector &input_vect, + std::vector< FadType> &output_vect); +template void SumFactorizedOperators::Hadamard_product_AD_vector( + const dealii::FullMatrix &input_mat, + const std::vector &input_vect, + std::vector< RadType> &output_vect); +template void SumFactorizedOperators::Hadamard_product_AD_vector( + const dealii::FullMatrix &input_mat, + const std::vector &input_vect, + std::vector< FadFadType> &output_vect); +template void SumFactorizedOperators::Hadamard_product_AD_vector( + const dealii::FullMatrix &input_mat, + const std::vector &input_vect, + std::vector< RadFadType> &output_vect); + } // OPERATOR namespace } // PHiLiP namespace diff --git a/src/operators/operators.h b/src/operators/operators.h index caabfcd23..351132578 100644 --- a/src/operators/operators.h +++ b/src/operators/operators.h @@ -49,7 +49,7 @@ namespace OPERATOR { * (3) Flux Operators: See above. It is important to note that since flux operators are "collocated" on the cubature set, the number of degrees of freedom of the flux basis MUST equal the number of cubature nodes. Importantly on the surface, the flux basis interpolates from the volume to the surface, thus corresponds to volume cubature nodes collocation. * (4) Metric Operators: Since the solution polynomial degree for each state varies, along with the local grid element's polynomial degree varying, the operators distinguish between polynomial degree (for solution or flux) and grid degree (for element). Explicitly, they first go vector of grid_degree, then vector of polynomial degree for the ones that are applied on the flux nodes. The mapping-support-points follow the standard from dealii, where they are always Gauss-Legendre-Lobatto quadrature nodes making the polynomial elements continuous in a sense. */ -template +template class OperatorsBase { public: @@ -97,25 +97,28 @@ class OperatorsBase ///Standard function to compute factorial of a number. double compute_factorial(double n); - ///virtual function to be defined. - virtual void matrix_vector_mult( - const std::vector &input_vect, - std::vector &output_vect, - const dealii::FullMatrix &basis_x, - const dealii::FullMatrix &basis_y, - const dealii::FullMatrix &basis_z, - const bool adding = false, - const double factor = 1.0) = 0; - ///virtual function to be defined. - virtual void inner_product( - const std::vector &input_vect, - const std::vector &weight_vect, - std::vector &output_vect, - const dealii::FullMatrix &basis_x, - const dealii::FullMatrix &basis_y, - const dealii::FullMatrix &basis_z, - const bool adding = false, - const double factor = 1.0) = 0; + ///Base matrix vetor mult never implemented. +// ///virtual function to be defined. +// template +// virtual void matrix_vector_mult( +// const std::vector &input_vect, +// std::vector &output_vect, +// const dealii::FullMatrix &basis_x, +// const dealii::FullMatrix &basis_y, +// const dealii::FullMatrix &basis_z, +// const bool adding = false, +// const double factor = 1.0) = 0; +// ///virtual function to be defined. +// template +// virtual void inner_product( +// const std::vector &input_vect, +// const std::vector &weight_vect, +// std::vector &output_vect, +// const dealii::FullMatrix &basis_x, +// const dealii::FullMatrix &basis_y, +// const dealii::FullMatrix &basis_z, +// const bool adding = false, +// const double factor = 1.0) = 0; protected: const MPI_Comm mpi_communicator; ///< MPI communicator. @@ -127,8 +130,8 @@ class OperatorsBase * sum factorization to perform their operations. * Note that we assume tensor product elements in this operators class. */ -template -class SumFactorizedOperators : public OperatorsBase +template +class SumFactorizedOperators : public OperatorsBase { public: /// Precompute 1D operator in constructor @@ -144,6 +147,7 @@ class SumFactorizedOperators : public OperatorsBase * we compute \f$v^T=\mathbf{A}u^T\f$. * Lastly, the adding allows the result to add onto the previous output_vect scaled by "factor". */ + template void matrix_vector_mult( const std::vector &input_vect, std::vector &output_vect, @@ -151,7 +155,7 @@ class SumFactorizedOperators : public OperatorsBase const dealii::FullMatrix &basis_y, const dealii::FullMatrix &basis_z, const bool adding = false, - const double factor = 1.0) override; + const double factor = 1.0); ///Computes the divergence using the sum factorization matrix-vector multiplication. /** Often, we compute a dot product in dim, where each matrix multiplictaion uses * sum factorization. Example, consider taking the reference divergence of the reference flux: @@ -163,6 +167,7 @@ class SumFactorizedOperators : public OperatorsBase * + \left( \mathbf{\chi}(\mathbf{\xi}) \otimes \mathbf{\chi}(\mathbf{\eta} \otimes \frac{d\mathbf{\chi}(\mathbf{\zeta})}{d\zeta})\right) \left(\hat{\mathbf{f}^r}\right)^T, * \f] where we use sum factorization to evaluate each matrix-vector multiplication in each dim direction. */ + template void divergence_matrix_vector_mult( const dealii::Tensor<1,dim,std::vector> &input_vect, std::vector &output_vect, @@ -174,6 +179,7 @@ class SumFactorizedOperators : public OperatorsBase const dealii::FullMatrix &gradient_basis_z); ///Computes the divergence using sum-factorization where the basis are the same in each direction. + template void divergence_matrix_vector_mult_1D( const dealii::Tensor<1,dim,std::vector> &input_vect, std::vector &output_vect, @@ -181,6 +187,7 @@ class SumFactorizedOperators : public OperatorsBase const dealii::FullMatrix &gradient_basis); ///Computes the gradient of a scalar using sum-factorization. + template void gradient_matrix_vector_mult( const std::vector &input_vect, dealii::Tensor<1,dim,std::vector> &output_vect, @@ -191,6 +198,7 @@ class SumFactorizedOperators : public OperatorsBase const dealii::FullMatrix &gradient_basis_y, const dealii::FullMatrix &gradient_basis_z); ///Computes the gradient of a scalar using sum-factorization where the basis are the same in each direction. + template void gradient_matrix_vector_mult_1D( const std::vector &input_vect, dealii::Tensor<1,dim,std::vector> &output_vect, @@ -200,15 +208,16 @@ class SumFactorizedOperators : public OperatorsBase ///Computes the inner product between a matrix and a vector multiplied by some weight function. /** That is, we compute \f$ \int Awu d\mathbf{\Omega}_r = \mathbf{A}^T \text{diag}(w) \mathbf{u}^T \f$. When using this function, pass \f$ \mathbf{A} \f$ and NOT it's transpose--the function transposes it in the first few lines. */ + template void inner_product( const std::vector &input_vect, - const std::vector &weight_vect, + const std::vector &weight_vect, std::vector &output_vect, const dealii::FullMatrix &basis_x, const dealii::FullMatrix &basis_y, const dealii::FullMatrix &basis_z, const bool adding = false, - const double factor = 1.0) override; + const double factor = 1.0); ///Computes the divergence of the 2pt flux Hadamard products, then sums the rows. @@ -217,19 +226,19 @@ class SumFactorizedOperators : public OperatorsBase * to be \f$ \mathcal{O}(n^{d+1})\f$. */ void divergence_two_pt_flux_Hadamard_product( - const dealii::Tensor<1,dim,dealii::FullMatrix> &input_mat, - std::vector &output_vect, - const std::vector &weights, + const dealii::Tensor<1,dim,dealii::FullMatrix> &input_mat, + std::vector &output_vect, + const std::vector &weights, const dealii::FullMatrix &basis, const double scaling = 2.0);//the only direction that isn't identity /// Computes the surface cross Hadamard products for skew-symmetric form from Eq. (15) in Chan, Jesse. "Skew-symmetric entropy stable modal discontinuous Galerkin formulations." Journal of Scientific Computing 81.1 (2019): 459-485. void surface_two_pt_flux_Hadamard_product( - const dealii::FullMatrix &input_mat, - std::vector &output_vect_vol, - std::vector &output_vect_surf, - const std::vector &weights, + const dealii::FullMatrix &input_mat, + std::vector &output_vect_vol, + std::vector &output_vect_surf, + const std::vector &weights, const std::array,2> &surf_basis, const unsigned int iface, const unsigned int dim_not_zero, @@ -246,10 +255,10 @@ class SumFactorizedOperators : public OperatorsBase * This is NOT for GENERAL Hadamard products since those are \f$ \mathcal{O}(n^{2d})\f$ . */ void two_pt_flux_Hadamard_product( - const dealii::FullMatrix &input_mat, - dealii::FullMatrix &output_mat, + const dealii::FullMatrix &input_mat, + dealii::FullMatrix &output_mat, const dealii::FullMatrix &basis,//the only direction that isn't identity - const std::vector &weights,//vector storing diagonal entries for case not identity + const std::vector &weights,//vector storing diagonal entries for case not identity const int direction);//direction for the derivative that corresponds to basis @@ -293,6 +302,7 @@ class SumFactorizedOperators : public OperatorsBase /** This is for the case where the operator of size dim is the dyadic product of * the same 1D operator in each direction */ + template void matrix_vector_mult_1D( const std::vector &input_vect, std::vector &output_vect, @@ -304,9 +314,10 @@ class SumFactorizedOperators : public OperatorsBase /* This is for the case where the operator of size dim is the dyadic product of * the same 1D operator in each direction */ + template void inner_product_1D( const std::vector &input_vect, - const std::vector &weight_vect, + const std::vector &weight_vect, std::vector &output_vect, const dealii::FullMatrix &basis_x, const bool adding = false, @@ -319,6 +330,7 @@ class SumFactorizedOperators : public OperatorsBase * Explicitly, this passes basis_surf in the direction by face_number, and basis_vol * in all other directions. */ + template void matrix_vector_mult_surface_1D( const unsigned int face_number, const std::vector &input_vect, @@ -329,10 +341,11 @@ class SumFactorizedOperators : public OperatorsBase const double factor = 1.0); /// Apply sum-factorization inner product on a surface. + template void inner_product_surface_1D( const unsigned int face_number, const std::vector &input_vect, - const std::vector &weight_vect, + const std::vector &weight_vect, std::vector &output_vect, const std::array,2> &basis_surf,//only 2 faces in 1D const dealii::FullMatrix &basis_vol, @@ -345,9 +358,19 @@ class SumFactorizedOperators : public OperatorsBase * \f$ A \circ B = C \implies \left( C \right)_{ij} = \left( A \right)_{ij}\left( B \right)_{ij}\f$. */ void Hadamard_product( - const dealii::FullMatrix &input_mat1, - const dealii::FullMatrix &input_mat2, - dealii::FullMatrix &output_mat); + const dealii::FullMatrix &input_mat1, + const dealii::FullMatrix &input_mat2, + dealii::FullMatrix &output_mat); + + ///Computes a single Hadamard product for AD type. + /** The input_mat is a matrix of double, input vector is a matrix stored as a vector + * in contiguous memory, and outputs a matrix stored as a vector in contiguous memory. + */ + template + void Hadamard_product_AD_vector( + const dealii::FullMatrix &input_mat, + const std::vector &input_vect, + std::vector &output_vect); //protected: public: @@ -377,8 +400,8 @@ class SumFactorizedOperators : public OperatorsBase /* This class stores the basis functions evaluated at volume and facet * cubature nodes, as well as it's gradient in REFERENCE space. */ -template -class basis_functions : public SumFactorizedOperators +template +class basis_functions : public SumFactorizedOperators { public: /// Constructor. @@ -412,8 +435,8 @@ class basis_functions : public SumFactorizedOperators }; ///\f$ \mathbf{W}*\mathbf{\chi}(\mathbf{\xi}_v^r) \f$ That is Quadrature Weights multiplies with basis_at_vol_cubature. -template -class vol_integral_basis : public SumFactorizedOperators +template +class vol_integral_basis : public SumFactorizedOperators { public: /// Constructor. @@ -432,8 +455,8 @@ class vol_integral_basis : public SumFactorizedOperators }; ///Local mass matrix without jacobian dependence. -template -class local_mass : public SumFactorizedOperators +template +class local_mass : public SumFactorizedOperators { public: /// Constructor. @@ -457,7 +480,7 @@ class local_mass : public SumFactorizedOperators dealii::FullMatrix build_dim_mass_matrix( const int nstate, const unsigned int n_dofs, const unsigned int n_quad_pts, - basis_functions &basis, + basis_functions &basis, const std::vector &det_Jac, const std::vector &quad_weights); }; @@ -468,8 +491,8 @@ class local_mass : public SumFactorizedOperators (\mathbf{S}_\xi)_{ij} = \int_\mathbf{{\Omega}_r} \mathbf{\chi}_i(\mathbf{\xi}^r) \frac{\mathbf{\chi}_{j}(\mathbf{\xi}^r)}{\partial \xi} d\mathbf{\Omega}_r \f] */ -template -class local_basis_stiffness : public SumFactorizedOperators +template +class local_basis_stiffness : public SumFactorizedOperators { public: /// Constructor. @@ -495,8 +518,8 @@ class local_basis_stiffness : public SumFactorizedOperators }; ///This is the solution basis \f$\mathbf{D}_i\f$, the modal differential opertaor commonly seen in DG defined as \f$\mathbf{D}_i=\mathbf{M}^{-1}*\mathbf{S}_i\f$. -template -class modal_basis_differential_operator : public SumFactorizedOperators +template +class modal_basis_differential_operator : public SumFactorizedOperators { public: /// Constructor. @@ -515,8 +538,8 @@ class modal_basis_differential_operator : public SumFactorizedOperators -class derivative_p : public SumFactorizedOperators +template +class derivative_p : public SumFactorizedOperators { public: /// Constructor. @@ -535,8 +558,8 @@ class derivative_p : public SumFactorizedOperators }; /// ESFR correction matrix without jac dependence -template -class local_Flux_Reconstruction_operator : public SumFactorizedOperators +template +class local_Flux_Reconstruction_operator : public SumFactorizedOperators { public: ///Constructor. @@ -651,8 +674,8 @@ class local_Flux_Reconstruction_operator : public SumFactorizedOperators -class local_Flux_Reconstruction_operator_aux : public local_Flux_Reconstruction_operator +template +class local_Flux_Reconstruction_operator_aux : public local_Flux_Reconstruction_operator { public: ///Constructor. @@ -690,8 +713,8 @@ class local_Flux_Reconstruction_operator_aux : public local_Flux_Reconstruction_ }; ///Projection operator corresponding to basis functions onto M-norm (L2). -template -class vol_projection_operator : public SumFactorizedOperators +template +class vol_projection_operator : public SumFactorizedOperators { public: ///Constructor. @@ -716,8 +739,8 @@ class vol_projection_operator : public SumFactorizedOperators }; ///Projection operator corresponding to basis functions onto \f$(M+K)\f$-norm. -template -class vol_projection_operator_FR : public vol_projection_operator +template +class vol_projection_operator_FR : public vol_projection_operator { public: ///Constructor. @@ -747,8 +770,8 @@ class vol_projection_operator_FR : public vol_projection_operator -class vol_projection_operator_FR_aux : public vol_projection_operator +template +class vol_projection_operator_FR_aux : public vol_projection_operator { public: ///Constructor. @@ -778,8 +801,8 @@ class vol_projection_operator_FR_aux : public vol_projection_operator -class FR_mass_inv : public SumFactorizedOperators +template +class FR_mass_inv : public SumFactorizedOperators { public: ///Constructor. @@ -801,8 +824,8 @@ class FR_mass_inv : public SumFactorizedOperators const dealii::Quadrature<1> &quadrature); }; ///The metric independent inverse of the FR mass matrix for auxiliary equation \f$(M+K)^{-1}\f$. -template -class FR_mass_inv_aux : public SumFactorizedOperators +template +class FR_mass_inv_aux : public SumFactorizedOperators { public: ///Constructor. @@ -824,8 +847,8 @@ class FR_mass_inv_aux : public SumFactorizedOperators const dealii::Quadrature<1> &quadrature); }; ///The metric independent FR mass matrix \f$(M+K)\f$. -template -class FR_mass : public SumFactorizedOperators +template +class FR_mass : public SumFactorizedOperators { public: ///Constructor. @@ -848,8 +871,8 @@ class FR_mass : public SumFactorizedOperators }; ///The metric independent FR mass matrix for auxiliary equation \f$(M+K)\f$. -template -class FR_mass_aux : public SumFactorizedOperators +template +class FR_mass_aux : public SumFactorizedOperators { public: ///Constructor. @@ -879,8 +902,8 @@ class FR_mass_aux : public SumFactorizedOperators * \mathbf{W}\nabla\Big(\chi_i(\mathbf{\xi}^r)\Big) * \f] */ -template -class vol_integral_gradient_basis : public SumFactorizedOperators +template +class vol_integral_gradient_basis : public SumFactorizedOperators { public: ///Constructor. @@ -912,8 +935,8 @@ class vol_integral_gradient_basis : public SumFactorizedOperators -class face_integral_basis : public SumFactorizedOperators +template +class face_integral_basis : public SumFactorizedOperators { public: ///Constructor. @@ -937,8 +960,8 @@ class face_integral_basis : public SumFactorizedOperators *NOTE this doesn't have metric Jacobian dependence, for DG solver *we build that using the functions below on the fly! */ -template -class lifting_operator : public SumFactorizedOperators +template +class lifting_operator : public SumFactorizedOperators { public: ///Constructor. @@ -978,8 +1001,8 @@ class lifting_operator : public SumFactorizedOperators * L_{FR}:\: _{\mathbf{\Omega}_r} = _{\mathbf{\Gamma}_2}, \forall v\in P^p(\mathbf{\Omega}_r) * \f]. */ -template -class lifting_operator_FR : public lifting_operator +template +class lifting_operator_FR : public lifting_operator { public: ///Constructor. @@ -1022,8 +1045,8 @@ class lifting_operator_FR : public lifting_operator * collocated on the mapping support points. * By default, we use Gauss-Lobatto-Legendre as the mapping support points. */ -template -class mapping_shape_functions: public SumFactorizedOperators +template +class mapping_shape_functions: public SumFactorizedOperators { public: ///Constructor. @@ -1039,10 +1062,10 @@ class mapping_shape_functions: public SumFactorizedOperators unsigned int current_grid_degree; ///Object of mapping shape functions evaluated at grid nodes. - basis_functions mapping_shape_functions_grid_nodes; + basis_functions mapping_shape_functions_grid_nodes; ///Object of mapping shape functions evaluated at flux nodes. - basis_functions mapping_shape_functions_flux_nodes; + basis_functions mapping_shape_functions_flux_nodes; ///Constructs the volume operator and gradient operator. /** @@ -1083,7 +1106,7 @@ class mapping_shape_functions: public SumFactorizedOperators *****************************************************************************/ ///Base metric operators class that stores functions used in both the volume and on surface. template -class metric_operators: public SumFactorizedOperators +class metric_operators: public SumFactorizedOperators { public: ///Constructor. @@ -1134,7 +1157,7 @@ class metric_operators: public SumFactorizedOperators const unsigned int n_quad_pts,//number volume quad pts const unsigned int n_metric_dofs,//dofs of metric basis. NOTE: this is the number of mapping support points const std::array,dim> &mapping_support_points, - mapping_shape_functions &mapping_basis); + mapping_shape_functions &mapping_basis); ///Builds the volume metric operators. /** Builds and stores volume metric cofactor and determinant of metric Jacobian @@ -1145,7 +1168,7 @@ class metric_operators: public SumFactorizedOperators const unsigned int n_quad_pts,//number volume quad pts const unsigned int n_metric_dofs,//dofs of metric basis. NOTE: this is the number of mapping support points const std::array,dim> &mapping_support_points, - mapping_shape_functions &mapping_basis, + mapping_shape_functions &mapping_basis, const bool use_invariant_curl_form = false); ///Builds the facet metric operators. @@ -1158,7 +1181,7 @@ class metric_operators: public SumFactorizedOperators const unsigned int n_quad_pts,//number facet quad pts const unsigned int n_metric_dofs,//dofs of metric basis. NOTE: this is the number of mapping support points const std::array,dim> &mapping_support_points, - mapping_shape_functions &mapping_basis, + mapping_shape_functions &mapping_basis, const bool use_invariant_curl_form = false); ///The volume metric cofactor matrix. @@ -1288,8 +1311,8 @@ class metric_operators: public SumFactorizedOperators /**Note that dofs and quad points aren't templated because they are variable with respect to each polynomial degree. *Also I couldn't template by polynomial degree/grid degree since they aren't compile time constant expressions. */ -template -class SumFactorizedOperatorsState : public SumFactorizedOperators +template +class SumFactorizedOperatorsState : public SumFactorizedOperators { public: ///Constructor. @@ -1312,8 +1335,8 @@ class SumFactorizedOperatorsState : public SumFactorizedOperators -class basis_functions_state : public SumFactorizedOperatorsState +template +class basis_functions_state : public SumFactorizedOperatorsState { public: ///Constructor. @@ -1344,8 +1367,8 @@ class basis_functions_state : public SumFactorizedOperatorsState -class flux_basis_functions_state : public SumFactorizedOperatorsState +template +class flux_basis_functions_state : public SumFactorizedOperatorsState { public: ///Constructor. @@ -1379,8 +1402,8 @@ class flux_basis_functions_state : public SumFactorizedOperatorsState -class local_flux_basis_stiffness : public flux_basis_functions_state +template +class local_flux_basis_stiffness : public flux_basis_functions_state { public: ///Constructor. diff --git a/src/physics/initial_conditions/set_initial_condition.cpp b/src/physics/initial_conditions/set_initial_condition.cpp index 20ee2c509..8a3706b3f 100644 --- a/src/physics/initial_conditions/set_initial_condition.cpp +++ b/src/physics/initial_conditions/set_initial_condition.cpp @@ -70,7 +70,7 @@ void SetInitialCondition::project_initial_condition( dealii::update_quadrature_points); const unsigned int max_dofs_per_cell = dg->dof_handler.get_fe_collection().max_dofs_per_cell(); std::vector current_dofs_indices(max_dofs_per_cell); - OPERATOR::vol_projection_operator vol_projection(1, dg->max_degree, dg->max_grid_degree); + OPERATOR::vol_projection_operator vol_projection(1, dg->max_degree, dg->max_grid_degree); vol_projection.build_1D_volume_operator(dg->oneD_fe_collection_1state[dg->max_degree], dg->oneD_quadrature_collection[dg->max_degree]); for (auto current_cell = dg->dof_handler.begin_active(); current_cell!=dg->dof_handler.end(); ++current_cell) { if (!current_cell->is_locally_owned()) continue; @@ -174,7 +174,7 @@ void SetInitialCondition::read_values_from_file_and_project( dealii::update_quadrature_points); const unsigned int max_dofs_per_cell = dg->dof_handler.get_fe_collection().max_dofs_per_cell(); std::vector current_dofs_indices(max_dofs_per_cell); - OPERATOR::vol_projection_operator vol_projection(1, dg->max_degree, dg->max_grid_degree); + OPERATOR::vol_projection_operator vol_projection(1, dg->max_degree, dg->max_grid_degree); vol_projection.build_1D_volume_operator(dg->oneD_fe_collection_1state[dg->max_degree], dg->oneD_quadrature_collection[dg->max_degree]); for (auto current_cell = dg->dof_handler.begin_active(); current_cell!=dg->dof_handler.end(); ++current_cell) { if (!current_cell->is_locally_owned()) continue; diff --git a/src/testing/advection_explicit_periodic.cpp b/src/testing/advection_explicit_periodic.cpp index e45102833..3de7ba5ee 100644 --- a/src/testing/advection_explicit_periodic.cpp +++ b/src/testing/advection_explicit_periodic.cpp @@ -74,7 +74,7 @@ double AdvectionPeriodic::compute_conservation(std::shared_ptr < PH // Projected vector of ones. That is, the interpolation of ones_hat to the volume nodes is 1. std::vector ones_hat(n_dofs_cell); // We have to project the vector of ones because the mass matrix has an interpolation from solution nodes built into it. - OPERATOR::vol_projection_operator vol_projection(dg->nstate, poly_degree, dg->max_grid_degree); + OPERATOR::vol_projection_operator vol_projection(dg->nstate, poly_degree, dg->max_grid_degree); vol_projection.build_1D_volume_operator(dg->oneD_fe_collection[poly_degree], dg->oneD_quadrature_collection[poly_degree]); vol_projection.matrix_vector_mult_1D(ones, ones_hat, vol_projection.oneD_vol_operator); diff --git a/src/testing/burgers_stability.cpp b/src/testing/burgers_stability.cpp index 8b639b70b..c944b4c20 100644 --- a/src/testing/burgers_stability.cpp +++ b/src/testing/burgers_stability.cpp @@ -66,7 +66,7 @@ double BurgersEnergyStability::compute_conservation(std::shared_ptr //Projected vector of ones. That is, the interpolation of ones_hat to the volume nodes is 1. std::vector ones_hat(n_dofs_cell); //We have to project the vector of ones because the mass matrix has an interpolation from solution nodes built into it. - OPERATOR::vol_projection_operator vol_projection(dg->nstate, poly_degree, dg->max_grid_degree); + OPERATOR::vol_projection_operator vol_projection(dg->nstate, poly_degree, dg->max_grid_degree); vol_projection.build_1D_volume_operator(dg->oneD_fe_collection[poly_degree], dg->oneD_quadrature_collection[poly_degree]); vol_projection.matrix_vector_mult_1D(ones, ones_hat, vol_projection.oneD_vol_operator); diff --git a/src/testing/convection_diffusion_explicit_periodic.cpp b/src/testing/convection_diffusion_explicit_periodic.cpp index 32bb733b0..b1ebed179 100644 --- a/src/testing/convection_diffusion_explicit_periodic.cpp +++ b/src/testing/convection_diffusion_explicit_periodic.cpp @@ -73,7 +73,7 @@ double ConvectionDiffusionPeriodic::compute_conservation(std::share // Projected vector of ones. That is, the interpolation of ones_hat to the volume nodes is 1. std::vector ones_hat(n_dofs_cell); // We have to project the vector of ones because the mass matrix has an interpolation from solution nodes built into it. - OPERATOR::vol_projection_operator vol_projection(dg->nstate, poly_degree, dg->max_grid_degree); + OPERATOR::vol_projection_operator vol_projection(dg->nstate, poly_degree, dg->max_grid_degree); vol_projection.build_1D_volume_operator(dg->oneD_fe_collection[poly_degree], dg->oneD_quadrature_collection[poly_degree]); vol_projection.matrix_vector_mult_1D(ones, ones_hat, vol_projection.oneD_vol_operator); diff --git a/src/testing/euler_split_inviscid_taylor_green_vortex.cpp b/src/testing/euler_split_inviscid_taylor_green_vortex.cpp index 69ead20ee..c3628b6d0 100644 --- a/src/testing/euler_split_inviscid_taylor_green_vortex.cpp +++ b/src/testing/euler_split_inviscid_taylor_green_vortex.cpp @@ -20,10 +20,10 @@ std::array EulerTaylorGreen::compute_change_in_entropy(co const unsigned int n_quad_pts = dg->volume_quadrature_collection[poly_degree].size(); const unsigned int n_shape_fns = n_dofs_cell / nstate; //We have to project the vector of entropy variables because the mass matrix has an interpolation from solution nodes built into it. - OPERATOR::vol_projection_operator vol_projection(1, poly_degree, dg->max_grid_degree); + OPERATOR::vol_projection_operator vol_projection(1, poly_degree, dg->max_grid_degree); vol_projection.build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]); - OPERATOR::basis_functions soln_basis(1, poly_degree, dg->max_grid_degree); + OPERATOR::basis_functions soln_basis(1, poly_degree, dg->max_grid_degree); soln_basis.build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]); dealii::LinearAlgebra::distributed::Vector entropy_var_hat_global(dg->right_hand_side); @@ -106,26 +106,26 @@ double EulerTaylorGreen::compute_volume_term(const std::shared_ptr const unsigned int n_shape_fns = n_dofs_cell / nstate; const unsigned int grid_degree = dg->high_order_grid->fe_system.tensor_degree(); - OPERATOR::basis_functions soln_basis(1, poly_degree, dg->max_grid_degree); + OPERATOR::basis_functions soln_basis(1, poly_degree, dg->max_grid_degree); soln_basis.build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]); soln_basis.build_1D_gradient_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]); soln_basis.build_1D_surface_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_face_quadrature); - OPERATOR::basis_functions flux_basis(1, poly_degree, dg->max_grid_degree); + OPERATOR::basis_functions flux_basis(1, poly_degree, dg->max_grid_degree); flux_basis.build_1D_volume_operator(dg->oneD_fe_collection_flux[poly_degree], dg->oneD_quadrature_collection[poly_degree]); flux_basis.build_1D_gradient_operator(dg->oneD_fe_collection_flux[poly_degree], dg->oneD_quadrature_collection[poly_degree]); flux_basis.build_1D_surface_operator(dg->oneD_fe_collection_flux[poly_degree], dg->oneD_face_quadrature); - OPERATOR::local_basis_stiffness flux_basis_stiffness(1, poly_degree, dg->max_grid_degree, true); + OPERATOR::local_basis_stiffness flux_basis_stiffness(1, poly_degree, dg->max_grid_degree, true); //flux basis stiffness operator for skew-symmetric form flux_basis_stiffness.build_1D_volume_operator(dg->oneD_fe_collection_flux[poly_degree], dg->oneD_quadrature_collection[poly_degree]); - OPERATOR::mapping_shape_functions mapping_basis(1, poly_degree, grid_degree); + OPERATOR::mapping_shape_functions mapping_basis(1, poly_degree, grid_degree); mapping_basis.build_1D_shape_functions_at_grid_nodes(dg->high_order_grid->oneD_fe_system, dg->high_order_grid->oneD_grid_nodes); mapping_basis.build_1D_shape_functions_at_flux_nodes(dg->high_order_grid->oneD_fe_system, dg->oneD_quadrature_collection[poly_degree], dg->oneD_face_quadrature); const std::vector &oneD_vol_quad_weights = dg->oneD_quadrature_collection[poly_degree].get_weights(); - OPERATOR::vol_projection_operator vol_projection(1, poly_degree, dg->max_grid_degree); + OPERATOR::vol_projection_operator vol_projection(1, poly_degree, dg->max_grid_degree); vol_projection.build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]); std::vector dofs_indices (n_dofs_cell); @@ -336,10 +336,10 @@ double EulerTaylorGreen::compute_entropy(const std::shared_ptr < DG const unsigned int n_shape_fns = n_dofs_cell / nstate; //We have to project the vector of entropy variables because the mass matrix has an interpolation from solution nodes built into it. - OPERATOR::basis_functions soln_basis(1, poly_degree, dg->max_grid_degree); + OPERATOR::basis_functions soln_basis(1, poly_degree, dg->max_grid_degree); soln_basis.build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]); - OPERATOR::mapping_shape_functions mapping_basis(1, poly_degree, dg->max_grid_degree); + OPERATOR::mapping_shape_functions mapping_basis(1, poly_degree, dg->max_grid_degree); mapping_basis.build_1D_shape_functions_at_grid_nodes(dg->high_order_grid->oneD_fe_system, dg->high_order_grid->oneD_grid_nodes); mapping_basis.build_1D_shape_functions_at_flux_nodes(dg->high_order_grid->oneD_fe_system, dg->oneD_quadrature_collection[poly_degree], dg->oneD_face_quadrature); @@ -430,10 +430,10 @@ double EulerTaylorGreen::compute_kinetic_energy(const std::shared_p const unsigned int n_shape_fns = n_dofs_cell / nstate; //We have to project the vector of entropy variables because the mass matrix has an interpolation from solution nodes built into it. - OPERATOR::basis_functions soln_basis(1, poly_degree, dg->max_grid_degree); + OPERATOR::basis_functions soln_basis(1, poly_degree, dg->max_grid_degree); soln_basis.build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]); - OPERATOR::mapping_shape_functions mapping_basis(1, poly_degree, dg->max_grid_degree); + OPERATOR::mapping_shape_functions mapping_basis(1, poly_degree, dg->max_grid_degree); mapping_basis.build_1D_shape_functions_at_grid_nodes(dg->high_order_grid->oneD_fe_system, dg->high_order_grid->oneD_grid_nodes); mapping_basis.build_1D_shape_functions_at_flux_nodes(dg->high_order_grid->oneD_fe_system, dg->oneD_quadrature_collection[poly_degree], dg->oneD_face_quadrature); diff --git a/tests/integration_tests_control_files/euler_integration/3d_euler_gaussian_bump_strong.prm b/tests/integration_tests_control_files/euler_integration/3d_euler_gaussian_bump_strong.prm new file mode 100644 index 000000000..8da7422c1 --- /dev/null +++ b/tests/integration_tests_control_files/euler_integration/3d_euler_gaussian_bump_strong.prm @@ -0,0 +1,60 @@ +# Listing of Parameters +# --------------------- + +set dimension = 3 +set run_type = flow_simulation +set pde_type = euler + +set conv_num_flux = two_point_flux_with_roe_dissipation + +set use_split_form = true +set use_weak_form = false +set two_point_num_flux_type = Ra + +subsection euler + set reference_length = 1.0 + set mach_infinity = 0.5 + set angle_of_attack = 0.0 +end + +subsection linear solver +#set linear_solver_type = direct + subsection gmres options + set linear_residual_tolerance = 1e-8 + set max_iterations = 2000 + set restart_number = 100 + set ilut_fill = 1 + # set ilut_drop = 1e-4 + end +end + +subsection ODE solver + # set output_solution_every_x_steps = 1 + # Maximum nonlinear solver iterations + set nonlinear_max_iterations = 500 + + # Nonlinear solver residual tolerance + set nonlinear_steady_residual_tolerance = 1e-11 + + set initial_time_step = 50 + set time_step_factor_residual = 25.0 + set time_step_factor_residual_exp = 4.0 + + # Print every print_iteration_modulo iterations of the nonlinear solver + set print_iteration_modulo = 1 + + # Explicit or implicit solverChoices are . + set ode_solver_type = implicit +end + +subsection flow_solver + set flow_case_type = gaussian_bump + set poly_degree = 0 + set steady_state = true + set steady_state_polynomial_ramping = true + subsection grid + set input_mesh_filename = ../../meshes/3d_gaussian_bump + set use_gmsh_mesh = true + # set grid_degree = 0 + end +end diff --git a/tests/integration_tests_control_files/euler_integration/CMakeLists.txt b/tests/integration_tests_control_files/euler_integration/CMakeLists.txt index 8ab6f3498..2b6c275e0 100644 --- a/tests/integration_tests_control_files/euler_integration/CMakeLists.txt +++ b/tests/integration_tests_control_files/euler_integration/CMakeLists.txt @@ -112,6 +112,13 @@ add_test( WORKING_DIRECTORY ${TEST_OUTPUT_DIR} ) +configure_file(3d_euler_gaussian_bump_strong.prm 3d_euler_gaussian_bump_strong.prm COPYONLY) +add_test( + NAME MPI_3D_EULER_INTEGRATION_GAUSSIAN_BUMP_STRONG_ENTROPY_STABLE + COMMAND mpirun -np ${MPIMAX} ${EXECUTABLE_OUTPUT_PATH}/PHiLiP_3D -i ${CMAKE_CURRENT_BINARY_DIR}/3d_euler_gaussian_bump_strong.prm + WORKING_DIRECTORY ${TEST_OUTPUT_DIR} +) + ##Artificial dissipation tests configure_file(2d_euler_gaussian_bump_with_artificial_dissipation_laplacian_residual_convergence_test.prm 2d_euler_gaussian_bump_with_artificial_dissipation_laplacian_residual_convergence_test.prm COPYONLY) add_test( diff --git a/tests/unit_tests/flow_variable_tests/auxiliary_equations_int_by_parts.cpp b/tests/unit_tests/flow_variable_tests/auxiliary_equations_int_by_parts.cpp index df584c82a..d88df093c 100644 --- a/tests/unit_tests/flow_variable_tests/auxiliary_equations_int_by_parts.cpp +++ b/tests/unit_tests/flow_variable_tests/auxiliary_equations_int_by_parts.cpp @@ -28,12 +28,12 @@ const double TOLERANCE = 1E-6; using namespace std; //namespace PHiLiP { -template +template void assemble_weak_auxiliary_volume( std::shared_ptr < PHiLiP::DGStrong > &dg, const std::vector ¤t_dofs_indices, const unsigned int poly_degree, - PHiLiP::OPERATOR::basis_functions &soln_basis, + PHiLiP::OPERATOR::basis_functions &soln_basis, PHiLiP::OPERATOR::metric_operators &metric_oper, std::vector> &local_auxiliary_RHS) { @@ -87,7 +87,7 @@ void assemble_weak_auxiliary_volume( } } } -template +template void assemble_face_term_auxiliary_weak( std::shared_ptr < PHiLiP::DGStrong > &dg, const unsigned int iface, const unsigned int neighbor_iface, @@ -100,8 +100,8 @@ void assemble_face_term_auxiliary_weak( const unsigned int n_face_quad_pts, const std::vector &dof_indices_int, const std::vector &dof_indices_ext, - PHiLiP::OPERATOR::basis_functions &soln_basis_int, - PHiLiP::OPERATOR::basis_functions &soln_basis_ext, + PHiLiP::OPERATOR::basis_functions &soln_basis_int, + PHiLiP::OPERATOR::basis_functions &soln_basis_ext, PHiLiP::OPERATOR::metric_operators &metric_oper_int, std::vector> &local_auxiliary_RHS_int, std::vector> &local_auxiliary_RHS_ext) @@ -327,16 +327,16 @@ int main (int argc, char * argv[]) auto metric_cell = dg->high_order_grid->dof_handler_grid.begin_active(); //build 1D reference operators - PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(dg->nstate, poly_degree, 1); + PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(dg->nstate, poly_degree, 1); mapping_basis.build_1D_shape_functions_at_grid_nodes(dg->high_order_grid->oneD_fe_system, dg->high_order_grid->oneD_grid_nodes); mapping_basis.build_1D_shape_functions_at_flux_nodes(dg->high_order_grid->oneD_fe_system, dg->oneD_quadrature_collection[poly_degree], dg->oneD_face_quadrature); - PHiLiP::OPERATOR::basis_functions basis(dg->nstate, dg->max_degree, dg->max_grid_degree); + PHiLiP::OPERATOR::basis_functions basis(dg->nstate, dg->max_degree, dg->max_grid_degree); basis.build_1D_volume_operator(dg->oneD_fe_collection_1state[dg->max_degree], dg->oneD_quadrature_collection[dg->max_degree]); basis.build_1D_gradient_operator(dg->oneD_fe_collection_1state[dg->max_degree], dg->oneD_quadrature_collection[dg->max_degree]); basis.build_1D_surface_operator(dg->oneD_fe_collection_1state[dg->max_degree], dg->oneD_face_quadrature); - PHiLiP::OPERATOR::basis_functions flux_basis(dg->nstate, dg->max_degree, dg->max_grid_degree); + PHiLiP::OPERATOR::basis_functions flux_basis(dg->nstate, dg->max_degree, dg->max_grid_degree); flux_basis.build_1D_volume_operator(dg->oneD_fe_collection_flux[dg->max_degree], dg->oneD_quadrature_collection[dg->max_degree]); flux_basis.build_1D_gradient_operator(dg->oneD_fe_collection_flux[dg->max_degree], dg->oneD_quadrature_collection[dg->max_degree]); flux_basis.build_1D_surface_operator(dg->oneD_fe_collection_flux[dg->max_degree], dg->oneD_face_quadrature); @@ -373,12 +373,24 @@ int main (int argc, char * argv[]) current_cell->get_dof_indices (current_dofs_indices); const dealii::types::global_dof_index current_cell_index = current_cell->active_cell_index(); - std::vector> rhs_strong(n_dofs_cell); + dealii::Tensor<1,dim,std::vector> rhs_strong; + for(int idim=0; idim> rhs_weak(n_dofs_cell); + const unsigned int n_shape_fns = n_dofs_cell / (PHILIP_DIM+2); + std::array,PHILIP_DIM+2> soln_coeff; + for (unsigned int idof = 0; idof < n_dofs_cell; ++idof) { + const unsigned int istate = dg->fe_collection[poly_degree].system_to_component_index(idof).first; + const unsigned int ishape = dg->fe_collection[poly_degree].system_to_component_index(idof).second; + if(ishape == 0) + soln_coeff[istate].resize(n_shape_fns); + soln_coeff[istate][ishape] = dg->solution[current_dofs_indices[idof]]; + } //assemble DG strong rhs auxiliary - dg->assemble_volume_term_auxiliary_equation ( - current_dofs_indices, + dg->assemble_volume_term_auxiliary_equation ( + soln_coeff, poly_degree, basis, flux_basis, @@ -396,7 +408,10 @@ int main (int argc, char * argv[]) //loop over faces for (unsigned int iface=0; iface < dealii::GeometryInfo::faces_per_cell; ++iface) { const auto neighbor_cell = current_cell->neighbor_or_periodic_neighbor(iface); - std::vector> rhs_ext_strong(n_dofs_cell); + dealii::Tensor<1,dim,std::vector> rhs_ext_strong; + for(int idim=0; idim> rhs_ext_weak(n_dofs_cell); //get facet metric operators @@ -412,15 +427,28 @@ int main (int argc, char * argv[]) neighbor_dofs_indices.resize(n_dofs_cell); neighbor_cell->get_dof_indices (neighbor_dofs_indices); const dealii::types::global_dof_index neighbor_cell_index = neighbor_cell->active_cell_index(); + + // Extract exterior modal coefficients of solution + std::array,(PHILIP_DIM+2)> soln_coeff_ext; + for (unsigned int idof = 0; idof < n_dofs_cell; ++idof) { + const unsigned int istate = dg->fe_collection[poly_degree].system_to_component_index(idof).first; + const unsigned int ishape = dg->fe_collection[poly_degree].system_to_component_index(idof).second; + if(ishape == 0){ + soln_coeff_ext[istate].resize(n_shape_fns); + } + soln_coeff_ext[istate][ishape] = dg->solution[neighbor_dofs_indices[idof]]; + } //evaluate facet auxiliary RHS - dg->assemble_face_term_auxiliary_equation ( + dg->assemble_face_term_auxiliary_equation ( iface, neighbor_iface, current_cell_index, neighbor_cell_index, + soln_coeff, soln_coeff_ext, poly_degree, poly_degree, - current_dofs_indices, neighbor_dofs_indices, basis, basis, metric_oper, + *dg->pde_physics_double, + *dg->diss_num_flux_double, rhs_strong, rhs_ext_strong); const unsigned int n_face_quad_pts = dg->face_quadrature_collection[poly_degree].size();//assume interior cell does the work @@ -441,7 +469,7 @@ int main (int argc, char * argv[]) for(unsigned int idof=0; idof1e-13){ + if(std::abs(rhs_ext_strong[idim][idof]-rhs_ext_weak[idof][idim])>1e-13){ pcout<<"The strong external cell face RHS is not correct."<1e-13){ + if(std::abs(rhs_strong[idim][idof]-rhs_weak[idof][idim])>1e-13){ pcout<<"The strong and weak RHS are not equivalent interior cell."<high_order_grid->dof_handler_grid.begin_active(); - PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(dg->nstate, poly_degree, 1); + PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(dg->nstate, poly_degree, 1); mapping_basis.build_1D_shape_functions_at_grid_nodes(dg->high_order_grid->oneD_fe_system, dg->high_order_grid->oneD_grid_nodes); mapping_basis.build_1D_shape_functions_at_flux_nodes(dg->high_order_grid->oneD_fe_system, dg->oneD_quadrature_collection[poly_degree], dg->oneD_face_quadrature); - OPERATOR::vol_projection_operator vol_projection(dg->nstate, dg->max_degree, dg->max_grid_degree); + OPERATOR::vol_projection_operator vol_projection(dg->nstate, dg->max_degree, dg->max_grid_degree); vol_projection.build_1D_volume_operator(dg->oneD_fe_collection[dg->max_degree], dg->oneD_quadrature_collection[dg->max_degree]); for (auto current_cell = dg->dof_handler.begin_active(); current_cell!=dg->dof_handler.end(); ++current_cell, ++metric_cell) { @@ -203,7 +203,7 @@ int main (int argc, char * argv[]) pcout<<"assembling aux residual"<assemble_auxiliary_residual(); + dg->assemble_auxiliary_residual(false,false,false); //TEST ERROR OOA diff --git a/tests/unit_tests/operator_tests/GCL_Collocated_test.cpp b/tests/unit_tests/operator_tests/GCL_Collocated_test.cpp index 3afc487e9..845f65e55 100644 --- a/tests/unit_tests/operator_tests/GCL_Collocated_test.cpp +++ b/tests/unit_tests/operator_tests/GCL_Collocated_test.cpp @@ -293,7 +293,7 @@ int main (int argc, char * argv[]) dealii::QGauss<1> flux_quad(poly_degree +1); dealii::QGauss<0> flux_quad_face(poly_degree +1); - PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(nstate,poly_degree,grid_degree); + PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(nstate,poly_degree,grid_degree); mapping_basis.build_1D_shape_functions_at_grid_nodes(fe_sys_grid, grid_quad); mapping_basis.build_1D_shape_functions_at_flux_nodes(fe_sys_grid, flux_quad, flux_quad_face); @@ -335,7 +335,7 @@ int main (int argc, char * argv[]) const dealii::FE_DGQArbitraryNodes<1> fe_poly(flux_quad); const dealii::FESystem<1,1> fe_sys_poly(fe_poly, nstate); - PHiLiP::OPERATOR::basis_functions_state flux_basis_quad(poly_degree, 1); + PHiLiP::OPERATOR::basis_functions_state flux_basis_quad(poly_degree, 1); flux_basis_quad.build_1D_gradient_state_operator(fe_sys_poly, flux_quad); flux_basis_quad.build_1D_volume_state_operator(fe_sys_poly, flux_quad); for(int idim=0; idim flux_quad(poly_degree +1); dealii::QGauss<0> flux_quad_face(poly_degree +1); - PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(nstate,poly_degree,grid_degree); + PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(nstate,poly_degree,grid_degree); mapping_basis.build_1D_shape_functions_at_grid_nodes(fe_sys_grid, grid_quad); mapping_basis.build_1D_shape_functions_at_flux_nodes(fe_sys_grid, flux_quad, flux_quad_face); @@ -329,7 +329,7 @@ int main (int argc, char * argv[]) const dealii::FE_DGQArbitraryNodes<1> fe_poly(flux_quad); const dealii::FESystem<1,1> fe_sys_poly(fe_poly, nstate); - PHiLiP::OPERATOR::basis_functions_state flux_basis_quad(poly_degree, 1); + PHiLiP::OPERATOR::basis_functions_state flux_basis_quad(poly_degree, 1); flux_basis_quad.build_1D_gradient_state_operator(fe_sys_poly, flux_quad); flux_basis_quad.build_1D_volume_state_operator(fe_sys_poly, flux_quad); for(int idim=0; idim flux_quad(poly_degree +1); dealii::QGauss<0> flux_quad_face(poly_degree +1); - PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(nstate,poly_degree,grid_degree); + PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(nstate,poly_degree,grid_degree); mapping_basis.build_1D_shape_functions_at_grid_nodes(fe_sys_grid, grid_quad); mapping_basis.build_1D_shape_functions_at_flux_nodes(fe_sys_grid, flux_quad, flux_quad_face); @@ -333,7 +333,7 @@ int main (int argc, char * argv[]) const dealii::FE_DGQArbitraryNodes<1> fe_poly(flux_quad); const dealii::FESystem<1,1> fe_sys_poly(fe_poly, nstate); - PHiLiP::OPERATOR::basis_functions_state flux_basis_quad(poly_degree, 1); + PHiLiP::OPERATOR::basis_functions_state flux_basis_quad(poly_degree, 1); flux_basis_quad.build_1D_gradient_state_operator(fe_sys_poly, flux_quad); flux_basis_quad.build_1D_volume_state_operator(fe_sys_poly, flux_quad); for(int idim=0; idim stiffness(1, poly_degree, 1); - PHiLiP::OPERATOR::local_mass mass(1, poly_degree, 1); + PHiLiP::OPERATOR::local_basis_stiffness stiffness(1, poly_degree, 1); + PHiLiP::OPERATOR::local_mass mass(1, poly_degree, 1); dealii::QGauss<1> quad1D (poly_degree+1); const dealii::FE_DGQArbitraryNodes<1> fe_dg(quad1D); const dealii::FESystem<1,1> fe_system(fe_dg, 1); diff --git a/tests/unit_tests/operator_tests/consistent_surface_Hadamard_test.cpp b/tests/unit_tests/operator_tests/consistent_surface_Hadamard_test.cpp index 6b7c3c941..2b5991975 100644 --- a/tests/unit_tests/operator_tests/consistent_surface_Hadamard_test.cpp +++ b/tests/unit_tests/operator_tests/consistent_surface_Hadamard_test.cpp @@ -68,8 +68,8 @@ int main (int argc, char * argv[]) const unsigned int poly_min = 2; for(unsigned int poly_degree=poly_min; poly_degree basis(1, poly_degree, 1); - PHiLiP::OPERATOR::local_mass mass(1, poly_degree, 1); + PHiLiP::OPERATOR::basis_functions basis(1, poly_degree, 1); + PHiLiP::OPERATOR::local_mass mass(1, poly_degree, 1); dealii::QGauss<1> quad1D (poly_degree+1); dealii::QGauss<0> quad1D_surf (poly_degree+1); const dealii::FE_DGQArbitraryNodes<1> fe_dg(quad1D); diff --git a/tests/unit_tests/operator_tests/flux_oper_test.cpp b/tests/unit_tests/operator_tests/flux_oper_test.cpp index ba479eb8b..a6d659afa 100644 --- a/tests/unit_tests/operator_tests/flux_oper_test.cpp +++ b/tests/unit_tests/operator_tests/flux_oper_test.cpp @@ -114,14 +114,14 @@ int main (int argc, char * argv[]) const dealii::FESystem<1,1> fe_system(fe_dg, nstate); const dealii::FE_DGQArbitraryNodes<1> fe_dg_flux(quad1D); const dealii::FESystem<1,1> fe_system_flux(fe_dg_flux, nstate); - PHiLiP::OPERATOR::vol_integral_gradient_basis vol_int_grad_basis(nstate, poly_degree, 1); + PHiLiP::OPERATOR::vol_integral_gradient_basis vol_int_grad_basis(nstate, poly_degree, 1); vol_int_grad_basis.build_1D_gradient_operator(fe_system, quad1D); - PHiLiP::OPERATOR::local_flux_basis_stiffness flux_stiffness(poly_degree, 1); + PHiLiP::OPERATOR::local_flux_basis_stiffness flux_stiffness(poly_degree, 1); flux_stiffness.build_1D_gradient_state_operator(fe_system_flux, quad1D); flux_stiffness.build_1D_volume_state_operator(fe_system, quad1D); - // PHiLiP::OPERATOR::basis_functions_state flux_basis_quad(poly_degree, 1); - PHiLiP::OPERATOR::flux_basis_functions_state flux_basis_quad(poly_degree, 1); + // PHiLiP::OPERATOR::basis_functions_state flux_basis_quad(poly_degree, 1); + PHiLiP::OPERATOR::flux_basis_functions_state flux_basis_quad(poly_degree, 1); flux_basis_quad.build_1D_volume_state_operator(fe_system_flux, quad1D); dealii::FullMatrix vol_int_parts(n_dofs_1D); @@ -132,7 +132,7 @@ int main (int argc, char * argv[]) dealii::QGauss<0> face_quad1D (poly_degree+1); dealii::FullMatrix surf_int_parts(n_dofs_1D); flux_basis_quad.build_1D_surface_state_operator(fe_system_flux, face_quad1D); - PHiLiP::OPERATOR::face_integral_basis surf_int_basis(nstate, poly_degree, 1); + PHiLiP::OPERATOR::face_integral_basis surf_int_basis(nstate, poly_degree, 1); surf_int_basis.build_1D_surface_operator(fe_system, face_quad1D); for(unsigned int iface=0; iface< dealii::GeometryInfo<1>::faces_per_cell; iface++){ const dealii::Tensor<1,1,real> unit_normal_1D = dealii::GeometryInfo<1>::unit_normal_vector[iface]; diff --git a/tests/unit_tests/operator_tests/metric_Jacobian_test.cpp b/tests/unit_tests/operator_tests/metric_Jacobian_test.cpp index ba72e620d..de322db16 100644 --- a/tests/unit_tests/operator_tests/metric_Jacobian_test.cpp +++ b/tests/unit_tests/operator_tests/metric_Jacobian_test.cpp @@ -294,7 +294,7 @@ int main (int argc, char * argv[]) dealii::QGauss<1> flux_quad(poly_degree +1); dealii::QGauss<0> flux_quad_face(poly_degree +1); - PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(nstate,poly_degree,grid_degree); + PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(nstate,poly_degree,grid_degree); mapping_basis.build_1D_shape_functions_at_grid_nodes(fe_sys_grid, grid_quad); mapping_basis.build_1D_shape_functions_at_flux_nodes(fe_sys_grid, flux_quad, flux_quad_face); diff --git a/tests/unit_tests/operator_tests/sum_factorization_Hadamard_matrix_assembly_test.cpp b/tests/unit_tests/operator_tests/sum_factorization_Hadamard_matrix_assembly_test.cpp index 4df1ffb2c..e6e9d1e19 100644 --- a/tests/unit_tests/operator_tests/sum_factorization_Hadamard_matrix_assembly_test.cpp +++ b/tests/unit_tests/operator_tests/sum_factorization_Hadamard_matrix_assembly_test.cpp @@ -78,7 +78,7 @@ int main (int argc, char * argv[]) std::array time_diff_original; for(unsigned int poly_degree=poly_min; poly_degree basis(nstate,poly_degree, 1); + PHiLiP::OPERATOR::basis_functions basis(nstate,poly_degree, 1); dealii::QGauss<1> quad1D (poly_degree+1); const dealii::FE_DGQArbitraryNodes<1> fe_dg(quad1D); const dealii::FESystem<1,1> fe_system(fe_dg, 1); diff --git a/tests/unit_tests/operator_tests/sum_factorization_Hadamard_surface_matrix_assembly_test.cpp b/tests/unit_tests/operator_tests/sum_factorization_Hadamard_surface_matrix_assembly_test.cpp index 28f63e6bb..aba7dd5e5 100644 --- a/tests/unit_tests/operator_tests/sum_factorization_Hadamard_surface_matrix_assembly_test.cpp +++ b/tests/unit_tests/operator_tests/sum_factorization_Hadamard_surface_matrix_assembly_test.cpp @@ -76,8 +76,8 @@ int main (int argc, char * argv[]) std::array time_diff_original; for(unsigned int poly_degree=poly_min; poly_degree basis(1,poly_degree, 1); - PHiLiP::OPERATOR::local_mass mass(1, poly_degree, 1); + PHiLiP::OPERATOR::basis_functions basis(1,poly_degree, 1); + PHiLiP::OPERATOR::local_mass mass(1, poly_degree, 1); dealii::QGauss<1> quad1D (poly_degree+1); dealii::QGauss<0> quad1D_surf (poly_degree+1); const dealii::FE_DGQArbitraryNodes<1> fe_dg(quad1D); diff --git a/tests/unit_tests/operator_tests/sum_factorization_Hadamard_test.cpp b/tests/unit_tests/operator_tests/sum_factorization_Hadamard_test.cpp index 92e7b90ef..fdfde71d3 100644 --- a/tests/unit_tests/operator_tests/sum_factorization_Hadamard_test.cpp +++ b/tests/unit_tests/operator_tests/sum_factorization_Hadamard_test.cpp @@ -78,7 +78,7 @@ int main (int argc, char * argv[]) std::array time_diff_sum_dir3; for(unsigned int poly_degree=poly_min; poly_degree basis(nstate,poly_degree, 1); + PHiLiP::OPERATOR::basis_functions basis(nstate,poly_degree, 1); dealii::QGauss<1> quad1D (poly_degree+1); const dealii::FE_DGQArbitraryNodes<1> fe_dg(quad1D); const dealii::FESystem<1,1> fe_system(fe_dg, 1); diff --git a/tests/unit_tests/operator_tests/sum_factorization_test.cpp b/tests/unit_tests/operator_tests/sum_factorization_test.cpp index 47bdf085c..cc395beb2 100644 --- a/tests/unit_tests/operator_tests/sum_factorization_test.cpp +++ b/tests/unit_tests/operator_tests/sum_factorization_test.cpp @@ -111,8 +111,8 @@ int main (int argc, char * argv[]) std::array time_diff_mass; std::array time_diff_mass_sum; for(unsigned int poly_degree=poly_min; poly_degree mass_matrix(nstate, poly_degree, 1); - PHiLiP::OPERATOR::basis_functions basis(nstate, poly_degree, 1); + PHiLiP::OPERATOR::local_mass mass_matrix(nstate, poly_degree, 1); + PHiLiP::OPERATOR::basis_functions basis(nstate, poly_degree, 1); dealii::QGauss<1> quad1D (poly_degree+1); const dealii::FE_DGQ<1> fe_dg(poly_degree); const dealii::FESystem<1,1> fe_system(fe_dg, nstate); diff --git a/tests/unit_tests/operator_tests/surface_GCL_Superparametric_test.cpp b/tests/unit_tests/operator_tests/surface_GCL_Superparametric_test.cpp index 7a9cf18f0..dfc37bd52 100644 --- a/tests/unit_tests/operator_tests/surface_GCL_Superparametric_test.cpp +++ b/tests/unit_tests/operator_tests/surface_GCL_Superparametric_test.cpp @@ -294,7 +294,7 @@ int main (int argc, char * argv[]) dealii::QGauss<1> flux_quad(poly_degree +1); dealii::QGauss<0> flux_quad_face(poly_degree +1); - PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(nstate,poly_degree,grid_degree); + PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(nstate,poly_degree,grid_degree); mapping_basis.build_1D_shape_functions_at_grid_nodes(fe_sys_grid, grid_quad); mapping_basis.build_1D_shape_functions_at_flux_nodes(fe_sys_grid, flux_quad, flux_quad_face); diff --git a/tests/unit_tests/operator_tests/surface_GCL_test.cpp b/tests/unit_tests/operator_tests/surface_GCL_test.cpp index a9e966ed2..65e4d8dc0 100644 --- a/tests/unit_tests/operator_tests/surface_GCL_test.cpp +++ b/tests/unit_tests/operator_tests/surface_GCL_test.cpp @@ -298,7 +298,7 @@ int main (int argc, char * argv[]) dealii::QGauss<1> flux_quad(poly_degree +1); dealii::QGauss<0> flux_quad_face(poly_degree +1); - PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(nstate,poly_degree,grid_degree); + PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(nstate,poly_degree,grid_degree); mapping_basis.build_1D_shape_functions_at_grid_nodes(fe_sys_grid, grid_quad); mapping_basis.build_1D_shape_functions_at_flux_nodes(fe_sys_grid, flux_quad, flux_quad_face); diff --git a/tests/unit_tests/operator_tests/surface_conforming_test.cpp b/tests/unit_tests/operator_tests/surface_conforming_test.cpp index 5c4105711..ee25e07e2 100644 --- a/tests/unit_tests/operator_tests/surface_conforming_test.cpp +++ b/tests/unit_tests/operator_tests/surface_conforming_test.cpp @@ -291,7 +291,7 @@ int main (int argc, char * argv[]) dealii::QGauss<1> flux_quad(poly_degree +1); dealii::QGauss<0> flux_quad_face(poly_degree +1); - PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(nstate,poly_degree,grid_degree); + PHiLiP::OPERATOR::mapping_shape_functions mapping_basis(nstate,poly_degree,grid_degree); mapping_basis.build_1D_shape_functions_at_grid_nodes(fe_sys_grid, grid_quad); mapping_basis.build_1D_shape_functions_at_flux_nodes(fe_sys_grid, flux_quad, flux_quad_face); diff --git a/tests/unit_tests/operator_tests/surface_oper_test.cpp b/tests/unit_tests/operator_tests/surface_oper_test.cpp index 49ef22ebe..0765bf207 100644 --- a/tests/unit_tests/operator_tests/surface_oper_test.cpp +++ b/tests/unit_tests/operator_tests/surface_oper_test.cpp @@ -112,7 +112,7 @@ int main (int argc, char * argv[]) const unsigned int n_dofs_1D = nstate * (poly_degree+1); // build stiffness 1D - PHiLiP::OPERATOR::local_basis_stiffness stiffness(nstate, poly_degree, 1); + PHiLiP::OPERATOR::local_basis_stiffness stiffness(nstate, poly_degree, 1); dealii::QGauss<1> quad1D (poly_degree+1); const dealii::FE_DGQ<1> fe_dg(poly_degree); const dealii::FESystem<1,1> fe_system(fe_dg, nstate); @@ -126,9 +126,9 @@ int main (int argc, char * argv[]) // compute surface integral dealii::FullMatrix face_int_parts(n_dofs_1D); dealii::QGauss<0> face_quad1D (poly_degree+1); - PHiLiP::OPERATOR::face_integral_basis face_int(nstate, poly_degree, 1); + PHiLiP::OPERATOR::face_integral_basis face_int(nstate, poly_degree, 1); face_int.build_1D_surface_operator(fe_system, face_quad1D); - PHiLiP::OPERATOR::basis_functions face_basis(nstate, poly_degree, 1); + PHiLiP::OPERATOR::basis_functions face_basis(nstate, poly_degree, 1); face_basis.build_1D_surface_operator(fe_system, face_quad1D); const unsigned int n_face_quad_pts = face_quad1D.size(); @@ -158,7 +158,7 @@ int main (int argc, char * argv[]) } } - PHiLiP::OPERATOR::lifting_operator lifting(nstate, poly_degree, 1); + PHiLiP::OPERATOR::lifting_operator lifting(nstate, poly_degree, 1); lifting.build_1D_volume_operator(fe_system, quad1D); lifting.build_1D_surface_operator(fe_system, face_quad1D); std::array,2> surface_int_from_lift; @@ -174,7 +174,7 @@ int main (int argc, char * argv[]) } } } - PHiLiP::OPERATOR::lifting_operator_FR lifting_FR(nstate, poly_degree, 1, FR_enum::cPlus); + PHiLiP::OPERATOR::lifting_operator_FR lifting_FR(nstate, poly_degree, 1, FR_enum::cPlus); lifting_FR.build_1D_volume_operator(fe_system, quad1D); lifting_FR.build_1D_surface_operator(fe_system, face_quad1D); std::array,2> surface_int_from_lift_FR; diff --git a/tests/unit_tests/operator_tests/tensor_product_test.cpp b/tests/unit_tests/operator_tests/tensor_product_test.cpp index f28942563..40b43dd92 100644 --- a/tests/unit_tests/operator_tests/tensor_product_test.cpp +++ b/tests/unit_tests/operator_tests/tensor_product_test.cpp @@ -91,7 +91,7 @@ int main (int argc, char * argv[]) dealii::QGauss<1> quad_1D (poly_degree+1); const dealii::FE_DGQ<1> fe(poly_degree); const dealii::FESystem<1,1> fe_system(fe, nstate); - PHiLiP::OPERATOR::basis_functions basis_1D(nstate, poly_degree, 1); + PHiLiP::OPERATOR::basis_functions basis_1D(nstate, poly_degree, 1); basis_1D.build_1D_volume_operator(fe, quad_1D); basis_1D.build_1D_gradient_operator(fe, quad_1D); dealii::FullMatrix basis_dim(n_dofs); diff --git a/tests/unit_tests/operator_tests/volume_operators_test.cpp b/tests/unit_tests/operator_tests/volume_operators_test.cpp index 8dc535fd4..094187a6b 100644 --- a/tests/unit_tests/operator_tests/volume_operators_test.cpp +++ b/tests/unit_tests/operator_tests/volume_operators_test.cpp @@ -112,7 +112,7 @@ int main (int argc, char * argv[]) const dealii::FE_DGQ fe_dim(poly_degree); const dealii::FESystem fe_system_dim(fe_dim, nstate); - PHiLiP::OPERATOR::local_mass mass_matrix(nstate, poly_degree, 1); + PHiLiP::OPERATOR::local_mass mass_matrix(nstate, poly_degree, 1); dealii::QGauss<1> quad1D (poly_degree+1); const dealii::FE_DGQ<1> fe_dg(poly_degree); const dealii::FESystem<1,1> fe_system(fe_dg, nstate); @@ -122,7 +122,7 @@ int main (int argc, char * argv[]) mass_matrix.oneD_vol_operator, mass_matrix.oneD_vol_operator,mass_matrix.oneD_vol_operator); - PHiLiP::OPERATOR::local_Flux_Reconstruction_operator local_FR(nstate, poly_degree, 1, FR_enum::cHU); + PHiLiP::OPERATOR::local_Flux_Reconstruction_operator local_FR(nstate, poly_degree, 1, FR_enum::cHU); local_FR.build_1D_volume_operator(fe_system,quad1D); dealii::FullMatrix FR_dim(n_dofs); FR_dim = local_FR.build_dim_Flux_Reconstruction_operator(mass_matrix.oneD_vol_operator, nstate, n_dofs); diff --git a/tests/unit_tests/regression/CMakeLists.txt b/tests/unit_tests/regression/CMakeLists.txt index 3cf9ea4fc..0d0f85973 100644 --- a/tests/unit_tests/regression/CMakeLists.txt +++ b/tests/unit_tests/regression/CMakeLists.txt @@ -39,3 +39,43 @@ foreach(dim RANGE 1 3) unset(ParametersLib) endforeach() + +set(TEST_SRC + jacobian_matrix_regression_strong.cpp + ) + +foreach(dim RANGE 1 3) + + # Output executable + string(CONCAT TEST_TARGET ${dim}D_jacobian_matrix_regression_strong_DG) + message("Adding executable " ${TEST_TARGET} " with files " ${TEST_SRC} "\n") + add_executable(${TEST_TARGET} ${TEST_SRC}) + # Replace occurences of PHILIP_DIM with 1, 2, or 3 in the code + target_compile_definitions(${TEST_TARGET} PRIVATE PHILIP_DIM=${dim}) + + # Compile this executable when 'make unit_tests' + add_dependencies(unit_tests ${TEST_TARGET}) + add_dependencies(${dim}D ${TEST_TARGET}) + + # Library dependency + set(ParametersLib ParametersLibrary) + string(CONCAT DiscontinuousGalerkinLib DiscontinuousGalerkin_${dim}D) + target_link_libraries(${TEST_TARGET} ${ParametersLib}) + target_link_libraries(${TEST_TARGET} ${DiscontinuousGalerkinLib}) + # Setup target with deal.II + if(NOT DOC_ONLY) + DEAL_II_SETUP_TARGET(${TEST_TARGET}) + endif() + + add_test( + NAME ${TEST_TARGET} + COMMAND mpirun -n 1 ${EXECUTABLE_OUTPUT_PATH}/${TEST_TARGET} + WORKING_DIRECTORY ${TEST_OUTPUT_DIR} + ) + + unset(TEST_TARGET) + unset(PhysicsLib) + unset(NumericalFluxLib) + unset(ParametersLib) + +endforeach() diff --git a/tests/unit_tests/regression/jacobian_matrix_regression_strong.cpp b/tests/unit_tests/regression/jacobian_matrix_regression_strong.cpp new file mode 100644 index 000000000..3175c85c7 --- /dev/null +++ b/tests/unit_tests/regression/jacobian_matrix_regression_strong.cpp @@ -0,0 +1,157 @@ +#include +#include +#include + +#include +#include + +#include + +#include "dg/dg_factory.hpp" +#include "parameters/parameters.h" +#include "physics/physics.h" +#include "numerical_flux/convective_numerical_flux.hpp" + +using PDEType = PHiLiP::Parameters::AllParameters::PartialDifferentialEquation; +using ConvType = PHiLiP::Parameters::AllParameters::ConvectiveNumericalFlux; +using DissType = PHiLiP::Parameters::AllParameters::DissipativeNumericalFlux; + +const bool COMPARE_MATRICES = true;//false; +const bool PRODUCE_TESTS = !COMPARE_MATRICES; +const double TOLERANCE = 1E-12; + +int main (int argc, char * argv[]) +{ + dealii::Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1); + + using namespace dealii; + using namespace PHiLiP; + const int dim = PHILIP_DIM; + int error = 0; + int success_bool = true; + + ParameterHandler parameter_handler; + Parameters::AllParameters::declare_parameters (parameter_handler); + + Parameters::AllParameters all_parameters; + all_parameters.parse_parameters (parameter_handler); + all_parameters.use_weak_form = false; + std::vector pde_type { + PDEType::advection, + // PDEType::diffusion, + // PDEType::convection_diffusion, + PDEType::advection_vector + }; + + for (auto pde = pde_type.begin(); pde != pde_type.end() && error == 0; pde++) { + for (unsigned int poly_degree=1; poly_degree<3; ++poly_degree) { + for (unsigned int igrid=2; igrid<5; ++igrid) { + // Generate grids +#if PHILIP_DIM==1 + using Triangulation = dealii::Triangulation; +#else + using Triangulation = dealii::parallel::distributed::Triangulation; +#endif + std::shared_ptr grid = std::make_shared( +#if PHILIP_DIM!=1 + MPI_COMM_WORLD, +#endif + typename dealii::Triangulation::MeshSmoothing( + dealii::Triangulation::smoothing_on_refinement | + dealii::Triangulation::smoothing_on_coarsening)); + GridGenerator::subdivided_hyper_cube(*grid, igrid); + + // Assemble Jacobian + all_parameters.pde_type = *pde; + std::shared_ptr < DGBase > dg = DGFactory::create_discontinuous_galerkin(&all_parameters, poly_degree, grid); + dg->allocate_system (); + + dg->solution *= 0.0; + + dg->assemble_residual(true); + + const int nrows = dg->system_matrix.m(); + + // Copy stuff into SparseMatrix since it has the function block_write and block_read + SparseMatrix sparse_mat; + SparsityPattern sparsity_pattern; + sparsity_pattern.copy_from(dg->sparsity_pattern); + sparse_mat.reinit(sparsity_pattern); + std::cout << sparse_mat.m() << std::endl; + std::cout << dg->system_matrix.m() << std::endl; + sparse_mat.copy_from(dg->system_matrix); + + // Define filename + std::string pde_string, poly_string = std::to_string(poly_degree), grid_string = std::to_string(igrid); + if (*pde == PDEType::advection) pde_string = "advection"; + if (*pde == PDEType::diffusion) pde_string = "diffusion"; + if (*pde == PDEType::convection_diffusion) pde_string = "convection_diffusion"; + if (*pde == PDEType::advection_vector) pde_string = "advection_vector"; + + std::string filename = std::to_string(dim) + "d_" + pde_string + "_poly_" + poly_string + "_gridsize_" + grid_string + ".mat"; + std::string path = "matrix_data/" + filename; + + if (COMPARE_MATRICES) { + // Load up matrix from file + std::cout << "Reading matrix from: "<< path << std::endl; + std::ifstream infile (path,std::ifstream::binary); + SparseMatrix sparse_mat_from_file; + sparse_mat_from_file.reinit(sparsity_pattern); + if (dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) sparse_mat_from_file.block_read(infile); + infile.close(); + + // Compare the matrices and evaluate the relative error in the Frobenius norm + double matrix_norm = sparse_mat_from_file.frobenius_norm(); + double sum = 0.0; + auto coeff2 = sparse_mat.begin(); + for (auto coeff1 = sparse_mat_from_file.begin(); coeff1 < sparse_mat_from_file.end(); ++coeff1) { + double diff = coeff1->value() - coeff2->value(); + sum += std::pow(diff, 2); + //std::cout << coeff1->value() << " " << coeff2->value() << " " << diff << sum << std::endl; + ++coeff2; + } + sum = sqrt(sum); + double rel_err = std::abs(sum/matrix_norm); + + success_bool = success_bool && (rel_err < TOLERANCE); + + std::cout << filename << ", Relative error: " << rel_err << std::endl; + if (!success_bool) { + error = 1; + std::cout << "Previous matrix given by "<< path << " did not match current one." << std::endl; + + if (nrows < 15) { + FullMatrix fullA(nrows); + fullA.copy_from(dg->system_matrix); + std::cout<<"CURRENT MATRIX:"< fullB(nrows); + fullB.copy_from(sparse_mat_from_file); + std::cout<<"MATRIX FROM FILE:"< + +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include "ode_solver/ode_solver_factory.h" +#include "dg/dg_factory.hpp" +#include "parameters/parameters.h" +#include "physics/physics_factory.h" + +using PDEType = PHiLiP::Parameters::AllParameters::PartialDifferentialEquation; +using ModelType = PHiLiP::Parameters::AllParameters::ModelType; + +#if PHILIP_DIM==1 + using Triangulation = dealii::Triangulation; +#else + using Triangulation = dealii::parallel::distributed::Triangulation; +#endif + +const double TOLERANCE = 1E-4; +const double EPS = 1E-4; + +// const unsigned int iw, const bool iw_relevant, +// const unsigned int jw, const bool jw_relevant, +// const int dipert, +// const int djpert, +// const double EPS, +// const PHiLiP::DGBase &dg, +// ) +//{ +// double old_iw, old_jw; +// PHiLiP::HighOrderGrid &high_order_grid = dg->high_order_grid; +// +// if (iw_relevant) { +// old_iw = dg->solution[iw]; +// dg->solution[iw] = old_iw+dipert*EPS; +// } +// if (jw_relevant) { +// old_jw = dg->solution[jw]; +// if (iw == jw) { +// dg->solution[jw] += j*EPS; +// } else { +// dg->solution[jw] = old_jw+djpert*EPS; +// } +// } +// dg->assemble_residual(false, false, false); +// perturbed_dual_dot_residual[ij] = dg->right_hand_side * dg->dual; +// +// if (iw_relevant) { +// dg->solution[iw] = old_iw; +// } +// if (jw_relevant) { +// dg->solution[jw] = old_jw; +// } +/** This test checks that dRdX evaluated using automatic differentiation + * matches with the results obtained using finite-difference. + */ +template +int test ( + const unsigned int poly_degree, + const std::shared_ptr grid, + const PHiLiP::Parameters::AllParameters &all_parameters) +{ + int mpi_rank = dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD); + dealii::ConditionalOStream pcout(std::cout, mpi_rank==0); + using namespace PHiLiP; + // Assemble Jacobian + std::shared_ptr < DGBase > dg = DGFactory::create_discontinuous_galerkin(&all_parameters, poly_degree, grid); + + const int n_refine = 1; + for (int i=0; ihigh_order_grid->prepare_for_coarsening_and_refinement(); + grid->prepare_coarsening_and_refinement(); + unsigned int icell = 0; + for (auto cell = grid->begin_active(); cell!=grid->end(); ++cell) { + if (!cell->is_locally_owned()) continue; + icell++; + if (icell < grid->n_active_cells()/2) { + cell->set_refine_flag(); + } + } + grid->execute_coarsening_and_refinement(); + bool mesh_out = (i==n_refine-1); + dg->high_order_grid->execute_coarsening_and_refinement(mesh_out); + } + dg->allocate_system (); + + pcout << "Poly degree " << poly_degree << " ncells " << grid->n_global_active_cells() << " ndofs: " << dg->dof_handler.n_dofs() << std::endl; + + // Initialize solution with something + using solutionVector = dealii::LinearAlgebra::distributed::Vector; + + std::shared_ptr > physics_double = Physics::PhysicsFactory::create_Physics(&all_parameters); + solutionVector solution_no_ghost; + solution_no_ghost.reinit(dg->locally_owned_dofs, MPI_COMM_WORLD); + dealii::VectorTools::interpolate(dg->dof_handler, *(physics_double->manufactured_solution_function), solution_no_ghost); + dg->solution = solution_no_ghost; + for (auto it = dg->solution.begin(); it != dg->solution.end(); ++it) { + // Interpolating the exact manufactured solution caused some problems at the boundary conditions. + // The manufactured solution is exactly equal to the manufactured_solution_function at the boundary, + // therefore, the finite difference will change whether the flow is incoming or outgoing. + // As a result, we would be differentiating at a non-differentiable point. + // Hence, we fix this issue by taking the second derivative at a non-exact solution. + //(*it) += 1.0; + } + dg->solution.update_ghost_values(); + + // Solving the flow to make sure that we're not at the point of non-differentiality between elements. + std::shared_ptr> ode_solver = PHiLiP::ODE::ODESolverFactory::create_ODESolver(dg); + ode_solver->steady_state(); + + // Set dual to 1.0 so that every 2nd derivative of the residual is accounted for. + for (auto it = dg->dual.begin(); it != dg->dual.end(); ++it) { + (*it) = 1.0; + } + dg->dual.update_ghost_values(); + + + dealii::TrilinosWrappers::SparseMatrix d2RdWdW_fd; + dealii::SparsityPattern sparsity_pattern = dg->get_d2RdWdW_sparsity_pattern(); + + const dealii::IndexSet &row_parallel_partitioning = dg->locally_owned_dofs; + const dealii::IndexSet &col_parallel_partitioning = dg->locally_owned_dofs; + d2RdWdW_fd.reinit(row_parallel_partitioning, col_parallel_partitioning, sparsity_pattern, MPI_COMM_WORLD); + + pcout << "Evaluating AD..." << std::endl; + dg->assemble_residual(false, false, true); + + pcout << "Evaluating FD..." << std::endl; + for (unsigned int iw = 0; iwdof_handler.n_dofs(); ++iw) { + + if (iw % 1 == 0) pcout << "iw " << iw+1 << " out of " << dg->dof_handler.n_dofs() << std::endl; + + for (unsigned int jw = iw; jwdof_handler.n_dofs(); ++jw) { + + const bool local_isnonzero = sparsity_pattern.exists(iw,jw); + bool global_isnonzero; + MPI_Allreduce(&local_isnonzero, &global_isnonzero, 1, MPI_C_BOOL, MPI_LOR, MPI_COMM_WORLD); + if (!global_isnonzero) continue; + + const bool iw_relevant = dg->locally_relevant_dofs.is_element(iw); + const bool jw_relevant = dg->locally_relevant_dofs.is_element(jw); + double old_iw = -99999; + double old_jw = -99999; + + if (iw_relevant) { + old_iw = dg->solution[iw]; + } + if (jw_relevant) { + old_jw = dg->solution[jw]; + } + std::array, 25> pert; + for (int i=-2; i<3; ++i) { + for (int j=-2; j<3; ++j) { + int ij = (i+2)*5 + (j+2); + pert[ij][0] = i; + pert[ij][1] = j; + } + } + + std::array perturbed_dual_dot_residual; + + for (int i=-2; i<3; ++i) { + for (int j=-2; j<3; ++j) { + int ij = (i+2)*5 + (j+2); + + if (iw_relevant) { + dg->solution[iw] = old_iw+i*EPS; + } + if (jw_relevant) { + if (iw == jw) { + dg->solution[jw] += j*EPS; + } else { + dg->solution[jw] = old_jw+j*EPS; + } + } + dg->assemble_residual(false, false, false); + perturbed_dual_dot_residual[ij] = dg->right_hand_side * dg->dual; + + if (iw_relevant) { + dg->solution[iw] = old_iw; + } + if (jw_relevant) { + dg->solution[jw] = old_jw; + } + } + } + + // http://www.holoborodko.com/pavel/2014/11/04/computing-mixed-derivatives-by-finite-differences/ + double fd_entry = 0.0; + int i,j, ij; + + // http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/central-differences/#comment-5289 + fd_entry = 0.0; + + double term[4] = { 0.0,0.0,0.0,0.0 }; + i = 1; j = -2 ; ij = (i+2)*5 + (j+2); + term[0] += perturbed_dual_dot_residual[ij]; + i = 2; j = -1 ; ij = (i+2)*5 + (j+2); + term[0] += perturbed_dual_dot_residual[ij]; + i = -2; j = 1 ; ij = (i+2)*5 + (j+2); + term[0] += perturbed_dual_dot_residual[ij]; + i = -1; j = 2 ; ij = (i+2)*5 + (j+2); + term[0] += perturbed_dual_dot_residual[ij]; + + term[0] *= -63.0; + + i = -1; j = -2 ; ij = (i+2)*5 + (j+2); + term[1] += perturbed_dual_dot_residual[ij]; + i = -2; j = -1 ; ij = (i+2)*5 + (j+2); + term[1] += perturbed_dual_dot_residual[ij]; + i = 2; j = 1 ; ij = (i+2)*5 + (j+2); + term[1] += perturbed_dual_dot_residual[ij]; + i = 1; j = 2 ; ij = (i+2)*5 + (j+2); + term[1] += perturbed_dual_dot_residual[ij]; + + term[1] *= 63.0; + + i = 2; j = -2 ; ij = (i+2)*5 + (j+2); + term[2] += perturbed_dual_dot_residual[ij]; + i = -2; j = 2 ; ij = (i+2)*5 + (j+2); + term[2] += perturbed_dual_dot_residual[ij]; + i = -2; j = -2 ; ij = (i+2)*5 + (j+2); + term[2] -= perturbed_dual_dot_residual[ij]; + i = 2; j = 2 ; ij = (i+2)*5 + (j+2); + term[2] -= perturbed_dual_dot_residual[ij]; + + term[2] *= 44.0; + + i = -1; j = -1 ; ij = (i+2)*5 + (j+2); + term[3] += perturbed_dual_dot_residual[ij]; + i = 1; j = 1 ; ij = (i+2)*5 + (j+2); + term[3] += perturbed_dual_dot_residual[ij]; + i = 1; j = -1 ; ij = (i+2)*5 + (j+2); + term[3] -= perturbed_dual_dot_residual[ij]; + i = -1; j = 1 ; ij = (i+2)*5 + (j+2); + term[3] -= perturbed_dual_dot_residual[ij]; + + term[3] *= 74.0; + + fd_entry = term[0] + term[1] + term[2] + term[3]; + fd_entry /= (600.0*EPS*EPS); + + // Reset node + if (iw_relevant) { + dg->solution[iw] = old_iw; + } + if (jw_relevant) { + dg->solution[jw] = old_jw; + } + + // Set + if (dg->locally_owned_dofs.is_element(iw) ) { + if (std::abs(fd_entry) >= 1e-12) { + d2RdWdW_fd.add(iw,jw,fd_entry); + } + } + if (iw != jw && dg->locally_owned_dofs.is_element(jw) ) { + if (std::abs(fd_entry) >= 1e-12) { + d2RdWdW_fd.add(jw,iw,fd_entry); + } + } + } + } + d2RdWdW_fd.compress(dealii::VectorOperation::add); + + dg->assemble_residual(false, false, true); + { + const unsigned int n_digits = 5; + const unsigned int n_spacing = 7+n_digits; + dealii::ConditionalOStream pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0); + dealii::FullMatrix fullA(d2RdWdW_fd.m(),d2RdWdW_fd.n()); + fullA.copy_from(d2RdWdW_fd); + pcout<<"Dense matrix from FD-AD:"< fullA(dg->d2RdWdW.m(),dg->d2RdWdW.n()); + fullA.copy_from(dg->d2RdWdW); + pcout<<"Dense matrix from FD-AD:"<d2RdWdW.frobenius_norm(); + const double fd_frob_norm = d2RdWdW_fd.frobenius_norm(); + double frob_norm = std::max(ad_frob_norm, fd_frob_norm); + if (ad_frob_norm < 1e-12) frob_norm = 1.0; // Take absolute error + + pcout << "FD-norm = " << d2RdWdW_fd.frobenius_norm() << std::endl; + pcout << "AD-norm = " << dg->d2RdWdW.frobenius_norm() << std::endl; + d2RdWdW_fd.add(-1.0,dg->d2RdWdW); + + const double diff_lone_norm = d2RdWdW_fd.l1_norm() / frob_norm; + const double diff_linf_norm = d2RdWdW_fd.linfty_norm() / frob_norm; + pcout << "(dRdX_FD - dRdX_AD) L1-norm = " << diff_lone_norm << std::endl; + pcout << "(dRdX_FD - dRdX_AD) Linf-norm = " << diff_linf_norm << std::endl; + + //if (diff_lone_norm > TOLERANCE) + { + const unsigned int n_digits = 5; + const unsigned int n_spacing = 7+n_digits; + dealii::ConditionalOStream pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0); + dealii::FullMatrix fullA(d2RdWdW_fd.m(),d2RdWdW_fd.n()); + fullA.copy_from(d2RdWdW_fd); + pcout<<"Dense matrix from FD-AD:"< TOLERANCE) return 1; + + return 0; +} + +int main (int argc, char * argv[]) +{ + dealii::Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1); + int mpi_rank = dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD); + dealii::ConditionalOStream pcout(std::cout, mpi_rank==0); + + using namespace PHiLiP; + const int dim = PHILIP_DIM; + int error = 0; + //int success_bool = true; + + dealii::ParameterHandler parameter_handler; + Parameters::AllParameters::declare_parameters (parameter_handler); + + Parameters::AllParameters all_parameters; + all_parameters.parse_parameters (parameter_handler); + all_parameters.use_weak_form = false; + std::vector pde_type { + //PDEType::diffusion + PDEType::advection + //, PDEType::convection_diffusion + , PDEType::advection_vector + , PDEType::euler + // , PDEType::navier_stokes +//#if PHILIP_DIM==3 +// , PDEType::physics_model +//#endif + }; + std::vector pde_name { + // " PDEType::diffusion " + " PDEType::advection " + //, " PDEType::convection_diffusion " + , " PDEType::advection_vector " + , " PDEType::euler " + // , " PDEType::navier_stokes " +//#if PHILIP_DIM==3 +// , " PDEType::physics_model " +//#endif + }; +#if PHILIP_DIM==3 + ModelType model = ModelType::large_eddy_simulation +#endif + + int ipde = -1; + for (auto pde = pde_type.begin(); pde != pde_type.end() || error == 1; pde++) { + ipde++; + for (unsigned int poly_degree=0; poly_degree<3; ++poly_degree) { + for (unsigned int igrid=2; igrid<3; ++igrid) { + pcout << "Using " << pde_name[ipde] << std::endl; + all_parameters.pde_type = *pde; + // Generate grids + std::shared_ptr grid = std::make_shared( +#if PHILIP_DIM!=1 + MPI_COMM_WORLD, +#endif + typename dealii::Triangulation::MeshSmoothing( + dealii::Triangulation::smoothing_on_refinement | + dealii::Triangulation::smoothing_on_coarsening)); + + dealii::GridGenerator::subdivided_hyper_cube(*grid, igrid); + + const double random_factor = 0.2; + const bool keep_boundary = false; + if (random_factor > 0.0) dealii::GridTools::distort_random (random_factor, *grid, keep_boundary); + for (auto &cell : grid->active_cell_iterators()) { + for (unsigned int face=0; face::faces_per_cell; ++face) { + if (cell->face(face)->at_boundary()) cell->face(face)->set_boundary_id (1000); + } + } + + if ((*pde==PDEType::euler) || (*pde==PDEType::navier_stokes) +#if PHILIP_DIM==3 + || ((*pde==PDEType::physics_model) && (model==ModelType::large_eddy_simulation)) +#endif + ) { + error = test(poly_degree, grid, all_parameters); + } else if (*pde==PDEType::burgers_inviscid) { + error = test(poly_degree, grid, all_parameters); + } else if (*pde==PDEType::advection_vector) { + error = test(poly_degree, grid, all_parameters); + } else { + error = test(poly_degree, grid, all_parameters); + } + if (error) return error; + } + } + } + + return error; +} + + + diff --git a/tests/unit_tests/sensitivities/d2RdWdX_fd_vs_ad_strong.cpp b/tests/unit_tests/sensitivities/d2RdWdX_fd_vs_ad_strong.cpp new file mode 100644 index 000000000..89d2495ca --- /dev/null +++ b/tests/unit_tests/sensitivities/d2RdWdX_fd_vs_ad_strong.cpp @@ -0,0 +1,391 @@ +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include "ode_solver/ode_solver_factory.h" +#include "dg/dg_factory.hpp" +#include "parameters/parameters.h" +#include "physics/physics_factory.h" + +using PDEType = PHiLiP::Parameters::AllParameters::PartialDifferentialEquation; +using ModelType = PHiLiP::Parameters::AllParameters::ModelType; + + +#if PHILIP_DIM==1 + using Triangulation = dealii::Triangulation; +#else + using Triangulation = dealii::parallel::distributed::Triangulation; +#endif + +const double TOLERANCE = 1E-3; +const double EPS = 1E-4; + +/** This test checks that dRdX evaluated using automatic differentiation + * matches with the results obtained using finite-difference. + */ +template +int test ( + const unsigned int poly_degree, + const std::shared_ptr grid, + const PHiLiP::Parameters::AllParameters &all_parameters) +{ + int mpi_rank = dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD); + dealii::ConditionalOStream pcout(std::cout, mpi_rank==0); + using namespace PHiLiP; + // Assemble Jacobian + std::shared_ptr < DGBase > dg = DGFactory::create_discontinuous_galerkin(&all_parameters, poly_degree, grid); + + const int n_refine = 1; + for (int i=0; ihigh_order_grid->prepare_for_coarsening_and_refinement(); + grid->prepare_coarsening_and_refinement(); + unsigned int icell = 0; + for (auto cell = grid->begin_active(); cell!=grid->end(); ++cell) { + if (!cell->is_locally_owned()) continue; + icell++; + if (icell < grid->n_active_cells()/2) { + cell->set_refine_flag(); + } + } + grid->execute_coarsening_and_refinement(); + bool mesh_out = (i==n_refine-1); + dg->high_order_grid->execute_coarsening_and_refinement(mesh_out); + } + dg->allocate_system (); + + pcout << "Poly degree " << poly_degree << " ncells " << grid->n_global_active_cells() << " ndofs: " << dg->dof_handler.n_dofs() << std::endl; + + // Initialize solution with something + using solutionVector = dealii::LinearAlgebra::distributed::Vector; + + std::shared_ptr > physics_double = Physics::PhysicsFactory::create_Physics(&all_parameters); + solutionVector solution_no_ghost; + solution_no_ghost.reinit(dg->locally_owned_dofs, MPI_COMM_WORLD); + dealii::VectorTools::interpolate(dg->dof_handler, *(physics_double->manufactured_solution_function), solution_no_ghost); + dg->solution = solution_no_ghost; + for (auto it = dg->solution.begin(); it != dg->solution.end(); ++it) { + // Interpolating the exact manufactured solution caused some problems at the boundary conditions. + // The manufactured solution is exactly equal to the manufactured_solution_function at the boundary, + // therefore, the finite difference will change whether the flow is incoming or outgoing. + // As a result, we would be differentiating at a non-differentiable point. + // Hence, we fix this issue by taking the second derivative at a non-exact solution. + //(*it) += 1.0; + } + dg->solution.update_ghost_values(); + + // Solving the flow to make sure that we're not at the point of non-differentiality between elements. + std::shared_ptr> ode_solver = PHiLiP::ODE::ODESolverFactory::create_ODESolver(dg); + ode_solver->steady_state(); + + // Set dual to 1.0 so that every 2nd derivative of the residual is accounted for. + for (auto it = dg->dual.begin(); it != dg->dual.end(); ++it) { + (*it) = 1.0; + } + dg->dual.update_ghost_values(); + + + dealii::TrilinosWrappers::SparseMatrix d2RdWdX_fd; + dealii::SparsityPattern sparsity_pattern = dg->get_d2RdWdX_sparsity_pattern(); + + const dealii::IndexSet &row_parallel_partitioning = dg->locally_owned_dofs; + const dealii::IndexSet &col_parallel_partitioning = dg->high_order_grid->locally_owned_dofs_grid; + d2RdWdX_fd.reinit(row_parallel_partitioning, col_parallel_partitioning, sparsity_pattern, MPI_COMM_WORLD); + + pcout << "Evaluating AD..." << std::endl; + dg->assemble_residual(false, false, true); + + pcout << "Evaluating FD..." << std::endl; + for (unsigned int iw = 0; iwdof_handler.n_dofs(); ++iw) { + + if (iw % 1 == 0) pcout << "iw " << iw+1 << " out of " << dg->dof_handler.n_dofs() << std::endl; + + for (unsigned int jnode = 0; jnode < dg->high_order_grid->dof_handler_grid.n_dofs(); ++jnode) { + + const bool local_isnonzero = sparsity_pattern.exists(iw,jnode); + bool global_isnonzero; + MPI_Allreduce(&local_isnonzero, &global_isnonzero, 1, MPI_C_BOOL, MPI_LOR, MPI_COMM_WORLD); + if (!global_isnonzero) continue; + + const bool iw_relevant = dg->locally_relevant_dofs.is_element(iw); + const bool jnode_relevant = dg->high_order_grid->locally_relevant_dofs_grid.is_element(jnode); + double old_iw = -99999; + double old_jnode = -99999; + + if (iw_relevant) { + old_iw = dg->solution[iw]; + } + if (jnode_relevant) { + old_jnode = dg->high_order_grid->volume_nodes[jnode]; + } + std::array, 25> pert; + for (int i=-2; i<3; ++i) { + for (int j=-2; j<3; ++j) { + int ij = (i+2)*5 + (j+2); + pert[ij][0] = i; + pert[ij][1] = j; + } + } + + std::array perturbed_dual_dot_residual; + + for (int i=-2; i<3; ++i) { + for (int j=-2; j<3; ++j) { + int ij = (i+2)*5 + (j+2); + + if (iw_relevant) { + dg->solution[iw] = old_iw+i*EPS; + } + if (jnode_relevant) { + dg->high_order_grid->volume_nodes[jnode] = old_jnode+j*EPS; + } + dg->assemble_residual(false, false, false); + perturbed_dual_dot_residual[ij] = dg->right_hand_side * dg->dual; + + if (iw_relevant) { + dg->solution[iw] = old_iw; + } + if (jnode_relevant) { + dg->high_order_grid->volume_nodes[jnode] = old_jnode; + } + } + } + + // http://www.holoborodko.com/pavel/2014/11/04/computing-mixed-derivatives-by-finite-differences/ + double fd_entry = 0.0; + int i,j, ij; + + // http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/central-differences/#comment-5289 + fd_entry = 0.0; + + double term[4] = { 0.0,0.0,0.0,0.0 }; + i = 1; j = -2 ; ij = (i+2)*5 + (j+2); + term[0] += perturbed_dual_dot_residual[ij]; + i = 2; j = -1 ; ij = (i+2)*5 + (j+2); + term[0] += perturbed_dual_dot_residual[ij]; + i = -2; j = 1 ; ij = (i+2)*5 + (j+2); + term[0] += perturbed_dual_dot_residual[ij]; + i = -1; j = 2 ; ij = (i+2)*5 + (j+2); + term[0] += perturbed_dual_dot_residual[ij]; + + term[0] *= -63.0; + + i = -1; j = -2 ; ij = (i+2)*5 + (j+2); + term[1] += perturbed_dual_dot_residual[ij]; + i = -2; j = -1 ; ij = (i+2)*5 + (j+2); + term[1] += perturbed_dual_dot_residual[ij]; + i = 2; j = 1 ; ij = (i+2)*5 + (j+2); + term[1] += perturbed_dual_dot_residual[ij]; + i = 1; j = 2 ; ij = (i+2)*5 + (j+2); + term[1] += perturbed_dual_dot_residual[ij]; + + term[1] *= 63.0; + + i = 2; j = -2 ; ij = (i+2)*5 + (j+2); + term[2] += perturbed_dual_dot_residual[ij]; + i = -2; j = 2 ; ij = (i+2)*5 + (j+2); + term[2] += perturbed_dual_dot_residual[ij]; + i = -2; j = -2 ; ij = (i+2)*5 + (j+2); + term[2] -= perturbed_dual_dot_residual[ij]; + i = 2; j = 2 ; ij = (i+2)*5 + (j+2); + term[2] -= perturbed_dual_dot_residual[ij]; + + term[2] *= 44.0; + + i = -1; j = -1 ; ij = (i+2)*5 + (j+2); + term[3] += perturbed_dual_dot_residual[ij]; + i = 1; j = 1 ; ij = (i+2)*5 + (j+2); + term[3] += perturbed_dual_dot_residual[ij]; + i = 1; j = -1 ; ij = (i+2)*5 + (j+2); + term[3] -= perturbed_dual_dot_residual[ij]; + i = -1; j = 1 ; ij = (i+2)*5 + (j+2); + term[3] -= perturbed_dual_dot_residual[ij]; + + term[3] *= 74.0; + + fd_entry = term[0] + term[1] + term[2] + term[3]; + fd_entry /= (600.0*EPS*EPS); + + // Reset node + if (iw_relevant) { + dg->solution[iw] = old_iw; + } + if (jnode_relevant) { + dg->high_order_grid->volume_nodes[jnode] = old_jnode; + } + + // Set + if (dg->locally_owned_dofs.is_element(iw) ) { + if (std::abs(fd_entry) >= 1e-12) { + d2RdWdX_fd.add(iw,jnode,fd_entry); + } + } + } + } + d2RdWdX_fd.compress(dealii::VectorOperation::add); + + dg->assemble_residual(false, false, true); + { + const unsigned int n_digits = 5; + const unsigned int n_spacing = 7+n_digits; + dealii::ConditionalOStream pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0); + dealii::FullMatrix fullA(d2RdWdX_fd.m(),d2RdWdX_fd.n()); + fullA.copy_from(d2RdWdX_fd); + pcout<<"Dense matrix from FD-AD:"< fullA(dg->d2RdWdX.m(),dg->d2RdWdX.n()); + fullA.copy_from(dg->d2RdWdX); + pcout<<"Dense matrix from FD-AD:"<d2RdWdX.frobenius_norm(); + const double fd_frob_norm = d2RdWdX_fd.frobenius_norm(); + double frob_norm = std::max(ad_frob_norm, fd_frob_norm); + if (ad_frob_norm < 1e-12) frob_norm = 1.0; // Take absolute error + + pcout << "FD-norm = " << d2RdWdX_fd.frobenius_norm() << std::endl; + pcout << "AD-norm = " << dg->d2RdWdX.frobenius_norm() << std::endl; + d2RdWdX_fd.add(-1.0,dg->d2RdWdX); + + const double diff_lone_norm = d2RdWdX_fd.l1_norm() / frob_norm; + const double diff_linf_norm = d2RdWdX_fd.linfty_norm() / frob_norm; + pcout << "(dRdX_FD - dRdX_AD) L1-norm = " << diff_lone_norm << std::endl; + pcout << "(dRdX_FD - dRdX_AD) Linf-norm = " << diff_linf_norm << std::endl; + + //if (diff_lone_norm > TOLERANCE) + { + const unsigned int n_digits = 5; + const unsigned int n_spacing = 7+n_digits; + dealii::ConditionalOStream pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0); + dealii::FullMatrix fullA(d2RdWdX_fd.m(),d2RdWdX_fd.n()); + fullA.copy_from(d2RdWdX_fd); + pcout<<"Dense matrix from FD-AD:"< TOLERANCE) return 1; + + return 0; +} + +int main (int argc, char * argv[]) +{ + dealii::Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1); + int mpi_rank = dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD); + dealii::ConditionalOStream pcout(std::cout, mpi_rank==0); + + using namespace PHiLiP; + const int dim = PHILIP_DIM; + int error = 0; + //int success_bool = true; + + dealii::ParameterHandler parameter_handler; + Parameters::AllParameters::declare_parameters (parameter_handler); + + Parameters::AllParameters all_parameters; + all_parameters.parse_parameters (parameter_handler); + all_parameters.use_weak_form = false; + std::vector pde_type { + //PDEType::diffusion + PDEType::advection + // , PDEType::convection_diffusion + , PDEType::advection_vector + , PDEType::euler + // , PDEType::navier_stokes +//#if PHILIP_DIM==3 +// , PDEType::physics_model +//#endif + }; + std::vector pde_name { + // " PDEType::diffusion " + " PDEType::advection " + // , " PDEType::convection_diffusion " + , " PDEType::advection_vector " + , " PDEType::euler " + // , " PDEType::navier_stokes " +//#if PHILIP_DIM==3 +// , " PDEType::physics_model " +//#endif + }; +#if PHILIP_DIM==3 + ModelType model = ModelType::large_eddy_simulation +#endif + + int ipde = -1; + for (auto pde = pde_type.begin(); pde != pde_type.end() || error == 1; pde++) { + ipde++; + for (unsigned int poly_degree=0; poly_degree<3; ++poly_degree) { + for (unsigned int igrid=2; igrid<3; ++igrid) { + pcout << "Using " << pde_name[ipde] << std::endl; + all_parameters.pde_type = *pde; + // Generate grids + std::shared_ptr grid = std::make_shared( +#if PHILIP_DIM!=1 + MPI_COMM_WORLD, +#endif + typename dealii::Triangulation::MeshSmoothing( + dealii::Triangulation::MeshSmoothing::smoothing_on_refinement | + dealii::Triangulation::MeshSmoothing::smoothing_on_coarsening)); + + dealii::GridGenerator::subdivided_hyper_cube(*grid, igrid); + + const double random_factor = 0.2; + const bool keep_boundary = false; + if (random_factor > 0.0) dealii::GridTools::distort_random (random_factor, *grid, keep_boundary); + for (auto &cell : grid->active_cell_iterators()) { + for (unsigned int face=0; face::faces_per_cell; ++face) { + if (cell->face(face)->at_boundary()) cell->face(face)->set_boundary_id (1000); + } + } + + if ((*pde==PDEType::euler) || (*pde==PDEType::navier_stokes) +#if PHILIP_DIM==3 + || ((*pde==PDEType::physics_model) && (model==ModelType::large_eddy_simulation)) +#endif + ) { + error = test(poly_degree, grid, all_parameters); + } else if (*pde==PDEType::burgers_inviscid) { + error = test(poly_degree, grid, all_parameters); + } else if (*pde==PDEType::advection_vector) { + error = test(poly_degree, grid, all_parameters); + } else { + error = test(poly_degree, grid, all_parameters); + } + if (error) return error; + } + } + } + + return error; +} + + + diff --git a/tests/unit_tests/sensitivities/d2RdXdX_fd_vs_ad_strong.cpp b/tests/unit_tests/sensitivities/d2RdXdX_fd_vs_ad_strong.cpp new file mode 100644 index 000000000..fe4d65061 --- /dev/null +++ b/tests/unit_tests/sensitivities/d2RdXdX_fd_vs_ad_strong.cpp @@ -0,0 +1,437 @@ +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include "ode_solver/ode_solver_factory.h" +#include "dg/dg_factory.hpp" +#include "parameters/parameters.h" +#include "physics/physics_factory.h" + +using PDEType = PHiLiP::Parameters::AllParameters::PartialDifferentialEquation; +using ModelType = PHiLiP::Parameters::AllParameters::ModelType; + +#if PHILIP_DIM==1 + using Triangulation = dealii::Triangulation; +#else + using Triangulation = dealii::parallel::distributed::Triangulation; +#endif + +const double TOLERANCE = 1E-3; +const double EPS = 1E-4; + +// const unsigned int inode, const bool inode_relevant, +// const unsigned int jnode, const bool jnode_relevant, +// const int dipert, +// const int djpert, +// const double EPS, +// const PHiLiP::DGBase &dg, +// ) +//{ +// double old_inode, old_jnode; +// std::shared_ptr> high_order_grid = dg->high_order_grid; +// +// if (inode_relevant) { +// old_inode = high_order_grid->volume_nodes(inode); +// high_order_grid->volume_nodes(inode) = old_inode+dipert*EPS; +// } +// if (jnode_relevant) { +// old_jnode = high_order_grid->volume_nodes(jnode); +// if (inode == jnode) { +// high_order_grid->volume_nodes(jnode) += j*EPS; +// } else { +// high_order_grid->volume_nodes(jnode) = old_jnode+djpert*EPS; +// } +// } +// dg->assemble_residual(false, false, false); +// perturbed_dual_dot_residual[ij] = dg->right_hand_side * dg->dual; +// +// if (inode_relevant) { +// high_order_grid->volume_nodes(inode) = old_inode; +// } +// if (jnode_relevant) { +// high_order_grid->volume_nodes(jnode) = old_jnode; +// } +/** This test checks that dRdX evaluated using automatic differentiation + * matches with the results obtained using finite-difference. + */ +template +int test ( + const unsigned int poly_degree, + std::shared_ptr grid, + const PHiLiP::Parameters::AllParameters &all_parameters) +{ + int mpi_rank = dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD); + dealii::ConditionalOStream pcout(std::cout, mpi_rank==0); + using namespace PHiLiP; + // Assemble Jacobian + std::shared_ptr < DGBase > dg = DGFactory::create_discontinuous_galerkin(&all_parameters, poly_degree, grid); + + const int n_refine = 1; + for (int i=0; ihigh_order_grid->prepare_for_coarsening_and_refinement(); + grid->prepare_coarsening_and_refinement(); + unsigned int icell = 0; + for (auto cell = grid->begin_active(); cell!=grid->end(); ++cell) { + if (!cell->is_locally_owned()) continue; + icell++; + if (icell < grid->n_active_cells()/2) { + cell->set_refine_flag(); + } + } + grid->execute_coarsening_and_refinement(); + bool mesh_out = (i==n_refine-1); + dg->high_order_grid->execute_coarsening_and_refinement(mesh_out); + } + dg->allocate_system (); + + pcout << "Poly degree " << poly_degree << " ncells " << grid->n_global_active_cells() << " ndofs: " << dg->dof_handler.n_dofs() << std::endl; + + // Initialize solution with something + using solutionVector = dealii::LinearAlgebra::distributed::Vector; + + std::shared_ptr > physics_double = Physics::PhysicsFactory::create_Physics(&all_parameters); + solutionVector solution_no_ghost; + solution_no_ghost.reinit(dg->locally_owned_dofs, MPI_COMM_WORLD); + dealii::VectorTools::interpolate(dg->dof_handler, *(physics_double->manufactured_solution_function), solution_no_ghost); + dg->solution = solution_no_ghost; + //for (auto it = dg->solution.begin(); it != dg->solution.end(); ++it) { + // // Interpolating the exact manufactured solution caused some problems at the boundary conditions. + // // The manufactured solution is exactly equal to the manufactured_solution_function at the boundary, + // // therefore, the finite difference will change whether the flow is incoming or outgoing. + // // As a result, we would be differentiating at a non-differentiable point. + // // Hence, we fix this issue by taking the second derivative at a non-exact solution. + // (*it) *= 1.1; + //} + //dg->solution.update_ghost_values(); + + // Solving the flow to make sure that we're not at the point of non-differentiality between elements. + std::shared_ptr> ode_solver = PHiLiP::ODE::ODESolverFactory::create_ODESolver(dg); + ode_solver->steady_state(); + + // Set dual to 1.0 so that every 2nd derivative of the residual is accounted for. + for (auto it = dg->dual.begin(); it != dg->dual.end(); ++it) { + (*it) = 1.0; + } + dg->dual.update_ghost_values(); + + pcout << "Evaluating AD..." << std::endl; + //dg->assemble_residual(false, false, true); + dg->assemble_residual(false, false, true); + + + dealii::TrilinosWrappers::SparseMatrix d2RdXdX_fd; + dealii::SparsityPattern sparsity_pattern = dg->get_d2RdXdX_sparsity_pattern(); + + const dealii::IndexSet &row_parallel_partitioning = dg->high_order_grid->locally_owned_dofs_grid; + //const dealii::IndexSet &col_parallel_partitioning = dg->high_order_grid->locally_relevant_dofs_grid; + const dealii::IndexSet &col_parallel_partitioning = dg->high_order_grid->locally_owned_dofs_grid; + d2RdXdX_fd.reinit(row_parallel_partitioning, col_parallel_partitioning, sparsity_pattern, MPI_COMM_WORLD); + + std::shared_ptr> high_order_grid = dg->high_order_grid; + + using nodeVector = dealii::LinearAlgebra::distributed::Vector; + nodeVector old_volume_nodes = high_order_grid->volume_nodes; + old_volume_nodes.update_ghost_values(); + + pcout << "Evaluating FD..." << std::endl; + for (unsigned int inode = 0; inodedof_handler_grid.n_dofs(); ++inode) { + + if (inode % 1 == 0) pcout << "inode " << inode+1 << " out of " << high_order_grid->dof_handler_grid.n_dofs() << std::endl; + + for (unsigned int jnode = inode; jnodedof_handler_grid.n_dofs(); ++jnode) { + + const bool local_isnonzero = sparsity_pattern.exists(inode,jnode); + bool global_isnonzero; + MPI_Allreduce(&local_isnonzero, &global_isnonzero, 1, MPI_C_BOOL, MPI_LOR, MPI_COMM_WORLD); + if (!global_isnonzero) continue; + + const bool inode_relevant = high_order_grid->locally_relevant_dofs_grid.is_element(inode); + const bool jnode_relevant = high_order_grid->locally_relevant_dofs_grid.is_element(jnode); + double old_inode = -99999; + double old_jnode = -99999; + + if (inode_relevant) { + old_inode = high_order_grid->volume_nodes[inode]; + } + if (jnode_relevant) { + old_jnode = high_order_grid->volume_nodes[jnode]; + } + std::array, 25> pert; + for (int i=-2; i<3; ++i) { + for (int j=-2; j<3; ++j) { + int ij = (i+2)*5 + (j+2); + pert[ij][0] = i; + pert[ij][1] = j; + } + } + + std::array perturbed_dual_dot_residual; + + for (int i=-2; i<3; ++i) { + for (int j=-2; j<3; ++j) { + int ij = (i+2)*5 + (j+2); + + if (inode_relevant) { + high_order_grid->volume_nodes(inode) = old_inode+i*EPS; + } + if (jnode_relevant) { + if (inode == jnode) { + high_order_grid->volume_nodes(jnode) += j*EPS; + } else { + high_order_grid->volume_nodes(jnode) = old_jnode+j*EPS; + } + } + dg->assemble_residual(false, false, false); + perturbed_dual_dot_residual[ij] = dg->right_hand_side * dg->dual; + + if (inode_relevant) { + high_order_grid->volume_nodes(inode) = old_inode; + } + if (jnode_relevant) { + high_order_grid->volume_nodes(jnode) = old_jnode; + } + } + } + + // http://www.holoborodko.com/pavel/2014/11/04/computing-mixed-derivatives-by-finite-differences/ + double fd_entry = 0.0; + int i,j, ij; + + // http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/central-differences/#comment-5289 + fd_entry = 0.0; + + double term[4] = { 0.0,0.0,0.0,0.0 }; + i = 1; j = -2 ; ij = (i+2)*5 + (j+2); + term[0] += perturbed_dual_dot_residual[ij]; + i = 2; j = -1 ; ij = (i+2)*5 + (j+2); + term[0] += perturbed_dual_dot_residual[ij]; + i = -2; j = 1 ; ij = (i+2)*5 + (j+2); + term[0] += perturbed_dual_dot_residual[ij]; + i = -1; j = 2 ; ij = (i+2)*5 + (j+2); + term[0] += perturbed_dual_dot_residual[ij]; + + term[0] *= -63.0; + + i = -1; j = -2 ; ij = (i+2)*5 + (j+2); + term[1] += perturbed_dual_dot_residual[ij]; + i = -2; j = -1 ; ij = (i+2)*5 + (j+2); + term[1] += perturbed_dual_dot_residual[ij]; + i = 2; j = 1 ; ij = (i+2)*5 + (j+2); + term[1] += perturbed_dual_dot_residual[ij]; + i = 1; j = 2 ; ij = (i+2)*5 + (j+2); + term[1] += perturbed_dual_dot_residual[ij]; + + term[1] *= 63.0; + + i = 2; j = -2 ; ij = (i+2)*5 + (j+2); + term[2] += perturbed_dual_dot_residual[ij]; + i = -2; j = 2 ; ij = (i+2)*5 + (j+2); + term[2] += perturbed_dual_dot_residual[ij]; + i = -2; j = -2 ; ij = (i+2)*5 + (j+2); + term[2] -= perturbed_dual_dot_residual[ij]; + i = 2; j = 2 ; ij = (i+2)*5 + (j+2); + term[2] -= perturbed_dual_dot_residual[ij]; + + term[2] *= 44.0; + + i = -1; j = -1 ; ij = (i+2)*5 + (j+2); + term[3] += perturbed_dual_dot_residual[ij]; + i = 1; j = 1 ; ij = (i+2)*5 + (j+2); + term[3] += perturbed_dual_dot_residual[ij]; + i = 1; j = -1 ; ij = (i+2)*5 + (j+2); + term[3] -= perturbed_dual_dot_residual[ij]; + i = -1; j = 1 ; ij = (i+2)*5 + (j+2); + term[3] -= perturbed_dual_dot_residual[ij]; + + term[3] *= 74.0; + + fd_entry = term[0] + term[1] + term[2] + term[3]; + fd_entry /= (600.0*EPS*EPS); + + // Reset node + if (inode_relevant) { + high_order_grid->volume_nodes(inode) = old_inode; + } + if (jnode_relevant) { + high_order_grid->volume_nodes(jnode) = old_jnode; + } + + // Set + if (dg->high_order_grid->locally_owned_dofs_grid.is_element(inode) ) { + if (std::abs(fd_entry) >= 1e-12) { + d2RdXdX_fd.add(inode,jnode,fd_entry); + } + } + if (inode != jnode && dg->high_order_grid->locally_owned_dofs_grid.is_element(jnode) ) { + if (std::abs(fd_entry) >= 1e-12) { + d2RdXdX_fd.add(jnode,inode,fd_entry); + } + } + } + } + d2RdXdX_fd.compress(dealii::VectorOperation::add); + + dg->assemble_residual(false, false, true); + { + const unsigned int n_digits = 5; + const unsigned int n_spacing = 7+n_digits; + dealii::ConditionalOStream pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0); + dealii::FullMatrix fullA(d2RdXdX_fd.m(),d2RdXdX_fd.n()); + fullA.copy_from(d2RdXdX_fd); + pcout<<"Dense matrix from FD-AD:"< fullA(dg->d2RdXdX.m(),dg->d2RdXdX.n()); + fullA.copy_from(dg->d2RdXdX); + pcout<<"Dense matrix from FD-AD:"<d2RdXdX.frobenius_norm(); + const double fd_frob_norm = d2RdXdX_fd.frobenius_norm(); + const double frob_norm = std::max(ad_frob_norm, fd_frob_norm); + + pcout << "FD-norm = " << d2RdXdX_fd.frobenius_norm() << std::endl; + pcout << "AD-norm = " << dg->d2RdXdX.frobenius_norm() << std::endl; + d2RdXdX_fd.add(-1.0,dg->d2RdXdX); + + const double diff_lone_norm = d2RdXdX_fd.l1_norm() / frob_norm; + const double diff_linf_norm = d2RdXdX_fd.linfty_norm() / frob_norm; + pcout << "(dRdX_FD - dRdX_AD) L1-norm = " << diff_lone_norm << std::endl; + pcout << "(dRdX_FD - dRdX_AD) Linf-norm = " << diff_linf_norm << std::endl; + + //if (diff_lone_norm > TOLERANCE) + { + const unsigned int n_digits = 5; + const unsigned int n_spacing = 7+n_digits; + dealii::ConditionalOStream pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0); + dealii::FullMatrix fullA(d2RdXdX_fd.m(),d2RdXdX_fd.n()); + fullA.copy_from(d2RdXdX_fd); + pcout<<"Dense matrix from FD-AD:"< TOLERANCE) return 1; + + return 0; +} + +int main (int argc, char * argv[]) +{ + dealii::Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1); + int mpi_rank = dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD); + dealii::ConditionalOStream pcout(std::cout, mpi_rank==0); + + using namespace PHiLiP; + const int dim = PHILIP_DIM; + int error = 0; + //int success_bool = true; + + dealii::ParameterHandler parameter_handler; + Parameters::AllParameters::declare_parameters (parameter_handler); + + Parameters::AllParameters all_parameters; + all_parameters.parse_parameters (parameter_handler); + all_parameters.use_weak_form = false; + std::vector pde_type { + //PDEType::diffusion + PDEType::advection + //, PDEType::convection_diffusion + , PDEType::advection_vector + , PDEType::euler + // , PDEType::navier_stokes +//#if PHILIP_DIM==3 +// , PDEType::physics_model +//#endif + }; + std::vector pde_name { + //" PDEType::diffusion " + " PDEType::advection " + //, " PDEType::convection_diffusion " + , " PDEType::advection_vector " + , " PDEType::euler " + // , " PDEType::navier_stokes " +//#if PHILIP_DIM==3 +// , " PDEType::physics_model " +//#endif + }; +#if PHILIP_DIM==3 + ModelType model = ModelType::large_eddy_simulation +#endif + + int ipde = -1; + for (auto pde = pde_type.begin(); pde != pde_type.end() || error == 1; pde++) { + ipde++; + for (unsigned int poly_degree=0; poly_degree<3; ++poly_degree) { + for (unsigned int igrid=2; igrid<3; ++igrid) { + pcout << "Using " << pde_name[ipde] << std::endl; + all_parameters.pde_type = *pde; + // Generate grids + std::shared_ptr grid = std::make_shared( +#if PHILIP_DIM!=1 + MPI_COMM_WORLD, +#endif + typename dealii::Triangulation::MeshSmoothing( + dealii::Triangulation::smoothing_on_refinement | + dealii::Triangulation::smoothing_on_coarsening)); + + dealii::GridGenerator::subdivided_hyper_cube(*grid, igrid); + + const double random_factor = 0.2; + const bool keep_boundary = false; + if (random_factor > 0.0) dealii::GridTools::distort_random (random_factor, *grid, keep_boundary); + for (auto &cell : grid->active_cell_iterators()) { + for (unsigned int face=0; face::faces_per_cell; ++face) { + if (cell->face(face)->at_boundary()) cell->face(face)->set_boundary_id (1000); + } + } + + if ((*pde==PDEType::euler) || (*pde==PDEType::navier_stokes) +#if PHILIP_DIM==3 + || ((*pde==PDEType::physics_model) && (model==ModelType::large_eddy_simulation)) +#endif + ) { + error = test(poly_degree, grid, all_parameters); + } else if (*pde==PDEType::burgers_inviscid) { + error = test(poly_degree, grid, all_parameters); + } else if (*pde==PDEType::advection_vector) { + error = test(poly_degree, grid, all_parameters); + } else { + error = test(poly_degree, grid, all_parameters); + } + if (error) return error; + } + } + } + + return error; +} + + diff --git a/tests/unit_tests/sensitivities/dRdW_fd_vs_ad_strong.cpp b/tests/unit_tests/sensitivities/dRdW_fd_vs_ad_strong.cpp new file mode 100644 index 000000000..fac7755b0 --- /dev/null +++ b/tests/unit_tests/sensitivities/dRdW_fd_vs_ad_strong.cpp @@ -0,0 +1,258 @@ +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include "dg/dg_factory.hpp" +#include "parameters/parameters.h" +#include "physics/physics_factory.h" +#include "numerical_flux/convective_numerical_flux.hpp" + +using PDEType = PHiLiP::Parameters::AllParameters::PartialDifferentialEquation; +using ConvType = PHiLiP::Parameters::AllParameters::ConvectiveNumericalFlux; +using DissType = PHiLiP::Parameters::AllParameters::DissipativeNumericalFlux; +using ModelType = PHiLiP::Parameters::AllParameters::ModelType; + +#if PHILIP_DIM==1 + using Triangulation = dealii::Triangulation; +#else + using Triangulation = dealii::parallel::distributed::Triangulation; +#endif + +const double TOLERANCE = 1E-5; + +/** This test checks that dRdW evaluated using automatic differentiation + * matches with the results obtained using finite-difference. + */ +template +int test ( + const unsigned int poly_degree, + const std::shared_ptr grid, + const PHiLiP::Parameters::AllParameters &all_parameters) +{ + int mpi_rank = dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD); + dealii::ConditionalOStream pcout(std::cout, mpi_rank==0); + using namespace PHiLiP; + std::shared_ptr < DGBase > dg = DGFactory::create_discontinuous_galerkin(&all_parameters, poly_degree, grid); + + const int n_refine = 1; + for (int i=0; ihigh_order_grid->prepare_for_coarsening_and_refinement(); + grid->prepare_coarsening_and_refinement(); + unsigned int icell = 0; + for (auto cell = grid->begin_active(); cell!=grid->end(); ++cell) { + if (!cell->is_locally_owned()) continue; + icell++; + if (icell < grid->n_active_cells()/2) { + cell->set_refine_flag(); + } + } + grid->execute_coarsening_and_refinement(); + bool mesh_out = (i==n_refine-1); + dg->high_order_grid->execute_coarsening_and_refinement(mesh_out); + } + dg->allocate_system (); + + pcout << "Poly degree " << poly_degree << " ncells " << grid->n_global_active_cells() << " ndofs: " << dg->dof_handler.n_dofs() << std::endl; + + // Initialize solution with something + using solutionVector = dealii::LinearAlgebra::distributed::Vector; + + std::shared_ptr > physics_double = Physics::PhysicsFactory::create_Physics(&all_parameters); + solutionVector solution_no_ghost; + solution_no_ghost.reinit(dg->locally_owned_dofs, MPI_COMM_WORLD); + dealii::VectorTools::interpolate(dg->dof_handler, *(physics_double->manufactured_solution_function), solution_no_ghost); + dg->solution = solution_no_ghost; + for (auto it = dg->solution.begin(); it != dg->solution.end(); ++it) { + // Interpolating the exact manufactured solution caused some problems at the boundary conditions. + // The manufactured solution is exactly equal to the manufactured_solution_function at the boundary, + // therefore, the finite difference will change whether the flow is incoming or outgoing. + // As a result, we would be differentiating at a non-differentiable point. + // Hence, we fix this issue by taking the second derivative at a non-exact solution. + (*it) += 1.0; + } + dg->solution.update_ghost_values(); + + + dealii::TrilinosWrappers::SparseMatrix dRdW_fd; + dealii::SparsityPattern sparsity_pattern = dg->get_dRdW_sparsity_pattern (); + + const dealii::IndexSet &row_parallel_partitioning = dg->locally_owned_dofs; + const dealii::IndexSet &col_parallel_partitioning = dg->locally_owned_dofs; + dRdW_fd.reinit(row_parallel_partitioning, col_parallel_partitioning, sparsity_pattern, MPI_COMM_WORLD); + + const double eps = 1e-5; + + pcout << "Evaluating AD..." << std::endl; + dg->assemble_residual(true, false, false); + + pcout << "Evaluating FD..." << std::endl; + const unsigned int n_dofs = dg->dof_handler.n_dofs(); + for (unsigned int idof = 0; idof < n_dofs; ++idof) { + if (idof % 100 == 0) pcout << "idof " << idof+1 << " out of " << n_dofs << std::endl; + double old_dof = -99999; + // Positive perturbation + if (dg->locally_owned_dofs.is_element(idof) ) { + old_dof = dg->solution[idof]; + dg->solution(idof) = old_dof+eps; + } + dg->assemble_residual(false, false, false); + solutionVector perturbed_residual_p = dg->right_hand_side; + + // Negative perturbation + if (dg->locally_owned_dofs.is_element(idof) ) { + dg->solution(idof) = old_dof-eps; + } + dg->assemble_residual(false, false, false); + solutionVector perturbed_residual_m = dg->right_hand_side; + + // Finite-difference + perturbed_residual_p -= perturbed_residual_m; + perturbed_residual_p /= (2.0*eps); + + // Reset node + if (dg->locally_owned_dofs.is_element(idof) ) { + dg->solution(idof) = old_dof; + } + + // Set + for (unsigned int iresidual = 0; iresidual < dg->dof_handler.n_dofs(); ++iresidual) { + if (dg->locally_owned_dofs.is_element(iresidual) ) { + const double drdx_entry = perturbed_residual_p[iresidual]; + if (std::abs(drdx_entry) >= 1e-12) { + dRdW_fd.add(iresidual,idof,drdx_entry); + } + } + } + } + dRdW_fd.compress(dealii::VectorOperation::add); + + dRdW_fd.add(-1.0,dg->system_matrix); + + const double diff_lone_norm = dRdW_fd.l1_norm(); + const double diff_linf_norm = dRdW_fd.linfty_norm(); + pcout << "(dRdW_FD - dRdW_AD) L1-norm = " << diff_lone_norm << std::endl; + pcout << "(dRdW_FD - dRdW_AD) Linf-norm = " << diff_linf_norm << std::endl; + + if (diff_lone_norm > TOLERANCE) + { + const unsigned int n_digits = 5; + const unsigned int n_spacing = 7+n_digits; + dealii::ConditionalOStream pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0); + dealii::FullMatrix fullA(dRdW_fd.m(),dRdW_fd.n()); + fullA.copy_from(dRdW_fd); + pcout<<"Dense matrix from FD-AD:"< pde_type { + // PDEType::diffusion + PDEType::advection + // , PDEType::convection_diffusion + , PDEType::advection_vector + , PDEType::euler + // , PDEType::navier_stokes +//#if PHILIP_DIM==3 +// , PDEType::physics_model +//#endif + }; + std::vector pde_name { + " PDEType::diffusion " + , " PDEType::advection " + // , " PDEType::convection_diffusion " + , " PDEType::advection_vector " + , " PDEType::euler " + , " PDEType::navier_stokes " +#if PHILIP_DIM==3 + , " PDEType::physics_model " +#endif + }; +#if PHILIP_DIM==3 + ModelType model = ModelType::large_eddy_simulation +#endif + + int ipde = -1; + for (auto pde = pde_type.begin(); pde != pde_type.end() || error == 1; pde++) { + ipde++; + for (unsigned int poly_degree=1; poly_degree<3; ++poly_degree) { + for (unsigned int igrid=2; igrid<4; ++igrid) { + pcout << "Using " << pde_name[ipde] << std::endl; + all_parameters.pde_type = *pde; + all_parameters.diss_num_flux_type = Parameters::AllParameters::DissipativeNumericalFlux::bassi_rebay_2; + // Generate grids + std::shared_ptr grid = std::make_shared( +#if PHILIP_DIM!=1 + MPI_COMM_WORLD, +#endif + typename dealii::Triangulation::MeshSmoothing( + dealii::Triangulation::smoothing_on_refinement | + dealii::Triangulation::smoothing_on_coarsening)); + + dealii::GridGenerator::subdivided_hyper_cube(*grid, igrid); + + const double random_factor = 0.2; + const bool keep_boundary = false; + if (random_factor > 0.0) dealii::GridTools::distort_random (random_factor, *grid, keep_boundary); + for (auto &cell : grid->active_cell_iterators()) { + for (unsigned int face=0; face::faces_per_cell; ++face) { + if (cell->face(face)->at_boundary()) cell->face(face)->set_boundary_id (1000); + } + } + + if ((*pde==PDEType::euler) || (*pde==PDEType::navier_stokes) +#if PHILIP_DIM==3 + || ((*pde==PDEType::physics_model) && (model==ModelType::large_eddy_simulation)) +#endif + ) { + error = test(poly_degree, grid, all_parameters); + } else if (*pde==PDEType::burgers_inviscid) { + error = test(poly_degree, grid, all_parameters); + } else if (*pde==PDEType::advection_vector) { + error = test(poly_degree, grid, all_parameters); + } else { + error = test(poly_degree, grid, all_parameters); + } + if (error) return error; + } + } + } + + return error; +} + + diff --git a/tests/unit_tests/sensitivities/dRdX_fd_vs_ad_strong.cpp b/tests/unit_tests/sensitivities/dRdX_fd_vs_ad_strong.cpp new file mode 100644 index 000000000..840777b8a --- /dev/null +++ b/tests/unit_tests/sensitivities/dRdX_fd_vs_ad_strong.cpp @@ -0,0 +1,286 @@ +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include "dg/dg_factory.hpp" +#include "parameters/parameters.h" +#include "physics/physics_factory.h" + +using PDEType = PHiLiP::Parameters::AllParameters::PartialDifferentialEquation; +using ModelType = PHiLiP::Parameters::AllParameters::ModelType; + +#if PHILIP_DIM==1 + using Triangulation = dealii::Triangulation; +#else + using Triangulation = dealii::parallel::distributed::Triangulation; +#endif + +const double TOLERANCE = 1E-5; +const double EPS = 1e-6; + +/** This test checks that dRdX evaluated using automatic differentiation + * matches with the results obtained using finite-difference. + */ +template +int test ( + const unsigned int poly_degree, + std::shared_ptr grid, + const PHiLiP::Parameters::AllParameters &all_parameters) +{ + int mpi_rank = dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD); + dealii::ConditionalOStream pcout(std::cout, mpi_rank==0); + using namespace PHiLiP; + // Assemble Jacobian + std::shared_ptr < DGBase > dg = DGFactory::create_discontinuous_galerkin(&all_parameters, poly_degree, grid); + + const int n_refine = 1; + for (int i=0; ihigh_order_grid->prepare_for_coarsening_and_refinement(); + grid->prepare_coarsening_and_refinement(); + unsigned int icell = 0; + for (auto cell = grid->begin_active(); cell!=grid->end(); ++cell) { + if (!cell->is_locally_owned()) continue; + icell++; + if (icell < grid->n_active_cells()/2) { + cell->set_refine_flag(); + } + } + grid->execute_coarsening_and_refinement(); + bool mesh_out = (i==n_refine-1); + dg->high_order_grid->execute_coarsening_and_refinement(mesh_out); + } + dg->high_order_grid->ensure_conforming_mesh(); + dg->allocate_system (); + + pcout << "Poly degree " << poly_degree << " ncells " << grid->n_global_active_cells() << " ndofs: " << dg->dof_handler.n_dofs() << std::endl; + + // Initialize solution with something + using solutionVector = dealii::LinearAlgebra::distributed::Vector; + + std::shared_ptr > physics_double = Physics::PhysicsFactory::create_Physics(&all_parameters); + solutionVector solution_no_ghost; + solution_no_ghost.reinit(dg->locally_owned_dofs, MPI_COMM_WORLD); + dealii::VectorTools::interpolate(dg->dof_handler, *(physics_double->manufactured_solution_function), solution_no_ghost); + dg->solution = solution_no_ghost; + for (auto it = dg->solution.begin(); it != dg->solution.end(); ++it) { + // Interpolating the exact manufactured solution caused some problems at the boundary conditions. + // The manufactured solution is exactly equal to the manufactured_solution_function at the boundary, + // therefore, the finite difference will change whether the flow is incoming or outgoing. + // As a result, we would be differentiating at a non-differentiable point. + // Hence, we fix this issue by taking the second derivative at a non-exact solution. + (*it) += 1.0; + } + dg->solution.update_ghost_values(); + + + dealii::TrilinosWrappers::SparseMatrix dRdXv_fd; + dealii::SparsityPattern sparsity_pattern = dg->get_dRdX_sparsity_pattern (); + + const dealii::IndexSet &row_parallel_partitioning = dg->locally_owned_dofs; + const dealii::IndexSet &col_parallel_partitioning = dg->high_order_grid->locally_owned_dofs_grid; + dRdXv_fd.reinit(row_parallel_partitioning, col_parallel_partitioning, sparsity_pattern, MPI_COMM_WORLD); + + std::shared_ptr> high_order_grid = dg->high_order_grid; + + using nodeVector = dealii::LinearAlgebra::distributed::Vector; + nodeVector old_volume_nodes = high_order_grid->volume_nodes; + old_volume_nodes.update_ghost_values(); + + dealii::AffineConstraints hanging_node_constraints; + hanging_node_constraints.clear(); + dealii::DoFTools::make_hanging_node_constraints(high_order_grid->dof_handler_grid, hanging_node_constraints); + hanging_node_constraints.close(); + + pcout << "Evaluating AD..." << std::endl; + dg->assemble_residual(false, true, false); + + pcout << "Evaluating FD..." << std::endl; + for (unsigned int inode = 0; inodedof_handler_grid.n_dofs(); ++inode) { + if (inode % 100 == 0) pcout << "inode " << inode+1 << " out of " << high_order_grid->dof_handler_grid.n_dofs() << std::endl; + double old_node = -99999; + // Positive perturbation + if (high_order_grid->locally_relevant_dofs_grid.is_element(inode) ) { + old_node = high_order_grid->volume_nodes[inode]; + high_order_grid->volume_nodes(inode) = old_node+EPS; + } + // This should be uncommented once we fix: + // https://github.com/dougshidong/PHiLiP/issues/48#issue-771199898 + //high_order_grid->ensure_conforming_mesh(); + //hanging_node_constraints.distribute(high_order_grid->volume_nodes); + //high_order_grid->volume_nodes.update_ghost_values(); + + dg->assemble_residual(false, false, false); + solutionVector perturbed_residual_p = dg->right_hand_side; + + //high_order_grid->volume_nodes = old_volume_nodes; + //high_order_grid->volume_nodes.update_ghost_values(); + + // Negative perturbation + if (high_order_grid->locally_relevant_dofs_grid.is_element(inode) ) { + high_order_grid->volume_nodes(inode) = old_node-EPS; + } + // This should be uncommented once we fix: + // https://github.com/dougshidong/PHiLiP/issues/48#issue-771199898 + //high_order_grid->ensure_conforming_mesh(); + //hanging_node_constraints.distribute(high_order_grid->volume_nodes); + //high_order_grid->volume_nodes.update_ghost_values(); + + dg->assemble_residual(false, false, false); + solutionVector perturbed_residual_m = dg->right_hand_side; + + //high_order_grid->volume_nodes = old_volume_nodes; + //high_order_grid->volume_nodes.update_ghost_values(); + + // Finite difference + perturbed_residual_p -= perturbed_residual_m; + perturbed_residual_p /= (2.0*EPS); + + // Reset node + if (high_order_grid->locally_relevant_dofs_grid.is_element(inode) ) { + high_order_grid->volume_nodes(inode) = old_node; + } + + // Set + for (unsigned int iresidual = 0; iresidual < dg->dof_handler.n_dofs(); ++iresidual) { + if (dg->locally_owned_dofs.is_element(iresidual) ) { + const double drdx_entry = perturbed_residual_p[iresidual]; + if (std::abs(drdx_entry) >= 1e-12) { + std::cout << iresidual << " " << inode << std::endl; + dRdXv_fd.add(iresidual,inode,drdx_entry); + } + } + } + } + dRdXv_fd.compress(dealii::VectorOperation::add); + + pcout << "(dRdX_FD frob_norm) " << dRdXv_fd.frobenius_norm(); + pcout << "(dRdX_AD frob_norm) " << dg->dRdXv.frobenius_norm() << std::endl; + dRdXv_fd.add(-1.0,dg->dRdXv); + + const double diff_lone_norm = dRdXv_fd.l1_norm(); + const double diff_linf_norm = dRdXv_fd.linfty_norm(); + pcout << "(dRdX_FD - dRdX_AD) L1-norm = " << diff_lone_norm << std::endl; + pcout << "(dRdX_FD - dRdX_AD) Linf-norm = " << diff_linf_norm << std::endl; + + if (diff_lone_norm > TOLERANCE) + { + const unsigned int n_digits = 5; + const unsigned int n_spacing = 7+n_digits; + dealii::ConditionalOStream pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0); + dealii::FullMatrix fullA(dRdXv_fd.m(),dRdXv_fd.n()); + fullA.copy_from(dRdXv_fd); + pcout<<"Dense matrix from FD-AD:"< pde_type { + //PDEType::diffusion + PDEType::advection + // , PDEType::convection_diffusion + , PDEType::advection_vector + , PDEType::euler + // , PDEType::navier_stokes +//#if PHILIP_DIM==3 +// , PDEType::physics_model +//#endif + }; + std::vector pde_name { + // " PDEType::diffusion " + " PDEType::advection " + // , " PDEType::convection_diffusion " + , " PDEType::advection_vector " + , " PDEType::euler " + // , " PDEType::navier_stokes " +//#if PHILIP_DIM==3 +// , " PDEType::physics_model " +//#endif + }; +#if PHILIP_DIM==3 + ModelType model = ModelType::large_eddy_simulation +#endif + + int ipde = -1; + for (auto pde = pde_type.begin(); pde != pde_type.end() || error == 1; pde++) { + ipde++; + for (unsigned int poly_degree=1; poly_degree<3; ++poly_degree) { + for (unsigned int igrid=2; igrid<4; ++igrid) { + pcout << "Using " << pde_name[ipde] << std::endl; + all_parameters.pde_type = *pde; + // Generate grids + std::shared_ptr grid = std::make_shared( +#if PHILIP_DIM!=1 + MPI_COMM_WORLD, +#endif + typename dealii::Triangulation::MeshSmoothing( + dealii::Triangulation::smoothing_on_refinement | + dealii::Triangulation::smoothing_on_coarsening)); + + dealii::GridGenerator::subdivided_hyper_cube(*grid, igrid); + + const double random_factor = 0.2; + const bool keep_boundary = false; + if (random_factor > 0.0) dealii::GridTools::distort_random (random_factor, *grid, keep_boundary); + for (auto &cell : grid->active_cell_iterators()) { + for (unsigned int face=0; face::faces_per_cell; ++face) { + if (cell->face(face)->at_boundary()) cell->face(face)->set_boundary_id (1000); + } + } + + if ((*pde==PDEType::euler) || (*pde==PDEType::navier_stokes) +#if PHILIP_DIM==3 + || ((*pde==PDEType::physics_model) && (model==ModelType::large_eddy_simulation)) +#endif + ) { + error = test(poly_degree, grid, all_parameters); + } else if (*pde==PDEType::burgers_inviscid) { + error = test(poly_degree, grid, all_parameters); + } else if (*pde==PDEType::advection_vector) { + error = test(poly_degree, grid, all_parameters); + } else { + error = test(poly_degree, grid, all_parameters); + } + if (error) return error; + } + } + } + + return error; +} + +